TL;DR
git worktreeが worktree ごとに分けるのは、作業ツリーとHEAD・indexなどの per-worktree ファイルだけです。git のドキュメントは、linked worktree が "sharing everything except per-worktree files" と書いています(git-worktree)。- 並列エージェントの間で共有されたまま残るのは、メインのチェックアウト・
refs/(stash を含む)と config・ディスク・台帳の採番・一時領域・ローカルで動かす重いテスト・認証の状態です。この記事はこれを 1 枚の棚卸し表にしました。 - 表の各行には、このリポジトリで実際に起きた事故を対応させています。メインのチェックアウトの切り替え、ディスク枯渇(ENOSPC)、台帳 ID の重複取得、一時ファイルの上書き、テストログの取り違えです。
- 閉じ方は、worktree の外にある資源ごとに委託文の境界として 1 行ずつ書くことです。書式を §4 に載せました。
はじめに:worktree で分けたのに、ぶつかった
こんにちは、みねです。
このリポジトリでは、記事の執筆やガードの修正を複数のエージェントに並列で委託しています。各エージェントには git worktree で別の作業ディレクトリを割り当てます。Claude Code のドキュメントも、並列セッションを worktree で分ける手順を "so concurrent edits don't collide" と紹介しています(Common workflows)。
それでも事故は起きました。どれも、ファイルの編集どうしがぶつかったのではありません。worktree の外にある資源を、複数のエージェントが同時に使ったことが原因でした。
この記事はその資源を棚卸しした記録です。基準のコミットは 122597ad71aaae46f6cb98b31f5d4c08f1408fb0(以降 122597ad)、計測日は 2026-10-14 です。
近接記事との違い
| 記事 | 主題 | この記事との違い |
|---|---|---|
| マルチエージェント開発の実装パターン2026 | Hub-and-Spoke / Pipeline / Peer-to-Peer の 3 構成と、エージェント間の状態の受け渡し・rate limit | エージェントどうしの通信を設計する記事。本記事は通信しないのに共有してしまうローカル資源を扱う |
| 『最大IDの次』は並行ブランチで必ず衝突する | 連番 ID の衝突と、CI ガードの検出窓 | 本記事の表の 1 行(台帳の採番)を深掘りした記事。本記事はその行を他の共有資源と並べて扱う |
1. worktree が分けるもの・分けないもの
git の仕様:refs と config は既定で共有
git のドキュメントは、共有の範囲をこう書いています。
In general, all pseudo refs are per-worktree and all refs starting with
refs/are shared.
分かれるのは HEAD のような pseudo ref と index で、ブランチ(refs/heads/)は共有です。config も "By default, the repository config file is shared across all worktrees." とあります。
stash は refs/stash に入ります(git-stash)。上の規則から、stash は worktree をまたいで共有されます。あるエージェントが素の git stash pop を打つと、別のエージェントが積んだ変更を取り出しうるということです。
Claude Code の worktree:共有されるものを明記している
Claude Code の worktree のドキュメントには "What worktrees share with the main checkout" の節があり、共有される .git ディレクトリ、プロジェクトスコープのプラグイン、許可の承認("Yes, and don't ask again" はメインのチェックアウトの .claude/settings.local.json に保存される)を挙げています。
同じページは、メインのチェックアウトへの書き込みを防ぐ検査の限界も書いています。
None of them tracks which files a shell command writes, so a command that writes into the main checkout without running git there, such as
cpor a shell redirect, isn't refused by them.
また worktree は新しい checkout なので、依存のインストールや .env のような gitignore 配下のファイルは自分で用意する必要があります(.worktreeinclude でコピーできる)。
ツール側も worktree の外に手を入れ始めている
2026-10 の更新でも、worktree の周辺に手が入っています。Codex CLI 0.162.0(2026-10-08)は、管理された Git worktree を作成・一覧するツールを追加しました。GitHub Copilot の 2026-10-09 の週次リリースには、VS Code 1.141 で非アクティブなセッションの worktree が使うディスク容量を表示し、削除を選べる機能が入っています。ディスクは worktree が分けない資源の 1 つで、どちらも worktree の作成と後始末の側の改善です。ここでは製品の優劣は扱いません。
2. 共有資源の棚卸し表
| # | 共有資源 | どう共有されるか | このリポジトリで起きたこと | 閉じ方(委託文の境界) |
|---|---|---|---|---|
| 1 | メインのチェックアウト | worktree を割り当てても、エージェントがメインのディレクトリで git checkout を打てる | ワーカーがメインのチェックアウトのブランチを切り替えた(2026-09-06、別リポジトリ)。同じ作業ディレクトリで別セッションがブランチを切り替え、commit が意図しないブランチに着地した(2026-04-14、AGENTS.md に記録) | 「メインのチェックアウトのブランチを切り替えない」。完了報告に作業ディレクトリの絶対パス |
| 2 | refs/・stash・config | git の仕様で共有(§1) | 事故の記録は無い。stash の共有は git の仕様から導いた(2026-10-14、作業用クローンで git stash list が 0 件) | 素の git stash を禁止。ブランチ作成直後に git branch --show-current を確認 |
| 3 | ディスク | 全 worktree が同じボリュームに載る | レビュアー 2 本の検証用クローンが約 1.4GB を使い、稼働中の 3 ワーカーが ENOSPC で停止(2026-09-10) | 「追加のクローン・pnpm install を作らない。作ったら終了時に消す」 |
| 4 | 台帳の採番 | どの worktree も同じ origin/main の最大 ID を読む | 3 本が独立に同じ L-0059 を取り、3 本とも CI を通った(2026-09-10) | 起動前に ID を 1 本ずつ予約して委託文に書く。予約した順をマージ順にする |
| 5 | 一時領域(scratchpad) | セッションの一時ディレクトリを複数ワーカーが使う | 別記事の古い節が残った一時ファイルを読み込み、本文 169 行を上書き(台帳 L-0046)。汎用名の PR 本文が別ワーカーの内容に置き換わった | ファイル名にワーカー固有の識別子を付ける |
| 6 | ローカルの重いテスト実行 | 同じマシンの CPU とログの置き場所 | 2 本が同じログ名に書き、片方が別セッションの進捗を自分のものと読んで「ストール」と誤報(2026-09-15、約 1 時間の空費) | ログ名にワーカー識別子。フルランはオーケストレーターが直列で回す |
| 7 | 認証の状態(gh auth) | マシン単位のアクティブアカウント | push の直前にアクティブアカウントが別のものに戻り、push が失敗した(AGENTS.md に記録) | gh auth switch -u <user> && gh ... を 1 コマンドで連鎖 |
#3〜#6 は 2026-09 のウェーブで観測し、筆者の作業メモと失敗台帳(spec/article_failure_ledger.md)に記録したものです。#1 は同じ型の事故が別リポジトリで起きた記録です。
このリポジトリの現在値
122597ad の worktree で 2026-10-14 に測った値です。
git worktree list --porcelain | grep -c '^worktree '
# => 4
du -sh .claude/worktrees/<この worktree>
# => 357M(node_modules なし)
df -h .
# => 460Gi 中 377Gi 使用、空き 47Gi(89%)
依存を入れない checkout だけで 1 本 357MB です。依存を入れた worktree やクローンを数本足すと、数 GB 単位で増えます。
この記事の画像を作るときにも、表の #3 に当たりました。割り当てられた worktree には node_modules が無く、Remotion で画像を描くには依存が要りました。メインのチェックアウトの node_modules への symlink は権限で拒否されたので、pnpm install --frozen-lockfile --offline で worktree に依存を入れました(262 パッケージ、4.3 秒)。pnpm はグローバルのストアから取り出すので、ここでもストアという worktree の外の資源を共有しています。
3. なぜ worktree だけでは閉じないのか
worktree が守るのは「同じファイルを 2 つのエージェントが同時に編集しない」ことです。表の 7 行は、どれもこの条件の外で起きました。
- #1・#2 は、git の操作が worktree の外の状態(メインの作業ツリー、共有の refs)に届いた
- #3・#6 は、ファイルではなく容量と計算資源を取り合った
- #4 は、ファイルを編集する前の読み取り(最大 ID)が全員同じ値を返した
- #5・#7 は、worktree の外のディレクトリや、マシン単位の状態を使った
#4 はとくに見えにくい事故です。3 本ともそれぞれのブランチでは正しく、CI も通りました。衝突は合流したときに初めて見えます。詳細は 『最大IDの次』は並行ブランチで必ず衝突する に書きました。
4. 委託文に書く境界の書式
worktree の外にある資源ごとに、境界を 1 行ずつ書きます。このリポジトリで現在使っている書式は次のとおりです。
## 境界
- 作業場所: 割り当てた worktree の中だけ。メインのチェックアウトのブランチを切り替えない
- 最初に `git branch --show-current` と `pwd` を確認し、完了報告に絶対パスを書く
- git: 素の `git stash` を使わない。ブランチは `origin/main` から切る
- ディスク: 追加のクローン・依存のインストールをしない。作ったら終了時に消し、消せなければパスを報告する
- 採番: 台帳 ID は <予約した ID> を使う。最大 ID の次を取らない
- 一時ファイル: ファイル名に <ワーカー識別子> を付ける
- 重いテスト: 実行しない(オーケストレーターが直列で回す)
- 認証: `gh auth switch -u <user> && gh ...` で 1 コマンドに連鎖する
ポイントは、worktree を割り当てたことを境界の代わりにしないことです。worktree は 1 行目(作業場所)を支えるだけで、残りの行は委託文に書かない限り、エージェントには伝わりません。
この記事自体も、この書式で委託されて書かれています。台帳 ID は L-0114 を事前に予約しました。
5. 自分の環境に持ち帰るときの確認
表の 7 行を、自分の並列実行に当てはめて確認します。
- エージェントがメインのチェックアウトで git を打てる経路はあるか(Claude Code の検査は
cpやリダイレクトを見ない) - stash を使う手順書やスクリプトがあるか
- worktree 1 本あたりの容量と、同時に作る最大本数を掛けて、空きに収まるか
- 連番を採る資源(台帳・マイグレーション・ADR)を、エージェントが自分で採番していないか
- 一時ディレクトリのファイル名が、ワーカー間で衝突しないか
- ローカルで重いテストやビルドを、複数のエージェントが同時に回していないか
- 認証やアクティブアカウントのような、マシン単位の状態に依存する操作があるか
まとめ
git worktreeが分けるのは作業ツリーとHEAD・indexで、refs/・stash・config は共有されます- 並列エージェントの事故は、ファイルの編集ではなく、worktree の外にある 7 つの資源で起きました
- 閉じ方は資源ごとに委託文の境界を 1 行書くことで、worktree の割り当てはそのうち 1 行を支えるだけです
FAQ
git worktree で分ければ、並列エージェントは互いに干渉しませんか
作業ツリーと HEAD・index は分かれますが、git のドキュメントによれば refs/ 以下の ref と config は既定で共有されます。stash も refs/stash に入るので共有です。ディスク・一時ディレクトリ・採番する ID・ローカルで動かすテストも worktree の外にあります。
Claude Code の worktree 隔離は、メインのチェックアウトへの書き込みをすべて止めますか
止めません。Claude Code のドキュメントは、検査が編集先のパス・コマンドの作業ディレクトリ・コマンドの文字列を読むだけで、cp やシェルのリダイレクトでメインのチェックアウトに書くコマンドは拒否されないと書いています。
台帳やマイグレーションの連番は、worktree ごとに最大値の次を取れば衝突しませんか
衝突します。どの worktree も同じ main を基準に最大値を読むので、並列に起動すると同じ番号を取ります。このリポジトリでは 3 本が同じ ID を取った例があり、以後は起動前に 1 本ずつ ID を予約して委託文に書いています。
並列エージェントで一時ファイルを共有ディレクトリに置くと何が起きますか
汎用のファイル名だと上書きし合います。このリポジトリでは、別記事の古い節が残った一時ファイルを読み込んで本文 169 行を上書きした例(台帳 L-0046)と、別のワーカーの PR 本文に置き換わっていた例がありました。
worktree を増やすとディスクはどれくらい使いますか
依存を入れない checkout だけで、このリポジトリでは 1 本 357MB でした(2026-10-14 計測)。検証用のクローンを作ったレビュアー 2 本で約 1.4GB を使い、ディスクが尽きて 3 本のワーカーが止まった例があります。
References
確認日はすべて 2026-10-14 です。
