Claude Media
Claude Codeのworktreeが再利用されるバグ — 前回セッションを誤って引き継ぐ

Claude Codeのworktreeが再利用されるバグ — 前回セッションを誤って引き継ぐ

新規セッションのはずが前回のworktreeディレクトリを引き継ぎ、別ブランチや未追跡ファイルまで混入するClaude Code Desktopの既知issue(#79366)を、reflogとレジストリの証拠から検証します。

Claude Code Desktopでworktree(ワークツリー)を有効にして新しいセッションを始めても、まっさらなディレクトリが与えられるとは限りません。GitHub issue #79366には、以前のセッションが使っていたディレクトリがそのまま新しいセッションに割り当てられ、別ブランチの履歴や未追跡ファイルまで引き継がれてしまうという報告が、2026年7月20日以降macOSとWindowsの両方から寄せられています。原因として指摘されているのは、アプリ側が持つworktreeの貸し出しプール(WorktreePool)が、セッションをアーカイブしてもディレクトリを削除せず、次のセッションへ回している設計です。

Claude Code Desktopで何が起きているか

最初の報告者は、worktree隔離を有効にした新規セッションが、無関係な過去タスクのために作られた既存のworktreeディレクトリの中に置かれたと説明しています。新しいブランチ自体は作られますが、チェックアウト先は古いディレクトリのままです。該当worktreeのreflogを見ると、直前まで別タスクのブランチをチェックアウトしていた履歴がそのまま残り、その上に新しいブランチへの切り替えが積まれています。

報告者が挙げる影響は3点です。ディレクトリ名がブランチやタスクの内容と一致しなくなること、前タスクの未追跡ファイルや.gitignore対象ファイルが新しいタスクのコンテキストやPRに紛れ込みうること、そしてこの現象が同じリポジトリで繰り返し起きていることです。同じ投稿では、サブエージェント(Agent tool)がworktreeではなくメインの作業コピーへ書き込んでしまう別の症状も「関連するかもしれない観察」として添えられており、後述のとおり別の参加者からも裏付けが寄せられています。

reflogとgit-worktrees.jsonが示す再利用の痕跡

参加者のxg-gh-25は、worktreeディレクトリ名がリポジトリ名など決定論的な規則で決まっているなら衝突は避けられず、セッションID込みの命名であればクリーンアップ処理側の不具合だと整理しました。対して@xni06は、実際に再現手順を組んで引き金を特定しています。

  1. worktree有効の新規セッションがフォルダXとブランチclaude/Xを得る(名前が一致している状態が「新規」の見た目)
  2. そのブランチにコミットしてからセッションをアーカイブする
  3. 別のworktree有効セッションを作ると、新しいブランチclaude/Yが発行されるが、チェックアウト先は古いフォルダXのままになる

git worktree listを見ながらアーカイブすると、対象フォルダの表示が[claude/<branch>]から(detached HEAD)に変わるだけでディスクからは消えません。この「detached状態で残ったフォルダ」がプールの正体だと@xni06は説明しています。新規worktreeかどうかを見分けるための簡易チェックとして、次のような確認コマンド群も共有されました。

basename "$(git rev-parse --show-toplevel)"        # フォルダ名
git branch --show-current                          # ブランチ名
stat -f "%SB" "$(git rev-parse --git-dir)/gitdir"  # フォルダの生成時刻
git status --porcelain                             # 引き継いだ未追跡ファイル

フォルダ名とブランチ名が一致し、生成時刻がセッション開始直後で、状態がクリーンなら新規worktreeです。どれか1つでも外れていれば再利用された疑いがあります。@kieranbentonはさらに、デスクトップアプリがmacOSでは~/Library/Application Support/Claude/git-worktrees.jsonにworktreeの貸し出し状況を記録していることを突き止めました。エントリにはleasedBy(貸し出し先セッションID)とbranchが入っており、フォルダ名が示す元タスクとは無関係な値になっているケースが確認されています。設定リファレンスとworktreeドキュメントを確認しても、このプール機構を無効化するworktree.*名前空間の設定は見当たらなかったと報告されています。

WorktreePoolの内部設計を読み解く

@keighleymcfは、配布されているデスクトップアプリのapp.asarとローカルログを解析し、症状の背後にある仕組みを次のように説明しています。あくまで非公式のリバースエンジニアリングという前提付きです。

  • リポジトリ単位でworktreeのプールを持ち、セッション終了時にプールへ返却するWorktreePoolという機構がある
  • ログには[WorktreePool] Reused worktree <dir> for session <id> (was leased by none)という再利用の記録が残る
  • app.asar内ではworktreePoolEnabledの既定値がfalseと読めるにもかかわらず実際には動作しており、既存インストールに対して機能ゲート経由で有効化された可能性を示唆している
  • 掃除(プルーニング)はディレクトリの経過時間ではなく保持数の上限で行われる

隠しプリファレンスとして観測された値は次のとおりです。

設定キー既定値内容
ccMaxWarmWorktrees既定値3内容リポジトリごとに保持する最新worktreeの数。超えた分は年数に関わらず回収対象になる
ccWorktreeReapAfterHours既定値24内容maxWarmが0のときに使われるアイドル判定のしきい値

この保持数キャップの副作用として、leasedByが入ったままのworktreeでもセッションが動いていなければ回収されうる、削除された場合はセッションが通知なくメインの作業コピーへフォールバックする、という2つの追加症状も報告されています。いずれも「報告済みだが未対応」として複数の関連issue番号(#43730、#62431、#46444など)が添えられていますが、本文まで取得していないため詳細はここでは扱いません。

実運用で起きている具体的な被害

@sun-13は自分のリポジトリのworktree listを見せながら、1つのディレクトリが3つの異なるセッション・3つの異なるブランチを渡り歩いた例を報告しています。もう一つの深刻な副作用は、アーカイブの安全チェックそのものを無効化してしまう点です。プレビュー用に作られる.claude/launch.jsonのような未追跡ファイルは、本来ならworktreeと一緒に消えるはずのものです。ところが再利用によってディレクトリが生き続けると、このファイルが残り続けて「dirty」の判定を出し続け、安全チェックが働かなくなります。

デスクトップアプリの公式な説明では、タスクが終わったセッションをアーカイブするとworktreeごと片付けられるとされています。今回の報告が示しているのは、実際にはアーカイブがleasedByをクリアするだけでgit worktree removeまでは実行されず、片付いたように見えて実はプールに戻っているだけ、という乖離です。

Windows側でも@stefanguhaが同型の挙動を報告しています。レジストリファイル(Windowsでは%APPDATA%\Claude\git-worktrees.json)を確認したところ、45件のエントリのうち25件が貸し出し中、16件がleasedBy: nullのままプールに残っていました。あるディレクトリのreflogは4日間で5つの無関係なセッション・ブランチを渡り歩いており、ディレクトリ名は最初のセッションのトピックのまま固定されていました。ディレクトリ名がタスクの中身に一致しないままフォルダ名だけが独り歩きする点は、セッションがgitブランチではなく作業ディレクトリに紐づくという仕様と組み合わさることで見分けをさらに難しくしています。この命名の食い違いは機密性の懸念にもつながるとして、別issue(#86239)として切り出されたと本スレッド内で説明されています。

@kcarriedoが同じスレッドで指摘しているとおり、サブエージェントがworktreeでなくメインの作業コピーへ書き込んでしまう症状も引き続き報告されており、最初の投稿にあった「関連するかもしれない観察」を裏付けています。@Kagamiは「セッションを非アクティブでアーカイブしない」「PRマージ・クローズ後の自動アーカイブを無効」の両方をオフにしても再利用が起きたと報告し、原因候補として「セッション状態を自動分類する」設定を疑っていますが、この仮説を検証した続報はスレッド内には見当たりません。

利用経路別に見る影響の有無

worktreeを使う経路は複数ありますが、この不具合の報告が集中しているのはデスクトップアプリの並列セッションです。

利用経路報告の有無備考
デスクトップアプリ(macOS)報告の有無報告あり(多数)備考症状の中心。git-worktrees.jsonのプールが直接の原因とされる
デスクトップアプリ(Windows)報告の有無報告あり備考レジストリの保存場所が異なるだけで同型の挙動
CLIの--worktreeフラグ報告の有無スレッド内に報告なし備考プールの仕組みはアプリ層にあるとされ、CLI単体での再現報告は見当たらない
サブエージェント隔離(isolation: worktree)報告の有無直接の再利用報告なし備考ただし同じ投稿者から、書き込み先がメインの作業コピーに解決される別症状が報告されている

自分でworktreeを作り再利用を避ける

@xni06が示した回避策は、アプリのworktree機能そのものを使わないことです。セッション開始時にworktreeのチェックボックスを外し、自分で明示的にworktreeを作ってからEnterWorktreeツールでそこへ固定します。

git fetch origin main --quiet
git worktree add ~/dev/worktrees/<repo>/<TICKET> -b <branch> origin/main

自分で作ったディレクトリはアプリのレジストリに登録されないため、プールに戻される対象にもなりません。ディレクトリ名は自分で選んだ名前のまま変わらず、ブランチ名も最初から意図したものになります。引き換えに、後片付けはgit worktree removeとブランチ削除を自分で行う必要があり、セッション一覧の表示はworktreeでなくリポジトリルート側になります。

一つだけ注意が必要な癖があります。EnterWorktreeで固定したセッションで/clearを実行すると、作業ディレクトリはセッションの起動時ディレクトリへ静かに戻り、固定していたはずのworktreeへの紐付けが外れます。クリア後にファイルを書き込む前には、EnterWorktreeで再度そのworktreeへ入り直す必要があります。worktreeの起点の選び方や依存関係の扱いなど、日常的な運用手順はClaude Code Worktree実践ガイドにまとめています。worktreeに関する設定はworktree.baseRefworktree.bgIsolationのように公開されたキーがある一方、今回のプールを無効化する設定は公開されていません。

まとめ

Claude Code Desktopのworktreeが前回セッションのディレクトリを引き継ぐ現象は、アプリ内部のWorktreePoolがアーカイブ時にgit worktree removeを実行せず、貸し出し状態だけを解除していることが原因だとコミュニティの調査で説明されています。macOS・Windowsの両方、複数のClaude Codeバージョンにまたがって報告があり、ディレクトリ名とブランチ・タスクの不一致、未追跡ファイルの引き継ぎ、アーカイブの安全チェック無効化という3種類の実害が確認されています。公式な設定での無効化手段が無い間の対応として、worktreeを自分で作ってEnterWorktreeで固定する運用がスレッド内で共有されています。

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