Git Worktree로 브랜치 관리하기: stash는 이제 그만

kukjunLEE·2025년 11월 29일

Git

목록 보기
4/4
post-thumbnail

서론

이번 주 TSBM 모임에 갔다가 흥미로운 이야기를 들었습니다.

옆에 계신 개발자분과 이야기하면서 생산성을 위한 앱이나 도구에 대한 이야기가 나왔고, 그 중 하나가 git worktree였습니다.

worktree를 쓰게 되면, 브랜치별로 작업하는게 훨씬 편하다고 하셨고, 저는 처음 들어본 내용이어서 되물어봤습니다.

git stash로 할 수 있는 거 아닌가요?

그분이 웃으시면서 이렇게 말씀하셨습니다.

"저는 worktree 씁니다. stash보다 훨씬 편해요. 한번 써보세요!"

Worktree?

Git을 나름 잘 쓰고 있다고 생각했는데 5년 넘게 써왔는데 처음 듣는 단어였습니다. 부끄럽기도 하고, 호기심이 생겨서 바로 찾아보았습니다.

그동안 git stash로도 문제를 해결할 수 있었다고 생각했는데, 다시 생각해보니 그건 비효율적으로 작업하고 있었던것 임을 알게 되었습니다.




본론

Git Worktree가 뭔가요?

간단하게 말하면, 하나의 Git 저장소를 여러 디렉토리에서 동시에 작업할 수 있게 해주는 기능입니다.

일반적으로 Git 저장소는 이렇게 생겼습니다.

my-project/
├── .git/
├── src/
└── README.md

한 번에 하나의 브랜치만 체크아웃할 수 있습니다.

하지만 worktree를 사용하면,

my-project/           # main 브랜치
├── .git/
├── src/
└── README.md

my-project-feature-a/ # feature-a 브랜치
├── src/
└── README.md

my-project-hotfix/    # hotfix 브랜치
├── src/
└── README.md

이렇게 동일한 저장소의 여러 브랜치를 각각 다른 디렉토리에서 동시에 작업할 수 있습니다.

각 디렉토리는 독립적인 작업 공간이지만, .git 디렉토리는 공유합니다. 그래서 commit, push, pull 같은 작업은 모두 동기화됩니다.




기존 stash의 문제점

내가 그동안 겪었던 전형적인 시나리오는 이랬다.

상황:

  • feature/user-dashboard 브랜치에서 신규 기능 개발 중
  • 갑자기 긴급 버그 수정 요청이 들어옴 → v1.2.3 태그에서 hotfix 필요

기존 방식 (stash 사용):

# 1. 현재 작업 임시 저장
git stash save "WIP: user dashboard"

# 2. hotfix 브랜치로 이동
git checkout v1.2.3
git checkout -b hotfix/urgent-bug

# 3. 버그 수정 후 커밋
# ... 수정 작업 ...
git add .
git commit -m "Fix urgent bug"

# 4. 다시 원래 브랜치로 돌아가기
git checkout feature/user-dashboard

# 5. stash 복원
git stash pop

문제점

  1. Context Switching이 느림
    • 브랜치를 바꿀 때마다 파일이 물리적으로 변경됨.
    • IDE가 리인덱싱하느라 시간 소요.
    • 특히 node_modules 같은 큰 디렉토리가 있으면 더 느림.
  1. 작업 상태를 완전히 잃어버림

    • 터미널 히스토리, 로그 파일, 실행 중이던 서버 등
    • 다시 돌아왔을 때 개발 환경을 재구성해야 함.
    • 새로운 feature에서 의존성을 삭제하거나 추가했다면 의존성 관련 작업도 다시 해야 함.
  2. 동시 작업이 불가능

    • hotfix 브랜치에서 빌드가 돌아가는 동안 원래 작업을 할 수 없음.
    • 두 브랜치를 동시에 비교하기 어려움.
  3. stash stack 관리의 어려움

    git stash list
    # stash@{0}: WIP: user dashboard
    # stash@{1}: WIP: some old work
    # stash@{2}: WIP: another feature
    • 어떤 stash가 어떤 브랜치용인지 헷갈림
    • git stash pop을 잘못된 브랜치에서 실행하면 conflict 지옥



Worktree를 사용한 해결

같은 상황, Worktree 사용

# 1. hotfix용 worktree 생성
git worktree add ../my-project-hotfix v1.2.3 -b hotfix/urgent-bug

# 2. 새 터미널 열어서 hotfix 디렉토리로 이동
cd ../my-project-hotfix

# 3. 버그 수정 후 커밋
# ... 수정 작업 ...
git add .
git commit -m "Fix urgent bug"

# 4. 원래 터미널은 그대로!
# feature/user-dashboard에서 계속 작업 가능

장점

  1. 원래 작업 환경이 그대로 유지됨

    • feature 브랜치 디렉토리는 전혀 건드리지 않음
    • 실행 중이던 개발 서버, 열어둔 파일, 터미널 히스토리 모두 유지
  2. 동시 작업 가능

    • VSCode 창 2개 열어서 동시에 작업
    • hotfix 브랜치에서 테스트 돌리면서, feature 브랜치에서 개발 계속
  3. 브랜치 비교가 쉬움

    # 두 디렉토리를 직접 비교
    diff -r my-project/src my-project-hotfix/src
    
    # 또는 IDE에서 폴더 비교 기능 사용
  4. Context Switching 비용 없음

    • 브랜치를 바꾸는 게 아니라 디렉토리를 바꾸는 것
    • 파일 시스템 변경 없음, IDE 리인덱싱 없음



실전 시나리오: 버전 관리 상황

더 구체적인 예시를 들어보겠습니다. 실무에서 자주 발생하는 상황입니다.

배경

  • Production 버전: v1.2.3
  • 현재 작업 중인 브랜치: feature/new-dashboard (v2.0.0 기능)
  • 갑자기 v1.2.3에서 치명적인 버그 발견

Stash 방식

# 1. 현재 작업 중단하고 저장
git stash save "WIP: new dashboard - half done with chart component"

# 2. v1.2.3 태그로 이동
git checkout v1.2.3
# ⚠️ 여기서 모든 파일이 v1.2.3 상태로 변경됨
# ⚠️ node_modules도 다시 설치해야 할 수 있음

# 3. hotfix 브랜치 생성
git checkout -b hotfix/v1.2.3-critical-bug

# 4. 버그 수정
vim src/api/auth.js  # v1.2.3 코드 구조
npm install          # v1.2.3 의존성
npm test            # v1.2.3 환경에서 테스트

# 5. 커밋 및 푸시
git add .
git commit -m "Fix critical auth bug in v1.2.3"
git push origin hotfix/v1.2.3-critical-bug

# 6. 다시 feature 브랜치로 복귀
git checkout feature/new-dashboard
# ⚠️ 다시 모든 파일이 변경됨
# ⚠️ node_modules 다시 설치

# 7. stash 복원
git stash pop
# ⚠️ 만약 package.json이 달라졌다면?
# ⚠️ conflict 발생 가능성

소요 시간: 약 5-10분 (의존성 재설치 포함 시 더 길어짐)

문제점

  • 브랜치 전환할 때마다 개발 환경 재구성
  • IDE가 파일 변경 감지하고 리인덱싱
  • node_modules, build 디렉토리 등도 변경됨
  • 원래 작업 컨텍스트(열어둔 파일, 터미널 상태 등) 손실

Worktree 방식

# 1. hotfix용 worktree 생성 (원래 디렉토리 그대로 유지)
git worktree add ../my-project-v1.2.3-hotfix v1.2.3 -b hotfix/v1.2.3-critical-bug
# ✅ 현재 디렉토리는 전혀 변경 없음
# ✅ feature/new-dashboard 작업 환경 그대로

# 2. 새 터미널 또는 VSCode 창에서 hotfix 디렉토리로 이동
cd ../my-project-v1.2.3-hotfix

# 3. 버그 수정 (독립적인 환경)
npm install          # v1.2.3 전용 node_modules
vim src/api/auth.js  # v1.2.3 코드
npm test            # v1.2.3 환경에서 테스트

# 4. 커밋 및 푸시
git add .
git commit -m "Fix critical auth bug in v1.2.3"
git push origin hotfix/v1.2.3-critical-bug

# 5. 원래 디렉토리로 돌아가기
cd ../my-project
# ✅ feature/new-dashboard 환경 그대로 유지됨
# ✅ 실행 중이던 dev server도 그대로
# ✅ IDE에서 열어둔 파일도 그대로

# 6. hotfix worktree 정리 (선택사항)
git worktree remove ../my-project-v1.2.3-hotfix

소요 시간: 약 1-2분

장점:

  • 원래 작업 환경 완전히 보존
  • 두 환경을 동시에 유지 가능
  • IDE 창 2개로 코드 비교 가능
  • 브랜치 전환 비용 없음



Worktree 주요 명령어

1. Worktree 생성

# 기본 사용법
git worktree add <path> <branch>

# 새 브랜치 생성하면서 worktree 추가
git worktree add ../my-project-feature feature/new-feature

# 기존 브랜치로 worktree 추가
git worktree add ../my-project-main main

# 특정 커밋/태그로 worktree 추가
git worktree add ../my-project-hotfix v1.2.3 -b hotfix/bug-fix

2. Worktree 목록 확인

git worktree list

# 출력 예시:
# /Users/me/my-project              abc123 [main]
# /Users/me/my-project-feature      def456 [feature/new-feature]
# /Users/me/my-project-hotfix       ghi789 [hotfix/bug-fix]

3. Worktree 제거

# worktree 제거 (브랜치는 유지)
git worktree remove ../my-project-hotfix

# 또는 디렉토리를 먼저 삭제한 경우
git worktree prune

4. Worktree 정보 확인

# 특정 worktree 정보
git worktree list --porcelain



Worktree vs Stash 비교표

항목StashWorktree
Context Switching브랜치 전환 시 파일 변경디렉토리 이동만
IDE 리인덱싱매번 발생없음
동시 작업불가능가능
작업 환경 유지손실됨완전 보존
코드 비교diff 명령어만폴더 비교, 2개 IDE 창
의존성 관리공유 (충돌 가능)독립적
디스크 사용량적음많음 (각 worktree마다 복사)
학습 곡선낮음중간
사용 시나리오간단한 임시 저장복잡한 멀티태스킹



"그냥 git clone 여러 번 하면 되지 않나요?"

사실 저도 예전엔 이렇게 했습니다...

git clone https://github.com/user/my-project.git my-project
git clone https://github.com/user/my-project.git my-project-hotfix

언뜻 worktree와 비슷해 보인다. 하지만 결정적인 차이 3가지가 있습니다.

1. 디스크 공간

Clone은 .git 디렉토리를 매번 복사합니다. 저장소가 1GB면 3개 clone = 3GB.
Worktree는 .git을 공유합니다. 저장소가 1GB면 worktree 10개 만들어도 ~1.1GB.

2. fetch/pull 동기화

Clone은 각 디렉토리마다 따로 git fetch 해야 합니다.
Worktree는 한 곳에서 fetch하면 모든 worktree가 자동 동기화가 됩니다.

3. 브랜치 안전장치

Clone은 실수로 같은 브랜치를 여러 곳에서 체크아웃할 수 있습니다.
Worktree는 같은 브랜치를 동시에 체크아웃할 수 없습니다. 이로 인해 혹시 모를 실수를 방지할 수 있습니다.


비교표:

항목Git CloneGit Worktree
디스크 공간저장소 크기 × N저장소 크기 × 1
fetch/pull각각 따로한 번에 모두 동기화
브랜치 중복가능 (위험)불가능 (안전)

같은 프로젝트에서 브랜치만 바꿔가며 작업한다면 Worktree가 압도적으로 효율적입니다.




결론

TSBM 모임에서 우연히 들은 worktree 이야기는 제 작업 방식을 완전히 바꿔놓았습니다.

이전에는 "Git을 충분히 잘 안다"고 생각했는데, worktree는 5년 넘게 써온 나도 몰랐던 기능이었습니다. 부끄럽기도 했지만, 동시에 즐거웠습니다.

개발자로서 가장 즐거운 순간은 이런 게 아닐까.

다른 개발자들과 이야기하면서, "아 이런 방법도 있구나!" 하고 배우는 것. 그리고 그걸 바로 적용해서 생산성이 올라가는 걸 체감하는 것.

Worktree는 특히 이런 상황에서 빛을 발하는 것 같습니다.

  • 여러 버전을 동시에 관리해야 할 때
  • 긴급 hotfix가 자주 발생하는 환경
  • feature 브랜치를 오가며 작업할 때
  • 브랜치 간 코드 비교가 잦을 때

물론 단점도 있긴 합니다. 디스크 공간을 더 많이 쓰고, 처음엔 개념이 좀 헷갈릴 수 있다. 하지만 한번 익숙해지면 돌아갈 수 없습니다.

브랜치 전환에 1분이라도 아까운 당신,
stash stack 관리에 지친 당신,

한번 worktree를 써보시면, 분명히 생산성이 올라갈 것이라고 생각합니다. :)

저도 개발팀 내부에서 worktree에 대해서 공유하고, 사용해보려고 합니다.


참고자료

profile
Software Engineer

0개의 댓글