본문 바로가기

GPT

OpenAI Codex 완전가이드 3편 — Git Worktree 병렬 에이전트: 기능 3개 동시 구현, 충돌 없이 머지까지

반응형

 

"에이전트 여러 개를 동시에 돌리면 어떻게 되나요?"

같은 폴더에서 두 Codex 세션을 돌리면 — 충돌입니다. 한 세션이 수정한 파일을 다른 세션이 덮어씁니다. 이게 Git Worktree를 써야 하는 이유입니다. Worktree는 같은 레포에서 브랜치마다 별도 폴더를 만들어 에이전트들이 서로 건드리지 않고 병렬로 작업하게 합니다. Codex의 가장 강력한 차별점이고, 혼자 쓰는 개발자도 생산성이 2~3배 달라집니다.


핵심 요약

→ Git Worktree: 같은 .git 히스토리를 공유하면서 각기 다른 폴더/브랜치로 체크아웃
→ 핵심 원칙: 병렬 작업은 파일이 겹치지 않는 작업끼리만 — 겹치면 충돌
→ Codex CLI: 수동으로 Worktree 만들고 각 폴더에서 터미널 실행
→ Codex App: UI에서 Thread 생성 시 Worktree 자동 관리 (4편에서 상세)
→ 기본 패턴: 기능 A 폴더 + 기능 B 폴더 + main 폴더(머지 허브) 3개
→ 머지 전략: Rebase Before PR이 가장 충돌 적음
충돌 예방 규칙 1: 같은 파일 두 Worktree에서 절대 동시 수정 금지
충돌 예방 규칙 2: package.json, config 파일은 main에서만 수정
충돌 예방 규칙 3: AGENTS.md에 Worktree별 수정 허용 경로 명시
→ clash 툴: 충돌 조기 감지 오픈소스 (github.com/clash-sh/clash)
→ 작업 전 항상 git commit — 롤백 기준점


실전 1 — Git Worktree가 뭔지 정확히

일반 git clone과 Worktree 비교

일반 방식:
my-project/     ← 브랜치 하나만 체크아웃 가능
  .git/
  src/
  
다른 브랜치 작업하려면?
→ git stash → git checkout feature/login
→ 파일 전체가 바뀜
→ 이전 작업 상태 잠시 사라짐

Git Worktree 방식:
my-project/           ← main 브랜치 (메인 폴더)
  .git/               ← 히스토리 공유 (한 군데)
  src/

my-project-login/     ← feature/login 브랜치 (별도 폴더)
  .git ← 파일 (포인터, 폴더 아님)
  src/               ← 완전히 독립된 파일 상태

my-project-dashboard/ ← feature/dashboard 브랜치
  .git ←
  src/

핵심 포인트 3가지

1. 파일은 별도 → 에이전트끼리 충돌 없음
2. 히스토리는 공유 → 불필요한 용량 낭비 없음
3. 동시에 여러 브랜치 체크아웃 → 기능 3개 동시 진행 가능

실전 2 — 사전 체크: Git 버전 확인

# Git 2.5 이상 필요 (Worktree는 2.5에서 도입)
git --version
# git version 2.43.x 이상이면 OK

# 2.5 미만이면 업데이트
# macOS:
brew upgrade git

# Ubuntu/Debian:
sudo apt update && sudo apt install git

# 업데이트 확인
git --version

실전 3 — 기본 Worktree 명령어

Worktree 생성

# 기본 문법
git worktree add <새폴더경로> <브랜치명>

# 예시: feature/login 브랜치를 ../my-project-login 폴더로
git worktree add ../my-project-login feature/login

# 새 브랜치 만들면서 동시에 Worktree 생성 (-b 플래그)
git worktree add -b feature/dashboard ../my-project-dashboard main
#                                                              ↑ main에서 분기

Worktree 목록 확인

git worktree list

# 출력 예시:
# /Users/cell/my-project           abc1234 [main]
# /Users/cell/my-project-login     def5678 [feature/login]
# /Users/cell/my-project-dashboard ghi9012 [feature/dashboard]

Worktree 삭제

# 작업 완료 후 정리
git worktree remove ../my-project-login

# 강제 삭제 (수정사항 있어도)
git worktree remove --force ../my-project-login

# 이미 삭제된 폴더의 Worktree 레퍼런스 정리
git worktree prune

실전 4 — 3개 병렬 에이전트 실전 플로우

시나리오: Node.js API에 기능 3개를 동시에 추가

기능 A: 사용자 인증 API (feature/auth)
기능 B: 상품 목록 API (feature/products)
기능 C: 기존 테스트 업데이트 (feature/tests)

→ 3개가 건드리는 파일이 다름 → 병렬 가능

Step 1. 시작 전 상태 정리

cd ~/projects/my-api

# 현재 상태 확인
git status
# → "nothing to commit" 이어야 함

# 깨끗하지 않으면 커밋 먼저
git add -A && git commit -m "before parallel work: stable state"

# main 최신 상태 확인
git pull origin main

Step 2. Worktree 3개 생성

# 기능 A: 인증
git worktree add -b feature/auth ../my-api-auth main

# 기능 B: 상품
git worktree add -b feature/products ../my-api-products main

# 기능 C: 테스트 (main에서 분기)
git worktree add -b feature/tests ../my-api-tests main

# 확인
git worktree list
# /Users/cell/my-api           (main)
# /Users/cell/my-api-auth      (feature/auth)
# /Users/cell/my-api-products  (feature/products)
# /Users/cell/my-api-tests     (feature/tests)

Step 3. 각 폴더에서 Codex 실행 (터미널 3개 열기)

# 터미널 1: 인증 기능
cd ~/projects/my-api-auth
codex -a auto-edit "JWT 기반 로그인/로그아웃 API 구현해줘.
POST /auth/login, POST /auth/logout
bcrypt 비밀번호 해싱, 토큰 만료 24시간
에러 처리 포함, Jest 테스트도 작성해줘"
# 터미널 2: 상품 기능
cd ~/projects/my-api-products
codex -a auto-edit "상품 목록 API 구현해줘.
GET /products (페이지네이션: page, limit)
GET /products/:id
응답 형식: { data, total, page, totalPages }
Jest 테스트 포함"
# 터미널 3: 테스트 업데이트
cd ~/projects/my-api-tests
codex -a auto-edit "기존 테스트 파일 전체 검토해서
실패하는 테스트 수정하고 커버리지 80% 이상으로 올려줘"

Step 4. 진행 상황 모니터링

# 메인 터미널에서 각 Worktree 상태 확인
watch -n 5 'git worktree list && echo "---" && git log --oneline --all --graph | head -20'

# 각 Worktree 커밋 현황
git log --oneline feature/auth | head -5
git log --oneline feature/products | head -5
git log --oneline feature/tests | head -5

Step 5. 완료된 것부터 diff 검토

# 인증 기능 완료되면
cd ~/projects/my-api-auth

# 변경사항 전체 보기
git diff main..feature/auth

# 파일 목록만 보기
git diff main..feature/auth --name-only

# 테스트 실행
npm test

실전 5 — 머지 전략: Rebase Before PR (권장)

병렬 작업 후 머지할 때 가장 충돌이 적은 방법입니다.

Rebase Before PR 패턴

# 기능 A 완료 후
cd ~/projects/my-api-auth

# 최신 main 반영
git fetch origin
git rebase origin/main
# 충돌 나면 수동 해결 → git add → git rebase --continue

# 테스트 통과 확인
npm test

# PR 생성 (GitHub CLI 사용)
gh pr create \
  --title "feat: JWT 인증 API 추가" \
  --body "로그인/로그아웃 API, bcrypt 해싱, JWT 토큰 발급" \
  --base main

# 또는 수동 머지
cd ~/projects/my-api
git merge --no-ff feature/auth
git push origin main

순서대로 머지하기

# 의존성 없는 순서로 하나씩 머지
# (한 번에 다 머지하면 충돌 복잡해짐)

# 1번 먼저
git merge --no-ff feature/auth
npm test  # 통과 확인

# 2번
git merge --no-ff feature/products
npm test  # 통과 확인

# 3번
git merge --no-ff feature/tests
npm test  # 최종 통과 확인

전체 테스트 통과 후 정리

# Worktree 삭제
git worktree remove ../my-api-auth
git worktree remove ../my-api-products
git worktree remove ../my-api-tests

# 브랜치도 삭제 (선택)
git branch -d feature/auth feature/products feature/tests

# 레퍼런스 정리
git worktree prune

# 확인
git worktree list
# /Users/cell/my-api  (main) 만 남아야 함

실전 6 — 충돌 예방 3가지 규칙

병렬 개발에서 가장 큰 위험은 두 에이전트가 같은 파일을 동시에 수정하는 것입니다. 이를 막는 핵심 원칙들이 있습니다.

규칙 1: 작업 전 파일 겹침 체크

시작 전 10분 투자 → 수시간의 충돌 해결 절감

체크 방법:
기능 A가 건드릴 파일 목록 작성
기능 B가 건드릴 파일 목록 작성
→ 교집합 있으면 → 순차 실행 or 역할 재분배

예시:
기능 A (인증): src/auth/*, tests/auth/*   ← 겹침 없음 ✅
기능 B (상품): src/products/*, tests/products/*
기능 C (공통 미들웨어): src/middleware/*  ← A, B 둘 다 쓸 수 있음 ⚠️

→ 기능 C는 A, B 완료 후 순차 실행

규칙 2: 공유 파일은 main에서만 수정

절대 Worktree에서 수정하면 안 되는 파일:
- package.json / package-lock.json
- tsconfig.json / .eslintrc
- .env (그냥 절대 건드리지 말 것)
- 모든 에이전트가 import하는 공통 유틸

이런 파일 수정 필요하면:
→ main에서 수정 → 커밋 → 각 Worktree에서 rebase

규칙 3: AGENTS.md에 수정 허용 경로 명시

# feature/auth Worktree 전용 AGENTS.md
cat > ~/projects/my-api-auth/AGENTS.md << 'EOF'
# 인증 기능 Worktree 규칙

## 이 Worktree에서 수정 가능한 경로
- src/auth/
- src/middleware/auth.ts
- tests/auth/

## 수정 절대 금지
- package.json (main에서만 수정)
- src/products/ (다른 Worktree 담당)
- .env

## 작업 완료 기준
- npm test 통과
- src/auth/ 함수 전부 타입 힌트 있음
- auth 관련 테스트 커버리지 80% 이상
EOF

실전 7 — 충돌 조기 감지: clash 툴

clash는 여러 Worktree 간 머지 충돌을 조기에 감지하는 오픈소스 CLI 툴입니다. 에이전트가 파일을 쓰기 전에 자동으로 충돌 체크를 실행합니다.

# 설치
npm install -g @clash-sh/clash

# 사용법: 현재 Worktree들 간 충돌 확인
cd ~/projects/my-api
clash check

# 출력 예시:
# Checking worktree conflicts...
# ✅ feature/auth   ↔ feature/products: no conflicts
# ⚠️  feature/auth   ↔ feature/tests: conflict in src/utils/validator.ts
# ✅ feature/products ↔ feature/tests: no conflicts
#
# 1 potential conflict found
# Run 'clash diff feature/auth feature/tests' for details

충돌 상세 확인:

clash diff feature/auth feature/tests
# → 어떤 줄이 충돌하는지 표시
# → 미리 알고 역할 재분배 가능

실전 8 — 자주 겪는 문제 해결

문제 1: "branch is already checked out" 오류

# 오류 메시지:
# fatal: 'feature/login' is already checked out at '/Users/.../my-project-login'

# 원인: 해당 브랜치가 이미 다른 Worktree에서 사용 중
# 해결: 다른 브랜치명 사용
git worktree add -b feature/login-v2 ../my-project-login2 main

# 또는 기존 Worktree 삭제 후 재생성
git worktree remove ../my-project-login
git worktree add ../my-project-login feature/login

문제 2: Worktree에서 node_modules 없음

# 각 Worktree는 독립 폴더 → node_modules 별도 설치 필요
cd ../my-project-login
npm install  # 또는 yarn / pnpm install

문제 3: rebase 도중 충돌

git rebase origin/main
# 충돌 발생 시:

# 1. 충돌 파일 확인
git status
# both modified: src/utils/validator.ts

# 2. 파일 열어서 수동 해결
# <<<<<<< HEAD (main의 내용)
# =======
# >>>>>>> feature/auth (내 변경)
# → 원하는 내용으로 편집

# 3. 해결 완료 표시
git add src/utils/validator.ts

# 4. rebase 계속
git rebase --continue

# 5. 포기하고 원상복구 (rebase 전으로)
git rebase --abort

문제 4: Worktree 폴더 실수로 삭제함

# 폴더는 없어도 git 레퍼런스 남아있음
git worktree list
# /Users/cell/my-project-login  (deleted)

# 레퍼런스 정리
git worktree prune

# 필요하면 다시 생성
git worktree add ../my-project-login feature/login

실전 9 — 혼자 쓰는 개발자를 위한 실용 패턴

패턴 A: 핫픽스 + 기능 동시 작업

상황: 기능 개발 중에 버그 수정 요청이 들어왔다

기존 방식:
git stash → git checkout hotfix → 수정 → git checkout feature → git stash pop
→ stash 충돌, 컨텍스트 전환 비용, 시간 낭비

Worktree 방식:
# 기능 개발 중 (터미널 1)
cd ~/projects/my-app-feature
codex -a auto-edit "로그인 페이지 계속 작업해줘"

# 버그 수정 요청 옴 → 터미널 2 열기
git worktree add -b hotfix/login-null ../my-app-hotfix main
cd ../my-app-hotfix
codex -a auto-edit "login() 함수에서 user가 null일 때 크래시 수정해줘"

# 버그 수정 완료 → 머지 → Worktree 삭제
cd ~/projects/my-app
git merge --no-ff hotfix/login-null
git worktree remove ../my-app-hotfix

# 기능 개발 계속 (터미널 1은 아무 영향 없음)

패턴 B: 실험적 리팩토링

# 리팩토링이 잘 될지 모르겠을 때
git worktree add -b experiment/refactor-auth ../my-app-exp main
cd ../my-app-exp

codex -a full-auto "인증 모듈 전체를 클래스 기반에서 함수형으로 리팩토링해줘.
테스트 다 통과하면 성공, 아니면 원인 알려줘"

# 결과 마음에 들면 → 머지
# 결과 별로면 → Worktree 그냥 삭제 (main에 영향 없음)
git worktree remove --force ../my-app-exp
git branch -D experiment/refactor-auth

패턴 C: A/B 구현 비교

# 같은 기능을 두 가지 방법으로 구현해서 비교
git worktree add -b approach/rest-api ../my-app-rest main
git worktree add -b approach/graphql ../my-app-graphql main

# 터미널 1
cd ../my-app-rest
codex "사용자 API를 REST 방식으로 구현해줘"

# 터미널 2
cd ../my-app-graphql
codex "사용자 API를 GraphQL 방식으로 구현해줘"

# 둘 다 완료 후 비교
git diff approach/rest-api approach/graphql

# 마음에 드는 쪽 머지
git merge --no-ff approach/rest-api
git worktree remove ../my-app-rest
git worktree remove ../my-app-graphql

실전 10 — 유용한 셸 함수

자주 쓰는 패턴을 셸 함수로 만들어두면 편합니다.

# ~/.zshrc 또는 ~/.bashrc에 추가

# Worktree 생성 + 이동 + Codex 실행 한 번에
function codex-new() {
  local branch=$1
  local task=$2
  local worktree_path="../$(basename $(pwd))-${branch//\//-}"
  
  git worktree add -b "$branch" "$worktree_path" main
  cd "$worktree_path"
  
  if [ -n "$task" ]; then
    codex -a auto-edit "$task"
  else
    codex
  fi
}

# 사용: codex-new feature/auth "JWT 인증 API 구현해줘"

# Worktree 전체 상태 한눈에 보기
function wt-status() {
  git worktree list
  echo ""
  git log --oneline --all --graph | head -20
}

# 완료된 Worktree 머지 + 삭제 한 번에
function wt-done() {
  local branch=$1
  local worktree_path="../$(basename $(pwd))-${branch//\//-}"
  
  cd $(git rev-parse --show-toplevel)
  git merge --no-ff "$branch"
  git worktree remove "$worktree_path"
  git branch -d "$branch"
  git worktree prune
  echo "✅ $branch merged and cleaned up"
}

# 사용: wt-done feature/auth
# 적용
source ~/.zshrc

마무리

상황 패턴 명령

기능 2~3개 동시 기본 병렬 git worktree add -b × N
버그 + 기능 동시 핫픽스 분리 main에서 hotfix 브랜치 Worktree
불확실한 리팩토링 실험 브랜치 실패하면 --force 삭제
A/B 비교 두 구현 병렬 둘 다 만들고 diff 비교
충돌 예방 파일 분리 작업 전 겹치는 파일 체크
충돌 조기 감지 clash 툴 clash check 주기적 실행
머지 전략 Rebase Before PR git rebase origin/main 후 머지

Worktree는 에이전트 간 파일 충돌 문제를 완전히 해결합니다. Git에 내장되어 있고, 설정은 5분이면 됩니다. 에이전트를 동시에 두 개 이상 쓰면서 Worktree를 안 쓰고 있다면, 지금 바로 설정하세요. 5분 설정이 수시간의 충돌 디버깅을 막습니다.

4편에서는 Codex App(데스크탑 UI)과 Codex Cloud를 다룹니다 — Worktree를 CLI에서 수동으로 관리하는 것과 달리 App에서는 UI 클릭 몇 번으로 처리됩니다. 그리고 MCP 연동으로 GitHub, DB 등 외부 도구를 Codex에 연결하는 방법까지.


관련 글

 

반응형