本地分支与远程分支分叉了(diverged)怎么办
分叉说明两边都有对方没有的提交。查看分叉情况 git log --left-right --oneline main...origin/main;合并用 git pull(merge)或 git pull --rebase;确定远程为准则 git reset --hard origin/main。
"分叉"= 你本地有未推送的提交,同时远程也有你没有的提交。 两条路合并分歧:git pull --no-rebase(明确采用 merge)或 git pull --rebase(把你的提交挪到远程提交之后,历史线性)。如果确定远程是对的(比如你的本地改动是垃圾),先备份当前提交与未提交内容,再用 git reset --hard origin/main 对齐;下文假设当前就在 main 分支。
先看清分叉了什么
git fetch
git log --left-right --oneline main...origin/main
# < 开头:本地独有提交
# > 开头:远程独有提交
方案一:merge 合并(保留分叉事实)
git pull --no-rebase origin main # 或 fetch 后 git merge origin/main
# 解决冲突后 commit 推送
历史出现一个合并提交,真实反映"两条线汇合"。
方案二:rebase(历史线性)
git pull --rebase origin main
git push
你的本地提交被重放到远程提交之后,像是一直基于最新代码开发。仅重放未发布的本地提交时通常普通 push 即可;若改写了已发布历史,则需先协调再评估 --force-with-lease。
方案三:以一边为准
git branch rescue-before-align # 保存当前提交,不保存未提交文件
# 另行备份未提交内容后才执行:
git reset --hard origin/main # 远程为准,丢弃当前已跟踪改动
常见问题(FAQ)
Q:为什么会分叉?
常见原因:在两台机器上先后提交、网页端改了文件本地也改了、amend/rebase 改写了已推送的提交后又 pull。
Q:pull 时怎么默认用 rebase?
git config --global pull.rebase true。想严格保守用 pull.ff only(非快进就报错,逼你手动选策略)。
Q:强推覆盖了同事的提交怎么办?
先停止继续改写,寻找同事本地或 reflog 中仍存在的提交并建立救援分支;比较双方新增工作后协调恢复,不能再盲目反向强推。这是"覆盖远程"方案的危险所在。