赞
踩
前文提要:国际劳动节,一起写一个linux初版的git吧
git-rebase - Reapply commits on top of another base tip
——git官方文档
git的初学者可能对rebase了解不深,它的使用频率没有pull、add、commit、push那么高,但了解rebase的使用还是有必要的,在一些场景下很可能会用到rebase。
rebase的直译就是变基,顾名思义就是改变基点,改变一串commits的基点,也就是把当前分支的一些commits拿下来,插在另一个分支的顶端。
文字描述会有一些抽象,用图来理解就很直观。
上图中左边的部分就是使用rebase命令之前的仓库状态,而右边则是使用rebase之后的状态,可以看出在rebase之后,原本的feature分支下的E、F两个commits都被“移动”到master分支的顶端了(事实上,这里并不是“移动”而是“复制”,具体见下文)。
rebase并不是简单的将E、F两个commits从rebase前的位置直接移动到rebase后的位置,这样的“移动”更像是一种“”剪切“、粘贴”的过程,而真正的rebase工作流程则更像是一种“复制”、“粘贴”的过程。
git会将需要被“移动”的commits(E、F)在目标分支(master)上按相同的顺序重新再现一遍,也就是说git会在目标分支上创建新的提交,新提交的作者、注释、日期等信息会和原本的提交完全相同,也就相当于创建了一个原commit的一模一样的副本,将副本提交在目标分支上。而原先的commits其实依然会存在于历史版本中(存放在.git文件夹的objects目录下),可以通过commit的sha1值来找到它们,当git执行垃圾回收之后才会真正的从版本库中消失。
下图表示了rebase使用前后的真正结果:
可以看到旧的commits并没有消失,只是不再能简单的被访问或使用,我们知道一个分支其实只是指向一个提交的指针,因此如果没有branch或tag指向旧的commits(E、F),那么它们将无法再被访问和使用,但它们依然会存在于objects中。
总结一下rebase的执行步骤:
1.确定需要“移动”的提交:确认活动分支(feature)的哪些提交不在目标分支(master)上,这些提交就是需要rebase(变基)的提交2.确认新的基点:新的基点就是目标分支的HEAD指向的提交,也就是该分支的最新提交,这里就是D3.复制提交:将步骤1中确定要变基的提交复制一份,并按顺序提交在目标分支(master)上4.移动活动分支指针:让feature分支指向复制好的目标分支上的最后一个提交,这里是F'
以上就是rebase的工作原理。
Merges one or more branches into your current branch and automatically creates a new commit if there are no conflicts. ——git官方文档
merge的意思是合并,就是将不同的branch合并,形象的比喻就是把不同的河流汇聚成一条大河。
Merge做的事情很简单,就是把两个不同的branch给合并,然后自动创建一个新的commit。从git object角度来看,merge创建的commit很特别,一般来说一个commit会有一个记录它的父节点的哈希值,但是merge创建的commit会有两个记录它父节点的哈希值,因为它是合并两个branch得到的,所以会有两个。
同样是上述情形,如果执行rebase,则C1会变成孤儿commit被回收掉,C2只有一个箭头指向最新的一次的commit,C2。
两者做的最终效果都是合并,但是从git object可以看到两者显著的区别。merge得到的commit对象会指向两个commit(也就是合并的两个branch所指向的commit),而rebase得到的commit对象只会指向一个commit。(但是知道这个并没有卵用)
优点 | 缺点 | |
Merge | 可以记录所有的commit记录,而且merge默认自动创建一个新的commit。 | 如果多次merge,可以看到分支很杂乱。 |
Rebase | "优化"一些不必要的commit,合并之前的commit历史,commit记录会显得是线性的,简洁的 | 被”优化“了的commit会变成孤儿commit,再也找不到了。如果rebase之后产生bug,不容易定位。 |
一般来说,个人独立开发一个项目,merge/rebase的区别并不是很明显。但是如果和他人合力开发项目时,
在个人开发的分支上面,推荐使用rebase有如下好处,
1.净化历史,这也是使用rebase的最重要的原因,使用rebase变基后再合并代码,就会使得个人开发的分支上不会出现交叉情况,就是一条线往下走,这样就易于维护和管理。2.可以删除commit,合并commit,移植分支,可以把一个分支上的一些提交移植到另一个分支上。达到简化commit树,方便后面与他人的分支在merge时更有条理。3.在自己的分支开发时,同步到最新的master的代码,都用rebase而不是merge。因为merge会让代码变得很难看。
在公共分支上面,推荐使用merge有如下好处:1.完整记录每一个commit,方便他人查找commit历史。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。