git merge 把另一个分支的改动整合进当前分支。结果分两种:能直接快进(fast-forward)时只移动指针;不能直接快进时生成一个有两个父提交的合并提交。

本文列出 git merge 的常用参数,重点讲 --no-ff、--ff-only、--squash 三种策略对历史形状的影响,以及冲突时的续作命令。

ℹ️
关于本系列
本文是《Git 使用教程》按命令拆分的第 21 / 28 篇,全部收录在 Git 栏目。参数表列的是日常高频项,并非穷举;想看某个命令的完整参数,用 git merge -h 看精简列表、git help merge 看完整手册。示例以 Git 2.56.0 为准。

一、命令语法

先看语法骨架,再对照下一节的参数表。<占位> 表示必填值,实际输入时不要带尖括号;[...] 表示可选项,-- 用来分隔选项与路径。

bash语法
git merge [<options>] <commit>...

二、参数逐项详解

下表按用途列出 git merge 的常用参数,每项都注明了「它到底改变了什么」。

参数作用
<commit>要合进来的分支、标签或提交,通常是功能分支名
--no-ff即使能快进也生成合并提交,保留「这里合过一个分支」的痕迹
--ff-only只允许快进,不满足就报错退出;发布分支保持线性历史时最安全
--squash把对方改动压成工作区/暂存区的一堆改动,不生成合并提交,自己再 commit 一次
-m <信息> / --no-edit指定合并提交信息 / 沿用自动生成的信息
-e / --edit提交前打开编辑器修改合并信息
--abort冲突时放弃合并,回到合并前的状态(有未提交改动时先 stash)
--continue解决冲突并 add 之后继续完成合并
--quit退出合并状态但保留工作区与索引里已解决的冲突
-s <策略> / --strategy指定合并策略,如 ort(默认)、recursive、octopus
-X <选项> / --strategy-option给策略传参,如 -X ours / -X theirs 冲突时偏向某一边
--no-commit整合改动但不自动落合并提交,便于提交前再检查
--stat / -n显示合并摘要 / 只演练不执行(--stat --no-commit 组合常用)

三种策略会留下什么历史

参数结果适合
默认(可快进)只移动指针,无合并提交个人小分支、追求线性
--no-ff一定有合并提交团队需要按功能回溯、方便整体 revert
--ff-only不能快进就失败发布分支、CI 自动更新
--squash无合并提交,改动压成一次新提交功能分支提交太碎,想保持主干干净

三、常用示例

标准合并流程

bash标准合并流程
git switch main
git fetch --prune
git merge --no-ff feature/login -m "merge: 合并登录功能"
git push origin main

冲突处理

bash冲突处理
git merge feature/payment
# Auto-merging ... CONFLICT (content)
git status -s                     # 找 UU 文件
git diff --check                  # 检查残留冲突标记
git add src/order.js
git merge --continue
# 或者整段放弃
git merge --abort

保持线性 / 压平提交

bash保持线性 / 压平提交
git merge --ff-only origin/main
git merge --squash feature/experiment
git commit -m "feat: 一次性合入实验功能"

四、注意事项

⚠️
合并前先确认自己在哪条分支
git merge A 是「把 A 合进当前分支」,方向反了会得到完全相反的结果。动手前 git status -sb 看一眼。另外工作区有未提交改动时,合并可能产生难以收拾的混合状态,先 stash 或先提交。
冲突标记要清干净: 解决完跑 git diff --check,它会报出残留的 <<<<<<< 标记与行尾空白,比肉眼扫一遍可靠。

五、小结

git merge 的参数其实在替团队回答一个问题:历史要不要留下「合并过」这个事实。要留用 --no-ff,不要留用 --ff-only 或 --squash。定下规范后写进团队文档,比每次临时争论更高效。

本系列共 28 篇,一个命令一篇,完整目录见 Git 栏目。下一篇:git tag 命令参数详解。