factsClaude Codeworktrees

stable4 日前 · 2026-08-09

Run parallel sessions with worktrees

概要

git worktree ごとに Claude Code のセッションを分離し、並行して走るセッションのファイル編集が衝突しないようにする仕組み。--worktree / -w で作成・起動する。worktree は git リポジトリを前提とし、他の VCS では hook で置き換える。

仕様

起動

  • claude --worktree <name>(短縮形 -w)で分離された worktree を作り、その中で Claude を起動する
  • 既定の作成先はリポジトリルートの .claude/worktrees/<name>/、ブランチ名は worktree-<name>
  • 名前を省略すると bright-running-fox のような名前が生成される
  • 対話実行には workspace trust が必要。そのディレクトリで Claude を実行したことがない場合、一度 claude を実行して trust ダイアログを承認する。未承認なら --worktree はエラー終了する
  • -p の非対話実行は trust チェックを飛ばすため、claude -p --worktree はそのまま進む
  • worktree は新しい checkout なので、依存関係のインストールなど開発環境の初期化が必要

セッション中に worktree へ入る

  • Claude に worktree で作業するよう依頼すると EnterWorktree ツールで作成する
  • worktree 内から EnterWorktree に対象パスを渡すと別の .claude/worktrees/ 配下の worktree へ直接切り替えられる。元の worktree はディスク上にそのまま残る
  • リポジトリの .claude/worktrees/ の外のパスに入る場合は必ず承認を求める。セッションの作業ディレクトリ・書き込み権限・CLAUDE.md などのプロジェクト設定がその場所へ移るため。EnterWorktree の permission rule や「don't ask again」ではこのプロンプトは抑止できず、bypassPermissions モードのみが飛ばす
    • v2.1.206 より前は、既存の worktree パスなら確認なしに入れた

後片付け

対話セッションを終了すると、削除で失われる作業(変更済み・未追跡ファイル、新しいコミット)があるかを検査する。

  • worktree がクリーン: 名前なしセッションでは worktree とブランチを自動削除する。名前付きセッションでは先に確認する
  • 作業が残っている: 保持か削除かを尋ねる。削除するとディレクトリ・ブランチと、その中の作業がすべて消える
  • -p の非対話実行には終了時のプロンプトが無いため後片付けされない。git worktree remove で削除する

セッションの resume

  • worktree 内にあったセッションを resume すると、その worktree へ戻る。対話 resume、-p での --continue / --resume、Agent SDK のいずれでも同じ
  • 戻す前に、その worktree が main checkout とは別の checkout であることを検証し、失敗した場合は再入場を拒否する
  • 起動ディレクトリと resume 方法で挙動が変わる
    • 起動ディレクトリ: main checkout やリポジトリの別ディレクトリから resume する。git で .claude/worktrees/ 配下に作った worktree は、その中から起動しても再入場する。それ以外の worktree の中から起動した場合、そこから保証できるときのみ再入場する(自身がリポジトリである worktree、git メタデータの無い worktree、git worktree add で作った worktree のサブディレクトリからの起動は拒否されるので main checkout から起動する)
    • --fork-session: fork したセッションは Claude を起動したディレクトリで開始し、元セッションの worktree には手を付けない
    • worktree が削除済み: 起動したディレクトリで resume し、worktree が無いことを通知してセッションの worktree binding をクリアする
  • Claude Code が git で作った worktree に出入りすると、トランスクリプトもセッションの新しい作業ディレクトリの下に記録される(/cd と同じ扱い)。WorktreeCreate hook が作った worktree はトランスクリプトを起動ディレクトリに保つ。v2.1.198 以降が必要
  • v2.1.212 より前は、非対話 resume は起動ディレクトリに留まり、ExitWorktree は「終了すべき worktree セッションが無い」と報告していた

分離の強制

worktree に分離されたセッション(--worktree 起動、EnterWorktree での入場、worktree セッションの resume のいずれでも)では、main checkout に到達するツール呼び出しをブロックする。分離セッションから起動したすべての subagent にも適用され、対話・バックグラウンドを問わない。

チェック内容
File editsmain checkout 内のパスを対象とする Edit / Write / NotebookEdit をブロックする
Command working directory作業ディレクトリが main checkout に解決される、または main checkout の外に留まることを検証できない Bash / PowerShell / Monitor コマンドをブロックする
Git redirectsgit -C--git-dirGIT_DIR / GIT_WORK_TREE 変数、git 実行前の main checkout への cd などで git を main checkout に向ける Bash / Monitor コマンドをブロックする。worktree 内に留まることを検証できないコマンドもブロックする。PowerShell コマンドには working-directory チェックのみを適用する
  • チェック対象は Claude Code を起動したリポジトリ(linked worktree のリンク元である main checkout を含む)

subagent の worktree 分離

  • カスタム subagent の frontmatter に isolation: worktree を追加すると常に自分の worktree で動く
  • 各 subagent には一時的な worktree が割り当てられ、変更なしで終了すると自動削除される。変更がある worktree は、後述の定期スイープが作業を失わずに削除できるようになるまでディスク上に残る
  • subagent の worktree は --worktree と同じ base branch を使う(worktree.baseRef"head" でない限りリポジトリの既定ブランチから分岐する)

定期スイープ

  • Claude が subagent とバックグラウンドセッション用に作った worktree のうち、cleanupPeriodDays 設定より古いものを定期的に削除する
  • 作業(変更済み・未追跡ファイル、未 push のコミット)が残っている worktree はスキップする
  • --worktree で自分が作った worktree は決して削除しない
  • agent の実行中は git worktree lock をかけ、並行するクリーンアップが削除できないようにする。終了時に解除される
  • プロセスが終了したセッションのために Claude Code が設定したロックはスイープが解除する。自分で git worktree lock したロックは解除しない。v2.1.210 より前は kill されたセッションのロックが git worktree unlock するまで残っていた
  • スイープが残した worktree を消すには git worktree remove(未コミット変更や未追跡ファイルがある場合は --force

作成のカスタマイズ

base branch

worktree.baseRef 設定(settings):

内容
"fresh"(既定)リモートのリポジトリ既定ブランチ(通常 main)から分岐する
"head"ローカルの現在の HEAD から分岐し、未 push のコミットや feature ブランチの状態を引き継ぐ。worktree 内では、その worktree の HEAD に解決される
  • worktree.baseRef にブランチ名は指定できない。特定の既存ブランチから始めるには git で直接作成する
  • "fresh" の場合、24 時間以内に fetch していなければ既定ブランチを fetch して origin/HEAD を更新する(上限 5 秒、失敗時はローカルキャッシュの ref を使う)。remote が未設定、または origin/HEAD がローカルに無く fetch もできない場合は現在のローカル HEAD にフォールバックする
  • v2.1.208 より前は、fresh の worktree はローカルにキャッシュ済みの origin/HEAD をそのまま使っていた

pull request から分岐

  • --worktree# 付きの PR 番号、または GitHub の pull request URL を渡す
  • origin から pull/<number>/head を fetch し、.claude/worktrees/pr-<number> に worktree を作る
  • シェルが # をコメント開始と解釈しないよう引用符で囲む

gitignore されたファイルのコピー

  • プロジェクトルートに .worktreeinclude を置くと、worktree 作成時に自動コピーされる
  • 記法は .gitignore と同じ。パターンに一致し、かつ gitignore されているファイルだけがコピーされる(追跡済みファイルは複製されない)
  • Claude Code が git で作るすべての worktree に適用される(--worktree、subagent の worktree、desktop アプリの並行セッション)
  • WorktreeCreate hook を使う場合は hook スクリプト内でコピーする

同じ worktree 名の再利用

  • 既にディレクトリが存在する名前を --worktree に渡すと、新規作成せずその worktree を開く
  • 既定の "fresh" base では、次の条件をすべて満たす場合に再オープン時にリポジトリ既定ブランチへリセットされる
    • 未コミットの変更も未追跡ファイルも無い
    • Claude Code が作ったブランチのまま
    • 独自のコミットが無い、または pull request がマージ済みでリモートブランチが削除されている
  • それ以外(条件を満たさない、状態を検証できない、worktree.baseRef"head"、名前が PR 番号)は古い tip で再オープンされる
  • v2.1.208 より前は、名前を再利用すると常に古い tip で再オープンされた

hook による置き換え

  • WorktreeCreate hook を設定すると、既定の git worktree ロジックを完全に置き換えられる(.claude/worktrees/ 以外の場所への配置を含む)
  • 非 git の VCS(SVN / Perforce / Mercurial など)では WorktreeCreateWorktreeRemove hook を設定する
  • hook が既定の git 挙動を置き換えるため、--worktree 使用時に .worktreeinclude は処理されない

main checkout と共有されるもの

worktree は独自のファイルとブランチを持つが、次を main checkout と共有する。--worktreegit worktree add・desktop アプリのいずれで作った場合も同じ。

  • リポジトリの .git ディレクトリ: worktree 内の git コマンドは main リポジトリの共有 .git に書き込む。sandboxing はその書き込みを許可するため、sandbox 有効時も worktree 内から git commit が動く
  • Plugins: main checkout から project scope でインストールした plugin は同じリポジトリの worktree でも読み込まれる。v2.1.200 以降が必要
  • Permission approvals: worktree セッションで Bash コマンドに「Yes, don't ask again」を選ぶと、ルールは main checkout の .claude/settings.local.json に保存され、main checkout と同リポジトリの全 worktree に適用され、worktree を削除しても残る。v2.1.211 より前はその worktree 内に保存され、他所には適用されず、worktree 削除で失われた

手動での管理

git worktree add ../project-feature-a -b feature-a
git worktree add ../project-bugfix fix-issue-456
git worktree list
git worktree remove ../project-feature-a

設定

{
  "worktree": {
    "baseRef": "head"
  }
}
# .worktreeinclude
.env
.env.local
config/secrets.json
---
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 には git リポジトリが必要
  • .claude/worktrees/.gitignore に追加すると、main checkout で worktree の内容が未追跡ファイルとして現れない
  • Windows では worktree の削除がその外のファイルを消さない。worktree 内のフォルダが NTFS junction やディレクトリ symlink の場合はリンクだけを削除し、参照先のフォルダは残す。v2.1.205 より前は、サブディレクトリにネストしたリンクを持つ worktree の削除で参照先フォルダを消すことがあった
  • .claude.claude/worktrees、worktree ディレクトリ自体が symlink の場合、worktree の作成を拒否する。symlink を削除して再試行する。v2.1.212 より前は、コミット済みの symlink があるとそれを辿ってリポジトリ外にファイルを作ることがあった
  • 起動時に worktree ディレクトリへ入れない場合、パスを示すエラーを出して終了コード 1 で終了する(WorktreeCreate hook が作成したディレクトリ以外を出力した場合や、セットアップ後にディレクトリが削除された場合)。v2.1.205 より前はセッションがクラッシュし、-p では約 30 秒停止した後に終了コード 0 で終了した
  • Refusing to use <path> as an isolation worktree は、ディレクトリの git identity 検査で拒否されたことを意味する。多くはディレクトリの git メタデータが main checkout に解決される場合(.git ファイルが main リポジトリの .git を指す、core.worktree リダイレクトで working tree が main checkout に解決されるなど)。読めない .git エントリがある場合も拒否する。拒否されたディレクトリは作業が残っている可能性があるためそのまま残される
  • ネットワークパスに記録された worktree へは決して resume しない(its recorded path has a network spelling

resume が worktree の外で始まる場合のメッセージ

メッセージの冒頭意味
Your worktree <path> no longer existsworktree ディレクトリが削除された。分離なしで現在のディレクトリで継続し、binding をクリアする。対処不要
Could not verify your worktree <path> this time検証できなかった(多くは一時的)。binding は保持され、分離なしで継続する。再度 resume して再試行する
Did not re-enter your worktree <path>binding が安全でないとして拒否された。binding をクリアし、分離なしで継続する
Could not re-enter your worktree <path>起動場所からその worktree を保証できなかった(多くは worktree の中から起動したため)。binding は保持される

-p の非対話モードと Agent SDK の resume では、worktree が消えている場合を除き、分離なしで継続せず stderr のエラーで resume を停止する。

関連

  • facts/claude-code/sub-agents.md
  • facts/claude-code/cli-reference.md
  • facts/claude-code/settings.md
  • facts/claude-code/hooks.md
  • facts/claude-code/permissions.md
  • facts/claude-code/sandboxing.md
  • facts/claude-code/tools-reference.md
  • facts/claude-code/headless.md