春江暮客

春江暮客的个人学习分享网站

git push 更新被拒绝:远程版本库包含您本地尚不存在的提交怎么处理

2020-01-06 技术
git push 更新被拒绝:远程版本库包含您本地尚不存在的提交怎么处理

在使用 Git 推送代码时,一个很常见的报错就是:git push 被拒绝,并提示远程仓库里存在你本地还没有的提交。这类错误本质上通常就是 non-fast-forward 推送失败。

我当时在更新博客主题 bobobk-hugo 时,也遇到了这类问题,报错如下:

(base) ➜  bobobk-hugo git:(master) git push origin
Username for 'https://github.com': tengbozhang
Password for 'https://tengbozhang@github.com': 
To https://github.com/tengbozhang/bobobk-hugo.git
 ! [rejected]        master -> master (fetch first)
error: 无法推送一些引用到 'https://github.com/tengbozhang/bobobk-hugo.git'
提示:更新被拒绝,因为远程版本库包含您本地尚不存在的提交。这通常是因为另外
提示:一个版本库已推送了相同的引用。再次推送前,您可能需要先合并远程变更
提示:(如 'git pull')。
提示:详见 'git push --help' 中的 'Note about fast-forwards' 小节。

这个提示的意思很明确:远程仓库已经比你本地分支多了一些提交,Git 为了避免直接把这些提交覆盖掉,所以拒绝了这次 push。

为什么会出现这个错误

最常见的原因有这些:

  1. 你在 GitHub 网页上直接修改过文件,但本地还没同步下来
  2. 另一个人已经向同一个分支推送了提交
  3. 你在另一台机器上提交过代码,现在当前机器的分支落后了

只要远程分支和本地分支已经分叉,直接 git push 就可能报这个错。

最常用的解决方法

实际使用里,推荐先把远程更新拉下来,再把本地提交“接到”远程提交后面,然后重新推送。最常见的一组命令是:

git pull --rebase origin master
git add .
git commit -m "your message"
git push origin master

如果你已经提前提交过本地修改,那么更常见的顺序其实是:

git status
git add .
git commit -m "your message"
git pull --rebase origin master
git push origin master

这里推荐 git pull --rebase,而不是直接 git pull,原因是它通常会让提交历史更干净,不额外制造一次无意义的 merge commit。

如果 pull –rebase 过程中出现冲突怎么办

如果远程和本地恰好改了同一段内容,rebase 时就可能出现冲突。这时处理流程通常是:

# 先查看哪些文件冲突了
git status

# 手动修改冲突文件后
git add conflicted_file
git rebase --continue

如果你不想继续这次 rebase,也可以退出:

git rebase --abort

什么时候不该直接强推

有些人看到 push 失败后,会直接执行:

git push --force

这在个人临时分支里有时能用,但如果目标是共享分支,比如 mastermain,强推可能把别人的提交直接覆盖掉。除非你非常确定后果,否则不要把 --force 当成这个问题的默认解法。

一个更稳妥的排查顺序

如果你不想上来就直接 pull,也可以先这样确认状态:

git fetch origin
git status
git log --oneline --graph --decorate --all -20

这样你可以先看清楚本地分支和远程分支到底差了哪些提交,再决定是 rebase、merge,还是处理冲突。

总结

git push 提示远程版本库包含本地尚不存在的提交,本质上通常就是远程分支比本地领先,导致 push 无法 fast-forward。

最常用、也比较推荐的解决思路是:先同步远程更新,再用 git pull --rebase 把本地提交接到最新远程提交后面,最后重新 push。只要理解了这一点,这类报错以后基本都能快速处理。

git_update_success

友情链接

其它