GitHub PR 不更新提交:关闭再打开就好了

太阳作者太阳
原创内容采用 CC-4.0 协议发布,转载请注明出处

这次遇到了一个有点好笑的问题:代码已经推送到 GitHub,PR 页面却像什么都没发生过,始终显示旧的提交列表。

最后的解决办法很朴素:把 PR 关掉,再重新打开。提交就同步了,随后也正常合进了 main。

不过,在点这两个按钮之前,最有用的一步是先确认:到底是代码没有推上去,还是 PR 没有跟上分支。

分支已更新,页面却只有旧的 8 个提交

当时的 PR 是 #76。页面显示 8 个提交,最后一个是 fab9342,并且提示:

No conflicts with base branch
Merging can be performed automatically.

看起来可以合并,但最新的两次修改没有出现在列表中。

最初怀疑是本地只做了 commit,没有 push。这个猜测很常见,也很好验证:

git push origin HEAD

结果只有一句:

Everything up-to-date

这说明这次推送没有新的分支更新需要发送。继续重复同一条命令,也不会凭空产生一次新的更新事件。

接着核对本地 HEAD 和远端分支,发现它们都已经到了 6ac0bfd57。因此,至少在这次核对时,“代码没推上去”已经解释不了现象。

把远端分支和 PR 引用放在一起看

真正让问题变清楚的是这条命令:

git ls-remote origin refs/heads/codex/game-user-config-token refs/pull/76/head refs/pull/76/merge

当时实际返回:

6ac0bfd5768692df9c601c663a6609aff1424814  refs/heads/codex/game-user-config-token
fab93428ea3256cd1bd58bc07efee9d38c370eef  refs/pull/76/head
46300399e963f736b8a54903a7be6981e9a36ce3  refs/pull/76/merge

前两行已经足够说明问题:远端分支到了新提交,PR 的 head 引用却仍停在旧提交,恰好与页面显示的最后一个提交一致。

第三行的 merge 引用单独列出作记录,它不应该被拿来与源分支 HEAD 直接比较是否相等;这次判断同步问题,依据的是前两行。

这时就不能再把问题简单归因于浏览器没刷新了:GitHub 对外提供的 PR 引用本身也没有跟上分支。

GitHub 在关于 PR 更新处理延迟的公告中说明,推送到 PR 分支的提交有时会比通常情况花更长时间处理,在进入提交列表前会显示提示。这个说明与当时的现象相符,但它没有告诉我这一次具体卡在了哪个内部步骤。

没有服务端日志,就无法进一步确认是任务积压、缓存失效,还是别的内部状态问题。能确认的是分支与 PR 引用不一致。

关闭,再重新打开

找到的GitHub 社区同类问题讨论提到了关闭再重新打开 PR,以及推送空提交等处理办法。这些是其他用户的恢复经验,不是保证成功的官方修复接口。

我这次选择了影响更小的操作:

  1. 关闭 #76,保留原分支。
  2. 重新打开同一个 PR。
  3. 确认页面恢复显示最新提交,再进行合并。

这次确实有效,最终修改已经进入 main。没有删除分支,没有重建 PR,也没有为了触发处理额外塞一个空提交。

这里的“重新打开”指关闭后点击 Reopen pull request,不是把浏览器标签页关掉再打开。

我没有在恢复后再保存一份 ls-remote 输出,因此这里不补写一段看似完整的“修复后日志”。恢复结果来自实际页面同步和后续合并成功。

下次遇到,先检查哪一层没有跟上

这次排查最值得留下的是三个检查点:

  • 本地 HEAD:修改究竟提交到了哪里。
  • 远端源分支:代码是否已经推送到 PR 使用的分支。
  • PR 的 head 引用:GitHub 的 PR 是否跟上了该分支。

可以按自己的分支名和 PR 编号执行:

git rev-parse HEAD
git ls-remote origin refs/heads/feature/my-change refs/pull/123/head

如果本地和远端分支不同,先处理推送问题。如果远端分支与 PR head 不同,就有了比页面提交数量更直接的证据。

页面显示“没有冲突”和“可以自动合并”,也不能代替这一步核对。至少在本次故障里,这两句话和旧的提交列表同时存在。

本地合并后直接推送 main 也是当时考虑过的路径,但最后没有用到。既然关闭再重新打开就恢复了,就继续沿原来的 PR 完成合并。

这次没有找到 GitHub 内部停滞的根因,只找到了一个有证据支持的定位方式,以及一个在本次故障中有效的恢复动作。Git 的分支已经到站,PR 还停在上一站;关掉再打开,终于追上了。