在之前的文章当中我们介绍了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. React代码开发规范

    前言 一般在团队开发中每个人的代码习惯都不太一样,这样就会导致代码风格不一致,以致于维护和修改bug的时候看别人的代码成为一种痛苦...这种情况尤其在前端开发中尤为明显.因为关于前端的开发规范貌似也没 ...

  2. SQL Server 子查询遇到的坑

    这两天改 Bug 时使用 Sql Server 的子查询遇到了一些问题,特此记录一下,之前用 MySQL 比较多,按照 MySQL 的语法其实是没有问题的. 以下面这张表为例: 执行以下 SQL: s ...

  3. 用JTable 实现日历

    效果图: 主要思想:日历最核心的功能就是能显示某年某月对应的日期和星期几.因此只要实现传入具体的年份和月份,得到一组存放了日期的数组a[ ]即可.其中数组的大小设置成42,要考虑的问题是当月的第一天对 ...

  4. Mindmaster破解版与正版

    1 免费版与正版 MindMaster思维导图软件,免费版没有过期时间可以一直使用,导出或者保存的文件没有水印.免费版和专业版的不同之处在于,专业版可以享受全功能,比如导出为可编辑的PDF.Offic ...

  5. 我竟在arm汇编除法算法里找到了leetcode某道题的解法

    今天讲讲arm汇编中除法的底层实现.汇编代码本身比较长了,如需参考请直接拉到文末. 下面我直接把arm的除法算法的汇编代码转译成C语言的代码贴出来,并进行解析. 因为篇幅有限,所以在此只解析无符号整型 ...

  6. 02 C语言最简单快速上手的IDE

    不要让开发环境 成为学习路上的拦路虎,先培养学习兴趣和学习路上的成就感,这个对于激励自己持续学习很重要. 等真正从小白入门了,甚至成为大牛了,能解决诸多困难问题了,安装个开发环境还会再是个什么难事吗? ...

  7. [学习笔记] Tarjan算法求桥和割点

    在之前的博客中我们已经介绍了如何用Tarjan算法求有向图中的强连通分量,而今天我们要谈的Tarjan求桥.割点,也是和上篇有博客有类似之处的. 关于桥和割点: 桥:在一个有向图中,如果删去一条边,而 ...

  8. 多测师讲解自动化测试 _RF连接数据库_高级讲师肖sir

    RF连接数据库:1.Connect To Database(连接数据库)2.Table Must Exist(表必须存在)3.Check If Exists In Database(查询某条件是否存在 ...

  9. go 多协程爬取图片

    package main import ( "fmt" "github.com/antchfx/htmlquery" "golang.org/x/ne ...

  10. PowerShell 定时输出citrix desktop昨日连接会话

    asnp citrix*$now_date = [datetime]::Today$day2 = [datetime]::Today - [TimeSpan]::FromHours(24)$fiel_ ...