安全网:
改坏了也退得回去
Codex 改的是你电脑上的真文件,而它没有"撤销上一步"的按钮。这不可怕:只要养成"动手前存个档"的习惯,再学会审阅面板里的几种退法,改坏了随时能退回去,而且不会顺手把你自己的改动也一起丢掉。
a1c2
5d2e
时间紧就看第 1、3 节和第 5 节的沙盘:记住"先提交再动手"和"只撤坏的那一块",就不会吃大亏。
Codex 没有"撤销上一步"
写文档时按一下撤销,刚才那几个字就回来了。Codex 没有这样的按钮:它改完的文件就在你硬盘上,想退回去,得靠 Git。
打一个比方:Codex 像一位手脚很快的装修师傅,直接在你家里动工。他没有"时光倒流"的本事,但你可以在他进门前拍一张全屋照片(Git 提交)。哪里弄坏了,照着照片恢复就行;照片拍得越勤,损失越小。
官方文档里的斜杠命令列表没有 /undo、/rewind 这类命令。想要一个撤销按钮的人很多,社区里专门有人提了需求(openai/codex#9203),但到本课核对时,官方文档里还没有撤销命令。
你手里有的五样安全网
/fork把对话复制一份,换个思路再试,原来的对话不动。这五样里,只有 Git 检查点能保证"一定退得回去"。审阅面板的 Revert 也是按 Git 算的:项目不是 Git 仓库,审阅面板就用不了(App 会提示你先建一个仓库)。
够用就好:四个 Git 词
Git 是记录文件每一次变化的工具。不用全学会,这一课只要四个词。它们是 Git 自己的命令,和 Codex 无关,在哪个项目里都一样用。
提交git add -A git commit -m "开工前存档"
分支main)不受影响。试砸了,整条分支不要就是了。git switch -c fix-pagination
还原文件git restore src/pages/Orders.tsx
先收起来-u。git stash # 收起来 git stash pop # 拿回来
还有一个常听到的说法:"工作区干净",意思是 git status 显示没有任何没提交的改动。这时候你的每一处改动都已经存了档。
这些命令可以在 App 的集成终端里自己敲(第 2 课),也可以直接让 Codex 帮你执行。要写 .git 文件夹的命令(提交、stash、切分支),默认档位下它会先停下来请你批准(第 3 课),第 9 节细说。
练一练:这种时候用哪个
官方的习惯:任务前后各留一个检查点
官方文档在好几处反复说同一件事:在任务开始前和结束后各建一个 Git 检查点,这样随时能退回去。把它拆开,就是下面四步。
main 上让它改。一个任务一条分支,试砸了整条丢掉。git stash 收起来,让 git status 显示干净。为什么第 2 步最要紧
官方在安全那一页说得很直接:在功能分支上工作,把任务交给 Codex 之前保持 git status 干净,这样 Codex 的改动更容易单独拎出来、退回去。反过来,如果你自己还有一堆没提交的改动,Codex 的改动就会和它们混在一起,退的时候很难只退它的。第 4 节会看到这到底有多麻烦。
同一页还有两条建议:勤提交,这样可以一小步一小步地往回退;把 Codex 的改动当成同事提的 PR 对待:跑有针对性的验证、看 diff、在提交说明里写清楚为什么这样改,方便以后查。
直接说"把这次改动提交一下,提交说明写清楚改了什么"。它会用 git commit,默认档位下会弹出批准卡片,你点"允许一次"就行(原因见第 9 节)。
审阅面板怎么退,为什么会误伤
审阅面板不只是用来看的,也能退:整体、按文件、按一小块(代码块,英文叫 hunk)三种粒度。但它是按 Git 算的,这一点决定了它会不会误伤你。
- 1整体审阅面板标题栏里的 Revert all / Stage all,一次处理整份改动。
- 2按文件单独暂存、取消暂存或 Revert 一个文件。
- 3按代码块一个文件里连在一起的一段改动。只撤这一块,同一文件的其他改动不受影响。
界面示意:按钮的样子和位置以你的 App 为准,三种粒度和按钮名称来自官方文档。
按 Git 算,是什么意思
审阅面板显示的是你这个 Git 仓库的状态,不只是 Codex 改的。默认的 Unstaged 视图里是所有还没暂存的改动:Codex 的、你手改的、别的程序改的。它分不清哪行是谁写的。
所以在 Unstaged 里点 Revert all,你自己没暂存的改动会一起没掉;按文件 Revert 一个你和 Codex 都改过的文件,你那部分也会一起没掉。防误伤最简单的办法:先把你自己的改动提交了。提交过的东西不再出现在 Unstaged 里,怎么 Revert 都碰不到它。
Last turn:只看 Codex 最近一轮
把审阅面板切到 Last turn,就只剩 Codex 最近一轮改的内容,你的手改不会混进来。找"是哪一块坏的",从这里下手最快。
但要注意"最近一轮"四个字:Codex 每回你一条消息就算一轮。它改坏了东西之后你又让它做了别的,Last turn 就换成了新一轮的内容,之前那块坏的得切回 Unstaged 去找。发现问题要趁早。
Last turn 里能不能直接点某一块的 Revert,文档没写,以你的 App 为准;不行就记下是哪一块,切回 Unstaged 对同一块点 Revert。
Revert 就是把改动扔掉,扔之前看清楚这一块里有没有你想留的。拿不准就先提交一次,或者先 git stash 收起来。
时间线沙盘:五种退法,谁留下、谁没了
"修复分页 bug"这个对话里,Codex 修分页时顺手把"导出 CSV"按钮弄坏了。选一个发现问题的时刻,再选一种退法,看看每一处改动各自的下场。
1 什么时候发现导出坏了(点时间线上的节点)
2 选一种退法
结果
示意:文件和提交号是虚构的;每种退法的效果按 Git 的规则推算。
按代码块撤最准;按文件撤只在这个文件里全是要丢的东西时才安全(这里 Orders.tsx 还有 Codex 改对的分页参数,所以怎么按文件撤都会撤多);Revert all 和回到检查点都是"一锅端";/fork 根本不动文件。打开"先提交你自己的两处",再点一遍,误伤就少了一大半。
练一练:该用哪种退法
5 个场景,每个选一种最合适的做法。选完会看到解析。
演练:只退坏的那一块,再让它重修
你手头有一处没提交的改动,又让 Codex 去修分页,结果它把导出按钮弄坏了。跟着走一遍:用 Last turn 找到那一块,只撤它,告诉 Codex,最后留一个检查点。中途有两处要你自己点。
画面为教学示意:文件名、提交号和 Codex 说的话都是虚构的;审阅面板的视图名称、三种退法的粒度、.git 受保护要批准,与官方文档一致;在 Last turn 视图里直接按块 Revert 是示意。
换条路再试:/fork 和 Worktree
有时候不是"改坏了",而是"想换个思路试试,又不想丢掉现在这条"。这时候用的不是 Revert,而是分出一条新路。
/fork:把对话复印一份
在输入框里打 /fork,App 会把当前这个本地对话复制到一个新的本地对话,或者一个新的 worktree 里。原来的对话一字不动,你可以在新对话里走另一条路,两边对比。
要分清:fork 复制的是对话,不是文件的"存档"。分到新的本地对话时,两个对话还是在同一个项目文件夹里干活,已经改坏的文件不会因为 fork 自己变回去。想让文件互不干扰,就分到 worktree。
官方的建议是:同一个问题尽量留在同一个对话里,这样推理的来龙去脉都在;真的分岔了再 fork。另外,App 里也能从更早的一条消息分叉对话(入口以你的 App 为准);命令行里是输入框为空时连按两次 Esc(第 14 课讲)。两种都只分叉对话,不会把文件改回去。
Worktree:给 Codex 一张单独的工作台
打个比方:你在自己的桌子上干活,另外复印一整套项目放在隔壁桌,让 Codex 在那边随便折腾。两张桌子上的文件互不影响,但共用同一本"存档记录"(同一个 .git)。
- 只能在 Git 仓库里用,底层就是 Git 自带的 worktree 功能。
- 新建对话时,在输入框下方打开 Worktree 开关,再选从哪个分支开始。
- 做得满意,可以用对话标题栏里的 Hand off 把对话和改动一起转回 Local(你自己的项目文件夹),或者用 Create branch here 把它变成一条分支;不满意,这张桌子上的东西不要就是了,你本地的文件一点没动。
| 做法 | 对话 | 文件 | 适合 |
|---|---|---|---|
| 在原对话里接着说 | 同一段 | 同一个项目文件夹 | 还是同一个问题,想保留来龙去脉 |
/fork 到本地对话 | 复制一份,原对话不动 | 还是同一个项目文件夹,改动不会退回 | 想换个问法,本地接着干 |
/fork 到 worktree | 复制一份,原对话不动 | 在一份独立的 worktree 副本里 | 想换个做法,又不想碰本地文件 |
| 新对话选 Worktree | 全新 | 独立副本,从你选的分支开始 | 大胆试验,或者和你手上的活并行 |
Worktree 的其他细节,比如被 .gitignore 忽略的 .env 不会自动带过去、怎么清理、保留几个,第 12 课细讲。
让 Codex 帮你用 Git,以及几个进阶做法
Git 命令不熟,可以直接让 Codex 执行。但有几件事你得心里有数。
它碰 Git 时为什么常要你批准
默认档位下,项目文件夹可写,但里面的 .git、.codex、.agents 三个文件夹是只读的,连里面的所有东西都算。Git 把提交记录、暂存区、stash 都存在 .git 里,所以提交、stash、切分支、回到某个提交这类命令都要写 .git,默认档位下通常会弹出批准卡片(除非你在这次对话里已经选过更大的批准范围)。这是好事:动存档记录的操作,本来就该你点头。
说清楚退哪些、别碰哪些
"帮我撤掉"太含糊,它可能把整个工作区都还原了,连你的手改一起。更好的说法:"只撤掉你这一轮对 Orders.tsx 的改动,README.md 是我改的,不要动"。批准卡片上的命令也要看一眼:带 .(整个目录)、--hard 的,都是一锅端。
反过来,你自己 Revert 了或者手改了它的代码,要告诉它一声。官方提示过:不说的话,它在下一轮可能又把你的修改覆盖掉。
给进阶的人
- 回到某个提交是最狠的一招。比如回到任务前的检查点:那之后所有没提交的改动都没了,那之后的提交也不在这条分支上了。只在你确定整段都不要时用。(其实 Git 还能从
git reflog里把丢掉的提交找回来,但别把它当常规手段。) - 补丁式工作流。官方安全建议里提到:比起让它直接改已跟踪的文件,更稳妥的是以补丁的形式往来(
git diff导出、git apply应用),并且勤提交,一小步一小步地回退。 - 提交前让它自己再审一遍。输入
/review,选 Review uncommitted changes,它会列出按优先级排好的问题,不会改你的文件。 - 暂存也能挡一下,但别指望它。同一个文件可以同时有已暂存和未暂存的部分,审阅面板会把它同时显示在 Staged 和 Unstaged 里,这是 Git 的正常行为。各个视图里的 Revert 具体撤到哪一步,文档没有写细,要紧的东西还是直接提交最稳。
- "输入
/undo撤销 Codex 上一步":现在官方的斜杠命令列表里没有这个命令。改用 Git 检查点和审阅面板的 Revert。 - "(命令行)连按两次 Esc 就能回到过去":文档里它的作用是编辑上一条消息、从那里分叉对话,没说会把文件改回去。文件还是要靠 Git。
- "thread / task":现在都叫对话(chat),
/fork复制的就是一个对话。
审阅面板里出现了 Codex 没改过的文件?
同一个文件在 Staged 和 Unstaged 里都出现了
按 ⌘Z 能撤销 Codex 的改动吗?
我的项目还不是 Git 仓库,怎么办?
撤掉之后,Codex 下一轮会不会又改回去?
Worktree 被自动清理了,里面的改动还在吗?
小测验
8 道题,每题选完会立刻看到解析。
