你在 src/billing.ts 改了两小时——debug 日志、做一半的重构、一段写着推理的 TODO 注释——都没提交。让 Claude Code 跑了个”小修”。Diff 把整个文件替换了——你的改动从 working tree 里消失,且你没 commit。
比你感觉的更经常可恢复。编辑器留 local history、git 留 reflog、即便文件被完全覆盖,编辑器 buffer / swap 文件 / 备份 snapshot 里常还有一份。下面是接下来 10 分钟的抢救路径 + 四层「以后不再发生」的设置。
常见原因
按命中率从高到低:
1. 跑 agent 时 working tree 是脏的
Agent Read 捕了你脏的状态。后续 Write 用它版本的”改动”替换整个文件——你的未提交改动没进 diff 因为 agent 没保留它们。
如何判断:看 agent 的 Write tool 调用——整文件替换(不是 patch)时未提交改动就被静默覆盖了。
2. 多 agent 同时动同一个文件
两个 Claude Code session 或 Claude + Cursor 同改一个文件——后写者赢,先写者的改动消失。
如何判断:git log src/billing.ts 看不出异常,但文件内容只匹配一个 agent 的 intent——另一个 agent 的活儿没了。
3. Agent 用了整文件 write 而非 Edit/patch
大改动有时 agent 用整文件重写。你在文件里加的 inline debug log 在 Claude 重写时没被任务认作要保留的——就没了。
如何判断:diff 整个文件改了(每行都动)而不是局部 hunk——这就是整文件重写。
4. 你以为保存了其实没保存
改动在未保存的 buffer 里。关编辑器或重启就丢了 buffer——磁盘上是 agent 保存的版本。
如何判断:你不记得 agent 跑之前按过 Cmd+S——磁盘上没改动但编辑器 recovery 里可能还有。
5. Agent commit 了一个 checkpoint,包含了它的覆盖
Claude 被 prompt 让 commit。它的 commit 捕了覆盖之后的状态——你的改动没进 git,但编辑器 local history 还可能有。
如何判断:git log -1 --stat 显示近期 agent commit,你的改动不在任何 commit 里——编辑器 history 是最后希望。
6. Stash 应用错了或在错分支 pop 了
你 stash 了改动,切分支跑 agent,stash 在错分支 pop 了——或者根本没 pop。
如何判断:git stash list 有你没意识到还在的 stash,或你的分支没你记得 stash 过的改动。
最短修复路径
按紧迫度。核完 local history 之前不要关编辑器。
Step 1:停 → 别关编辑器
多数恢复路径要求编辑器还在跑。关了或重启某些 buffer-based 恢复就丢了。
- 不要关 VS Code / Cursor / Sublime / 你的编辑器
- 不要跑 `git stash` 或其他改状态的 git 命令
- 不要再跑 agent "撤销一下"
锁住当前状态,先盘点能救什么。
Step 2:查编辑器 local history
现代编辑器都保留独立于 git 的文件历史:
VS Code / Cursor / Windsurf:
Explorer 里文件右键 → Open Timeline
或 View → Timeline
里面有「Saved 15 min ago」之类条目——点进去 diff / restore。
JetBrains(IntelliJ、WebStorm):
文件右键 → Local History → Show History
Sublime Text:装「Local History」插件,否则没内置。
这一步能救 80% 的「agent 覆盖了我的改动」。其他都之前先试这个。
Step 3:用 Cmd+Z 检查未保存 buffer
文件还在编辑器里、没重启的话,buffer 的 undo 历史可能保留改动:
1. 在编辑器里打开受影响文件
2. 点击文件(聚焦 buffer)
3. 反复按 Cmd+Z(或 Ctrl+Z)——看 diff 向你的改动回退
4. 改动恢复到你想要的状态就停
5. 立刻保存(Cmd+S)
Cmd+Z 跳过你的改动或 undo 历史被清——退回 local history。
Step 4:查 git reflog 和 stash
即便没正式 commit,有时存在 checkpoint:
# 找丢的 commit(包括 Claude Code 自动 commit)
git reflog --all | head -30
# 找 stash
git stash list
# 编辑器 swap / 备份文件(vim、emacs)
ls -la .*.sw[opq] 2>/dev/null
find . -name "*.orig" -o -name "*~" 2>/dev/null
reflog 里有你的改动就恢复:
git checkout <hash> -- src/billing.ts
Step 5:真丢了就重写 + 写「跑 agent 前 commit」规则
所有恢复路径都试了还没回来——重写。然后立规矩:
# 跑 agent 前仪式
git status # 确认 working tree
git add -A && git commit -m "wip" # 打 checkpoint
# 跑 agent
一个之后可以 squash 的 wip commit 比两小时丢工作便宜。
Step 6:多 agent / 并行工作用 git worktree
经常一边跑 agent 一边手动改:
# 给 agent 工作建 worktree
git worktree add ../project-agent main
# 之后:`project/` 手改,`project-agent/` 跑 agent
# 各自 working tree,互不覆盖
agent 完事后按你的节奏 merge 它的分支回主 worktree。
预防建议
- 「跑 agent 前 commit」是硬规矩——working tree 脏不要跑
- 探索性 wip 不想 commit 就
git stash,之后git stash list复核 - 并行 agent + 手编辑用 git worktree——working tree 分开就不会撞
- agent prompt 里列出不要动的文件:「不要改 src/billing.ts,有未提交活儿」
- 编辑器开自动保存(1 秒 debounce),未保存 buffer 状态尽量少
- CLAUDE.md 要求局部改动用 Edit-style patch,不用整文件 Write
相关阅读
- Claude Code 改错文件
- Claude Code 重构 scope 太大
- Agent 回滚不彻底
- Claude Code 新手入门
- Claude Code 工作流
- Claude Code 项目配置
标签: #排查 #Claude Code #排查 #覆盖