当前位置:   article > 正文

rebase 之前的代码_从零开始写git:理解rebase与merge

代码rebase什么意思

前文提要:国际劳动节,一起写一个linux初版的git吧

下文由 PioneerIncubator组织的yyellowsun与ZYZ合作而成。

rebase(变基)

git-rebase - Reapply commits on top of another base tip

——git官方文档

什么是rebase

git的初学者可能对rebase了解不深,它的使用频率没有pull、add、commit、push那么高,但了解rebase的使用还是有必要的,在一些场景下很可能会用到rebase。

rebase的直译就是变基,顾名思义就是改变基点,改变一串commits的基点,也就是把当前分支的一些commits拿下来,插在另一个分支的顶端。

文字描述会有一些抽象,用图来理解就很直观。

d271db643a91d31a8a76b988d4bcae5d.png

上图中左边的部分就是使用rebase命令之前的仓库状态,而右边则是使用rebase之后的状态,可以看出在rebase之后,原本的feature分支下的E、F两个commits都被“移动”到master分支的顶端了(事实上,这里并不是“移动”而是“复制”,具体见下文)。

rebase的工作原理

rebase并不是简单的将E、F两个commits从rebase前的位置直接移动到rebase后的位置,这样的“移动”更像是一种“”剪切“、粘贴”的过程,而真正的rebase工作流程则更像是一种“复制”、“粘贴”的过程。

git会将需要被“移动”的commits(E、F)在目标分支(master)上按相同的顺序重新再现一遍,也就是说git会在目标分支上创建新的提交,新提交的作者、注释、日期等信息会和原本的提交完全相同,也就相当于创建了一个原commit的一模一样的副本,将副本提交在目标分支上。而原先的commits其实依然会存在于历史版本中(存放在.git文件夹的objects目录下),可以通过commit的sha1值来找到它们,当git执行垃圾回收之后才会真正的从版本库中消失。

下图表示了rebase使用前后的真正结果:

8cb5cf43cf1f410202528d9fe9bb9896.png

可以看到旧的commits并没有消失,只是不再能简单的被访问或使用,我们知道一个分支其实只是指向一个提交的指针,因此如果没有branch或tag指向旧的commits(E、F),那么它们将无法再被访问和使用,但它们依然会存在于objects中。

总结一下rebase的执行步骤:

1.确定需要“移动”的提交:确认活动分支(feature)的哪些提交不在目标分支(master)上,这些提交就是需要rebase(变基)的提交2.确认新的基点:新的基点就是目标分支的HEAD指向的提交,也就是该分支的最新提交,这里就是D3.复制提交:将步骤1中确定要变基的提交复制一份,并按顺序提交在目标分支(master)上4.移动活动分支指针:让feature分支指向复制好的目标分支上的最后一个提交,这里是F'

以上就是rebase的工作原理。


与rebase有类似功能但实际很不一样的是merge。

Merge(合并)

Merges one or more branches into your current branch and automatically creates a new commit if there are no conflicts. ——git官方文档

什么是merge

merge的意思是合并,就是将不同的branch合并,形象的比喻就是把不同的河流汇聚成一条大河。

merge的工作原理

Merge做的事情很简单,就是把两个不同的branch给合并,然后自动创建一个新的commit。从git object角度来看,merge创建的commit很特别,一般来说一个commit会有一个记录它的父节点的哈希值,但是merge创建的commit会有两个记录它父节点的哈希值,因为它是合并两个branch得到的,所以会有两个。

rebase和merge的区别

289816d5e253c69d57ef6592ed0b82ce.png

我们有两个branch,jen/master和master,jen/master是我们clone别人的库默认得到的一个branch,master是我们的本地branch。你想合并两次最近的commit,于是merge了两个分支得到了一个新的commit叫做C2.

我们可以注意到:无论是你的commit,还是别人的commit,都只有一个箭头指向上一次的commit,但是merge之后的新的commit是有两个箭头指向合并的两个branch。而且merge会自动创建一个新的commit

ef0d394a3135290ef5fe3b1d9ca01a2b.png

同样是上述情形,如果执行rebase,则C1会变成孤儿commit被回收掉,C2只有一个箭头指向最新的一次的commit,C2。

一图以蔽之:

4e26d37add482aea8131ded7a0bdff48.png

Merge和Rebase最大的不同:

两者做的最终效果都是合并,但是从git object可以看到两者显著的区别。merge得到的commit对象会指向两个commit(也就是合并的两个branch所指向的commit),而rebase得到的commit对象只会指向一个commit。(但是知道这个并没有卵用)

谈谈merge和Rebase的优缺点:

优点缺点
Merge可以记录所有的commit记录,而且merge默认自动创建一个新的commit。如果多次merge,可以看到分支很杂乱。
Rebase"优化"一些不必要的commit,合并之前的commit历史,commit记录会显得是线性的,简洁的被”优化“了的commit会变成孤儿commit,再也找不到了。如果rebase之后产生bug,不容易定位。

何时使用merge和rebase呢?

一般来说,个人独立开发一个项目,merge/rebase的区别并不是很明显。但是如果和他人合力开发项目时,

在个人开发的分支上面,推荐使用rebase有如下好处,

1.净化历史,这也是使用rebase的最重要的原因,使用rebase变基后再合并代码,就会使得个人开发的分支上不会出现交叉情况,就是一条线往下走,这样就易于维护和管理。2.可以删除commit,合并commit,移植分支,可以把一个分支上的一些提交移植到另一个分支上。达到简化commit树,方便后面与他人的分支在merge时更有条理。3.在自己的分支开发时,同步到最新的master的代码,都用rebase而不是merge。因为merge会让代码变得很难看。

在公共分支上面,推荐使用merge有如下好处:1.完整记录每一个commit,方便他人查找commit历史。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/631362
推荐阅读
相关标签
  

闽ICP备14008679号