手滑把改动回滚了、暂存区清空了、文件没保存就关了……别急着重写。这篇文章帮你理清 VS Code 的恢复机制,并给出一套按成功率排序的抢救流程。

一、先分清:你丢的到底是哪一种”改动”

代码”消失”有好几种完全不同的场景,恢复手段天差地别。动手前先对号入座:

最容易被误解的一点:取消暂存(unstage)根本没有删掉你的代码,它只是把文件从暂存区移回工作区。看到文件跑到”未暂存”区别慌,git add 回去就行。

真正需要抢救的是后两种——尤其是”没保存”的情况。

二、核心机制:VS Code 的 Timeline / Local History 是什么

代码觉得不合适,一不小心点了全部清掉!怎么找回?

VS Code 有一套独立于 Git 的文件快照系统,叫 Local History(本地历史),展示在编辑器左侧资源管理器底部的 TIMELINE 面板里(1.66 版本起自带,默认开启)。

它的原理其实非常朴素:

  1. 触发时机 = 文件保存。 你每按一次保存(Ctrl/Cmd + S),VS Code 就判断内容是否和上一份快照不同,不同就存一份新副本。从没保存过的改动,不会产生任何历史记录。
  2. 存的是完整副本,不是差异。 和 Git 用 SHA + 增量对象不同,Local History 走”整份复制”路线:每个快照就是那一刻文件的完整拷贝。好处是恢复极其可靠,直接拷回去就行,不依赖任何链式历史。
  3. 回滚动作本身也会被记录。 当你执行”回滚/放弃更改”,VS Code 会把这个动作也当成一次文件变更记下来。于是 Timeline 里会新增一个”回滚后的状态”点,而回滚前的那个状态点仍然保留——这就是你能反悔的根本原因。
  4. 完全不依赖 Git。 不需要 add、不需要 commit,甚至不需要仓库。只要文件保存过,就有历史。

快照的物理存放位置(了解即可,一般不用手动翻):

# macOS
~/Library/Application Support/Code/User/History/<文件夹hash>/
# Windows
%APPDATA%\Code\User\History\<文件夹hash>\
# Linux
~/.config/Code/User/History/<文件夹hash>/

每个目录里是一堆随机名文件 + 一个 entries.json,记录着每个快照的时间戳和原始路径。由于是整份复制,会占磁盘,所以它有保留上限(默认按数量/天数自动清理旧记录)。

三、实战恢复:用 Timeline 找回被回滚的改动

  1. 在资源管理器中打开那个出事的文件。
  2. 展开左下角的 TIMELINE 面板。
  3. 面板里按时间倒序列出所有记录点,找到回滚发生之前的那个时间点。
  4. 单击它可以打开 diff 对比,确认就是你要的版本。
  5. 右键该记录点 → Restore Contents(恢复内容),文件即刻还原。

四、最棘手的情况:根本没按保存

这是成功率的分水岭,取决于那份内容是”已存在的文件”还是”新建的 Untitled 文件”。

情况 A:改的是已存在的文件,只是没保存

坦白说,Timeline 救不了——没保存就没有新快照,Timeline 里最新的点还是你上次保存时的样子。但仍有几根救命稻草,按成功率排序:

  1. 立刻按撤销 Ctrl/Cmd + Z(最有效)。 只要那个文件标签页还开着、编辑器没关,VS Code 的内存级撤销栈就还在,狂按撤销能把回滚动作退回去。前提:别关标签页、别关 VS Code。
  2. 翻热退出(Hot Exit)缓存。 如果标签页关了但整个 VS Code 没关过,未保存的 buffer 可能还在备份目录里:里面按窗口 hash 分文件夹,可能藏着未保存的内容。
  3. 以上都没有 → 基本无解,只能重写。

情况 B:从没保存过的新建文件(Untitled)

反而更有救。VS Code 对 Untitled-1 这类文件有专门的备份保护:只要你没手动点”不保存”把它关掉,重启 VS Code 后通常会自动恢复;备份同样在上面的 Backups/ 目录里。

五、黄金原则:出事后第一时间该做什么

抢救是有时效性的,尤其是”没保存”的场景——每多一次操作,成功率就流失一分。记住这套优先级:

  1. 标签页还开着? 什么都别做,立刻先狂按 Cmd/Ctrl + Z。这是成功率最高的一招。
  2. 别关标签页、别关 VS Code。 撤销栈和内存 buffer 都靠进程活着。
  3. 保存过的改动 → 用 Timeline / Local History 恢复。
  4. 提交过的改动(哪怕后来 reset)→ 用 git reflog 找回。
  5. 都不行再考虑重写。

六、防患于未然:让自己以后不再慌

  • 勤保存(或开启自动保存 Files: Auto Save),让 Local History 有足够多的记录点。
  • 勤 commit,哪怕是本地提交,Git 的安全网远比本地历史牢固。
  • 确认 Timeline / Local History 已开启:设置里搜 workbench.localHistory.enabled,确保为 true
  • 别用 git reset --hard 当”撤销”,它会连工作区一起清空,是最容易造成不可逆丢失的命令。

结语

一句话总结整套机制:VS Code 的 Local History 就是个”每次保存自动另存为一份带时间戳的备份”的傻瓜但可靠的机制,靠磁盘空间换后悔药。它救得了”保存后被回滚”,但救不了”从没保存”。所以真正的护身符还是两个老生常谈的习惯——勤保存、勤提交