Claude Media
Claude Code checkpointの制限 — Bash変更・サブエージェント編集は復元されない

Claude Code checkpointの制限 — Bash変更・サブエージェント編集は復元されない

Claude CodeのcheckpointはBashコマンドの変更、バックグラウンドのサブエージェント編集、リンクされたファイルなどを戻せません。対象外の5つのケースと、復元そのものが失敗する条件、対処法をまとめます。

/rewind でコードを巻き戻したのに、ファイルの中身が変わっていない。Claude Codeのcheckpoint機能を使っているとこの状況に遭遇することがあります。原因は不具合ではなく、checkpointが追跡していない変更が最初から存在するためです。

Claude Codeのcheckpointは、ユーザープロンプトで手番が始まるたびに、その時点のコードの状態を自動で保存点として記録します。/rewind で戻せるのは、Claudeがファイル編集ツールで直接加えた変更だけです。次の5つは対象外になります。

対象外

checkpointが追跡しない5つの変更

  • Bashコマンド

    rm mv cp など、シェル経由のファイル操作です。

  • バックグラウンドのサブエージェント

    既定の動作で走るforkスキルや、バックグラウンドの /code-review --fix が該当します。

  • リンクされたパス

    シンボリックリンクとハードリンクは、復元時にスキップされます。

  • セッション外の変更

    エディタでの手動編集や、並行する別セッションの編集です。

  • 手番の途中で送ったメッセージ

    実行中の手番に合流したメッセージには、保存点が作られません。

/rewind コマンド自体の使い方はBash・サブエージェント・シンボリックリンクの3制限を扱っています。本記事はそこに加えて、セッション外の変更、手番の途中で送ったメッセージ、復元そのものが失敗する条件、そしてGitとの役割分担まで踏み込みます。

Bashコマンドで変更したファイルはなぜ戻らないのか

Claude Codeがcheckpointとして記録するのは、編集ツール(Edit・Write等)による変更だけです。Bashツール経由で実行されたファイル操作は追跡されません。

rm file.txt
mv old.txt new.txt
cp source.txt dest.txt

Claudeにこうしたコマンドを実行させると、rm で消えたファイルも mv でリネームされたファイルも、checkpointの記録には残りません。これらの変更は /rewind で取り消せません。

ビルドスクリプトのクリーンアップ、パッケージマネージャーの初期化、一括リネームスクリプトなど、Bash経由でまとめて片付けさせる場面ほど、この抜け穴に当たりやすくなります。

編集ツールとBashツールは同じセッション内で併用されるのが普通です。その結果、同じ手番の中で一部のファイルだけが復元され、残りは戻らない非対称な状態が生まれます。

サブエージェントの編集が復元されないのはどんなときか

Sub-agentsもClaudeと同じファイル編集ツールで書き換えますが、その編集は通常、メインセッションのcheckpointに入りません。復元されるかどうかは、そのサブエージェントがどこで走ったかで決まります。

くらべる

forkスキルの実行場所で復元可否が分かれる

戻せる

フォアグラウンドで実行

context: fork に background: false を加えたスキルです。メインセッションの手番の中で作業ツリーを直接編集するため、/rewind で通常どおり戻せます。

戻せない

バックグラウンドで実行

forkスキルの既定の動作です。ほかのサブエージェントや、バックグラウンドで実行した /code-review --fix も同じです。編集がcheckpointの外側で適用されるため、取り消しにはgitを使います。

background: false はスキルのfrontmatterに書く項目で、Claude Code v2.1.218以降で使えます。v2.1.218より前は、forkスキルは常に手番を止めて終了を待っていました。

指定しなくても待つ場面があります。非対話モード(-p フラグやAgent SDK)、CLAUDE_CODE_DISABLE_BACKGROUND_TASKS を 1 にした環境、同じスキルの前の呼び出しがまだ走っている間、スケジュールタスクの起動などです。

/code-review --fix の実行経路は別の記事で使い分けを扱っています。/rewind で戻したい修正は、フォアグラウンドで走らせる経路を選びます。

シンボリックリンク・ハードリンクのファイルが巻き戻せない理由

/rewind メニューで「Restore code」か「Restore code and conversation」を選ぶと、checkpointが記録していたパスへ順に書き戻していきます。ただしそのパスがシンボリックリンクやハードリンクになっている場合、Claude Codeは書き戻しをスキップします。

スキップされる条件は3つです。

条件内容
リンクである内容対象パスがシンボリックリンク・ハードリンク・その他の非通常ファイルになっている(checkpoint記録後に変化した場合を含む)
ディレクトリが変化した内容checkpoint記録後に、そのファイルを含むディレクトリ構造が変わった
バックアップが読めない内容復元元のスナップショットを安全に読み取れない

スキップされたファイルは現在の中身のまま残り、Restored the code, but skipped N files という警告が出ます。警告に出るのは件数だけで、パスは載りません。切り分けは次の順で進めます。

手順

スキップされたファイルの切り分け

  1. 1

    デバッグログを有効にして復元する

    /debug でデバッグログをオンにしてから /rewind を実行します。~/.claude/debug/<session-id>.txt に、スキップされたパスが1件ずつ記録されます。

  2. 2

    リンクを直接洗い出す

    macOSやLinuxなら、プロジェクト直下で次の2つを実行します。

    find . -type l
    find . -type f -links +1
  3. 3

    リンクの出どころで対処を決める

    自分で作ったリンクなら、/rewind は中身に触れていません。そのセッションの変更を取り消したいときは、Claudeに逆の編集を頼むか、自分で直します。心当たりのないリンクは、中身を確認してから信用します。

find の出力の読み方には注意点があります。一時ディレクトリに real.txt と other.txt を置き、real.txt へのシンボリックリンク sym.txt とハードリンク hard.txt を作って試すと、出力は次のとおりでした。

$ find . -type l
./sym.txt
$ find . -type f -links +1
./hard.txt
./real.txt

ハードリンクは実体を共有する別名なので、リンク元の real.txt も同じ一覧に入ります。リンクされていない other.txt は、どちらにも出ません。2つ目のコマンドの結果から「自分が作ったリンクの片割れ」を除いて読む必要があります。

dotfileマネージャーがプロジェクトへシンボリックリンクした設定ファイルや、pnpmがハードリンクで配置したファイルは典型例です。

v2.1.216より前のバージョンでは、/rewind はリンク先まで書き戻していた上に、この部分復元自体を報告していませんでした。バージョンを跨いで運用しているチームでは、古い挙動を前提にした手順書が残っていないか一度見直す価値があります。

セッションの外からの変更はどう扱われるか

checkpointが追跡するのは、現在のセッション内で編集されたファイルだけです。Claude Codeの外で自分が手動編集したファイルや、別の並行セッションが加えた変更は、たまたま同じファイルを現在のセッションも編集していない限り記録されません。

複数のセッションを並行して走らせていると、この境界を意識しないまま「戻したはずなのに変更が残っている」状況に当たりやすくなります。別セッションが同じファイルを編集していた場合、/rewind が戻せるのは自分のセッションが把握している状態までです。

Worktreeで作業ツリーを分けている構成では、この境界がとくに効きます。各Worktreeはディレクトリが別です。checkpointが追跡するのは現在のセッションで編集したファイルだけなので、別のWorktreeで進めている変更は対象に入りません。

裏を返せば、ひとつのWorktree内でエディタから直接手を入れた変更は、そのセッションのcheckpointに乗らないまま残り続けます。「Claudeにまとめてやり直させたい」場面では、手動編集を挟まずセッション内で完結させたほうが、/rewind の結果を予測しやすくなります。並行編集を避けたいファイルがあるなら、Worktreeで分けるか、片方のセッションが終わってからもう片方を動かす順番にします。

手番の途中で送ったメッセージには保存点がない

実行中のClaudeに追加の指示を送ると、そのメッセージは新しい手番を始めず、動いている手番に合流することがあります。この場合、メッセージは会話に表示されますが、checkpointは作られず、/rewind のメニューにも並びません。

合流したメッセージや、それより後にClaudeが加えた編集を取り消すには、その手番を始めたプロンプトまで巻き戻します。メッセージが届く前にClaudeが済ませた作業も、同時に巻き戻ります。

手番を新しく始める形で送られた指示には、通常どおり保存点が作られます。細かく区切って戻りたい作業では、実行中に指示を足すより、手番が終わってから次のプロンプトとして送る運用が選べます。

復元そのものが失敗する条件と保持期間

対象外の変更とは別に、追跡されているはずの変更が戻らないこともあります。保存点の数と寿命には上限があります。

数字

checkpointの保持に関わる数字

  • 保持する保存点

    直近100件

    古い保存点を捨てると、ほかの保存点が参照しないスナップショットも消えます(各ファイルの最初のスナップショットを除く)

  • スナップショットの寿命

    約30日

    セッションが最後に保存してからの目安です。cleanupPeriodDaysで変更できます

  • 警告で報告

    v2.1.216以降

    リンクでスキップされた件数を表示します

  • 失敗を報告

    v2.1.260以降

    バックアップ欠落などで1件も復元できないとき、エラーを表示します

スナップショットはセッションごとに保存されます

セッションは保存点ごと保存されるため、/resume で再開しても /rewind は使えます。ただし、スナップショットが保持期間を過ぎて消えたセッションでは、保存点の一覧は残っていても、そこへ戻そうとすると No files were restored で失敗することがあります。

エラーの全文は No files were restored: N files failed (backup missing, or the file could not be updated) です。原因は2通りあり、保存時のバックアップが無い場合と、Claude Codeがファイルを書き込めない・削除できない場合です。

セッションをforkすると、元のバックアップがforkへコピーされます。ディスクが満杯などでコピーに失敗すると、forkの側でそのバックアップが欠け、同じエラーになることがあります。

v2.1.260より前は、バックアップの無いファイルを黙ってスキップし、復元が成功したように見えていました。古いバージョンで「戻ったはず」と判断した履歴があれば、その時点でファイルが戻っていたかを疑う余地があります。

対処は原因で分かれます。バックアップが消えている場合は /rewind を繰り返しても同じ結果になるので、Claudeに編集を取り消させるか、バージョン管理から戻します。書き込めない場合は、ファイルの権限など妨げを直してから再実行します。

長く残したい作業では cleanupPeriodDays を大きくしておけば、以降のセッションのバックアップが長持ちします。

同じClaude Codeプロセスで /clear を実行していた場合は、/rewind のメニューの先頭に /resume <session-id> (previous session) という項目が加わります。会話を消したあとでも、Claude Codeを終了するか別のセッションを再開するまでは、この項目から前のセッションへ戻れます。

戻す前に、その地点が復元対象かを知る方法

/rewind のメニューは、選んだプロンプト地点に追跡済みのファイル変更があるかどうかで、選択肢が変わります。変更が追跡されていない地点では「Restore code」「Restore code and conversation」が表示されません。残るのは「Restore conversation」と要約系の選択肢だけです。

この表示は判断材料になります。コード復元の選択肢が出ない手番は、編集ツールによる変更が記録されていません。その手番でファイルが変わっていたなら、Bashなどcheckpointの外側で変わったと見て、gitを確認します。

要約系の選択肢は「Summarize from here」と「Summarize up to here」です。会話を圧縮するだけでディスク上のファイルは変えないので、コードを戻す手段にはなりません。

checkpointとGitはどう役割分担するか

checkpointは「この手番の前まで一気に戻したい」という短期の試行錯誤に向いています。コミット単位の恒久的な履歴管理は担えません。

checkpointの外で起きた変更は、gitでしか戻せません。作業前にこまめにコミットしておく習慣が、checkpointの死角を埋める最も確実な方法になります。

変更の種類ごとの経路は2つの軸で判断できます。編集ツールかBashか、フォアグラウンドかバックグラウンドか、です。リンク先のファイルだけは例外で、中身をClaudeに指示して直すか手動で編集します。

Editツールがスマート引用符を意図せず書き換える既知の問題も、コミット前のgit diffで気づける典型例です。checkpointをワークフロー全体にどう組み込むかは、計画・実行・レビューの流れとあわせて決めると位置付けが掴みやすくなります。

checkpointの保存件数・保持期間そのものや、/rewind コマンドの操作手順は/rewind コマンドの解説記事にもまとめています。

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