
두 개의 터미널, 한 잔의 차: Git Worktrees를 활용한 Claude Code 병렬 작업
요약
Git Worktrees를 활용하여 Claude Code의 여러 세션을 병렬로 실행하고 관리하는 효율적인 워크플로우를 소개합니다. 각 작업마다 독립된 디렉토리와 브랜치를 할당함으로써 코드 충돌 없이 안전하게 멀티태스킹을 수행할 수 있습니다.
핵심 포인트
- Git Worktrees를 통해 동일 저장소 내 독립된 작업 디렉토리 생성 가능
- Claude Code 세션별로 브랜치를 격리하여 병렬 작업 수행
- Stash나 브랜치 전환 없이 여러 작업을 동시에 검토 및 진행 가능
- 작업당 하나의 폴더를 할당하여 컨텍스트 혼란 방지
처리해야 할 작업이 산더미처럼 쌓여 있었고, 이번만큼은 티켓을 하나씩 붙잡고 늘어지고 싶지 않았습니다.
Claude Code가 여러 세션을 병렬로 실행할 수 있다는 것을 알고 있었기에, 제 첫 번째 생각은 여러 에이전트를 동시에 서로 다른 작업에 풀어놓는 것이었습니다.
하지만 곧 실제적인 문제에 부딪혔습니다. 저는 제가 읽지 않은 코드는 머지(merge)하지 않습니다.
저는 diff를 제대로 살펴보는 것을 좋아하며, 최근에는 git-lrc를 사용하고 있습니다.
그래서 질문이 생겼습니다. 어떻게 하면 모든 변경 사항이 단일 브랜치에 검토 불가능한 혼란 상태로 쌓이지 않게 하면서, 여러 세션이 동시에 작업하게 할 수 있을까요?
단일 체크아웃(checkout) 상태에서는 정의상 모든 것이 순차적이기 때문입니다: 작업 → 리뷰 → 커밋(commit) → 푸시(push) → 새 브랜치 생성 → 이 모든 과정을 다시 시작.
이전 작업이 끝나기 전에는 다음 작업을 시작할 수 없습니다.
그리고 작업 중간에 무언가 방해를 받으면, 예전의 습관대로 돌아가게 됩니다: stash, main 체크아웃, 브랜치 생성, 수정, 다시 전환, stash pop, 그리고 내가 보지 않는 사이에 빌드가 다시 돌아가지 않기를 기도하기.
그때 git worktrees가 떠올랐습니다. 그리고 Claude가 이에 대해 정말 좋은 문서를 가지고 있다는 사실을 알게 되었습니다.
아이디어가 즉시 떠올랐습니다.
작업당 하나의 폴더, 각각은 자신만의 브랜치에서, 각각은 자신만의 Claude 세션과 함께.
저의 규칙은 매우 단순했습니다: 브랜치 이름 = 세션 이름 = 해당 작업의 용도.
그렇게 하면 언제든 원하는 작업으로 점프하거나 몇 시간 뒤에 돌아와도, 무엇이 무엇인지 기억하기 위해 눈을 가늘게 뜨며 고민할 필요가 없습니다.
그래서 저는 자리에 앉아 제가 사용하는 작은 TUI 파일 브라우저인 peektea를 통해 실제로 이를 익혔습니다.
짧은 글을 작성해 보았습니다. 차 한 잔 대접할게요 xD
worktree란 실제로 무엇인가
일반적인 clone은 하나의 브랜치에 연결된 하나의 작업 디렉토리(working directory)를 제공합니다.
worktree는 동일한 저장소(repo)를 위해, 다른 브랜치에 배치된 두 번째 작업 디렉토리(working directory)입니다.
두 폴더는 하나의 .git (파일)을 공유하며 동일한 히스토리와 동일한 원격(remote) 저장소를 가지지만, 파일들은 완전히 독립적입니다.
한 곳에서 수정, 빌드 또는 실행을 수행해도 다른 곳은 전혀 눈치채지 못합니다.
그 격리(isolation)가 바로 핵심입니다.
Claude가 터미널 A에서 하나의 기능을 연결하는 동안 사용자는 터미널 B에서 관련 없는 무언가를 수정할 수 있으며, 두 세션 중 어느 것도 서로의 파일을 덮어쓸 수 없습니다. 스태싱(stashing)도 필요 없고, 차를 쏟을 일(실수할 일)도 없습니다.
모든 것을 결정하는 단 하나의 규칙
하나의 worktree는 정확히 하나의 저장소에 속하며, 하나의 브랜치는 한 번에 정확히 하나의 worktree에만 존재할 수 있습니다. 따라서 계산은 간단합니다: 병렬 기능 하나당 하나의 worktree. peektea에서 두 개의 기능을 작업한다면 → 두 개의 worktree → 두 개의 터미널 → 두 개의 세션이 됩니다.
우리의 두 가지 "티켓"
저는 peektea에 서로 영향을 주지 않아 병렬로 진행하기 이상적인 두 개의 이슈(issue)를 생성했습니다:
| 기능 | 이슈 | 내용 |
|---|---|---|
| A | #2 | 단축키 복사: y는 강조된 경로를 복사하고, Y는 파일 내용을 복사합니다 |
| B | #3 | 파일 이동: x는 항목을 잘라내고, v는 현재 디렉토리에 붙여넣습니다 |
두 기능 모두 master 브랜치에서 파생되었습니다.
둘 다 키 바인딩(keybindings)을 추가하지만 서로 다른 코드 경로에 존재하며, 이는 정확히 worktree가 만들어진 목적, 즉 "각각 별도의 PR로 처리될 수 있으면서 동시에 완료될 수 있는" 작업의 전형입니다.
저의 메인 체크아웃(checkout) 위치는 ~/pers/peektea입니다.
worktree들은 바로 그 옆에 위치하게 될 것입니다.
Go: 각 터미널 하나씩
git worktree add는 저장소의 어느 기존 체크아웃(checkout) 위치에서든 실행할 수 있습니다. 새로운 워크트리(worktree)를 만들기 위해 반드시 특정 워크트리
시각적으로 보면, 두 기능이 각자의 컵에 담겨 있다가 병합(merge)할 때만 만납니다:
커밋(commit)하고 푸시(push)하는 것은 일반적인 절차이며, 첫 번째 푸시는 단순히 업스트림(upstream)을 설정할 뿐입니다:
cd ~/pers/peektea-copy
git add -A
git commit -m "feat: y/Y to copy path and file contents (#2)"
...
앱이 실제로 실행되는 곳 (Where the app actually runs)
여기서 Go TUI(Text User Interface)는 웹 스택에 비해 정말 큰 장점입니다.
peektea는 단일 바이너리이며, 프런트엔드도, 백엔드도 없고, 충돌할 포트도 없습니다.
작업트리(worktree) 안에서 빌드하고 로컬 바이너리를 실행합니다. 왜냐하면 메인 트리의 코드가 아닌, 당신이 수정한 코드를 테스트하는 것이기 때문입니다:
cd ~/pers/peektea-move
make build # worktree 내의 ./peektea를 빌드합니다
./peektea # 당신의 변경 사항이 적용된 버전을 실행합니다
Claude와 함께 반복 작업(iterate)하는 동안 라이브 리로드(live reload)가 필요하신가요? make start는 모든 .go 파일 저장 시 재빌드됩니다:
make start # air가 감지하고 ./peektea를 재빌드합니다
그리고 서버가 없기 때문에, 포트 충돌이나 프록시 조작 없이, 두 모든 작업트리에서 make start를 문제없이 실행할 수 있습니다. 중단하고 다시 시작할 필요가 없습니다.
TUI는 단순히 구동된 터미널을 읽어들일 뿐입니다.
아무튼.
정리하기 (Cleaning up)
기능이 병합되면, 삭제하려는 폴더 안에서가 아니라 다른 체크아웃(checkout) 위치에서 해당 작업트리를 제거해야 합니다:
cd ~/pers/peektea
git worktree list # 모든 목록을 확인합니다
git worktree remove ~/pers/peektea-move
# 워크트리(worktree)가 dirty 상태(변경 사항이 있는 상태)이면 거부됩니다. 변경 사항을 버리려면 --force를 추가하세요.
...
git worktree remove는 의도적으로 브랜치를 남겨둔다는 점에 유의하세요. 덕분에 폴더를 삭제한다고 해서 병합되지 않은 작업 내용이 실수로 날아가는 일을 방지할 수 있습니다.
브랜치는 의도적으로 별도로 삭제됩니다. 마지막 한 방울까지 예의를 갖추는 셈이죠.
"하지만 Claude Code에는 --worktree 옵션이 있는데…"
맞습니다! claude --worktree feature-x를 실행하면 워크트리(worktree)를 생성하고 즉시 세션으로 진입하므로, 빠른 스파이크(spike, 개념 검증) 작업에 완벽합니다.
하지만 실제 티켓(ticket) 작업을 할 때는 여전히 두 가지 이유로 수동 git worktree add를 사용합니다.
- 브랜치 이름이 제가 원하는 정확한 이름(
copy-path-and-contents)이 아니라worktree-feature-x로 지정됩니다. origin/HEAD(여기서는 어차피master)로부터 브랜치를 생성합니다. 하지만 메인 브랜치가dev나develop인 저장소에서는 잘못된 베이스(base)가 됩니다.
브랜치 이름과 베이스가 모두 정확히 맞아야 할 때는 일반적인 git worktree add가 승리합니다.
한 번 쓰고 버릴 실험용이라면, --worktree가 더 빠르게 차를 따르는 방법입니다.
치트 시트 (Cheat sheet) :D
| 명령어 | 기능 |
|---|---|
git worktree add -b <branch> <dir> <base> | 새로운 브랜치로 새로운 워크트리 생성 |
| ... |
요약 (The takeaway)
워크트리(Worktrees)는 "한 번에 하나의 브랜치만 다룰 수 있다"는 제약을 "터미널 개수만큼 손이 있다"로 바꿔줍니다.
여기에 체크아웃(checkout)마다 이름을 지정한 Claude Code 세션을 결합하면, 병렬 작업은 더 이상 저글링처럼 느껴지지 않고... 마치 두 잔의 차를 동시에 우려내는 것처럼 느껴질 것입니다.
스태시(stash)를 주고받는 번거로움도, 잘못된 브랜치에 커밋하는 실수도, 쏟아진 차도 없습니다.
면책 조항: 이 글은 제가 작성하였으며, 문법 교정 및 가독성 향상을 위해 AI를 사용했습니다.
AI 에이전트는 코드를 빠르게 작성합니다. 하지만 말도 없이 로직을 제거하거나, 동작을 변경하고, 버그를 유발하기도 합니다. 그리고 당신은 종종 운영 환경(production)에서 이를 발견하게 됩니다.
git-lrc가 이 문제를 해결합니다. 이 도구는 git commit에 후킹(hook)하여, 변경 사항이 반영되기 전에 모든 디프(diff)를 검토합니다. 설정에는 60초가 소요되며, 완전히 무료입니다.
모든 피드백과 기여자를 환영합니다! 이 프로젝트는 온라인에서 확인할 수 있으며, 소스 코드(source-available)가 공개되어 있어 누구나 사용할 준비가 되어 있습니다.
⭐ GitHub에서 Star를 눌러주세요:
HexmosTech / git-lrc
Git Commit 시 실행되는 무료 마이크로 AI 코드 리뷰 (Micro AI Code Reviews)
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기




