mcpField
W
worktree

worktree

github.com/robsonrung開発249 回インストール4 日前に更新
リポジトリ

worktree について

worktree は、メインのチェックアウトに影響を与えずにリポジトリ作業を分離するコーディングスキルです。既存の分離状態を確認し、ホストのネイティブツールを優先して、必要に応じて Git に切り替えます。

主な機能

  1. 01既存のリンク済みワークツリーを検出
  2. 02ホスト標準のワークツリーツールを優先
  3. 03新規ブランチまたは既存参照に対応
  4. 04Git による代替セットアップ手順
  5. 05ワークツリーのトラブルシューティング

活用シーン

  1. 01PR のレビューや修正を別環境で実施
  2. 02独立した機能を並行して開発

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/robsonrung/rar-skills --skill worktree

インストール後、Claude Code で/worktreeを入力して読み込まれたか確認します。

詳細

Worktree の分離

最初にブランチを選択します。ワークスペースのセットアップでは、現在のロールと、呼び出し元の分離権限の範囲内にある直接ツールを使用します。モデルワーカーやルート解決は不要です。以降のワーカーへのディスパッチは shared/references/model-preview.md に従い、再解決や追加ワーカーなしで、呼び出し元が承認したスナップショットを使用します。

ユーザーのメインチェックアウトに影響を与えず、現在の作業を分離されたワークスペースで行うようにします。ほとんどのコーディングハーネスはセッション開始時にデフォルトで worktree を作成するため、まず分離がすでに存在するかを検出します。

一般的な呼び出し元は、分離を求めるユーザーです。実装ワークフローでは、計画によって独立した作業トラックが特定された後に分離を求める場合があります。元に戻せる worktree の作成は、実装依頼の範囲内です。コミットに基づく統合には、別途承認が必要です。それ以外の場合、implement-and-review では、作業ツリーを使って順次進める単一のトラックを使用します。

操作順序は、既存の分離を検出 -> ハーネス標準の worktree ツールを優先 -> 通常の git にフォールバックです。ハーネスから認識できない worktree は作成しないでください。

呼び出し元のニーズに応じて設定する 2 つのモード:

  • 新しい作業(デフォルト)。 特定の ref が指定されていない場合 — ベース(trunk)から新しいブランチを作成します。
  • 既存の ref を分離する。 呼び出し元が、PR の head、既存のブランチ、コミットなど、分離して作業する ref を指定した場合 — 新しいブランチを作成するのではなく、その ref に worktree をアタッチします。このモードには、git の重要なルールが 1 つあります。ブランチをチェックアウトできる worktree は一度に 1 つだけです。 指定された ref がすでにどこかでチェックアウトされている場合(最も一般的なのは、メインチェックアウトで現在のブランチになっている場合)、その ref 用の 2 つ目の worktree を作成してはいけません。すでに <path> でチェックアウトされていることを報告し、呼び出し元が対応できるようにします(そこで作業するか、クリーンな別のツリーがどうしても必要な場合に限り、同じコミットに detached worktree を作成します)。1 つのブランチを 2 つの worktree に配置してはいけません。

以下の手順(検出 -> ネイティブツール -> git へのフォールバック)は、どちらのモードにも適用されます。モードによって変わるのは、何をチェックアウトし、呼び出し元に何を報告するかだけです。

Step 0: 既存の分離を検出する

何かを作成する前に、現在のディレクトリがすでにリンクされた worktree かどうかを確認します。git dir と共通 git dir の解決済み絶対パスを比較してください。まずそれぞれを絶対パスに解決し、git rev-parse の生の出力ではなく、そのパス同士を比較します。Git は現在のディレクトリによって絶対形式と相対形式を使い分けます(通常のチェックアウトのサブディレクトリでは、--git-dir は絶対パスを返しますが、--git-common-dir は相対パスの場合があります)。そのため、生の文字列を比較すると「すでに分離されている」という誤判定が発生します。

git rev-parse --absolute-git-dir                     # absolute git dir for this worktree
(cd "$(git rev-parse --git-common-dir)" && pwd -P)   # absolute shared (common) git dir

2 つの絶対パスが等しい場合、これは通常のチェックアウトです — Step 1 に進みます。

2 つのパスが異なる場合、リンクされた worktree または サブモジュール内にいます。両者を区別します。

git rev-parse --show-superproject-working-tree
  • 出力が空でない -> サブモジュール内です。通常のチェックアウトとして扱い、Step 1 に進みます。
  • 出力が空 -> すでに分離された worktree 内です。worktree のパス(git rev-parse --show-toplevel)と現在のブランチを報告します。別の worktree は作成しないでください。worktree 内から worktree を作成すると、誤ったツリーに配置され、現在の worktree を作成したハーネスから認識できなくなります。その後、その場で作業します。新しい作業モードではここで続行します。既存の ref を分離するモードでは、その ref がすでに現在のブランチでない限り、worktree を入れ子にするのではなく、ここでその ref をチェックアウトします。

Step 1: ハーネス標準の worktree ツールを優先する

ハーネスにネイティブの worktree プリミティブがある場合は、それを使用して終了します。Claude Code では EnterWorktree ツールです。他のハーネスでは、/worktree コマンドや --worktree フラグが提供されている場合があります。ネイティブツールは、ハーネスが管理できるよう worktree の配置、追跡、クリーンアップを行います。ハーネスに知らせず git worktree add を実行すると、ハーネスから認識、移動、クリーンアップできない幽霊状態が作成されます。

ステップ 2:Git によるフォールバック

ネイティブツールがなく、かつステップ 0 で既存の分離が見つからなかった場合にのみ実行します。

  1. リポジトリのルートから実行します。 以下の .worktrees/ と .gitignore のパスはリポジトリルートからの相対パスですが、スキルはユーザーの現在のディレクトリから実行されます。現在のディレクトリはサブディレクトリの場合があるため、まずルートに移動します:cd "$(git rev-parse --show-toplevel)"。これを行わないと、.worktrees/<branch> と .gitignore の編集がリポジトリルートではなくサブディレクトリ(例:src/.worktrees/...、src/.gitignore)に作成されます。
  2. 作業内容に基づいて意味のあるブランチ名を選びます(例:feat/login、fix/email-validation)。不透明な自動生成名は避けてください。ベースブランチを選びます(デフォルト:origin のデフォルトブランチ、なければ main)。
  3. 何かを作成する前に、.worktrees/ が Git の無視対象になっていることを確認します。git check-ignore -q .worktrees/ を実行します。末尾のスラッシュを付けてください。これにより、ディレクトリがまだ存在しなくても、既存のディレクトリのみを対象とする .worktrees/ ルールが適用されます(末尾にスラッシュを付けずに git check-ignore .worktrees を実行すると、このルールが検出されず、適切に設定されたリポジトリが変更済みの状態になってしまいます)。無視対象でなければ、.gitignore に .worktrees/ の行を追加します。
  4. 現在のチェックアウトに影響を与えない範囲で、ベースブランチの更新を試みます:git fetch origin <from-branch>。これは失敗しても処理を続けます。エラーになった場合(origin リモートがない、リモート名が異なる、またはローカルのみのブランチなど)、中断せず次のステップに進み、ローカルの参照を使用します。
  5. ワークツリーを作成します。コマンドはモードによって異なります:
    • 新規作業: git worktree add -b <branch-name> .worktrees/<branch-name> origin/<from-branch>(origin/<from-branch> が存在しない場合は、ローカルの <from-branch> 参照を使用します)。ベースから新しいブランチを作成します。
    • 既存の参照を分離: ブランチを作成するのではなく、その参照をチェックアウトします。既存のブランチまたはタグの場合は、git worktree add .worktrees/<slug> <target-ref> を実行します。PR の場合は、ローカルブランチでチェックアウトします(切り離された FETCH_HEAD は使用しないでください。修正ループのコミットが PR の更新に反映されず、孤立してしまいます):git fetch origin pull/<n>/head:pr-<n> を実行してから、git worktree add .worktrees/pr-<n> pr-<n> を実行します。(push の追跡先を PR に戻すには、まず切り離し状態でワークツリーを作成します:git worktree add --detach .worktrees/pr-<n>。次にそのディレクトリへ cd し、gh pr checkout <n> を実行します。この方法はフォークにも安全で、フォークからの PR にも使えます。)参照がすでに別の場所でチェックアウトされていると Git が報告した場合は、2 つのモードの「すでにチェックアウトされている場合」のルールに従い、2 つ目のワークツリーを強制的に作成しないでください。
  6. ワークツリーに切り替えます:cd .worktrees/<branch-name>(または .worktrees/<slug>)。

git worktree add がサンドボックスまたは権限エラーで失敗した場合は、同じ操作についてホストの通常の権限取得または昇格の手順を使用してください。要求された参照と分離状態を維持します。必要な権限が付与された後にのみ再試行してください。ワークツリーを作成する権限がすでにあっても、ホストの制御を回避することはできません。

権限が拒否された場合、利用できない場合、または許可を得て再試行しても失敗する場合は、妨げとなっている要因を報告してください。要求されたワークスペースを変更する場合、または分離を断念する場合に限り、決定を求めてください。ユーザーが明示的に承認しない限り、現在のチェックアウトには手を加えないでください。可能であれば、独立して許可されている作業を続けてください。

その他のワークツリー操作

git を直接使用します。ラッパーは不要です:

git worktree list                          # list worktrees
git worktree remove .worktrees/<branch>    # remove a worktree
cd .worktrees/<branch>                     # switch to a worktree
cd "$(git rev-parse --show-toplevel)"      # return to the current checkout root

ワークツリーを作成するタイミング

すでに分離されておらず、別のワークスペースが必要な場合にのみ、ワークツリーを作成します(ステップ 1/2):

  • 現在のチェックアウトを他の作業用に空けておきながら、PR をレビューまたは修正する場合
  • ブランチ切り替えの手間をかけずに、複数の機能を並行して進める場合

現在のチェックアウトのブランチ上で実行できる単一タスクの作業では、ワークツリーを作成しないでください。また、ステップ 0 ですでにワークツリー内にいることが示されている場合は、決して作成しないでください。

トラブルシューティング

「Worktree already exists」:パスは使用中です。そこへ移動する(cd .worktrees/<branch>)か、再作成する前に削除します(git worktree remove .worktrees/<branch>)。

「Cannot remove worktree: it is the current worktree」:まずワークツリーの外へ cd で移動してから、git worktree remove を実行します。


compound-engineering-plugin をもとにしています(MIT)。NOTICE をご覧ください。

コメント