关于Git分支高级合并的一些笔记整理

news2024/12/26 11:32:49

写在前面


  • 分享一些 Git 高级合并的笔记
  • 博文为《Pro Git》读书笔记整理
  • 感谢开源这本书的作者和把这本书翻译为中文的大佬们
  • 理解不足小伙伴帮忙指正,书很不错,感兴趣小伙伴可以去拜读

傍晚时分,你坐在屋檐下,看着天慢慢地黑下去,心里寂寞而凄凉,感到自己的生命被剥夺了。当时我是个年轻人,但我害怕这样生活下去,衰老下去。在我看来,这是比死亡更可怕的事。--------王小波


合并冲突

对于更复杂的冲突,Git 提供了几个工具来帮助你指出将会发生什么以及如何更好地处理冲突。

在做一次可能有冲突的合并前尽可能保证工作目录是干净的。如果你有正在做的工作,要么提交到一个临时分支要么储藏它。这使你可以撤消在这里尝试做的任何事情。如果在你尝试一次合并时工作目录中有未保存的改动,下面的操作可能会丢失你的操作。

合并发生冲突

$ git merge whitespace
Auto-merging hello.rb
CONFLICT (content): Merge conflict in hello.rb
Automatic merge failed; fix conflicts and then commit the result.

中断一次合并

可能你不想处理合并冲突的这种情况,完全可以通过 git merge --abort 来简单地退出合并。

$ git status -sb
## master
UU hello.rb
$ git merge --abort
$ git status -sb
## master

git merge --abort 选项会尝试恢复到你运行合并前的状态。 但当运行命令前,在工作目录中有未储藏、未提交的修改时它不能完美处理,除此之外它都工作地很好。

如果出于某些原因你想要重来一次,也可以运行 git reset --hard HEAD 回到上一次提交的状态。请牢记此时任何未提交的工作都会丢失,所以请确认你不需要保留任何改动。

忽略空白

如果你看到在一次合并中有大量关于空白的问题,你可以直接中止它并重做一次,这次使用-Xignore-all-space -Xignore-space-change选项。第一个选项在比较行时完全忽略空白修改,第二个选项将一个空白符与多个连续的空白字符视作等价的。

$ git merge -Xignore-space-change whitespace
Auto-merging hello.rb
Merge made by the 'recursive' strategy.
 hello.rb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

手动文件再合并

通过 git show 命令与一个特别的语法,你可以将冲突文件的这些版本释放出一份拷贝。

Git 在索引中存储了所有这些版本,在 “stages” 下每一个都有一个数字与它们关联。

  • Stage 1 是它们共同的祖先版本
  • stage 2 是你的版本
  • stage 3 来自于 MERGE_HEAD,即你将要合并入的版本(“theirs”)。
$ git show :1:hello.rb > hello.common.rb
$ git show :2:hello.rb > hello.ours.rb
$ git show :3:hello.rb > hello.theirs.rb

工作目录中已经有这所有三个阶段的内容,我们可以手工修复它们来修复空白问题,然后使用鲜为人知的 git merge-file 命令来重新合并那个文件。

$ git merge-file -p \
  hello.ours.rb hello.common.rb hello.theirs.rb > hello.rb

要在合并前比较结果与在你的分支上的内容,换一句话说,看看合并引入了什么,可以运行 git diff --ours

$ git diff --ours
* Unmerged path hello.rb
diff --git a/hello.rb b/hello.rb
index 36c06c8..44d0a25 100755
--- a/hello.rb
+++ b/hello.rb
@@ -2,7 +2,7 @@
 # prints out a greeting
 def hello
- puts 'hello world'
+ puts 'hello mundo'
 end
 hello()

如果我们想要查看合并的结果与他们那边有什么不同,可以运行 git diff --theirs

$ git diff --theirs -b
* Unmerged path hello.rb
diff --git a/hello.rb b/hello.rb
index e85207e..44d0a25 100755
--- a/hello.rb
+++ b/hello.rb
@@ -1,5 +1,6 @@
 #! /usr/bin/env ruby
+# prints out a greeting
 def hello
  puts 'hello mundo'
 end

可以通过 git diff --base 来查看文件在两边是如何改动的。

$ git diff --base -b
* Unmerged path hello.rb
diff --git a/hello.rb b/hello.rb
index ac51efd..44d0a25 100755
--- a/hello.rb
+++ b/hello.rb
@@ -1,7 +1,8 @@
 #! /usr/bin/env ruby
+# prints out a greeting
 def hello
- puts 'hello world'
+ puts 'hello mundo'
 end
 hello()

在这时我们可以使用 git clean 命令来清理我们为手动合并而创建但不再有用的额外文件。

$ git clean -f
Removing hello.common.rb
Removing hello.ours.rb
Removing hello.theirs.rb

撤消合并

假设现在在一个主题分支上工作,不小心将其合并到 master 中,现在提交历史看起来是这样:

在这里插入图片描述

有两种方法来解决这个问题,这取决于你想要的结果是什么。

修复引用

如果这个不想要的合并提交只存在于你的本地仓库中,最简单且最好的解决方案是移动分支到你想要它指向的地方。 大多数情况下,如果你在错误的 git merge 后运行 git reset --hard HEAD~,这会重置分支指向所以它们看起来像这样:

在这里插入图片描述

reset --hard 通常会经历三步:

  1. 移动 HEAD 指向的分支。 在本例中,我们想要移动 master 到合并提交(C6)之前所在的位置。
  2. 使索引看起来像 HEAD。
  3. 使工作目录看起来像索引。

如果其他人已经有你将要重写的提交,你应当避免使用 reset

还原提交

如果移动分支指针并不适合你,Git 给你一个生成一个新提交的选项,提交将会撤消一个已存在提交的所有修改。 Git 称这个操作为“还原”,在这个特定的场景下,你可以像这样调用它:

$ git revert -m 1 HEAD
[master b1d8379] Revert "Merge branch 'topic'

-m 1 标记指出 “mainline” 需要被保留下来的父结点。 当你引入一个合并到 HEAD(git merge topic),新提交有两个父结点:

  • 第一个是 HEAD(C6)
  • 第二个是将要合并入分支的最新提交(C4)。

在本例中,我们想要撤消所有由父结点 #2(C4)合并引入的修改,同时保留从父结点 #1(C6)开始的所有内容。

在这里插入图片描述

新的提交 ^M 与 C6 有完全一样的内容,所以从这儿开始就像合并从未发生过,除了“现在还没合并”的提交依然在 HEAD 的历史中。 如果你尝试再次合并 topic 到 master Git 会感到困惑

$ git merge topic
Already up-to-date.

topic 中并没有东西不能从 master 中追踪到达。 更糟的是,如果你在 topic 中增加工作然后再次合并,Git只会引入被还原的合并 之后 的修改。

在这里插入图片描述

$ git revert ^M
[master 09f0126] Revert "Revert "Merge branch 'topic'""
$ git merge topi

解决这个最好的方式是撤消还原原始的合并,因为现在你想要引入被还原出去的修改,然后 创建一个新的合并提交:

在这里插入图片描述

选择以某一版本合并

当 Git 看到两个分支合并中的冲突时,它会将合并冲突标记添加到你的代码中并标记文件为冲突状态来让你解决。 如果你希望 Git 简单地选择特定的一边并忽略另外一边而不是让你手动解决冲突,你可以传递给 merge 命令一个-Xours -Xtheirs 参数。

$ git merge mundo
Auto-merging hello.rb
CONFLICT (content): Merge conflict in hello.rb
Resolved 'hello.rb' using previous resolution.
Automatic merge failed; fix conflicts and then commit the result.
$ git merge -Xours mundo
Auto-merging hello.rb
Merge made by the 'recursive' strategy.
 hello.rb | 2 +-
 test.sh | 2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)
 create mode 100644 test.sh

博文部分内容参考

文中涉及参考链接内容版权归原作者所有,如有侵权请告知


《Pro Git》


© 2018-2023 liruilonger@gmail.com,All rights reserved. 署名-相同方式共享 4.0 国际 协议(CC BY 4.0)

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

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

相关文章

传统图像处理方法实现车辆计数

本文通过传统OpenCV图像处理方法实现单向行驶的车辆计数。用于车辆检测的视频是在https://www.bilibili.com/video/BV1uS4y1v7qN/?spm_id_from333.337.search-card.all.click里面下载的。 思路一:来自B站某教程。大致是在视频中选取一窄长条区域,统计每…

【软件测试面试题】项目经验?资深测试 (分析+回答) 我不信你还拿不到offer......

目录:导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜)前言 在面试过程中&#…

Winform中操作Sqlite数据增删改查、程序启动时执行创建表初始化操作

场景 Sqlite数据库 SQLite是一个进程内的库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。 它是一个零配置的数据库,这意味着与其他数据库不一样,您不需要在系统中配置。 就像其他数据库,SQLite 引擎不…

day03

文章目录一、盒子模型1. 基础概念2. 外边距3. 边框1) 边框实现2) 单边框设置3) 网页三角标制作4) 圆角边框5) 轮廓线2. 内边距3. 盒阴影4. 盒模型概念5. 标签最终尺寸的计算5. 标签最终尺寸的计算一、盒子模型 1. 基础概念 ​ 盒子模型分别由外边距、边框、内边距和标签内容组…

【Datawhale图机器学习】图神经网络的表示能力

图神经网络的表示能力 GNN理论 GNN有多强大 已经提出了许多GNN模型(例如,GCN、GAT、GraphSAGE、设计空间)。这些GNN模型的表达能力什么? 表达、学习、区分、拟合如何设计一个最具表现力的GNN模型 一个GNN层 多个GNN层 GNN…

在小公司工作3年,从事软件测试6年了,才发现自己还是处于“初级“水平,是不是该放弃....

金三银四面试季,相信大家都想好好把握住这次机会拿到心仪的offer,今天就给大家分享我面试经历及总结,文章最后我还会分享一些自己的面试经验还有面试宝典,希望对程序媛们和程序猿们都能有所帮助~ 市场分析 现在的市场环境确实不大…

基本系统性质

系统的记忆特性 定义:对任意的输入信号,如果每一个时刻系统的输出信号值仅取决于该时刻的输入信号值,这个系统就是无记忆系统 接下来请看一看下面那些是记忆系统,哪些是无记忆系统。 非常简单,只有第一个和最后一个是…

LeetCode202 快乐数

题目: 编写一个算法来判断一个数 n 是不是快乐数。 「快乐数」 定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。 如果这个过程 结果…

vue 3.0组件(下)

文章目录前言:一,透传属性和事件1. 如何“透传属性和事件”2.如何禁止“透传属性和事件”3.多根元素的“透传属性和事件”4. 访问“透传属性和事件”二,插槽1. 什么是插槽2. 具名插槽3. 作用域插槽三,单文件组件CSS功能1. 组件作用…

css实现音乐播放器页面 · 笔记

效果 源码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevice-width, …

k8s 系列之 CoreDNS 解读

k8s 系列之 CoreDNS CoreDNS工作原理 kuberntes 中的 pod 基于 service 域名解析后&#xff0c;再负载均衡分发到 service 后端的各个 pod 服务中&#xff0c;如果没有 DNS 解析&#xff0c;则无法查到各个服务对应的 service 服务 在 Kubernetes 中&#xff0c;服务发现有几…

都2023年还不知道Java8如何优雅简化代码就落后了

1、使用 Stream 简化集合操作 Java8 Stream流操作总结_出世&入世的博客-CSDN博客 2、使用 Optional 简化判空逻辑 空指针异常&#xff08;NullPointerExceptions&#xff09;是 Java 最常见的异常之一&#xff0c;一直以来都困扰着 Java 程序员。一方面&#xff0c;程序…

springboot集成canal 实现mysql增量同步mongodb

一、canal官网https://kgithub.com/alibaba/canal/二、下载地址https://kgithub.com/alibaba/canal/releases三、细节1.6版本有bug&#xff08;如果只是部署deployer&#xff0c;那没问题&#xff0c;如果你想部署admin模块来监控&#xff0c;那就会报错&#xff1a;java.nio.B…

运算方法和运算电路

文章目录运算方法和运算电路基本运算部件定点数的移位运算算术移位逻辑移位循环移位定点数的加减运算原码的加减法补码的加减法原码的乘法补码的乘法原码的除法补码的除法符号扩展大小端和内存对齐刷题小结最后运算方法和运算电路 基本运算部件 运算器一般包含这么几部分&…

7 线性回归及Python实现

1 统计指标 随机变量XXX的理论平均值称为期望: μE(X)\mu E(X)μE(X)但现实中通常不知道μ\muμ, 因此使用已知样本来获取均值 X‾1n∑i1nXi.\overline{X} \frac{1}{n} \sum_{i 1}^n X_i. Xn1​i1∑n​Xi​.方差variance定义为&#xff1a; σ2E(∣X−μ∣2).\sigma^2 E(|…

STM32单片机的FLASH和RAM

STM32内置有Flash和RAM&#xff08;而RAM分为SRAM和DRAM&#xff0c;STM32内为SRAM&#xff09;&#xff0c;硬件上他们是不同的设备存储器、属于两个器件&#xff0c;但这两个存储器的寄存器输入输出端口被组织在同一个虚拟线性地址空间内。 MDK预处理、编译、汇编、链接后编…

月薪7k和月薪27k的测试人都有哪些区别?掌握这些,领导都要高看你...

了解软件测试这行的人都清楚&#xff0c;功能测试的天花板可能也就15k左右&#xff0c;而自动化的起点就在15k左右&#xff0c;当然两个岗位需要掌握的技能肯定是不一样的。 如果刚入门学习完软件测试&#xff0c;那么基本薪资会在7-8k左右&#xff0c;这个薪资不太高主要是因…

【存储】RAID0、RAID1、RAID3、RAID5、RAID6、混合RAID10、混合RAID50

存储RAID基本概念RAID数据组织形式RAID数据保护方式常用RAID级别与分类标准创建RAID组成员盘要求热备盘&#xff08;Hot Spare&#xff09;RAID 0的工作原理RAID 0的数据写入RAID 0的数据读取RAID 1的工作原理RAID 1的数据写入RAID 1的数据读取RAID 3的工作原理RAID 3的数据写入…

数据Python 异常处理

python标准异常异常名称描述BaseException所有异常的基类SystemExit解释器请求退出KeyboardInterrupt用户中断执行(通常是输入^C)Exception常规错误的基类StopIteration迭代器没有更多的值GeneratorExit生成器(generator)发生异常来通知退出StandardError所有的内建标准异常的基…

python学习之定制发送带附件的电子邮件

Python SMTP发送邮件 SMTP&#xff08;Simple Mail Transfer Protocol&#xff09;即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则&#xff0c;由它来控制信件的中转方式。python的smtplib提供了一种很方便的途径发送电子邮件。它对smtp协议进行了简单的封…