rebase 之后 git push 被拒绝怎么办
rebase 改写已发布提交后可能与远程历史分叉,Git 会拒绝非快进推送。个人功能分支核对远端旧提交后可用显式 force-with-lease;共享分支应先协调,避免直接改写历史。
这是正常的保护机制:rebase 可能重写部分提交(未改变的提交或无操作变基并非都产生新哈希),你本地的分支与远程的旧历史产生分叉,Git 为防止覆盖远程提交而拒绝。如果这个功能分支只有你自己在用,用 git push --force-with-lease 强推即可;共享分支请改用 merge,不要 rebase。
安全强推
git push --force-with-lease
后台 fetch 会更新默认 lease 参照,削弱“已审阅”的保证;更严格时使用 --force-with-lease=refs/heads/feature:<已核对旧SHA> 并显式指定目标引用。
--force-with-lease 比 --force 安全:它在推送前检查远程分支是否还是你上次 fetch 时的样子——如果这期间有人推了新提交,推送会被拒绝而不是悄悄覆盖别人的工作。
为什么重写已发布历史后可能需要强推
rebase 前(远程): A---B---C feature
rebase 后(本地): A---B---C' feature(C' 是新哈希)
本地和远程的 feature 已经"分叉"。普通 push 要求快进(fast-forward),只有远端旧提交不再是本地新顶端的祖先时,才不能普通快进推送;未发布的提交变基或无需改写的情形不一定需要强推。
什么情况不要强推
- 分支有其他人协作(强推会把别人的工作冲掉);
- main/master、release 等受保护分支(GitHub 通常也禁止强推);
- 不确定时:换 merge 策略重来。
常见问题(FAQ)
Q:强推后同事的本地分支会怎样?
他们可能遇到历史分叉。应先保全未提交改动与本地提交,再协调重放到新基线;不能直接用 reset --hard 丢弃本地工作。这就是共享分支不该 rebase 的原因。
Q:--force-with-lease 也失败怎么办?
可能是远程引用不符合预期,也可能是权限、保护规则等限制,先查看具体错误。先 git fetch,git log HEAD..origin/feature 看看是什么,确认可以丢弃再强推,或者 merge 进来。
Q:想保持干净历史又怕强推,有折中吗?
有:rebase 只在合并回 main 之前对纯个人分支做;合并用 GitHub 的 "Squash and merge",既得到线性历史又无需强推共享分支。