Dev/기타

Git Worktree로 작업 효율성 높이기

newtype 2026. 1. 5. 10:22

Git Worktree로 작업 효율성 높이기

Git Worktree란?

Git Worktree는 하나의 저장소에서 여러 브랜치를 동시에 체크아웃할 수 있게 해주는 Git의 강력한 기능입니다. 일반적으로 Git 저장소는 한 번에 하나의 브랜치만 체크아웃할 수 있지만, worktree를 사용하면 여러 작업 디렉토리를 만들어 각각 다른 브랜치에서 작업할 수 있습니다.

모든 worktree는 동일한 .git 디렉토리를 공유하므로, 저장소를 여러 번 클론할 필요 없이 효율적으로 여러 작업을 병렬로 진행할 수 있습니다.

기존 방식의 한계와 불편함

Worktree를 사용하지 않을 때 여러 작업을 전환하려면 stash, checkout 등의 명령어를 반복적으로 사용해야 합니다. 실제 시나리오를 통해 이런 불편함을 살펴보겠습니다.

시나리오: 기능 개발 중 긴급 수정 요청 발생

새로운 기능을 개발하는 feature/user-service 브랜치에서 작업 중이라고 가정해봅시다.

# feature/user-service 브랜치에서 작업 중
$ git checkout feature/user-service
$ vim user_handler.go  # 코드 수정 중...

이때 갑자기 운영팀에서 긴급 버그 수정 요청이 들어왔습니다. 기존 방식으로는 다음과 같은 절차를 거쳐야 합니다.

# 1. 현재 작업 내용을 stash에 임시 저장
$ git stash save "WIP: user service refactoring"
Saved working directory and index state On feature/user-service: WIP: user service refactoring

# 2. main 브랜치로 이동
$ git checkout main
Switched to branch 'main'

# 3. 긴급 수정을 위한 새 브랜치 생성
$ git checkout -b hotfix/auth-panic
Switched to a new branch 'hotfix/auth-panic'

# 4. 버그 수정 작업
$ vim auth.go
$ git add auth.go
$ git commit -m "Fix nil pointer panic in auth middleware"

# 5. main에 머지
$ git checkout main
$ git merge hotfix/auth-panic

# 6. 다시 원래 작업으로 돌아가기
$ git checkout feature/user-service

# 7. stash했던 작업 내용 복원
$ git stash pop
# 충돌이 발생할 수 있음!

문제점

  1. 컨텍스트 스위칭 오버헤드: 브랜치를 전환할 때마다 작업 디렉토리의 파일들이 변경되어 IDE나 빌드 시스템이 재로딩되어야 합니다.

  2. Stash 관리의 복잡성: stash가 쌓이면 어떤 stash가 어떤 작업인지 추적하기 어렵습니다.

   $ git stash list
   stash@{0}: On feature/user-service: WIP: user service refactoring
   stash@{1}: On feature/api-v2: WIP: API v2 migration
   stash@{2}: On feature/monitoring: WIP: add prometheus metrics
  1. Stash 충돌 가능성: git stash pop을 할 때 다른 변경사항과 충돌이 발생할 수 있습니다.

  2. 빌드 아티팩트 문제: 브랜치를 전환하면 빌드된 바이너리나 캐시 파일들이 불일치할 수 있어 클린 빌드가 필요합니다.

  3. 테스트 실행의 어려움: 두 브랜치의 코드를 동시에 비교하거나 테스트하려면 여러 번 브랜치를 오가야 합니다.

Git Worktree로 개선하기

같은 시나리오를 worktree로 처리해봅시다.

초기 설정

# 메인 저장소
$ cd ~/projects/myapp

# 현재 feature/user-service에서 작업 중
$ git branch
* feature/user-service
  main

Worktree를 사용한 긴급 수정

# 1. 긴급 수정을 위한 별도 worktree 생성
$ git worktree add ../myapp-hotfix main
Preparing worktree (checking out 'main')
HEAD is now at a1b2c3d Latest stable release

# 2. 새로운 디렉토리로 이동하여 작업
$ cd ../myapp-hotfix
$ git checkout -b hotfix/auth-panic
$ vim auth.go
$ git add auth.go
$ git commit -m "Fix nil pointer panic in auth middleware"
$ git push origin hotfix/auth-panic

# 3. 원래 작업 디렉토리로 돌아가기
$ cd ../myapp
# 작업 내용이 그대로 유지됨! stash 불필요
$ vim user_handler.go  # 바로 작업 재개 가능

동시에 여러 작업 진행

# 프로젝트 루트
$ cd ~/projects/myapp

# 현재 worktree 목록 확인
$ git worktree list
/home/user/projects/myapp              a1b2c3d [feature/user-service]
/home/user/projects/myapp-hotfix       a1b2c3d [hotfix/auth-panic]

# 코드 리뷰를 위한 또 다른 worktree 추가
$ git worktree add ../myapp-review feature/api-v2
$ cd ../myapp-review
# 코드 리뷰 진행...

# 메인 작업 디렉토리
$ cd ~/projects
$ ls -la
drwxr-xr-x  myapp/           # feature/user-service
drwxr-xr-x  myapp-hotfix/    # hotfix/auth-panic
drwxr-xr-x  myapp-review/    # feature/api-v2

Worktree vs 기존 방식 비교

측면 기존 방식 (stash/checkout) Worktree
브랜치 전환 파일 시스템 변경 발생 디렉토리 이동만 하면 됨
작업 보존 stash 필요 자동으로 보존됨
동시 작업 불가능 (순차적) 여러 브랜치 동시 작업 가능
IDE 로딩 브랜치마다 재로딩 각 디렉토리별 독립 세션
빌드 상태 브랜치 전환 시 재빌드 필요 각 worktree가 독립적인 빌드 상태 유지
테스트/비교 브랜치 전환 반복 필요 동시에 열어서 비교 가능
디스크 사용량 적음 각 worktree마다 작업 디렉토리 필요

실전 활용 팁

1. Worktree 명명 규칙

일관된 명명 규칙을 사용하면 관리가 쉬워집니다.

# 브랜치 이름을 반영한 명명
$ git worktree add ../myapp-feature-user feature/user-service

# 또는 작업 타입별로 구분
$ git worktree add ../myapp-hotfix hotfix/critical-bug
$ git worktree add ../myapp-review feature/code-review

2. 임시 작업용 Worktree

빠른 테스트나 확인이 필요할 때 임시 worktree를 만들 수 있습니다.

# 특정 커밋 체크아웃
$ git worktree add --detach ../myapp-temp a1b2c3d

# 작업 완료 후 삭제
$ git worktree remove ../myapp-temp

3. Worktree 정리

# 현재 worktree 목록 확인
$ git worktree list

# 특정 worktree 제거
$ git worktree remove ../myapp-hotfix

# 또는 디렉토리를 직접 삭제한 후 정리
$ rm -rf ../myapp-hotfix
$ git worktree prune  # 참조 정리

4. 각 Worktree에서 독립적인 환경 설정

각 worktree는 독립적인 작업 디렉토리이므로 서로 다른 설정을 가질 수 있습니다.

# 메인 worktree: 개발 환경
$ cd ~/projects/myapp
$ export ENV=development
$ go run main.go

# hotfix worktree: 프로덕션 유사 환경
$ cd ~/projects/myapp-hotfix
$ export ENV=production
$ go build -o app
$ ./app

주의사항

  1. 브랜치 중복 체크아웃 불가: 같은 브랜치를 여러 worktree에 동시에 체크아웃할 수 없습니다.
   $ git worktree add ../myapp-test main
   fatal: 'main' is already checked out at '/home/user/projects/myapp-hotfix'
  1. 디스크 공간: 각 worktree는 전체 작업 디렉토리를 가지므로 대용량 프로젝트에서는 디스크 공간을 고려해야 합니다.

  2. Worktree 삭제 시 주의: worktree를 삭제하기 전에 커밋하지 않은 변경사항이 없는지 확인하세요.

실제 개발 워크플로우 예시

Go 애플리케이션 개발에서 worktree를 활용하는 실제 시나리오입니다.

# 프로젝트 구조
~/projects/
├── myapp/                    # main 브랜치 (안정 버전)
├── myapp-feature-user/       # 사용자 서비스 개발
├── myapp-feature-api/        # API 리팩토링
└── myapp-hotfix/             # 긴급 수정용

# 1. 메인 개발 작업
$ cd ~/projects/myapp-feature-user
$ vim internal/user/handler.go
$ go test ./...

# 2. 동시에 다른 터미널에서 API 작업
$ cd ~/projects/myapp-feature-api
$ vim api/v2/router.go
$ go test -v ./api/...

# 3. 긴급 버그 발생 시
$ cd ~/projects/myapp-hotfix
$ git pull origin main
$ git checkout -b hotfix/urgent-fix
$ vim middleware/auth.go
$ go test ./middleware
$ git commit -am "Fix authentication middleware panic"
$ git push origin hotfix/urgent-fix

# 4. 다시 원래 작업으로 즉시 복귀
$ cd ~/projects/myapp-feature-user
# 모든 작업 내용이 그대로 유지됨

Go 모듈 캐시 공유

Go는 모듈 캐시를 $GOPATH/pkg/mod에 저장하므로, 모든 worktree가 자동으로 같은 캐시를 공유합니다.

# 각 worktree에서 의존성을 다시 다운로드할 필요 없음
$ cd ~/projects/myapp-feature-user
$ go mod download  # 한 번만 실행하면 됨

$ cd ~/projects/myapp-hotfix
# 이미 캐시된 모듈 사용
$ go build  # 빠른 빌드

독립적인 바이너리 빌드

각 worktree에서 독립적으로 바이너리를 빌드하고 실행할 수 있습니다.

# feature 브랜치: 개발 중인 새 기능 테스트
$ cd ~/projects/myapp-feature-user
$ go build -o myapp-dev
$ ./myapp-dev &

# hotfix 브랜치: 수정된 버전 테스트
$ cd ~/projects/myapp-hotfix
$ go build -o myapp-hotfix
$ ./myapp-hotfix &

# 두 버전을 동시에 실행하여 비교 테스트 가능

결론

Git Worktree는 특히 다음과 같은 상황에서 매우 유용합니다:

  • 긴급 수정과 기능 개발을 병행해야 할 때
  • 여러 버전의 코드를 동시에 테스트하거나 비교해야 할 때
  • 코드 리뷰를 위해 다른 브랜치를 확인하면서 현재 작업을 유지하고 싶을 때
  • 대규모 리팩토링 작업과 일반 개발을 분리하고 싶을 때

stash와 checkout을 반복하는 기존 방식에서 벗어나 worktree를 활용하면 작업 효율성을 크게 높일 수 있습니다. 각 작업을 독립적으로 유지하면서도 빠르게 전환할 수 있는 worktree의 장점을 활용해보세요.

반응형