
1. Codex 自动回滚代码的排查思路先分清 git restore、IDE 本地历史还是工具链触发你让 Codex 改一个功能回头一看工作区被清空了git status干净得像刚 clone 下来这种体验确实让人血压升高。我先把结论放前面Codex 本身不会主动执行git restore .真正触发回滚的通常是三类来源——命令行工具链里的 git 操作、IDE 的本地历史机制、以及 Codex 在自动运行模式下调用 shell 时产生的副作用。这篇就按「先定位来源再复现验证」的顺序把 Codex 自动回滚代码怎么排查讲清楚涉及 git restore、Android Studio Local History、Codex 的 endpoint 与 auth.json 配置最后用 TaoToken 接入来复现整个链路。先说清楚 Codex 是什么、能做什么、适合谁。Codex 是 OpenAI 推出的编码代理工具可以在本地仓库里读写文件、执行命令、跑测试适合单人项目或小团队做功能迭代。它的工作方式是「读上下文 → 生成 patch → 应用改动」如果开了自动运行auto-run / full-auto它会直接执行 shell 命令而不逐条问你。问题就出在这里当它判断「当前工作区太乱需要回到干净状态」时可能调用git restore .或git checkout .而这两个命令会把你未提交的改动全部丢掉。我踩过的坑是这样的同时开了好几个 Codex 窗口一个窗口在改 A 功能另一个窗口在改 B 功能两个窗口共享同一个工作区。窗口 B 觉得工作区有「不属于自己任务」的改动就执行了一次git restore .把窗口 A 的成果一起抹掉了。这不是 Codex 的 bug而是多窗口并发 自动运行 共享工作区的组合问题。排查的核心逻辑是时间线对齐先确定回滚发生的时间点再去看这个时间点前后有哪些进程动过 git。具体分三步走。第一步看 git 的 refloggit reflog --dateiso会列出 HEAD 的每一次移动如果回滚是通过git reset或git checkout触发的reflog 里会有记录。第二步看 IDE 的 Local HistoryAndroid Studio 和 IntelliJ 系都会在.idea之外维护一份本地历史路径在系统缓存目录里即使 git 被清空Local History 也可能保留改动。第三步看 Codex 的会话日志它执行过的 shell 命令通常会记录在会话文件或终端输出里搜restore、checkout、reset就能找到元凶。这里有个容易忽略的点git restore .和git checkout .只影响已跟踪文件的未提交改动未跟踪的新文件不会被删。所以如果你发现新写的文件还在、老文件的改动没了基本可以锁定是 restore/checkout 类操作。反过来如果连新文件都没了那可能是git clean -fd或者更暴力的操作排查方向要换。还有一个隐蔽来源是工具链的格式化或 lint 自动修复。有些项目配了 pre-commit hook 或保存时自动格式化如果 Codex 触发了这些 hook而 hook 里又调用了git stash或git checkout也会造成「代码被回滚」的假象。排查时用git config --list | grep hook和查看.git/hooks/目录确认有没有自定义脚本。定位清楚来源之后才能谈修复。如果是 Codex 自动运行触发的最直接的办法是关掉 auto-run改成逐条确认如果是多窗口并发就给每个窗口分配独立的工作区或分支如果是 hook 触发的就改 hook 逻辑。下面几节我会给出可复制的 git 配置、Android Studio Local History 的检查步骤以及把 Codex 接到 TaoToken 后如何复现验证。2. TaoToken 前置准备把 Codex 的 endpoint 与 auth.json 改到 TaoToken在复现回滚问题之前得先让 Codex 能稳定跑起来。很多同学卡在第一步Codex 默认走 OpenAI 官方 endpoint网络和额度都不太可控。这里我用 TaoToken 作为接入层把 Codex 的请求指向https://taotoken.net/api这样既能复现问题也方便观察 Codex 到底发了哪些命令。TaoToken 是一个大模型 API 聚合服务支持 OpenAI 兼容协议Codex、Claude Code、Cline 这类工具都能接。它的作用是统一 endpoint 和鉴权你不用在每个工具里分别配 key。官网入口是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 地址是 https://taotoken.net/api 注意 API 地址不带 UTM 参数。Codex 的配置分两块一块是auth.json存 API Key一块是config.toml存 endpoint 和模型。默认路径在用户目录下的.codex/里。Linux/macOS 是~/.codex/Windows 是C:\Users\你的用户名\.codex\。先确认这个目录存在不存在就手动建。auth.json的格式很简单就是一个 JSON 对象字段名是OPENAI_API_KEY。注意这里虽然叫 OPENAI但填的是 TaoToken 的 key因为 Codex 走的是 OpenAI 兼容协议。key 在 TaoToken 控制台的 API Keys 页面生成地址是 https://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。生成后复制粘贴到auth.json里。config.toml里要改的是model_provider和base_url。Codex 支持自定义 provider把 base_url 指向 TaoToken 的 API 地址模型 ID 填你想要的比如gpt-5-codex或claude-sonnet-4-5。这里有个细节Codex 的 TOML 配置里provider 的wire_api要设成chat或responses取决于模型不确定就先用chat。配置改完之后用codex --version确认版本再用一个简单 prompt 测试连通性。如果返回正常说明接入成功。这一步很重要因为后面复现回滚问题时你需要确认 Codex 确实在执行命令而不是因为网络问题卡住了。顺便说一句如果你用的是 Claude Code 而不是 Codex配置方式类似但文件是~/.claude/settings.json字段是ANTHROPIC_BASE_URL和ANTHROPIC_AUTH_TOKEN。Claude Code 的接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 里面有完整的配置示例。配置好之后建议先在一个测试仓库里跑别直接上生产项目。测试仓库里放几个文件做几次提交然后让 Codex 改点东西观察它的行为。这样即使触发回滚损失也可控。3. 可复制配置git 快照规范 Codex config.toml auth.json 三件套这一节给出可以直接复制的配置片段。先说 git 侧的防护再说 Codex 侧的三件套Base URL Key Model ID。git 侧的核心思路是在任何 AI 编辑之前先打快照。这样即使 Codex 执行了git restore .你也能从快照 tag 恢复。下面这段是INSTRUCTIONS规范可以放到项目的AGENTS.md或 Codex 的指令文件里让它每次改代码前先执行。INSTRUCTIONS ## Git snapshots before any AI edits (REQUIRED) 在对仓库进行任何代码/文件修改包括 apply_patch、格式化、自动修复等之前必须先创建一个快照提交并打 tag。 执行顺序固定如下 1) git add -A 2) git commit -m snapshot before AI 3) git tag ai-pre-timestamp ### timestamp 规范 - 使用本地时间格式YYYYMMDD-HHMMSS例如ai-pre-20260209-141530 ### 例外处理 - 如果工作区没有变更导致 git commit 失败则使用 git commit --allow-empty -m snapshot before AI 再继续第 3 步。 /INSTRUCTIONS光有规范还不够Codex 不一定每次都遵守。更稳的做法是在 git 层面加一层保护配置git config让 restore 类操作需要确认或者用 alias 把危险命令包一层。下面这段是 git 配置可以复制到~/.gitconfig或项目级.git/config。[alias] # 安全版 restore先 stash 再 restore避免直接丢改动 safe-restore !f() { git stash push -u -m \pre-restore-$(date %Y%m%d-%H%M%S)\; git restore \$\; }; f # 查看最近的回滚痕迹 rollback-log reflog --dateiso --prettyformat:%h %gd %gs [core] # 禁止自动 gc 在关键时刻清理对象 autogc false [gc] auto 0这段配置的作用是git safe-restore会先把改动 stash 起来再 restore即使 restore 了也能从 stash 找回git rollback-log快速看 reflog关掉自动 gc 避免对象被清理。接下来是 Codex 的三件套。auth.json路径~/.codex/auth.json{ OPENAI_API_KEY: sk-你的TaoToken密钥 }config.toml路径~/.codex/config.tomlmodel gpt-5-codex model_provider taotoken [model_providers.taotoken] name TaoToken base_url https://taotoken.net/api wire_api chat env_key OPENAI_API_KEY这里三个关键字段base_url指向 TaoToken 的 API 地址env_key指定从环境变量读 key也可以直接读 auth.jsonwire_api选chat。模型 ID 按你实际用的填TaoToken 支持的模型列表在控制台能看到。如果你用的是 Claude Code配置换成~/.claude/settings.json{ env: { ANTHROPIC_BASE_URL: https://taotoken.net/api, ANTHROPIC_AUTH_TOKEN: sk-你的TaoToken密钥, ANTHROPIC_MODEL: claude-sonnet-4-5 } }三件套配齐后用codex exec echo hello或类似命令测试。如果 Codex 能正常返回说明 Base URL、Key、Model ID 都对上了。这一步是后面复现验证的前提。4. 验证请求与成功结果复现回滚并确认来源配置好之后开始复现。目标是让 Codex 在一个可控的测试仓库里触发回滚然后确认是哪个环节干的。先建测试仓库mkdir codex-rollback-test cd codex-rollback-test git init echo line 1 a.txt echo line 2 b.txt git add -A git commit -m init然后制造一些未提交的改动echo uncommitted change in a a.txt echo new file c.txt git status此时a.txt有未提交改动c.txt是未跟踪文件。现在开一个 Codex 会话让它改点东西。用codex进入交互模式输入类似「帮我把 b.txt 的内容改成 hello」的 prompt并开启 auto-run。观察 Codex 执行了哪些命令。如果 Codex 执行了git restore .你会看到a.txt的改动消失但c.txt还在因为 restore 不影响未跟踪文件。这就是典型的 restore 特征。此时用git reflog --dateiso看 HEAD 有没有移动如果没移动说明是工作区级别的 restore不是 reset。git reflog --dateiso git status如果 reflog 没有异常但改动没了基本锁定是git restore .或git checkout .。接下来去 Codex 的会话日志里搜。Codex 的会话文件通常在~/.codex/sessions/下按时间排序找最近的ls -lt ~/.codex/sessions/ | head grep -r restore\|checkout\|reset ~/.codex/sessions/ | tail -20如果搜到了git restore .元凶确认。如果没搜到那可能是 IDE 或 hook 触发的进入下一步。Android Studio Local History 的检查步骤在 Android Studio 里右键项目根目录 → Local History → Show History会弹出一个时间线窗口。左侧是时间点右侧是文件差异。找到回滚发生前后的时间点对比差异就能看到哪些文件被改了。Local History 的存储路径在系统缓存里Windows 是%LOCALAPPDATA%\Google\AndroidStudio版本\LocalHistorymacOS 是~/Library/Caches/Google/AndroidStudio版本/LocalHistoryLinux 是~/.cache/Google/AndroidStudio版本/LocalHistory。Local History 的局限是保留时间有限默认几天到两周而且不是所有文件都记录。如果回滚发生得早可能已经过期。所以它只能作为辅助手段不能当主力恢复方案。成功复现的标志是你能明确说出「这次回滚是 Codex 在 X 时间执行了git restore .导致的」并且能从快照 tag 或 stash 里恢复改动。下面给一个恢复示例# 从快照 tag 恢复 git tag | grep ai-pre git checkout ai-pre-20260209-141530 -- . # 或者从 stash 恢复 git stash list git stash pop验证请求是否走 TaoToken 的方法在 Codex 会话里执行一个需要调用模型的 prompt同时看 TaoToken 控制台的请求日志。如果日志里有对应的请求记录说明 endpoint 配置正确。这一步能排除「Codex 因为网络问题没真正执行」的干扰。5. 本篇常见错排查401、local proxy failed、reading choices、OAuth复现过程中会遇到几类典型报错逐个说清楚。401 Unauthorized最常见key 不对或没读到。检查auth.json里的OPENAI_API_KEY是不是 TaoToken 的 key有没有多余空格。如果用的是环境变量方式确认echo $OPENAI_API_KEY有输出。Codex 读 key 的顺序是 auth.json 优先其次环境变量。401 还有一种可能是 key 过期或被禁用去 TaoToken 控制台确认 key 状态。local proxy failed / connection refusedCodex 尝试连本地代理但失败。检查config.toml里的base_url是不是写成了http://localhost:xxxx应该改成https://taotoken.net/api。如果系统里配了全局代理环境变量HTTP_PROXY、HTTPS_PROXYCodex 可能会走代理导致连接失败。临时清掉这些变量再试unset HTTP_PROXY HTTPS_PROXY ALL_PROXY codex exec testreading choices / unexpected response formatCodex 收到的响应格式和预期不符。通常是wire_api设错了。如果模型走的是 chat completions 协议wire_api要设chat如果走 responses 协议设responses。改完重启 Codex 会话。还有一种可能是模型 ID 写错TaoToken 返回了错误结构去控制台核对模型 ID。OAuth / login requiredCodex 提示需要登录。这是因为 Codex 默认走 OpenAI 的 OAuth 流程但你已经改成 API Key 方式了。检查config.toml里有没有preferred_auth_method apikey没有就加上。如果还是提示 OAuth删掉~/.codex/下的auth.json重新生成确保格式正确。git restore 后改动找不回如果没打快照也没 stash试试git fsck --lost-found有时候 git 对象还在能捞回来。Android Studio 的 Local History 也可以试但别抱太大希望。最坏情况就是重写所以快照规范一定要提前配。多窗口并发冲突两个 Codex 窗口改同一个仓库互相覆盖。解决办法是给每个窗口分配独立分支git worktree add ../feature-a feature-a git worktree add ../feature-b feature-b每个 worktree 是独立工作区互不干扰。Codex 在各自目录里跑就不会出现 A 窗口 restore 掉 B 窗口改动的情况。Codex 不遵守快照规范即使写了INSTRUCTIONSCodex 也可能跳过。这时候用 git hook 强制。在.git/hooks/pre-commit里加检查或者在 Codex 的配置里把 auto-run 关掉改成逐条确认。关 auto-run 的方法是在config.toml里设approval_policy on-request或类似字段具体看 Codex 版本。排查的核心是先定位来源再对症下药。401 和 proxy 是配置问题reading choices 是协议问题OAuth 是鉴权方式问题restore 是行为问题。分清楚之后解决起来就快了。6. 长期编码与 Agent 场景用 Coding Plan 稳定跑 Codex如果你只是偶尔用 Codex 改改代码按上面的配置就够了。但如果你像我一样长期用 Codex 做功能迭代甚至跑 Agent 任务那建议上 Coding Plan。它的好处是额度稳定、endpoint 固定不会因为临时额度问题中断会话。Coding Plan 的入口在 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 里面有套餐说明。长期跑 Codex 的经验是把快照规范固化到项目里别指望每次手动打 tag。可以在项目根目录放一个AGENTS.md把INSTRUCTIONS写进去Codex 每次启动会读。再配合 git hook 做双保险。这样即使 Codex 抽风执行了 restore也能从快照恢复。另一个经验是给 Codex 划定工作区。用git worktree或者单独的 clone别让它和你的主工作区混在一起。Codex 在独立目录里跑即使回滚也只影响那个目录主工作区安全。这个习惯能省掉很多麻烦。模型选择上Codex 类任务用gpt-5-codex或claude-sonnet-4-5都行前者对代码补全更友好后者对长上下文理解更好。在 TaoToken 控制台可以切换模型不用改代码。模型对话功能在 https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 可以用来测试不同模型的表现。最后说一个实用技巧在 Codex 会话开始前先手动执行一次快照命令把当前状态存下来。这样即使 Codex 不遵守规范你也有个兜底。命令很简单git add -A git commit -m snapshot before AI git tag ai-pre-$(date %Y%m%d-%H%M%S)跑完再开 Codex心里踏实。回滚了就从 tag 恢复几秒钟的事。这套流程我用了几个月再没出现过代码被清空的情况。