コーディングエージェントのWorktree管理:クリーンアップの手間をなくす方法

エージェントは git worktree を高速に作成するが、そのどれも後片付けしない。ここでは、4コマンドのクリーンアップ手順、各ステップでの失敗モード、そしてタスクボードがスクリプトに勝る場面を紹介する。

Aiden Flux

Aiden Flux

4 11月 2026

コーディングエージェントのWorktree管理:クリーンアップの手間をなくす方法

ワークツリーの作成は簡単で、忘れるのも簡単だ。エージェントがブランチを分離して作業できるようにワークツリーを立ち上げ、エージェントが作業を終え、あなたが差分をレビューする。そしてそのディレクトリはそのまま放置される。1週間後には git worktree list の出力は画面に収まりきらず、リポジトリで du -sh を実行すれば12ギガバイトと表示され、そのうち3つのディレクトリは数日前にマージされて削除されたブランチを指している。誰も残そうと決めたわけではない。作成はコマンド一発、後片付けは面倒な作業だったために、ただ溜まっていったのだ。

これは並列エージェント作業について誰も警告してくれない部分だ。分離の仕組みそのものは十分に文書化されている。AIコーディングエージェント向けのgitワークツリーのガイドでは、作成とブランチの仕組みを詳しく扱っている。痛みが潜んでいるのは「完了」した後のライフサイクルであり、ワークツリーを作るのが、1分で5つも開けてしまい片付ける本能など持ち合わせないエージェントともなれば、事態は急速に悪化する。本記事が扱うのはその後半部分、つまりクリーンアップの規律、具体的なコマンド、各ステップで待ち受ける失敗パターン、そして自作スクリプトでは対応しきれなくなるポイントだ。

Sharklyは「誰が片付けるのか」という問題への1つの答えだ。すべてのタスクを専用のワークツリーで実行し、そのワークツリーを、覚えておかなければならないディレクトリではなくタスクのライフサイクルの一部として扱う。そこには後ほど触れる。まずは仕組みから見ていこう。手作業をやめると決める前に、手動でのやり方を理解しておくべきだからだ。

TL;DR

gitワークツリーとは、1つのリポジトリに紐づく2つ目の作業ディレクトリで、独自のブランチ、インデックス、HEAD を持つ。エージェントは各実行で分離を求めるのに、どれも自分で後片付けをしないため、ワークツリーはどんどん溜まっていく。クリーンアップの流れは4つのコマンドで構成される。存在を確認する git worktree list、完了したものを削除する git worktree remove、古いメタデータを消す git worktree prune、残したいものを保護する git worktree lock だ。それぞれに失敗パターンがあり、ステップを飛ばすと、孤立したディレクトリ、失われた作業、ロックされたブランチといった事態を招く。手動でのやり方はワークツリーが数個なら機能する。それを超えるなら、各ワークツリーをタスクレコードに紐づけて、クリーンアップに責任者を持たせよう。Sharklyはこれを自動で行う。

エージェントを使うとワークツリーがたまりやすい理由

ワークツリーには、人が自然に管理できるライフサイクルがある。作成し、作業し、マージし、削除する。この削除のステップは、人が覚えていることに依存している。エージェントはこの前提を同時に2方向から壊す。

1つは量だ。4つのエージェントを並列で走らせる開発者は、1日に1つではなく1時間に4つのワークツリーを作っている。複数のClaude Codeエージェントを並列で実行するという記事では、なぜその数がこれほど急速に増えるのかを解説している。2つ目は、片付ける本能がないことだ。エージェントはタスクを読み、作業を行い、結果を書き出して停止する。「ブランチがマージされたから、このディレクトリはもう無駄だ」とは考えない。こうしてディレクトリは本来の役目を終えても残り続け、その生き残りが問題になる。削除済みブランチの古いチェックアウト、エージェントが放棄した中途半端な実験、そしてどれも同じくディスクを食いつぶす重複した node_modules ツリーだ。

コストは抽象的な話ではない。各ワークツリーは完全なチェックアウトに加え、エージェントがそこにインストールしたものすべてを抱えている。中規模のJavaScriptリポジトリでワークツリーが10個あれば、node_modules ディレクトリも10個ある。ディスクは圧迫され、集合全体で git status は遅くなり、次に git worktree list を実行する人は、どのディレクトリが現役の作業でどれが残骸なのか判別できなくなる。

クリーンアップの手順を1つずつ

ライフサイクル全体は4つのコマンドに集約される。この順番で実行すれば、失敗パターンは封じ込められる。

存在を確認する。クリーンアップは必ずここから始める:

git worktree list
# /repo              a1b2c3d [main]
# /repo-auth-refactor 4d5e6f7 [auth-refactor]
# /repo-fix-logging   8g9h0i1 [fix-logging]

これを飛ばした場合の失敗パターンは、間違ったディレクトリを削除してしまうことだ。似た名前のブランチを使う2つのエージェントは、似た名前のワークツリーパスを生成する。現役の方を削除すれば、未コミットの作業を失う。何か手を付ける前にリストを読むこと。

完了したものを削除する。ワークツリーのブランチがマージされ、中に未コミットのものがないことを確認したら:

git worktree remove /repo-fix-logging

失敗パターン:ワークツリーに未コミットの変更や未追跡のファイルがあると remove は拒否する。これは安全なデフォルトだ。危険なのは、エラーを消し去ろうと --force に手を伸ばすことだ。ダーティなワークツリーへのforceは、エージェントが生み出したがコミットしなかった実際の作業を削除する。remove が文句を言うなら、まずディレクトリを確認しよう。その警告はたいてい正しい。

古いメタデータを削除する。ワークツリーのディレクトリが git worktree remove ではなく rm -rf で削除された場合、gitはまだその管理記録を保持している。これが典型的な孤立エントリだ:

git worktree prune
git worktree prune --dry-run   # preview first

失敗パターン:pruneを飛ばすと、git worktree list にゴーストエントリが残り、さらに悪いことに、どこかでまだチェックアウトされているとgitが考えているブランチを再利用できなくなることがある。prune はその記録を消去する。何が削除されるかを確認するため、先に --dry-run を実行しよう。git worktreeのドキュメントには、pruneが何を古いとみなすかが正確に記されている。

残したいものをロックする。低速な外付けドライブ上のワークツリーや、長時間実行される実験を保持するワークツリーは、積極的なクリーンアップスクリプトにpruneされるべきではない:

git worktree lock /repo-experiment --reason "release repro, keep until 2.0 ships"

失敗パターン:ロックがなければ、「古い」ものをすべてpruneする夜間のクリーンアップジョブが、あなたが意図的に残したワークツリーを削除してしまう可能性がある。ロックと理由文字列の有無が、信頼できるクリーンアップスクリプトと、大事なものを食った末に無効化するスクリプトの違いだ。

クリーンアップスクリプトが通用しなくなるポイント

4つのステップすべてを自動化することはできる。ワークツリーを一覧し、各ブランチをマージ済み履歴と照合し、マージ済みのものを削除するcronジョブは、シェル30行ほどで書ける。それは機能し、少数のエージェントを走らせる個人開発者ならそれで十分だ。ワークツリーの数が少なく、リポジトリの責任者が1人ならスクリプトを使えばいい。

それが通用しなくなるのは、処理能力ではなく判断の部分だ。スクリプトはブランチがマージされたかどうかは判断できる。だが、あるワークツリーが、まだレビューしていないエージェントの未コミット作業を保持していることや、「古い」ブランチが実は誰かが再開しようとしている中断中のタスクであることは判断できない。クリーンアップがワークツリーの意図を知る必要がある瞬間、gitの状態しか見ないルールは、いずれ大事なものを削除してしまう。もう1つの天井は調整だ。共有マシンでは、ある人のクリーンアップスクリプトは別の人のエージェントが何をしているか知らない。「これは削除しても安全か」は、git worktree list だけでは答えられなくなる。この共有マシンの問題については、並列AIコーディングエージェントを管理するツールのまとめを参照してほしい。

タスクボードが加えるもの

解決策は、すべてのワークツリーにシェルセッションより長生きする所有者を与えることだ。各ワークツリーをタスクレコードに紐づければ、クリーンアップは「どのディレクトリが古く見えるか」ではなく「どのタスクが完了しレビュー済みか」になる。

これがSharklyが位置するレイヤーだ。あなたにはすでにコーディングエージェントがいる。Sharklyは各実行をタスクにすることで、それらをチームに変える。タスクが開始すると、接続されたコンピュータ上のローカルサービスがそのタスク用の分離されたワークツリーを用意する。タスクの結果がレビューのために戻り、人がそれを承認すると、ワークツリーのライフサイクルは誰も覚えていないディレクトリとして残るのではなく、タスクとともに終わる。ワークツリーが決して匿名ではなかったからこそ、クリーンアップの問いに答えが出るのだ。

役割分担は誠実なままだ。エージェントはタスクを引き受け、分離されたワークツリーで作業し、テストを実行し、差分を返す。人は方向性を定め、マージとリリースのステップを決める。SharklyはClaude Code、Codex、あるいは上記のgitコマンドの代替ではない。共有の記録を加えることで、分離、進捗、結果、クリーンアップを、端末のあちこちに散らばせるのではなく、リクエストからリリースまで可視化し続ける。エージェントを1つ走らせていて、手作業のクリーンアップに10秒しかかからないなら、まだこれは必要ない。ワークツリーのリストが画面に収まらなくなったとき、管理の問題こそが本当の問題であり、エージェント実行をまたいで人間をループに保つことについての記事が、そのレビュー側を扱っている。

今日から実行できるチェックリスト

エージェントが作業してきたリポジトリで、このパスを実行しよう:

  • git worktree list を実行し、何かを削除する前に最後まで読む。
  • 完了した各ワークツリーについて:ブランチがマージされたことを確認し、ディレクトリがクリーンであることを確認してから git worktree remove(ダーティなツリーに --force は決して使わない)。
  • git worktree prune --dry-run を実行して確認し、それから git worktree prune で孤立したメタデータを消去する。
  • 意図的に残すワークツリーは理由文字列を付けて git worktree lock する。
  • ディスクを確認:ワークツリー全体で du -sh を実行し、死んだツリーから重複した依存関係のインストールを削除する。
  • これを1日に何度もやっているなら、クリーンアップのスクリプト化をやめ、各ワークツリーにタスクの所有者を与えよう。

4つのコマンドをそのまま手で実行し続けてもいいし、既存のコーディングエージェントをSharkly経由で実行することで、ワークツリーが属するタスクとともに作成・追跡・廃止されるようにしてもいい。

関連記事

Gemini Omni 1.2 Flash API:動画生成をAIエージェントが実行可能なタスクにする

Gemini Omni 1.2 Flash API:動画生成をAIエージェントが実行可能なタスクにする

Gemini Omni 1.2 Flash APIを追跡可能なエージェント作業として実行する:API呼び出しの構成、ブリーフ、参照アセット、マルチターン編集、そしてクリップ公開前の人間によるレビュー。

6 11月 2026

ChatGPT Images 2.6でブランドマスコットをアニメーション化する方法

ChatGPT Images 2.6でブランドマスコットをアニメーション化する方法

ChatGPT Images 2.6でブランドマスコットをアニメーション化:検証済みのスプライトシート用プロンプト、滑らかなループを実現するフレームの位置合わせ、チームレビューのワークフロー

6 11月 2026

安価なモデルほど高くつく理由:AIエージェントのコストは採用された変更単位で評価せよ

安価なモデルほど高くつく理由:AIエージェントのコストは採用された変更単位で評価せよ

100万トークンあたり0.10ドルのGPT-6 Lunaは、1回の試行コストを引き下げ、リリースされる変更1件あたりの試行回数、アウトプット、意思決定数を増やします。エージェントの実行には、トークン単位ではなく、採用された変更単位で価格を設定すべきです。

6 11月 2026