git revert 详解以及产生的问题

1,397 阅读2分钟

如图,比如当我们将dev 合并到master后,发现代码有bug需要回退,而我们此时又不希望使用git reset的时候(因为此时有可能master已经超前dev多个版本了),此时就需要使用到git revert(反造),所谓反造,就是对某一个commitID的提交进行反向操作,增加的文件会被删除,修改会被还原,此时注意会在master上形成一个新的提交,而不像reset回滚提交的代码,这个新的提交会把某一个提交的代码进行反造,形成一个新的提交到master上。

但是,使用git revert需要注意以下问题,直接例子

  • 1.merge dev到master
  • 2.过了若干时间后,在C4时突然发现当初合并进master的dev的M1代码有问题,此时对master上的M1进行revert(反造),形成一个新的提交W1在master上,此时M1提交的代码已经被W1所反造了,相当于把M1的代码进行了回滚
  • 3.好了,既然是dev的问题,切换回dev进行若干个版本(c,d)的开发后,把之前的bug修复
  • 4.dev修复完bug后,重新把dev的代码merge进master,但是,此时问题来了,M2的合并完成后的代码是不包含dev分支上的a,b两个提交的代码,为什么呢?因为当git merge某个分支的代码时,只会合并分支没有合并过的提交,如图,git判断到a,b两个提交的代码已经在M1合并过了,所以在M2进行合并时,只会把c,d的两个提交的变更合并的到master上,但是我们在W1时,又把之前M1提交的a,b两个提交进行了反造,所以在M2将dev merge进master时,会丢失,a,b这两个提交。

怎么解决呢,先上图

方案一: 在dev修复完bug后,执行git merge dev之前,先对W1的revert(反造)再进行一次revert(反造),相当于把在W1删除的M1的变更又添加了回来,这时再执行git merge dev就不会丢失a,b两次提交的变更了

方案二: 在dev修复完bug后,先将dev以master进行rebase(变基),因为rebase后,a,b两次的提交的commitID,已经和M1时merge进master的commitID不一样了,此时再执行git merge dev,git判断到dev上a,b,c,d的commitID均没有在master上出现过,就会把dev上所有的代码都合并到master

方案三: 在dev修复完bug后,使用cherry-pick 手动把,dev上的a,b,c,d的代码都合并到master上,形成4个新的commit,这样也不会丢失a,b的变更。