가이드

git worktree: 여러 브랜치를 동시에 작업하는 방법

업데이트: · Skillaria.Top

git worktree는 한 저장소에 작업 폴더를 여러 개 연결해서, 각 폴더에 서로 다른 브랜치를 열어 두는 기능입니다. git worktree add ../hotfix main을 실행하면 프로젝트 옆에 main 브랜치의 폴더가 생기고, 히스토리와 객체는 공유되므로 저장소를 다시 클론할 필요가 없습니다.

git worktree가 하는 일

git worktree는 한 저장소에 작업 폴더를 여러 개 연결합니다. 기본 폴더에는 기능 브랜치가 열려 있고, 옆 폴더에는 긴급 핫픽스를 위한 main이 열려 있으며, 둘 다 동시에 존재합니다. 객체, 커밋, 브랜치는 공유됩니다. 한 폴더에서 만든 커밋은 push나 fetch 없이 다른 폴더에서 바로 보입니다.

worktree가 없으면 문맥을 바꾸는 과정은 이렇습니다. git stash, git switch main, 수정, git switch로 돌아가기, git stash pop. 프로젝트에 오래 걸리는 빌드나 무거운 node_modules가 있으면, 브랜치를 바꿀 때마다 캐시도 무효화됩니다. 다른 방법인 저장소를 다시 클론하면 히스토리가 두 개의 독립된 사본이 되어 원격 서버를 통해 동기화해야 합니다.

worktree는 두 방식의 장점을 합칩니다. 폴더는 따로 있지만 .git은 하나입니다. 이것이 가능한 이유는 Git의 브랜치가 파일 사본이 아니라 커밋을 가리키는 포인터이기 때문입니다. 서로 다른 작업 폴더가 서로 다른 포인터를 보는 것은 아무 문제가 없습니다.

추가 작업 폴더 만들기

기본 형식은 git worktree add <경로> [<브랜치>]입니다. 주요 형태를 살펴봅시다.

기존 브랜치 열기

cd ~/projects/shop
git worktree add ../shop-main main
Preparing worktree (checking out 'main')
HEAD is now at 3f2c1ab Обновить README

프로젝트 옆에 main 브랜치의 shop-main 폴더가 생깁니다. 평범하게 cd로 들어가서 일반 저장소처럼 작업하면 됩니다.

새 브랜치와 함께 작업 폴더 만들기

git worktree add -b hotfix/payment-timeout ../shop-hotfix main

-b는 main에서 hotfix/payment-timeout 브랜치를 만들고 새 폴더에서 엽니다. -B는 같은 일을 하지만 브랜치가 이미 있으면 지정한 커밋으로 초기화하므로, 조심해서 쓰세요.

짧은 형태

git worktree add ../experiment

브랜치를 지정하지 않으면 Git은 경로의 마지막 부분(여기서는 experiment)과 같은 이름의 새 브랜치를 현재 HEAD에서 만듭니다. 같은 이름의 브랜치가 이미 있다면 그것을 엽니다.

브랜치 없는 작업 폴더

git worktree add --detach ../shop-v1.4 v1.4.0

detached HEAD 모드는 불필요한 브랜치를 만들지 않고, 태그로 옛 릴리스를 빌드하거나 확인할 때 편리합니다.

원격 서버의 브랜치로 열기

git fetch origin
git worktree add ../review-auth feature/auth

로컬에 feature/auth가 없고 원격 origin/feature/auth만 하나 있으면, Git은 git switch feature/auth처럼 추적 설정이 된 로컬 브랜치를 만듭니다. 내 작업을 건드리지 않고 남의 pull request를 검토할 때 편리합니다.

작업 폴더 보기와 삭제하기

git worktree list
/home/anna/projects/shop            a1b2c3d [feature/cart]
/home/anna/projects/shop-hotfix     7e8f9a0 [hotfix/payment-timeout]
/home/anna/projects/shop-v1.4       5d6e7f8 (detached HEAD)

첫 줄은 기본 작업 폴더(main worktree)이고, 나머지는 연결된 폴더(linked)입니다. 스크립트에서 쓰려면 기계가 읽기 좋은 git worktree list --porcelain을 쓰세요.

핫픽스가 병합되면 작업 폴더를 지우세요.

git worktree remove ../shop-hotfix
git branch -d hotfix/payment-timeout

git worktree remove는 폴더와 관리 정보를 지웁니다. 작업 폴더에 커밋하지 않은 변경이나 추적되지 않는 파일이 있으면 거부합니다. 그것들이 필요 없다고 확신할 때만 --force를 붙이세요. 이 명령은 브랜치 자체는 지우지 않으며, 브랜치는 따로 지워야 합니다.

폴더를 수동으로 지웠다면

파일 관리자나 rm -rf로 폴더를 지우면 .git/worktrees에 고아 항목이 남고, 브랜치는 여전히 사용 중으로 취급됩니다. 이런 항목은 다음 명령으로 정리합니다.

git worktree prune --verbose

Git도 가끔 가비지 컬렉션 때 스스로 정리하지만, 기다릴 필요는 없습니다.

내부 동작 방식

연결된 작업 폴더에는 .git 폴더 대신 한 줄짜리 .git 파일이 있습니다.

gitdir: /home/anna/projects/shop/.git/worktrees/shop-hotfix

이 관리 폴더에는 작업 폴더마다 고유한 데이터가 있습니다. 자기 HEAD, 자기 인덱스(staging area), 진행 중인 merge나 rebase 상태가 들어갑니다. 나머지는 모두 공유합니다. 객체, 브랜치, 태그, 원격 저장소, 설정, 훅이 그렇습니다.

작업 폴더마다 따로 있는 것모두가 공유하는 것
HEAD(현재 브랜치 또는 커밋)객체와 전체 히스토리
인덱스(git add)로컬과 원격 브랜치, 태그
끝나지 않은 merge, rebase, cherry-pickstash(refs/stash는 공유)
작업 디렉터리의 파일.git/config와 훅

표에서 나오는 흥미로운 점: 어느 폴더에서든 git stash list는 같은 항목을 보여 줍니다. 한 폴더에서 변경을 숨기고 다른 폴더에서 꺼낼 수도 있어서 편리합니다.

가장 중요한 제약: 브랜치 하나에 작업 폴더 하나

같은 브랜치를 두 작업 폴더에서 동시에 열 수는 없습니다. 시도하면 Git은 이렇게 오류를 냅니다.

git worktree add ../shop-copy feature/cart
fatal: 'feature/cart' is already used by worktree at '/home/anna/projects/shop'

(예전 Git 버전에서는 "is already checked out at"이라는 문구입니다.) 이 제약은 한 폴더의 커밋이 다른 폴더의 브랜치를 몰래 바꾸는 상황을 막아 줍니다. 해결 방법은 같은 커밋에서 새 브랜치를 만들거나(-b), 폴더를 --detach 모드로 열거나, 정말 필요하다면 --force를 쓰는 것입니다. 결과를 이해한 경우에만 후자를 쓰세요.

같은 이유로, main이 옆 작업 폴더에서 열려 있으면 기본 폴더에서는 git switch main을 실행할 수 없습니다.

실전 시나리오

기능 작업 중 긴급 핫픽스

git worktree add -b hotfix/null-price ../shop-hotfix main
cd ../shop-hotfix
# 수정, 테스트
git commit -am "빈 가격에서 발생하는 오류 수정"
git push -u origin hotfix/null-price
cd ../shop
git worktree remove ../shop-hotfix

미완성 기능은 그대로 남아 있고, 아무것도 stash할 필요가 없으며, 열어 둔 IDE 프로젝트도 전환을 알아차리지 못합니다.

코드를 실행하면서 pull request 검토하기

검토용 별도 폴더를 두면 남의 브랜치를 빌드하고 실행하고 테스트할 수 있으며, 동시에 옆 에디터 창에서 내 작업을 계속할 수 있습니다.

두 버전의 동작 비교

태그가 다른 두 폴더를 서로 다른 포트에서 동시에 실행하면, 예를 들어 최적화 전후의 API 응답 속도를 나란히 비교할 수 있습니다.

오래 걸리는 테스트와 빌드

한 폴더에서 전체 테스트를 돌리는 동안 다른 폴더에서 코드를 계속 쓸 수 있습니다. 파일을 바꿔도 빌드가 깨지지 않습니다.

여러 AI 에이전트의 병렬 작업

여러 에이전트나 프로세스가 작업을 나눠 한다면, 각자에게 별도의 작업 폴더와 브랜치를 주면 서로 방해하지 않고, 결과는 같은 저장소로 바로 모입니다.

작업 폴더를 매일 쓴다면 구조 정하기

작업 폴더를 매일 쓴다면 구조를 미리 정하세요. 그렇지 않으면 옆 디렉터리가 금방 뒤죽박죽이 됩니다. 흔한 방식은 프로젝트 상위 폴더 안에 bare 저장소와 브랜치마다 폴더 하나를 두는 것입니다.

git clone --bare git@example.com:team/shop.git ~/projects/shop/.bare
cd ~/projects/shop
echo "gitdir: ./.bare" > .git
git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
git fetch origin

git worktree add main
git worktree add -b feature/cart feature-cart main

remote.origin.fetch 줄이 필요한 이유는 bare 클론이 기본적으로 원격 브랜치 추적을 설정하지 않기 때문입니다. 결과적으로 ~/projects/shop에는 main과 feature-cart 폴더가 있고, 각각 자기 브랜치를 가지며, 어느 쪽이 더 중요하지 않습니다.

또 하나의 좋은 습관은 폴더 이름을 브랜치 이름과 같게 하는 것입니다(슬래시는 하이픈으로 바꿉니다). 그러면 git worktree list 출력과 터미널 경로를 보고 지금 어디에 있는지 항상 알 수 있습니다. 마지막으로, 브랜치를 병합한 직후에 작업 폴더를 지우세요. 오래된 작업 폴더는 디스크를 차지하고 브랜치를 "사용 중"으로 묶어 둡니다.

흔한 실수와 주의할 점

  • 의존성과 빌드는 공유되지 않음. 각 폴더는 독립된 디렉터리이므로 node_modules, Python 가상 환경, .env, 빌드 결과물을 새로 만들어야 합니다. 추적되지 않는 파일은 새 폴더로 옮겨지지 않습니다.
  • 작업 폴더를 기본 폴더 안에 만듦. git worktree add ./hotfix는 프로젝트 안에 폴더를 만들고, 기본 작업 폴더는 이것을 추적되지 않는 파일로 봅니다. 폴더는 옆(../)이나 별도 디렉터리에 두거나, 경로를 .gitignore에 추가하세요.
  • 폴더를 손으로 옮김. 연결이 끊어집니다. git worktree move ../old ../new로 옮기고, 이미 옮겼다면 새 폴더에서 git worktree repair를 실행하세요.
  • 분리된 디스크의 작업 폴더가 사라짐. 연결된 디스크가 없을 때 prune이 기록을 지우지 않도록, 잠그세요: git worktree lock --reason "외장 디스크" ../shop-usb.
  • 서브모듈. 작업 폴더에서 서브모듈 지원은 제한적입니다. 폴더를 만든 뒤 git submodule update --init을 실행하고 결과를 확인하세요.

git worktree 치트시트

작업명령
기존 브랜치를 새 폴더에서 열기git worktree add ../dir 브랜치
브랜치와 폴더 함께 만들기git worktree add -b new-branch ../dir main
브랜치 없는 폴더(태그, 커밋)git worktree add --detach ../dir v1.0
폴더 목록git worktree list
폴더 삭제git worktree remove ../dir
지워진 폴더의 기록 정리git worktree prune
폴더 옮기기git worktree move ../dir ../new-dir
옮긴 뒤 연결 복구git worktree repair
prune으로부터 보호git worktree lock ../dir

git worktree, stash, 두 번째 클론 비교

기준stashworktree두 번째 clone
전환 속도빠르지만 브랜치를 바꿔야 함즉시. 그냥 다른 폴더즉시
디스크 사용량최소작업 파일만히스토리 전체 사본
동기화필요 없음필요 없음. 히스토리 공유push와 fetch로
동시 작업불가가능가능

stash는 2~3분 정도의 짧은 중단에 여전히 가장 좋은 선택입니다. 그보다 길거나, 두 버전을 동시에 열어 두어야 한다면 worktree가 편합니다.

정리

git worktree는 여러 브랜치를 동시에 다루는 간단한 방법입니다. add로 폴더를 만들고, list로 확인하고, remove와 prune으로 정리합니다. 히스토리는 공유되고, HEAD, 인덱스, 파일은 폴더마다 따로 있습니다. 한 브랜치는 두 폴더에서 동시에 열 수 없습니다. 브랜치가 얼마나 가볍고 전환이 얼마나 쉬운지는 Git 강의에서 실습으로 다룹니다.

자주 묻는 질문

git worktree는 어느 버전부터 있나요?

Git 2.5에서 추가되었고, 이후 remove, move 같은 명령이 더해졌습니다. 최신 Git에서는 이 글의 모든 명령을 쓸 수 있습니다.

한 작업 폴더에서 커밋하면 다른 폴더에서 바로 볼 수 있나요?

네, 히스토리가 공유됩니다. 커밋은 어느 폴더에서든 git log로 바로 보이고, push나 fetch 없이 git merge로 합칠 수 있습니다.

IDE가 여러 작업 폴더를 인식하나요?

IDE 입장에서 각 폴더는 일반 프로젝트 폴더이므로, 별도 창에서 엽니다. 많은 편집기가 내장 Git 인터페이스에서 작업 폴더 목록도 보여 줍니다.

git worktree remove는 브랜치도 지우나요?

아니요. 폴더와 관리 기록만 지웁니다. 브랜치는 git branch -d로 따로 지우세요.

bare 저장소에서도 git worktree를 쓸 수 있나요?

네. 인기 있는 방식은 bare 클론을 두고, 브랜치마다 작업 폴더를 만드는 것입니다. 이 경우 파일이 들어 있는 "기본" 폴더가 아예 없습니다.

영상으로 이 주제 배우기

이 주제는 “Git 완전 정복: 초보에서 능숙한 개발자로” 강의에서 실습과 함께 자세히 다룹니다.

강의로 이동