当前位置:首页 > 技术 > 正文内容

Git 冲突处理完全指南

访客 技术 2026年7月2日 1

1. 冲突处理的核心目标

Git 冲突在团队协作和分支开发中极为常见,并非代码异常,而是多人协同工作的自然结果。

本文将聚焦于冲突的实际处理流程,帮助开发者快速掌握解决合并冲突的技能。

核心内容包括:

1. 冲突产生的根本原因是什么?
2. 冲突标记 <<<<<<<、=======、>>>>>>> 的含义
3. merge 操作冲突的解决步骤
4. rebase 操作冲突的解决步骤
5. 解决冲突后为何需要 git add 命令
6. 如何取消正在进行的 merge 或 rebase 操作

建议配合理解 mergerebasepull 的概念,可参考相关文档进行学习。

2. 冲突产生的原因分析

Git 能够自动合并的前提条件是:

修改位置不存在重叠
或者 Git 能够明确判断应保留的版本

当两个分支同时修改了同一个文件的相同位置时,Git 无法自行判断应该采用哪个版本。

以具体场景为例:main 分支上对某行进行了如下修改:

int connectionLimit = 10;

而在功能分支上,同一位置被修改为:

int connectionLimit = 20;

此时 Git 无法确定最终应保留 10 还是 20,冲突便由此产生。

3. 冲突发生时的 Git 内部状态

假设仓库历史结构如下:

A -- B -- C
          |
        main
          \
           D -- E
                |
          feature/optimization

main 分支执行合并操作:

git merge feature/optimization

若双方修改存在重叠,Git 会中断合并并提示:

Auto-merging settings.cpp
CONFLICT (content): Merge conflict in settings.cpp
Automatic merge failed; fix conflicts and then commit the result.

此时仓库处于"合并进行中"状态,需要执行以下步骤:

1. 定位并打开冲突文件
2. 手动确定最终保留的内容
3. 使用 git add 标记冲突已处理

4. 冲突标记的解读方法

冲突文件中通常会看到如下标记:

<<<<<<< HEAD
int connectionLimit = 10;
=======
int connectionLimit = 20;
>>>>>>> feature/optimization

各部分含义说明:

<<<<<<< HEAD 到 ======= 之间:当前分支的代码版本
======= 到 >>>>>>> feature/optimization 之间:被合并分支的代码版本

若当前处于 main 分支执行合并:

git merge feature/optimization

则:

HEAD 代表 main 分支的当前内容
feature/optimization 代表即将合并进入的分支内容

5. 冲突文件的处理方式

处理冲突并非简单删除某一方的代码,而是需要根据业务需求确定最终的正确代码。

以上述冲突为例,可以选择:

int connectionLimit = 20;

也可以根据业务逻辑改写为:

int connectionLimit = loadLimitFromServer();

处理原则:

最终文件中必须完全移除 <<<<<<<、=======、>>>>>>> 标记
代码必须符合正确的业务逻辑

完成处理后执行:

git status
git add settings.cpp

此处 git add 的作用并非"准备提交新功能",而是:

向 Git 表明该文件的冲突已处理完毕

6. merge 冲突的标准处理流程

完整操作步骤:

git checkout main
git merge feature/optimization

若产生冲突,先检查状态:

git status

打开冲突文件,修改为期望的内容。

随后执行:

git add settings.cpp
git status
git commit

普通 merge 操作会生成一个 merge commit,Git 通常会自动准备好提交信息,直接保存即可。

7. rebase 冲突的标准处理流程

完整操作步骤:

git checkout feature/optimization
git rebase main

当某个提交应用时发生冲突,Git 会暂停 rebase 过程。

解决冲突后执行:

git add settings.cpp
git rebase --continue

若后续提交继续产生冲突,重复以下步骤:

修改冲突文件
执行 git add
执行 git rebase --continue

这一过程的特点在于:

merge 冲突是一次性解决
rebase 冲突则是逐个提交逐次解决

8. ours 和 theirs 的概念辨析

处理冲突时经常会使用以下命令:

git checkout --ours settings.cpp
git checkout --theirs settings.cpp

在 merge 操作中的语义为:

ours   当前所在分支的版本
theirs 被合并分支的版本

例如当前在 main 分支执行:

git merge feature/optimization

则:

ours   代表 main 分支
theirs 代表 feature/optimization 分支

若确定保留当前分支版本:

git checkout --ours settings.cpp
git add settings.cpp

若确定保留对方分支版本:

git checkout --theirs settings.cpp
git add settings.cpp

重要提醒:

不应仅因操作简便就直接保留整文件
多数冲突需要综合两边的逻辑进行整合

9. rebase 中 ours 和 theirs 的语义差异

在 rebase 操作中,ourstheirs 的含义与 merge 不同,容易产生混淆。

rebase 的执行原理是:

先切换到目标基础分支
随后将你的提交逐一应用上去

因此在 rebase 冲突场景下:

ours   通常代表目标基础分支的内容
theirs 通常代表正在被重新应用的提交内容

对于初学者,建议避免在 rebase 冲突中直接使用:

git checkout --ours
git checkout --theirs

更稳妥的做法是:

打开冲突文件
理解冲突的上下文环境
手动修改为最终期望的代码

10. 如何终止 merge 操作

若在 merge 过程中改变主意不想继续:

git merge --abort

此命令会尝试恢复至 merge 执行前的状态。

适用场景:

冲突数量过多,想换一种合并策略
发现合并到了错误的分支
尚未准备好处理这些冲突

执行后通过以下命令确认:

git status

确保仓库已恢复到正常状态。

11. 如何终止 rebase 操作

若在 rebase 过程中不想继续:

git rebase --abort

此命令会完全回退至 rebase 开始前的状态。

其他相关操作:

若已解决当前冲突并希望继续:git rebase --continue
若想跳过当前这个提交:git rebase --skip

使用 --skip 时需谨慎,因为它意味着该提交会被丢弃。

12. 冲突解决后的验证工作

处理完冲突后,不仅要确保 Git 不报错,还需验证代码逻辑的正确性。

建议的检查顺序:

git status
git diff --cached

随后根据项目实际情况执行构建和测试:

cmake --build build
ctest --test-dir build

至少应运行当前修改模块的相关测试。

冲突处理中最容易出现的问题不是语法错误,而是:

两边的逻辑都被保留,但合并后语义错误
虽然删除了冲突标记,却误删了必要的代码逻辑
代码能够编译,但配置、路径或条件判断错误

13. 减少冲突的实用建议

虽然无法完全避免冲突,但可以通过良好的开发习惯减少其发生:

1. 功能分支应尽快完成,避免长期存在
2. 定期 fetch 并同步主分支的最新内容
3. 单一提交中不要混合多个不相关的修改
4. 代码格式调整与业务逻辑修改分开提交
5. 修改公共头文件或配置文件时格外谨慎
6. 合并前先检查 git status,确保工作区干净

在 C++ 项目中,以下文件类型最容易引发多人冲突:

CMakeLists.txt
公共头文件
配置文件
README.md
接口定义文件

修改这些文件前,建议先同步最新版本的主分支。

14. 核心要点总结

冲突的本质是 Git 无法自动判定最终应保留的内容。

处理流程总结:先通过 git status 定位冲突文件,然后手动修改为正确的代码,最后使用 git add 标记冲突已解决;若操作方向错误,可使用 merge --abortrebase --abort 回退。

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。