多人协作遇到 Git push 冲突时,最推荐的做法是在本地执行 git pull `--rebase` 合并远程变更,解决冲突后再推送,避免使用 git push `--force` 覆盖他人提交。适用场景为公共分支协作,风险边界在于 rebase 过程中需手动解决代码冲突,不可强行跳过。
先说结论:优先使用变基(rebase)保持提交历史线性,严禁在公共分支直接强制推送。
- 先确认冲突类型为 remote 包含本地没有的提交
- 先处理本地变基合并并解决代码冲突
- 再验证推送结果确保历史未被覆盖
命令速用版
以下命令适用于标准分支协作场景,直接在冲突报错后的终端执行。
git fetch origin
git rebase origin/<分支名>
# 解决冲突后
git add .
git rebase `--continue`
git push origin <分支名>为什么会这样
Git 拒绝推送是因为远程仓库包含了本地没有的提交,直接推送会丢失他人代码。
当协作者 A 和 B 基于同一 commit 开发,A 先推送成功,B 再推送时,Git 检测到 B 的本地历史不是远程历史的子集(非快进式),为防止覆盖 A 的代码,服务端拒绝请求。使用 git pull `--rebase` 可以将本地提交“挪”到远程最新提交之后,保持历史线性且不留合并提交记录。
分步处理
按顺序执行以下步骤,确保每一步状态正确后再进行下一步。
第一步:获取远程最新状态
执行 git fetch origin 更新远程引用,不自动合并,确保本地知道远程最新 commit 位置。
第二步:执行变基操作
执行 git rebase origin/main(将 main 替换为实际分支名)。Git 会尝试将本地提交逐个应用到远程最新提交之上。
第三步:解决冲突
若终端提示 CONFLICT,打开冲突文件,保留需要的代码,删除冲突标记(<<<<<,=======,>>>>>)。执行 git add <文件> 标记解决,然后执行 git rebase `--continue`。若需放弃变基,执行 git rebase `--abort` 回滚。
第四步:推送代码
变基完成后,执行 git push origin <分支名>。此时本地历史领先远程,推送应成功。
怎么验证是否生效
推送成功后,需确认远程历史未丢失且本地状态干净。
检查提交历史
执行 git log `--oneline` `--graph` `--all`,确认本地分支 tip 与远程分支 tip 一致,且没有意外的合并 commit。
检查工作状态
执行 git status,输出应包含 nothing to commit, working tree clean,确保没有遗留的未提交变更或 rebase 状态。
常见坑
以下场景容易导致协作事故,操作前需额外谨慎。
严禁公共分支强制推送
除非团队明确约定,否则不要在 main/master 等共享分支使用 git push `--force`,这会删除他人已推送的提交。
二进制文件冲突
图片、编译产物等二进制文件冲突无法自动合并,rebase 时会报错。需手动选择保留本地或远程版本,避免文件损坏。
变基中途断电或中断
若 git rebase `--continue` 过程中中断,仓库会处于 detached 状态。执行 git rebase `--abort` 可恢复至变基前状态,再重新尝试。
常见问题
git push `--force` 会有什么后果?
强制推送会直接用本地历史覆盖远程历史,导致他人基于旧历史提交的代码丢失。
merge 和 rebase 解决冲突有什么区别?
merge 会生成一个新的合并提交节点,历史呈网状;rebase 会将本地提交移到远程之后,历史呈线性。
变基解决冲突后还能回滚吗?
可以,只要变基未完成,执行 git rebase `--abort` 即可回到变基前的状态。
多人同时修改同一行代码怎么办?
Git 会标记为冲突,必须人工打开文件决定保留哪一部分代码,无法自动处理。