한국어

Worktree

ChatGPT 데스크톱 앱의 Codex에서 Git worktree를 사용하여 여러 채팅을 병렬로 실행하세요

ChatGPT 데스크톱 앱에서 worktree를 사용하면 Codex가 같은 프로젝트에서 서로 간섭하지 않는 여러 독립적인 채팅을 실행할 수 있습니다. Git 저장소의 경우 예약된 작업을 전용 백그라운드 worktree에서 실행하여 진행 중인 작업과 충돌하지 않도록 할 수 있습니다. 버전 관리가 적용되지 않는 프로젝트에서는 예약된 작업이 프로젝트 디렉터리에서 직접 실행됩니다. worktree에서 채팅을 수동으로 시작하고 Handoff를 사용하여 Local과 Worktree 간에 채팅을 이동할 수도 있습니다.

Worktree란 무엇인가요?

Worktree는 내부적으로 Git worktree를 사용하므로 Git 저장소에 속한 프로젝트에서만 작동합니다. Worktree를 사용하면 저장소의 두 번째 사본("checkout")을 만들 수 있습니다. 각 worktree에는 저장소의 모든 파일에 대한 자체 사본이 있지만, 커밋과 브랜치 등에 관한 메타데이터(.git 폴더)는 모두 공유합니다. 따라서 여러 브랜치를 동시에 checkout하여 작업할 수 있습니다.

용어

  • Local checkout: 사용자가 만든 저장소입니다. ChatGPT 데스크톱 앱에서는 간단히 Local이라고도 합니다.
  • Worktree: ChatGPT 데스크톱 앱에서 local checkout을 기반으로 만든 Git worktree입니다.
  • Handoff: Local과 Worktree 간에 채팅을 이동하는 흐름입니다. Codex가 두 환경 사이에서 작업을 안전하게 이동하는 데 필요한 Git 작업을 처리합니다.

Worktree를 사용하는 이유

  1. 현재 Local 설정을 방해하지 않고 Codex와 병렬로 작업할 수 있습니다.
  2. 포그라운드 작업에 집중하면서 백그라운드 작업을 대기열에 추가할 수 있습니다.
  3. 변경 사항을 검토하거나 테스트하거나 더 직접적으로 협업할 준비가 되면 나중에 채팅을 Local로 이동할 수 있습니다.

시작하기

Worktree를 사용하려면 Git 저장소가 필요합니다. 선택한 프로젝트가 Git 저장소에 속해 있는지 확인하세요.

  1. "Worktree" 선택

    새 채팅 화면의 작성기 아래에서 Worktree를 선택합니다. 필요하다면 worktree용 설정 스크립트를 실행할 로컬 환경을 선택합니다.

  2. 시작 브랜치 선택

    작성기 아래에서 worktree의 기반으로 사용할 Git 브랜치를 선택합니다. main / master 브랜치, 기능 브랜치 또는 스테이징되지 않은 로컬 변경 사항이 있는 현재 브랜치를 선택할 수 있습니다.

  3. 프롬프트 제출

    프롬프트를 제출하면 Codex가 선택한 브랜치를 기반으로 Git worktree를 만듭니다. 기본적으로 Codex는 "detached HEAD"에서 작업합니다.

  4. 작업을 계속할 위치 선택

    준비가 되면 worktree에서 직접 계속 작업하거나 채팅을 local checkout으로 넘길 수 있습니다. Local로 또는 Local에서 Handoff하면 채팅과 코드가 모두 이동하므로 다른 checkout에서 작업을 계속할 수 있습니다.

Local과 Worktree 간 작업

Worktree의 모양과 사용 방식은 local checkout과 매우 유사합니다. 차이점은 작업 흐름에서의 역할입니다. Local은 포그라운드, Worktree는 백그라운드라고 생각하면 됩니다. Handoff를 사용하면 두 환경 간에 채팅을 이동할 수 있습니다.

내부적으로 Handoff는 두 checkout 간에 작업을 안전하게 이동하는 데 필요한 Git 작업을 처리합니다. 이는 Git에서는 한 브랜치를 한 번에 한 위치에서만 checkout할 수 있기 때문입니다. Worktree에서 브랜치를 checkout하면 local checkout에서 동시에 checkout할 수 없으며, 그 반대도 마찬가지입니다.

실제로는 다음 두 가지 경로가 일반적입니다.

  1. Worktree에서만 작업합니다. 예를 들어 로컬 환경 설정 스크립트를 사용하여 종속성과 도구를 설치했기 때문에 worktree에서 변경 사항을 직접 검증할 수 있을 때 가장 적합한 경로입니다.
  2. 채팅을 Local로 Handoff합니다. 평소 사용하는 IDE에서 변경 사항을 검토하거나 앱 인스턴스를 하나만 실행할 수 있는 경우처럼 채팅을 포그라운드로 가져오고 싶을 때 사용합니다.

옵션 1: Worktree에서 작업하기

변경 사항과 함께 worktree에서만 계속 작업하려면 채팅 헤더의 Create branch here 버튼을 사용하여 worktree를 브랜치로 전환하세요.

이제 변경 사항을 커밋하고 브랜치를 원격 저장소에 push한 다음 GitHub에서 pull request를 열 수 있습니다.

헤더의 "Open" 버튼을 사용하여 IDE에서 worktree를 열거나, 통합 터미널 또는 worktree 디렉터리에서 필요한 다른 도구를 사용할 수 있습니다.

브랜치 컨트롤과 worktree 세부 정보가 표시된 Worktree 채팅 화면(라이트 모드)

Worktree에서 브랜치를 만들면 local checkout을 포함한 다른 어떤 worktree에서도 해당 브랜치를 checkout할 수 없다는 점을 기억하세요.

옵션 2: 채팅을 Local로 Handoff하기

채팅을 포그라운드로 가져오려면 채팅 헤더에서 Hand off를 선택하고 Local로 이동하세요.

평소 사용하는 IDE 창에서 변경 사항을 확인하거나, 기존 개발 서버를 실행하거나, 일상적으로 사용하는 동일한 환경에서 작업을 검증하려는 경우에 적합한 경로입니다.

Codex는 worktree와 local checkout 간에 채팅을 안전하게 이동하는 데 필요한 Git 단계를 처리합니다.

각 채팅에는 시간이 지나도 동일한 worktree가 연결됩니다. 나중에 채팅을 다시 worktree로 넘기면 Codex가 동일한 백그라운드 환경으로 돌려보내므로 중단한 지점부터 계속할 수 있습니다.

채팅을 worktree에서 Local로 이동하는 Handoff 대화 상자(라이트 모드)

반대 방향으로도 이동할 수 있습니다. 이미 Local에서 작업 중이고 포그라운드를 비우고 싶다면 Hand off를 사용하여 채팅을 worktree로 이동하세요. 로컬에서 다른 작업으로 다시 주의를 돌리는 동안 Codex가 백그라운드에서 계속 작업하도록 하려는 경우에 유용합니다.

Handoff는 Git 작업을 사용하므로 .gitignore 파일에 포함된 파일은 Codex가 .worktreeinclude을 사용하여 로컬 관리형 worktree로 복사하지 않는 한 채팅과 함께 이동하지 않습니다.

고급 세부 정보

Codex 관리형 및 영구 worktree

기본적으로 채팅은 Codex 관리형 worktree를 사용합니다. 이러한 worktree는 가볍게 사용하고 폐기할 수 있도록 설계되었습니다. Codex 관리형 worktree는 일반적으로 하나의 채팅에 전용으로 사용되며, 나중에 채팅을 다시 넘기면 Codex가 해당 채팅을 동일한 worktree로 돌려보냅니다.

장기간 유지되는 환경이 필요하다면 사이드바의 프로젝트에 있는 점 3개 메뉴에서 영구 worktree를 만드세요. 그러면 자체 프로젝트로 구성된 새로운 영구 worktree가 생성됩니다. 영구 worktree는 자동으로 삭제되지 않으며 동일한 worktree에서 여러 채팅을 시작할 수 있습니다.

Codex가 worktree를 관리하는 방식

Codex는 $CODEX_HOME/worktrees에 worktree를 만듭니다. 시작 커밋은 작업을 시작할 때 선택한 브랜치의 HEAD 커밋입니다. 로컬 변경 사항이 있는 브랜치를 선택했다면 Codex가 커밋되지 않은 변경 사항도 worktree에 적용합니다. Worktree는 브랜치로 checkout되지 않습니다. detached HEAD 상태로 유지됩니다. 따라서 Codex는 브랜치를 불필요하게 늘리지 않고 여러 worktree를 만들 수 있습니다.

무시된 로컬 파일을 관리형 worktree로 복사하기

로컬 Codex 관리형 worktree는 Git checkout에서 시작하므로 추적되는 파일은 이미 존재합니다. 저장소에서 새 worktree에 필요한 로컬 설정 파일을 무시하도록 구성한 경우 저장소 루트에 .worktreeinclude 파일을 추가하고, Codex가 관리형 worktree를 만들 때 복사할 무시된 경로나 .gitignore 형식의 패턴을 나열하세요.

Git이 의도적으로 무시하는 .env, .env.local 또는 config/secrets.json 같은 파일에 이 기능을 사용하세요. Codex는 .worktreeinclude과 일치하는 무시된 파일만 복사하며, Git이 추적하지 않는 다른 로컬 파일은 복사하지 않습니다. 추적되는 파일은 나열하지 마세요.

Codex는 무시된 AGENTS.override.md을 로컬 관리형 worktree에 자동으로 복사하므로 .worktreeinclude에 나열할 필요가 없습니다.

# .worktreeinclude
.env
.env.local
config/secrets.json

Codex는 원본 symlink를 건너뛰며 새 checkout에 이미 존재하는 파일을 덮어쓰지 않습니다. 이 동작은 로컬 ChatGPT 데스크톱 앱의 관리형 worktree에 적용되며, 원격 worktree나 명령줄에서 직접 만드는 Git worktree에는 적용되지 않습니다.

브랜치 제한 사항

Codex가 worktree에서 작업을 마쳤고 Create branch here를 사용하여 그 위치에 feature/a 브랜치를 만들었다고 가정해 보겠습니다. 이제 local checkout에서 이를 사용해 보려고 합니다. 해당 브랜치를 checkout하려고 하면 다음 오류가 발생합니다.

fatal: 'feature/a' is already used by worktree at '<WORKTREE_PATH>'

이 문제를 해결하려면 worktree에서 feature/a 대신 다른 브랜치를 checkout해야 합니다.

브랜치를 로컬에서 checkout할 계획이라면 같은 브랜치를 두 위치에서 동시에 checkout하려 하지 말고 Handoff를 사용하여 채팅을 Local로 이동하세요.

이 제한이 존재하는 이유

브랜치는 작업 트리의 “현재 checkout 상태”를 나타내는 변경 가능한 단일 참조(refs/heads/<name>)이므로 Git은 동일한 브랜치를 동시에 둘 이상의 worktree에서 checkout하지 못하도록 합니다.

브랜치가 checkout되면 Git은 해당 HEAD가 그 worktree에 속한 것으로 간주하며 커밋, reset, rebase, merge 같은 작업이 명확하게 정의되고 직렬화된 방식으로 해당 참조를 진행할 것으로 예상합니다. 여러 worktree에서 같은 브랜치를 동시에 checkout하도록 허용하면 어느 worktree의 작업이 브랜치 참조를 업데이트하는지 모호해지고 경합 상태가 발생하여 커밋 손실, 일관되지 않은 인덱스 또는 불명확한 충돌 해결로 이어질 수 있습니다.

Git은 worktree당 하나의 브랜치만 허용하여 각 브랜치에 신뢰할 수 있는 단일 작업 사본이 있도록 보장하는 동시에, 다른 worktree가 detached HEAD 또는 별도 브랜치를 통해 동일한 커밋을 안전하게 참조할 수 있도록 합니다.

Worktree 정리

Worktree는 많은 디스크 공간을 차지할 수 있습니다. 각 worktree에는 자체 저장소 파일, 종속성, 빌드 캐시 등이 있습니다. 따라서 ChatGPT 데스크톱 앱은 worktree 수를 적절한 한도 내로 유지하려고 합니다.

기본적으로 Codex는 가장 최근의 Codex 관리형 worktree 15개를 유지합니다. 디스크 사용량을 직접 관리하려면 설정에서 이 한도를 변경하거나 자동 삭제를 끌 수 있습니다.

Codex는 아직 중요한 worktree가 삭제되지 않도록 합니다. 다음 조건 중 하나에 해당하면 Codex 관리형 worktree는 자동으로 삭제되지 않습니다.

  • 고정된 채팅이 연결되어 있음
  • 채팅이 아직 진행 중임
  • 영구 worktree임

Codex 관리형 worktree는 다음과 같은 경우 자동으로 삭제됩니다.

  • 연결된 채팅을 보관 처리함
  • 구성된 한도를 유지하기 위해 Codex가 오래된 worktree를 삭제해야 함

Codex는 Codex 관리형 worktree를 삭제하기 전에 그 안의 작업에 대한 snapshot을 저장합니다. Worktree가 삭제된 후 채팅을 열면 복원 옵션이 표시됩니다.

자주 묻는 질문

Worktree가 생성되는 위치를 제어할 수 있나요?

예. Codex는 기본적으로 $CODEX_HOME/worktrees 아래에 관리형 worktree를 만듭니다. 다른 위치를 선택하려면 Settings > Worktrees를 열고 Worktree root를 변경하세요.

Local과 Worktree 간에 채팅을 이동할 수 있나요?

예. 채팅 헤더의 Hand off를 사용하여 로컬 체크아웃과 worktree 간에 채팅을 이동할 수 있습니다. Codex는 환경 간에 채팅을 안전하게 이동하는 데 필요한 Git 작업을 처리합니다. 나중에 채팅을 worktree로 다시 넘기면 Codex는 동일하게 연결된 worktree로 채팅을 되돌립니다.

worktree가 삭제되면 채팅은 어떻게 되나요?

기반 worktree 디렉터리가 삭제되더라도 채팅은 기록에 남아 있을 수 있습니다. Codex가 관리하는 worktree의 경우 Codex는 worktree를 삭제하기 전에 스냅샷을 저장하며, 연결된 채팅을 다시 열면 복원할 수 있는 옵션을 제공합니다. 영구 worktree는 해당 채팅을 보관 처리해도 자동으로 삭제되지 않습니다.