两人同时修改Git提交历史时如何同步仓库保留双方改动
多人协作重写Git提交历史后的同步方案
不要直接执行普通git pull或git pull --rebase,该操作会将旧提交链中已被重写废弃的提交全部重复叠加到新链上,产生大量冗余提交和无意义冲突,按以下步骤操作即可完整保留双方改动:
- 操作前先打备份标签,执行
git tag backup-before-sync,后续如果操作失误可随时通过git reset --hard backup-before-sync回到操作前状态,不会丢失本地改动。 - 执行
git fetch origin拉取远程最新的提交记录,不要做合并或rebase操作,此时本地origin/<目标分支名>会指向已经重写后的远程最新提交链。 - 定位本地独有提交的分叉起点:找到你本地开始做自有修改前的最后一个公共提交(也就是重写历史前,你和远程分支对齐的最后一个提交,比如场景中的旧H提交),可以通过
git reflog查看历史操作记录快速定位该提交的hash,记为<old-base-commit>。 - 执行带
--onto参数的定向rebase,命令格式如下:git rebase --onto origin/<目标分支名> <old-base-commit> <当前本地分支名>
该命令的作用是:将本地分支中,所有在<old-base-commit>之后的自有提交(对应场景中的H2、I2、J2、K2),整体裁剪下来,依次拼接到远程最新的重写后提交链的尾部,不会带入旧链中已经被废弃的D、E、F、G等提交。 - 处理rebase过程中的冲突:
- 出现冲突时,手动编辑冲突文件,同时保留双方的有效改动
- 冲突解决后执行
git add <冲突文件路径>标记冲突已处理 - 执行
git rebase --continue继续rebase流程 - 如果遇到和新链中完全重复的提交(比如对应改动已经被squash到前面的重写提交中),执行
git rebase --skip跳过该提交即可
- rebase完成后,核对本地提交链和代码内容,确认无误后执行
git push --force-with-lease推送到远程即可,不要使用普通git push,也尽量不要用裸--force参数,--force-with-lease会自动校验远程分支在你操作期间是否有新的推送,避免覆盖其他人的新改动。
额外建议:做这类大规模提交重排、squash操作前,最好提前和团队协作者约定临时冻结该分支的推送,等重写完成强推到远程后,再通知所有人按上述步骤同步本地分支,能大幅减少冲突处理成本。
内容的提问来源于stack exchange,提问作者Kushan Shekhar
相关产品推荐
相关产品推荐

