1 问题
问题描述:
- 项目在gitbub页面上,生产分支(prod) 往 开发分支(dev)上合并时,有冲突,导致开发分支的代码全部上了生产分支
场景描述:
- 生产分支(prod) 修复了一些bug
- 开发分支(dev) 已经开发了一些新的功能
- 现在希望把prod分支上的修改merge到dev分支: prod -> dev,
2 原因
- 一旦两个分支merge时出现冲突,即使只有一个文件冲突,merge这个文件后,两个分支所有文件都会进行merge
- 如果没有冲突,dev分支上的代码是不会到prod分支上的
3 还原措施
- 这里是通过命令 git revert [commitId] -m [branchOrder], 对指定merge操作还原
- 1 目标:去掉生产分支(prod)上的新代码(dev上开发的新功能)
- 2 查看 prod分支的git history, 有一次merge叫 :Merge branch ‘dev’ into prod
- 3 使用命令:
git revert [此次merge操作的commitId] -m 1
注:这里 1 表示dev分支,是要把dev分支的改动去掉
特别注意:现在生产分支的代码比dev分支少,因为revert过了; 最关键的一点是,即使重新把dev merge到 prod分支,这部分代码也不会更新到prod分支(revert之后的代码,还是会被merge到 prod),因为revert 产生的结点更新,dev上的结点(commitId)排在后面,因此dev上早于这个结点的代码不会merge到prod分支.
- 因此,还原后,生产分支可能遗失代码.
- 解决代码可能在prod分支上遗失的问题
解决方式一:
- git push -f dev:prod
- 这个时候,你本地拉取不到最新的代码,因为本地commtId 比 现在prod的都新(来自于dev)
- git branch -D prod (不删除本地的prod, revert代码永远也回不来,因此要提醒其它同事注意这个问题)
- git checkout -b prod origin/prod
本地的代码就是github上面prod分支的代码(本质就是dev分支的代码)
解决方式二:
- 在生产分支上,找到上次revert对应的commitId , 进行revert
- git revert 【上次revert的commitId】
针对现在的场景,方式三最好,发完生产后,在合适的时间(这些revert的代码要上生产的时候)把这次revert 撤销,相当于推迟了之前那次merge- revert一般是为了删除不要的代码,但这里我们的代码是要的,只是时间不对而已
4 正确的处理
方式一
- 正确的做法应该是,每个热修复都应该cherry-pick到dev分支, 但当时是想着一次性把代码merge过来
- cherry-pick也可能产生冲突,因为修改的文件,可能dev分支也修改了,或者删除了,
- 我觉得冲突也要分情况,如果实在不好merge, 干脆到dev上重新改一遍, 最后force push到 pod分支
方式二
- 目标:生产分支(prod) merge to 开发分支(dev) 时,编辑冲突后,dev分支的代码,不会到prod上
- 操作方式:
-
1 把两个分支的最新代码都拉到本地(dev, prod)
-
2 切换到dev分支: git checkout dev
-
3 合并prod分支到dev: git merge prod
-
4 编辑冲突,推送代码: git push origin dev:dev
其实就是本地进行merge, 而不在github上去合并代码
-
5 从git history看分支合并
- 分支2 合并(merge)到 分支1
- 无冲突, 分支2无影响, 分支1合并分支2代码
- 有冲突, 处理冲突文件后,两个分支都会更新,分支2合并分支1代码,分支1合并分支2代码
下图是分支1的history