git merge --no-ff 是什么
加 --no-ff 之后,即使目标分支可以直接快进,Git 也会强制生成一个合并提交。这样历史里就留下了一个明确的合并点,能看出这一组提交是作为一个特性整体合入的。评审与回溯时,这个边界比一串混在一起的提交有用得多。
它和其他合并方式的区别
默认快进会把分支指针直接前移,看不出曾经有过分支;--squash 把差异压成一次待提交的改动,连提交历史都不保留;--no-ff 居中:既保留被合入分支的全部提交,又额外留下一个合并点。配合 --first-parent 查看主干时,这些合并点就像主干上的里程碑。
基本信息
| 适用平台 | Linux / macOS / Windows(Git 2.x) |
|---|---|
| 语法 | git merge --no-ff -m '描述' <分支> |
| 效果 | 即使可以快进也生成合并提交 |
| 默认配置 | git config merge.ff false 可设为默认行为 |
| 配套查看 | git log --first-parent 只看主干线 |
| 与 squash 区别 | squash 不保留被合入分支的提交 |
典型使用场景
- 保留特性边界:历史里能看到某个特性作为整体被合入
- 主干里程碑:用合并点标记每一次功能集成
- 便于回退:需要整体撤销某个特性时,合并点提供了清晰边界
- 团队规范:约定主干只接受带合并点的合入,历史更整齐
- 发布整理:发版前按合并点梳理变更清单
常用示例
常用示例
git switch main
git merge --no-ff -m 'Merge feature/login' feature/login
git log --oneline --graph -15
git log --oneline --first-parent -10 # 只看主干上的提交与合并点
git config merge.ff false # 让 --no-ff 成为默认行为三种合入方式对比
| 方式 | 分支内提交 | 合并点 | 历史形态 |
|---|---|---|---|
| 默认快进 | 保留 | 无 | 线性,看不出分支 |
| --no-ff | 保留 | 有 | 线性主干加合并点 |
| --squash | 压成一次改动 | 无 | 完全线性,无分支痕迹 |
合并提交的第二个父提交指向被合入分支的顶端,用 git log --first-parent 就能只看主干主线上的提交,跳过分支内部的细节。
对长期存在的分支频繁制造合并提交会让历史噪声明显增大。团队需要先约定在主干还是特性分支上做合并提交。