submodule を含む worktree は、後始末の remove に --force が要る

  • #Git
  • #worktree
  • #submodule
  • #自動化
submodule を含む worktree は、後始末の remove に --force が要る

今回やったこと

複数エージェントが同じリポジトリで作業すると、作業開始時の git worktree add だけでなく、終了時の worktree 撤去までが自動化の一部になる。submodule を含む構成では、通常の git worktree removeworking trees containing submodules cannot be moved or removed で止まることが分かった。手順書に書いた終了コマンドが、submodule を含む実際のリポジトリ構成では動かない状態だった。

この記事の実装ステータスは実装済み。公開記事の作業ルートと共通手順を git worktree remove --force へ訂正し、無人の掃除スクリプトには未コミットを巻き込まない別経路を残した。目的は変更を強制的に捨てることではなく、作業をコミット・push・PR・マージまで終えた後に、確実に作業領域を畳むことである。

submodule が終了処理を止める

このリポジトリには外部リポジトリを参照する submodule がある。worktree を作ると、その作業領域にも submodule が展開される。通常の remove は、内部で作業ツリーを移動または削除する途中に submodule を検出して停止する。結果として、変更を失ったわけではないのに、作業ディレクトリと Git の worktree 登録だけが残る。

実測では、同じ理由で7個の worktree が残った。掃除処理が警告だけを出して次へ進む設計だと、毎日同じ失敗を繰り返し、残骸が増えていく。worktree の数だけを見ていると「作業中のもの」と「終了したのに畳めていないもの」を区別できない。

git -C /path/to/repository worktree remove --force /path/to/worktree
git -C /path/to/repository branch -d feature/example

--force は submodule のブロックを越えるために必要である。同時に未コミットの変更も捨て得るため、コマンドを打つ順序が重要になる。先に git status --short を確認し、コミット、push、PR の作成とマージを済ませてから実行する。作業中の worktree に対して自動掃除から無条件に force を掛けてはいけない。

手動の終了と無人掃除を分ける

共通の作業手順書では、終了した自分の worktree を明示的に --force 付きで撤去する。これは、作業完了を人間が確認できる経路である。一方、scripts/git_cleanup.sh は他セッションの残骸を刈るための無人処理なので、既定では24時間以内に触られた worktree を残す。マージ済みか、未コミット変更がないか、現在の worktree ではないかを確認してから候補にする。

無人掃除側は、通常の remove が submodule で失敗した場合に、submodule の deinit、ディレクトリ撤去、git worktree prune へ進む実装を持つ。ここで force を常用しないのは、掃除スクリプトが未コミット変更を巻き添えにしないためである。手動の完了処理と、他セッションを保護する保守処理では、同じ削除コマンドを共有しないほうが安全である。

テストできる終了条件にする

回帰テスト scripts/test_git_cleanup.sh は、submodule 付きの worktree を用意し、通常の remove が失敗してフォールバックが発火すること、--apply 後に作業ディレクトリが残らないことを確認する。単に「スクリプトが終了した」だけでなく、失敗理由を検出し、実際に残骸が消えたことまで見る。

worktree 運用の安全性は、作業開始時の分離、変更のレビュー、終了時の撤去という3点で成立する。最後の撤去を省くと、古いブランチや残骸が別の自動化から見えるようになり、どの作業コピーが正しいか分からなくなる。submodule は特殊ケースではなく、使っているリポジトリの構成そのものとして終了手順へ組み込むべき対象だった。

試した環境・バージョンは、Git worktree、submodule を含む一時テストリポジトリ、Bash の掃除スクリプトである。外部サービスへ依存せず、remove の失敗、フォールバック、最終的な worktree 登録の整理をローカルで確認できる。

更新履歴

  • 2026-09-14: 初稿。submodule を含む worktree の撤去手順と無人掃除の責務分離を記録。

訂正履歴

  • なし。