본문으로 건너뛰기

© 2026 Molayo

Zenn헤드라인2026. 05. 14. 23:05

Git Worktree CLI 「vibe」로 Claude Code와 병행하는 개발 플로우 만들기

요약

본 기사는 여러 브랜치를 병행 작업하는 개발 환경의 비효율성을 해결하기 위해 `git worktree`와 CLI 도구 `vibe`를 결합한 워크플로우를 소개합니다. `git worktree`는 여러 클론보다 가볍고 안전하게 여러 브랜치 작업을 가능하게 하며, `vibe`는 여기에 `.env` 복사, `pnpm install` 재실행 등 수동으로 처리해야 하는 후속 작업을 자동화하여 '바로 작업 가능한' 격리된 환경을 구축합니다. 특히 Claude Code와 같은 AI 에이전트의 서브 에이전트 작업 시에도 이 자동화가 적용되어 일관성을 높입니다.

핵심 포인트

  • `git worktree`는 여러 브랜치 작업을 위해 리포지토리를 여러 번 클론하는 것보다 디스크 용량과 속도 면에서 압도적으로 효율적이다.
  • `vibe` CLI는 `git worktree add` 이후 필요한 `.env` 복사, 패키지 설치 등 후속 작업을 선언적(`.vibe.toml`)으로 자동화하여 개발 환경 전환 비용을 최소화한다.
  • AI 에이전트(예: Claude Code)의 서브 에이전트를 격리된 `worktree`로 실행할 때도 `vibe`가 정의한 초기화 훅(`pre_start`, `post_start`)이 적용되어 일관성을 유지한다.
  • Worktree를 사용하면 여러 브랜치의 상태를 한눈에 파악할 수 있어 개발 과정에서의 오조작을 방지하는 이점이 있다.

TL;DR

git worktree

는 "같은 리포지토리에서 여러 브랜치를 병행 작업하기" 위한 메커니즘입니다. 여러 번 클론(clone)하는 것보다 압도적으로 가볍고 안전합니다. CLI vibe는 worktree의 생성, 삭제, 이동을 거의 제로(zero) 조작 수준으로 줄여줍니다.

  • Claude Code의 서브 에이전트(sub-agent)를
    isolation: "worktree"

로 실행하면, 메인 작업 디렉토리를 더럽히지 않고 AI에게 시행착오를 겪게 할 수 있습니다.

  • Claude Code의
    WorktreeCreate

/
WorktreeRemove

hook에서
git worktree

대신
vibe start

를 호출하면, AI 측의 격리된 worktree에도 .env 복사나 post_start가 적용됩니다.

시작하며

AI 에이전트와 함께 코드를 작성하게 되면서, "동시에 실행되는 브랜치의 수"가 급격히 늘어났습니다. Claude Code에게 하나의 작업을 맡기고 있는 동안, 다른 브랜치에서 자신은 별도의 수정을 진행합니다. 리뷰용 브랜치에서 빠르게 동작 확인을 하고 싶어집니다. 실험용 브랜치를 만들어 버릴 것을 전제로 아이디어를 시험해보고 싶어집니다.

이것을 git switch로 하나의 작업 디렉토리 안에서 전환하며 수행하는 것은 이제 무리입니다. node_modules의 교체, 빌드 결과물의 오염, .env의 덮어쓰기, 에디터나 LSP(Language Server Protocol)의 리로드, AI 에이전트의 작업 중단 ── 전환 비용이 쌓여 사고의 흐름이 끊깁니다.

그래서 Git Worktree가 있습니다. 하지만 순수한 git worktree 명령어만 사용하면 ".env 복사", "pnpm install 재실행", "핫 훅(hot hook) 설정" 등을 매번 수동으로 처리해야 하므로 결국 번거롭습니다. 이를 통째로 관리해 주는 CLI로서 vibe를 만들고 있습니다.

이 기사는 Qiita에 나누어 썼던 2편의 소개 기사를 다시 정리한 것입니다. Zenn 독자들을 위해 특히 Claude Code와의 연동을 주축으로 삼아 재구성했습니다.

Git Worktree의 이점

애초에 worktree를 사용해야 하는가라는 점부터 정리하겠습니다. "브랜치마다 디렉토리를 나누고 싶다"는 목적뿐이라면 git clone을 여러 번 하면 실현할 수 있습니다. 다만, 여러 번 클론하는 것과 비교했을 때 worktree에는 4가지 확실한 이점이 있습니다.

1. 디스크 용량 절약

여러 번 클론하면 각각이 완전한 .git을 가집니다. 대규모 리포지토리에서는 .git만으로 수백 MB ~ 수 GB에 달하는 일이 드물지 않으며, 브랜치마다 클론을 생성하면 금방 디스크가 가득 찹니다.

Worktree는 .git 오브젝트를 하나의 리포지토리에서 공유합니다. 추가된 브랜치마다 늘어나는 것은 워킹 트리(working tree)와 관리용의 가벼운 메타데이터뿐입니다.

2. 클론 시간 단축

최초 클론은 한 번뿐입니다. 이후에는 git worktree add만으로 새로운 작업 디렉토리를 얻을 수 있습니다. 네트워크 통신도 리포지토리 전체의 파일 복사도 발생하지 않으므로, 디렉토리를 통째로 복사하는 것에 비해 대폭 빠릅니다.

3. Git 조작의 일원 관리

git fetch는 한 번으로 모든 worktree에 반영됩니다. 태그, 브랜치, 리퍼크(refspec)도 당연히 한 곳입니다. 여러 번 클론하면 "저쪽 clone에서는 fetch 했지만, 이쪽은 아직"과 같은 차이가 발생하지만, worktree에서는 그런 일이 없습니다.

4. 오조작 방지

git worktree list를 통해 현재 뻗어 있는 가지의 전체 모습을 한눈에 볼 수 있습니다. "어디에 어떤 브랜치가 있었더라?"를 머릿속에 기억해 둘 필요가 없어지며, 잘못된 디렉토리에서 조작하는 사고가 줄어듭니다.

$ git worktree list
/path/to/repo deadbeef [main]
/path/to/repo-feat-foo cafebabe [feat/foo]
...

vibe의 기본: 한 번의 명령으로 "바로 작업을 시작할 수 있는 worktree" 만들기

worktree의 표준 명령어는 미니멀합니다. git worktree add로 할 수 있는 것은 디렉토리와 git의 상태뿐이며, .env 복사나 pnpm install 재실행은 직접 관리해야 합니다.

vibe는 그와 같은 「git worktree add 이후에 해야 할 일 목록」을 .vibe.toml을 통해 **선언적 (declaratively)**으로 작성할 수 있게 해줍니다.

vibe start

# 신규 브랜치를 생성하여 worktree를 만듦
vibe start feat/new-feature
# 기존 브랜치를 체크아웃함
...

.vibe.toml로 자동화하기

리포지토리 루트 직하에 .vibe.toml을 두면, vibe는 이를 읽어 훅 (hook) 및 복사 대상을 결정합니다.

[copy]
# 개별 파일: 환경마다 다른 설정이나 인증 정보
files = [".env", ".env.local", "config/local.json"]
...

pre_start는 worktree 생성 전에, post_start는 생성 후에 실행됩니다. 「브랜치를 생성하면 자동으로 pnpm install까지 실행되는」 상태로 만들어 두면, 브랜치 전환에 소요되는 시간은 말 그대로 몇 초에 불과합니다.

Copy-on-Write를 통한 고속 복사

node_modules의 복사는 일반적인 방식으로 하면 느리다는 점은 누구나 한 번쯤 맞닥뜨리는 문제입니다. vibe는 macOS (APFS)나 Linux (Btrfs / XFS)에서 이용할 수 있는 Copy-on-Write (CoW) API를 네이티브로 호출하여, 메타데이터만 복사하는 것으로 작업을 완료합니다.

GB 단위의 node_modules거의 즉시 복제되므로, 「복사를 기다리며 다른 일을 하는」 필요가 없어집니다.

보안

.vibe.toml에는 임의의 명령어를 작성할 수 있으므로, 「타인의 리포지토리를 clone 하는 순간 수상한 명령어가 실행되는」 동작은 피하고 싶은 부분입니다. vibe는 .vibe.toml의 **SHA-256 해시 (hash)**를 신뢰 목록 (trusted list)으로 관리하며, 승인되지 않은 설정이 포함된 경우 훅의 실행을 차단합니다.

# 현재의 .vibe.toml을 신뢰 목록으로 등록
vibe trust

신뢰 기반의 접근 방식이므로, 리포지토리의 소유자가 본인이든 외부 리포지토리든 동일한 보안 모델로 동작합니다.

더욱 진화한 사용성: scratch / jump / home / clean

vibe start는 worktree를 「만드는」 명령어이지만, 매일 사용하다 보면 「만들기·이동하기·삭제하기」의 반복이 늘어납니다. 최근의 vibe는 이 부분을 철저하게 줄였습니다.

vibe scratch ── 이름을 고민하지 않고 즉시 착수하기

실험용 브랜치일수록 이름이 잘 떠오르지 않습니다. feat/...로 만들기에는 애매하고, 그렇다고 메인에서 테스트하기에는 불안합니다.

vibe scratch

vibe scratch일회성 전제 (disposable)의 worktree를 자동적인 브랜치 이름으로 생성합니다. 가볍게 시도해 보고, 안 되면 버립니다. 마음에 들면 승격시킵니다.

vibe rename feat/awesome-idea

「먼저 코드로 놀아보고, 나중에 이름을 붙이는」 흐름을 자연스럽게 만들 수 있습니다.

vibe jump ── 기존 worktree로 모호 일치 (fuzzy match)를 통해 점프

vibe jump feli # feat/feature-flag-iteration에 매치됨

브랜치 이름이 길어지기 쉬운 팀에서도, 몇 글자만 입력하면 고유한 위치에 도착합니다. cd $(git worktree list | grep ...)를 직접 타이핑하지 않아도 된다는 단순한 차이지만, 효과는 확실합니다.

vibe home ── 언제든 메인으로 복귀

vibe home

메인 worktree (clone 직후의 본체)로 즉시 복귀합니다. 「헤매면 홈으로」 돌아갈 수 있다는 안도감은 의외로 큽니다.

vibe clean ── 삭제를 빠르고 안전하게

vibe clean

불필요해진 worktree를 한꺼번에 정리합니다. rm -rf가 아니라 OS의 휴지통으로 이동하는 구현으로 변경했기 때문에, 실수하더라도 즉시 복구할 수 있습니다. CoW로 복사한 worktree라면 삭제도 빠릅니다.

Claude Code와의 조합

여기까지가 vibe 단독에 대한 이야기였습니다. 이제부터가 본론인데, 이것을 Claude Code와 조합하면 워크플로우(flow)가 완전히 달라집니다.

서브 에이전트 (Sub-agent) × 격리된 worktree

Claude Code의 서브 에이전트 정의(.claude/agents/*.md) 프론트매터(frontmatter)에서 isolation: worktree를 설정하면, 해당 서브 에이전트는 일시적인 Git worktree 안에서 동작합니다.

---
name: refactor-explorer
description: 대규모 리팩터링을 시행착오하며 시도하기 위한 에이전트
...

공식 문서의 Supported frontmatter fields에서도 다음과 같이 명시되어 있습니다.

isolation

... Set to worktree to run the subagent in a temporary git worktree, giving it an isolated copy of the repository. The worktree is automatically cleaned up if the subagent makes no changes.

이 기능이 효과를 발휘하는 상황은 대략 다음과 같습니다.

  • 에이전트에게 대규모 리팩터링을 시도하게 하고 싶을 때: 메인 워킹 트리(working tree)를 더럽히지 않고, 별도의 worktree에서 실행한 뒤 결과만 가져옵니다.
  • 여러 안을 병렬로 시도하고 싶을 때: 여러 서브 에이전트를 각각 다른 worktree에서 동시에 실행합니다.
  • 실패해도 깔끔하게 버리고 싶을 때: 머지(merge)하지 않으면 worktree째로 삭제됩니다.

인간(본인)은 vibe start로 연 worktree에서 메인 태스크를 진행하면서, 서브 에이전트는 격리된 worktree에서 실험을 수행합니다. 즉, 동일한 리포지토리 안에서 사람과 에이전트가 분리되어 실행되는 구조를 자연스럽게 구축할 수 있습니다.

WorktreeCreate / WorktreeRemove hook으로 「Claude Code가 만드는 worktree」에도 vibe 적용하기

지금까지 설명한 격리된 worktree는 표준 git worktree로만 생성됩니다. 즉, .env의 복사도, node_modules의 CoW(Copy-on-Write) 복제도, pnpm install도 실행되지 않으므로, 서브 에이전트는 "셋업이 완료되지 않은 worktree" 안에서 동작하게 됩니다. 리팩터링을 시키고 싶어도 우선 빌드(build)가 통과되지 않아 막히는 상황이 발생하기 쉽습니다. 설령 서브 에이전트가 스스로 pnpm install부터 시작한다 하더라도, 그 설치 시간 동안 계속 기다려야 하므로 에이전트를 병렬로 실행하는 의미가 퇴색됩니다.

이 간극을 메워주는 것이 Claude Code의 WorktreeCreate / WorktreeRemove hook입니다. 공식 문서의 hook 목록에는 다음과 같이 기재되어 있습니다.

— When a worktree is being created via WorktreeCreate --worktree or isolation: "worktree". Replaces default git behavior.

— When a worktree is being removed, either at session exit or when a subagent finishes. WorktreeRemove

WorktreeCreate기본 git 동작을 대체하는 hook입니다. 여기서 git worktree add 대신 vibe start를 호출하도록 설정해 두면, isolation: "worktree"로 기동된 서브 에이전트의 작업 디렉토리에도 .vibe.tomlcopypost_start가 그대로 적용됩니다. WorktreeRemove 측에서 vibe clean에 상응하는 명령을 호출하도록 해두면 뒷정리까지 일치하게 됩니다.

이를 통해:

  • 인간: vibe start로 연 worktree (.env 및 의존성 셋업 완료) -
  • 서브 에이전트: Claude Code가 WorktreeCreate

를 통해 만든 worktree(이 또한 .env 및 의존성 셋업 완료)라는, 사람과 AI가 동일한 셋업 품질의 작업 환경을 서로 다른 worktree로서 병행하여 가지는 상태를 만들 수 있습니다.

서브 에이전트의 worktree 분리 그 자체에 대해서는, 별도의 「Claude Code의 Skills와 Sub-agents, 어떻게 구분해서 사용해야 하는가」라는 기사에서도 다룰 예정이므로, 함께 읽어보시면 이미지를 떠올리기 쉬울 것입니다.

설치

1. 바이너리 설치

macOS는 Homebrew로 설치할 수 있습니다.

brew install kexi/tap/vibe

그 외에도 npm / Bun / Deno / mise / Nix / .deb / Windows PowerShell을 통해서도 설치할 수 있습니다. 자세한 내용은 리포지토리(Repository)의 README를 참조해 주세요.

2. 셸 통합(Shell Integration) 셋업

vibe jumpvibe home으로 현재 셸의 디렉토리를 이동하기 위해, 셸에 작은 함수를 심어둘 필요가 있습니다. vibe 본체가 표준 출력(Standard Output)으로 cd 등의 셸 명령어를 출력하고, 이를 래퍼(Wrapper) 함수가 eval 하는 구조입니다.

사용 중인 셸의 설정 파일에 다음을 추가합니다. zsh의 경우는 다음과 같습니다.

# ~/.zshrc
vibe() { eval "$(command vibe "$@")" }

bash / fish / Nushell / PowerShell이나, miseenter 훅(Hook)을 통한 자동 셋업 예시는 리포지토리의 README를 참조해 주세요.

셸을 다시 열거나 source로 설정을 다시 불러오면, vibe jumpvibe home이 해당 셸의 현재 디렉토리(Current Directory)에 적용됩니다.

요약

  • Git Worktree는 여러 브랜치를 병행 작업할 때의 부담을 상당히 낮춰준다.
  • vibe는 그 worktree의 「생성·이동·삭제」를 **거의 제로 조작(Zero-operation)**으로 만드는 CLI다.
  • Claude Code의 서브 에이전트를 isolation: "worktree"로 실행하면, 사람과 에이전트를 동일한 리포지토리 내에서 분리할 수 있다.
  • Claude Code의 WorktreeCreate 훅(Hook)에서 vibe start를 호출하면, AI 측의 격리된 worktree에도 .vibe.tomlcopypost_start가 그대로 적용된다.

개인적으로는 AI 에이전트가 일상적으로 옆에서 돌아가게 된 이후로, 「지금 내가 만지고 있는 워킹 트리(Working Tree)」를 인간 전용으로 유지하는 것의 가치가 높아졌다고 느끼고 있습니다. worktree와 vibe는 이를 위한 가장 소박하고 강력한 도구입니다.

「나는 이런 방식으로 운용하고 있다」라거나 「.vibe.toml을 이렇게 작성하고 있다」와 같은 지견이 있다면, 꼭 댓글이나 SNS로 알려주세요.

AI 자동 생성 콘텐츠

본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
3

댓글

0