git merge
文章目录
1.简介
git merge 用于将两个或多个分支的修改合并到一起。通常用于将功能分支(feature)合并回主分支(main)。
合并时,Git 会根据分支的提交历史自动选择合并策略:
- 快进合并(Fast-forward):当前分支没有新提交,直接将指针向前移动
- 三方合并(3-Way Merge):两个分支都有新提交,创建一个新的合并提交
2.格式
git merge [<options>] <branch>
git merge (--continue | --abort | --quit)
3.选项
--ff
当前分支完全包含了被合并分支的提交时,应如何处理合并。-ff 是允许快进(默认)。
快进(Fast-Forward) 是 Git 合并时的一种特殊情况:当目标分支(如 main)自创建功能分支(如 feature)以来没有产生新的提交时,只需将 main 的指针直接向前移动到 feature 的最新提交,就像“顺着链条快进”一样,不创建新的合并提交,历史变成一条直线。
--no-ff
禁用快进合并,强制创建合并提交
--ff-only
只允许快进合并,否则报错。
--squash
压缩合并,将多个提交合并为一个变更(不创建合并提交)
--abort
中止当前有冲突的合并
--quit
就地停止:忘记当前合并,不再继续。但保留工作区和暂存区的所有修改(包括冲突和已解决的内容)
--continue
解决冲突后继续合并
-m <msg>
为合并提交指定消息
--no-commit
合并但不自动提交(用于进一步调整)
--stat
显示差异统计,即修改了多少个文件,多少行插入,多少行删除。默认行为
-n, --no-stat
不显示差异统计
-s, --strategy=<strategy>
指定合并策略,可以多次指定 -s,Git 会按顺序尝试,直到某个策略成功,单分支合并缺省 ort,多分支合并缺省 octopus
4.关键知识点
合并策略
Git 的合并策略是决定如何将两个或多个开发历史(分支)整合在一起的底层算法。它直接影响代码冲突的处理方式、合并结果的正确性以及执行的性能。Git 提供多种策略,可以在执行 git merge 时通过 -s 选项指定。
常用合并策略:
| 策略 | 别名 | 核心机制 | 适用场景 | 注意事项 |
|---|---|---|---|---|
ort |
无 | 递归三路合并,优化重命名与冲突处理 | 日常开发首选 | Git 2.34+ 默认,支持 -X 选项 |
recursive |
无 | 传统递归三路合并 | 兼容旧版本 Git(< 2.34) | 2.33 及之前默认策略 |
octopus |
无 | 不合并内容,直接将多个分支提交树叠加 | 同时合并 3 个及以上分支 | 不处理冲突,仅做简单拼接 |
resolve |
无 | 两分支三方合并,不检测重命名 | 极简合并场景 | 功能较弱,不推荐常规使用 |
ours |
无 | 完全忽略被合并分支的变更 | 标记已废弃分支或保留当前版本 | 不产生冲突,但会创建合并提交 |
subtree |
无 | 将合并限制在指定子目录内 | 合并子项目或模块到主仓库 | 需配合 -X subtree=<path> |
ort 是日常最好的默认策略,适合绝大部分场景。octopus 专治多分支合并,ours 用于丢弃变更,subtree 用于目录级别的合并。
5.示例
基础合并
# 切换到目标分支
git switch main
# 将 feature 分支合并到 main
git merge feature
禁用快进合并(推荐团队协作)
# 强制创建合并提交,保留分支历史
git merge --no-ff feature -m "merge feature: 添加用户登录功能"
只允许快进合并
# 如果不能快进则报错(常用于拉取上游更新)
git merge --ff-only origin/main
只允许快进合并的核心使用场景是:当你明确知道当前分支没有新提交,只是想“追上”上游分支的最新代码时,用它来防止意外创建合并提交。
压缩合并
假设分支历史如下:
main: A---B---C
\
feature: D---E---F
普通合并:
git switch main
git merge feature
结果:
main: A---B---C---------M
\ /
feature: D---E---F
- M 是合并提交,有两个父提交(C 和 F)
- feature 的所有提交(D、E、F)都保留在历史中
优点: 完整保留分支历史。
缺点: 历史中会包含大量零碎提交(如 fix typo、update 等)
使用 --squash 合并:
git switch main
# 将 feature 的所有提交压缩成一个变更
git merge --squash feature
git commit -m "feat: 添加用户登录功能"
结果:
main: A---B---C---S
feature: D---E---F
- S 是普通提交,不是合并提交
- feature 的所有变更被压缩成一个提交 S
- feature 分支的 D、E、F 提交不会进入 main 历史
优点: 主分支历史保持线性、整洁。
缺点: 丢失 feature 分支的详细开发历史。
一图看懂:

判断是否使用 --squash 选项最根本的标准是,待合并分支上的历史记录是否有意义。如果没有意义,建议使用 --squash 选项将其废弃。
解决冲突
# 尝试合并时出现冲突
git merge feature
# CONFLICT in main.go
# 手动解决冲突后
git add .
git merge --continue
# 或放弃合并
git merge --abort
完全忽略被合并分支的变更
有一种场景,当前特性分支为最新版本,但是发起 Merge Request 时存在冲突。此时需要解决冲突,需要先将 main 分支合并到当前分支,解决冲突的方式是放弃 main 分支的所有变更,即以当前特性分支为准,那么可以使用-s ours选项。
git merge -s ours main --no-ff -m "Merge branch 'main' into feature/foo"
注意: 这与 -X ours 有区别:-X ours 是"有冲突时选我方",冲突文件之外 main 的新文件还是会带入;-s ours 是"完全忽略 main 的所有变更",连新文件也不带。
6.注意
6.1 合并策略对比
| 场景 | 命令 | 效果 |
|---|---|---|
| 默认合并(可快进) | git merge feature |
直接移动指针,无合并提交 |
| 默认合并(不可快进) | git merge feature |
自动创建合并提交 |
| 强制创建合并提交 | git merge --no-ff feature |
总是创建合并提交,保留分支历史 |
| 只允许快进 | git merge --ff-only feature |
不能快进时报错 |
| 压缩合并 | git merge --squash feature |
将所有提交压缩为一个变更 |
6.2 查看合并历史
# 查看分支图(直观展示合并关系)
git log --oneline --graph --all
# 查看哪些分支已合并到当前分支
git branch --merged
# 查看哪些分支尚未合并到当前分支
git branch --no-merged
6.3 撤销合并
# 撤销最近一次合并(假设还没推送)
git reset --hard HEAD~1
# 如果已推送,使用 revert(保留历史)
git revert -m 1 HEAD
6.4 常用别名设置
git config --global alias.mnf "merge --no-ff"
git config --global alias.mffo "merge --ff-only"
# 使用别名
git mf feature
git mffo origin/main
别名解释与扩展:
-
git config --global alias.mnf "merge --no-ff":创建全局别名mnf,代表merge --no-ff。使用git mnf feature即可执行禁用快进的合并,强制创建合并提交,便于在团队协作中清晰保留功能分支的合并历史。 -
git config --global alias.mffo "merge --ff-only":创建全局别名mffo,代表merge --ff-only。使用git mffo origin/main可以确保只进行快进合并,如果无法快进(即当前分支有本地提交),则会报错并中止合并。这常用于安全地拉取上游更新,避免意外产生合并提交。
为何要设置别名?
- 提高效率:长命令变短命令,减少输入错误。
- 统一团队规范:团队成员配置相同的别名,可以确保使用一致的合并策略。
- 便于记忆:
mnf(merge no-ff)、mffo(merge ff-only) 等缩写直观易记。
更多实用别名建议:
# 压缩合并别名
git config --global alias.ms "merge --squash"
# 合并并自动提交(用于无冲突的常规合并)
git config --global alias.mc "merge --no-edit"
# 查看合并历史图
git config --global alias.lg "log --oneline --graph --all"
配置完成后,可以通过 git config --global --list | grep alias 查看所有已设置的别名。
7.小结
| 需求 | 命令 | 说明 |
|---|---|---|
| 普通合并 | git checkout main && git merge feature |
默认行为 |
| 强制创建合并提交 | git merge --no-ff feature |
保留分支历史,推荐团队协作 |
| 只允许快进 | git merge --ff-only upstream/main |
避免意外合并提交 |
| 压缩合并 | git merge --squash feature |
保持主干历史整洁 |
| 中止冲突合并 | git merge --abort |
安全退出冲突状态 |
| 解决冲突后继续 | git add . && git merge --continue |
继续合并 |
一句话总结:git merge 用于将不同分支的工作整合到一起。推荐团队协作使用 --no-ff 保留分支历史;遇到冲突时用 --abort 安全退出;合并前先用 git branch --merged 确认分支状态。
参考文献
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)