“non-fast-forward”错误是Git拒绝覆盖远程分支历史的保护机制,因本地与远程分支不一致且本地提交非远程最新提交的直接后代所致;需先git pull同步再push,或谨慎使用--force。

为什么 git push 会报 “non-fast-forward” 错误
这个错误本质是 Git 拒绝覆盖远程分支的历史——你本地的 main(或 master)分支和远程不一致,且你的提交不是远程最新提交的直接后代。常见于:别人先推了新提交、你本地很久没拉、或者你强制重写了历史。
它不是 bug,是保护机制。强行用 git push --force 能压过去,但会丢别人的工作,除非你明确知道后果且有协作共识。
合并前必须先同步远程变更
多数情况下,只需两步就能干净合并:
- 运行
git pull origin main(把远程最新变更拉下来并自动合并到本地) - 解决可能出现的冲突(Git 会提示哪些文件有冲突,编辑后
git add+git commit) - 再执行
git push origin main,此时就是 fast-forward 或 merge commit,不会报错
注意:git pull 默认等价于 git fetch + git merge;如果你习惯用 rebase,可改用 git pull --rebase,让本地提交“重放”在远程最新基础上,避免无意义的 merge 提交。
遇到冲突时别跳过 git add
合并冲突后,Git 会把冲突标记写进文件(<<<< HEAD 和 >>>> commit-hash 之间),这时:
- 必须手动编辑文件,删掉冲突标记,保留最终内容
- 每改完一个冲突文件,都要
git add <file>—— 这步漏掉,git commit会失败或提交不完整 -
git status会清楚列出 “both modified” 的文件,它是你检查是否漏add的最可靠依据
很多人卡在这一步,以为保存文件就完了,结果 git commit 报 “nothing to commit”,其实是还没 add。
谁动了远程分支?查日志比猜更快
如果不确定为什么远程变了,直接看:
git log --oneline --graph --all --decorate
或者更聚焦地查远程跟踪分支:
git log main..origin/main
这条命令会列出远程有、但你本地没有的提交,一眼看出是谁、什么时候、加了什么——比问同事快得多。
真正麻烦的是多人同时强制推送、或 CI/CD 自动合入了 PR 后又回退,这种场景下光靠 pull 不够,得先 git fetch 看清全貌,再决定用 merge 还是 rebase,甚至要联系协作者确认意图。


















