TECH 으로 돌아가기
TECH HACKER NEWS 오늘 7분 읽기 32 READS

AI 코딩 에이전트가 다시 소환한 기능, 깃 워크트리와 Magit

AI 코딩 에이전트가 다시 소환한 기능, 깃 워크트리와 Magit
SOURCE IMAGE · HACKER NEWS

깃 워크트리(git worktree)는 2015년 7월 깃 2.5에 추가된 뒤 10년 넘게 존재해 왔지만, 많은 개발자에게 여전히 낯선 기능이다. 브랜치 기반 워크플로가 워낙 잘 작동하기 때문이다. 브랜치를 만들고, 작업하고, 병합하고, 지우고, 다시 시작하는 반복만으로도 대부분의 일은 처리된다. Emacs Redux의 필자 역시 워크트리를 몰라도 오래 불편함을 느끼지 못했다고 고백한다. 그가 뒤늦게 워크트리를 들여다보게 된 계기는 뜻밖에도 AI 코딩 에이전트였다. Claude Code 같은 도구가 작업마다 워크트리를 만들어, 여러 에이전트나 같은 에이전트의 여러 세션이 하나의 저장소에서 서로 간섭하지 않고 병렬로 일하게 하기 때문이다. 어느 순간 프로젝트 디렉터리가 비슷한 이름의 형제 폴더로 가득 찼고, 대체 무슨 일이 벌어지는지 이해할 필요가 생긴 것이다.

브랜치로는 부족해지는 지점

브랜치는 특정 커밋을 가리키는 이동 가능한 포인터일 뿐이라 만드는 데 사실상 비용이 들지 않는다. 문제는 저장소가 작업 디렉터리를 하나만 갖는다는 점이다. 두 브랜치를 동시에 다루려면 그 하나의 디렉터리를 이리저리 전환해야 한다. 절반쯤 진행한 작업을 스태시하거나 커밋한 뒤 다른 브랜치를 체크아웃하고, 일을 마친 다음 원래 브랜치로 돌아와 다시 복원하는 익숙한 절차다. 동작하기는 하지만 번거롭고, 두 브랜치가 프로젝트를 서로 다른 빌드 상태로 남겨 둘 때는 전환할 때마다 절반쯤을 다시 컴파일해야 하는 상황까지 겹친다.

워크트리는 같은 저장소에 추가 작업 디렉터리를 붙이는 방식으로 이 문제를 푼다. 새 디렉터리는 해당 브랜치의 완전한 체크아웃이지만, 기존 메인 체크아웃은 그대로 유지된다. 객체 데이터베이스, 레퍼런스, 스태시, 원격 저장소는 모두 공유된다. 워크트리는 클론이 아니므로 한쪽에서 페치하면 전체에 반영되고, 생성도 거의 즉시 끝난다. 다만 워크트리마다 자체 HEAD와 인덱스를 갖고, 깃은 한 가지 규칙을 강제한다. 하나의 브랜치는 동시에 한 워크트리에서만 체크아웃될 수 있다.

언제 값어치를 하는가

워크트리가 유용한 상황은 두 가지 일이 같은 시점에 일어나야 할 때다. 한 브랜치에서 긴 테스트를 돌리면서 다른 브랜치에서 작업하거나, 진행 중인 작업을 건드리지 않고 PR을 리뷰하거나, 요즘 가장 많이 언급되는 사례인 AI 에이전트가 격리된 환경에서 작업하도록 하는 경우다. 대가는 비교적 적당하다. 작업 파일이 디스크에 중복으로 존재하고, 깃이 추적하지 않는 것들, 즉 의존성이나 빌드 캐시, node_modules 같은 항목은 워크트리마다 다시 세팅해야 한다. Elisp라면 부담이 거의 없지만, 규모가 큰 JVM이나 JS 프로젝트에서는 이 콜드 빌드 캐시가 이 방식의 가장 큰 단점이 된다.

필자는 논의를 잠시 넓혀 최근 버전 관리 분야에서 가장 흥미로운 프로젝트로 Jujutsu(jj)를 언급한다. jj는 깃과 호환되는 VCS로, 워크트리가 해결하려는 문제 자체를 상당 부분 없앤다. jj에서는 작업 복사본이 곧 커밋이며 작업하는 동안 자동으로 스냅샷된다. 스테이징 영역도 스태시도 없는데, 잃어버리거나 방해가 될 커밋되지 않은 상태가 아예 없기 때문이다. 그래서 컨텍스트 전환이 언제나 안전하다. 병렬 작업 디렉터리(jj workspace)도 정식으로 지원하고, 거의 모든 작업을 되돌릴 수 있게 하는 오퍼레이션 로그도 있다. 마지막 특성은 AI 에이전트 진영이 jj에 관심을 갖는 이유 중 하나다. 기존 깃 저장소 위에 얹어 쓰는 코로케이티드(colocated) 방식도 가능해, 동료들과 Magit은 여전히 평범한 깃 저장소로 인식한다.

Emacs와 Magit에서의 실전

다시 Emacs로 돌아오면, Magit은 이미 오래전부터 Z 키 뒤에 워크트리 지원을 숨겨 두고 있었다. 가장 좋은 점은 따로 배울 것이 없다는 것이다. 워크트리마다 자체 상태 버퍼를 갖고, 모든 Magit 명령은 현재 버퍼가 속한 워크트리를 대상으로 동작한다. 전환 수단은 Z g 하나면 충분하며, 이마저도 다른 상태 버퍼를 방문하는 단축키에 지나지 않는다. 상태 버퍼는 저장소의 모든 워크트리를 보여 주고, 어느 것에서든 RET로 이동할 수 있다.

실무적으로 필자가 권하는 요령은 명확하다. 워크트리는 메인 체크아웃 안에 중첩하지 말고 형제로, 설명이 담긴 이름을 붙여 만들라는 것이다. 중첩하면 grep, find 같은 도구가 혼란을 겪는다. Magit의 브랜치 선택 화면은 다른 워크트리에서 체크아웃된 브랜치에 해당 경로를 표시하고 두 번째 체크아웃을 거부하는데, 이는 Magit이 까다로워서가 아니라 깃의 규칙이다. 브랜치가 체크아웃되지 않는 이유는 대개 이것이다. 또한 각 워크트리는 project.el이나 Projectile 관점에서 독립된 프로젝트로 취급되어 프로젝트 전환과 검색이 자연스럽게 동작한다. 작업이 끝난 워크트리는 Z k나 git worktree remove로 지우면 되고, 디렉터리만 손으로 삭제했다면 git worktree prune이 남은 정리를 맡는다. 필자의 요즘 흐름은 에이전트가 워크트리에서 일하는 동안 그 변경을 Magit에서 리뷰하고, 브랜치가 병합되면 워크트리를 없애는 방식으로 자리잡았다. 오래 눈에 띄지 않던 기능이 워크플로가 바뀌면서 비로소 쓸모를 드러낸 셈이다.

SOURCE · HACKER NEWS
원문 전체 보기 → https://emacsredux.com/blog/2026/09/02/working-with-git-work...
SHARE
NEXT · CHOOSE

변화를 읽었다면,
내가 만들 수익 구조를 고릅니다.

정보를 더 모으는 데서 멈추지 않고, 광고·외주·판매·중개·구독 중 내 상황에 맞는 출발점을 정해보세요.

21가지 수익 구조 살펴보기
처리 중...