Skip to content
Published on

모던 Git 도구 2026 — Git 2.46+ / lazygit / gitui / gh CLI / jj (Jujutsu) / Sapling (Meta) / GitButler / magit / vim-fugitive 심층 가이드

Authors

1. 2026년 모던 Git 도구 지도 — CLI / TUI / GUI / 에디터 4 분류

Git 생태계가 이렇게 복잡해진 이유

Linus Torvalds가 2005년에 Git을 만들었을 때, 그것은 단순한 분산 버전 관리 시스템이었습니다. 명령어는 git, 데이터는 .git 디렉토리, UI는 터미널 한 줄이 전부였습니다. 2026년에 들어선 지금, Git을 둘러싼 도구 생태계는 4개의 큰 진영으로 분화되었습니다.

분류대표 도구사용자 프로필
CLIgit, gh, glab, tea표준 사용자, CI/CD, 자동화
TUIlazygit, gitui, tig터미널 중심 개발자, SSH 환경
GUIFork, Sublime Merge, GitKraken, GitButler, Tower시각적 워크플로우 선호
에디터 통합magit (Emacs), vim-fugitive (Vim), VS Code GitIDE/에디터 의존도 높은 사용자
새 모델jj (Jujutsu), SaplingGit의 다음 세대 실험

왜 새 도구가 계속 나오는가

Git은 매우 강력하지만, 동시에 매우 어렵습니다. 두 가지 종류의 문제가 있습니다.

첫째, 개념적 어려움. Git의 인덱스(staging area), 분리된 HEAD, rebase의 충돌 해결, 서브모듈 등은 처음 배우는 사람을 좌절시킵니다. 토스의 한 시니어 개발자가 "Git을 10년 써도 git reset --hard와 git reset --soft의 차이를 외워서 쓰는 게 아니라 매번 검색한다"고 말한 게 농담만은 아닙니다.

둘째, 워크플로우의 변화. 모노레포가 늘어나면서 한 PR에 너무 많은 변경사항이 들어가는 문제, 큰 팀에서 PR 리뷰 대기열이 쌓이는 문제, 한 명이 동시에 여러 기능을 작업해야 하는 상황 등 — Git이 처음 설계되었을 때 가정하지 않았던 시나리오들이 일상이 되었습니다.

그래서 2026년의 도구들은 단순히 "예쁜 UI"를 넘어, Git의 데이터 모델을 재해석하거나 (jj, Sapling), 새로운 워크플로우를 강제하거나 (GitButler의 가상 브랜치, Graphite의 스택 PR), 자주 쓰는 명령어를 한 화면에 압축 (lazygit, gitui) 하는 방향으로 진화하고 있습니다.

이 문서의 구성

이 가이드는 18개 챕터로 2026년 시점 모든 주요 Git 도구를 다룹니다. 각 도구에 대해 다음 4가지를 일관되게 설명합니다.

  1. 어떤 문제를 푸는가
  2. 어떻게 동작하는가 (데이터 모델 또는 UX 측면)
  3. 누가 쓰는가 (실제 회사 사례)
  4. 언제 쓰지 말아야 하는가

2. Git 2.46-2.50 — 코어의 점진적 진화

메이저 변화 요약

2024년 8월의 Git 2.46부터 2026년 초의 2.50까지, Git 코어는 빠르게 진화하기보다 다음 방향으로 누적적으로 개선되었습니다.

버전출시 시점주요 변경
2.462024-08git config 서브커맨드 도입 (get/set/unset 등), reftable 백엔드 안정화 진전
2.472024-10기본 브랜치 메인 사용 메시지 정리, 패치 모드 개선
2.482025-01reftable 백엔드 기본 옵션 노출, sparse-checkout 성능 개선
2.492025-03name-rev 출력 형식 통합, fetch.pruneTags 안정화
2.502025-06다양한 버그 수정, sideband 프로토콜 메시지 정돈

핵심은 한 번에 큰 새 기능이 추가되기보다, reftable (참조 저장 새 백엔드), sparse-checkout, partial clone, commit-graph 같은 기존 인프라가 더 안정적이고 빠르게 다듬어지고 있다는 점입니다.

reftable — 큰 저장소를 위한 ref 백엔드

전통적으로 Git은 ref(브랜치, 태그)를 .git/refs/ 디렉토리의 파일로 저장합니다. 이는 단순하지만, 수만 개의 브랜치를 가진 모노레포에서는 디렉토리 탐색이 느려집니다.

reftable은 Google의 JGit에서 처음 구현된 형식으로, ref를 하나의 바이너리 파일로 압축 저장합니다. 2.46부터 점진적으로 안정화되어 2026년 시점에는 다음 명령으로 활성화할 수 있습니다.

git init --ref-format=reftable myrepo

Chromium, Android 같은 거대 저장소에서 git fetch, git branch 같은 명령이 수십 배 빨라집니다.

sparse-checkout과 partial clone

모노레포 시대의 두 핵심 기능입니다.

git clone --filter=blob:none --sparse https://github.com/org/monorepo.git
cd monorepo
git sparse-checkout set apps/frontend libs/shared

위 명령은 다음을 수행합니다.

  • partial clone (--filter=blob:none): 처음에는 파일 내용을 다운로드하지 않고, 실제로 필요한 시점에 가져옴
  • sparse-checkout: 작업 트리에 두 디렉토리만 체크아웃

이 조합으로 100GB 저장소를 5분 안에 클론하고, 자신이 보는 디렉토리만 디스크에 두는 것이 가능해집니다. Microsoft, Google, Meta가 내부적으로 활발히 사용합니다.

그 외 자주 쓰이는 새 기능

  • git switch / git restore: 2.23부터 있지만, 2026년에는 git checkout보다 표준으로 자리잡았습니다. switch는 브랜치 변경, restore는 파일 복원입니다.
  • git maintenance: 백그라운드 GC, 자동 git gc/fetch를 cron 없이 관리합니다.
  • git column: git branch, git tag 출력을 자동 컬럼화합니다.
  • git range-diff: 두 브랜치 시리즈의 차이를 비교합니다 (rebase 전후 비교에 유용).

3. lazygit (Jesse Duffield) — TUI 표준

무엇을 푸는가

lazygit은 Jesse Duffield가 2018년경 시작한 Go 기반 터미널 UI Git 클라이언트입니다. 2026년 현재, 터미널 환경에서 Git을 다루는 표준이 되었습니다.

전통적인 Git CLI는 "내가 지금 무엇을 하고 있는지" 한눈에 보이지 않습니다. git status, git log, git diff, git branch를 따로따로 실행해야 전체 상황을 파악할 수 있습니다. lazygit은 이 모든 정보를 한 화면에 동시에 보여줍니다.

화면 구성

lazygit을 실행하면 다음과 같은 5개 패널이 보입니다.

+--------------+------------------+
| Status       | Files            |
+--------------+------------------+
| Branches     | Commits          |
+--------------+ Diff             |
| Stash        |                  |
+--------------+------------------+
  • Status: 현재 브랜치, 원격 동기화 상태
  • Files: 변경된 파일 목록 (스테이지 가능)
  • Branches: 로컬/원격 브랜치
  • Commits: 최근 커밋 (커서로 이동 가능)
  • Stash: 임시 저장 변경사항
  • Diff: 선택된 항목의 변경 내용

핵심 키 바인딩

동작
space파일 스테이지/언스테이지
c커밋 (메시지 입력 창 열림)
Ppush
ppull
sstash
r인터랙티브 rebase 시작
zundo (직전 동작 되돌리기)
?도움말

특히 r (인터랙티브 rebase)이 강력합니다. 일반 Git에서는 git rebase -i HEAD~5를 친 다음 텍스트 에디터에서 pick/squash/edit를 직접 입력해야 합니다. lazygit에서는 커밋을 선택하고 s를 누르면 즉시 squash, e를 누르면 edit, d를 누르면 drop입니다.

설정 파일

~/.config/lazygit/config.yml에 설정합니다.

gui:
  showFileTree: true
  showRandomTip: false
  language: en
git:
  autoFetch: true
  paging:
    colorArg: always
    pager: delta --paging=never
  commit:
    signOff: true
keybinding:
  universal:
    quit: q

특히 paging.pager에 delta를 지정하면 diff가 컬러풀하게 표시됩니다.

누가 쓰는가

토스(Toss), 카카오, Mercari, 메르카리 — SSH 서버에서 작업하는 인프라/플랫폼 엔지니어 다수가 lazygit을 기본 도구로 씁니다. VS Code 같은 GUI 에디터를 쓰는 사람도 큰 인터랙티브 rebase가 필요할 때 lazygit을 띄웁니다.

한계

  • 매우 큰 저장소(100만 커밋 이상)에서 시작 시간이 길어집니다
  • Windows에서는 일부 색상/유니코드가 깨질 수 있습니다
  • 마우스가 잘 안 됩니다 (TUI의 특성)

4. gitui — Rust TUI 대안

lazygit과의 차이

gitui는 Stephan Dilly가 만든 Rust 기반 TUI Git 클라이언트입니다. 2020년에 처음 공개되었고, lazygit과 비슷한 5패널 UI를 가집니다. 가장 큰 차이는 두 가지입니다.

항목lazygitgitui
언어GoRust
백엔드git CLI 호출gitoxide / libgit2 직접
시작 속도보통매우 빠름
메모리보통적음
인터랙티브 rebase강력기본만

gitui의 핵심은 속도입니다. git CLI를 fork/exec 하지 않고, Rust 네이티브 라이브러리로 직접 .git을 읽어 들이므로, 거대한 저장소에서도 거의 즉시 응답합니다.

단축키

lazygit과 키 매핑이 비슷하지만 약간 다릅니다.

동작
1-5패널 이동
s스테이지
u언스테이지
c커밋
t태그
g로그
h도움말

누가 쓰는가

리눅스 커널 개발자, Rust 커뮤니티, 그리고 단순히 lazygit의 인터랙티브 rebase가 필요 없는 사람들. 회사에서 Mercari의 일부 인프라 엔지니어가 가벼움 때문에 gitui를 선호한다는 인터뷰가 있습니다.

언제 쓰지 말아야 하나

  • 복잡한 인터랙티브 rebase가 자주 필요할 때 (lazygit이 우월)
  • Hooks, submodule, LFS 통합이 깊이 필요할 때

5. gh CLI (GitHub) + glab (GitLab) + tea CLI (Gitea)

호스팅 서비스 CLI의 등장

Git 자체는 분산형이지만, 실제로 거의 모든 팀은 GitHub, GitLab, Gitea 같은 중앙 호스팅을 씁니다. 그런데 PR 만들기, 리뷰, 이슈 관리는 모두 웹에서 해야 한다는 게 불편했습니다. 그래서 호스팅 서비스마다 공식 CLI가 나왔습니다.

도구호스팅언어설치
ghGitHubGobrew install gh
glabGitLabGobrew install glab
teaGiteaGobrew install tea

gh CLI 핵심 명령

# PR 생성 (현재 브랜치에서)
gh pr create --title "feat: add user search" --body "Closes #123"

# PR 목록
gh pr list --author "@me" --state open

# PR 체크아웃
gh pr checkout 456

# PR 리뷰
gh pr review 456 --approve

# 이슈 만들기
gh issue create --title "Bug in login" --label bug

# GitHub Actions 워크플로 보기
gh run list
gh run view 12345 --log

특히 gh pr checkout 456이 강력합니다. 이는 다음과 동등합니다.

git fetch origin pull/456/head:pr-456
git switch pr-456

PR을 로컬에서 검토할 때 필수입니다.

gh API — 일반화된 GitHub API 호출

gh api repos/{owner}/{repo}/pulls/123/comments

위 명령은 PR 코멘트를 JSON으로 가져옵니다. 다만 owner와 repo는 실제 값으로 바꿔서 호출해야 합니다.

glab — GitLab 버전

GitLab은 GitHub보다 더 풍부한 CI/CD를 가지고 있어서, glab는 다음을 추가로 지원합니다.

glab ci view              # 현재 파이프라인 시각화
glab ci status            # 실행 상태
glab ci trace             # 라이브 로그
glab snippet create file.py

tea — Gitea

Gitea는 자체 호스팅 GitLab/GitHub 대체재입니다. 사내 폐쇄망에서 흔히 씁니다.

tea login add --url https://gitea.example.com
tea issue create --title "..." --description "..."
tea pulls list

한국 / 일본 사례

  • 토스: GitHub Enterprise + gh CLI 적극 사용
  • 카카오: 일부 팀 GitLab + glab
  • 메르카리: GitHub + gh CLI 가 표준

6. jj (Jujutsu, Google) — Git-compatible 새 모델

누가 만들었는가

jj(Jujutsu)는 Martin von Zweigbergk이 Google에서 시작한 새로운 버전 관리 시스템입니다. 2020년 초에 공개되었고, Google 내부에서도 일부 사용 중입니다. 가장 큰 특징은 Git-compatible이라는 점 — jj가 만든 저장소는 GitHub에 push할 수 있고, Git 저장소를 jj로 다룰 수 있습니다.

Git과의 핵심 차이

jj는 Git의 데이터 모델을 다음과 같이 재해석합니다.

개념Gitjj
작업 트리 변경명시적으로 스테이지/커밋자동으로 working copy commit에 누적
브랜치강조됨 (HEAD 위치)약화됨 (선택 사항)
충돌즉시 해결해야 함저장된 상태로 유지 가능
히스토리 편집rebase, amend, reset모든 변경이 동등하게 편집 가능
식별자40자 SHAchange ID + commit ID

Working Copy as Commit

jj의 가장 충격적인 차이는 작업 트리 자체가 커밋이라는 점입니다.

Git에서는: 파일을 수정 → git add (스테이지) → git commit (저장) jj에서는: 파일을 수정 → 자동으로 현재 working copy commit이 업데이트됨

# jj 초기화 (기존 Git 저장소에서)
jj git init --colocate

# 변경 사항 보기 (git status에 해당)
jj status

# 새 변경 만들기 (git commit -m 에 해당하지 않음)
jj new -m "WIP: trying new approach"

# 변경 메시지 수정
jj describe -m "feat: add user authentication"

# 로그
jj log

Change ID — Commit ID와 분리

Git에서 git commit --amend 또는 rebase를 하면 SHA가 바뀝니다. 그래서 다른 사람이 그 커밋을 참조하던 것이 깨집니다.

jj에서는 모든 변경에 change ID(영구)와 commit ID(snapshot)가 있습니다. amend, rebase를 해도 change ID는 유지되고, commit ID만 바뀝니다.

jj log
@ kzqp 0a1b2c3 main | feat: user search
o mnop 4d5e6f7 fix: login bug
o qrst 8g9h0i1 initial commit

위에서 kzqp가 change ID, 0a1b2c3이 commit ID입니다.

충돌을 미루기

Git의 rebase 도중 충돌이 나면 진행이 멈춥니다. jj는 충돌을 저장된 상태로 유지합니다. 즉 rebase를 끝까지 진행한 후, 나중에 충돌만 따로 해결할 수 있습니다.

누가 쓰는가

  • Google 사내 일부 팀
  • Rust 커뮤니티 일부
  • "Git의 다음 세대"를 시험해 보고 싶은 얼리 어답터

언제 쓰지 말아야 하나

  • 팀 전체가 Git에 익숙한 경우 (인지 부담)
  • Git GUI/TUI 통합이 필수인 경우 (jj 통합은 아직 부족)
  • 안정성이 절대적으로 중요한 프로덕션 (아직 1.0 미만)

7. Sapling (Meta) — Mercurial-based 사내

배경

Meta(구 Facebook)는 자사의 거대 모노레포(수억 라인) 때문에 Git이 성능적으로 부족하다고 판단했고, 오랫동안 Mercurial을 기반으로 한 내부 도구를 써왔습니다. 2022년 11월, 이를 Sapling이라는 이름으로 오픈소스화했습니다.

Git과의 차이

Sapling은 Mercurial UX 위에 Meta의 확장을 더한 시스템입니다.

항목GitSapling
기반자체 모델Mercurial 변형
브랜치 모델명시적 브랜치익명 브랜치
인덱스staging area없음
큰 저장소느림빠름 (EdenFS 가상 파일 시스템)
GitHub 통합네이티브sl pr 명령

sl 명령어

Sapling의 CLI는 sl입니다.

sl clone https://github.com/facebook/sapling
cd sapling
sl status
sl commit -m "feat: ..."
sl push
sl pr submit       # GitHub PR 만들기

특히 sl pr submit이 흥미로운데, 이는 현재 커밋 스택을 GitHub PR 시리즈로 자동 분리해 줍니다. 즉 5개의 커밋이 있으면 5개의 연결된 PR이 만들어집니다 (Stacked PRs).

EdenFS

Sapling의 차별점은 EdenFS라는 가상 파일 시스템입니다. 클론 시 모든 파일을 다운로드하지 않고, 접근할 때마다 lazy하게 가져옵니다. 100GB 저장소를 1분에 "클론"하는 것이 가능합니다.

누가 쓰는가

  • Meta 사내 (메인 도구)
  • 일부 거대 모노레포 사용자
  • "Git 외의 대안"을 시험해 보는 사람

한계

  • GitHub 외 호스팅과의 통합 부족
  • 학습 곡선 (Mercurial 명령어를 새로 배워야 함)

8. GitButler — Tauri 가상 브랜치 GUI

무엇을 푸는가

GitButler는 Scott Chacon (전 GitHub 공동 창업자, "Pro Git" 책 저자)이 2023년 시작한 새로운 Git GUI입니다. Tauri(Rust + 웹뷰)로 만들어졌고, 가장 큰 특징은 **가상 브랜치(Virtual Branches)**입니다.

가상 브랜치 개념

전통적인 Git 워크플로우에서, 동시에 여러 기능을 작업하려면 다음 중 하나를 합니다.

  1. 한 브랜치에서 작업하고, 커밋할 때 나누기 (어려움)
  2. 작업 중간에 stash → 다른 브랜치로 switch → 작업 → 돌아오기 (귀찮음)
  3. worktree로 여러 디렉토리 운영 (디스크 사용)

GitButler는 4번째 방법을 제공합니다. 하나의 작업 트리 안에서 여러 가상 브랜치가 동시에 존재합니다. 파일 변경 사항을 드래그해서 어느 가상 브랜치에 속할지 결정하고, 각 가상 브랜치는 독립적으로 PR로 push할 수 있습니다.

화면

GitButler GUI는 다음과 같이 보입니다.

+-----------------+ +-----------+ +-----------+
| 변경된 파일       | | 가상 브랜치 A | | 가상 브랜치 B |
| - file1.ts      | | + file1.ts | | + file3.ts |
| - file2.ts      | | + file2.ts | |            |
| - file3.ts      | |            | |            |
+-----------------+ +-----------+ +-----------+

각 파일을 드래그해서 어느 브랜치에 넣을지 정합니다.

누가 쓰는가

  • 여러 기능을 동시에 작업하는 개인 개발자
  • 자주 context switching 해야 하는 풀스택 개발자
  • 큰 PR을 작은 단위로 분리하고 싶은 사람

한계

  • 팀 워크플로우에 깊이 통합되지 않음
  • 리뷰어 입장에서는 결국 일반 PR로 보임
  • Git 본질을 가린다는 비판도 있음

9. Fork / Sublime Merge / GitKraken / GitHub Desktop — GUI

4대 데스크톱 GUI 비교

도구가격플랫폼특징
Fork약 $50 (일회성)Mac, Win가볍고 빠름, conflict resolver 우수
Sublime Merge$99 (일회성)Mac, Win, LinuxSublime Text 팀 제작, 매우 빠름
GitKraken$60-100/년 (구독)Mac, Win, Linux화려한 UI, 팀 협업 기능
GitHub Desktop무료Mac, WinGitHub 친화적, 기본 기능

Fork

Mac 사용자에게 가장 인기 있는 GUI입니다. 시작 시간이 1초 이내고, 화려한 그래프 시각화, 인터랙티브 rebase를 드래그 앤 드롭으로 합니다. Conflict resolver가 특히 우수합니다.

Sublime Merge

Sublime Text를 만든 Jon Skinner 팀의 작품입니다. 압도적인 속도가 장점이고, 큰 저장소에서도 매끄럽게 작동합니다. CLI와 거의 1:1 매칭되어, Git 내부를 이해하는 사람에게 잘 맞습니다.

GitKraken

가장 화려한 UI를 가졌습니다. 브랜치 그래프, GitFlow 시각화, Issue Board 통합 등이 있습니다. 단점은 무겁고 구독 모델입니다.

GitHub Desktop

GitHub의 공식 데스크톱 클라이언트입니다. 가장 단순하고, 입문자에게 적합합니다. 다만 인터랙티브 rebase, cherry-pick 같은 고급 기능이 약합니다.

누가 무엇을 쓰는가

  • Fork: Mac 사용 시니어 개발자, 디자이너 협업 환경
  • Sublime Merge: Linux + Sublime Text 사용자
  • GitKraken: 팀 협업이 중요한 회사 (시각적 그래프 공유)
  • GitHub Desktop: 입문자, 비개발자 (PM, 디자이너 등)

10. Tower / SmartGit — 그 외 GUI

Tower

Tower는 fournova GmbH가 만든 Mac/Win GUI로, 2010년부터 있었습니다. 매우 정제된 UI, 깊은 Git 통합, 학습 도구로서의 가이드가 강점입니다. 가격은 약 $69/년입니다.

특징:

  • Git의 모든 명령에 시각적 매핑
  • Pull request 워크플로우 직접 지원 (GitHub, GitLab, Bitbucket)
  • 학습 가이드 (Git 입문자를 위한 단계별 튜토리얼)
  • 충돌 해결 UI 우수

SmartGit

SmartGit은 독일의 syntevo GmbH가 만든 Java 기반 크로스 플랫폼 GUI입니다. 윈도우/맥/리눅스 모두에서 동일하게 작동하고, 매우 깊은 Git 기능 지원이 강점입니다.

특징:

  • Mercurial과 Subversion 동시 지원
  • Pull request 워크플로우
  • 강력한 머지 도구 내장
  • 비상업적 사용은 무료

누가 쓰는가

  • Tower: Mac 디자인 회사, 입문자 + 시니어 혼합 팀
  • SmartGit: 윈도우 중심의 기업 환경, Java 개발팀

11. magit (Emacs) — Git의 마술

소개

magit은 Jonas Bernoulli가 2008년에 시작한 Emacs용 Git 인터페이스입니다. 많은 사람이 "Git을 진정으로 이해하려면 magit을 써야 한다"고 말할 정도로 강력합니다.

핵심 철학은 다음과 같습니다.

  1. Git의 모든 명령을 키 시퀀스로 노출
  2. 각 화면에서 가능한 모든 동작을 popup으로 보여줌
  3. 키 한 번으로 가장 자주 쓰는 동작 실행

화면 예시

Emacs에서 M-x magit-status를 실행하면 다음과 같이 나타납니다.

Head:     main feat: add user search
Push:     origin/main

Unstaged changes (3)
modified   src/components/Search.tsx
modified   src/lib/api.ts
new file   src/utils/debounce.ts

Recent commits
abc1234 main feat: add user search (45 minutes ago)
def5678      fix: login bug (2 hours ago)

여기서 s를 누르면 스테이지, c를 누르면 커밋 popup이 열립니다.

커밋 popup

c를 누르면 다음과 같은 popup이 나타납니다.

Commit
 -a Stage all modified  
 -e Allow empty
 -v Show diff           
 -n No verify

 c Commit
 e Extend
 w Reword
 a Amend
 f Fixup

각 옵션을 토글하고, 마지막에 c를 다시 누르면 커밋이 실행됩니다.

누가 쓰는가

  • Emacs 사용자 (당연)
  • 함수형 프로그래밍 커뮤니티 (Clojure, Haskell, Lisp)
  • "키보드만으로 모든 것을 하고 싶은" 시니어 개발자

한계

  • Emacs 학습이 선행되어야 함
  • 가장 가파른 학습 곡선

12. vim-fugitive (Vim) — Vim Git 표준

소개

vim-fugitive는 Tim Pope가 2009년에 만든 Vim용 Git 플러그인입니다. Vim 사용자라면 거의 모두가 씁니다.

핵심 명령

Vim 안에서 다음과 같이 사용합니다.

:Git status           " git status 출력
:Git add %            " 현재 파일 스테이지
:Git commit           " 커밋 메시지 입력 창 열림
:Git push
:Git blame            " 현재 파일의 blame 보기
:Gdiffsplit           " 현재 파일 diff를 분할 창으로
:GBrowse              " GitHub/GitLab에서 현재 줄 보기

특히 :Git blame과 :Gdiffsplit이 강력합니다. blame 결과에서 커서를 올리고 enter를 치면, 해당 커밋의 diff가 새 창에서 열립니다.

vim-rhubarb

vim-fugitive와 함께 자주 쓰이는 vim-rhubarb (Tim Pope의 또 다른 플러그인)는 GitHub 통합을 추가합니다. :GBrowse가 GitHub URL로 현재 줄을 엽니다.

누가 쓰는가

  • Vim/Neovim 사용자
  • 키보드 중심 개발자
  • 서버에서 SSH로 자주 작업하는 사람

13. git-cliff (Rust) — changelog 생성

소개

git-cliff는 Orhun Parmaksız가 만든 Rust 기반 changelog 생성 도구입니다. 커밋 메시지를 분석해서 CHANGELOG.md를 자동으로 만들어 줍니다.

동작 원리

git-cliff는 다음을 가정합니다.

  1. 커밋 메시지가 Conventional Commits 형식을 따름 (feat:, fix:, chore: 등)
  2. 태그가 SemVer 형식 (v1.2.3)

이 두 가정 하에, 태그 사이의 커밋을 분류하여 changelog를 만듭니다.

사용 예

# 설치
brew install git-cliff

# 모든 태그에 대한 changelog 생성
git cliff -o CHANGELOG.md

# 다음 릴리스를 위한 changelog
git cliff --unreleased --tag v1.2.0

설정

cliff.toml에 설정합니다.

[changelog]
header = "# Changelog\n"
body = """
## [{{ version }}] - {{ timestamp | date(format="%Y-%m-%d") }}

{% for group, commits in commits | group_by(attribute="group") %}
### {{ group | upper_first }}
{% for commit in commits %}
- {{ commit.message | upper_first }}
{% endfor %}
{% endfor %}
"""

[git]
conventional_commits = true
filter_unconventional = true
commit_parsers = [
  { message = "^feat", group = "Features"},
  { message = "^fix", group = "Bug Fixes"},
  { message = "^doc", group = "Documentation"},
  { message = "^perf", group = "Performance"},
  { message = "^refactor", group = "Refactor"},
]

누가 쓰는가

  • Rust 프로젝트 (Cargo 친화)
  • Conventional Commits를 엄격히 따르는 팀
  • 릴리스 자동화를 원하는 팀

semantic-release와의 비교

semantic-release(JS 생태계)는 changelog 생성 + 버전 번호 결정 + npm publish까지 자동화합니다. git-cliff는 changelog 생성에만 집중합니다.

14. nbdime / git-lfs / git-annex / git-filter-repo — 그 외 유틸

nbdime — Jupyter 노트북 diff

Jupyter 노트북(.ipynb)은 JSON 형식이라서 일반 git diff로 보면 알아볼 수 없습니다. nbdime은 이를 사람이 읽을 수 있는 diff/merge UI로 보여줍니다.

pip install nbdime
nbdime config-git --enable --global

git diff notebook.ipynb   # 이제 nbdime이 자동으로 동작

git-lfs — 큰 파일

100MB 이상의 파일을 Git에 직접 넣으면 저장소가 빠르게 비대해집니다. Git LFS(Large File Storage)는 큰 파일을 별도 저장소에 두고, .git에는 포인터만 둡니다.

git lfs install
git lfs track "*.psd"
git add .gitattributes
git add design.psd
git commit -m "design files"

git-annex

git-annex는 더 극단적인 큰 파일 관리 도구입니다. 파일의 콘텐츠를 다양한 저장소(S3, rsync, USB 등)에 분산 저장하고, Git은 메타데이터만 추적합니다. 과학 데이터, 영상 같은 거대 파일에 씁니다.

git-filter-repo — 히스토리 재작성

과거에는 git filter-branch로 히스토리를 재작성했지만, 매우 느리고 위험했습니다. git-filter-repo(Elijah Newren 작)는 안전하고 빠른 대체재입니다.

# 특정 파일을 히스토리에서 완전 제거
git filter-repo --path secrets.env --invert-paths

# 특정 경로만 남기기
git filter-repo --path src/

# 이메일 주소 변경
git filter-repo --email-callback 'return email.replace(b"@old.com", b"@new.com")'

자격 증명 유출 사고 후 정리, 모노레포 분리 등에 필수입니다.

15. Hooks — pre-commit / husky / lefthook / commitlint / conventional commits / semantic-release

Git Hooks의 한계

Git 자체에는 .git/hooks 디렉토리에 셸 스크립트를 두면 자동 실행되는 hook 시스템이 있습니다. 하지만 두 가지 문제가 있습니다.

  1. .git/hooks는 저장소에 들어가지 않음 (각자 설치해야 함)
  2. 셸 스크립트만으로 복잡한 로직을 짜기 어려움

그래서 hook 프레임워크가 나왔습니다.

pre-commit (Python)

pre-commit은 Anthony Sottile이 만든 Python 기반 hook 프레임워크입니다. .pre-commit-config.yaml에 hook들을 선언하고, pre-commit install로 .git/hooks에 자동 설치합니다.

repos:
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v4.5.0
    hooks:
      - id: trailing-whitespace
      - id: end-of-file-fixer
      - id: check-yaml
  - repo: https://github.com/psf/black
    rev: 24.3.0
    hooks:
      - id: black
  - repo: https://github.com/astral-sh/ruff-pre-commit
    rev: v0.3.0
    hooks:
      - id: ruff

husky (JS)

husky는 JavaScript 생태계의 hook 도구입니다. package.json과 통합됩니다.

npm install --save-dev husky
npx husky init

이렇게 하면 .husky/pre-commit 스크립트가 만들어지고, 그 안에 npm run lint 같은 명령을 넣을 수 있습니다.

lefthook (Go)

lefthook은 Evil Martians가 만든 Go 기반 hook 도구입니다. husky보다 빠르고, 병렬 실행을 지원합니다.

pre-commit:
  parallel: true
  commands:
    lint:
      glob: "*.{js,ts}"
      run: npx eslint {staged_files}
    test:
      run: npm test

commitlint + Conventional Commits

Conventional Commits는 커밋 메시지의 형식을 표준화한 명세입니다.

feat: add user search
fix: handle null in login
chore: bump deps
docs: update README
refactor!: rename API endpoint

commitlint은 commit-msg hook에서 메시지가 이 형식을 따르는지 검증합니다.

npm install --save-dev @commitlint/cli @commitlint/config-conventional

semantic-release

semantic-release는 커밋 메시지를 분석해서 다음을 자동화합니다.

  1. 다음 버전 결정 (feat → minor, fix → patch, BREAKING → major)
  2. CHANGELOG.md 생성
  3. Git 태그 생성
  4. npm 패키지 publish
  5. GitHub Release 생성

CI에서 메인 브랜치 push 시마다 실행하면, 사람이 버전을 결정할 필요가 없습니다.

16. Stacked PRs — jj / Graphite / Sapling / GitButler

문제: 큰 PR vs 작은 PR

리뷰 효율을 위해 PR은 작아야 합니다. 하지만 한 기능이 너무 커서 작은 PR로 나누면, 의존 관계가 생깁니다 (PR-2가 PR-1을 base로 함).

전통적인 GitHub PR UX는 이런 의존 PR을 잘 다루지 못합니다. PR-1이 머지되면 PR-2의 base가 바뀌어야 하고, PR-1에 리뷰 코멘트가 달리면 PR-2까지 rebase해야 합니다.

Stacked PR 도구

도구접근
Graphite (CLI: gt)GitHub PR을 스택으로 관리하는 외부 도구
Sapling (sl)스택이 1급 시민, sl pr submit으로 자동 생성
jjchange ID로 인해 rebase 후에도 식별자 유지
GitButler가상 브랜치로 스택 시각화

Graphite (gt)

Graphite는 Tomas Reimers가 만든 회사이자 도구입니다. CLI gt를 사용합니다.

gt create -m "feat: part 1"
# 코드 작성, 자동 스테이지/커밋
gt create -m "feat: part 2"
# 또 코드 작성
gt submit         # 모든 스택을 GitHub PR로 푸시

PR-2가 PR-1을 자동으로 base로 가지고, PR-1이 머지되면 PR-2의 base가 자동으로 메인으로 바뀝니다.

누가 쓰는가

  • Meta, Google 같은 큰 회사 (Sapling/jj)
  • 빠르게 움직이는 스타트업 (Graphite)
  • 풀스택 1인 개발 (GitButler)

17. 한국 / 일본 — 토스 / 카카오 / 메르카리 git workflow

토스의 Git workflow

토스는 GitHub Enterprise를 메인 호스팅으로 씁니다. 핵심 워크플로우는 다음과 같습니다.

  1. main 브랜치는 보호 (PR + 2명 승인 + CI 통과 필수)
  2. feature 브랜치 — 짧게 (보통 2-3일 수명)
  3. Squash merge가 기본 (히스토리 단순화)
  4. PR 템플릿에 "체크리스트" 강제 (배포 영향, 롤백 가능성, 모니터링)
  5. CI는 GitHub Actions + 자체 빌드 시스템

도구 사용:

  • 시니어 백엔드: 주로 lazygit + gh CLI
  • 프론트엔드: VS Code Git + gh CLI
  • 일부 SRE: vim-fugitive

카카오의 Git workflow

카카오는 사업부마다 다르지만, 공통적으로 GitHub Enterprise 또는 사내 GitLab을 씁니다. 카카오 페이/뱅크는 GitHub, 카카오 광고/검색은 GitLab을 쓰는 경향이 있습니다.

특징:

  • Trunk-based development가 점점 늘어남 (main에 직접 작은 PR 머지)
  • Release 브랜치는 정해진 시점에만 만듦
  • 한국어 커밋 메시지가 허용 (대신 PR 제목은 명확하게)
  • pre-commit hook으로 lint, secret 검사

메르카리의 Git workflow

메르카리(Mercari)는 일본 기업이지만 영어가 공식 언어이고, GitHub을 사용합니다.

특징:

  • Conventional Commits 강제 (commitlint + husky)
  • semantic-release로 자동 버전 관리
  • Microservices가 많아 monorepo + multi-repo 혼합
  • PR 리뷰 SLA를 KPI로 관리 (24시간 내 첫 리뷰)
  • Sapling을 일부 팀에서 시험 도입 중

한일 공통 트렌드

  1. Lazygit / Sublime Merge가 시니어 사이에서 빠르게 확산
  2. gh CLI가 PR 검토에 필수
  3. pre-commit + commitlint이 사실상 표준
  4. Stacked PR은 아직 일부 얼리 어답터만

18. 누가 무엇을 골라야 하나 — 입문 / TUI 좋아함 / 모노레포 / 큰 팀

입문자

  • GUI: GitHub Desktop (가장 단순, 무료)
  • CLI: git + gh CLI
  • 학습: Tower의 가이드, Pro Git 책, magit이 아닌 일반 도구부터

터미널/SSH 중심 사용자

  • 메인: lazygit
  • 빠름 우선: gitui
  • 보조: gh CLI, vim-fugitive (편집기로 Vim 쓸 때)

모노레포 운영자

  • Git 자체: sparse-checkout + partial clone 필수
  • 대안 시도: Sapling, jj
  • 대용량 파일: git-lfs, git-annex
  • 히스토리 정리: git-filter-repo

큰 팀 / 회사 워크플로우

  • 호스팅: GitHub Enterprise + gh CLI
  • Hook: pre-commit + commitlint
  • 릴리스: semantic-release 또는 git-cliff
  • PR 스택: Graphite 또는 Sapling

1인/소규모 풀스택

  • GUI: Fork (Mac) 또는 Sublime Merge (크로스 플랫폼)
  • 가상 브랜치: GitButler 시도해볼 만함
  • changelog: git-cliff

Emacs / Vim 사용자

  • Emacs: magit (사실상 강제)
  • Vim: vim-fugitive + vim-rhubarb

다음 세대를 시험해 보고 싶은 사람

  • jj: Git-compatible이라 점진 도입 가능
  • Sapling: 거대 모노레포에서 진가
  • GitButler: 풀스택 1인 작업에서

마지막 조언

도구는 도구일 뿐, Git 자체를 이해하는 것이 가장 중요합니다. 어떤 도구를 쓰든 다음 개념은 머릿속에 있어야 합니다.

  1. 커밋 = 스냅샷 + 부모 참조
  2. 브랜치 = 커밋을 가리키는 포인터
  3. HEAD = 현재 작업 위치 포인터
  4. 인덱스(staging area) = 다음 커밋을 준비하는 공간
  5. push/pull/fetch가 무엇을 옮기는지

이걸 모른 채로 lazygit/magit/Sapling을 쓰면, 결국 어딘가에서 막힙니다.

19. 참고 / References