Git Worktree

작성일:2026.02.02|조회수:3

Git Worktree

Git으로 여러 작업을 병렬로 진행하다 보면 브랜치 전환 자체가 비용이 되는 순간이 잦다. 기능 개발 중에 긴급 핫픽스를 처리해야 하거나, PR 리뷰를 위해 다른 브랜치를 실행해 봐야 하는 상황에서 git checkout과 stash를 반복하는 방식은 작업 흐름을 지속적으로 끊는다. 이 과정에서 실수가 발생하기도 하고, 현재 어떤 작업 맥락에 있는지 놓치는 경우도 많다.

Git Worktree는 이러한 문제를 브랜치 전환이 아닌 작업 공간 분리라는 방식으로 해결한다. 하나의 Git 저장소를 공유하면서 여러 작업 디렉터리를 동시에 운용할 수 있게 함으로써, 각 브랜치를 독립적인 작업 환경으로 다룰 수 있게 한다. 작업 단위가 브랜치가 아니라 폴더가 되면서, 컨텍스트 스위칭 비용이 눈에 띄게 줄어들고 병렬 작업이 구조적으로 가능해진다.

Git Worktree 핵심 명령어 정리

명령어

설명

비고

git worktree add <경로> <브랜치>

새 워크트리 생성

경로는 프로젝트 폴더 바깥

git worktree add <경로> --detach

브랜치 없는 임시 워크트리

PR 리뷰, 테스트용

git worktree list

모든 워크트리 목록 조회

브랜치 점유 상태 확인

git worktree remove <경로>

워크트리 안전 삭제

변경 사항 있으면 삭제 불가

git worktree prune

잘못 남은 워크트리 정리

폴더 직접 삭제 후

git worktree lock <경로>

워크트리 잠금

외장/네트워크 드라이브

git worktree unlock <경로>

워크트리 잠금 해제

git worktree repair

워크트리 경로 복구

폴더 이동 후

문제 해결 방법 및 주의사항

워크트리 생성 위치가 잘못된 경우

워크트리를 기존 프로젝트 디렉터리 안에 생성하면 안 된다. 이 경우 Git이 워크트리 디렉터리를 원래 레포지토리의 untracked 파일로 인식한다.

SH
# 프로젝트 폴더 안에 워크트리 생성 (실수)
git worktree add project/feature-cool feature/cool

이렇게 하면 project/feature-cool 폴더가 원래 레포지토리의 untracked 파일로 보인다. git status를 실행하면 불필요한 파일이 화면에 많이 나온다.

SH
# 상위 폴더에 워크트리 생성
git worktree add ../feature-cool feature/cool
cd ../feature-cool
git status

이제 feature/cool 브랜치를 별도의 디렉터리에서 안전하게 다룰 수 있다. 워크트리는 원래 폴더와 분리되어 있으므로 git status가 지저분해지지 않는다.

동일 브랜치를 동시에 열 수 없음 (브랜치 충돌 방지)

Git은 동일한 브랜치를 두 개 이상의 워크트리에서 동시에 체크아웃할 수 없다. 이 경우 에러가 발생한다.

SH
# 워크트리1
git worktree add ../feature-a feature/a
cd ../feature-a
# 이 브랜치가 이미 체크아웃되어 있음

# 다른 위치에서 다시 같은 브랜치를 열려고 하면
git worktree add ../feature-a-copy feature/a
# fatal: 'feature/a' is already used by worktree ...

위와 같이 같은 브랜치를 동시에 열면 Git이 충돌을 막는다.

SH
# detach 옵션으로 임시 워크트리 생성
git worktree add ../temp-check --detach
cd ../temp-check

# 임시 실행이나 테스트 목적이라면 이 상태로 충분
git status

--detach 옵션은 기존 브랜치를 건드리지 않고 작업만 실행하려는 경우 유용하다.

워크트리마다 의존성은 별도

워크트리는 독립적인 디렉터리이므로 기존 워크트리의 의존성(예: node_modules)을 공유하지 않는다.

SH
# 새 워크트리 생성
git worktree add ../feature-auth feature/auth
cd ../feature-auth

# 이 워크트리에는 node_modules가 없다
ls node_modules # (없음)

# 의존성 설치
npm install

워크트리는 하나의 저장소를 여러 디렉터리로 나눈 것일 뿐, 파일 시스템 관점에서 각각 별도의 프로젝트다. 따라서 의존성 설치는 각 워크트리별로 수행해야 한다.

폴더를 직접 삭제했을 때

워크트리를 rm -rf로 강제 삭제하면 Git 메타데이터에는 그 워크트리가 남아 있을 수 있다. 이런 상황에서는 git worktree prune으로 정리해야 한다.

SH
# 실수로 워크트리 폴더를 직접 삭제
rm -rf ../feature-bugfix

# 이 상태에서 prune 실행
git worktree prune
# prune된 워크트리가 Git 메타데이터에서 제거된다

이렇게 하면 Git의 워크트리 목록과 실제 폴더가 일치하게 된다. 

워크트리를 제거할 때는 단순히 디렉터리만 지우지 말고 git worktree remove를 이용하는 것이 안전하다. 이 명령어는 워크트리 메타데이터를 정리하며, 브랜치가 해당 워크트리에서 체크아웃된 상태인지 확인한다.

SH
# 워크트리 제거
git worktree remove ../feature-ui

이 명령은 실제 디렉터리를 삭제하고, Git이 관리하는 워크트리 목록에서도 제거한다.

필요하다면 브랜치는 별도로 삭제한다.

베어 레포지토리(Bare Repository) 전략

Git Worktree를 제대로 활용하려면, 결국 레포지토리 구조를 어떻게 가져갈 것인가에 대한 고민으로 이어진다. 이때 가장 깔끔한 방식이 베어 레포지토리를 중심에 두는 전략이다. 베어 레포지토리는 소스 코드 없이 Git 데이터베이스만 존재하는 저장소다. 즉, .git 디렉터리만 따로 떼어내 하나의 “중앙 관리소”로 두고, 실제 작업은 모두 Worktree에서만 수행한다.

일반적인 Git 저장소는 다음과 같은 구조를 가진다.

JAVA
project/
 ├─ .git/
 ├─ src/
 ├─ package.json

반면, 베어 레포지토리 전략에서는 구조가 완전히 달라진다.

PY
project-root/
 ├─ .bare/        # Git 데이터베이스만 존재
 ├─ main/         # main 브랜치 작업 공간
 ├─ feature-a/    # feature 브랜치
 ├─ hotfix/       # hotfix 브랜치

.bare는 Git의 “두뇌” 역할만 하고, main, feature-a, hotfix 같은 폴더들이 실제 작업 공간이 된다. 이 구조에서는 폴더 자체가 작업 컨텍스트가 된다.

초기 세팅 방법

먼저 프로젝트를 담을 루트 폴더를 만든다.

SH
mkdir project-root
cd project-root

그 다음, 원격 레포지토리를 베어 레포지토리로 clone한다. 이 시점에서 .bare 폴더에는 소스 코드가 없고 Git 데이터만 존재한다.

CSS
git clone --bare <REPO_URL> .bare

이제 첫 번째 작업 공간(main 브랜치)을 만든다. 이렇게 하면 main/ 폴더가 생성되고, 그 안에 실제 소스 코드가 체크아웃된다. 이제부터는 모든 개발 작업을 워크트리 폴더 안에서만 진행한다.

CSS
git worktree add main

추가 워크트리 생성 예시

기능 개발을 위한 브랜치를 추가로 열고 싶다면 다음과 같이 한다.

SH
git worktree add feature-login feature/login

또는 아직 브랜치가 없다면 새 브랜치를 생성하면서 열 수도 있다.

CSS
git worktree add -b feature/search feature-search

이제 디렉터리 구조는 다음과 같이 확장된다. 각 폴더는 서로 완전히 독립된 작업 공간이다.

CSS
project-root/
 ├─ .bare/
 ├─ main/
 ├─ feature-login/
 ├─ feature-search/

베어 레포지토리 사용 시 반드시 지켜야 할 규칙

가장 중요한 규칙은 .bare 폴더에서는 작업하지 않는 것이다. 여기에는 소스 코드가 없으므로 git pull이나 git merge 같은 명령을 실행하면 오류가 난다. 원격 변경 사항을 가져오고 싶다면 다음 중 하나의 방식만 사용한다.

PY
# 루트에서 Git 데이터만 갱신
git -C .bare fetch
SH
# 실제 작업 중인 워크트리에서
cd main
git pull

베어 레포지토리 전략을 사용하면 더 이상 “지금 어떤 브랜치에서 작업 중이지?”를 의식할 필요가 없다. 작업 상태는 브랜치 이름이 아니라 어떤 폴더에 들어가 있는지로 자연스럽게 드러난다. main 폴더에 있으면 메인 작업을 하고 있는 것이고, feature-login 폴더에 있으면 해당 기능 개발을 하고 있는 상태다. 작업 맥락을 기억해야 할 대상이 Git 상태가 아니라 파일 시스템이 된다.

이 방식은 동시에 여러 작업을 진행해야 하는 상황에서 특히 효과적이다. 기능 개발 도중에도 핫픽스 작업을 즉시 병행할 수 있고, PR 리뷰를 위해 별도의 워크트리를 만들어 코드를 실제로 실행해 볼 수도 있다. 각 워크트리는 완전히 독립된 디렉터리이기 때문에, 여러 서버를 서로 다른 포트로 동시에 띄우는 것도 어렵지 않다. 필요하다면 워크트리별로 Node.js 버전이나 환경 설정을 분리해, 레거시 유지보수와 신규 개발을 병렬로 진행할 수도 있다.

Git Worktree 자체만으로도 충분히 강력하지만, 베어 레포지토리를 함께 사용하면 프로젝트 전체 구조가 한 단계 정리된다. Git의 역할을 “브랜치 전환 도구”에서 “작업 공간 관리 도구”로 바꾸는 느낌에 가깝다. Git 데이터와 소스 코드를 물리적으로 분리하고, 모든 실제 작업은 Worktree에서만 수행한다. 그 결과 폴더 구조 자체가 현재 어떤 작업을 하고 있는지를 설명하는 문맥이 된다.

Git Worktree를 단기적인 실험이 아니라 장기적인 작업 방식으로 가져갈 계획이라면, 베어 레포지토리 전략은 선택이라기보다 거의 필수에 가깝다.

더 읽어보기

  • 2025.11.05

    Steiger

    FSD(Feature-Sliced Design)는 프론트엔드 아키텍처를 장기적으로 유지하기에 매우 유용한 방법론이다. 레이어와 슬라이스를 명확히 구분하고 의존 방향을 제한함으로써, 프로젝트 규모가 커질수록 코드베이스의 복잡도를 구조적으로 통제할 수 있다. 다만 이 장점은 동시에 부담이…

  • 2025.08.16

    pnpm과 terborepo로 시작하는 모노레포

    최근 개발 현장에서는 여러 프로젝트를 하나의 저장소에서 관리하는 모노레포 구조가 빠르게 확산되고 있다. 모노레포는 여러 패키지를 한 곳에서 관리하기 때문에 공통 코드 재사용이 쉽고, 여러 팀이 동시에 작업하더라도 의존성과 변경 이력을 일관되게 관리할 수 있다는 장점이 있다. 반면, 패키…

  • 2025.02.01

    Pandas

    pandas는 표 형식 데이터를 다루기 위한 파이썬의 대표 도구다. 핵심은 “데이터를 표로 생각한다”는 관점이고, 이를 Series(열)와 DataFrame(표)로 모델링한다. list와 dict로도 데이터를 다룰 수 있지만, 컬럼 단위 연산과 결측치 처리, 그룹화 같은 작업이 필요해지…

  • 2024.12.07

    Jest

    프론트엔드든 백엔드든, 테스트를 어디까지 작성해야 하는지는 늘 논쟁거리다. 모든 계층을 촘촘하게 테스트하는 방식도 있고, 핵심 로직에만 집중하는 방식도 있다. 나는 후자에 가깝다. 컨트롤러나 레졸버, 레포지토리 계층까지 전부 테스트하기보다는, 비즈니스 로직이 모여 있는 서비스 계층을 중…

  • 2026.04.17

    Code Server

    처음 코드 서버를 만들었던 건 아마도 3년쯤 전의 일이다. 맥미니만 있던 탓에 밖에서 개발하는 게 쉽지 않았고, 아이패드로 언제 어디서든 개발을 하고 싶었던 끝에 찾아낸 해결책이었다. 다행히 집에는 Synology NAS가 있었고, Docker를 통해 어렵지 않게 코드 서버를 만들 수…

  • 2026.04.11

    Trie 자료구조

    문자열 데이터를 다룰 때 단순히 “이 단어가 있나?”만으로는 부족한 순간이 있다. 자동 완성처럼 특정 접두사로 시작하는 후보를 모아야 할 때도 있고, 어떤 키에 값을 두고 빠르게 찾고 싶을 때도 있다. 이럴 때 가장 자연스럽게 떠올릴 수 있는 자료구조가 바로 Trie이다.Trie는 무엇…

  • 2026.03.19

    Streams API 부록 2. 왜 이미지는 위에서 아래로 나타날까

    웹 페이지에서 이미지를 로드할 때 흥미로운 장면을 종종 볼 수 있다. 이미지가 한 번에 완전히 나타나는 것이 아니라, 위에서 아래로 조금씩 채워지면서 나타나는 경우가 있기 때문이다. 특히 네트워크가 느리거나 이미지가 큰 경우 이런 현상이 더 분명하게 보인다. 마치 이미지가 위쪽부터 스캔…

댓글

댓글을 불러오는 중...