引言

网上有太多讲rebase和merge的文章,但大多都是复制粘贴没有自己的理解,而且很多博客的例子写的过于复杂,让人没兴趣看下去。根据奥卡姆剃刀原则,本文举最简单例子,大白话几句就让你快速掌握rebase的核心原理和用法。

本博客将持续修订更新,看完如果还是有疑问,可以评论区留言,我解释到你彻底搞懂为止!
最新更新:2022.11.3


一、提交节点图解

首先通过简单的提交节点图解感受一下rebase在干什么

构造两个分支master和feature,其中feature是在提交点B处从master上拉出的分支

master上有一个新提交M,feature上有两个新提交C和D

此时我们切换到feature分支上,执行rebase命令,相当于是想要把master分支合并到feature分支(这一步的场景就可以类比为我们在自己的分支feature上开发了一段时间了,准备从主干master上拉一下最新改动。模拟了git pull --rebase的情形)

# 这两条命令等价于git rebase master feature
git checkout feature
git rebase master

下图为变基后的提交节点图,解释一下其工作原理:

  • feature:待变基分支、当前分支
  • master:基分支、目标分支

官方原文解释(如果觉得看不懂可以直接看下一段):当执行rebase操作时,git会从两个分支的共同祖先开始提取待变基分支上的修改,然后将待变基分支指向基分支的最新提交,最后将刚才提取的修改应用到基分支的最新提交的后面。

结合例子解释:当在feature分支上执行git rebase master时,git会从master和featuer的共同祖先B开始提取feature分支上的修改,也就是C和D两个提交,先提取到。然后将feature分支指向master分支的最新提交上,也就是M。最后把提取的C和D接到M后面,注意这里的接法,官方没说清楚,实际是会依次拿M和C、D内容分别比较,处理冲突后生成新的C’和D’。一定注意,这里新C’、D’和之前的C、D已经不一样了,是我们处理冲突后的新内容,feature指针自然最后也是指向D’

通俗解释(重要!!):rebase,变基,可以直接理解为改变基底。feature分支是基于master分支的B拉出来的分支,feature的基底是B。而master在B之后有新的提交,就相当于此时要用master上新的提交来作为feature分支的新基底。实际操作为把B之后feature的提交先暂存下来,然后删掉原来这些提交,再找到master的最新提交位置,把存下来的提交再接上去(接上去是逐个和新基底处理冲突的过程),如此feature分支的基底就相当于变成了M而不是原来的B了。(注意,如果master上在B以后没有新提交,那么就还是用原来的B作为基,rebase操作相当于无效,此时和git merge就基本没区别了,差异只在于git merge会多一条记录Merge操作的提交记录)

上面的例子可抽象为如下实际工作场景:张三从B拉了代码进行开发,目前提交了两次,开发到D了;李四也从B拉出来开发了并且开发完毕,他提交到了M,然后合到主干上了。此时张三想拉下最新代码,于是他在feature分支上执行了git rebase master,即把master分支给rebase过来,由于李四更早开发完并合了主干,如此就相当于张三是基于李四的最新提交M进行的开发了。


二、实际git提交示例

我这里严格按照上面的图解,构造了实际的git提交示例(注意,这里重新贴了新图,之前的图逻辑上还是不够清晰)

如下图所示,ABM是master分支线,ABCD是feature分支线。

此时,在feature分支上执行git rebase master后,会提示有冲突,这里是关键,之前没有把这个细节说清楚。冲突其实也简单,因为我们要生成新的C’和D’嘛,那C’的内容如何得到呢?照搬C的?当然不是,C’的内容就是C和M两个节点的内容合并的结果,D’的内容就是D和M两个节点的内容合并的结果。我们手动处理冲突后,执行如下命令即可:

# 先处理完C,会继续报D的冲突,所以下面命令一共会执行两次
git add file
git rebase --continue

变基完成以后如下图所示,ABM还是没变化,ABMC’D’是rebase完成后的feature节点图,私以为讲到这里就还是比较清楚了


三、推荐使用场景

搞来搞去那么多,这其实是最重要的。不同公司,不同情况有不同使用场景,不过大部分情况推荐如下:

  1. 自己单机的时候,拉公共分支最新代码的时候使用rebase,也就是git pull -r或git pull --rebase。这样的好处很明显,提交记录会比较简洁。但有个缺点就是rebase以后我就不知道我的当前分支最早是从哪个分支拉出来的了,因为基底变了嘛,所以看个人需求了。总体来说,即使是单机也不建议使用,确实有点绕啊QAQ
  2. 往公共分支上合代码的时候,使用merge。如果使用rebase,那么其他开发人员想看主分支的历史,就不是原来的历史了,历史已经被你篡改了。举个例子解释下,比如张三和李四从共同的节点拉出来开发,张三先开发完提交了两次然后merge上去了,李四后来开发完如果rebase上去(注意李四需要切换到自己本地的主分支,假设先pull了张三的最新改动下来,然后执行<git rebase 李四的开发分支>,然后再git push到远端),则李四的新提交变成了张三的新提交的新基底,本来李四的提交是最新的,结果最新的提交显示反而是张三的,就乱套了。
  3. 正因如此,大部分公司其实会禁用rebase,不管是拉代码还是push代码统一都使用merge,虽然会多出无意义的一条提交记录“Merge … to …”,但至少能清楚地知道主线上谁合了的代码以及他们合代码的时间先后顺序

四、总结

无论是个人开发,还是公司协作开发,只要没有特殊需求,用merge准没错!!

参考文章:图解 Git 基本命令 merge 和 rebase

git rebase详解(图解+最简单示例,一次就懂)相关推荐

  1. git merge 和 git rebase详解

    git merge 和 git rebase 都是用来合并两个分支的. git merge b   #把b分支合并到当前分支 git rebase b   #把b分支合并到当前分支 --------- ...

  2. Git 原理详解及实用指南

    Git 原理详解及实用指南 什么是版本控制系统(VCS) 很多人认为 Git 难以理解的第一个门槛在于:所谓的「Git 是一个分布式版本控制系统」这句话的具体含义不够清楚.其实分布式版本控制系统(Di ...

  3. GitHub使用教程详解(下)——Git的安装以及Git命令详解

    上一篇GitHub使用教程详解(上)--官网操作指南[翻译],是针对官网的guide进行了翻译,其实个人来说,我是很不喜欢那么操作的,又要等待页面加载,操作又慢!程序员嘛,还是直接敲入命令代码更迅速高 ...

  4. git命令详解( 四 )

    此篇为git命令详解的第四篇,话不多说,我们直接上知识点好吧 git Push 偏离的工作 gitPush: 此命令负责将你的变更上传到指定的远程仓库,并在远程仓库上合并你的新提交记录.一旦 git ...

  5. git 原理详解及实用指南_如何编写良好的提交消息:实用的Git指南

    git 原理详解及实用指南 To create a useful revision history, teams should first agree on a commit message conv ...

  6. 人工智能里程碑ChatGPT之最全详解图解

    人工智能里程碑ChatGPT之最全详解图解 1. ChatGPT的前世今生 1.1 ChatGPT演化路线 1.2技术推进路线 2.ChatGPT主要功能及应用领域 2.1 主要功能 2.2 应用领域 ...

  7. git amend详解和撤销

    git amend 详解和撤销 git amend详解 git amend 作用 git amend如何撤销 git amend详解 git amend 作用 git 在现在的开发中使用频繁,解决了很 ...

  8. java开发中常用的Git命令详解

    java开发中常用的Git命令详解(IDEA内如何操作) 一:写这篇文章的目的是什么? 二:使用场景在哪里? 1:当我们要使用idea去git仓库拉代码时,首先我们的idea得配置git工具 2:项目 ...

  9. 区块链技术用解决拜占庭将军问题_两军问题_拜占庭将军问题详解图解算法

    两军问题 我们来看一下好处理器的情况,但通信线路有问题.这就是所谓的两军问题,可以概括如下: A,B 两军师协同攻击敌军C, A和B在物理上是分开的,并使用信使进行通信. A向B发送一个消息" ...

  10. php中的装饰,详解PHP装饰模式的示例代码

    详解PHP装饰模式的示例代码<?php // 装饰模式 function echoLine($msg) { echo $msg, ' '; } class RequestHelper { /** ...

最新文章

  1. Linux运维笔记-文档总结-NFS文件共享(网络文件系统)
  2. 墙面也能变镜子,只看影子就能还原视频,MIT新算法让摄像头无死角
  3. TensorFlow alexnet在华为Mate10上运行方法
  4. Android模拟器无法上网问题
  5. python学习笔记(八)——继承
  6. “ShardingCore”是如何针对分表下的分页进行优化的
  7. React后台管理系统-file-uploader组件
  8. 为什么我的文章总是没人回复
  9. Android中SlidingDrawer介绍【安卓进化三十四】
  10. Qt容器类之三:通用算法
  11. 好程序员Java分享JVM类加载机制
  12. 读嵌入式linux驱动程序设计从入门到精通 3
  13. 对话西蒙斯:解密金融模型和量化投资帝国
  14. 个人笔记本安装ubuntu系统
  15. 你这手写vue2.x/3.x的响应式保熟吗?
  16. mysql拖库_利用SQL注入漏洞拖库的方法
  17. 定制Android开发者专属T恤
  18. Python sklearn 分类效果评估
  19. JGG | 江南大学翟齐啸组解析肠道益生菌体外免疫刺激活性的种属依赖性
  20. PPT基础(三十)图片的特殊效果

热门文章

  1. HALCON获取区域的中心点、面积和最小外接圆半径
  2. R语言常见报错及解决方法
  3. 高数定理、法则(持续添加)
  4. webpack中各个模块归纳总结图
  5. 2013,爱上暗色调
  6. HCSA-07 配置Web认证、配置Active Directory(AD)
  7. 计算机默认登录用户名和密码是什么,Windows7默认管理员账户用户名和密码是什么...
  8. 统计学习方法概论之思维导图图解
  9. 文件夹病毒或1K病毒解决
  10. php计算面积,PHP中长方形的面积怎么求