[Git] Worktree

1. Git Worktree란?

Manage multiple working trees attached to the same repository. A git repository can support multiple working trees, allowing you to check out more than one branch at a time.

공식문서에 따르면 Git worktree는 하나의 Git 저장소(.git)를 공유하면서, 서로 다른 branch를 동시에 checkout할 수 있도록 해주는 기능이다.

여기서 Worktree는 작업 디렉터리를 지칭하는 단어인 것 같다.

기존의 Git은 하나의 Worktree 하나의 HEAD만 존재하므로, 한 시점에 하나의 브랜치만 체크아웃할 수 있다.

버그 수정, 코드 리뷰, 병렬 개발 등 동시에 여러 브랜치를 사용하고 싶으면 Git 저장소(.git)을 사용할 수 없었고, 다른 디렉터리에 완전히 분리된 새로운 Git 저장소를 clone해야 했다.

하지만 이제 Git의 Worktree를 사용하면, 하나의 Git 저장소(.git)을 여러 worktree에서 공유할 수 있다.

여러 작업 디렉터리에서 하나의 .git을 공유할 수 있다는 말이다.

.git을 공유하면서 독립된 환경에서 코딩, 빌드, 테스트, 실행이 가능해졌다.

또한 물리적으로 작업 디렉터리가 분리됨에 따라서 파일 충돌 없이 병렬 작업 가능하다.

Multi Agent를 활용한 병렬 작업을 위해서 필수가 될 기술이다.

.git (공유)
 ├─ worktree A (main)
 ├─ worktree B (feature/login)
 └─ worktree C (hotfix/critical)

2. 탄생 배경

Worktree는 결국 Git의 Branch 전환 비용과 제약을 해결하기 위해 등장했다.

  • Git Branch 전환 시 Context Switching 발생한다
    • 병렬 작업 불가능
      • 다른 브랜치의 버그를 바로 수정하려면 복잡하다.
      • 작업 중인 변경사항 stash 필요
      • Stash → Checkout → 작업 → 다시 Checkout → 다시 Stash
      • 중간에 Stash가 꼬이는 문제가 많이 발생해서 머리 아팠다.
    • 환경 의존 프로젝트의 불편함
      • 프론트엔드, 워드프레스, 대규모 모노레포 등에서 브랜치 전환 시 실행 환경이 파괴된다.
      • 환경변수 재설정 필요
    • 캐싱 초기화
      • 빌드 결과물, node_modules, vendor 등 재생성 필요

Branch는 논리적 개념이고, Worktree는 물리적 디렉터리라는 점에 착안하여 “Branch는 하나의 Worktree에 묶일 필요가 없다”라는 철학으로 도입되었다.


3. 사용법

가. add

# 기본 문법
git worktree add [options] <디렉터리 생성 위치> [<브랜치 이름>]
Code language: HTML, XML (xml)
# 기존 브랜치로 worktree 생성
git worktree add <디렉터리 생성 위치> <브랜치 이름>
Code language: HTML, XML (xml)
  • <디렉터리 생성 위치>
    : 보통 ../디렉터리_이름과 같이 상위 디렉터리로 한번 올라간다.
    : 바로 옆에 새 Worktree를 만들 수 있기 때문에 관리가 편하다.
../을 많이 사용하는 이유

# 새 브랜치로 worktree 생성
git worktree add -b < 브랜치 이름> <디렉터리 생성 위치>
Code language: HTML, XML (xml)
  • -b <새 브랜치 이름> : options 영역으로 해석되기 때문에 path 앞에 와야 한다. 순서가 뒤바뀌어 혼란스럽다.

# 특정 커밋 기준으로 생성 (detached HEAD)
git worktree add <디렉터리 생성 위치> <커밋 Hash 값>
Code language: HTML, XML (xml)
  • <커밋 Hash 값> : a1b2c3d과 같이 커밋의 Hash 값을 넣으면 해당 커밋을 쉽게 재현할 수 있다.

나. list

# 기본 조회
git worktree list

# 상세 내용 포함
git worktree list --verbose
Code language: PHP (php)

다. lock

# 잠그기
git worktree lock <디렉터리 위치>

# 해제
git worktree unlock <디렉터리 위치>
Code language: HTML, XML (xml)
  • 실수로 삭제되는 것 방지
  • 장기 작업용 worktree에 적합

라. prune

# 실제 디렉터리는 삭제됐는데 Git 메타데이터만 남아있는 경우 정리
git worktree prune

# 삭제 대상 미리 확인
git worktree prune --dry-run
Code language: PHP (php)

실제 디렉터리는 삭제됐는데 Git 메타데이터만 남아있는 경우 정리한다.


마. delete

# 기본 삭제
git worktree remove <디렉터리 위치>
Code language: HTML, XML (xml)

잠금 상태면 삭제할 수 없다.

# 강제로 삭제
git worktree remove --force <디렉터리 위치>
Code language: HTML, XML (xml)

물론 무시하고 강제로 삭제할 수 있다.


3. 멀티 에이전트 병렬 작업

Tistory2WordPress를 통해서 Skill을 통해 하나의 에이전트를 능숙하게 컨트롤하는 것에 성공했다.

단, 개발자의 개입이 늘어난 만큼 생산성이 하락했다.

개발 속도를 높이기 위해서 여러 에이전트를 사용하여 병렬로 작업을 하는 방법을 탐구할 필요가 있다.

이 단계에서 각 에이전트 간의 독립된 개발환경을 보장하기 위해서 worktree가 필요하다.

어떻게 멀티 에이전트를 활용하여 생산성을 높일 수 있을지 전략을 세워보자.


가. 파일 시스템 분리

Agent 간의 충돌을 최소화해야 한다.

그래서 하나의 Agent에 하나의 Worktree를 할당한다.

.git (shared)
 ├─ wt-main/        → 기준 브랜치 (read-only)
 ├─ wt-agent-1/     → agent/refactor
 ├─ wt-agent-2/     → agent/test
 ├─ wt-agent-3/     → agent/docs

.git만 공유하고 파일 시스템은 완전히 분리한다.

main worktree는 read-only(chmod -R a-w wt-main)로 만든다.


나. 병합 정책

worktree를 사용하면 충돌은 병합 단계에서만 발생한다.

Agent끼리 직접 merge 금지한다.

PR을 통해서만 코드를 통합할 수 있도록 제한한다.

사람 또는 상위 Orchestrator만 merge할 수 있도록 한다.


다. 코드 리뷰

가장 큰 병목은 Agent가 생성한 코드를 개발자가 리뷰하는 과정에서 발생함.

지금처럼 모든 코드를 읽고 고치면서 100% 내 맘처럼 개발할 수 있지만 생산성이 떨어진다.

어떻게 하면 통제력을 유지하면서도 개발자의 개입을 최소화할 수 있을까?

코드 신뢰성을 보장할 중간 관리자 Agent가 필요해 보인다.

반드시 지켜져야할 최소한의 규칙을 잘 준수하고 있는지 평가하는 Agent 또는 시스템이 필요해 보인다.

오늘 주제는 Worktree기 때문에 멀티 에이전트를 활용한 병렬 작업에서 Worktree가 어떻게 사용될 수 있을지만 정리해보았다.

멀티 에이전트를 활용한 병렬 작업에 대해서는 더 많은 연구가 필요한 관계로 따로 시간을 내서 글을 작성하도록 한다.

(그나저나 적고 보니깐 왕정국가의 시스템과 비슷하다?)


댓글 남기기