ワークツリー
ChatGPT デスクトップアプリの Codex で Git ワークツリーを使用し、複数のチャットを並行して実行します
ChatGPT デスクトップアプリでは、ワークツリーを使用することで、Codex が同じプロジェクト内で複数の独立したチャットを互いに干渉させずに実行できます。Git リポジトリでは、スケジュール済みタスクを専用のバックグラウンドワークツリーで実行し、進行中の作業との競合を避けられます。バージョン管理されていないプロジェクトでは、スケジュール済みタスクはプロジェクトディレクトリで直接実行されます。手動でワークツリー内のチャットを開始し、Handoff を使用して Local と Worktree の間でチャットを移動することもできます。
ワークツリーとは
ワークツリーは内部で Git worktrees を使用するため、Git リポジトリに含まれるプロジェクトでのみ機能します。ワークツリーを使うと、リポジトリの 2 つ目のコピー(「checkout」)を作成できます。各ワークツリーにはリポジトリ内のすべてのファイルが個別にコピーされますが、commit やブランチなどのメタデータ(.git フォルダー)は共有されます。これにより、複数のブランチを並行してチェックアウトし、作業できます。
用語
- Local checkout:ユーザーが作成したリポジトリです。ChatGPT デスクトップアプリでは、単に Local と呼ばれることもあります。
- Worktree:ChatGPT デスクトップアプリでローカルの checkout から作成された Git worktree です。
- Handoff:Local と Worktree の間でチャットを移動するフローです。Codex が、両者の間で作業を安全に移動するために必要な Git 操作を処理します。
ワークツリーを使用する理由
- 現在の Local 環境に影響を与えず、Codex と並行して作業できます。
- フォアグラウンドの作業に集中しながら、バックグラウンドの作業をキューに追加できます。
- 変更を確認、テスト、またはより直接的に共同作業する準備ができたら、後でチャットを Local に移動できます。
はじめに
ワークツリーには Git リポジトリが必要です。選択したプロジェクトが Git リポジトリ内にあることを確認してください。
「Worktree」を選択する
新しいチャット画面で、入力欄の下にある Worktree を選択します。必要に応じて、ワークツリーのセットアップスクリプトを実行するローカル環境を選択します。
開始ブランチを選択する
入力欄の下で、ワークツリーの基点にする Git ブランチを選択します。
main/masterブランチ、機能ブランチ、またはステージされていないローカル変更を含む現在のブランチを選択できます。プロンプトを送信する
プロンプトを送信すると、Codex が選択したブランチを基に Git ワークツリーを作成します。デフォルトでは、Codex は "detached HEAD" で作業します。
作業を続ける場所を選択する
準備ができたら、ワークツリーで直接作業を続けるか、チャットをローカルの checkout にハンドオフできます。Local との間でハンドオフすると、チャットとコードの_両方_が移動し、移動先の checkout で作業を続けられます。
Local と Worktree の間で作業する
ワークツリーの見た目や操作感は、ローカルの checkout とほぼ同じです。違いは、作業フローのどこで使用するかです。Local はフォアグラウンド、Worktree はバックグラウンドと考えることができます。Handoff を使用すると、両者の間でチャットを移動できます。
内部では、Handoff が 2 つの checkout 間で作業を安全に移動するために必要な Git 操作を処理します。これは、Git では 1 つのブランチを一度に 1 か所でしかチェックアウトできないため重要です。ワークツリーでブランチをチェックアウトしている場合、同時にローカルの checkout でそのブランチをチェックアウトすることはできません。逆の場合も同様です。
実際には、一般的に次の 2 つの進め方があります。
- ワークツリーだけで作業する。この方法は、たとえばローカル環境のセットアップスクリプトを使用して依存関係やツールをインストール済みで、ワークツリー上で変更を直接検証できる場合に最適です。
- チャットを Local にハンドオフする。通常の IDE で変更を確認したい場合や、アプリを 1 インスタンスしか実行できない場合など、チャットをフォアグラウンドに移したいときに使用します。
選択肢 1:ワークツリーで作業する
変更を含むワークツリーだけで作業を続ける場合は、チャットヘッダーの Create branch here ボタンを使用して、ワークツリーをブランチに変換します。
ここから変更をコミットし、ブランチをリモートリポジトリにプッシュして、GitHub で pull request を開くことができます。
ヘッダーの「Open」ボタンを使用して IDE でワークツリーを開くことも、統合ターミナルや、ワークツリーディレクトリで必要なその他のツールを使用することもできます。
ワークツリーでブランチを作成した場合、ローカルの checkout を含むほかのワークツリーで、そのブランチをチェックアウトすることはできません。
選択肢 2:チャットを Local にハンドオフする
チャットをフォアグラウンドに移す場合は、チャットヘッダーの Hand off を選択し、Local に移動します。
この方法は、普段使用している IDE ウィンドウで変更を確認したい場合、既存の開発サーバーを実行したい場合、または日常的に使用している同じ環境で作業を検証したい場合に適しています。
Codex が、ワークツリーとローカルの checkout の間でチャットを安全に移動するために必要な Git 操作を処理します。
各チャットには、継続して同じワークツリーが関連付けられます。後でチャットをワークツリーに戻すと、Codex は同じバックグラウンド環境に戻すため、中断したところから再開できます。
逆方向への移動も可能です。すでに Local で作業していてフォアグラウンドを空けたい場合は、Hand off を使用してチャットをワークツリーに移動します。ローカルでは別の作業に注意を戻しつつ、Codex にバックグラウンドで作業を続けてもらいたい場合に便利です。
Handoff は Git 操作を使用するため、.gitignore ファイルに含まれるファイルは、Codex が .worktreeinclude を使用してローカルの管理対象ワークツリーにコピーしない限り、チャットとともに移動しません。
詳細
Codex 管理のワークツリーと永続ワークツリー
デフォルトでは、チャットは Codex 管理のワークツリーを使用します。これは軽量で破棄しやすい環境として設計されています。通常、Codex 管理のワークツリーは 1 つのチャット専用で、後でチャットをそのワークツリーに戻すと、Codex は同じワークツリーに戻します。
長期間使用する環境が必要な場合は、サイドバーにあるプロジェクトの三点メニューから永続ワークツリーを作成します。これにより、独立したプロジェクトとして新しい永続ワークツリーが作成されます。永続ワークツリーは自動的に削除されず、同じワークツリーから複数のチャットを開始できます。
Codex によるワークツリーの管理方法
Codex は $CODEX_HOME/worktrees にワークツリーを作成します。開始 commit は、タスクの開始時に選択したブランチの HEAD commit です。ローカル変更を含むブランチを選択した場合、Codex は未コミットの変更もワークツリーに適用します。ワークツリーはブランチとしてチェックアウトされません。detached HEAD 状態になります。これにより、Codex はブランチを増やすことなく複数のワークツリーを作成できます。
無視されたローカルファイルを管理対象ワークツリーにコピーする
ローカルの Codex 管理ワークツリーは Git の checkout から開始されるため、追跡対象ファイルはすでに存在します。リポジトリで無視されているローカルセットアップファイルが新しいワークツリーに必要な場合は、リポジトリのルートに .worktreeinclude ファイルを追加し、Codex が管理対象ワークツリーを作成するときにコピーする無視対象のパスまたは .gitignore 形式のパターンを記載します。
.env、.env.local、config/secrets.json など、Git が意図的に無視するファイルに使用してください。Codex は .worktreeinclude に一致する無視対象ファイルのみをコピーします。Git が追跡していないほかのローカルファイルはコピーしません。追跡対象ファイルは記載しないでください。
Codex は、無視対象の AGENTS.override.md をローカルの管理対象ワークツリーに自動的にコピーするため、.worktreeinclude に記載する必要はありません。
# .worktreeinclude
.env
.env.local
config/secrets.jsonCodex はコピー元のシンボリックリンクをスキップし、新しい checkout にすでに存在するファイルを上書きしません。この動作は、ローカルの ChatGPT デスクトップアプリが管理するワークツリーに適用されます。リモートワークツリーや、コマンドラインから自分で作成した Git ワークツリーには適用されません。
ブランチの制限
Codex がワークツリーで作業を完了し、Create branch here を使用して feature/a ブランチを作成したとします。次に、それをローカルの checkout で試したくなったとします。そのブランチをチェックアウトしようとすると、次のエラーが発生します。
fatal: 'feature/a' is already used by worktree at '<WORKTREE_PATH>'解決するには、ワークツリーで feature/a ではない別のブランチをチェックアウトする必要があります。
ローカルでブランチをチェックアウトする予定がある場合は、同じブランチを 2 か所で同時にチェックアウトしようとせず、Handoff を使用してチャットを Local に移動してください。
この制限が存在する理由
ブランチは、作業ツリーの「現在チェックアウトされている状態」を示す単一の可変参照(refs/heads/<name>)であるため、Git は同じブランチを同時に複数のワークツリーでチェックアウトできないようにしています。
ブランチがチェックアウトされると、Git はその HEAD が該当ワークツリーによって所有されているものとして扱い、commit、reset、rebase、merge などの操作によって、その参照が明確かつ直列化された方法で更新されることを前提とします。複数のワークツリーで同じブランチを同時にチェックアウトできると、どのワークツリーの操作がブランチ参照を更新するのかが曖昧になり、競合状態が発生します。その結果、commit の消失、index の不整合、競合解決の不明確化につながる可能性があります。
Git はブランチごとに 1 つのワークツリーというルールを適用することで、各ブランチに信頼できる単一の作業コピーが存在することを保証しつつ、ほかのワークツリーが detached HEAD や別のブランチを通じて同じ commit を安全に参照できるようにしています。
ワークツリーのクリーンアップ
ワークツリーは多くのディスク容量を使用することがあります。各ワークツリーには、リポジトリファイル、依存関係、ビルドキャッシュなどがそれぞれ存在します。そのため、ChatGPT デスクトップアプリはワークツリー数を適切な上限に保とうとします。
デフォルトでは、Codex は最近使用した Codex 管理ワークツリーを 15 個保持します。ディスク使用量を自分で管理したい場合は、設定でこの上限を変更するか、自動削除を無効にできます。
Codex は、まだ重要なワークツリーを削除しないようにします。次の場合、Codex 管理ワークツリーは自動的に削除されません。
- ピン留めされたチャットに関連付けられている
- チャットがまだ進行中である
- 永続ワークツリーである
次の場合、Codex 管理ワークツリーは自動的に削除されます。
- 関連付けられたチャットをアーカイブした
- 構成した上限内に収めるため、Codex が古いワークツリーを削除する必要がある
Codex 管理ワークツリーを削除する前に、Codex はそのワークツリー上の作業のスナップショットを保存します。ワークツリーの削除後にチャットを開くと、復元するオプションが表示されます。
よくある質問
ワークツリーの作成場所を指定できますか?
はい。デフォルトでは、Codex は $CODEX_HOME/worktrees の下に管理対象ワークツリーを作成します。別の場所を選択するには、Settings > Worktrees を開き、
Worktree root を変更します。
Local と Worktree の間でチャットを移動できますか?
はい。チャットヘッダーの Hand off を使用して、ローカルの checkout とワークツリーの間でチャットを移動できます。Codex が環境間でチャットを安全に移動するために必要な Git 操作を処理します。後でチャットをワークツリーに戻すと、 Codex は同じ関連付けられたワークツリーに戻します。
ワークツリーを削除するとチャットはどうなりますか?
基になるワークツリーディレクトリが削除されても、チャットは履歴に残ることがあります。Codex 管理ワークツリーの場合、Codex はワークツリーを削除する前にスナップショットを保存し、関連付けられたチャットを再度開いたときに復元するオプションを表示します。永続ワークツリーは、関連するチャットをアーカイブしても自動的には削除されません。