详解Git合并冲突——问题重现、原因及解决 “Automatic merge failed; fix conflicts and then commit the result.“

2023-11-13


最后更新日期:2022/10/6

在Git中使用git merge命令合并两个分支的时候,有可能产生这种情况:

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

这就是发生了冲突(conflict)。

为什么会有冲突?要如何解决呢?请看下文介绍。

为什么会发生冲突?

简单来说,就是两个分支都对同一个文件做了更改,当这两个分支合并的时候,Git不知道要采用哪一个更改,便发生了冲突。

图1 一个冲突的例子

举个栗子,假设刚开始master分支版本为C0,然后依次发生了以下情况:

  1. 小A基于C0创建新分支new_branch,并在该分支上改动了文件merge.txt,提交得到版本C2
  2. 小B在主分支master上进行开发,同样改动了merge.txt,提交得到版本C1

此时,如果用git mergemasternew_branch合并,就会发生冲突。完整的过程如图1所示。

Git提示冲突,也是一件好事,它其实是在告诉你:
“你让我合并new_branchmaster两个分支,但是它们两个都改动了merge.txt,一个说要这样改,一个说要那样改,我应该听谁的呀?你来帮我看下吧!”。(形象解释)

在讲解如何解决冲突之前,我们得先有一个冲突。下面将根据图1制造出一个冲突。

制造一个冲突

制造图1的冲突分为4个步骤:

第一步:初始化仓库及文件

首先创建一个新仓库。打开Git Bash,顺序执行以下命令:

$ mkdir git-merge-test
$ cd git-merge-test
$ git init
Initialized empty Git repository in path/to/your/work/dictionary/git-merge-test/.git/

以上命令在当前位置创建了一个名为git-merge-test的文件夹,并将其初始化为Git仓库。

然后创建仓库文件。在仓库根目录下新建merge.txt,写入以下内容:

这是第一行,这行不会被修改
这是第二行

在这里插入图片描述

添加merge.txt到暂存区并提交更改:

$ git add .
$ git commit -m"初始化仓库内容"
[master 8bc6262] 初始化仓库
 Date: Wed Oct 5 16:30:35 2022 +0800
 1 file changed, 2 insertions(+)
 create mode 100644 merge.txt

此时,master处于图1中的C0

第二步:在新分支上更改并提交文件

然后,创建一个新分支new_branch::

$ git checkout -b new_branch
Switched to a new branch 'new_branch'

说明:git checkout -b 分支名表示创建一个新分支并切换到这个分支上。

修改merge.txt

这是第一行,这行不会被修改
我在new_branch分支上修改了第二行

在这里插入图片描述

添加merge.txt并提交更改:

$ git commit -am"修改merge.txt"
[new_branch 8eb88a9] 修改merge.txt
 1 file changed, 1 insertion(+), 1 deletion(-)

说明:git commit -am"提交信息"中的选项a表示先git add所有发生改动的文件再提交。

此时,new_branch位于图1中的C2

第三步:在主分支上更改并提交文件

$ git checkout master
Switched to branch 'master'
$ echo "我在master分支上添加了第三行" >> merge.txt
$ git commit -am"新增内容到merge.txt"
[master 52c86fa] 新增内容到merge.txt
 1 file changed, 1 insertion(+)

上述命令的意思是,先切换回master分支,然后往merge.txt中添加一行内容(">>"表示追加重定向文件),最后提交更改。

此时,master位于图1中的C1

第四步:执行合并,触发冲突

在合并之前,我们先捋一下现在的状况:

  • 最初的merge.txt的内容为:
    这是第一行,这行不会被修改
    这是第二行
    
  • new_branch分支上改动后的merge.txt内容为:
    这是第一行,这行不会被修改
    我在new_branch分支上修改了第二行
    
  • master主分支上改动后的merge.txt内容为:
    这是第一行,这行不会被修改
    这是第二行
    我在master分支上添加了第三行
    

两个分支都改动了merge.txt,合并会发生什么呢?下面就来试一下。

master分支上执行git merge new_branch,尝试把new_branch分支合并过来:

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

可以看到,冲突发生了。

在解决冲突之前,应该先要知道如何查看冲突。下面将进行介绍。

如何查看冲突?

文章刚开始已经提到,合并时发生冲突,是因为两个分支都对同一个文件做了更改。当合并masternew_branch的时候,Git发现对于merge.txt,一个分支这样改,另一个分支那样改,就陷入了两难。从报错信息可知,冲突需要我们手动解决后方可提交。

很多人到这里就懵了,不知道该怎么弄。实际上,我们现在正处于合并的“中间状态”。合并的中间状态就是合并了,但还没完全合并。。好吧,是废话,意思就是你执行git merge了,但git merge并没有执行完成(因为发生冲突了),需要你解决冲突后继续进行。

敲入git status,就可以看到这样的信息:

$ git status
On branch master
You have unmerged paths.
  (fix conflicts and run "git commit")
  (use "git merge --abort" to abort the merge)

Unmerged paths:
  (use "git add <file>..." to mark resolution)
        both modified:   merge.txt

no changes added to commit (use "git add" and/or "git commit -a")

git status告诉我们以下信息:

  • “You have unmerged paths”:我们现在正处于合并的中间状态,有一些没有合并的文件;
  • “Unmerged paths”:下面列出了所有未合并的文件,都显示为红色(网页上看不到)。可以看到,merge.txt没有合并,因为两个分支都更改了它(“both modified”),发生了冲突。我们要先把冲突解决了。

那我们现在就来查看冲突。用编辑器打开merge.txt,会发现内容变成了这样:

这是第一行,这行不会被修改
<<<<<<< HEAD
这是第二行
我在master分支上添加了第三行
=======
我在new_branch分支上修改了第二行
>>>>>>> new_branch

里面多了三行我们看不懂的记号:

  • <<<<<<< HEAD
  • =======
  • >>>>>>> new_branch

这些记号是标记冲突内容的分隔线,解释如下:

  • <<<<<<< HEAD=======之间的内容:是master分支修改的内容(准确来说是HEAD指针指向的分支修改的内容);
  • =======>>>>>>> new_branch之间的内容:是new_branch分支修改的内容;
  • 分割线之外的内容:是两个分支都没有改动的内容(如merge.txt第一行)。

看懂了吗?然后,解决冲突就变得很简单了。

如何解决冲突?

解决冲突只需3步:

  1. 编辑冲突文件。决定要保留的内容,然后删掉三行分割线
  2. git add将冲突文件添加到暂存区
  3. git commit提交

对于第1步,要按照你的具体情况去改。通常情况下,我们有这两种做法:

  • 保留其中一个修改,删掉另一个
  • 同时保留两个修改

不管怎样,最终改好的文件会原封不动地提交到仓库中。另外需要注意,最后不要忘了删掉三行分隔线,即:<<<<<<< HEAD=======>>>>>>> new_branch

在我们的例子中,假如我们想同时保留两个分支的修改,那么可以编辑merge.txt,仅删掉三行分隔线,其他部分不用管,得到以下内容:

这是第一行,这行不会被修改
这是第二行
我在master分支上添加了第三行
我在new_branch分支上修改了第二行

改好后,就可以提交了:

$ git add merge.txt
$ git commit -m "合并new_branch分支并解决冲突"
[master 0c88c4f] 合并new_branch分支并解决冲突

查看合并后的提交记录:

$ git log
commit 0c88c4f9210af067125c9027f3e5885065f88dd0 (HEAD -> master)
Merge: 52c86fa 8eb88a9
Author: lanjianghao <528601933@qq.com>
Date:   Wed Oct 5 22:28:34 2022 +0800

    合并new_branch分支并解决冲突

commit 52c86fa51bca34c7763ed7b56b7705b3ce31379c
Author: lanjianghao <528601933@qq.com>
Date:   Wed Oct 5 19:23:32 2022 +0800

    新增内容到merge.txt

commit 8eb88a9d1dc88b30333492ec44c12685aaa8187c (new_branch)
Author: lanjianghao <528601933@qq.com>
Date:   Wed Oct 5 19:17:06 2022 +0800

    修改merge.txt

commit 8bc626277eec39e413dcdd764642865b5291674e
Author: lanjianghao <528601933@qq.com>
Date:   Wed Oct 5 16:30:35 2022 +0800

    初始化仓库

可以看到,日志中新增了一条合并记录。

总结

  • 为什么合并时发生了冲突?
    • 要合并的两个分支改动了同一个文件,Git不知道要采用哪个,还是两个都采用,需要由你来决定。
  • 怎样查看冲突?
    • git status查看冲突的文件
    • 编辑器打开冲突的文件,查看冲突的内容
    • 冲突内容分隔线怎么看:
      未冲突的内容(两个分支都未改动)在分隔线外面
      <<<<<<< HEAD
      Git当前所在分支修改的内容(准确来说是HEAD指针指向的分支修改的内容)
      =======
      要合并过来的分支修改的内容
      >>>>>>> branch_to_merge
      
  • 怎样解决冲突?
    1. git status查看冲突的文件
    2. 编辑冲突文件,解决冲突(记得删除三行分隔线)
    3. git add 冲突文件
    4. git commit -m "提交信息"

其他问题

  • 我不想继续合并了,如何退出合并的中间状态?
    git merge --abort
    
    前文中提到,如果执行git merge合并时发生冲突,则会进入合并的中间状态。合并的中间状态下将无法执行其他一些操作(如切换分支)。
    如果不想继续合并,要先用git merge --abort命令退出。该命令会使你回到执行git merge 分支之前的状态。

感谢大家能看到这里!本人也还是小白,如果有不对的地方,欢迎指正!

参考:
https://www.atlassian.com/git/tutorials/using-branches/merge-conflicts

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

详解Git合并冲突——问题重现、原因及解决 “Automatic merge failed; fix conflicts and then commit the result.“ 的相关文章

  • 无法从 Sourcetree 拉取 Git 远程存储库

    我生成了 ssh 密钥并配置了我的 git 和 SourceTree 我可以 git pull 并从 Git bash 执行其他操作 注意 我在 bashrc 中添加了以下内容以使其正常工作 eval ssh agent ssh add 然
  • GIT:以下未跟踪的工作树文件将被签出覆盖

    我有两个分支 一个称为 master 另一个称为 dev 我目前位于 master 分支 我想转到 dev 分支将文件移动到开发服务器 但是当我执行 git checkout dev 我收到消息 以下未跟踪的工作树文件将被覆盖 查看 pag
  • 当 .gitattributes 中的 EOL 设置为 CRLF 时,Git diff 认为行结尾为 LF

    当我恢复对带有 Windows 行结尾的文件的更改并且 gitattributes 将 EOL 定义为 CRLF 时 git 认为行结尾已更改为 LR 即使十六进制编辑器显示 CRLF 仅当 gitattributes 定义 EOL 字符时
  • Git 将一个分支合并到所有其他分支中

    我知道这个问题已经在这里被问过 https stackoverflow com questions 2329716 merging changes from master into all branches using git https
  • git 提交错误:检测到大文件

    您好 我正在为 ios 8 1 开发一个应用程序 xcode 我已经使用 googleMaps 框架来实现自动完成功能 当我尝试在 Git 中推送我的项目时 我收到大文件检测错误 后来尝试使用 git lfs 并跟踪 git 检测到的文件
  • github - 启用分支锁

    作为 GitHub 管理员 我想为所有用户锁定 GitHub 中的特定分支 例如如果我不希望任何人推送到主 生产或项目分支 我该怎么做 有没有办法直接锁定 GitHub 服务器上的分支 而不是使用任何客户端挂钩 是否有任何第三方工具 API
  • Git 提交失败:“请使用 -m 或 -F 选项提供消息。”

    当我键入 git commit 命令来提交文件时 我收到以下错误消息 Microsoft Visual Studio 微软 找不到命令 错误 核心编辑器 Microsoft Visual Studio 存在问题 请使用 m 或 F 选项提供
  • 将bitbucket发布到数字海洋

    我本质上是试图使用 bitbucket 来理解 git 的概念 我一直在通过修改本地帐户和 bitbucket 帐户之间的文件来练习版本控制 事实证明这很有帮助 现在我正在尝试弄清楚如何将文件从 bitbucket 或者我猜是 GitHub
  • Git difftool 未启动外部 DiffMerge 程序

    我一直遵循 戴夫的博客条目 http www davesquared net 2009 05 setting up git difftool on windows html 链接在此answer https stackoverflow co
  • 为所有子文件夹设置 git 配置值

    我知道可以设置每个存储库的配置来覆盖用户级配置 即 path to my repo gitconfig覆盖 gitconfig 是否可以设置 git 配置来覆盖给定文件夹的所有子文件夹的用户级设置 即 我有 topLevelFolder1
  • Android 存储库初始化失败

    我想我非常仔细地遵循该网站的说明 http source android com source downloading html http source android com source downloading html 但是当我尝试这
  • Git 在哪里存储标签?

    Git 在哪里存储标签 我执行 git tag v0 1 0 v0 10 0 v0 11 0 但目录 git refs tags是空的 Git 将这些标签存储在哪里 谢谢 它们也可以存储在 git packed refs
  • 为什么我的 Github 托管网站响应 HTTP 302 而不是 200?

    我拥有该域名penkov id au http penkov id au 我主持一个blog http michael penkov id au blog 2014 01 02 reinventing the wheel html usin
  • Git - 如何将整个目录恢复到特定提交(删除任何添加的文件)

    我想恢复 git 中的目录 恢复其中的所有文件 并删除自该提交以来添加的所有文件 进行结账似乎只能满足我的第一个要求 但不会删除任何文件 我想出了最简单的解决方案 git rm path to dir git checkout
  • 无法通过 Git Bash 克隆 git 存储库

    在尝试使用克隆存储库时git clone 它显示以下错误 致命 无法访问 https github com microsoft c9 python getting started git https github com microsoft
  • 为什么 Git 无法将文件更改与修改后的父级/主控合并?

    我有一个文件 里面只有一行 我创建一个分支并向同一文件添加第二行 保存并提交到分支 我切换回主人 并向文件中添加不同的第二行 保存并提交给master 现在总共有 3 条独特的线路 如果我现在尝试将分支合并回主分支 则会遇到合并冲突 为什么
  • Git 更改丢失 - 为什么?

    我们的开发团队正在使用 git 最近我们至少两次丢失了文件更改 我们正在使用私人 Github 存储库 在当前情况下 我们可以返回 Github 上的日志并查看我对文件所做的一些更新 后来 另一位团队成员更改了文件的不同部分 它似乎破坏了我
  • git 是否有任何静态接口?

    我一直在寻找一个宁静的 git api 但似乎没有找到 我得到的最接近的是 Github 的 api 来访问一些存储库信息 还有其他的实施吗 Orion Git API http wiki eclipse org Orion Server
  • git 2.32 git push -u origin master 没有任何反应

    I ve starting to use git github and I m stucked on how to push my codes to github I m following some tutorials and when
  • 有没有一个简单的命令可以将分支转换为标签?

    我即将完成将 哑快照 转换为 git 的繁琐过程 这个过程进展得非常顺利 感谢这个重命名过程 https stackoverflow com questions 6628539 how to tell git that its the sa

随机推荐

  • 【解决】mysql安装时,Unable to connect to any of the specified MySQL hosts

    解决方法 win r打开运行 输入regedit 打开注册表 更改注册表 找到HKEY LOCAL MACHINE SYSTEM CurrentControlSet services mysql 服务名 ImagePath 我原先的地址为
  • 性能调优篇07:Zabbix性能优化的几点原则

    性能调优 概述 使Zabbix系统正确调整以获得最佳性能是非常重要的 Zabbix性能优化的几点原则 确保zabbix内部组件性能处于被监控状态 调优的基础 使用硬件性能足够好的服务器 不同角色分开 使用各自独立的服务器 使用分布式部署 调
  • 统计:Flutter,开发采用量

    本文作者 徐宜生 原文发布于 群英传 Flutter这个东西出来这么久了 到底市场占有率怎么样呢 为了让大家了解这一真实数据 也为了让大家了解当前Flutter在各大App中的使用情况 我今天下载了几百个App 占了手机将近80G空间 就为
  • 队列同步器AQS原理分析及具体实现

    Java中的并发编程很多都是以队列同步器AbstractQueuedSynchronizer为基础的 例如ReentrantLock CountDownLatch等 下面介绍其构成以及相应的实现 构成 private volatile in
  • 【汽车电子】浅谈LIN总线

    目录 1 为何使用LIN总线 2 什么是LIN总线 3 LIN总线的主从关系 4 LIN的特点 5 LIN报文帧结构 6 LIN总线波形 7 帧类型 8 进度表 9 状态机的实现 10 总结 11 声明 1 为何使用LIN总线 在这里你可能
  • Vue常用的修饰符有哪些?分别有什么应用场景?

    一 修饰符是什么 在程序世界里 修饰符是用于限定类型以及类型成员的声明的一种符号 在Vue中 修饰符处理了许多DOM事件的细节 让我们不再需要花大量的时间去处理这些烦恼的事情 而能有更多的精力专注于程序的逻辑处理 vue中修饰符分为以下五种
  • 一步一步详解LSTM网络【从RNN到LSTM到GRU等,直至attention】

    一步一步详解LSTM网络 从RNN到LSTM到GRU等 直至attention 0 前言 1 Recurrent Neural Networks循环神经网络 2 The Problem of Long Term Dependencies长期
  • import sys

    import sys 的作用是什么 参考来源 1 首先 先看一段代码 1 from sys import argv 2 script first second third argv 3 print The script is called
  • 3A之自动白平衡(AWB)篇

    在手机相机的专业模式中 可以看到有一个白平衡 WB 调节的选项 什么是AWB 人眼视觉系统具有颜色恒常性的特点 对物体的观察不受光源的影响 本质上是白色的物体 在不同色温 反射光线颜色不同的场景下 经过人眼的视觉系统矫正后还是白色 而对于C
  • 信息安全渗透测试都需要学习哪些内容?

    这个问题 说实话 在2019年之前 其实关注信息安全相关的人并不多 对于市场来讲 信息安全的需求量也不是很大 但大家都知道 在中国 随着时代和技术的发展 信息安全越来越受到重视 一步一步上升到国家战略层面 随着等保2 0出台 相应的信息行业
  • 阿里开源FASTJSON2,为FASTJSON重构升级,目标是为下一个十年提供一个高性能的JSON库

    大厂杂谈关注到阿里最近开源了fastjson2 推出几天已经获得500多的star FASTJSON2是FASTJSON项目的重要升级 目标是为下一个十年提供一个高性能的JSON库 持JSON JSONB两种协议 JSONPath是一等公民
  • 代码质量保障第2讲:单元测试 - 浅谈单元测试

    代码质量保障第2讲 单元测试 浅谈单元测试 本文是代码质量保障第2讲 浅谈单元测试 单元测试 unit testing 是指对软件中的最小可测试单元进行检查和验证 这是基础 所以围绕着单元测试 我从网上搜集和总结了相关的概念 以助你完善体系
  • 「OKR 理论篇」5 分钟快速掌握 OKR 管理法

    近几年在企业管理领域有一个很火的词 OKR 它发源于英特尔 兴盛于Google 随着字节跳动等互联网新贵的迅速崛起 引起了越来越多创新企业的关注 然而 对大部分公司而言 他们并没有完全理解 OKR 理念 往往将 OKR 与绩效考核等同起来
  • 用朴素贝叶斯做垃圾邮件分类&demo

    贝叶斯公式 全概公式 思路和实现 最终的目标 对于一封邮件 分词得到 我们需要求出给定的条件下 这封邮件是垃圾邮件的概率 即求出 这里s表示是垃圾邮件 spam 根据贝叶斯公式 根据全概公式 上式 这里n表示是正常邮件 noraml 令先验
  • 分布式应用:Zabbix代理服务器与SNMP监控

    目录 一 理论 1 分布式监控 2 Zabbix代理服务器部署 3 配置 agent 使用 proxy 4 设置 Zabbix SNMP 监控 二 实验 1 Zabbix代理服务器部署 2 配置 agent 使用 proxy 3 设置 Za
  • 多线程与高并发--------线程

    一 线程的基础概念 一 基础概念 1 1 进程与线程 什么是进程 进程是指运行中的程序 比如我们使用钉钉 浏览器 需要启动这个程序 操作系统会给这个程序分配一定的资源 占用内存资源 什么线程 线程是CPU调度的基本单位 每个线程执行的都是某
  • Linux下七种文件类型、文件属性及其查看方法

    1 七种文件类型 普通文件类型 Linux中最多的一种文件类型 包括 纯文本文件 ASCII 二进制文件 binary 数据格式的文件 data 各种压缩文件 第一个属性为 目录文件 就是目录 能用 cd 命令进入的 第一个属性为 d 例如
  • C++ 函数模板(template)详解

    目录 1 前言 2 为什么要使用函数模板 3 函数模板语法 3 1函数模板定义形式 4 函数模板和函数重载 4 1函数模板无法隐式数据类型转换 4 2当函数模板和普通函数都符合调用时 优先选择普通函数 4 3如果函数模板会产生更好的匹配 使
  • 【网络编程·应用层】https协议——加密与窃密的攻防战

    需要云服务器等云产品来学习Linux的同学可以移步 gt 腾讯云 lt gt 阿里云 lt gt 华为云 lt 官网 轻量型云服务器低至112元 年 新用户首次下单享超低折扣 目录 一 https协议的介绍 二 加密和解密 1 加密和解密的
  • 详解Git合并冲突——问题重现、原因及解决 “Automatic merge failed; fix conflicts and then commit the result.“

    最后更新日期 2022 10 6 在Git中使用git merge命令合并两个分支的时候 有可能产生这种情况 git merge A Auto merging merge txt CONFLICT content Merge conflic