答案是本地分支落后于远程分支,Git为防止历史覆盖而拒绝推送;根本原因是远程已有本地缺失的提交,需先git pull同步再push,或用git pull --rebase保持线性历史,严禁随意--force。

git push 被拒:提示 “behind its remote counterpart”
这是最典型的本地分支落后场景,git push 直接失败,错误信息里明确写着 “your current branch is behind its remote counterpart”。Git 拒绝推送,不是因为你写错了命令,而是它在保护远程历史不被意外覆盖。
根本原因只有一个:远程分支有你本地没有的提交(比如同事刚 push 了新代码)。此时不能硬推(git push --force),除非你确认远程那些提交可以丢弃——绝大多数情况下不该这么做。
- 先运行
git status,看当前分支名和是否干净 - 再执行
git fetch origin,只拉取元数据,不改动工作区 - 用
git log HEAD..origin/your-branch-name --oneline确认落后多少提交(把your-branch-name换成你实际的分支名)
git pull origin branch-name 合并更新
git pull origin branch-name 是最常用、最安全的同步方式。它等价于 git fetch origin + git merge origin/branch-name,自动完成拉取和合并两步。
注意:如果你当前不在目标分支上,得先 git checkout branch-name;如果已 checkout,直接 pull 即可。
- 成功时会看到类似
Merge made by the 'recursive' strategy的提示 - 失败时出现
CONFLICT,说明有文件冲突,需手动编辑标记(<<<<< HEAD和>>>>> origin/xxx之间) - 解决后必须
git add <file>+git commit,才能算完成合并 - 最后
git push推送合并结果(如果绑定了上游,不用写完整 refspec)
git pull --rebase origin branch-name 保持线性历史
如果你希望提交历史是直的、没有多余的 merge 提交,用 --rebase 更合适。它不会创建合并节点,而是把你本地的提交“重放”到远程最新提交之后。
但要注意:rebase 会改写你本地的提交 SHA,如果这些提交已经推过远程,再 rebase 后必须 git push --force-with-lease(不是 --force),否则可能覆盖别人的工作。
- 执行前确保没推送过本地提交,或确认没人基于它们继续开发
- rebase 过程中遇到冲突,解决后用
git add <file>,再git rebase --continue - 想放弃整个 rebase?用
git rebase --abort - 完成后直接
git push即可(前提是之前已用-u设置过 upstream)
远程新建了分支,本地怎么同步出来
同事在远程新建了 feature/login,你在本地 git branch -a 却看不到它?因为 git fetch 默认只更新已知远程分支的引用,不会自动创建本地跟踪分支。
正确做法分两步:先刷新远程分支列表,再创建本地分支并建立追踪关系。
- 运行
git fetch origin或更彻底的git remote update origin -p(-p会清理已删除的远程分支) - 查看远程分支:
git branch -r,确认origin/feature/login已存在 - 创建并切换本地分支:
git checkout --track origin/feature/login(推荐)或git checkout -b feature/login origin/feature/login - 之后在这个分支上,
git pull和git push都能直接用,无需指定远程和分支名
真正容易被忽略的是:git fetch 本身不改变任何本地分支指针,它只是把远程的最新状态“下载”到 origin/xxx 引用里;真正让本地分支动起来的,是后续的 merge、rebase 或 checkout --track。很多人卡在这一步,以为 fetch 就等于同步完成了。


















