Claude Media
Claude Desktopのgit maintenanceで、Sublime Mergeに存在しない差分が出る

Claude Desktopのgit maintenanceで、Sublime Mergeに存在しない差分が出る

Claude Desktopのworktreeがあるリポジトリでloose-*パックができ、Sublime Mergeに存在しない差分が出る報告の内容と、確認コマンド、直し方、再発防止の設定をまとめます。

Claude Desktopでworktreeを使っているリポジトリを、Sublime Mergeで開いたときだけ変な表示が出る。git statusもgit fsckも正常なのに、Sublime Mergeには身に覚えのない「staged」ファイルが並ぶ。そんな症状がGitHubのissue(anthropics/claude-code#99346)で報告されています。

先に断っておくと、このissueはopenのままで、コメントはありません。原因の特定は報告者の推定を含み、修正もまだ出ていません。この記事では、報告された内容、Git側の仕組み、手元で確かめる手順、止め方を順に説明します。

報告されている症状と環境

報告者の環境は次のとおりです。

  • Windows 11、Claude desktopアプリのCodeタブ(.claude/worktrees/配下のworktreeを使うセッション)
  • Git for Windows 2.43.0
  • Sublime Merge build 2091(同梱のgitは2.39.1)
  • Claude Code 2.1.286

症状はSublime Mergeにだけ出ます。git fsckとgit statusはきれいで、gitそのものは壊れていません。Sublime Mergeでは、HEADにあるはずのツリーが欠けて見え、ステージされていないはずのファイルが「staged」として並びます。差分の欄には<diff disabled - couldn't load diff object …>と出ます。

発生は散発的です。ローカルの緩いオブジェクトが一定数を超えたときだけ起きるため、報告者は最初、自分のコミットやpushがリポジトリを壊していると疑ったそうです。

何が起きているのか

報告者は、グローバルのtrace2イベントログを3日間(10月1日から3日、gitプロセス5,636件)有効にして調べています。そこで見つかった事実は次のとおりです。

  • 約30分おきに、.claude/worktrees/があるリポジトリを順に巡って、次の形のコマンドが走る
  • 3日間で15回。対象は.claude/worktrees/を持つ3リポジトリだけで、ほかの13リポジトリには届いていない
  • 同じオプション群(core.hooksPathのNULデバイス指定、safe.directory=*など)を持つgitプロセスは3,816件で、うち2,444件が.claude/worktrees/<worktree>の中で動いている
git.exe -c core.hooksPath=\\.\NUL -c safe.directory=* -c core.fsmonitor=false \
        -c branch.autoSetupMerge=false -c gc.auto=0 -c maintenance.auto=false ... \
        maintenance run --auto --task=loose-objects --task=incremental-repack

報告者のほうでは、maintenance.*の設定もgit maintenance startも、gitのスケジュールタスクも入れていません。Sublime Mergeの同梱gitがメンテナンスを走らせた形跡もない、とのことです。

2つのタスクが何をするか

ログのコマンドにはloose-objectsとincremental-repackの2タスクが指定されています。順に見ます。

loose-objectsタスクが作るもの

Git本体のドキュメントによると、loose-objectsタスクは緩いオブジェクトをパックファイルにまとめます。手順は二段階です。すでにパックにあるオブジェクトの緩いコピーを消し、続いて「loose-」で始まる名前の新しいパックを作ります。

--auto付きで走らせたとき、このタスクが動く条件はmaintenance.loose-objects.autoの値で決まります。既定値は100で、緩いオブジェクトがその数以上あれば実行されます。0なら--autoでは走りません。

報告では、この結果として.git/objects/pack/loose-<ハッシュ>.packと、対応する.idx、.revが作られています。2026年9月28日(UTC)に2つのリポジトリでloose-パックが1つずつできたことが、ログで確認されています。

incremental-repackタスクが動かすもの

incremental-repackは、multi-pack-index(複数のパックをまとめて引く索引)を使ってパックを統合するタスクです。まずgit multi-pack-index expireで索引から参照されなくなったパックを消し、次にgit multi-pack-index repackで小さなパックをいくつか選び、より大きな1つに詰め直します。

--auto付きの発火条件はmaintenance.incremental-repack.autoで、索引に入っていないパックが指定数以上あると動きます。既定値は10で、0なら--autoでは走りません。再発防止の2行目は、この条件を0にして止めるものです。

Sublime Mergeは、このloose-パックに入ったオブジェクトを読まないようだ、というのが報告者の見立てです。パックの中のツリーがHEADから欠けて見えるため、実在しないstagedファイルが出ます。

どこまでが確かな話か

項目状態
loose-objectsタスクがloose-*パックを作る状態Gitのドキュメントに記載あり
既定のしきい値が100状態Gitのドキュメントに記載あり
Sublime Mergeがloose-パックを読めない状態報告者の観察(Sublime Merge build 2091)
メンテナンスを実行しているのがClaude Desktopである状態推定

最後の項目について、報告者自身が注記を書いています。Windowsのtrace2はプロセスの親子関係を記録しないため、呼び出し元の特定は「オプションの組み合わせの特徴」と「Claudeのworktreeがあるリポジトリにだけ現れること」からの推論です。

また、報告者は「1週間以上前はこうなっていなかった」と書き、worktreeの掃除まわりの変更が関係しているのではと推測しています。これも根拠のある特定ではなく、最後に動いていたバージョンは不明です。

したがって、同じ症状でも原因が同じとは限りません。表の最上段の動きは、手元のリポジトリで確かめられます。

自分のリポジトリで確かめる

loose-パックがあるか

worktreeの中から実行しても、パックは共通の.gitにあります。まず共通のgitディレクトリを引きます。

cd "$(git rev-parse --git-common-dir)/objects/pack"
ls -l loose-* 2>/dev/null

loose-<ハッシュ>.packが見つかれば、loose-objectsタスクが一度は動いています。作成時刻も出るので、Claude Desktopを使った時間帯と突き合わせられます。

緩いオブジェクトの数

しきい値に届きそうかは、次で見ます。

git count-objects -v

count:が緩いオブジェクトの数です。既定のしきい値は100なので、これを超えていれば次のメンテナンスで対象になります。

設定を誰が入れたか

自分で入れた覚えのないメンテナンス設定がないかも見ます。

git config --show-origin --get-regexp '^maintenance\.'

何も出なければ、メンテナンス関連の設定はどこにもありません。報告者の環境もこの状態でした。

メンテナンスが実際に走っているか

報告者はtrace2のイベントログを有効にして、maintenance run --autoが呼ばれる様子を捉えました。環境変数GIT_TRACE2_EVENTにログファイルの絶対パスを入れると、gitがJSON形式のイベントを追記します。報告者が使ったのはグローバル設定のtrace2.eventTargetで、こちらは設定すれば全リポジトリのgitプロセスを拾えます。

export GIT_TRACE2_EVENT="$HOME/git-trace2-event.json"
# 数日使ったあとで、メンテナンス起動の記録を探す
grep '"maintenance"' "$HOME/git-trace2-event.json" | grep -- '--auto'

環境変数はそのシェルで起動したgitにしか効かないため、Claude Desktopのようなアプリが呼ぶgitまで見るには、trace2.eventTargetを使う必要があります。ログにはすべてのgit実行が残って大きくなるので、確認が済んだら設定を外してください。起動元のプロセスはWindowsのtrace2では記録されない点は、前述のとおりです。

壊れて見えるリポジトリを直す

報告者が示している直し方は、パックを一度まとめ直すものです。

git -c pack.writeReverseIndex=false repack -a -d

repack -a -dで既存のパックを1つに束ね、不要になったパックを削除します。pack.writeReverseIndex=falseは、.revファイルを作らない指定です。issueでは、loose-パックに.revが付いていた点も併記されています。

報告者の記述はこの指定を付けた形までで、.revの有無がSublime Mergeの読み取りにどう効くのかは書かれていません。git statusが正常であることと、Sublime Mergeの表示が戻るかどうかは別なので、実行後にSublime Mergeで開き直して確かめてください。

再発を防ぐ設定

issueで案内されている予防策は、グローバルのgit設定に2行を足すものです。

git config --global maintenance.loose-objects.auto 0
git config --global maintenance.incremental-repack.auto 0

効く理由はコマンドラインの設定との関係にあります。上のログのコマンドは、gc.auto=0とmaintenance.auto=falseを-cで渡しています。ところがmaintenance run --auto --task=...のようにタスクを直接指定すると、この二つでは止まりません。

Gitのドキュメントでは、タスク別の.autoの値が0なら、そのタスクは--autoで走らないとされています。報告者が書いているとおり、アプリが上書きしているのはgc.autoとmaintenance.autoで、このタスク別の値は上書きされていません。

注意点が二つあります。

  • --globalは、そのユーザーのすべてのリポジトリに効きます。特定のリポジトリだけに留めたいときは、そのリポジトリで--globalを外して実行します
  • 緩いオブジェクトの整理とパックの統合が止まるので、オブジェクトが溜まってリポジトリが肥大することがあります。必要なら、自分でgit gcを走らせます

これはissueの回避策を言い換えたもので、Claude Desktop側の公式な設定項目ではありません。アプリ側で止める手段は、このissueでは示されていません。

似た症状との見分け方

worktreeまわりでは、「いつの間にかgitの状態が変わる」ように見える症状が別の原因でも起きます。

.claude/worktrees/にディレクトリが溜まっているだけなら、パックは関係なく、agent viewのworktree掃除の話です。worktree内からmainへのgit操作が拒否されるなら、それはメンテナンスではなく権限側の挙動で、worktreeはmainへの読み取り専用gitも拒否するで説明しています。Desktopがセッションごとにgitを分ける仕組み自体を知りたいときは、Claude Code Desktopの並列セッションが出発点です。

この記事の症状との見分け方は単純です。git statusやgit fsckが正常で、特定の外部Gitクライアントだけが欠けたオブジェクトを訴えるなら、このissueの症状に近いと考えられます。.git/objects/pack/にloose-*のパックがあるかが、最初の手がかりです。

issueに書かれていないこと

issueには、次の点が書かれていません。

  • どのバージョンのDesktopアプリから起きるようになったか。報告者は「分からない」としています
  • Sublime Merge以外のクライアントへの影響
  • macOSやLinuxで同じ頻度で起きるか。報告はWindowsだけです
  • アプリ側でメンテナンスを止める設定の有無

状況が動いたときは、issueのステータスとコメントを見るのが確実です。Sublime Mergeを使わない場合でも、loose-*パックの存在自体はgitの正常な動作なので、症状がなければ対処は要りません。

この記事を共有:XはてブLinkedIn