当前位置: 首页 > news >正文

git 合并策略

不清楚 git 冲突的表示方法,不了解 git 的合并原理,不知道 git 解冲突的多种策略。即便如此,大多数人依然可以正常使用 git 完成合并、拉取操作,并且解一些冲突。这得益于 git 默认情况下的合并方式可以处理大多数情况下的正常合并。

然而,你是否遭遇 git 自动合并炸掉的情况?命名提示没有冲突,代码却早已无法编译通过。

本文将介绍 git 的合并策略,你可能可以更好的使用不同的策略来解决冲突。


本文内容

      • git 合并策略
      • resolve
      • recursive
        • ours
        • theirs
        • patience
        • no-renames
        • 其他的参数
      • octopus
      • ours
      • subtree
        • 参考资料

git 合并策略

典型的使用指定 git 合并策略的命令这么写:

$ git merge 要合并进来的分支名 --strategy=合并策略

例如:

$ git merge origin/master --strategy=resolve

或者使用简写 -s,例如:

$ git merge origin/master -s resolve

可以指定的合并策略有:

  • resolve
  • recursive
  • octopus
  • ours
  • subtree

resolve

这使用的是三路合并算法。不过我们在 git 的合并原理(递归三路合并算法) 中说过,普通的三路合并算法会存在发现多个共同祖先的问题。此策略会“仔细地”寻找其中一个共同祖先。

由于不需要递归合并出虚拟节点,所以此方法合并时会比较快速,但也可能会带来更多冲突。不敢说带来更多冲突是好事还是坏事,因为自动合并成功并不一定意味着在代码含义上也算是正确的合并。所以如果自动合并总是成功但代码含义上会失败,可以考虑此合并策略,这将让更多的冲突变成手工合并而不是自动合并。

recursive

这是默认的合并策略,如果你不指定策略参数,那么将使用这个合并策略。这将直接使用递归三路合并算法进行合并,详见:git 的合并原理(递归三路合并算法)。

当指定为此策略时,可以额外指定下面的这些参数,方法是:

$ git merge 要合并进来的分支名 --strategy=合并策略 -X diff-algorithm=参数

例如:

$ git merge origin/master -s recursive -X diff-algorithm=patience

由于 recursive 是默认的合并策略,所以可以简化成:

$ git merge origin/master -X diff-algorithm=patience

ours

如果不冲突,那么与默认的合并方式相同。但如果发生冲突,将自动应用自己这一方的修改。

注意策略里面也有一个 ours,与这个不同的。

theirs

这与 ours 相反。如果不冲突,那么与默认的合并方式相同。但如果发生冲突,将自动应用来自其他人的修改(也就是 merge 参数中指定的那个分支的修改)。

patience

此策略的名称叫“耐心”,因为 git 将话费更多的时间来进行合并一些看起来不怎么重要的行,合并的结果也更加准确。当然,使用的算法是 recursive 即递归三路合并算法。

不过此名称也难以准确描述到底如何准确,不过可以举一个例子来说明:

int Foo()
{
    // 一些省略的代码。
}

int Baz()
{
    // 一些省略的代码。
}

然后在这两个函数中增加另一个函数:

int Bar()
{
    // 一些省略的代码。
}

默认情况下 git 会认为修改是这样的:

+ }
+
+ int Bar()
+ {
+     // 一些省略的代码。

然而使用 patience 策略后,git 将认为修改是这样的:

+ int Bar()
+ {
+     // 一些省略的代码。
+ }
+

如果你经常合并出现这些括号丢失或者符号不再匹配的问题,可以考虑使用 patience 策略进行合并。

no-renames

默认情况下 git 会识别出你重命名或者移动了文件,以便在你移动了文件之后依然可以与原文件进行合并。如果指定此策略,那么 git 将不再识别重命名,而是当作增加和删除了文件。

其他的参数

  • diff-algorithm=[patience|minimal|histogram|myers]
  • renormalize
  • no-renormalize
  • find-renames[=<n>]
  • rename-threshold=<n>
  • subtree[=<path>]

octopus

又是一个奇怪的名字——章鱼。章鱼有很多的触手,此合并策略就像这么多的触手一样。

此策略允许合并多个 git 提交节点(分支)。不过,如果会出现需要手工解决的冲突,那么此策略将不会执行。

此策略就是用来把多个分支聚集在一起的。

$ git merge t/lvyi t/walterlv -s octopus
error: Merge requires file-level merging
Trying really trivial in-index merge...
Nope.
Merge with strategy octopus failed.

ours

在合并的时候,无论有多少个合并分支,当前分支就直接是最终的合并结果。无论其他人有多少修改,在此次合并之后,都将不存在(当然历史里面还有)。

你可能觉得这种丢失改动的合并策略没有什么用。但如果你准备重新在你的仓库中进行开发(程序员最喜欢的重构),那么当你的修改与旧分支合并时,采用此合并策略就非常有用,你新的重构代码将完全不会被旧分支的改动所影响。

注意 recursive 策略中也有一个 ours 参数,与这个不同的。

subtree

此策略使用的是修改后的递归三路合并算法。与 recursive 不同的是,此策略会将合并的两个分支的其中一个视为另一个的子树,就像 git subtree 中使用的子树一样。


参考资料

  • Git merge strategy options & examples - Atlassian Git Tutorial
  • diff - Any example to use git merge patience strategy? - Stack Overflow
  • Git - merge-strategies Documentation
  • When would you use the different git merge strategies? - Stack Overflow
  • -X patience vs -X diff-algorithm=patience with git merge-recursive - Stack Overflow
  • Git diff --patience not working - Stack Overflow

我的博客会首发于 https://walterlv.com/,而 CSDN 和博客园仅从其中摘选发布,而且一旦发布了就不再更新。

如果在博客看到有任何不懂的内容,欢迎交流。我搭建了 dotnet 职业技术学院 欢迎大家加入。

知识共享许可协议

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名吕毅(包含链接:https://walterlv.blog.csdn.net/),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系。

相关文章:

  • .NET/C# 将一个命令行参数字符串转换为命令行参数数组 args
  • .NET/C# 获取一个正在运行的进程的命令行参数
  • 使用一句 git 命令将仓库的改动推送到所有的远端
  • 将 svn 仓库迁移到 git 仓库
  • 使用 Visual Studio 调试多进程的程序
  • 如何更精准地设置 C# / .NET Core 项目的输出路径?(包括添加和删除各种前后缀)
  • .NET 使用 JustAssembly 比较两个不同版本程序集的 API 变化
  • Windows 上的应用程序在运行期间可以给自己改名(可以做 OTA 自我更新)
  • 为 WPF 程序添加 Windows 跳转列表的支持
  • 在 Windows 系统上降低 UAC 权限运行程序(从管理员权限降权到普通用户权限)
  • 专栏素材
  • Visual Studio 如何能够不进行编译就调试 .NET/C# 项目(用于解决大项目编译缓慢的问题)
  • 仅反射加载(ReflectionOnlyLoadFrom)的 .NET 程序集,如何反射获取它的 Attribute 元数据呢?
  • 全局或为单独的项目添加自定义的 NuGet 源
  • 电脑总是意外从睡眠状态唤醒,可以找出原因然后解决
  • [nginx文档翻译系列] 控制nginx
  • 【面试系列】之二:关于js原型
  • CODING 缺陷管理功能正式开始公测
  • CSS居中完全指南——构建CSS居中决策树
  • Django 博客开发教程 8 - 博客文章详情页
  • HTTP--网络协议分层,http历史(二)
  • java 多线程基础, 我觉得还是有必要看看的
  • JavaScript实现分页效果
  • JavaScript学习总结——原型
  • js对象的深浅拷贝
  • nginx(二):进阶配置介绍--rewrite用法,压缩,https虚拟主机等
  • Redis 中的布隆过滤器
  • Synchronized 关键字使用、底层原理、JDK1.6 之后的底层优化以及 和ReenTrantLock 的对比...
  • 关于 Cirru Editor 存储格式
  • 基于MaxCompute打造轻盈的人人车移动端数据平台
  • 将回调地狱按在地上摩擦的Promise
  • 免费小说阅读小程序
  • 前端每日实战 2018 年 7 月份项目汇总(共 29 个项目)
  • 携程小程序初体验
  • 一个SAP顾问在美国的这些年
  • 用Visual Studio开发以太坊智能合约
  • Nginx实现动静分离
  • ​草莓熊python turtle绘图代码(玫瑰花版)附源代码
  • #{}和${}的区别是什么 -- java面试
  • #162 (Div. 2)
  • #大学#套接字
  • $.proxy和$.extend
  • (1)(1.11) SiK Radio v2(一)
  • (1)STL算法之遍历容器
  • (11)MSP430F5529 定时器B
  • (搬运以学习)flask 上下文的实现
  • (论文阅读笔记)Network planning with deep reinforcement learning
  • (每日持续更新)jdk api之FileReader基础、应用、实战
  • (七)Knockout 创建自定义绑定
  • (三)mysql_MYSQL(三)
  • (三)Pytorch快速搭建卷积神经网络模型实现手写数字识别(代码+详细注解)
  • (深度全面解析)ChatGPT的重大更新给创业者带来了哪些红利机会
  • *p++,*(p++),*++p,(*p)++区别?
  • .NET “底层”异步编程模式——异步编程模型(Asynchronous Programming Model,APM)...
  • .NET 8 中引入新的 IHostedLifecycleService 接口 实现定时任务