博客资源误删恢复日志

我误删了原博客的内容和资源,手里只剩下两样东西:一个还能打开的旧项目备份,以及原博客最后一次成功生成出来的静态站目录 Blog-main。前者还能提供一部分可编辑源码,后者则保存着“博客最后一次对外发布时到底长什么样”的全部事实。恢复工作就是围绕这两份材料展开的。

我昨天在为博客修改样式时不小心把博客资源文件夹删除了,不过我做的有备份,上次的备份之后我修改过博客样式,也发布了一篇新文章,用上次的备份会导致我丢失一小部分内容,倒是问题不大。我突然灵机一动,这不刚好能是一个测试一下gpt-5.4的能力的场景吗?于是我打开Codex,把最后一次发布的源代码(也就是Hexo生成的内容)以及上次的备份给Codex读取,告诉它:事情是这样的,我不小心误删了原博客的所有内容与资源,但是我有上次的备份(也就是当前项目),以及原博客最后一次生成的内容 Blog-main 根据原博客最后一次生成的内容帮助我恢复原博客。

然后它就咔咔咔开始分析,我就在一旁观看它的分析,它刚开始发现的丢失内容就是我丢失的全部了,也就只有一篇文章和搜索框的样式,不过它做了全面的比对(有相当大的一部分为无用功),后面重复生成和比对,刚好把我 5h限额用完。如果我告诉它我丢失的部分,只让它对比校对这部分就可以节省掉一半的Token支出,这说明了一件事情:高效的人机协作,是人负责“收窄解空间”与选择,AI负责“遍历解空间”。


下面是GPT写的恢复报告:

1. 先确定恢复原则

我先给这次恢复定了一个很重要的原则:

  • Blog-main 作为最后发布版的真相来源,优先级最高
  • 当前项目作为可维护源码的恢复基础
  • 先恢复“站点能回到原样”,再恢复“源码能继续维护”

这样做的好处是,整个过程不会陷入“我觉得原来应该是这样”的猜测里。凡是页面表现、资源引用、文章内容、标签页图标这些能从 Blog-main 直接确认的内容,都以它为准。

2. 先盘点缺了什么

恢复不是一上来就改文件,而是先比对。

我先对照了当前项目和 Blog-main,把差异分成了三类:

  • 文章源码缺失:有的文章已经出现在 Blog-main/posts/*.html 里,但 source/_posts 中没有对应 Markdown
  • 静态资源缺失:例如浏览器标签页用到的 favicon 资源已经丢了
  • 配置与生成差异:即使源码还在,重新生成出来的 public/ 也不一定和最后发布版完全一致

这个阶段最关键的收获是:博客并不是“全没了”,而是“源码缺了一部分,生成产物还保留着最后的现场”。只要最后的现场还在,就能反推回来。

3. 先把缺失文章和资源补回源码

接下来做的是最直接的恢复工作。

文章恢复

我从 Blog-main/posts/47194.html 中把缺失文章的正文、标题、分类、标签和 abbrlink 反推出去,重新写回 source/_posts/AI工具使用心得.md。这样恢复出来的不是单纯的 HTML 页面,而是一篇以后还能继续编辑的 Markdown 源文。

资源恢复

原来的 favicon 资源也已经丢失了。我从 Blog-main/images/favicon-zyh.svg 把它补回到 source/images/favicon-zyh.svg,并把相关引用统一改成这个文件名,避免继续和主题目录里的同名资源发生覆盖冲突。

这一步完成后,博客至少重新拥有了:

  • 缺失文章的可编辑源文件
  • 原站实际使用过的图标资源
  • 后续能继续维护的基本项目结构

4. 修配置,让重新生成的站点尽量贴近原站

源码补回去并不代表恢复结束,因为 Hexo 重新生成时还会受到配置、时区、更新时间、主题行为的影响。

这次最麻烦的地方其实就在这里。

我先后修了几类问题:

时区与时间字段

部分文章和页面虽然内容没错,但重新生成后 article:published_timearticle:modified_time 和原站不一致。后来排查发现,问题并不只是日期字符串本身,而是:

  • 站点时区会影响最终输出的 UTC 时间
  • 有些页面依赖 mtime
  • 有些文章需要精确到毫秒级的 date/updated

所以我把相关文章和页面的时间字段逐个校正,连毫秒都尽量对齐。

主题资源与样式

我统一了 favicon 的输出方式,关闭了会干扰浏览器缓存判断的默认 PNG favicon,并把侧边栏作者链接的样式颜色修回和最后发布版一致。

特殊页面

aboutcategoriestags404 这类页面虽然不是普通文章,但它们同样带有时间元信息,也要单独校正。

5. 反复生成、反复比对

真正耗时间的不是“写回一个文件”,而是不断验证。

我采用的方式很简单粗暴:

  • 重新执行 hexo clean && hexo generate
  • diff -rq public Blog-main 对比生成结果和最后发布版
  • 发现差异就回到源码层继续修

在这个过程中,我陆续处理了:

  • 缺失文章导致的页面缺口
  • favicon 引用不一致
  • 文章和页面时间戳漂移
  • 搜索页、归档页、标签页的联动差异
  • 样式细节偏差

这类恢复工作和普通写文章不一样,它更像是在做一场“静态站取证”。每个看起来很小的差异,比如一个图标路径、一个毫秒值、一个页面更新时间,最后都会扩散到归档、RSS、搜索索引和分页页面里。

6. 最后的处理策略

当大部分源码都补齐后,重新生成的站点已经能非常接近 Blog-main 了,但仍然有极少数差异来自 Hexo/主题在生成顺序和标签顺序上的行为。

因此最后我采用了一个务实策略:

  • 源码层尽量补齐并校正
  • 最终 public/Blog-main 为准

这样做的结果是:

  • 站点对外展示可以完整恢复到误删前最后一次发布的状态
  • 当前项目也保留了继续维护所需的大部分源码
  • 后续如果继续写文章,不需要从零重建博客

7. 这次恢复给我的教训

这次事故最直观的教训不是“以后别手滑”,而是:

  • 生成产物本身也是一种备份
  • 源码备份和发布版备份都要保留
  • 恢复时一定要先确定权威来源

如果这次只有旧项目,没有 Blog-main,那我最多只能恢复“一个差不多的博客”;如果这次只有 Blog-main,没有当前项目,我又只能恢复“能看但不好维护的静态站”。正因为两份材料都还在,才有机会把“最后发布状态”和“可继续维护的源码”同时救回来。