今天在合并分支的时候碰到了一个问题,情况是这样的,当前开发分支A , 合并了分支B,发现有冲突,于是就去改冲突,改好冲突后commit。但是此时老大提醒说提醒用另一中方法可能更好。于是就想退回去,重新改改试试。其实直接reset就好了。不过一查看到官网有篇文章是介绍这种情况的,正好就按他说的写一下。
文章地址:https://git-scm.com/blog/2010/03/02/undoing-merges.html
先说一下几个Git的基本知识:
- Git仓库有三个主要组成——工作目录,缓存区和提交历史。
- reset将一个分支的末端指向另一个提交。
- checkout 分支切换。
- revert撤销一个提交的同时会创建一个新的提交。
git revert
是个安全的方法。相比git reset
他不会改变现在的提交历史,因此git revert
可以用在公共分支上,而git reset
最好用在私人分支上。
下面说一下那篇文章介绍的撤销merge的方法:
Reset a Merge:
reset 到merge之前的commit,然后重新做之后的操作,不过这要求所有的协作者知道如何处理回退的head,如果这不是问题,或者只是本地分支,这是一个很好的解决方法。方法如下:
$ git checkout master
git reset --hard [要回退的commit的sha值]
简单暴力,不过很好用。
Reverting a Merge:
当 merge 以后还有别的操作和改动时,或者你的协作者在你merge之后又做了一些提交的时候,git 正好也有办法能撤销 merge。你可以使用revert命令。方法如下:
$ git resert -m [要撤销的那条merge线的编号] [merge前的版本号,即sha值]
Finished one revert.
[master 88edd6d] Revert "Merge branch 'jk/post-checkout'"
1 files changed, 0 insertions(+), 2 deletions(-)
这样会创建新的 commit 来抵消对应的 merge 操作,如果你尝试再次合并,Git会看到该分支上的提交是在历史记录中,并假设你错误地尝试合并你已经有的东西。
$ git merge jk/post-checkout
Already up-to-date.
Reverting the Revert
$ git revert [方法二撤销merge时提交的commit的版本号,这里是88edd6d]
Finished one revert.
[master 268e243] Revert "Revert "Merge branch 'jk/post-checkout'"" 1 files changed, 2 insertions(+), 0 deletions(-)
这样就可以正常的merge了,不过这可能会产生更多的冲突。
现在基本上重新介绍了我们以前撤回的分支中的一切。现在如果我们在这个分支上有更多的工作,我们可以重新合并它。
$ git merge jk/post-checkout
Auto-merging test.txt
Merge made by recursive. test.txt | 1 + 1 files changed, 1 insertions(+), 0 deletions(-)
写在最后
大致的看完之后,发现后面的方法太麻烦,简直是没事找事。不过作者可能完全是基于在公共分支改动的比较复杂的情况,总之,感觉还是在本地分支用reset最方便,或者revert也可以,别整的那个麻烦就行了。
最后分享一篇Git Community Book中关于git rebase 的文章,之前不太了解,感觉写的很好:http://gitbook.liuhui998.com/4_2.html