首页 / Git 入门教程 / 分支合并与冲突解决

Git 入门教程

分支合并与冲突解决

本教程共 26 篇 · 第 10 篇 · 更新于 2026-07-29 · 约 8 分钟阅读

GitGit 入门教程分支合并git merge冲突解决三方合并快进合并

10. 分支合并与冲突解决

本节目标:理解 git merge 的快进和三方合并两种模式,学会识别并手动解决代码冲突,让分支修得掉也合得拢。

分支存在的意义,最终都要回到合并上。写好的功能、修完的 bug,不合并回主线就只是自嗨。Git 的 merge 就是把两条分叉的时间线重新拧成一股。

merge 的基本用法

合并前,先确认你在”要合并到哪个分支”上。想把 feature 合进 main,就先切到 main

git switch main          # 旧写法:git checkout main
git merge feature

一句话解释:把 feature 分支的修改并入当前分支(main)。

快进合并(Fast-forward)

最简单的合并场景:目标分支没有新提交。

你在 main 上创建了 feature,然后只在 feature 上提交了两次。这期间 main 原地没动。Git 要做的只是把 main 指针往前挪到 feature 的位置。

git merge feature
Updating a1b2c3d..f4e5d6c
Fast-forward
 feature.py | 10 ++++++++++
 1 file changed, 10 insertions(+)

输出里那个 Fast-forward 就是关键信号。这种合并没有额外提交,也没有冲突风险,干净利落。

三方合并(Three-way merge)

现实没这么一帆风顺。如果 main 在你开发期间也往前走了一步,两条线就分叉了。Git 没法再简单地挪指针,只能做”三方合并”。

它取出三个快照:两条分支各自的最新提交、以及它们的共同祖先。三者一比对,生成一个全新的”合并提交”。

git merge feature
Merge made by the 'recursive' strategy.
 readme.md | 2 ++
 1 file changed, 2 insertions(+)

这个合并提交有两个父提交,所以提交历史会出现一个倒 V 字形。用 --graph 看就很直观。

git log --oneline --graph
*   abc1234 (HEAD -> main) Merge branch 'feature'
|\
| * def5678 (feature) 添加新功能
* | 9f0g1h2 修复主线的一个错别字
|/
* a1b2c3d 共同祖先

当冲突发生时

如果你和同事改了同一个文件的同一行,Git 就懵了。它做不了决定,把球踢回给你。

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

Git 没有创建合并提交,整个合并流程暂停。你的工作目录里,冲突文件会被塞进一堆标记。打开冲突文件,能看到这样的结构:

<<<<<<< HEAD
<button class="btn-primary">确认</button>
=======
<button class="btn-submit">确定</button>
>>>>>>> feature
  • <<<<<<< HEAD======= 之间:你在当前分支上的版本。
  • =======>>>>>>> feature 之间:要合并进来的分支版本。

你的任务就是决定:要哪边?还是两边都留?还是重写?

解决冲突的四个步骤

假设最终你决定用”确认”这个文案,同时保留对方的样式类。

  1. 编辑文件,删掉所有冲突标记,留下你想要的内容。
<button class="btn-submit">确认</button>
  1. 把解决后的文件标记为已解决。
git add index.html
  1. 检查是否还有其它冲突文件。
git status
  1. 提交合并结果。
git commit

Git 会自动生成类似 “Merge branch ‘feature’” 的提交信息,直接保存即可。

想反悔怎么办

解决到一半发现搞砸了,可以用 git merge --abort 一键回到合并前的状态。

git merge --abort

abort 在合并冲突、工作目录脏乱但有暂存内容时都能救场。但要记住,工作目录里未提交的改动可能会丢,所以合并前尽量保持干净状态。

除了 --abort,也可以用 git reset --hard HEAD 回到合并前最后一次提交。更暴力,也更彻底,所有未提交的改动都消失。用前三思。

有时候空白在捣鬼

合并报错,打开文件一看其实逻辑上没冲突,纯粹是缩进或换行符在搞事。Git 提供了两个参数来忽略这类差异:

git merge -Xignore-all-space feature      # 完全忽略空白
git merge -Xignore-space-change feature    # 把多个空白当作等价

只想选一边

某些场景下,你明确知道要哪个版本。-Xours-Xtheirs 能直接站队。

git merge -Xours feature     # 所有冲突自动选当前分支版本
git merge -Xtheirs feature   # 所有冲突自动选要合并分支的版本

注意:非冲突部分还是正常合并。这两个选项只影响冲突部分。

图形化工具来帮忙

如果你看标记眼花了,git mergetool 可以启动可视化工具。

git mergetool

Git 会按顺序弹出每个冲突文件的三方对比界面。改完保存,Git 自动把文件标记为已解决。

本章小卡片

场景命令
合并分支git merge <branch>
中断合并git merge --abort
忽略空白合并git merge -Xignore-space-change <branch>
冲突时选当前分支git merge -Xours <branch>
冲突时选对方分支git merge -Xtheirs <branch>
启动合并工具git mergetool
Note

合并前先 git status 确认工作目录干净。有未提交的改动就合并,大概率会被拒绝或者把历史搅浑。