故障处理

Codex 推送失败、创建 PR 失败?先查提交、远端分支与执行通道

Codex 说任务完成,GitHub 却没有分支或 PR?从实际仓库、提交 SHA、远端分支和 PR 状态逐步核对,区分桌面 Git 面板、终端与集成通道,按错误定位下一步并验证交付结果。

Codex 已经改好代码,甚至回复“任务完成”,但 GitHub 上没有预期分支或 Pull Request。先查四件事:文件是否真的改了、改动是否进入提交、目标提交是否到达正确远端、PR 是否指向正确仓库与分支。 一条完成回复不能同时证明这四件事。

本文处理“Codex 推送失败”“Codex 创建 PR 失败”、codex push failed 和 codex failed to create pr。先保留现有文件、提交及原始错误,按下表找到尚未完成的阶段。前面的检查不需要重新提交、推送或建 PR;只有最后明确需要写远端、且已获授权时,才进行一次对应操作。

先定位停在哪一步

当前证据 下一步
文件有变化,但没有包含这些变化的提交 第 1、2 步核对项目、暂存区与提交;先不查 PR
本地已有目标提交,远端分支不确定 第 3 步核对实际推送目标及远端 SHA
正确远端分支已有目标提交,却找不到 PR 第 4 步查目标仓库、base/head、状态与已有 PR
桌面面板只报“无法完成”或生成提交说明失败 第 5 步查具体子操作,不先认定 GitHub 认证失败
有 PR 链接,但页面、分支或差异不对 第 4、7 步核对仓库、来源分支、提交和文件
推送或建 PR 后响应中断,不知道是否成功 先查远端现状,不直接再创建一次

只需要推送的任务,不要求额外创建 PR。 需要 PR 的任务,还要继续核对 PR;PR 已创建也不代表已经合并、通过 CI 或部署上线。

1. 确认客户端、执行主机和真正的仓库

适用条件: 还不能确认改动在哪一份项目里,或者自己在终端能操作、Codex 却失败。

记下客户端及版本,并明确这次使用的通道:桌面 Git 面板、CLI/IDE 任务中的命令、集成终端、GitHub 集成工具,还是 Cloud 任务。浏览器登录、Codex 登录、Git 的 SSH/HTTPS 身份与 GitHub CLI 的登录状态,不能相互替代。

OpenAI 本地环境说明列出了桌面端的暂存、提交、推送分支和创建 PR 控件,也允许用集成终端处理其他 Git 操作。这不代表任意聊天里的 GitHub 连接器都有同样的写入能力。Cloud 中的任务则核对该任务实际选择的仓库、分支和环境,本机终端成功不能证明云端身份可用。

在本次任务实际使用的 checkout 和执行主机里,逐条运行下面的本地检查。若不在 Git 仓库、命令不支持或 HEAD 尚不存在,停在对应错误处,不继续套用后面的推送示例:

git rev-parse --show-toplevel
git branch --show-current
git rev-parse --verify HEAD
git --no-optional-locks status --short --branch --untracked-files=all
git --no-pager log -5 --format="%H %s"

预期结果: 项目根目录和分支是本次目标,能记录当前完整提交 SHA,并看到待提交文件。分支名为空可能是 detached HEAD,不要因此默认推到 main;先确认要保留的提交及团队允许的目标分支。没有任何提交的新仓库,HEAD 检查失败也不等于认证失败。

若改动在另一棵 worktree,先按 worktree 改动定位找到它。这里只读定位,不通过切分支、重置或复制覆盖文件来“修好”状态。

2. 分清“文件变了”“已暂存”和“已提交”

适用条件: 找到了正确项目,但还不能证明这次修改已经进入提交。

对照 Git status 的状态含义:?? 是未跟踪文件;普通修改与已暂存修改是不同状态。工作区干净只能说明当前没有报告的待提交变化,不能证明提交已推到远端。 也可能是你看错了 checkout,或任务根本没有产生预期变化。

查看工作区、暂存区和最近提交的实际内容:

git --no-pager diff --no-ext-diff --no-textconv --
git --no-pager diff --cached --no-ext-diff --no-textconv --
git --no-pager show --format=oneline --stat HEAD

预期结果: 能把本次目标文件与一个明确提交对应起来,而不是只看到一条相似的提交标题。普通 diff 没有输出不代表未跟踪文件已进入提交;必要时在提交详情中逐文件核对正文。若改动仍在工作区/暂存区,先按原任务范围审查并完成提交,不要为了排障默认 git add . 把其他工作一起提交。

若提交阶段已报 .git/index.lock: Permission denied、Operation not permitted 或锁占用,转 Git 写权限与 index.lock 排查。这时尚未完成本地提交,不把它归为 PR 创建故障。若必须撤销错误操作,先看 保留原有修改的撤销边界,不使用 reset/clean 清空现场。

3. 本地有提交:确认推到了哪一个远端分支

先核对目标,而不是只看 origin 或 ahead/behind

适用条件: 已有要交付的完整提交 SHA,仓库和分支已经确认。

先列出远端名称,再把示例中的 origin 换成实际使用的远端。URL 只在本地核对;可能含账号或认证信息,不原样公开:

git remote
git remote get-url --all origin
git remote get-url --push --all origin

Git remote 文档区分读取与推送 URL。核对主机、OWNER/REPO、SSH/HTTPS,以及是否配置了多个推送 URL。origin 只是名称,不保证它就是你期望的仓库;fork 与上游也可能使用不同远端。目标不明确或有多目标推送配置时,先找维护者核实,不运行通用 push 改写多个远端。

本地 origin/某分支 和 status 的 ahead/behind 基于本地已有的远端跟踪信息,可能尚未刷新。它们不能单独证明 GitHub 此刻已有或没有某个提交。

查询远端当前分支及 SHA

适用条件: 已确认查询的目标就是预期推送仓库,且允许从该执行端联网读取它。下面假定 origin 的读取与推送目标相同,codex/example 是已核对的目标分支;两项都要换成实际值。

git ls-remote --exit-code origin "refs/heads/codex/example"

这是对远端的引用查询,不推送更新,但仍会联网并使用当前执行环境的认证。读取与推送 URL 不同时,改用已核对的目标 URL 查询,或直接在正确仓库的网页查看分支与提交;不要把查询另一处仓库的结果拿来验收。

按 Git ls-remote 官方说明读取输出:有匹配时会显示完整对象 ID 和引用名;使用 --exit-code 后,无匹配返回 2,成功匹配返回 0。其他错误先按原文处理;认证失败、网络失败不能记为“分支不存在”。检查退出码时,Bash/zsh 紧接着用 printf '%s\n' "$?",PowerShell 紧接着看 $LASTEXITCODE,不要先执行另一条命令覆盖结果。

预期结果: 目标分支指向已核对的提交。若 SHA 不同,先确认分支是否已被你或协作者继续推进;不同不一定表示本次提交没推成功,可在网页提交历史中核对它是否已包含。未查清前不强推来“对齐 SHA”。若分支已含目标提交,推送阶段已有证据,继续查 PR,不重复推送。

4. 远端已有提交:确认 PR 是否真正存在

适用条件: 任务确实要求 PR,并且来源分支已经到达正确远端。

先打开要接收改动的仓库的 Pull requests 页面,核对完整的来源仓库/分支(head)和目标仓库/分支(base),同时检查 Open、Closed、Merged。已有 PR、已关闭 PR 和只打开了“比较并创建 PR”的页面,是不同状态。fork 中同名分支也不代表同一个来源仓库。

已有 GitHub CLI 且有该仓库读取权限时,可作一次明确仓库的查询;没有 gh 不必为了本步骤安装,使用网页即可。以下 OWNER/REPO 指目标仓库,分支名换成实际值;企业实例还要使用正确主机:

gh pr list --repo OWNER/REPO --head codex/example --state all --limit 100 --json number,url,state,isDraft,baseRefName,headRefName,headRefOid,headRepository,headRepositoryOwner

gh pr list默认只列 Open;这里显式查所有状态。--head 按分支名筛选,不支持把 OWNER:BRANCH 直接塞进去,因此还要核对结果中的来源 owner。结果限制为 100 条;空列表可能来自筛选、身份、目标仓库或范围问题,不自动证明 PR 从未创建。

有具体 PR 编号或已返回链接时,再查该 PR。下面 123 是示例编号:

gh pr view 123 --repo OWNER/REPO --json number,url,state,isDraft,baseRefName,headRefName,headRefOid,headRepository,headRepositoryOwner

预期结果: 能实际打开链接,来源 owner/head、base 和预期提交对应,并核对 Files changed 确实包含本次修改。GitHub PR 说明区分草稿和后续合并状态;Draft 可以证明 PR 已存在,但不能当作已就绪或已合并。PR 已合并、来源分支又被删除时,也不能仅因查询不到分支就认定交付失败,要查合并记录和实际结果。

若请求在返回链接前中断,先执行上述查询或在网页确认已有 PR。不要因为 Codex 没拿到响应,就再建一个重复 PR。

5. 按实际失败通道排查,不把所有错误都归为权限

适用条件: 已定位阶段,仍需判断为什么该阶段失败。

错误或停顿位置 具体检查与失败后的去向
桌面面板在生成说明、暂存或提交时失败 保留具体子操作、错误和版本;按第 2 步确认有无产生提交。生成说明失败本身不能证明远端认证失败
src refspec ... does not match any、找不到来源分支 对照第 1、2 步查来源引用拼写、HEAD 与提交是否存在,不换 token 重试
non-fast-forward / fetch first 远端可能已有不同提交;先查看双方历史并审查如何整合,不默认强推或直接 pull/rebase 改写现场
remote rejected、保护规则或服务端检查拒绝 读完整拒绝原因,按仓库既定流程处理;不删除保护规则、不跳过 hook 来通过
Permission denied (publickey)、认证失败、HTTP 403 核对报错来自 SSH、Git HTTP 还是 PR API,以及当前主机/协议/身份是否获准访问该仓库;403 本身不证明 token 过期
超时、DNS、连接中断 先查第 3、4 步远端现状,再排查失败的具体连接;任务命令联网见下方内链
无可比较改动、head/base 无效、已有同源 PR 核对两端仓库/分支与已有 PR;base/head 选择错,不靠重新提交一份相同代码解决

Git push 文档对本地拒绝、远端拒绝和未确认成功的远端故障分别说明。以完整错误为依据;“我在另一个终端能推”只能作为对照,不能证明当前 Codex 执行端使用相同身份、协议、代理和权限。

桌面面板失败时,可在当前客户端提供的日志/诊断入口查相应时间段;入口随客户端与版本而异,不编造所有平台共用的日志路径。允许使用集成终端的场景,仍需先核对同一 checkout、主机、目标与授权,再用它完成必要操作;不为绕过管理策略换工具。社区旧版本的单个提交说明、图片或同步目录个案,不作为当前所有用户的通用根因。

只有命令确实报 Git 目录写入拒绝时才转 index.lock 专题;命令网络失败转 任务网络专题;配置来源有疑问看 config.toml 加载与覆盖。PR 已存在但 @codex review 没反应,则是 GitHub 审查触发问题,不是创建 PR 失败。

6. 确认缺少的动作后,才完成获准的推送或 PR

只缺推送:限定正确目标,不批量试命令

适用条件: 已审查提交内容与相关检查,HEAD 正是要发布的提交;已获得向指定仓库/分支推送的授权;远端配置只有一个已确认目标,且不是未处理的冲突、分叉或未知保护状态。先确认本地 Git hooks 和仓库流程,不把排障当成跳过它们的理由。

下例是会写远端的操作,仅用于已核对的普通分支推送;origin、目标分支均须替换。它不是诊断步骤,不要和前面的检查一口气执行:

git push --no-follow-tags --recurse-submodules=no origin HEAD:refs/heads/codex/example

预期结果: 只有指定目标分支得到预期更新;这里显式关闭随附标签和递归推送子模块,不为一次普通分支交付附带其他发布。需要发布标签或子模块时另按项目流程处理。之后仍按第 3 步核对远端;报错或响应中断时先查现状,不加 --force、--all、--mirror 或 --no-verify 重试。git push --dry-run 也不是纯本地检查:它不实际发送更新,但仍涉及远端连接及 pre-push hook 等流程,不能替代上述授权与目标审查。

只缺 PR:核对 base/head,并保留验证说明

适用条件: 来源分支已在远端、没有符合本次目标的已有 PR,当前集成支持创建且用户已授权。可使用当前客户端的创建入口,填清 base/head、改动内容、实际运行的检查和未完成项,创建后按第 4 步核验。

使用 GitHub CLI 时,先在本地编辑并审阅一份 pr-description.txt,只写本次交付说明。以下为同一仓库内已有来源分支的草稿 PR 示例,不适用于未核对的 fork;替换仓库、分支、标题和说明文件路径后才执行:

gh pr create --repo OWNER/REPO --base main --head codex/example --draft --title "说明本次修改" --body-file ./pr-description.txt

按 gh pr create 官方说明,显式指定 --head 可跳过自动 fork/推送分支的交互行为;这里先要求分支已经存在。该命令仍然会创建远端 PR,草稿不是私有本地预览。尤其不要把 gh pr create --dry-run 当作零副作用的检查,其帮助明确说明仍可能推送 Git 改动。

预期结果: 返回可打开、base/head 正确且内容符合预期的草稿链接。若无创建权限或集成不支持,OpenAI 官方交付流程允许交付 diff、PR 描述和验证证据,由有权限的人按原流程完成。此时明确写“代码/提交已准备,PR 未创建”,而不是宣称全部完成;不默认换 token、增加权限、建立 fork 或绕过组织要求。

7. 最终验收:按真实目标逐项交付证据

只检查本次任务要求的阶段,不为了让状态好看添加额外发布动作:

  • 本地改动: 正确项目/worktree 中能读到实际修改;需要保留的用户工作仍在,相关检查有真实结果。
  • 提交: 给出完整提交 SHA,并核对提交内确实含目标变化;暂存成功或生成了提交说明都不能代替它。
  • 推送: 给出正确远端仓库、分支及核对时的提交状态;本地跟踪缓存、dry-run 或口头回复不能单独充当远端证据。
  • PR: 仅在任务要求时提供可打开的 PR 链接,核对来源 owner/head、base、目标提交与文件差异,并如实标记 Draft/Open/Closed/Merged、CI 和未完成项。PR 存在不等于合并或部署。

如果只能确认到某一步,就交代“已确认到这里、下一步被什么阻挡”。求助时提供客户端/版本、执行主机、失败通道、阶段、脱敏错误及必要提交/PR 信息;不贴含认证的远端 URL、token、完整环境或私有日志。查不到私有仓库与确认它不存在,是两种不同结论。

本文于 2026-10-17 核对 OpenAI、Git、GitHub 与 GitHub CLI 官方资料,并用隔离的本地仓库和 bare 远端验证阶段检查、未推送/已推送、缺失分支、过期跟踪信息和推送拒绝等边界。GitHub CLI 选项按本机帮助核对;未为文章创建真实 GitHub PR、调用模型或宣称实测所有客户端。实际 PR 权限、状态与界面仍应在对应仓库和执行端核验。

社区讨论

补充你的经验或问题

评论由 GitHub Discussions 承载;参与讨论需要登录 GitHub。