【博客552】git auto-merge原理以及auto-merge的不同模式

news2024/9/23 9:24:55

git auto-merge原理

1、merge 常见误区

1、git merge 是用时间先后决定merge结果的,后面会覆盖前面的?

答 :git 是分布式的文件版本控制系统,在分布式环境中时间是不可靠的,git是靠三路合并算法进行合并的。

2、git merge 只要两行不相同就一定会报冲突,叫人工解决?
答:git 尽管两行内容不一样,git 会进行取舍,当git无法进行取舍的时候才会进行人工解决冲突

2、merge对比单位:行

git 合并文件是以行为单位进行一行一行进行合并的,但是有些时候并不是两行内容不一样git就会报冲突,因为smart git 会帮我们自动帮我们进行取舍,分析出那个结果才是我们所期望的,如果smart git 都无法进行取舍时候才会报冲突,这个时候才需要我们进行人工干预。

3、git二路合并和三路合并处理冲突原理

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4、git auto-merge的不同模式

1、Fast-Forward Merge模式

当前工作分支到合并目标分支之间的提交历史是线性路径时,可以进行快进合并。在这种情况下,不需要真实的合并两个分支,Git只需要把当前分支的顶端指针移动到目标分支的顶端就可以了(也就是快进的意思)。在这种情况下快进合并成功的将提交历史合并至一处,毕竟目标分支中的提交此时都包含在当前分支的提交历史中了。

判断依据:

在找2个修改集合X,Y 公共祖先的时候,会发现公共祖先就是他们中的一个,

要求:

要求合并的两个分支(或提交)必须是祖孙/父子关系

场景:dev是从master的c2 commit修改拉出来的,并做了dev分支上的c3,c4 commit

在这里插入图片描述

将dev合入master的时候,master没有变化,此时可以直接将master指向dev就好了

在这里插入图片描述
分析:

由于master分支从c2开始与dev分叉以后就再也没有新的提交了,所以Git只是简单地把master的head指针向前移动到c4,合并就完成了。这就是所谓的Fast-Forward Merge。因为不涉及内容变更的比较,所以这种合并方式效率很高。Fast-Forward Merge要求参与合并的两个分支上的提交必须是“一脉相承”的父子或祖孙关系。不过它有个缺点,作为被合并的dev分支,它的提交历史在合并以后会和master分支的提交历史重合。

如果我们想在合并后保留来自被合并分支的提交历史,并显式标注出合并发生的位置,那就需要在执行合并时加上参数–no-ff。当然,这样也表示我们在合并时将不使用Fast-Forward Merge:

git merge --no-ff -m c5 dev

在这里插入图片描述

2、Three-Way Merge模式

如果在合并时使用–no-ff参数,Git就会采用Three-Way Merge(三方合并)对两个分支进行合并。

场景:dev从master的c2 commit拉出来的,并做了c3,c4 commit,此时master也做了c5 commit,要将dev合并进来
在这里插入图片描述

这个时候,Git会自动采用Three-Way Merge方式进行合并。首先,它会在两个分支上分别找到head指针(又被称为branch tip)所对应的提交:c4和c5。然后,找到距离它们俩最近的“共同祖先”:c2(也就是前面所说的“原件”,又被称为common ancestor),然后进行Three-Way Merge。

在这里插入图片描述

3、Squash Merge模式

Squash Merge:

指Git在做两个分支间的合并时,会把被合并分支(通常被称为topic分支)上的所有变更“压缩(squash)”成一个提交,追加到当前分支的后面,作为“合并提交”(merge commit)。从参与合并的文件变更上来说,Squash Merge和普通Merge并没有任何区别,效果完全一样。唯一的区别体现在提交历史上:正如我们前面提到的,对于普通的Merge而言,在当前分支上的合并提交通常会有两个parent;而Squash Merge却只有一个。

在这里插入图片描述
在这里插入图片描述

使用场景:

如果在被合并分支上,完整的提交历史里包含了很多中间提交(intermediate commit),比如:改正一个小小的拼写错误可能也会成为一个独立的提交,而我们并不希望在合并时把这些细节都反应在当前分支的提交历史里。这时,我们就可以选择Squash Merge。

4、Ours模式

Ours策略:

无论有没有冲突发生,都会毫不犹豫的丢弃来自被合并分支的修改,完整保留当前分支上的修改。所以,对于Ours策略而言,实质上根本就没有做任何真正意义上的合并,或者说做的是假合并(fake merge)。不过,从提交历史上看,Git依然会创建一个新的合并提交(merge commit),并让它的parent分别指向参与合并的两个分支上的提交记录。

exmaple:

git merge -s ours -m   feature1 feature2

没有Theirs策略!

事实上,Git在以前的版本里是有Theirs策略的,但后来它被去掉了。其实道理也很简单,因为它太危险了。正如Ours策略会毫不犹豫地丢弃被合并分支上的修改,Theirs策略也会毫不犹豫的丢弃当前分支上的修改。这相当于自己之前在当前分支上所做的工作全部丢掉了!

5、Octopus模式

Octopus策略:

假如我们要合并的分支超过两个,那该怎么办呢?这个时候,我们依然可以使用Recursive策略,对分支进行两两合并。但是,这样做每合并一次就会产生一个新的合并提交(merge commit)。过多的合并提交出现在提交历史里,会成为一种“杂音”,对提交历史造成不必要的“污染”,让它变得更加复杂,更难看懂。
这个时候,Octopus策略就派上用场了。Git在对两个以上的分支进行合并时,会自动选择Octopus策略。它的主要特点在于,只会生成一个合并提交,从而最大限度地减少了因为合并对提交历史造成的“污染”。因为按照这种合并策略得到的提交历史形似章鱼,所以名字还是起的很形象的

example:

git merge -m feature1 feature2 feature3

在这里插入图片描述

如果要是采用Recursive策略,git要在master分支上逐个合并feature1和feature2,其中,c4是在合并feature1时产生的,c5是在合并feature2时产生:

在这里插入图片描述

6、Recursive模式

Recursive模式:

Git在对两个分支进行合并时所采用的默认策略,它只适用于两个分支之间的合并。因此,对于超过两个分支的合并,需要反复地进行两两合并,才能最终完成所有分支的合并(这也是Recursive名字的由来)。本质上,Recursive就是一种Three-Way Merge。它的特点在于,如果Git在寻找共同祖先时,在参与合并的两个分支上找到了不只一个满足条件的共同祖先,它会先对共同祖先进行合并,建立临时快照。然后,把临时产生的“虚拟祖先”作为合并依据,再对分支进行合并。

如下图所示:

在对两个分支上的提交A和B进行合并时,我们发现了它们有两个共同祖先,分别是:ancestor0和ancestor1。这个时候,Recursive策略会对ancestor0和ancestor1进行合并,临时创建一个虚拟祖先:ancestor2。用ancestor2与A,B一起进行Three-Way Merge。

在这里插入图片描述

为啥叫递归模式:

如果在找ancestor0与ancestor1的公共祖先的时候,发现这两个分支的公共祖先也不止一个,又要找他们公共祖先的祖先,依次递归,直到找到公共祖先

Recursive模式中的Ours和Theirs参数:

在处理合并时,和其他某些Merge策略一样,Recursive策略通常会尽量自动完成合并。如果在合并过程中发现冲突,Git会在被合并的文件里插入冲突标记(merge conflict markers),并标记当前文件存在冲突,然后交由人工来处理。

不过,我们也可以通过指定参数告诉Git,当发生冲突时自动选择或丢弃其中一个分支上的修改。比如,假设我们要把分支B合并到分支A。如果指定参数-Xours,则表明丢弃分支B上的修改,保留当前分支A上的内容;指定参数-Xtheirs则刚好相反。

这里要注意的是,这两个参数只在发生冲突时起作用。而正常情况下,即没有发生冲突时,Git还是会帮我们自动完成合并的

Recursive模式中的Ours参数与上述Ours模式的差别:

如果在使用Recursive策略时指定-Xours参数,那么当发生冲突时,Git会选择丢弃来自被合并分支的修改,而保留被当前分支上的原有修改。这种情况只在有冲突时才会发生,如果没有冲突,Git还是会帮我们自动完成合并的。
与之不同的是,Ours策略无论有没有冲突发生,都会毫不犹豫的丢弃来自被合并分支的修改,完整保留当前分支上的修改。所以,对于Ours策略而言,实质上根本就没有做任何真正意义上的合并,或者说做的是假合并(fake merge)。不过,从提交历史上看,Git依然会创建一个新的合并提交(merge commit),并让它的parent分别指向参与合并的两个分支上的提交记录。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/59610.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

电脑装了w10没有w7流畅怎么办?

如果我们对自己的电脑进行了系统的重装,在电脑装了win10系统之后发现没有win7流畅的话,很多小伙伴不知道是什么情况应该怎么解决。 那么据微点阅读小编所知可能是我们电脑硬件设施的不兼容所导致的。我们可以在官网上查看win10系统的配置要求是否符合自…

一文带你深入理解【Java基础】· 泛型

写在前面 Hello大家好, 我是【麟-小白】,一位软件工程专业的学生,喜好计算机知识。希望大家能够一起学习进步呀!本人是一名在读大学生,专业水平有限,如发现错误或不足之处,请多多指正&#xff0…

Arduino开发实例-DIY风速测量及显示

DIY风速测量及显示 1、应用介绍 本次实例将使用一款具有 NPN 脉冲输出的数字风速计传感器。 NPN脉冲输出风速计效果好,性价比高。另外它仅在 5V 电源下工作。 在本次实例中,将此风速计传感器与 Arduino 板和 0.96 英寸 OLED 显示屏连接。 OLED显示屏将以米/秒为单位显示风速…

[附源码]计算机毕业设计基于SpringBoot的酒店预订系统设计与实现

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

​AAAI 2023 | 基于历史对比学习的时序知识图谱推理

©PaperWeekly 原创 作者 | 徐奕单位 | 上海交通大学Acemap研究方向 | 数据挖掘论文标题:Temporal Knowledge Graph Reasoning with Historical Contrastive Learning论文链接:https://arxiv.org/abs/2211.10904代码链接:https://github…

Elasticsearch好用查询插件分享

以前我常用的ES查询工具是Head,作为插件形式在浏览器中运行,挺方便的,后来发现head不太好用,比如在数据浏览的时候,不小心就点击了两个索引,背景色设置的还不够明显,比较容易看错数据的。于是想…

git中rebase和merge的区别

介绍 Merge和Rebase是合并两个分支的操作。都是checkout到某个分支上,然后将别的分支合并(变基)到本分支上。 注意:本分支(head指向的分支,或者经过checkout后的分支)会变化,而别的…

在Linux上部署Servlet程序

目录 一、部署环境 1、安装JDK 2、安装Tomcat 3、安装MySQL 二、部署程序 1、构造云服务器上的数据库 2、打包程序 3、部署程序 一、部署环境 为了部署我们自己的web程序,首先需要在Linux上安装程序所依赖的环境~ 1、安装JDK 直接使用yum安装openjdk&…

小程序云开发笔记二

小程序云开发笔记二一、读取数据库播放列表将数据显示到界面二、上拉加载三、上拉刷新四、云函数路由优化tcb-router案例:点击两个按钮调用同一个云函数将music中写成koa风格的云函数五、事件冒泡组件参数properties和data一、读取数据库播放列表将数据显示到界面 …

java同步方法

观看此文 首先 你要了解 java的同步锁 如果不了解 可以观看我的文章 java 同步锁synchronized 解决线程共享数据重复操作问题 那么 从下图 我们可以看到 逻辑代码上被绑了一个同步锁 但这个其实大可以写成一个函数 看起来会美观便捷很多 同步方法的格式如下 修饰符 synchro…

git switch 命令详解

1. 前言 2. switch 创建分支 3. switch 切换分支 1. 前言 checkout 命令具有 分支的管理 和 文件的恢复 两个核心功能,功能较多、不够准确。在 git 2.23 版本中新增了 switch 和 restore命令,用于替代 checkout 命令,进而分化 checkout 命…

(附源码)springboot大学生竞赛管理平台 毕业设计

题 目 springboot大学生竞赛管理平台 目 录 摘要 1 1 绪论 1 1.1选题意义 1 1.2国内外研究现状 1 1.3系统开发技术的特色 4 1.4论文结构与章节安排 4 2 大学生竞赛管理平台分析 5 2.1 可行性分析 5 2.2 系统流程分析 6 2.2.1数据增加流程 7 2.3.2数据修改流程 7 2.3.3数据删…

java面向对象----封装 构造器

目录 封装和隐藏 为什么需要封装? 信息的封装和隐藏 四种访问权限修饰符 构造器(构造方法) 构造器的特征 语法格式: 构造器重载 构造器重载举例 属性赋值过程 JavaBean UML类图 关键字—this this是什么? 使用this,…

计算机网络笔记2 物理层

计算机网络系列笔记目录👇 计算机网络笔记6 应用层计算机网络笔记5 运输层计算机网络笔记4 网络层计算机网络笔记3 数据链路层计算机网络笔记2 物理层计算机网络笔记1 概述 本文目录文章前言 💗一、物理层概述😊二、物理层的传输媒体&#x…

Spring源码该如何阅读?十年架构师带来的Spring源码解析千万不要错过!

写在前面 最近学习了一句话,感觉自己的世界瞬间明朗,不再那么紧张焦虑恐慌,同样推荐给大家,希望我们都终有所得。 “如果一个人不是发自内心地想要做一件事情,那么,他是无法改变自己的人生的。” 同样这句…

4. 死信队列

二八佳人体似酥,腰间仗剑斩愚夫。虽然不见人头落,暗里教君骨髓枯。 死信 概念 先从概念解释上搞清楚这个定义,死信,顾名思义就是无法被消费的消息,字面意思可以这样理 解,一般来说,producer 将…

「Redis」05 Jedis操作Redis

笔记整理自【尚硅谷】Redis 6 入门到精通 超详细 教程 Redis——Jedis操作Redis 即通过 Java 操作 Redis。 1. Jedis基本操作 Ⅰ. 测试连接 连接Redis注意事项 禁用Linux的防火墙:Linux(CentOS7)里执行命令:systemctl stop/disab…

我的周刊(第068期)

我的信息周刊,记录这周我看到的有价值的信息,主要针对计算机领域,内容主题极大程度被我个人喜好主导。这个项目核心目的在于记录让自己有印象的信息做一个留存以及共享。🎯 项目osquery[1]像操作 SQL 一样操作你的电脑&#xff0c…

康复训练的未来:VR和元宇宙如何帮助患者康复

欢迎来到Hubbleverse 🌍 关注我们 关注宇宙新鲜事 📌 预计阅读时长:7分钟 本文仅代表作者个人观点,不代表平台意见,不构成投资建议。 一位有平衡问题的患者站在波速球上,同时在两只潇洒的企鹅之间击打着…

第十六章 品质保证:发布覆盖率测试报告

代码覆盖率才是评价一个项目品质的标准。在挑选一个项目的时候,有经验的使用者都会根据代码覆盖率来确定代码的可靠性。 虽然自动化测试工具可以自动验证代码的正确性,但是如果只有部分代码经过了测试,或者只是简单地跑通了代码,…