ワークツリー

ChatGPT デスクトップアプリの Codex で Git ワークツリーを使用し、チャットを並行して実行します

ワークツリーを使うと、Codex は同じプロジェクト内で複数の独立したチャットを互いに干渉することなく実行できます。リポジトリ、ワークツリー、コマンドは、プロジェクトが置かれているコンピューターまたはリモート開発環境に保持されます。ChatGPT デスクトップアプリで直接作業することも、ChatGPT モバイルアプリの Codex を使って、接続先のコンピューターでワークツリーのチャットを開始し、指示、承認、レビューを行うこともできます。

Git リポジトリでは、スケジュール済みタスクを専用のバックグラウンドワークツリーで実行できるため、進行中の作業と競合しません。バージョン管理されていないプロジェクトでは、スケジュール済みタスクはプロジェクトディレクトリで直接実行されます。チャットをワークツリーで手動で開始し、Handoff を使用して Local と Worktree の間でチャットを移動することもできます。

ワークツリーとは

ワークツリーは内部で Git ワークツリーを使用するため、Git リポジトリに含まれるプロジェクトでのみ利用できます。ワークツリーを使用すると、リポジトリの 2 つ目のコピー(「チェックアウト」)を作成できます。各ワークツリーにはリポジトリ内のすべてのファイルの独自コピーがありますが、コミットやブランチなどのメタデータ(.git フォルダー)はすべてのワークツリーで共有されます。これにより、複数のブランチを並行してチェックアウトし、作業できます。

用語

  • Local checkout:自分で作成したリポジトリです。ChatGPT デスクトップアプリでは、単に Local と呼ばれることもあります。
  • ワークツリー:ChatGPT デスクトップアプリでローカルチェックアウトから作成された Git ワークツリーです。
  • Handoff:Local とワークツリーの間でチャットを移動するフローです。Codex が、作業を安全に移動するために必要な Git 操作を処理します。

ワークツリーを使用する理由

  1. 現在の Local 環境に影響を与えず、Codex と並行して作業できます。
  2. フォアグラウンドの作業に集中しながら、バックグラウンド作業をキューに追加できます。
  3. 内容を詳しく確認、テスト、または直接共同作業する準備ができたら、チャットを Local に移動できます。

はじめに

Worktree を使用するには Git リポジトリが必要です。選択したプロジェクトが Git リポジトリ内にあることを確認してください。

  1. 「ワークツリー」を選択する

    新しいチャット画面で、入力欄の下にある Worktree を選択します。必要に応じて、ワークツリーでセットアップスクリプトを実行するローカル環境を選択します。

  2. 開始ブランチを選択する

    入力欄の下で、ワークツリーのベースとする Git ブランチを選択します。main/master ブランチ、機能ブランチ、またはステージされていないローカル変更を含む現在のブランチを選べます。

  3. プロンプトを送信する

    プロンプトを送信すると、選択したブランチに基づいて Codex が Git ワークツリーを作成します。デフォルトでは、Codex は detached HEAD 状態で作業します。

  4. 作業を続ける場所を選択する

    準備ができたら、ワークツリー上で直接作業を続けるか、チャットをローカルチェックアウトに引き渡すことができます。Local との間で Handoff を行うと、チャットとコードの 両方 が移動するため、移動先のチェックアウトで作業を続けられます。

Local とワークツリーを行き来して作業する

ワークツリーの外観や操作感は、ローカルチェックアウトとよく似ています。違いは、ワークフロー内での役割です。Local をフォアグラウンド、ワークツリーをバックグラウンドと考えることができます。Handoff を使用すると、両者の間でチャットを移動できます。

内部では、Handoff が 2 つのチェックアウト間で作業を安全に移動するために必要な Git 操作を処理します。これは、Git では 1 つのブランチを同時に 1 か所でしかチェックアウトできない ため重要です。ワークツリーでブランチをチェックアウトすると、そのブランチを同時にローカルチェックアウトでチェックアウトすることはできません。逆の場合も同様です。

実際には、一般的に次の 2 つの進め方があります。

  1. ワークツリー上だけで作業する。たとえば、ローカル環境のセットアップスクリプトを使って依存関係やツールをインストール済みで、ワークツリー上で変更を直接検証できる場合に最適です。
  2. チャットを Local に引き渡す。普段の IDE で変更を確認したい場合や、アプリのインスタンスを 1 つしか実行できない場合など、チャットをフォアグラウンドに移したいときに使用します。

選択肢 1:ワークツリー上で作業する

変更を含むワークツリー上だけで作業を続ける場合は、チャットヘッダーの Create branch here ボタンを使用してワークツリーをブランチに変換します。

ここから変更をコミットし、ブランチをリモートリポジトリにプッシュして、GitHub で pull request を作成できます。

ヘッダーの Open ボタンを使用して IDE でワークツリーを開いたり、統合ターミナルを使用したり、ワークツリーディレクトリから必要なほかの操作を行ったりできます。

ブランチコントロールとワークツリーの詳細が表示されたワークツリーチャット画面(ライトモード)
ワークツリーでブランチを作成すると、ローカルのチェックアウトを含むほかのワークツリーでは、そのブランチをチェックアウトできない点に注意してください。

選択肢 2:チャットを Local に引き渡す

チャットをフォアグラウンドに移すには、チャットヘッダーで Hand off を選択し、Local に移動します。

この方法は、普段の IDE ウィンドウで変更を確認したい場合、既存の開発サーバーを実行したい場合、または日常的に使用している同じ環境で作業を検証したい場合に適しています。

Codex は、ワークツリーとローカルチェックアウトの間でチャットを安全に移動するために必要な Git 操作を処理します。

各チャットには、時間が経過しても同じワークツリーが関連付けられます。後でチャットを再びワークツリーに引き渡すと、Codex は同じバックグラウンド環境に戻すため、中断したところから再開できます。

チャットをワークツリーから Local へ移動する Handoff ダイアログ(ライトモード)
逆方向に移動することもできます。すでに Local で作業していてフォアグラウンドを空けたい場合は、**Hand off** を使用してチャットをワークツリーに移動します。ローカルでは別の作業に注意を戻しつつ、Codex にバックグラウンドで作業を続けてもらいたい場合に便利です。

Handoff は Git 操作を使用するため、.gitignore ファイルの対象となるファイルは、Codex が .worktreeinclude を使用してローカルの管理対象ワークツリーにコピーしない限り、チャットと一緒には移動しません。

詳細

Codex が管理するワークツリー

デフォルトでは、チャットは Codex 管理のワークツリーを使用します。これは軽量で使い捨てやすいことを目的としています。Codex 管理のワークツリーは通常 1 つのチャット専用であり、後からチャットをワークツリーに戻すと、Codex は同じワークツリーに戻ります。

Codex によるワークツリーの管理方法

Codex は $CODEX_HOME/worktrees にワークツリーを作成します。開始コミットは、チャットを開始するときに選択したブランチの HEAD コミットです。ローカルの変更があるブランチを選択した場合、Codex は未コミットの変更もワークツリーに適用します。ワークツリーはブランチとしてチェックアウトされません。detached HEAD 状態になります。これにより、Codex はブランチを増やすことなく複数のワークツリーを作成できます。

無視されているローカルファイルを管理対象ワークツリーにコピーする

ローカルの Codex 管理ワークツリーは Git チェックアウトから作成されるため、追跡対象ファイルはすでに存在します。リポジトリが、新しいワークツリーに必要なローカルセットアップファイルを無視している場合は、リポジトリのルートに .worktreeinclude ファイルを追加し、Codex が管理対象ワークツリーを作成するときにコピーする無視対象パスまたは .gitignore 形式のパターンを記載します。

これは、.env、.env.local、config/secrets.json など、Git が意図的に無視するファイルに使用します。Codex がコピーするのは、.worktreeinclude に一致する無視対象ファイルのみです。Git が追跡していない他のローカルファイルはコピーされません。追跡対象ファイルは記載しないでください。

Codex は、無視対象の AGENTS.override.md をローカルの管理対象ワークツリーに自動的にコピーするため、.worktreeinclude に記載する必要はありません。

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

Codex はコピー元のシンボリックリンクをスキップし、新しいチェックアウトにすでに存在するファイルを上書きしません。この動作は、ローカルの ChatGPT デスクトップアプリが管理するワークツリーに適用され、リモートワークツリーやコマンドラインから自分で作成した Git ワークツリーには適用されません。

ブランチの制限

Codex がワークツリー上で作業を完了し、Create branch here を使用して、そのワークツリーに feature/a ブランチを作成したとします。次に、ローカルチェックアウトでそのブランチを試すことにしました。このブランチをチェックアウトしようとすると、次のエラーが発生します。

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

解決するには、ワークツリー上で feature/a ではない別のブランチをチェックアウトする必要があります。

このブランチをローカルでチェックアウトする予定がある場合は、両方の場所で同じブランチを同時にチェックアウトしようとせず、Handoff を使用してチャットを Local に移動してください。

この制限がある理由 Git では、同じブランチを複数のワークツリーで同時にチェックアウトできません。これは、ブランチが単一の可変参照(`refs/heads/`)であり、その意味がワークツリーの「現在チェックアウトされている状態」だからです。

ブランチがチェックアウトされると、Git はその HEAD をそのワークツリーが所有するものとして扱い、git commit、git reset、git rebase、git merge などの操作が、明確に定義された順序で逐次的にその参照を進めることを想定します。複数のワークツリーで同じブランチを同時にチェックアウトできるようにすると、どのワークツリーの操作がブランチ参照を更新するのかが曖昧になり、競合状態が生じます。その結果、コミットの消失、インデックスの不整合、競合解決方法の不明確化につながる可能性があります。

Git は、各ブランチをチェックアウトできるワークツリーを 1 つに制限することで、各ブランチに唯一の正となる作業コピーが存在することを保証します。同時に、ほかのワークツリーからも、detached HEAD 状態または別のブランチ上で同じコミットを安全に参照できます。

ワークツリーのクリーンアップ

ワークツリーは大量のディスク容量を使用することがあります。各ワークツリーには、リポジトリファイル、依存関係、ビルドキャッシュなどがそれぞれ個別に存在します。そのため、ChatGPT デスクトップアプリはワークツリーの数を適切な上限に保とうとします。

デフォルトでは、Codex は直近の Codex 管理ワークツリーを 15 個保持します。ディスク使用量を自分で管理したい場合は、設定でこの上限を変更したり、自動削除を無効にしたりできます。

Codex は、まだ重要なワークツリーを削除しないようにします。次の場合、Codex 管理のワークツリーは自動的に削除されません。

  • ピン留めされたチャットが関連付けられている
  • チャットがまだ進行中である

以前のバージョンで作成された永続ワークツリーは引き続き利用でき、自動クリーンアップの対象にはなりません。プロジェクトメニューから永続ワークツリーを新規作成することはできなくなりました。

Codex 管理のワークツリーは、次の場合に自動的に削除されます。

  • 関連付けられたチャットをアーカイブした
  • 設定された上限内に収めるため、Codex が古いワークツリーを削除する必要がある

Codex は、管理対象ワークツリーを削除する前に、そのワークツリー上の作業のスナップショットを保存します。ワークツリーの削除後にチャットを開くと、復元するための選択肢が表示されます。

よくある質問

ワークツリーの作成場所を指定できますか? はい。デフォルトでは、Codex は `$CODEX_HOME/worktrees` 以下に管理対象のワークツリーを作成します。別の場所を選択するには、**Settings > Worktrees** を開き、 **Worktree root** を変更します。

Local と Worktree の間でチャットを移動できますか? はい。チャットヘッダーの**Hand off** を使用すると、ローカルのチェックアウトとワークツリーの間でチャットを移動できます。Codex は、環境間でチャットを安全に移動するために必要な Git 操作を処理します。後でチャットをワークツリーに戻すと、 Codex は関連付けられた同じワークツリーにチャットを戻します。

ワークツリーが削除されると、チャットはどうなりますか? チャットは、対応するワークツリーのディレクトリが削除されても履歴に残ることがあります。Codex が管理するワークツリーの場合、Codex は削除前にスナップショットを保存し、関連するチャットを再び開いたときに復元を提案します。