在之前的文章当中我们介绍了git merge的用法,明白了通过git merge我们可以合并两个分支的改动。这样我们就可以很方便地进行协同开发了,每个人都在自己的分支下开发代码,开发完毕之后再一起合并到master分支。通过这种方式可以保证大家的代码不会陷入混乱,但是这样有一个隐含的缺陷。

缺陷就是我们之前说过的,当我们合并两个没有上下游关系的分支时,git会自动替我们生成一个merge commit,记录此次的merge。记录merge操作没有什么问题,问题是如果我们遇到特殊情况需要反复merge的时候,就会导致commit的提交记录非常混乱,你根本分不清什么是什么。尤其是当你merge了一个巨大改动的分支之后,你的git log基本上就不用看了,肯定全都是其他人的各种乱七八糟你也不清楚的提交记录。

为了解决这个头疼的问题,我们就需要用到rebase操作。

rebase简介

rebase是一个非常强大的操作,可以实现一些神奇的功能,但是强大也意味着有隐患,因为如果使用得不好可能给团队的代码造成非常大的问题,成为团队当中被无情指责的背锅侠。所以我们在使用之前一定要先了解清楚原理,之后再小心谨慎地使用,否则很有可能会产生问题。

首先说说rebase的功能,rebase的功能说白了可以提取我们在A分支上的改动,然后应用在B分支的代码上,完成类似于补丁的功能。我这么说非常空洞,我从learngitbranching.js.org网站上截取了一些图,会清晰一些。另外推荐一下这个网站,当中有一些图形化的演示和实操功能, 我们可以在上面练习我们学到的git命令加深印象。但是它也有一个缺点,就是一些细节介绍得比较少,这也是我没有一开始的时候就推荐给大家的原因。

这张图非常经典,是很多场景下的常态。C1是线上的版本,在C1的代码上线了之后我们发现了一个bug,于是我们checkout了一个叫做bugFix的分支。与此同时还有新的功能在开发,新的功能提交到了master之后形成了节点C2。这个时候我们在bugFix分支当然可以merge master这没有什么问题,但是也可以rebase master,rebase之后整棵git树会变成这样:

这个结果就好像是我们先到了C2然后checkout出了bugFix分支,然后在bugFix分支上将之前写过的代码重新写了一遍。这样的操作就是变基,当我们rebase了之后再提交合并请求我们的合并记录里面会非常干净,没有多余merge的信息。对于多人协同开发的场景非常有帮助。

更牛的例子

上面只是一个rebase操作的基本应用,通过rebase操作我们还可以实现更加炫酷的功能。我们来看这样一张提交图:

这张图也非常经典,master是正常的线上分支,在C2节点处代码上线。上线之后继续开发新的需求checkout了新的分支feature,与此同时master也经过了一些合并,合并了另外的一些改动到了C4节点。之后新的分支feature开发完成了一个重要性能提升的改动C5,这时,我们发现了线上代码的一个bug并且性能不佳,我们需要紧急修复。于是在C5处checkout了新的分支bugFix,我们在bugFix分支当中修复了bug,想要发布上线。

这时候feature分支继续开发到了C6节点,仍然没有开发完成,也没有经过系统测试。所以我们并不希望C6的代码发布上线,我们希望合并进入master的代码之后C5,C7和C8。我们只需要在bugFix分支rebase到master,然后修复冲突之后提交。提交完成了之后,我们再checkout到master把bugFix分支merge进来。整个流程如下:

git checkout bugFix
git rebase master
git checkout master
git merge bugFix

最后我们得到的结果会是这样:

我们继续问一个问题,假如我们只需要合并bugFix分支自己的改动,不希望把C5节点也合并进来,我们应该怎么办?如果不用rebase会非常麻烦,我们很难处理。有了rebase之后非常简单,我们只需要使用onto参数,它可以限制我们rebase从什么地方开始。

比如我们希望rebase的内容是在bugFix这个分支当中不在feature分支里的内容,我们可以这么写:

git rebase --onto master feature bugFix

git执行这条命令的时候会先找到feature和bugFix的共同祖先,然后将共同祖先之后的部分rebase到master。

还有一个问题是如果我们要把两个分支合并进master,我们要rebase merge两次不免有些麻烦,我们也可以这么操作。比如我们要把刚才说的feature和bugFix都merge进来,我们可以直接执行git rebase master feature,它会先checkout到feature分支然后执行rebase master的操作,之后我们再checkout到master进行合并即可。也就是说我们在命令当中可以把要执行的执行分支和目标分支都写出来,这样可以一步到位。

比如我现在在master分支,我执行git rebase master bugFix之后会变成这样:

比我们自己一条一条命令写会方便很多。

总结

简单总结一下,我们使用rebase命令有很多好处,既可以让merge操作变得顺滑,减少没有意义的commit记录。也可以实现一些比较棘手的功能,但对于新手来说,这个功能还是比较陌生的,总是会觉得晕不知道自己到底做了什么。这也是非常正常的,我们可以在learngit这个网站上实际动手试试,多练习一下,这个网站的提交都是虚假的,怎么玩都不会出问题,总比我们在实际工作当中拿真实的代码来演练要好。

在下一篇文章当中我们将会一起来看看git rebase不能做什么,可能有的隐患。

今天的文章就到这里,衷心祝愿大家每天都有所收获。如果还喜欢今天的内容的话,请来一个三连支持吧~(点赞、关注、转发

原文链接,求个关注

本文使用 mdnice 排版

详解git rebase,让你走上git大神之路的更多相关文章

  1. <转>详解DNS的常用记录(上):DNS系列之二

    详解DNS的常用记录(上) 在上篇博文中,我们介绍了DNS服务器的体系结构,从中我们了解到如果我们希望注册一个域名,那么必须经过顶级域名服务器或其下级的域名服务器为我们申请的域名进行委派,把解析权委派 ...

  2. (转) shiro权限框架详解06-shiro与web项目整合(上)

    http://blog.csdn.net/facekbook/article/details/54947730 shiro和web项目整合,实现类似真实项目的应用 本文中使用的项目架构是springM ...

  3. Tomcat原理系列之六:详解socket如何封装成request(上)

    目录 参与者 总结 @(详解socket如何封装成request) 看源码虽然不能马上提升你的编码水平.但能让你更好的理解编程. 因为我们tomcat多是以NIO形式处理请求,所以本系列讲的都是NIO ...

  4. 详解Linux运维工程师高级篇(大数据安全方向).

    hadoop安全目录: kerberos(已发布) elasticsearch(已发布)http://blog.51cto.com/chenhao6/2113873 knox oozie ranger ...

  5. git 一口气带你走完git之旅

    1.git是目前世界上最先进的分布式版本控制系统.svn是集成式版本控制系统,那么问题来了,什么叫分布式管理和集中式管理? 首先,svn 需要有一个中央服务器,协同开发者需要同中央服务器连接,所有的版 ...

  6. git命令行 整理(一位大神给我的私藏)

    Evernote Export Git 是一个很强大的分布式版本控制系统.它不但适用于管理大型开源软件的源代码,管理私人的文档和源代码也有很多优势. Git常用操作命令: 1) 远程仓库相关命令 检出 ...

  7. 经典书Discrete.Mathematics上的大神

    版权声明:本文作者靖心,靖空间地址:http://blog.csdn.net/kenden23/,未经本作者同意不得转载. https://blog.csdn.net/kenden23/article ...

  8. 图文详解在Windows server 2008 R2上安装SQL Server 2012集群

    1.准备: 4台服务器(1台AD.2台SQL服务器.1台iSCSI存储服务器) 9个IP(1个AD的IP.2个SQL服务器的IP.2个心跳IP.1个iSCSI存储服务器的IP.1个集群IP.1个DTC ...

  9. PHP基础入门详解(一)【世界上最好用的编程语言】

       简介 --------- PHP(超文本预处器)是一种通用开源脚本语言.语法吸收了C语言.Java和Perl的特点,利于学习,使用广泛,主要适用于Web开发领域.PHP 独特的语法混合了C.Ja ...

随机推荐

  1. Git-使用Rebase合并分支

    commit 合并 在开发过程中,可能会出现多个 commit 所涉及的逻辑都是同一个功能模块,此时,会导致 log tree 非常的混乱,不美观,因此,我们可以将多个 commit 进行合并,变成一 ...

  2. Java基础——HashMap

    1.HashMap底层的实现 JDK 1.7 中 HashMap 是以数组+链表的形式组成的 JDK 1.8 之后数组+链表/红黑树的组成的,当链表大于 8 并且容量大于 64 时,链表结构会转换成红 ...

  3. tornado-简介和原理

    tornado-设计初衷 1. 追求小而精 2. epoll IO多路复用和协程 3. 支持WebSocket 4. 单线程程序(GIL限制,本身某种意义上不启动多进程就是单线程程序) # Pytho ...

  4. OpenCV计算机视觉学习(2)——图像算术运算 & 掩膜mask操作(数值计算,图像融合,边界填充)

    在OpenCV中我们经常会遇到一个名字:Mask(掩膜).很多函数都使用到它,那么这个Mask到底是什么呢,下面我们从图像基本运算开始,一步一步学习掩膜. 1,图像算术运算 图像的算术运算有很多种,比 ...

  5. 编程体系结构(06):Java面向对象

    本文源码:GitHub·点这里 || GitEE·点这里 一.基础概念 1.面向对象概念 面向对象编程的主要思想是把构成问题的各个事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙一 ...

  6. JS/TS 对数组中的对象按对象的值进行去重

    举个例子:对以下数组按 lastName 的值进行去重 let listData = [ { firstName: "Rick", lastName: "Sanchez& ...

  7. JDK 中的栈竟然是这样实现的?

    前面的文章<动图演示:手撸堆栈的两种实现方法!>我们用数组和链表来实现了自定义的栈结构,那在 JDK 中官方是如何实现栈的呢?接下来我们一起来看. 这正式开始之前,先给大家再解释一下「堆栈 ...

  8. Vue路由History模式分析

    Vue路由History模式分析 Vue-router是Vue的核心组件,主要是作为Vue的路由管理器,Vue-router默认hash模式,通过引入Vue-router对象模块时配置mode属性可以 ...

  9. Androng,一个针对Android的Pong克隆

    下载application from Android market 下载source - 532 KB 内容 IntroductionAndroid游戏开发 活动视图绘图使用CanvasAnimati ...

  10. 为Android(和其他移动平台)安装MoSync

    为Android(和其他移动平台)安装MoSync Android教程比赛 这是我提交的文章#2:设置你的Android开发环境.它的主要区别在于它描述了如何安装MoSync,这是一种开发环境,它不是 ...