【Git】Git 变基(rebase)以及rebase和merge之间的区别

2023-09-13 15:43:04

Git 变基

1.变基 — rebase

在 Git 中整合来自不同分支的修改主要有两种方法:merge 以及 rebase

在前面的文章中已经介绍了merge,这里我们来学习另一个指令rebase

变基的基本操作

回顾之前在 分支的合并 中的一个例子,在该例子中,我们可以看到开发任务分叉到两个不同分支,又各自提交了更新。

在这里插入图片描述

之前介绍过,整合分支最容易的方法是 merge 命令。 当两个分支分叉时,它会把两个分支的最新快照(C3C4)以及二者最近的共同祖先(C2)进行三方合并,合并的结果是生成一个新的快照(并提交)

在这里插入图片描述

其实,还有一种方法:你可以提取在 C4 中引入的补丁和修改,然后在 C3 的基础上应用一次。 在 Git 中,这种操作就叫做 变基(rebase)。 你可以使用 rebase 命令将提交到某一分支上的所有修改都移至另一分支上,就好像“重新播放”一样。

比如,在这个例子中,执行下面的指令:

$ git checkout experiment
$ git rebase master

即切换到 experiment 分支,将其变基到 master 上(这里需要注意一下,因为使用merge时,是在合并入的分支上,将要合并的分支合并到当前分支,而使用rebase时,则是将当前分支变基到目标分支上)。

rebase的原理是:

首先找到这两个分支(即当前分支 experiment、变基操作的目标基底分支 master) 的最近共同祖先 C2,然后对比当前分支相对于该祖先的历次提交,提取相应的修改并存为临时文件, 然后将当前分支指向目标基底分支指向的提交对象C3, 最后以此将之前另存为临时文件的修改依序应用

在这里插入图片描述

此时,C4' 提交对象中的快照就和上面使用mergeC5 提交对象中的快照一模一样了!

但是,这里需要注意的是,变基过程中,目标基底分支的指针是不会变化的!移动是仅仅是当前分支的指针,所以,实际上 git rebase xxx 也可以理解为基于xxx进行变基。

比如这个例子中,目标基底分支master是始终没有变化的,仅仅是当前分支experiment发生了移动。

如果你后续想要让master分支跟上进度,只需要执行一次**快进合并(fast-forward)**即可(实际上就是执行merge)。

2.rebase 与 merge 的区别

对于mergerebase这两种整合方法的最终结果没有任何区别,但是变基使得提交历史更加整洁。 你在查看一个经过变基的分支的历史记录时会发现,尽管实际的开发工作是并行的, 但它们看上去就像是串行的一样,提交历史是一条直线没有分叉。

一般我们这样做的目的是为了确保在向远程分支推送时能保持提交历史的整洁——例如向某个其他人维护的项目贡献代码时。 在这种情况下,你首先在自己的分支里进行开发,当开发完成时你需要先将你的代码变基到 origin/master 上,然后再向主项目提交修改。 这样的话,该项目的维护者就不再需要进行整合工作,只需要快进合并便可。

总的来说,无论是通过变基,还是通过三方合并,整合的最终结果所指向的快照始终是一样的,只不过提交历史不同罢了。

变基是将一系列提交按照原有次序依次应用到另一分支上,而合并是把最终结果合在一起

3.变基的其他使用方法

在对两个分支进行变基时,所生成的“重放”并不一定要在目标分支上应用,你也可以指定另外的一个分支进行应用。 就像 从一个主题分支里再分出一个主题分支的提交历史 中的例子那样。 你创建了一个主题分支 server,为服务端添加了一些功能,提交了 C3C4。 然后从 C3 上创建了主题分支 client,为客户端添加了一些功能,提交了 C8C9。 最后,你回到 server 分支,又提交了 C10

在这里插入图片描述

假设你希望将 client 中的修改合并到主分支并发布,但暂时并不想合并 server 中的修改, 因为它们还需要经过更全面的测试。这时,你就可以使用 git rebase 命令的 --onto 选项, 选中在 client 分支里但不在 server 分支里的修改(即 C8C9),将它们在 master 分支上重放:

$ git rebase --onto master server client

以上命令的意思是:“取出 client 分支,找出它从 server 分支分歧之后的补丁, 然后把这些补丁在 master 分支上重放一遍,让 client 看起来像直接基于 master 修改一样”。这理解起来有一点复杂,不过效果非常酷。

在这里插入图片描述

现在可以快进合并 master 分支了。(如图 快进合并 master 分支,使之包含来自 client 分支的修改):

$ git checkout master
$ git merge client

在这里插入图片描述

接下来你决定将 server 分支中的修改也整合进来。 使用 git rebase <basebranch> <topicbranch> 命令可以直接将主题分支 (即本例中的 server)变基到目标分支(即 master)上。 这样做能省去你先切换到 server 分支,再对其执行变基命令的多个步骤。

$ git rebase master server

如图 server 中的修改变基到 master 所示,server 中的代码被“续”到了 master 后面。

在这里插入图片描述

然后就可以快进合并主分支 master 了:

$ git checkout master
$ git merge server

至此,clientserver 分支中的修改都已经整合到主分支里了, 你可以删除这两个分支,最终提交历史会变成下面的样子:

$ git branch -d client
$ git branch -d server

在这里插入图片描述

4.变基的风险

使用变基得遵守一条准则:

如果提交存在于你的仓库之外,而别人可能基于这些提交进行开发,那么不要执行变基。

变基操作的实质是丢弃一些现有的提交,然后相应地新建一些内容一样但实际上不同的提交。 如果你已经将提交推送至某个仓库,而其他人也已经从该仓库拉取提交并进行了后续工作,此时,如果你用 git rebase 命令重新整理了提交并再次推送,你的同伴因此将不得不再次将他们手头的工作与你的提交进行整合,如果接下来你还要拉取并整合他们修改过的提交,事情就会变得一团糟。

总的原则是,只对尚未推送或分享给别人的本地修改执行变基操作清理历史, 从不对已推送至别处的提交执行变基操作,这样,你才能享受到两种方式带来的便利。

5.Rerere

更多推荐

短视频矩阵系统源代码开发搭建分享--代码开源SaaS

一、什么是短视频矩阵系统?短视频矩阵系统是专门为企业号商家、普通号商家提供帐号运营从流量到转化成交的一站式服务方案,具体包含:点赞关注评论主动私信,评论区回复,自动潜客户挖掘,矩阵号营销,自动化营销,粉丝管理等功能,可以帮助企业或商家快速批量制作高质量短视频,扩大企业宣传,提升企业经营效果。通过短视频矩阵系统的运营,可

React面试题总结(一)

1、redux本来是同步的,为什么它能执行异步代码?实现原理是什么?中间件的实现原理是什么?1、Redux-thunk这个中间件支持异步操作2、执行异步的操作首先需要下载一个thunk,通过thunk来进行异步的一个操作,支持异步操作,可以使用dispatch和getState来进行数据的获取或状态3、Redux是一个

【C++】STL—— unordered_map的介绍和使用、 unordered_map的构造函数和迭代器、 unordered_map的增删查改函数

文章目录1.unordered_map的介绍2.unordered_map的使用2.1unordered_map的构造函数2.2unordered_map的迭代器2.3unordered_map的容量和访问函数2.4unordered_map的增删查改函数1.unordered_map的介绍unordered_map的

【Java 基础篇】Java多线程编程详解:线程创建、同步、线程池与性能优化

Java是一门强大的编程语言,其中最引人注目的特性之一是多线程支持。多线程允许我们在同一程序中同时执行多个任务,这大大提高了应用程序的性能和响应能力。本文将深入介绍Java线程的基础知识,无论您是初学者还是有一些经验的开发人员,都将从中获益。什么是线程?在计算机科学领域,线程是指在一个进程内部执行的独立单元。一个进程可

多线程设计模式【线程安全、 Future 设计模式、Master-Worker 设计模式 】(一)-全面详解(学习总结---从入门到深化)

目录SingleThreadExecution设计模式线程安全Future设计模式Master-Worker设计模式生产者消费者设计模式定义不可变对象的策略SingleThreadExecution设计模式机场过安检SingleThreadExecution模式是指在同一时刻只能有一个线程去访问共享资源,就像独木桥一样

runc和docker

在Docker中,runc是一个轻量级的运行时工具,用于创建和运行容器。它是OpenContainerInitiative(OCI)的一部分,负责管理和执行容器中的进程。runc负责创建和管理Linux命名空间、控制组(cgroups)和文件系统挂载等功能,以便隔离容器中的进程、资源和文件系统。它还提供了容器的生命周期

在项目中,关于前端实现数据可视化的技术选择

前言在项目中,数据可视化以图表、报表类型为主。需求背景技术框架是Vue2.x版本,组件库是AntDesignofVue能够支撑足够多的图表类型开发图表大小/位置能够随意变动图表样式需要支持丰富多样的用户配置强大、开放的图表语法支持复杂的数据可视化场景兼顾电脑端和手机端、同时兼顾开发周期和后期维护版本稳定、社区活跃,方便

【数据结构】二叉树

树的概念及结构树的概念树是一种非线性的数据结构,它是由n(n>=0)个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。有一个特殊的结点,称为根结点,根节点没有前驱结点(上图中的A结点就是根节点)除根节点外,其余结点被分成M(M>0)个互不相交的集合T1、T2、

SpringCLoud——RabbitMQ的消息模型

WorkQueue工作队列他的主要作用就是增加消费者的个数,可以提高消息处理速度,避免队列消息堆积。案例实现一个队列绑定多个消费者首先修改一下之前的发送消息的代码,让他循环发送50次,但是不要一次性发完:@TestvoidLoopSend()throwsInterruptedException{StringqueueN

计算机网络知识补充(1)

计算机网络:是一个将分散的,具有独立功能的计算机系统,通过通信设备和线路进行连接起来,由功能完善的软件实现资源共享和信息共享的系统,计算机网络是互连的,自治的计算机集合互连:通过通信链路来进行互联互通自治:没有主从关系1)电路交换:电路交换是一种通信方式,它是通过建立点对点的电路连接来传输数据的,在电路交换中,如果两个

同为科技(TOWE)工业用插头插座及配电箱产品选型推荐

工业用插头插座及配电箱产品是专用于工业环境中的电源连接和电气设备控制,与普通家用插头插座相比,通常具有更高的功率和电流容量,并且设计上考虑了耐用性、安全性和适应各种环境条件的能力。工业用插头插座产品类型多样,包括插头插座、工业连接器、防水配电箱等,满足户内外工业用电的各种需求,适用于工业、建筑、船舶、交通、能源、通信等

热文推荐