git worktree로 '리뷰 가능한 크기'를 유지하는 방법
요약
AI가 생성한 대규모 코드를 효과적으로 검토하기 위해 작업을 '리뷰 가능한 크기'로 분할하는 방법을 제시합니다. git worktree를 사용하여 브랜치별 작업 폴더를 분리하고, 이슈 단위로 태스크를 나누어 관리하며 AI에게 순차적으로 개발을 요청하는 워크플로우를 설명합니다.
핵심 포인트
- 작업의 복잡성을 줄이기 위해 기능을 작은 단위(이슈)로 분할해야 합니다.
- git worktree는 하나의 리포지토리에서 여러 브랜치를 별도 폴더에 열어볼 수 있게 해줍니다.
- 각 이슈별로 독립적인 브랜치와 MR을 생성하여 검토 범위를 명확히 합니다.
- AI에게 작업 요청 시, 이슈 번호를 활용해 지시를 구조화하고 추적성을 높일 수 있습니다.
AI에게 코드를 작성하게 되면서 겪었던 어려움은, 그 코드를 읽어내는 양이었습니다.
"이 기능을 만들어줘"라고 요청하면 DB부터 API, 화면까지 의존하는 모든 곳을 한 번에 만들어줍니다. 감사한 일이지만, 변경되는 파일이 많아질수록 사람이 직접 검토하기가 어려워졌습니다.
그래서 지금은 먼저 '리뷰 가능한 크기'로 작업을 분할하고 있습니다. 단위별로 태스크를 나누어 이슈(issue)를 만들고, git worktree를 사용해 작업 폴더도 분리합니다. 이 글에서는 worktree의 작동 방식과 제가 실제로 사용하는 방법을 정리했습니다.
git worktree는 하나의 리포지토리에서 여러 개의 작업 폴더를 생성할 수 있는 기능입니다.
일반적으로는 리포지토리가 하나에 작업 폴더도 하나이며, 다른 브랜치를 보고 싶을 때는 git switch로 내부 내용을 교체합니다. 하지만 worktree를 사용하면 브랜치별로 별도의 폴더를 준비하여 나란히 열어둘 수 있습니다.
~/Documents/
├── myapp/ ← 본체
└── myapp-wt/
...
여기서 중요한 점은, 이력(history)을 본체와 공유한다는 것입니다. clone을 여러 번 하는 것과 달리 커밋이나 브랜치는 한 곳에 있으므로, worktree에서 커밋한 내용은 본체에서도 그대로 볼 수 있습니다.
사용하는 명령어는 거의 이것뿐입니다.
# 원격의 최신 기본 브랜치부터 브랜치를 분기하여 별도의 폴더로 만듭니다
git fetch origin
git worktree add ../myapp-wt/feature-db -b feature/xxx-db origin/main
...
기준점은 git fetch로 가져온 원격의 기본 브랜치입니다(예시에서는 origin/main). 로컬 브랜치는 업데이트를 잊어버려 오래된 상태일 수 있기 때문입니다.
계기는 실패였습니다.
한 기능을 AI에게 만들게 했을 때, 변경 사항이 통째로 하나의 커밋에 들어가 버렸습니다. 티켓은 '관리 화면'과 'API'로 나뉘어 있었고, '이는 범위 외'라고도 적혀 있었는데, 브랜치와 MR(Merge Request)을 하나로 진행한 것이 원인이었습니다.
다음에는 반성하여, 기능을 먼저 세부적인 티켓으로 분할한 후 AI에게 순서대로 만들게 했습니다. 이때는
기능의 단위는 프론트엔드, 백엔드, 테스트를 한 묶음으로 잘라서 처리하면 리뷰하기가 수월합니다. 크기는 파일 수보다는 변경된 코드 라인 수로 보는 것이 좋을 것 같습니다. 파일 수가 적더라도 라인 수가 많으면 분리하는 편이 읽기 쉽습니다.
분리한 단위마다 GitLab이나 GitHub에 이슈를 생성합니다.
이는 평소 태스크 관리하는 곳(Notion, Linear, Obsidian 등)에서 진행해도 괜찮습니다.
기준은 티켓이나 요구사항입니다.
티켓에는 요청 사항이 2~3줄밖에 적혀 있지 않은 경우도 있으므로, AI와 질의응답을 거치면서 완료 조건, 깨지기 쉬운 부분, 아직 결정되지 않은 부분을 명확히 한 후에 이슈로 만듭니다.
큰 기능이라면 부모(parent) 이슈를 하나 만들고 전체 순서와 충돌할 가능성이 있는 파일을 작성합니다. 단위별 이슈에는 '해야 할 일'과 '하지 않을 일'을 적습니다.
브랜치와 MR은 이슈당 1개씩입니다. AI에게는 이슈 번호를 전달하고, 본문과 댓글을 읽게 한 후 생성하도록 합니다. 매번 지시를 대화에 쓸 필요가 없어지고, 무엇을 어디까지 했는지 나중에 이슈에서 추적할 수 있습니다.
동시에 진행할 그룹만 worktree를 만들고 각각 AI에게 전달합니다. 1개의 worktree는 1개 이슈, 1개 브랜치, 1개 MR, 1세션을 의미합니다.
마이그레이션과 공통 컴포넌트에 관련된 단위는 나란히 배치하지 않습니다. 마이그레이션은 동시에 만들면 실행 순서가 바뀌고, 공통 컴포넌트는 다른 모든 것과 충돌하기 때문입니다.
동시에 진행할 개수는 작업의 난이도와 컴퓨터 사양을 보고 결정합니다. 보통 2개인 경우가 많지만, 3개를 나란히 배치하기도 합니다. worktree 내에서 테스트까지 실행하는 경우, 해당 worktree 전용 개발 환경(Docker)도 구축하므로 메모리를 많이 사용합니다.
주의하는 점은 리뷰 대기열이 너무 쌓이지 않도록 하는 것입니다. 만드는 것이 더 빠르기 때문에, 쌓아두면 결국 한꺼번에 읽게 됩니다.
worktree를 항상 사용하는 것은 아닙니다. 평소에는 메인 폴더에서 최신 기본 브랜치로부터 분기한 브랜치로 작업합니다. worktree는 병렬 처리가 필요할 때와, 메인에서 다른 작업을 하는 도중에 리뷰용 브랜치를 열고 싶을 때만 사용합니다. 다 사용하면 삭제합니다.
배치는 리포지토리 외부(예: myapp-wt/)에 합니다.
여러 개를 나란히 돌려보면서 놀랐던 점은, AI가 자신의 담당 업무를 추측해서 모두가 같은 답을 내놓았다는 것입니다.
당시에는 AI 세션을 전부 메인 폴더에서 띄우고 있었기 때문에, 현재 위치도, 현재 브랜치도, 커밋되지 않은 변경 사항도 모두 똑같이 보였습니다. 거기서 '자신의 담당은 무엇일까'를 추측하게 하니, 모두가 같은 티켓을 주장했습니다. 지금은 worktree마다 AI를 띄우고, 어느 worktree에서 어떤 브랜치로 무엇을 할지 첫 지시에 반드시 작성합니다.
worktree를 여러 개 만들고 AI를 나란히 배치하면, 어디서 무엇이 돌아가고 있는지 파악하기 어려워집니다. 이를 보완하기 위해 다음 도구들을 조합하여 사용하고 있습니다.
worktree와 AI 터미널을 한 곳에서 다룰 수 있는 앱입니다. worktree를 만들면 그 작업 공간의 탭이 열리고, 거기서 Claude Code나 Codex 등을 구동할 수 있습니다. 어느 worktree에서 어떤 AI가 작동하는지 한 화면에서 볼 수 있어, 여러 개를 배치해도 길을 잃지 않습니다.
구현은 Claude Code로 하고, 리뷰는 Codex로 하는 식으로 탭별로 역할을 분리하기도 합니다. worktree 생성/삭제 시 스크립트를 호출할 수 있어서, worktree를 만들면 개발 환경 준비가 자동으로 실행되고, 삭제하면 정리 작업이 자동으로 돌아가도록 했습니다.
Whiteboard Desktop이라는 앱에 AI가 작성한 코드 흐름이나 리뷰 결과를 그려 넣습니다. 시작부터 끝까지의 흐름이 프레임으로 연결되어 있고, 프레임을 누르면 해당 라인의 코드가 열립니다. 차이점을 처음부터 읽기 전에 전체적인 형태를 파악할 수 있어, 리뷰 진입점으로 사용합니다.
그 외에도 자주 하는 작업은 Claude Code의 스킬(AI용 절차서)로 직접 만들고 있습니다.
모든 것을 worktree에 넣을 수는 없습니다. 다음과 같은 경우에는 사용하지 않습니다.
- 1~2개의 작은 수정. 그냥 1개 브랜치로 하는 것이 빠릅니다.
- 사양이 확정되지 않은 경우. 먼저 1개로 시도해 보고, 확정된 후에 분리합니다.
- 의존성이 강해서 순차적으로만 진행할 수 있는 경우
worktree는 '병렬로 빠르게 만들기 위한 도구'로 소개되는 경우가 많을 것 같습니다. 저에게는 병렬로 빨리 구현하는 것도 맞지만, 리뷰하기 쉽게 하는 용도로 사용하고 있습니다.
(아직 인간의 확인과 수정이 필요하다고 생각하므로)
본론은 어디까지나 '리뷰 가능한 크기'로 나누는 것입니다. worktree는 그것을 지탱하는 보조 수단일 뿐입니다. AI가 아무리 많이 써주게 된 지금이야말로, 읽는 쪽의 편의에 따라 구분할 수 있는 메커니즘이 필요하다고 생각합니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기