Claude Media
Claude Code Worktree実践ガイド — 並列セッションの隔離と落とし穴

Claude Code Worktree実践ガイド — 並列セッションの隔離と落とし穴

git worktreeでClaude Codeの並列セッションを隔離する全体像。起点別の挙動、baseRefの選び方、依存関係の扱い、pushの落とし穴までを実務目線で追います。

複数のClaude Codeセッションを同時に走らせると、同じファイルを別々のセッションが書き換えて衝突します。防ぐ手立てがgit worktreeです。1つのリポジトリから物理的に別々の作業ディレクトリを生やし、セッションごとに専用のチェックアウトを与えます。Claude Codeがこの仕組みを使う経路は5つ。--worktreeフラグ、会話中の依頼、サブエージェント、バックグラウンドセッション、デスクトップアプリです。経路ごとに挙動は細かく異なります。作成自体が失敗する場合はsymlinkが原因の拒否も確認してください。

git worktreeの基礎 — 何が共有され何がされないか

git worktreeはGit本体の標準機能です。1つの.gitディレクトリを複数の作業ディレクトリで共有します。メインの作業コピーを~/repoとすると、~/repo/.claude/worktrees/feature-xのような別ディレクトリを追加し、そこに別のブランチをチェックアウトできます。複製cloneより軽量です。.git実体を持たないぶん、1回のfetchが全worktreeに反映されます。

共有される範囲とされない範囲は明確です。

共有されるworktreeごとに独立
ブランチ参照(refs/heads/*)・タグ・リモート追跡参照worktreeごとに独立HEAD(現在のチェックアウト位置)
オブジェクトデータベース(コミット・ツリー・blob)worktreeごとに独立インデックス(ステージングエリア)
config(既定)・hooksworktreeごとに独立作業ディレクトリの実ファイル
—worktreeごとに独立refs/bisect/*・refs/worktree/*・refs/rewritten/*

extensions.worktreeConfigを有効にするとcore.worktreeやcore.sparseCheckoutのようにworktreeごとに独立させたい設定だけを分離できます。Git公式の見解は明確です。複数チェックアウトについて「サブモジュールのサポートは不完全で、スーパープロジェクトの複数チェックアウトは推奨しない」と明記しています。サブモジュールを使うリポジトリなら、本格運用の前に確認しておく価値があります。

Claude Codeがworktreeを作る5つの起点

Claude Codeがworktreeを作る経路は5つです。どれも最終的には同じgit worktreeの仕組みに乗りますが、保存先やクリーンアップの主導権が違います。

起点トリガー保存先主導権
CLIフラグトリガーclaude --worktree <name>保存先.claude/worktrees/<name>/主導権セッション終了時にあなたが判断
会話中の依頼トリガー「worktreeで作業して」→EnterWorktreeツール保存先.claude/worktrees/配下主導権セッションが移動先を選ぶ
サブエージェント隔離トリガーfrontmatterのisolation: worktree保存先サブエージェントごとの一時worktree主導権変更なしなら自動削除
バックグラウンドセッショントリガーagent view・/bg・claude --bg保存先.claude/worktrees/配下主導権定期スイープが自動削除
デスクトップアプリトリガーセッション作成時にworktreeを選択保存先既定は.claude/worktrees/(変更可)主導権アーカイブ操作

worktreeで切ったセッションを別ブランチへ移したり、複数ブランチをまたいで作業を続けたりしたときの扱いはClaude Codeでブランチをまたぐセッションはどう扱われるかで扱っています。報告されたバージョンのタグをworktreeに切り出してissueを再現する使い方はClaude Codeのissue再現の記事にあります。

--worktreeフラグでセッションを隔離する

-wまたは--worktreeに名前を渡すと、隔離されたworktreeを作ってその中でClaude Codeを起動します。保存先は既定で.claude/worktrees/<name>/です。ブランチ名はworktree-<name>になります。

claude --worktree feature-auth

別のターミナルで別名を指定して同じコマンドを実行すれば、2つ目の隔離セッションが立ち上がります。名前の省略も可能です。その場合はbright-running-foxのような名前が自動生成されます。

v2.1.287のclaude --helpには、--worktreeに関係するフラグがもう1つ載っています。

-w, --worktree [name]   Create a new git worktree for this session (optionally specify a name)
--tmux                  Create a tmux session for the worktree (requires --worktree).
                        Uses iTerm2 native panes when available; use --tmux=classic
                        for traditional tmux.

--tmuxは--worktreeとセットで使い、worktreeごとにtmuxセッションを作ります。worktreeを複数並べて、ターミナルの画面側も分けたい場合の入口です。

対話実行にはワークスペース信頼が必要です。そのディレクトリでClaude Codeを一度も実行したことがなければ、先にclaudeを1回実行して信頼ダイアログを通すか、--worktreeがエラーで促してきます。-pを使う非対話実行はこの信頼チェックをスキップするため、claude -p --worktreeはそのまま進みます。

worktreeは新規チェックアウトなので、依存関係のインストールなど環境構築が必要です。.claude/worktrees/は自分のリポジトリの.gitignoreに加えておくと、メインの作業コピーに未追跡ファイルとして出てこなくなります。

会話の途中でworktreeへ移る — EnterWorktreeツール

セッションの途中で「worktreeで作業して」と頼むと、Claude CodeはEnterWorktreeツールでworktreeを作って移動します。すでにworktree内にいる場合は、EnterWorktreeに移動先パスを渡すことで別のworktreeへ切り替えられ、直前のworktreeはディスク上にそのまま残ります。

.claude/worktrees/の外側にあるパスへ入ろうとするときは、必ず承認を求められます。移動によってセッションの作業ディレクトリ・書き込み権限・CLAUDE.mdや設定などのプロジェクト構成がそのパスに切り替わるためです。この確認はEnterWorktreeの権限ルールや「今後確認しない」を選んでも省略されず、bypassPermissionsモードのときだけスキップされます。v2.1.206より前は、既存のworktreeパスへは確認なしで入れていました。

worktreeの後片付けとセッション再開

対話セッションのworktreeを終了するとき、Claude Codeは削除によって失われる作業(変更・未追跡ファイル・新規コミット)がないか確認します。

後片付け

終了時の3つの分岐

  • きれいな状態

    名前を指定しなかったセッションは、worktreeとブランチを自動で削除します。名前付きセッションは先に確認を挟み、あとで再利用するために残す選択もできます。

  • 作業が残っている

    保持するか削除するかを確認されます。保持すればディレクトリとブランチはそのままで、削除すれば中身ごと消えます。保持したときは、終了時に表示されるclaude --worktree <name> --resumeで戻れます。

  • 状態を確認できない

    変更数を数えられない場合や、チェックアウト済みサブモジュールを調べられない場合は、自動では削除されません。確認できなかった内容がプロンプトに出ます。

-pを使う非対話実行には終了時の確認プロンプトがなく、worktreeは自動で片付きません。作成時にかけたロックも、あとのセッションが走らせるスイープで解放されるまで残ります。git worktree removeで手動削除し、ロックを理由に拒否されたら先にgit worktree unlockを実行します。agent viewで削除したセッションの残骸はagent viewで.claude/worktreesが溜まる原因と掃除の手順で扱います。Windowsでは、worktreeの削除がworktree外のファイルまで削除することはありません。ただし、worktree内のフォルダがNTFSジャンクションやディレクトリシンボリックリンクのこともあります。その場合に削除されるのはリンクだけで、リンク先の実体は残ります。v2.1.205より前は、サブディレクトリにネストしたリンクの削除でリンク先の実体まで消えるケースがありました。

セッションを再開すると、そのセッションが使っていたworktreeに戻ります。この挙動は対話再開だけでなく、非対話モードの--continue・--resume、Agent SDKでも同じです。worktree内からExitWorktreeで抜けることもできます。--fork-sessionで分岐した再開は起動時のディレクトリで始まり、元のセッションのworktreeには影響しません。worktreeディレクトリがすでに存在しない場合も、起動時のディレクトリで再開します。v2.1.198以降、worktreeへの出入りは/cdと同じ扱いでトランスクリプトの記録先も追従します(/desktopや--resumeもその移動先で見つけられます)。追従するのはClaude Codeがgitで作ったworktreeだけで、WorktreeCreateフックで作ったworktreeのトランスクリプトは起動ディレクトリに残ります。

サブエージェントをworktreeで隔離する

サブエージェントは既定でメインセッションと同じ作業ディレクトリで動きます。並列で走る複数のサブエージェントに同じファイルを触らせたくないときは、.claude/agents/のfrontmatterにisolation: worktreeを追加します。

---
name: refactorer
description: Applies mechanical refactors across many files
isolation: worktree
---
 
Apply the requested refactor across every affected file, then run the tests
and report the results.

このサブエージェントは常に専用のworktreeで実行され、変更を残さず終了すると自動で削除されます。変更が残っている場合はディスク上に残ります。定期スイープが消すのは、cleanupPeriodDays(既定30日)より古く、失う作業がなくなったworktreeだけです。サブエージェントのworktreeは--worktreeと同じ基点(次節のworktree.baseRef)を使うため、設定を"head"にしない限りリポジトリの既定ブランチから分岐します。

エージェントが実行中の間、Claude Codeはそのworktreeにgit worktree lockをかけて並行するクリーンアップから守ります。ロックはエージェント終了時に解放され、v2.1.210以降はプロセスが強制終了したバックグラウンドセッションのロックも自動解放されます(それより前はgit worktree unlockが必要でした)。

安全機構はここで終わりません。v2.1.203以降、isolation: worktreeのサブエージェントのBash/PowerShellコマンドは、作業ディレクトリがメインの作業コピーに解決されるとエラーで失敗します。それ以前は、メインの作業コピーでそのまま実行できてしまいました。v2.1.210以降はこのチェックがリポジトリ全体に拡張され、セッション自身がworktree内にいる場合は連携元のメインチェックアウトも対象になります。v2.1.216以降はBashコマンドの中身も検査します。git -C・--git-dir・GIT_DIR/GIT_WORK_TREE環境変数でgitをメイン側へ向けるコマンドは、エラーで止まります。cdでメインチェックアウトへ迂回するコマンドも同様です。複雑すぎて解析できないコマンドも、単純なコマンドに分けるよう促すエラーで弾かれます。この検査はBashのみが対象で、PowerShellは作業ディレクトリのチェックだけが働きます。この検査は無効にできません。意図してメインのチェックアウトを操作したいときは、セッション外のターミナルで自分で実行します。詳しい原因と回避策はClaude Codeのworktreeはmainへの読み取り専用gitも拒否するにまとめています。

サブエージェント自体の設計・並列パターンはサブエージェント完全活用とSub-agents完全ガイドにまとめています。

バックグラウンドセッションの自動隔離とデスクトップアプリのworktree

claude agentsで開くagent view、/bg、claude --bgで起動したバックグラウンドセッションは、ファイル編集の直前に自動で.claude/worktrees/配下のworktreeへ移動します。すでにリンク済みのworktree内にいる場合、書き込み先が作業ディレクトリの外側の場合は、この移動をスキップします。作業ディレクトリがgitリポジトリでなくWorktreeCreateフックも未設定な場合も同じです。編集対象のファイルが、セッションやサブエージェントがgit worktree addで作ったリンク済みworktreeの中にある場合も移動しません。

隔離が不要なリポジトリでは、設定でこの自動移動そのものを無効化できます。

{
  "worktree": {
    "bgIsolation": "none"
  }
}

既定値は"worktree"で、EnterWorktreeが呼ばれるまでメインの作業コピーへのEdit/Writeをブロックします。"none"にするとバックグラウンドジョブが作業コピーを直接編集するようになります(v2.1.143以降)。worktree内でコード変更を隔離したバックグラウンドセッションは、確認なしでコミットし、リモートがあればブランチをpushします。ドラフトPRはタスクが求めるときに開きます。タスクやCLAUDE.mdで「コミットは自分でやる」と指示していれば、gitには触りません。mainやmasterへの直接pushやマージはしません。

この隔離下では、シンボリックリンク経由の書き込みが「cannot be safely resolved」でブロックされることもあります。原因と直し方は「cannot be safely resolved」の原因と対処にまとめています。

削除方法にも違いがあります。agent viewでCtrl+Xを2回押すと、未コミットの変更ごとworktreeが削除されます。残したい変更は先にコミットしておく必要があります。シェルからclaude rmで削除する場合、未コミットの変更が残るworktreeはそのセッション行ごと保持されます。未pushのコミットが残るworktreeは、最初の削除ではどちらの操作でも残り、ブランチ名と未pushのコミット数が表示されます。続けてもう一度削除すると、コミットごと破棄されます(v2.1.260以降)。agent viewならCtrl+Xを2回、シェルなら表示されたclaude rm <id> --discard-unpushedです。残したいコミットは先にpushします。

デスクトップアプリでは、Gitリポジトリならセッション作成時にブランチ名の隣のworktreeオプションを選ぶと、そのセッション専用のworktreeが割り当てられます。1つのセッションで加えた変更はコミットするまで他のセッションに影響しません。保存先は既定で<project-root>/.claude/worktrees/ですが、設定の「Worktree location」でカスタムディレクトリに変更でき、worktreeのブランチ名に付くプレフィックスも設定できます。セッションをアーカイブすると対応するworktreeも削除され、PRのマージやクローズをきっかけに自動アーカイブする設定も用意されています。Windows版でLFSファイルがポインタのまま残るときはLFSポインタの原因と直し方を参照します。

エージェントの状態を1画面で束ねる運用はagent view: 複数セッションを束ねる常駐プロセス設計で扱っています。

worktree・サブエージェント・agent view・agent teamsの使い分け

Claude Codeで作業を並列化する手段は複数あり、それぞれ「誰が調整するか」「作業者同士が話すか」「同じファイルを触るか」で選び分けます。

アプローチ得られるもの向いている場面
サブエージェント得られるもの1つの会話の中で側作業を任せ、要約だけ受け取る向いている場面調査結果でメインの会話を埋めたくないとき
agent view得られるものバックグラウンドで走る複数セッションを1画面で管理向いている場面独立したタスクを渡し、進捗を後から確認したいとき
agent teams得られるもの共有タスクリストとメッセージングを持つ複数セッション向いている場面リード役がプロジェクトを分割し作業者を同期させたいとき(実験的機能・既定オフ)
ダイナミックワークフロー得られるもの台本(スクリプト)が結果を突き合わせながら多数のサブエージェントを回す向いている場面1ターンでは調整しきれない規模、または複数の視点を突き合わせたい仕事

worktreeはこの表の4つとは層が違います。ファイル編集を隔離するための道具で、単独の並列化スタイルではありません。自分で走らせるセッションにはworktreeを使い、agent viewが起動するセッションは自動的に専用worktreeへ移り、スポーンしたサブエージェントもそれぞれworktreeを持てます。一方でagent teamsはチームメイトをworktreeで隔離しないため、担当ファイルを分けて競合を避ける設計が必要です。大きな一括変更を5〜30個のworktree隔離サブエージェントに分けてそれぞれPRを開かせる/batchスキルも、この仕組みの上に成り立つ既製パターンです。

作業を指揮役と実行役に分けてサブエージェントへ振る設計はオーケストレーター設計、台本駆動で大量のサブエージェントを回す仕組みはダイナミックワークフローとはで詳しく扱っています。

baseRefでworktreeの起点を選ぶ

新規worktreeは既定でリポジトリの既定ブランチから分岐します。現在の作業の続きとしてworktreeを切りたいときは、設定のworktree.baseRefを変更します。この設定は--worktreeだけでなく、会話中のEnterWorktreeツールやサブエージェント隔離にも同じく適用されます。

{
  "worktree": {
    "baseRef": "head"
  }
}
くらべる

baseRefの2つの値

リモートから

"fresh"(既定)

リモートのorigin/<default-branch>(通常はmain)から分岐し、常にリモートと一致したきれいな状態で始まります。

手元から

"head"

ローカルの現在のHEADから分岐し、未pushのコミットや作業中のブランチの状態を引き継ぎます。進行中の作業に対してサブエージェントを隔離したいときに向きます。リンク済みworktreeの内側では、そのworktree自身のHEADを指します。

worktree.baseRefに特定のブランチ名を直接指定することはできません。既存の特定ブランチから始めたいときは、後述するgit worktree addで手動作成します。

"fresh"を使う場合、Claude Codeはorigin/HEADを裏で最新に保ちます。直近24時間以内にfetchしていなければ既定ブランチをfetchし(最大5秒でタイムアウト)、fetchに失敗すればローカルにキャッシュされた参照を使います。リモートが設定されていない場合は、ローカルの現在のHEADにフォールバックします。origin/HEADがキャッシュされておらずfetchもできない場合も同じです(v2.1.208より前は、ローカルにキャッシュされていたorigin/HEADをそのまま使っていました)。

特定のPull Requestから分岐したいときは、--worktreeにPR番号を#付きで渡すか、GitHubのPR URLをそのまま渡します。シェルが#をコメントの開始と解釈しないよう、引用符で囲みます。

claude --worktree "#1234"

このコマンドはoriginからpull/<number>/headをfetchし、.claude/worktrees/pr-<number>にworktreeを作ります。GitLabのmerge requestも同じ使い方ができ、その場合はmerge-requests/<number>/headをfetchします(v2.1.233以降)。fetch先はホストごとに変わります。

すでに存在する名前を--worktreeに渡すと、新規作成ではなく既存のworktreeを開きます。既定の"fresh"基点では、次の条件をすべて満たすときだけリポジトリの既定ブランチにリセットされます。未コミットの変更や未追跡ファイルがないこと、Claude Codeが作ったブランチのままであること、独自コミットがないか、あってもPull Requestがマージ済みでリモートブランチが削除されていること。それ以外は古い状態のまま再オープンされます。baseRefが"head"の場合と、名前がPull Requestの参照(#1234など)の場合も、リセットされません。v2.1.208より前は、名前の再利用は常に古い状態のまま再オープンでした。

マージ済みかどうかは、git上の状態だけで判定されます。push先のリモートブランチがすでに存在せず、worktree内のコミットがすべて既定ブランチに入っている場合が「マージ済み」です。

node_modulesなど大きい依存の扱い方

worktreeは新規チェックアウトなので、node_modulesのような依存ディレクトリは最初から存在しません。素朴に毎回インストールし直すと、ディスク消費とインストール時間の両方が膨らみます。Claude Codeにはこれに対応する設定が3つ用意されています。

worktree.symlinkDirectoriesは、指定したディレクトリをメインリポジトリから各worktreeへシンボリックリンクし、ディスク上での重複を避けます。既定では何もリンクされません。

{
  "worktree": {
    "symlinkDirectories": ["node_modules", ".cache"]
  }
}

大規模なモノレポでは、worktree.sparsePathsでgitのsparse-checkoutを使い、指定したディレクトリとルート直下のファイルだけをworktreeに書き出す設定もあります。ディスクへの書き込み量そのものを減らせるため、リポジトリ全体が巨大なケースに向きます。

{
  "worktree": {
    "sparsePaths": ["packages/my-app", "shared/utils"]
  }
}

.envのようなgitignore対象の設定ファイルは、シンボリックリンクではなく.worktreeincludeファイルで個別にコピーします。プロジェクトルートに置き、書式は.gitignoreと同じです。gitignoreされていてかつパターンに一致するファイルだけがコピーされるため、追跡対象のファイルが誤って重複することはありません。

.env
.env.local
config/secrets.json

この.worktreeincludeは、--worktreeで作るworktree・サブエージェントのworktree・デスクトップアプリの並列セッションのすべてに適用されます。WorktreeCreateフックで独自の作成ロジックに置き換えている場合はこのファイルが処理されないため、コピー処理はフックのスクリプト内に自分で書きます。

worktree間で共有されるもの・されないもの

worktreeは専用のファイルとブランチを持ちますが、メインの作業コピーと共有しているものが4つあります。作成経路が--worktreeでもgit worktree addでもデスクトップアプリでも、この4つは同じように働きます。

  • .gitディレクトリ: worktree内のgitコマンドはメインリポジトリの共有.gitディレクトリに書き込みます。sandboxing(ファイルシステムへの書き込みを制限する隔離機能)はこの書き込みを許可するため、sandbox有効時でもworktree内からgit commitが問題なく動きます
  • プラグイン(v2.1.200以降): メインの作業コピーでプロジェクトスコープにインストールしたプラグインは、同じリポジトリのworktreeでもそのまま読み込まれ、worktreeごとの再インストールは不要です
  • 権限承認(v2.1.211以降): worktreeセッションでBashコマンドを「今後確認しない」で承認すると、その規則はメインの作業コピーの.claude/settings.local.jsonに保存されます。この規則はメインの作業コピーでも他の全worktreeでも適用され、worktreeを削除しても残ります。ただしWindowsなど、Claude Codeがリポジトリルートを使わない場合は、規則はそのworktreeに残ります。v2.1.211より前は承認内容がそのworktree内に保存されるだけで、他の場所には適用されず、worktreeを削除すると失われていました
  • 未追跡のスキル・エージェント・コマンド: worktreeのチェックアウトにルート直下の.claude/skillsがないことがあります(.claude/skillsをgitignoreしているときなど)。その場合は、メインの作業コピーのプロジェクトスキルがworktreeセッションにも読み込まれます。worktree側に.claude/skillsがあれば、そちらだけが読み込まれます。.claude/agentsと.claude/commandsも同じ扱いで、スキルについてはv2.1.277以降が条件です

共有されない側にも、フックまわりで1点つまずきやすい所があります。worktreeに入ったあとも、フックの${CLAUDE_PROJECT_DIR}はセッションを始めたプロジェクトルートを指したままです。そのため${CLAUDE_PROJECT_DIR}/.claude/hooks/check-style.shのようなコマンドは、メインの作業コピーにあるスクリプトを動かします。worktreeのパスが必要なフックは、入力JSONのcwdを読みます。cwdはworktreeのルートを指し、Claudeがcdするたびに動きます。

設定項目そのものの全体像はsettings.json完全ガイドにまとめています。

pushする前に確認しておきたいこと

worktreeそのものに固有の危険ではありませんが、複数のworktreeを行き来していると見落としやすい落とし穴があります。Gitのpushは引数を省略するとpush.defaultの設定に従って挙動が決まり、既定値はGit 2.0以降"simple"(現在のブランチと同名のリモートブランチへpush)です。ここを"upstream"に変更していると、git pushは現在のブランチの@{upstream}、つまりそのブランチが追跡しているリモートブランチへ直接pushします。

手動でgit worktree addする際に--trackなどでリモート追跡ブランチ(たとえばorigin/main)を上流に持つブランチを切ると、そのローカルブランチの上流がorigin/mainになります。この状態でpush.defaultが"upstream"だと、意図せずmainへ直接pushしてしまう構図が成立します。worktreeで作業する前に、現在のブランチの上流を確認しておくと安全です。

git rev-parse --abbrev-ref --symbolic-full-name @{push}

Git 2.50.1で、一時リポジトリを使って確かめました。origin/mainを追跡するブランチをgit worktree add --track -b local-mainで切り、push.defaultをupstreamにしたあとの出力です。

$ git worktree list
<demo>/repo     e2daaf5 [main]
<demo>/wt-a     e2daaf5 [feature-a]
<demo>/wt-main  e2daaf5 [local-main]
$ cd ../wt-main && git rev-parse --abbrev-ref --symbolic-full-name @{push}
origin/main

ブランチ名はlocal-mainでも、pushの行き先はorigin/mainと表示されます。feature-aをチェックアウト中のworktreeが残っている間にgit branch -d feature-aを実行しました。結果はerror: cannot delete branch 'feature-a' used by worktree at '<demo>/wt-a'で拒否されました。git worktree remove ../wt-aのあとも、ブランチfeature-a自体は残っています。

手動でのworktree管理とGit以外のVCS対応

git worktreeコマンドを直接使うのは、特定の既存ブランチをチェックアウトしたいときや、worktreeをリポジトリの外側に置きたいときです。

git worktree add ../project-feature-a -b feature-a
cd ../project-feature-a
claude

一覧・削除・ロックなど、サブコマンドは用途ごとに揃っています。

サブコマンド用途
git worktree list用途一覧表示。-vで詳細、--porcelainでスクリプト用出力
git worktree remove用途削除。未追跡ファイルや追跡ファイルの変更が残る場合は-fが必要
git worktree lock / unlock用途削除・pruneの対象から一時的に除外
git worktree move用途移動。メインの作業コピー自体、またはサブモジュールを含むworktreeは移動不可
git worktree prune用途参照が失われたworktree情報を掃除。git gc経由で呼ばれるときの既定の猶予期間はgc.worktreePruneExpireで3か月(git worktree prune --expire 3.months.ago相当)
git worktree repair用途手動でmvしたあとの接続を再確立

PRレビューでこの手動管理を使う場面もあります。レビュー対象のブランチを別worktreeでチェックアウトすれば、進行中の自分の作業を止めずに動作確認できます。Claude Codeでgh pr createを使ってPRを作ると、セッションはそのPRに自動でリンクされ、あとからclaude --from-pr <番号>でそのPRに紐づくセッションを絞り込んで再開できます。PRリンクの遷移先を変える設定はprUrlTemplateの使い方で扱っています。

Gitではないバージョン管理(SVN・Perforce・Mercurial等)を使うリポジトリでは、WorktreeCreateとWorktreeRemoveのフックで作成・削除のロジックそのものを置き換えられます。WorktreeCreateフックは標準出力にworktreeのパスを返す必要があり、ゼロ以外の終了コードを返すとworktree作成自体が中止されます。WorktreeRemoveがゼロ以外の終了コードで終わり、そのあともworktree_pathのディレクトリが残っていると、削除失敗として扱われ、worktreeはディスクに残ります。gitへのフォールバックはありません。JSON出力は読まれず、フックが作ったブランチもClaude Codeは消さないため、ブランチ削除はフック内に書きます。この場合、.worktreeincludeはGitのロジックを前提にしているため処理されず、gitignore対象ファイルのコピーはフックのスクリプト内に自分で書きます。

フックの入力スキーマ・実行タイプ・設定ファイルの書き方はHooks完全ガイド、ユースケース別のレシピはHooks実例カタログにまとめています。

つまずきやすい落とし穴

削除忘れ: git worktree removeを忘れると、そのブランチをgit branch -dしようとしたときに「worktreeでチェックアウト中」と拒否されます。git worktree listで定期的に棚卸しする習慣が実質的な対策です。

シンボリックリンク化されたパスでの作成拒否: .claude・.claude/worktrees・worktreeディレクトリ自体がシンボリックリンクの場合、Claude Codeはworktreeの作成そのものを拒否し、そのパスをエラーで示します。v2.1.212より前は、リポジトリにコミット済みのシンボリックリンクがこれらのパスにあると素通りしてしまい、リポジトリの外側にファイルを作成してしまうことがありました。

起動時のworktree進入失敗: WorktreeCreateフックが作成したディレクトリ以外の文字列を出力した場合や、セットアップ後にディレクトリが削除された場合、Claude Codeはパス名を含むエラーを出して終了コード1で終わります。

大きいリポジトリでのディスク消費: .gitは共有されますが、チェックアウトしたファイル群はworktreeごとに実体として存在します。10GBのリポジトリを5つworktreeで切れば単純計算で50GB近くになるため、symlinkDirectoriesやsparsePathsを検討する価値があります。ただしsparsePathsはsparse worktreeが存在する間、共有.git/configのextensions.worktreeConfigを有効化する副作用を伴います。go-git系のサードパーティ製gitツールを併用している場合は、この設定変更が影響しないか確認しておくと安全です。

大きい失敗の再現・回避策はClaude Codeが期待通りに動かない10シナリオ、開発環境をコンテナ単位で隔離する別のアプローチはDevContainerで安全に動かす完全実装で扱っています。worktreeはディレクトリ単位の隔離、DevContainer sandboxはプロセス・認証情報単位の隔離で、目的が異なるぶん組み合わせて使えます。

worktreeが片付かない・期待どおり動かないときの切り分け

sweep(定期スイープ)が残すworktreeは、次の順で手動削除します。ロックと未コミットの変更が、拒否の主な理由です。隔離中のセッションでコマンドが拒否されたときは、worktree isolation checksで拒否される原因と直し方を参照してください。

手順

残ったworktreeを手動で消す順序

  1. 1

    一覧で場所とブランチを確かめる

    git worktree listで、消したいworktreeのパスとブランチを特定します。

  2. 2

    ロックされていたら外す

    git worktree removeがロックを理由に拒否したら、git worktree unlock <path>を先に実行します。

  3. 3

    未コミットの変更ごと捨てるなら --force

    変更や未追跡ファイルが残っているworktreeは、git worktree remove --force <path>で削除します。ブランチは消えないので、不要ならgit branch -dを足します。

スイープが残すのは、次のworktreeです。変更・未追跡ファイル・未pushのコミットがあるもの、--worktreeで起動したままバックグラウンドへ回していないセッションのもの、自分でgit worktree addしたものです。チェックアウト済みサブモジュールに変更がある、または調べられない場合(v2.1.274以降)や、filter driverを判定できない、無効化できない設定がある場合も残ります。Claude Codeが作ったworktreeにはgitのメタデータへ印が書かれ、印のないworktreeはフックで作ったものも含めてスイープの対象外です。

Git LFSをgit lfs install --localで設定したリポジトリでは、Claude Codeが作ったworktreeのLFS管理ファイルが実体ではなくポインタファイルになります。リポジトリ自身の.git/configにあるフィルタードライバーはシェルコマンドであり、Claudeを含めて書き込める側が仕込める余地があるため、作成時に実行されません。v2.1.247より前は実行されていました。worktree内でgit lfs pullを実行すれば実体が揃います。グローバル設定に書く通常のgit lfs installは影響しません。

worktreeそのものが作られないケースもあります。リポジトリのgit configを読めないときなどです。Could not read the repository git config ...やGit was not run: ...のようなエラーが出ます。

サブエージェントのisolation: worktreeには、もう1つ癖があります。起動時に読む指示ファイルはメインの会話から取るため、既定の.claude/worktrees/配下では、worktreeのルートにあるCLAUDE.mdや.claude/rules/は、ブランチ側で内容が違っていても読み込まれません。

まとめ

並列化の主目的がファイル衝突の回避なら、まず--worktreeで十分です。依存ディレクトリの重複や.envの持ち込みが気になるようになった段階で、symlinkDirectoriesと.worktreeincludeを足していく順で進められます。push先の上流確認は、push.defaultを"upstream"にしている人にとっては作業前の1コマンドで済む保険です。

参照した一次ソース

この記事の記述は、次の一次ソースと照合しています。更新時に参照先が変わった場合は一覧も更新します。

  1. code.claude.com/docs/en/worktrees
  2. code.claude.com/docs/en/sub-agents
  3. code.claude.com/docs/en/agents
  4. code.claude.com/docs/en/settings
  5. code.claude.com/docs/en/hooks
  6. code.claude.com/docs/en/agent-view
  7. code.claude.com/docs/en/desktop
  8. git-scm.com/docs/git-worktree
  9. git-scm.com/docs/git-config
この記事を共有:XはてブLinkedIn