git merge 的 --no-ff 参数有什么作用

--no-ff 禁止快进合并:即使可以直接快进,也强制创建一个合并提交。作用是保留"这里曾经合并过一个功能分支"的历史痕迹,让分支拓扑清晰可见,回滚整组改动更容易。

最佳实践
Git 分支协作与合并示意

默认情况下,如果目标分支没有新提交,merge 会"快进"(fast-forward)——分支指针直接前移,不产生合并提交,历史上看不出这里曾有一条功能分支。 --no-ff 强制生成一个合并提交,把"这次合并"作为一个可见的节点留在历史里。

图解

默认快进(--ff):
main: A---B---C---D    (D 原属于 feature,看不出分支存在过)

--no-ff:
main: A---B-----------M  (M 是合并提交,"Merge branch 'feature-x'")
            \         /
feature-x:     C---D

为什么团队喜欢 --no-ff

  1. 特性边界清晰:git log --first-parent main 看到的就是一份"合并历史",每个合并点对应一个特性/PR;
  2. 回滚整组改动容易:git revert -m 1 <合并提交> 一次撤销整个特性;
  3. 配合分支删除:分支删了,拓扑仍在。

配置默认行为

git config --global merge.ff false     # 本机所有合并默认 --no-ff
# 只对特定分支(如 main)
git config branch.main.mergeoptions "--no-ff"

常见问题(FAQ)

Q:--no-ff 和 squash merge 怎么选?

--no-ff 保留功能分支的每个提交+合并节点(历史详尽);squash 压成一个提交(最干净)。要细节选前者,要简洁选后者。

Q:Git Flow 必须用 --no-ff 吗?

Git Flow 的分支模型依赖合并提交来标记特性边界,所以是它的惯例配置。GitHub Flow 下按团队喜好。

Q:--ff-only 又是什么?

相反方向:只允许快进,不能快进就报错。用于"我不想产生合并提交"的线性历史策略,常与 rebase 工作流搭配。

参考资料

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台