简要分析git rebase 和 git merge区别以及使用场景

发布时间:2021-01-26 11:36:29编辑:文明阅读(1040)

    前段时间由于某种原因,开始接手开发公司前端Vue搭建的项目

    该前端项目采用的是基于git rebase的形式去合并代码,而我之前使用git一直都是采用merge的形式合并分支代码,对于rebase一概不知

    故此利用碎片时间学习整理一下关于git rebase的原理以及其和git merge的区别是什么,我会采用实际的案例描述二者的区别

    准备工作

    • git 客户端安装(只要git bash即可)

    • github上新建一个项目

    create project

    2

    • 项目clone到本地

    3

    clone完成以后进入该项目文件夹下,准备工作完毕

    模拟日常开发

    同学A:

    • 执行git log

    4

    可以看出此时该项目仅有一次提交记录

    • 执行新增文件a.txt,并本地提交一次后再次执行git log

    5

    这个时候打开github,刷新该项目的commit记录

    6

    发现远程仓库还是只有一次提交记录的,说明A同学还没有将自己最新的修改push到远程仓库,其他同学这个时候是看不到A的最新提交的

    • A同学将自己的最新提交Push到远程仓库

    7

    • 再次刷新github 提交记录,发现已经多了一个A同学提交的最新记录了

    image.png

    切分支开发

    • 基于已有两次提交记录的本地master分支检出一个新分支dev,并将该分支推到远程仓库

    8

    • 查看远程仓库,多了一个dev分支

    9

    • 此时本地的git分支图类似如下

    10

    A同学开发功能

    假设A同学基于dev分支开发功能,在本地新做了三次代码提交,git log
    如下


    image.png

    那么此时的git分支图如下

    image.png

    • 重点

    如果此时在A同学准备进行第四次本地提交之前,另一个同学B向远程仓库推送了一个master分支的提交,即此时master实际的提交已经向前走了

    我们这个时候在github上操作一次commit,模拟另一个同学此时push了master分支

    image.png

    • A同学本地更新一下master分支

    image.png

    发现master分支已经向前走了一次提交,此时的分支图如下

    image.png

    此时我们知道A同学开发的dev分支是基于C2提交点切出来的,而这个时候master分支已经被更新了

    如果A同学开发完毕,需要将其所作的功能合并到master分支 ,他可以有两种选择

    直接git merge

    如果A同学选择用git merge的方式进行合并dev到master分支,那么git会这么做

    1. 找出dev分支和master分支的最近共同祖先commit点,即C2

    2. 将dev最新一次commit(C5)和master最新一次commit(C6)合并后生成一个新的commit(C7),有冲突的话需要解决冲突

    3. 将以上两个分支dev和master上的所有提交点(从C2以后的)按照提交时间的先后顺序进行依次放到master分支上

    image.png

    git rebase 后再git merge

    1. rebase之前需要经master分支拉到最新

    2. 切换分支到需要rebase的分支,这里是dev分支

    3. 执行git rebase master,有冲突就解决冲突,解决后直接git add . 再git rebase --continue即可

    此时的git log如下

    image.png

    可以发现其一并没有多出一次commit,其二dev后面几次提交的commit hash值已经变了,包括C3,C4,C5

    1. 切换到master分支,执行git merge dev

    image.png

    发现采用rebase的方式进行分支合并,整个master分支并没有多出一个新的commit,原来dev分支上的那几次(C3,C4,C5)commit在rebase之后其hash值发生了变化,不在是当初在dev分支上提交的时候的hash值了,但是提交的内容被全部复制保留了,并且整个master分支的commit记录呈线性记录

    其分支图最终如下

    image.png

    总结

    • git merge 操作合并分支会让两个分支的每一次提交都按照提交时间(并不是push时间)排序,并且会将两个分支的最新一次commit点进行合并成一个新的commit,最终的分支树呈现非整条线性直线的形式

    • git rebase操作实际上是将当前执行rebase分支的所有基于原分支提交点之后的commit打散成一个一个的patch,并重新生成一个新的commit hash值,再次基于原分支目前最新的commit点上进行提交,并不根据两个分支上实际的每次提交的时间点排序,rebase完成后,切到基分支进行合并另一个分支时也不会生成一个新的commit点,可以保持整个分支树的完美线性

    另外值得一提的是,当我们开发一个功能时,可能会在本地有无数次commit,而你实际上在你的master分支上只想显示每一个功能测试完成后的一次完整提交记录就好了,其他的提交记录并不想将来全部保留在你的master分支上,那么rebase将会是一个好的选择,他可以在rebase时将本地多次的commit合并成一个commit,还可以修改commit的描述等

    最后

    如果你想要你的分支树呈现简洁,不罗嗦,线性的commit记录,那就采用rebase

    否则,就用merge吧


    作者:0爱上1
    链接:https://www.jianshu.com/p/6960811ac89c
    来源:简书
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


关键字gitrebasemerge

    还没有小伙伴评论,快来抢沙发啦~~!