背景
将开发分支dev兼并进主分支main以后,假如发现bug需要回滚代码时,咱们常使用git revert完结操作,可是当咱们将dev上的bug修复之后想再把它合进main却会发现,dev上的功用代码合不进去了,原因是这些功用代码的commit现已在main分支上了(尽管被revert了,但仍在),所以git会回绝合进重复的commit。本人最近就遇到了这种问题场景,查阅网上材料推荐的做法一般是把main之前的revert再revert掉然后合dev,可是实际操作过程中却产生了如下错误:
不明就里,估计是由于多人协作导致main分支一日千里,revert操作产生了不行描述的抵触,翻看长串的git log已难以厘清… …但我决议不去深究这些细节,由于已想到更完美的解决方案!那便是利用git rebase -i将dev的commit们 squash(紧缩)为一个commit(首要意图是生成一个新的commit哈希),然后再去rebase main分支即可,实测效果拔群再也不必担心类似的问题了!
Demo复现该问题
- 初始状况:基于main分支切了dev分支并开发
- dev兼并到main后
- 发现bug,在main上进行回滚
- 在dev上做bugfix并测试OK
- dev从头兼并到main
到这儿问题来了,咱们期望得到的main分支效果应该相当于以下分支:
c0 <- c1 <- c2 <- c3 <- c4
但由于c2
c3
被revert掉(改动内容消失了),却现已存在于main上(从头兼并时main分支认为现已合过它俩,于是回绝重复引入c2
c3
),所以到第5步得到的效果实际相当于:
c0 <- c1 <- c4
这便是标题所说「Git Revert之后再次合代码无效」的问题
用Squash方式解决该问题
在上述Demo的过程4基础上改
1、切到dev履行git rebase -i,让它自己rebase自己,意图是把dev上多个commit squash(紧缩兼并)为一个commit,这个新commit将具有新的哈希值(这样main分支就不会回绝它了)
咱们期望将c2
c3
c4
兼并(即dev分支上完好的改变内容),假定c2
的哈希值为c2_hash
,需要履行以下shell命令
$ git checkout dev
$ git rebase -i c2_hash
2、弹出的vi编辑界面如下,根据提示squash掉dev上的commit
3、填写commit信息,dev squash完结,效果如下
4、再用dev去rebase main分支,此刻咱们能够彻底遗忘git revert的黑历史,就像将一个新鲜出炉的功用分支rebase主分支相同,有抵触解决抵触即可
5. 再次将dev兼并到main即可,完美收官!
小结
解决git revert副作用问题,网上干流的方法是:
- 在main分支找到之前revert的commit(可能有多个,假如是多人协作则还可能分散)
- 将之前的revert再次进行revert
- 合dev分支,解决抵触
本文介绍的方法是:
- 在dev分支上找功用代码触及的commit(开发分支上一般是连续的几个commit,简单找)
- 将这些commit紧缩兼并为一个
- dev分支rebase到main分支,解决抵触
个人比较倾向于本文这种做法,一则处理起来比较舒畅,彻底不必去关心之前的revert记录;二则看起来舒畅,处理完之后dev分支较main分支只会多一个commit,这个commit包括dev上的一切功用代码改变