让 AI 做出第一个网站之后,还会遇到一件很现实的事:
昨天能用的页面,今天改了几个地方,价格错了、按钮没了。你让它“恢复昨天那版”,它又重写一遍,顺便把今天刚补好的内容也删了。
这时候,你需要能找到的旧文件,以及明确知道该撤销哪一次修改。
下面走一遍具体操作:一个报名页先保存了正确价格,后来价格被改错,再后来补了常见问题。我们把价格恢复,同时留下后补的常见问题。
你可以把文中的指令交给能操作项目文件的 Codex。无需自己编写代码,但仍要确认哪些内容正确、哪些新改动必须保留。整篇只解决这件事,不要求先背一张 Git 命令表。
先确认:你手里有没有真正的存档
Git 是项目的版本记录工具。每次 commit,相当于给选中的文件保存一个有编号的版本。GitHub 可以托管这些提交,push 后远端才有相应记录。Git 与 GitHub 的关系
这里有三个容易混淆的动作:
- 文件保存了:当前文件在磁盘上
- commit 了:选中的改动进入了本地 Git 历史
- push 了:对应提交传到了远端仓库

图1:保存文件、commit、push各自记录什么。原创示意;本次练习没有配置远端或执行push。
聊天里说过“上一版挺好”,不代表那一版已经 commit。电脑上有个项目文件夹,也不代表里面有版本历史。
本文适合已经有 Git 提交记录的项目。项目可以只有文案、网页文件,也可以有代码。
如果从来没有存过旧版,Git 不能凭空恢复。先找编辑器的本地历史、系统备份或其他真实副本;让 AI 参考聊天重做,可以叫重建,不能叫找回原版。
第一次操作,拿不含客户资料、密钥和真实业务数据的练习项目走一遍。正在运行的正式项目,先保住现有文件,再谈恢复。
第一步:让 AI 找出“现在在哪”,先别动文件
在 Codex 中打开正确的项目目录。把这段发给它,填上你实际看到的问题。
我想恢复这个项目的一处错误,先只读检查,不要修改文件。
项目目录:[填写准确路径]
现在的问题:[例如,报名页课程价格从199元变成了99元]
最后一次正常的线索:[例如,修改首页文案之前;不知道就写不知道]
必须保留的新内容:[例如,后来增加的常见问题]
请检查并告诉我:
1. 实际打开的仓库根目录、当前分支、当前提交编号。
2. 哪些已跟踪文件还有未提交改动,哪些文件尚未被Git跟踪。
3. 与这个问题相关的最近提交:编号、时间、说明、改动文件。
4. 你怀疑哪次提交引入问题,依据是哪段差异。
5. 你能找到的旧版是否真的包含正确内容。
不要只根据提交标题判断;要检查实际差异。
不读取或展示密钥值。不提交、不推送、不切换分支、不恢复文件。
如果没有Git历史,明确说没有,停止恢复操作。
看它返回的目录,是不是你正在修改的那个项目。看分支,是不是这次出问题的那条。很多人电脑上有“项目”“项目副本”“项目最终版”,第一步弄错,后面再熟练也会修错地方。
接着看未提交改动。这部分还没有进入版本历史,不能因为你准备恢复旧版,就把它们一起丢掉。Git 的状态检查会区分已修改、已暂存和未跟踪文件;被忽略的文件还要另行考虑。Git 状态说明
Codex 的审阅面板也可以查看差异,但里面不只包含 AI 改的文件,还可能有你自己或其他工具做的修改。别看到一屏差异就全部接受或全部撤销。Codex 本地改动审阅
第二步:保住今天的新改动,再开恢复分支
分支可以用来试修,但新建分支本身不会自动给未提交文件存档。
如果第一步显示还有未提交改动,先请 AI 给出具体保全方案:哪些文件需要在本机复制一份,哪些可以形成一次临时提交,哪些不能进仓库。备份要覆盖相关的未跟踪文件;被忽略的配置和素材也不能靠一句“Git 是干净的”就认定已备份。
可以发:
先保全当前内容,不开始恢复。
请列出这次可能受影响的文件,包括相关的未提交、未跟踪和被忽略文件。
提出一个本机备份位置,放在当前项目目录之外,不上传。
说明会复制哪些文件、哪些无法完整备份;不要展示敏感内容。
另外列出适合做临时本地提交的文件清单。
密钥、.env、客户数据、数据库文件和不明大文件不要直接加入提交。
只给方案,等我确认文件清单及备份位置后再执行。
确认后,再让它按清单备份,并逐项核对备份文件是否存在、内容是否一致;适合提交的改动单独保存为本地检查点。这里的临时提交只是为了保全现场,不代表内容已经可以上线。
备份或提交有缺口,先补齐。不要一边报“备份失败”,一边继续覆盖文件。
等相关改动已经妥善保存、工作区适合继续操作,再从当前版本新建一个恢复分支,例如 recovery-price。原分支先留着,不在上面直接试修。分支与提交
如果仓库正处在一次未完成的合并、rebase 或其他恢复中,先停下,请 AI 解释现有状态,别叠加第二次操作。
第三步:找到该撤销的那次,不把整个项目倒回昨天
来看一个示意项目。它有三次已保存的提交:
A:报名页价格是 199 元,常见问题暂未补充
B:价格被改成 99 元
C:增加了“支持回放;报名后可查看学习资料”
现在希望得到:价格回到 199 元,C 增加的常见问题仍然保留。
如果把整个项目直接换回 A,常见问题也会跟着消失。

图2:隔离练习的A→B→C→revert B。恢复价格,保留FAQ;这是根据真实练习日志绘制的示意,不是业务界面截图。
这次更合适的是撤销 B 引入的改动,再新增一条恢复提交。Git 把这种操作叫 revert。原来的 A、B、C 仍留在历史里,后来的人能看见问题怎样产生、又怎样修复。Git revert 官方说明
但不能看到“价格改错了”,就让 AI 随便选一个提交撤销。先让它把计划说清楚:
请基于刚才的检查,提出恢复计划,暂不执行。
目标:恢复[具体正确内容],保留[后来新增且仍需要的内容]。
请指出:
- 要撤销的确切提交编号;
- 该提交实际改了哪些文件、哪些内容;
- 其中是否混有我仍然需要的其他改动;
- 后续提交是否依赖它,或者又修改了同一部分;
- 整次revert是否适合这个目标。
如果该提交同时包含其他要保留的功能,或者是合并提交,
不要直接整次撤销。列出冲突与影响,给出最小修复建议,等我决定。
不要把整个项目替换成某个旧版。
这一步要做一个很具体的判断:B 是不是只包含那次不想要的修改。
如果 B 同时“改错价格”和“修好报名按钮”,整次撤销就会把按钮修复也撤掉。此时应改成有针对性的修复,不要硬套本文的单次 revert 路线。
第四步:在恢复分支执行,遇到冲突就停
确认目标提交、影响范围和要保留的内容后,再发执行指令。
确认刚才的恢复计划。
只在[恢复分支名]操作,撤销[确切提交编号]引入的改动。
执行前再次核对仓库、分支、提交及工作区状态,
确认与刚才审阅时一致;若出现新改动,先停下来。
采用保留历史的revert,不使用reset --hard、clean、强制推送,
不删除分支,不改远端配置,不合并到主分支,不部署。
如果出现冲突,停止自动处理,返回冲突文件、冲突原因,
以及需要我决定保留的两部分内容;不要默认全部选ours或theirs。
完成后给我:
1. 新恢复提交的编号和修改文件清单;
2. 恢复前后的关键差异;
3. 需要我打开检查的页面或文件。
不要推送。
revert 并不是保证成功的“撤销魔法”。后续又改了同一段代码,或者新功能依赖旧改动,就可能产生冲突。即使没有文本冲突,也仍然可能存在业务上的依赖。
例如,价格后来又从 99 改成了 89,AI 不应代替你猜现在究竟要 199、99 还是 89。你需要先确定正确结果,再处理冲突。
如果决定放弃这次恢复,Git 提供 revert 的中止操作,回到此次操作开始前的状态。让 AI 先确认当前确实处在这次 revert 中,再中止;不要把“放弃本次操作”理解成删除整个项目。
第五步:同时检查“找回的”和“留下的”
恢复后,打开实际文件或本地预览,检查两件事:
- 原来错误的内容恢复了吗?
- 后来应该保留的内容还在吗?
在上面的示例里,就是价格显示 199 元,常见问题仍显示“支持回放;报名后可查看学习资料”。
如果恢复的是网站功能,还要运行项目原有检查,走一遍相关按钮和操作。看见代码里有按钮,不等于页面真的能点击;文件恢复了,也不代表数据库或已经发出去的数据跟着恢复。
把这段交给 AI:
请检查这次恢复结果。
必须恢复:[列出具体内容或操作]
必须保留:[列出后来新增且仍需要的内容或操作]
先核对文件差异,再运行项目现有且适用于本次修改的检查。
能预览时,打开实际页面验证相关操作。
逐项列出实际观察、通过/未通过/未验证,以及对应依据。
不要为了通过检查修改原有标准。
不能运行的项目检查,说明具体缺什么,不能写成通过。
最后列出本次恢复没有覆盖的内容,例如数据库、线上部署或外部文件。
确认本地结果符合预期,才考虑把恢复分支推到原来的私有仓库,并按项目已有方式开 PR、审阅、合并或部署。这些是后续动作,恢复本地文件不会自动完成它们。
已经推上 GitHub 的错误提交,也可以通过新的 revert 提交纠正内容;不需要为了“抹掉犯过的错”去强行改写整条历史。
有一个例外必须单独处理:如果误提交了密码或 API Key,普通 revert 不能清除旧历史里的秘密。应先撤销或轮换泄露凭证,再按 GitHub 的敏感数据处理说明处理历史。误提交敏感数据的处理
没有真实项目,也能先练一次
用一个只含示意文案的新空目录,就能看懂整件事。不要在正式项目里故意制造错误。
下面这段可以一次复制给 Codex。它只在你指定的新目录里做本地练习,不连接 GitHub:
请在我指定的新空目录[填写目录]做一次Git恢复练习。
先检查目标路径及父目录,确认不是现有仓库或其子目录。
如果目录已有文件、已在其他仓库内,或者Git不可用,先停下告诉我。
不要安装软件,不读其他项目,不联网,不创建远端仓库。
创建一个page.md,内容为一个虚构活动报名页:
上方写“课程价格:199元”;
中间写至少10行课程介绍、时间安排和联系方式占位文字,
让价格和常见问题位于相隔足够远的段落,降低本次入门演练的上下文冲突干扰;
末尾单独设置“常见问题”,先写“暂无”。
不要放真实联系方式或真实商业信息。
在这个新目录初始化Git。
提交身份只设在本练习仓库,使用Tutorial Demo和tutorial@example.invalid,
不要修改我的全局Git配置。
依次完成三次本地提交:
A:保存初始文件。
B:只把价格改成99元并提交,这是故意制造的示例错误。
C:只把常见问题改为“支持回放;报名后可查看学习资料”并提交。
记下A、B、C各自的真实提交编号。
从C新建recovery-price分支,仅revert B,不把整个文件恢复成A。
若出现冲突先停下,不自动选择覆盖。
最后打开文件并核对:
价格恢复为199元;常见问题保留C的内容。
展示四次提交、实际文件内容和检查结果。
比较A与恢复后的版本,确认差异仅为新增的常见问题;
检查工作区无未提交改动、没有配置远端。
不要推送、合并、删除目录或清理历史。
这个练习的重点,是亲眼看见恢复前后的区别:坏改动被撤销,新内容还在,历史也没有消失。
以后让 AI 改项目前,多说这一句
“先确认当前可用版本已经存档。把这次要改的内容单独放到一个分支;只提交本次相关文件。完成后给我改动说明和预览结果,再决定是否合并。”
每次提交尽量只做一件容易说清楚的事,例如“修改报名页价格”或“补充常见问题”。以后真要恢复,就更容易撤销一项,留下另一项。
Git 能帮你找回已经保存过的内容。让它真正有用,要在动手前留下那个可用版本。
学习参考:Adrian Punk《GitHub 小白零基础从 0 到 1 教程》中的版本存档、分支与先检查状态的思路。本文围绕“恢复错误提交并保留后续改动”独立展开,示意项目与操作指令为本文重新编写;不复用作者经历或成绩。 原文:https://x.com/adrianpunk115/status/2074744543170469894
