同时进行 Git 推送导致的竞态条件错误 | AI生成和翻译

Home 2026.01

Question: 为什么在打开两个窗口/Terminal 执行 git add -Agit commitgit push 时会出现错误 “! [remote rejected] main -> main (cannot lock ref ‘refs/heads/main’: is at b2c0835c1c7c14323a162a90e17f8a78145e3f0a but expected 59383ebd13b30aab988c8eefcc0f64f103f0f44d)”?

Answer:

出现这个错误是因为 两个 Git 进程尝试在几乎同一时间更新远程服务器上相同的 branch reference (refs/heads/main),从而导致了竞态条件 (race condition)。

逐步分析实际发生的过程

  1. 你在 同一个本地 repository 中打开了 两个 Terminal 窗口
  2. 在两个窗口中你都运行了:
    • git add -A
    • git commit → 由于 working tree 和 index 通常是共享的,两者由于提交时间或内容微差会生成 两个不同的 commits
    • git push (或 git push origin main)

由于文件系统 (index + working tree) 在两个 Terminal 之间是共享的:

这本质上就是两个 push 操作之间的 race condition

在你的场景中最常见的原因

如何避免

看到此错误时的快速恢复方法

通常只需运行:

git pull --rebase    # 或 git pull --autostash
git push

这会让你的本地分支保持最新,然后再 push 你的新 commit。

总结

该错误 并非数据损坏 —— 它是 Git 保护远程分支免受并发冲突更新的一种机制。
它的发生正是 因为你几乎同时从两个 Terminal 发起了 push

References:


Back

x-ai/grok-4.1-fast

Donate