Worktrees
概要
同じプロジェクトで複数の独立したチャットを互いに干渉させずに動かす仕組み。Git worktree を土台に、ChatGPT desktop app の Local checkout と Worktree の間でチャットを移動(Handoff)できる。
worktree が使えるのは ChatGPT desktop app の Codex のみ。 worktree でチャットを始める前に Codex を選ぶ必要がある。
仕様
前提
- Git リポジトリの一部であるプロジェクトでのみ動く(内部で Git worktree を使うため)
- worktree はリポジトリの 2 つめの checkout。各 worktree はリポジトリの全ファイルのコピーを持ち、コミットやブランチのメタデータ(
.gitフォルダ)は共有する
用語
| 用語 | 意味 |
|---|---|
| Local checkout | 自分で作ったリポジトリ。desktop app では単に Local |
| Worktree | desktop app が local checkout から作った Git worktree |
| Handoff | Local と Worktree の間でチャットを移すフロー。必要な Git 操作は Codex が行う |
開始の流れ
- 新規チャットビューで composer の下の Worktree を選ぶ。任意で local environment を選ぶと worktree のセットアップスクリプトが走る
- worktree の基にする Git ブランチを選ぶ(
main/master、フィーチャーブランチ、あるいは未ステージのローカル変更を含む現在のブランチ) - プロンプトを送ると、選んだブランチを基に Git worktree が作られる。既定では detached HEAD で作業する
- そのまま worktree で作業を続けるか、Local へ handoff するかを選ぶ
Handoff
- Handoff は 2 つの checkout 間で作業を安全に移すための Git 操作を行う。Git は 1 つのブランチを同時に 1 か所でしか checkout できないため、これが必要になる
- 各チャットは同じ worktree を継続して持つ。 後でチャットを worktree に戻すと、同じバックグラウンド環境に戻る
- Local から worktree へ移す方向にも使える
- Handoff は Git 操作を使うため、
.gitignoreに含まれるファイルは、.worktreeincludeによってローカルの managed worktree にコピーされる場合を除き、チャットと一緒には移動しない
worktree だけで作業する場合
- チャットヘッダーの Create branch here で worktree をブランチにする
- そこからコミット・push・PR 作成ができる
- ヘッダーの Open ボタンで IDE を worktree に開く、統合ターミナルを使う、など
- worktree でブランチを作ると、local checkout を含む他のどの worktree でもそのブランチを checkout できない
Codex-managed worktree と permanent worktree
- 既定ではチャットは Codex-managed worktree を使う。軽量で使い捨て。通常は 1 チャット専用で、後でチャットを戻すと同じ worktree に返る
- 長命な環境が要る場合は、サイドバーのプロジェクトの三点メニューから permanent worktree を作る。これは独自のプロジェクトとして新しい permanent worktree を作る。permanent worktree は自動削除されず、同じ worktree から複数のチャットを始められる
作成のされ方
- worktree は
$CODEX_HOME/worktreesに作られる。Settings > Worktrees の Worktree root で場所を変えられる - 開始コミットは、チャット開始時に選んだブランチの
HEAD - ローカル変更のあるブランチを選んだ場合、未コミットの変更も worktree に適用される
- worktree はブランチとして checkout されず detached HEAD 状態。これによりブランチを汚さずに複数の worktree を作れる
.worktreeinclude
- managed worktree は Git checkout から始まるため tracked なファイルは既にある。ignore されているセットアップファイルが必要な場合、リポジトリルートに
.worktreeincludeを置き、コピーしたいパスまたは.gitignore形式のパターンを列挙する .env、.env.local、config/secrets.jsonのような Git が意図的に無視するファイル向け.worktreeincludeに一致する ignore 済みファイルだけをコピーする。 Git が追跡していない他のローカルファイルはコピーしない。tracked なファイルを列挙しないこと- ignore された
AGENTS.override.mdは自動的にローカルの managed worktree へコピーされるため、列挙は不要 - source の symlink はスキップし、新しい checkout に既にあるファイルは上書きしない
- この挙動はローカルの ChatGPT desktop app の managed worktree に対するもので、remote worktree やコマンドラインで自分が作った Git worktree には適用されない
ブランチの制限
- worktree で
feature/aブランチを作った後に local checkout で同じブランチを checkout しようとするとfatal: 'feature/a' is already used by worktree at '<WORKTREE_PATH>'になる - 解決するには worktree 側で別のブランチを checkout する。ローカルで checkout する予定なら、両方で同じブランチを保とうとせず Handoff でチャットを Local に移す
クリーンアップ
- 既定では直近 15 個の Codex-managed worktree を保持する。 この上限は設定で変更でき、自動削除を切ることもできる
- 自動削除されない条件
- ピン留めしたチャットが紐づいている
- チャットが進行中
- permanent worktree である
- 自動削除される条件
- 紐づくチャットをアーカイブしたとき
- 設定した上限に収めるために古い worktree を消す必要があるとき
- Codex-managed worktree を消す前に作業のスナップショットを保存する。worktree 削除後にチャットを開くと復元の選択肢が出る
- チャットは worktree ディレクトリが消えても履歴に残りうる。 permanent worktree は、紐づくチャットをアーカイブしても自動削除されない
scheduled tasks との関係
- Git リポジトリでは、scheduled tasks を専用のバックグラウンド worktree で走らせて現在の作業と衝突させないようにできる
- バージョン管理下にないプロジェクトでは、scheduled tasks はプロジェクトディレクトリで直接動く
設定
# .worktreeinclude
.env
.env.local
config/secrets.json
関連
facts/codex/env-vars.mdfacts/codex/sandbox.mdfacts/codex/agents-md.md