git(三)之分支的使用以及合并

一、前言

这篇博文是建立在大家都已经正常使用git建立分支,并且可以切换使用的情况下。主要介绍分支的合并操作,git rebase与git merge之间的区别。

那么我们都知道git rebase和git merge都是用来合并两个分支的差异提交,即合并代码提交结果,但有什么区别呢,接下来就说一下我的看法。

二、正文

2.1引出分支

git当前很强大的分支。如图,这是当前在git上使用分支操作的一个很常见的情况,我们从master分支开始,在commit2节点引入1-F分支、并且在3节点引入2-T分支,每个分支都可以独立的前进,不受其他分支的影响。

使用分支开发能带来的好处想必大家也都很清楚:很轻松的对独立模块协作开发;处理临时bug等。

首先我们从协作开发说起来,场景就是每个人操作的分支进度都不一样。通常情况下在开发完毕之后,大家都是基于自己当前的分支向master提出合并请求,如果自己的分支领先master分支如图的2-T领先于master,直接提出merge request即可,进行合并;但如果分支又有落后又有领先呢,就需要先把别人已经推送至master的提交,先同步合并至本地。如何合并分支代码呢,我们都知道有两个命令可以合并两个分支的代码,merge和rebase,那到底两个有什么区别和使用场景呢。

git(三)之分支的使用以及合并

2.2分支合并——merge

首先是merge,字面意思就是合并,如下图所示,我们引入一个场景,master分支从2提交节点分别引出1-F和2-T的分支,并且分别前进了3,4,5,6的提交,这时候想从2-T拿到1-T分支的代码,就在2-T分支上执行merge 1-F。

git(三)之分支的使用以及合并

                                                                                  merge之前

这时候会执行的操作就是,对2-T的头部提交、1-F的头部提交、两个分支最近起始点,进行一个三方合并,做出差异对比形成一个单独的commit 进行提交,置于当前分支的头部,此时在使用git log时也能看到3456的提交,但真正起作用的只有7提交。于是形成了下图的情况。

git(三)之分支的使用以及合并

                                                                                            merge之后

2.3分之合并(变基)——rebase

rebase,字面是变基的意思,如图所示,依旧是这两个分支,  我们从2-T分支rebase1-F分支。

git(三)之分支的使用以及合并

                                                                                       rebase之前

执行rebase之后,变成了下图的情况,rebase其实做的就是找到两个分支的最近起始点,将起始点之后的被合并分支提交先拿掉,将合并分支(1-F)起始点之后的所有提交在当前分支“重现一遍”,之后把当前分支所有提交(5,6)在后面进行差异提交。

而由于5,6之前是分别在2,5的基础上进行的提交,而当前的2-T的提交则不一样了,因此5,6就会变成5’,6’。因此我们可以看到,当前的2-T分支,比rebase之前的分支,基础被变了,这个变基的命名还是挺形象的,2-T的历史都被修改了。

变基操作使分支提交历史相对merge很漂亮简洁,但会修改历史。这会导致什么呢,你当前本地2-T的分支的历史与远程的5-6历史不一致,导致远程不认识,因此无法提交至远程。而如果你把这个提交强行合并到远程,跟你一起在2-T上工作的伙伴们并没有误操作,但是就是提示历史有变动,2-T有问题。因此我们对于公共分支(即共同开发的分支,尽量不要使用变基),来自于官方文档的一句吐槽。

git(三)之分支的使用以及合并

                                                                                    执行rebase之后

2.4 fast-forawrd式的merge和rebase

以上是对rebase、merge两种合并代码方式的其中一个场景描述,但是大家不能就这么直观的判断,merge就是合并分支在最后加入新的commit吗?这是个误区。如下图所示,这是另外一个合并代码的应用场景。

git(三)之分支的使用以及合并

 

                                                                    rebase/merge之前

即从2-T分支拉取过1-F分支之后,1-F单独提交了3、4,而2-T保持不动,此时我们在对2-T进行merge以及rebase时,都默认只执行的是一个fast forward,快速合并,即2-T分支的head指针直接向前移动即可。

git(三)之分支的使用以及合并

                                                                            rebase/merge之后

当然也可以使用非fast forward的方式进行merge,即使用--no-ff参数,如图所示,把4和2进行差异对比,形成5的merge提交,即可成为有merge commit。

git(三)之分支的使用以及合并

                                                             使用git merge --no-ff 使用非fast forward方式的merge

 

三、结语

本篇博文对git分支使用中,rebase/merge的区别做出了总结以及fast-forward形式的合并方式。希望对大家的理解有所帮助。