Git merge与rebase使用区别

Git合并分支的操作可以分为两种,merge和rebase,之前的工作中都是只使用merge,没有使用过rebase,现在在这里总结下两者的区别。
结论先说:推荐在将主干代码合并到自己分支上时使用rebase而非merge。在公共代码库中不使用rebase。
一、merge
merge这种合并方式会保留所有commit,并按照时间顺序排列。工作流程如下所示:

如果c3->c5->c4->c6是这几个commit的时间顺序的话,在log中,他们就会按照这个顺序排列,然后最后是c7这个提交,他包括了merge的信息。
对于merge方式合并,我进行了一次简单试验:git log如下所示

因为试验比较简单,所以看起来还可以接受,但是,时间久了的话,他有可能是这样的(还能接受吗?):

二、rebase
rebase这种合并方式会将自己分支的所有提交删除,作为一个patch保存到主干代码的所有commit之后,效果看起来就是把自己分支的所有提交统一转移到了主干代码的commit之后。工作流程如下:

图中可以看到c5和c6提交被”转移”到了主干代码commit的后面。
同样,对rebase方式合并进行试验,git log如下:

由此可见,以rebase方式合并主干代码,可以使代码历史更加清晰,代码历史会呈现出一个线性的状态,而非merge那样看起来很混乱。
所以推荐大家在团队git工作流中,使用rebase方式合并主干代码
三、merge与rebase进行合并的异同
1.merge方式进行合并,合并后会有一个包含merge信息的commit(在merge表现为c7)。而rebase方式进行合并则没有。
2.merge方式进行合并,各个commit会按照时间排序。而rebase虽然保留了commit的时间,但是将所有本地commit放到了合并分支的后面。
3.merge方式进行合并,可以通过git log方便的reset到本地某一节点(不包含合并分支中的代码)。而rebase方式进行合并,需要通过git reflog来找到rebase之前的commit节点进行reset,不太方便。因此建议在rebase主干代码前,创建一个备份分支。
4.rebase方式可以进行一些高级的合并方式,包括只提交部分commit、将多个commit合成一个commit进行提交、修改commit信息等等。
四、注意事项
由于rebase可以实现一些高级功能、可以修改提交历史,因此在公共代码库中应该禁止使用rebase操作:参考链接(rebase的风险