
Claude Code의 병행 개발은 git worktree에 가깝게 — 여러 개의 클론과 DevContainer를 버린 이유
요약
Claude Code를 사용하여 여러 세션을 동시에 병행 개발할 때, 파일 충돌을 방지하기 위한 최적의 구성으로 git worktree를 제안합니다. 여러 개의 클론이나 DevContainer 방식보다 디스크 사용량이 적고 이력 공유가 용이하여 효율적입니다.
핵심 포인트
- Claude Code 세션 간 파일 경합을 방지하려면 물리적 디렉토리 분리가 필수적임
- git worktree는 .git을 공유하면서 디렉토리를 분리하여 이력 동기화 문제를 해결함
- 여러 개의 클론 방식은 fetch 과정이 번거롭고 이력이 분기되는 단점이 있음
- DevContainer는 격리 수준은 높으나 2~3개 세션 운영 시 기동 비용이 과도함
결론부터 말씀드리겠습니다. 하나의 리포지토리(Repository)에서 여러 개의 Claude Code 세션을 동시에 실행하려면, git worktree로 디렉토리를 나누는 것이 가장 비용이 적게 들고 가장 망가지기 어려운 구성입니다. 검증 환경은 macOS 상의 Claude Code CLI, 리포지토리는 모노레포(Monorepo)가 아닌 단일 패키지, 동시에 실행하는 것은 2~3개 세션이라는 전제하에 판단했습니다. "병행 개발을 어떻게 구성할 것인가"를 두고 여러 개의 클론(Clone)이나 DevContainer를 비교하며 고민하고 있다면, worktree 쪽으로 기울이고 나머지는 버려도 좋다는 것이 이 글의 주장입니다.
병행 개발에서 하고 싶은 것은 하나입니다. 어떤 세션에 기능 추가를 맡기고 있는 동안, 다른 세션에서 리뷰 지적 사항에 대한 수정을 진행하고 싶습니다. 이때 문제가 되는 것은 Claude Code가 편집하는 것이 "작업 디렉토리의 실제 파일"이라는 점입니다. 같은 디렉토리에서 두 개를 실행하면, 한쪽이 작성 중인 파일을 다른 쪽이 읽게 되어 의도하지 않은 차분(Diff)을 포함하게 됩니다. 브랜치(Branch)를 전환할 때마다 git checkout이 실행되면, 실행 중인 세션의 발밑에서 파일이 바뀌게 됩니다. 따라서 물리적으로 디렉토리를 나눌 필요가 있습니다.
나누는 방법의 후보는 4가지를 검토했습니다. 기각 이유를 포함하여 표로 정리합니다.
| 수법 | 분리 단위 | 이력 공유 | 디스크 | 기각 이유 |
|---|---|---|---|---|
| git worktree | 디렉토리 | .git 공유 | 작음 | 채택 |
| 여러 개의 클론 | 디렉토리 + .git | 각각 다름 (fetch 필요) | 큼 | 이력이 분기되어 동기화가 번거로움 |
| DevContainer | 컨테이너 | 볼륨에 따라 다름 | 큼 | 기동이 무겁고 2~3개 병렬에는 과도함 |
| tmux 페인 분할만 사용 | 없음 (동일 디렉토리) | 동일 | 최소 | 파일 충돌이 해결되지 않음 |
tmux만으로 나누는 것은 애초에 문제를 해결하지 못합니다. 페인을 나누더라도 작업 디렉토리는 하나이므로 파일 경합은 그대로 남습니다. 여러 개의 클론은 분리라는 측면에서는 맞지만, .git이 각각 달라지기 때문에 한쪽에서 커밋한 내용을 다른 쪽에서 사용하려면 fetch를 거쳐야 합니다. 로컬의, 나만 만지고 있는 브랜치들끼리 fetch를 돌리는 것은 낭비이며, 이력도 가지치기되어 머릿속의 지도가 어긋나게 됩니다. DevContainer는 분리 측면에서 가장 강력하지만, 2~3개 세션을 위해 매번 컨테이너를 기동하고 동기화하는 것은 얻을 수 있는 격리에 비해 기동 비용이 맞지 않습니다. 맡길 범위를 결정하는 것이 인간의 일이며, 여기서 너무 과하게 격리하는 것은 설계의 과잉입니다.
worktree는 이 중간을 공략합니다. .git을 공유한 채로 작업 트리(Worktree)만 별도의 디렉토리에 전개합니다. 그래서 한쪽의 커밋은 즉시 다른 쪽에서도 보이며, fetch는 필요 없습니다. 절차는 이것뿐입니다.
# 메인 리포지토리 내에서 실행
git worktree add ../myapp-review -b fix/review-comments
git worktree add ../myapp-feature -b feat/new-endpoint
...
../myapp-review와 ../myapp-feature는 완전히 독립된 파일군이 됩니다. 한쪽의 Claude Code가 아무리 파일을 바꿔 써도 다른 쪽 디렉토리에는 영향을 주지 않습니다. 그러면서도 git log는 공통의 이력을 가리키므로, feature 측에서 머지(Merge)된 커밋은 review 측에서도 바로 참조할 수 있습니다. 저는 이 구성으로 Sitemora의 프로토타입을 만지던 시기에, LLM과 대화하며 하루 만에 첫 구성을 구축했습니다. 병행으로 돌릴 수 있다는 전제하에, 대기 시간이 그대로 다른 작업으로 채워지기 때문에 체감 속도가 달라집니다.
되돌릴 수 없는 조작이 하나 있으므로, 그 공정에 대해서만 주의 사항을 적습니다. worktree를 지울 때 rm -rf ../myapp-review와 같이 디렉토리를 직접 삭제하면, .git/worktrees 쪽에 메타데이터가 남아서 다음에 같은 경로를 사용하려고 할 때 거부됩니다. 삭제는 반드시 git worktree remove ../myapp-review를 사용하고, 사라진 디렉토리의 청소가 필요해지면 git worktree prune을 사용하세요.
실행합니다. 한 가지 주의할 점은, 동일한 브랜치를 두 개의 worktree에 동시에 체크아웃할 수는 없다는 것입니다. 이는 사양(specification)이며, 제가 review용과 feature용의 브랜치 이름을 반드시 다르게 설정하는 이유이기도 합니다.
worktree를 사용할지 결정하는 분기점은 동시 세션 수와 격리(isolation) 요구사항입니다. 2~3개 정도를 병렬로 돌리고 의존성 패키지(dependency package)의 버전도 동일하다면 worktree로 충분합니다. 만약 특정 세션 하나만 다른 Node 버전을 사용해야 하거나, 호스트(host) 환경을 더럽히고 싶지 않다는 요구사항이 생기는 즉시, 그 세션만 DevContainer로 전환합니다. 모든 세션을 동일한 방식으로 맞출 필요는 없으며, 격리가 필요한 하나만 컨테이너로 돌리는 것이 현실적인 타협점입니다. 우선 worktree로 시작하고, 격리가 부족해진 부분을 나중에 무겁게 구성하십시오. 이 순서를 따르면 처음부터 무거운 구성을 구축했다가 활용하지 못하는 실수를 피할 수 있습니다.
다음 단계로 직접 실습해 보려면, 현재 열려 있는 리포지토리에서 git worktree add ../$(basename $PWD)-tmp -b tmp/try를 입력하고, 다른 터미널에서 Claude Code를 하나 더 실행해 보세요. 테스트를 마친 후 git worktree remove로 깔끔하게 정리할 수 있는지까지 확인한다면, 이 구성이 자신의 손에 익을 것입니다.
출처
Discussion

AI 자동 생성 콘텐츠
본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기