原典: Run parallel sessions with worktrees / 日本語版
一行要約
並行して走らせる Claude Code のセッションを別々の git worktree に閉じ込めて編集の衝突を防ぐ機能で、隔離は「そうしてください」ではなく Claude Code 側の4つの検査で強制される(うち1つは無効化できない)。
要点
何をするものか
A git worktree is a separate working directory with its own files and branch, sharing the same repository history and remote as your main checkout. Running each Claude Code session in its own worktree means edits in one session never touch files in another, so one session can build a feature while a second fixes a bug.
git worktree は、独自のファイルとブランチを持ち、リポジトリの履歴とリモートはメインのチェックアウトと共有する、別の作業ディレクトリである。Claude Code のセッションをそれぞれ自分の worktree で走らせれば、あるセッションの編集が別のセッションのファイルに触れることは決してない。一方が機能を作り、もう一方がバグを直せる。
claude --worktree feature-auth # -w でも同じ既定では .claude/worktrees/<name>/ に作られ、ブランチ名は worktree-<name>。名前を省くと bright-running-fox のような名前が生成される。
並行実行の手段は他にもあり、worktree が担うのはファイル編集の隔離だけ。 原典は sub-agents(1セッション内で仕事を分ける)と cross-session-messaging(worktree にいるセッション間で発見を渡す)を並べて位置づけている。
隔離は4つの検査で強制される
ここがこのページの中心。「別ディレクトリだから当たらないはず」ではなく、当たろうとしたツール呼び出しを Claude Code が拒否する。
| 検査 | 何を止めるか |
|---|---|
| File edits | メインのチェックアウトのパスを狙う Edit / Write / NotebookEdit |
| Command working directory | 作業ディレクトリがメインのチェックアウトに解決される、または外に留まると検証できない Bash / PowerShell / Monitor |
| Git redirects | git -C、--git-dir、GIT_DIR / GIT_WORK_TREE、git の前の cd で git をメインへ向けるもの |
| Command shape | コマンドの文面から「走る git が worktree 内に留まる」と検証できない形 |
最後のものが特に強い。
Claude Code blocks a Bash or Monitor command when it can’t verify from the command text that any git the command runs stays inside the worktree. That happens, for example, when the command name is computed at runtime, when the syntax can’t be parsed, or when an expansion such as
${!name}or${ command; }could run a command the text doesn’t spell out. Claude Code tells Claude how to rewrite the refused command, such as splitting it into plain, separate commands. You can’t turn this check off.Claude Code は、そのコマンドが走らせる git が worktree の内側に留まることを、コマンドの文面から検証できないとき、Bash / Monitor のコマンドをブロックする。たとえばコマンド名が実行時に決まるとき、構文が解析できないとき、
${!name}や${ command; }のような展開が文面に書かれていないコマンドを走らせうるときである。拒否したコマンドをどう書き直すか(素直な別々のコマンドに分ける等)は Claude に伝える。この検査は切れない。
同じ強制は、そのセッションが起こす subagent 全部に及ぶ。 対話セッションでも background でも同じで、--worktree で始めても、Claude が EnterWorktree で入っても、worktree セッションを resume しても同じ。PowerShell のコマンドについてだけは、作業ディレクトリの検査のみが適用される。
検査の対象は、起動したリポジトリと、リンク元のメインのチェックアウト(linked worktree から辿れるほう)。拒否はworktree の名前と進め方を添えたツールエラーとして Claude に見える。
subagent を worktree に隔離する
「エージェントに worktree を使って」と頼むか、カスタム subagent の frontmatter に isolation: worktree を書けば恒久的になる。
---
name: refactorer
description: Applies mechanical refactors across many files
isolation: worktree
---worktree で走る subagent が起動時に持つ指示ファイルは main の会話から来る(worktree からではない)。既定の場所(.claude/worktrees/)の worktree なら、その中のファイルを読んでも、worktree のルートの CLAUDE.md と .claude/rules/ は読み込まない —— worktree のブランチで中身が違っていても。
変更なしで終わった subagent の worktree は自動で消える。変更が残っていれば、後述の掃除が安全に消せるまでディスク上に残る。
hook のパスは worktree に付いてこない(落とし穴)
${CLAUDE_PROJECT_DIR}stays put: it still points at the project root where the session started, so a hook command such as${CLAUDE_PROJECT_DIR}/.claude/hooks/check-style.shstill runs the script in the main checkout.
${CLAUDE_PROJECT_DIR}は動かない。セッションが始まったプロジェクトルートを指したままなので、${CLAUDE_PROJECT_DIR}/.claude/hooks/check-style.shのような hook コマンドはメインのチェックアウト側のスクリプトを走らせる。
worktree のパスが要る hook は、入力 JSON の cwd を読む(cwd は Claude に追随し、cd でさらに動く)。
終了時に消えるかどうか
対話セッションを抜けるとき、Claude Code は消して失われるもの(変更・未追跡ファイル・チェックアウトした submodule の中の未コミットの作業・新しいコミット)を検査する。この規則は Claude Code が git で作った worktree の話で、WorktreeCreate hook が作ったものは WorktreeRemove の規則に従う(hooks)。
- きれい → 名前なしのセッションなら worktree もブランチも自動で削除。名前付きセッションは先に確認を求める
- 作業が残っている → 残すか消すかを尋ねる
- 状態を確かめられない(変更を数えられない、submodule のチェックアウトを調べられない)→ 自動では消さずに尋ね、何を確かめられなかったかを挙げる
-pの非対話実行には終了時の確認が無いので掃除されず、作成時に取ったロックも後日の一掃まで残る
定期的な一掃は subagent と background セッションの worktree を cleanupPeriodDays を過ぎたら消すが、次のものは残す —— 作業が残っている(変更・未追跡ファイル・未 push のコミット)、チェックアウトした submodule に変更や未追跡ファイルがあるか submodule を調べられない(v2.1.274 以降)、filter driver の設定を判別できないか切れない、まだ background にしていない --worktree セッションのもの(古さに関わらず)、自分で git worktree add したもの。Claude Code は自分が git で作った worktree の git メタデータに目印を書き込み、目印の無いものは消さない —— 自分で git worktree add したものが巻き込まれないようにするため。WorktreeCreate hook が作った worktree にも目印は無いので、一掃では常に残る。
メインのチェックアウトと共有されるもの
ファイルとブランチは別になるが、4つは共有される(--worktree で作っても git worktree add でもデスクトップアプリでも同じ)。
| 共有のされ方 | |
|---|---|
.git ディレクトリ | worktree の git コマンドはメインの共有 .git に書く。sandbox はこの書き込みを許すので、sandbox 有効でも worktree から git commit できる |
| plugin | メインのチェックアウトで project スコープに入れた plugin は、同じリポジトリの worktree でもロードされる(worktree ごとの入れ直しは不要。v2.1.200 以降) |
| 権限の承認 | worktree で「Yes, and don’t ask again」を選ぶと、ルールはメインのチェックアウトの .claude/settings.local.json に保存される。だから他の worktree にも効き、その worktree を消しても残る(Windows などリポジトリルートを使わない場合はその worktree に残る。v2.1.211 より前は worktree の中に保存され、消すと失われた) |
| 未追跡の skill / agent / command | worktree 側のルートに .claude/skills が無ければ(gitignore しているときなど)、メインのチェックアウトのものがロードされる。worktree に自前の .claude/skills があればそちらだけ。.claude/agents と .claude/commands も同じ(skill は v2.1.277 以降) |
知っておくこと
- 対話実行には workspace trust が要る。 そのディレクトリで一度も
claudeを動かしていないと--worktreeはエラーで終わる。-pの非対話実行は trust の検査を飛ばす .claude/worktrees/を.gitignoreに入れる(メインのチェックアウトに未追跡ファイルとして出てくるため)- worktree は新しいチェックアウトなので開発環境の初期化が要る。
.envのような gitignore されたファイルを毎回持ち込むには.worktreeincludeを置く - Claude が
EnterWorktreeで.claude/worktrees/の外へ出るときは必ず承認を求める。permission ルールや「今後聞かない」でも抑制されず、bypassPermissionsだけが飛ばす - worktree の中で終わった(抜けずに終わった)セッションを再開すると、その worktree に戻る(対話・
-pの--continue/--resume・Agent SDK のいずれでも。--continueは起動したディレクトリで記録された最新のセッションを選ぶ)。worktree を残して抜けたなら、終了時に出るclaude --worktree <name> --resumeで戻る。worktree が消えていれば起動したディレクトリで再開し、束縛を解除する- 戻る前に「メインとは別のチェックアウトのままか」を検証し、通らない worktree には入り直さない
- どこから起動したかで変わる。 Claude Code が git で
.claude/worktrees/下に作った worktree は、その中から起動しても戻る。それ以外の worktree の中から起動した場合は、そこから素性を保証できるときだけ戻る(自分自身がリポジトリである worktree、git メタデータの無い worktree、git worktree addで作った worktree のサブディレクトリからの起動は断られる)—— メインのチェックアウトから起動するのが確実 --fork-sessionでは、fork したセッションは起動したディレクトリで始まり、元セッションの worktree はそのまま
- subagent の worktree も
--worktreeと同じベースブランチを使う(worktree.baseRefが"head"でなければ既定ブランチから分岐する) - git でないバージョン管理でも、hook で git のロジックを置き換えれば使える
そのまま使える具体例
claude --worktree feature-auth # 隔離した worktree を作って起動
claude -w # 名前は自動生成
git worktree remove <path> # -p 実行など、自動で消えなかったものを消す
git worktree remove --force <path> # 未コミットの変更・未追跡ファイルがあるとき
git worktree unlock <path> # ロックで remove が拒否されるとき.claude/worktrees/——.gitignoreに入れる.worktreeinclude—— gitignore されたファイルを新しい worktree に持ち込む
原典で言及されている関連文書
- sub-agents — 1セッション内で仕事を分ける側。
isolation: worktreeの frontmatter もこちら - cross-session-messaging — worktree にいるセッション間で発見を渡す
- sessions — 名前付きセッションと再開
- hooks —
${CLAUDE_PROJECT_DIR}と入力 JSON のcwd - permissions —
EnterWorktreeの承認 - headless —
-pでの再開と trust の扱い - settings —
cleanupPeriodDays