Skip to content
源码分析手册

会话重绕与检查点:对物理文件与对话记忆的协同回撤

在复杂的代码编辑任务中,Claude 可能会进入错误的推理路径或产生不符合预期的修改。为了提供一种“后悔药”机制,Claude Code 实现了细粒度的会话重绕(Rewind)与状态检查点(Checkpointing)协议。

核心概念

Rewind 本质上是 对会话转录本(Transcript)与物理文件系统的原子式非破坏性回溯

这不是简单地删除最后几条对话消息。在 Claude Code 中,由于模型的操作会产生副作用(如修改文件、执行 Bash),Rewind 必须是一套协同机制:它既要回撤模型的“记忆”(消息序列),也要能够精准撤销对物理环境的影响,并重新对齐文件的历史版本。

代码里的真实逻辑

这一机制主要由 claude-code-opensource/src/utils/fileHistory.tsclaude-code-opensource/src/utils/conversationRecovery.ts 支撑,其核心执行逻辑包括:

  1. 文件强制检查点(File Checkpointing): 这是 Rewind 能够成立的物理基础。在任何涉及文件变更的工具(如 EditWrite)执行前,系统会强制触发 fileHistoryTrackEdit。它会将目标文件的当前内容备份到本地 ~/.claude/file-history/ 目录中。每个备份都通过 messageId 与对话节点进行强绑定。

  2. 状态镜像(FileHistorySnapshot): 当一轮工具调用完成,系统会生成一个 FileHistorySnapshot。这个快照记录了此时此刻工作区内所有被跟踪文件的“备份版本号”。这意味着每一个对话轮次都对应着一个完整的文件系统镜像(Image)。

  3. 回滚指令处理(The /rewind Command): 当用户输入 /rewind 时,执行链如下:

    • 交互式选择:通过 MessageSelector 组件渲染一个交互式时间轴。
    • Transcript 裁剪:物理截断本地 Transcript 文件,移除目标节点之后的所有历史。
    • 文件系统还原:系统检索目标消息 ID 对应的 FileHistorySnapshot,将所有受控文件物理地还原到该快照记录的备份版本。
  4. 分叉与新分支(Context Forking): 重绕后的第一次输入会开启一条全新的执行分支。系统会重新生成 messageIdsnapshotSequence,确保旧的备份不会被新操作盲目覆盖,保留了在不同分支间切换的可能性。

实战注意事项

  • 副作用的局部性:Rewind 只能撤销“受控文件”的内容。它无法撤销已经执行的 Bash 命令产生的不可逆影响(如 rm -rf、向远端 API 发送的请求、或修改了非工作区内的系统配置)。
  • 备份容量上限:系统默认仅保留最近 100 个 FileHistorySnapshot。超过此范围的旧状态会被自动清理,导致无法重绕到极早期的节点。
  • Git 协同风险:如果你在 Rewind 期间手动在外部编辑器中修改了文件,可能会导致备份内容与物理内容产生版本冲突。
  • SDK 模式的差异:在 SDK 模式下,文件系统重绕默认是关闭的,除非显式设置了 CLAUDE_CODE_ENABLE_SDK_FILE_CHECKPOINTING 环境开关。

推荐阅读路径

源码锚点

  • claude-code-opensource/src/utils/fileHistory.tsFileHistorySnapshot 结构定义与强制备份逻辑(fileHistoryTrackEdit)。
📄 src/utils/fileHistory.ts — `FileHistorySnapshot` 结构定义与强制备份逻辑(`fileHistoryTrackEdit`)。L39-43 of 1116
typescript
export type FileHistorySnapshot = {
  messageId: UUID // The associated message ID for this snapshot
  trackedFileBackups: Record<string, FileHistoryBackup> // Map of file paths to backup versions
  timestamp: Date
}
  • claude-code-opensource/src/utils/conversationRecovery.ts — 会话恢复的顶层封装与回滚逻辑。
📄 src/utils/conversationRecovery.ts — 会话恢复的顶层封装与回滚逻辑。L24-26 of 598
typescript
  type FileHistorySnapshot,
} from './fileHistory.js'
import { logError } from './log.js'
  • claude-code-opensource/src/components/MessageSelector.tsx — 用于可视化选择回滚点的 UI 组件。
📄 src/components/MessageSelector.tsx — 用于可视化选择回滚点的 UI 组件。L19-21 of 831
tsx
function isTextBlock(block: ContentBlockParam): block is TextBlockParam {
  return block.type === 'text';
}

基于 Claude Code v2.1.88 开源快照的深度分析