AI 에이전트 병렬 개발을 위한 git worktree 활용법
- 하나의 저장소에서 브랜치별 독립 작업 디렉토리를 만들 수 있어 AI 에이전트 병렬 작업에 잘 맞습니다
- stash 없이 컨텍스트를 분리하고, clone 없이 히스토리와 오브젝트를 공유할 수 있습니다
- 같은 브랜치는 두 worktree에 동시에 체크아웃할 수 없고, 의존성 폴더는 각 worktree마다 별도 관리해야 합니다
- AI가 만든 여러 작업 브랜치는 대부분 squash merge로 정리하는 것이 깔끔합니다
TL;DR
AI 코딩 에이전트를 병렬로 돌리고 싶다면 git worktree가 정답입니다. 같은 저장소에서 브랜치마다 독립된 작업 디렉토리를 만들어주기 때문에, stash도 필요 없고 clone도 필요 없습니다.
Git Worktree란
여러 프로젝트를 동시에 진행하더라도, 사람이 직접 개발할 때는 결국 한 번에 한 작업만 가능합니다. 그래서 기존에는 git stash로 현재 작업을 잠시 쌓아두고 브랜치를 체크아웃해서 다른 작업을 하다가, 다시 돌아와서 stash를 꺼내는 방식으로 왔다 갔다 했습니다.
git worktree는 이 흐름 자체를 바꿔주는 기능입니다. 하나의 Git 저장소에 여러 개의 작업 디렉토리를 붙일 수 있는 기능이죠. 보통 우리가 아는 Git 저장소는 하나의 working tree만 가지는데, worktree를 사용하면 같은 .git 히스토리와 오브젝트 DB를 공유하면서 각기 다른 브랜치를 별도 폴더에 체크아웃해둘 수 있습니다.
구조를 보면 이렇게 됩니다:
/projects/
├── my-app/ ← main worktree (main 브랜치)
│ └── .git/ ← 실제 git 데이터
├── my-app-feature/ ← linked worktree (feature/auth 브랜치)
│ └── .git ← .git 디렉터리가 아닌 파일, main의 .git을 가리킴
└── my-app-hotfix/ ← linked worktree (hotfix/login 브랜치)
└── .git각 worktree는 자체 HEAD, 스테이징 영역, 작업 파일을 가지지만 커밋 히스토리와 오브젝트 DB는 공유합니다. Git 오브젝트 기준으로는 추가 디스크 사용량이 거의 없지만, node_modules, .venv 같은 의존성은 각 worktree마다 별도로 설치해야 해서 무거운 프로젝트에서 여러 개를 동시에 운영하면 디스크를 빠르게 소모합니다.
한 가지 제약도 있습니다. 같은 브랜치를 두 worktree에 동시에 체크아웃하는 건 불가능합니다. 이건 의도된 설계인데, 양쪽에서 동시에 커밋하면 서로 다른 diff가 갑자기 나타나는 혼란을 방지하기 위해서입니다.
언제 처음 나왔나
git worktree는 2015년 7월 29일, Git 2.5 릴리즈와 함께 정식 기능으로 들어왔습니다. 주요 기여자는 Nguyễn Thái Ngọc Duy로, 수년간 이 개념을 다듬어왔습니다. 처음 출시 당시에는 experimental 딱지가 붙어 있었고 서브모듈과의 호환성 문제도 있었지만, 지금은 그런 문제들이 대부분 해결된 상태입니다.
이후 Git 2.7에서 git worktree move, git worktree remove가 추가됐고, Git 2.15에서는 git worktree lock과 git worktree unlock이 도입됐습니다.
저도 최근에야 알게 됐는데, 이미 잘 쓰고 있는 분들은 오래전부터 쓰고 있던 기능이더군요. 거의 10년 가까이 “아는 사람만 쓰는 기능”이었는데, AI 코딩 에이전트가 일상화된 지금은 갑자기 필수 도구처럼 느껴지는 케이스입니다.
하네스 엔지니어링, 왜 worktree가 필요한가
하네스 엔지니어링이란 AI 에이전트를 직접 짜는 게 아니라, 위임할 수 있는 환경을 설계하고 조율하는 방식을 말합니다. worktree는 이런 환경이 갖춰졌을 때 비로소 날개를 달아주는 기능이죠.
Claude Code나 Codex 같은 AI 에이전트는 작업 디렉토리의 파일을 직접 읽고 씁니다. 에이전트가 feature/payments 브랜치에서 작업 중이라면, 그 순간 작업 디렉토리는 절반쯤 수정된 상태가 됩니다.
이 상태에서 다른 브랜치로 체크아웃하거나 두 번째 에이전트를 띄우면 어떻게 될까요? 파일이 충돌하거나, 에이전트가 잘못된 상태의 코드를 기반으로 작업하게 됩니다.
전통적인 해결책은 git stash였지만, 여러 stash가 쌓이면 어느 것이 어느 작업인지 추적하기가 금방 힘들어집니다. 저장소를 두 번 clone하는 방법도 있지만, 히스토리가 분리되고 변경 사항을 push/pull 없이 공유할 수가 없습니다.
git worktree는 이 문제를 깔끔하게 해결합니다. 각 AI 세션이 완전히 독립된 디렉토리에서 자기 브랜치로만 작동하고, 히스토리와 오브젝트는 공유합니다. 실제로 Claude Code는 2026년 2월 공식 --worktree 플래그를 추가하면서 이 워크플로우를 1등 시민으로 지원하기 시작했습니다.

워크트리 작업 시작법
기본 명령어는 간단합니다:
# 새 브랜치와 함께 worktree 생성
git worktree add ../my-app-feature -b feature/auth
# 기존 브랜치로 worktree 생성
git worktree add ../my-app-hotfix hotfix/login
# 현재 연결된 worktree 목록 확인
git worktree list폴더 구조는 보통 두 가지 방식을 씁니다. 첫 번째는 메인 프로젝트 옆에 나란히 두는 방식입니다:
/projects/
├── my-app/
├── my-app-feature-auth/
└── my-app-hotfix-login/두 번째는 프로젝트 안에 trees/ 폴더를 만들어 모아두는 방식입니다:
/my-app/
├── src/
├── .git/
└── trees/
├── feature-auth/
└── hotfix-login/두 번째 방식을 쓴다면 .gitignore에 trees/를 추가하는 걸 잊으면 안 됩니다. 안 그러면 메인 worktree에서 untracked files로 잡힙니다.
worktree를 생성할 때 한 가지 더 챙겨야 할 게 있습니다. .env 같이 .gitignore에 들어있는 파일은 자동으로 복사되지 않습니다. 단순 복사(cp)도 되지만, 메인 worktree의 .env가 바뀔 때마다 다시 복사해야 하는 번거로움이 있습니다. symlink로 연결해두면 메인의 .env를 수정해도 모든 worktree에 자동으로 반영됩니다:
# worktree 생성 후 .env symlink 연결
git worktree add trees/feature-auth -b feature/auth
ln -s "$(pwd)/.env" trees/feature-auth/.env.env.local, .env.development 등 환경별 파일이 여러 개라면 worktree 생성 함수를 만들어두면 편합니다:
# ~/.zshrc 또는 ~/.bashrc
wt() {
git worktree add "$1" -b "$2"
for f in .env .env.local .env.development; do
[ -f "$f" ] && ln -s "$(pwd)/$f" "$1/$f" && echo "linked $f"
done
}
# 사용법
wt trees/feature-auth feature/authClaude Code를 쓴다면 --worktree 플래그로 더 간단히 할 수 있습니다:
# worktree 생성 + Claude Code 세션 시작을 한 번에
claude --worktree feature-auth이 명령 하나로 .claude/worktrees/feature-auth/ 디렉토리와 브랜치가 생성되고, 그 안에서 Claude 세션이 시작됩니다.
워크트리에서 작업하기
worktree를 만들었으면 그냥 해당 디렉토리로 이동해서 평소처럼 작업하면 됩니다. IDE나 에디터도 각 디렉토리를 별도 프로젝트로 열 수 있습니다.
AI 에이전트와 함께라면 이런 식으로 됩니다:
# 터미널 1 - feature 작업
cd ../my-app-feature-auth
claude # 또는 codex, gemini-cli 등
# 터미널 2 - hotfix 작업 (동시에!)
cd ../my-app-hotfix-login
claude한쪽 에이전트가 작업하는 동안 다른 쪽 결과물을 리뷰할 수 있습니다. 기다리는 게 아니라 지휘하는 역할이 되는 거죠.

각 worktree 안에서 커밋은 평소와 동일합니다. 브랜치가 이미 분리되어 있으니 어느 브랜치인지 신경 쓸 필요가 없습니다.
git add .
git commit -m "feat: add auth middleware"워크트리 작업 후
작업이 완료됐다면 일반적인 PR 플로우와 동일합니다. worktree 디렉토리 안에 있으면 자동으로 해당 브랜치 기준으로 push됩니다:
cd ../my-app-feature-auth
git push -u origin feature/auth
gh pr create --title "Add auth middleware" --base mainPR을 올린 다음 메인 worktree에 합치는 방법은 세 가지가 있습니다. 상황에 따라 골라 쓰면 됩니다.
Squash merge — AI 작업 결과물엔 이게 제일 깔끔합니다
worktree 안에서 AI가 이것저것 시도하며 커밋을 여러 개 남겼을 텐데, 그 과정 커밋들은 메인 히스토리에 굳이 남길 필요가 없습니다. 전체를 커밋 하나로 압축해서 머지하는 방식이죠. GitHub PR에서 "Squash and merge"를 선택하거나, CLI로는 이렇게 합니다:
git merge --squash feature/auth
git commit -m "feat: add auth middleware"Rebase merge — 히스토리를 선형으로 유지하고 싶을 때
worktree 브랜치의 커밋들을 메인 worktree 위에 재배치해서 머지합니다. 브랜치 분기 흔적 없이 히스토리가 한 줄로 정리되는 게 장점입니다. 커밋 하나하나가 의미 있는 단위로 잘 정리돼 있을 때 쓰면 좋습니다:
# worktree 디렉토리에서 (기본 브랜치가 master라면 main → master)
git rebase main
# 메인 worktree로 돌아와서
git checkout main
git merge feature/auth --ff-onlyMerge commit — 브랜치 히스토리를 그대로 보존할 때
머지 커밋이 하나 생기면서 “이 시점에 feature/auth 브랜치가 합쳐졌다”는 기록이 남습니다. 작업 단위가 크거나 나중에 브랜치별 히스토리 추적이 필요한 경우에 적합합니다:
git checkout main
git merge feature/auth하네스 엔지니어링으로 AI가 처리한 작은 작업들은 대부분 squash merge가 제일 잘 맞습니다. 히스토리가 지저분해질 이유가 없고, 메인 worktree 입장에서는 “이 기능이 추가됐다”는 커밋 하나면 충분하니까요.
머지가 완료됐다면 worktree를 정리합니다.
워크트리 제거
# 해당 worktree 제거
git worktree remove ../my-app-feature-auth
# 브랜치도 함께 삭제
git branch -d feature/auth
# 더 이상 존재하지 않는 worktree 레퍼런스 정리
git worktree pruneClaude Code --worktree 옵션으로 생성한 경우, 세션 종료 시 변경 사항이 없으면 자동으로 worktree와 브랜치가 삭제됩니다. 커밋이 있는 경우엔 유지할지 물어봅니다.
주의할 점
같은 파일을 건드리는 작업은 병렬로 돌리지 마세요. worktree는 파일 충돌을 마법처럼 해결해주지 않습니다. 두 에이전트가 같은 파일을 수정하면 나중에 머지할 때 충돌이 그대로 남습니다. 작업을 병렬로 나누기 전에 의존성을 먼저 파악하는 게 중요합니다.
같은 포트를 쓰는 서버는 충돌합니다. 여러 worktree에서 동시에 dev 서버를 띄우면 포트가 겹칩니다. 각 worktree의 서버 포트를 다르게 설정하거나, 한 번에 하나만 실행하는 방식으로 관리해야 합니다.
git worktree prune은 주기적으로 실행해두는 편이 좋습니다. 디렉토리를 수동으로 삭제하면 worktree 메타데이터가 남아서 목록이 지저분해집니다. git worktree prune으로 유효하지 않은 레퍼런스를 정리할 수 있습니다.
마치며
git worktree는 2015년에 나왔지만, AI 코딩 에이전트가 일상화된 지금이야말로 진가를 발휘하는 기능입니다. 여러 에이전트를 동시에 돌리면서 서로 간섭 없이 병렬 개발을 하는 것, 이게 지금 시점에서 worktree가 사실상 필수인 이유입니다. stash와 체크아웃을 반복하는 대신, 디렉토리를 이동하는 것만으로 컨텍스트를 전환할 수 있습니다.
Refs
- Git Official Documentation - git-worktree
- Git Worktrees: The Feature That Waited a Decade for Its Moment
- Claude Code Common Workflows - Worktree Support
- Parallel Vibe Coding: Using Git Worktrees with Claude Code
- How we're shipping faster with Claude Code and Git Worktrees
- Mastering Git Worktrees with Claude Code for Parallel Development Workflow


