merge和rebase详解

2014-04-06 GitHub不完全装B指南

前天的文章当中讲了merge和rebase的区别,当晚@ョァャオ 同学就提出了疑问。昨天晚上@yakiang  同学也告诉我文章中有错误。


感谢这两位同学!


我仔细的搜了一下之后才发现,确实错了,而且是大错特错。


今天就专门写一篇文章来弥补一下。


先说merge:


假设当前工作分支为master,另一个分支为B,我们运行"git merge B",效果是把B分支上从分支点开始的改动都合并到master上。为什么是从分支点开始呢?因为分支点之前根本就没有B分支。。。


运行完命令之后,分支B是不会消失的,这里我之前讲错了。


运行结果:




下面看rebase:


rebase不太好懂,大家一定要仔细看。


假设当前工作分支为master,另一分支为B,运行"git rebase B"之后会发生三件事:

  1. 把master分支自分支点之后的所有commit撤销,并把它们暂存起来,也就是说把master分支回退到分支点

  2. 把B分支自分支点之后的所有更改全部应用到master分支

  3. 把第一步暂存的更改再应用到master分支


好像有点乱是吧,我解释一下。


base的意思是“基础”,我们可以理解为“开始”。

而rebase的意思,就是“重新设定开始”。


看图:

灰色是运行之前的状态,B分支和master分支分别指向不同的版本,它们的分支点是B点。


运行之后,master生成了一个新的版本E,大家看出来区别了吗?


B分支并没有发生改变,它仍然指向C版本,它的分支点也还是B点。


master分支生成了一个新版本E,我们可以理解,因为合并了修改嘛。但是请注意,master的分支点变成了C


现在大家理解为什么这条命令叫rebase了吧,因为它把当前分支的分支点移动到了另一个分支指向的点!所以叫做“重新设定开始”。


现在我们也可以理解,为什么rebase要先把本分支的更改撤销并暂存,然后应用另一个分支的更改,然后再把本分支的更改应用。因为我们要实现“移动分支点”,就必须走这三步才行!


好了,现在大家清楚了吧~


最后说说应用场景。


两者都可以实现合并,不过merge合并完之后,我们从master分支只能看到一条新的commit历史。也就是说我们并不知道在B分支一共有多少commit。这在公司当中可能会涉及到计算工作量的问题,大家要注意。rebase就不会出现这个问题,因为它是一个一个commit应用上去的,所以可以看到所有的commit记录。


其实这两条命令并没有绝对的应用场景,很多时候两者都是可以互换的。关键是大家要明白两个命令的工作机制,这样在实际工作中就可以选择最合适的命令了。

举报


当前位置: 传送门 ›› GitHub不完全装B指南