Windowsでgit worktreeを削除できないとき、ロック元プロセスを1コマンドで調べる

Claude CodeやCodexなどをworktree分離で使っていると、不要になったworktreeをgit worktree removeで削除しようとしても、「使用中のため削除できません」というエラーで失敗することがあります。これはworktreeを使うツール一般に起こりうる問題で、特定のツールだけの事情ではありません。

目次

手作業だと何が面倒か

このエラーの原因を調べようとすると、通常は複数の確認が必要になります。

  • git worktree listで一覧を確認
  • git statusで未コミットの変更がないか確認
  • pathが実際に存在するか確認
  • handle.exeやProcess Explorerでロック元プロセスを探す
  • PIDをタスクマネージャーで照合
  • 必要なら個別ファイルを確認

ChatGPTに聴く場合でも、これらの情報を先に人間が集めてから質問する必要があります。

作ったもの

worktree-lock-diagnosticというPowerShellスクリプトを作りました。GitHubで公開しています。

https://github.com/iwadjp/worktree-lock-diagnostic

PowerShell 1コマンドで、以下をまとめて確認できます。

  • worktreeの登録状態とbranch
  • git status
  • file-handle lockの有無
  • ロックしているPIDとプロセス名
  • 取得できる範囲でのロックされているresource

ロック検出方法

Windows標準のRestart Manager APIを使っています。Windows Installerやエクスプローラーが「このファイルは使用中です」と表示するときに使っているものと同じ仕組みです。handle.exeなどの外部ツール依存はありません。AI/LLMも使用していません。すべてGitとWindows APIの呼び出しによる確定的な判定です。

実際のdogfood

以下のパターンを実際に使って確認しました(実際のprivate repo名・worktree名は記載していません)。

  • 正常なworktree(lockなしを正しく表示)
  • 意図的にfile handleを保持したworktree(PID・プロセス名を検出)
  • 存在しないpath(明確にnot found)
  • gitでないディレクトリ
  • 相対 path指定

prototypeで見つかったバグ

実際に手元でdogfoodしなければ見つからなかったバグが3件ありました。

1つ目は、ディレクトリパスをRestart Managerへ登録対象に混在させたためAPIがエラーを返していたのに、その戻り値を確認していなかったため、実際はロックされているのに「検出なし」と誤判定していた false negativeです。

2つ目は、Get-Help -Fullが全く動作していなかった問題です。#requiresの位置がコメントベースヘルプの解析を壊していました。

3つ目は、gitでないディレクトリを対象にすると、gitコマンドのstderr出力と$ErrorActionPreference=’Stop’が衝突し、未処理の例外でスクリプトが異常終了していました。

いずれも、実際に手元のdogfoodをしなければ見つからなかった問題です。特に1つ目は、「正常なworktreeだけで試していたら、本当に検出なしなのか、静かに検出に失敗しているのか区別できない」というタイプのバグで、テストの重要性を改めて実感しました。

使い方

GitHubのREADMEに応じて、以下のように実行します。

.\diagnose-worktree-lock.ps1 "..\my-feature-worktree"

Limitations

  • ディレクトリを単にcurrent working directoryとして保持しているshell等のロックは、Restart Managerでは検出できない場合があります
  • すべてのgit worktree remove失敗原因を診断できるわけではありません
  • 一度にスキャンするファイル数にはMaxFilesToScan(既定500)の上限があります
  • Restart Managerの結果は「ファイルとの関連」を示すものであり、原因であることの厳密な証明ではありません

Safety / Privacy

完全にローカルで動作し、読み取り専用です。プロセスのkill、git worktree removeの実行、git pruneの実行、ネットワークへの送信はいずれも行いません。

GitHub

ソースコードはこちらで公開しています。

https://github.com/iwadjp/worktree-lock-diagnostic