news 2026/5/5 5:39:38

Git merge 的几种不同模式

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Git merge 的几种不同模式

Git 中的 merge 可以理解为:把另一个分支上的修改合并到当前分支。不同合并模式的区别,是合并后提交历史如何呈现、是否保留分支痕迹,以及是否重写提交记录。

下面以 main 分支和 feature 分支为例,对常见合并方式进行说明。

main: A---B---C

feature: \---D---E

其中,D、E 表示在 feature 分支上完成的两个提交。


1. Fast-forward merge:快进合并

基本含义

Fast-forward merge 是最简单的一类合并。它发生在当前分支从创建 feature 分支之后没有新的提交时,Git 不需要额外创建合并提交,只需要把当前分支指针直接移动到 feature 分支的最新提交。

合并前:

合并后:

常用命令

git switch main git merge feature

如果 Git 判断可以快进,就会自动执行 fast-forward merge。也可以使用下面的命令强制只允许快进合并:

git merge --ff-only feature

这条命令的意思是:如果能够快进就合并;如果不能快进,就直接报错,不创建额外的 merge commit。

特点

此时 feature 分支上包含:

A---B---C---D

main 也包含:

A---B---C---D

也就是说,feature 上的内容没有消失,只是 main 也走到了同一个位置。可以理解成:原来 feature 比 main 领先两个提交;FF merge 后,main 追上了 feature;两者现在站在同一个提交点上。

优点是提交历史非常干净,最终看起来是一条直线;缺点是分支开发的痕迹不明显,后续不容易看出某几个提交原本属于同一个功能分支。


2. No-fast-forward merge:非快进合并

基本含义

No-fast-forward merge 表示即使当前场景可以直接快进,也强制创建一个新的合并提交。这个新的提交通常被称为 merge commit,用来记录某个功能分支被合并进主分支。

合并后:

其中,M 就是新增的 merge commit。

常用命令

git switch main git merge --no-ff feature

特点

优点是可以保留分支结构,能够清楚看出 C、D 是作为一个完整功能分支开发后合并进来的;缺点是提交历史中会多出 merge commit,历史线条不如纯直线简洁。

这种方式适合比较正式的功能开发,例如登录模块、支付模块、实验性功能等。因为这些内容本身就是一个相对完整的开发单元,保留分支痕迹反而更利于后续回溯。


3. Three-way merge:三方合并

基本含义

Three-way merge 严格来说不是一个需要单独手动选择的模式,而是 Git 在无法快进合并时自动采用的合并方式。当 main 和 feature 在共同祖先之后各自都有新提交时,Git 不能简单移动分支指针,只能根据三个版本进行合并。

合并前:

合并后:

三方合并中的“三方”分别是:共同祖先 B、当前分支最新提交 C,以及被合并分支最新提交 E。Git 会比较 C 和 E 相对于 B 的变化,然后尝试把两边的修改合在一起。

常用命令

git switch main git merge feature

特点

如果两边修改的内容不冲突,Git 可以自动合并;如果两边修改了同一文件的同一位置,就可能出现 conflict,需要手动解决冲突后再提交。


4. Squash merge:压缩合并

基本含义

Squash merge 会把 feature 分支上的多个提交压缩成一个新的提交,再放到 main 分支上。它不会把 feature 分支上的原始提交 C、D、E 原样带入 main,而是生成一个包含全部修改的新提交 S。

合并前:

合并后:

常用命令

git switch main git merge --squash feature git commit -m "add feature"

git merge --squash feature 之后,Git 只是把 feature 分支上的改动放入暂存区,并不会自动提交,因此还需要手动执行 git commit。

特点

优点是主分支历史非常简洁,通常可以做到一个功能对应一个提交;缺点是 feature 分支上原来的多个提交记录不会原样进入 main。

这种方式适合 feature 分支提交比较杂乱的情况,例如提交信息中有 fix、debug、try、test 等临时提交。将这些过程性提交压缩成一个清晰提交,可以提高主分支历史的可读性。


5. Rebase merge:变基后合并

基本含义

Rebase 本身不是 git merge 命令的一种参数,但在实际开发和 GitHub Pull Request 中经常与 merge 放在一起讨论。它的核心思想是:把 feature 分支上的提交搬到 main 分支的最新提交后面。

原始状态:

rebase 后:

这里的 D'、E' 不是原来的 D、E,而是 Git 根据新的基础重新生成的提交,因此 rebase 会重写提交历史。

常用命令

git switch feature git fetch origin git rebase origin/main

完成 rebase 后,如果要把 feature 合并回 main,通常可以执行 fast-forward 合并:

git switch main git merge --ff-only feature

最终主分支历史会变成一条直线:

特点

优点是主分支历史保持线性,看起来非常清楚;缺点是会改写 feature 分支的提交历史。如果该分支已经被多人共享,不建议随意 rebase。

rebase 后 push

如果这个 feature 分支之前没 push 过,

git push origin feature

远程 GitHub 上还没有这个 feature 分支,不存在历史冲突。直接push

如果这个 feature 分支之前已经 push 过

原来可能是:

rebase 之后变成:

普通 push 很可能会失败,这时候应该用:

git push --force-with-lease origin feature

它的意思是:如果远程 feature 没有被更新过,就允许覆盖;如果别人已经推了新提交,就拒绝覆盖。


6. 几种模式的对比

模式

常用命令

历史形状

是否保留分支痕迹

适合场景

Fast-forward

git merge feature

直线

不明显

main 没有新提交时

No-ff merge

git merge --no-ff feature

有分叉和合并点

保留

正式功能分支

Three-way merge

git merge feature

有 merge commit

保留

main 和 feature 都有新提交

Squash merge

git merge --squash feature

直线

不保留原提交

feature 提交较乱

Rebase + merge

git rebase + merge --ff-only

直线

不保留原分叉

追求干净线性历史

fast-forward:直接把 main 指针往前挪
--no-ff:保留分支痕迹,生成 merge commit
three-way:两边都改了,Git 找共同祖先合并
squash:把一整个分支压成一个提交
rebase:把自己的提交搬到 main 最新提交后面


7.GitHub Merge

GitHub Pull Request 中常见的三个按钮,通常对应 Merge commit、Squash merge 和 Rebase merge。

情况一:本地合并进 main,然后 push main

git switch main git merge feature git push origin main

等价于在本地直接做了最终合并。不需要 GitHub PR merge

但团队开发通常是另一种流程:本地只 push feature,然后在 GitHub 点 PR

git switch feature git push origin feature

然后 GitHub 上点:

Squash and merge

或者:

Create merge commit

或:

Rebase and merge

这时最终合并由 GitHub 完成


一般的PR 流程

git switch feature git add . git commit -m "add login page" git push origin feature

然后到 GitHub 上创建 PR:feature → main

审核通过后,在 GitHub 上选择:

Merge commit / Squash merge / Rebase merge

实现最终合并。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/5 5:29:26

测试可移植python解释器pocketpy

在微信公众号文章中看到它,一个c文件就能解析python,感到很神奇,到github存储库https://github.com/pocketpy/pocketpy,下载了2.1.8版头文件(https://github.com/pocketpy/pocketpy/releases/download/v2.1.8/pocketpy…

作者头像 李华
网站建设 2026/5/5 5:26:30

别急着给 Claude Code 接一堆 MCP

别急着给 Claude Code 接一堆 MCP很多人熟练使用 Claude Code 之后,会自然进入下一步: 既然 Claude Code 能读项目、能跑命令、能记规则,那是不是应该把 GitHub、Sentry、数据库、Figma全接上,再装几十个 subagents,让…

作者头像 李华
网站建设 2026/5/5 5:26:27

Authy:为AI智能体设计的本地化密钥保险库与安全注入方案

1. 项目概述:为AI智能体打造的本地化密钥保险库如果你和我一样,日常工作中需要频繁地与各种AI助手(比如Claude、Cursor、Windsurf)打交道,并且经常需要让它们执行一些需要访问敏感信息的任务——比如部署脚本、连接数据…

作者头像 李华
网站建设 2026/5/5 5:25:30

网络状态验证实践:从CoPAW项目看自动化运维闭环构建

1. 项目概述与核心价值最近在梳理一些开源项目时,发现了一个挺有意思的仓库:jsirish/copaw-phase2-enhancement。这个项目名乍一看有点抽象,但如果你对网络自动化、特别是基于意图的网络(IBN)和网络状态验证&#xff0…

作者头像 李华
网站建设 2026/5/5 5:25:29

空间智能评估:层次化框架与动态权重实践

1. 空间智能评估的行业痛点与破局思路在智慧城市、工业物联网和数字孪生等领域,空间智能系统的评估一直存在三大核心痛点:评估维度单一化、指标权重主观化、结果解读片面化。传统评估方法往往只关注设备密度或连接数量这类表面数据,却忽视了系…

作者头像 李华
网站建设 2026/5/5 5:24:39

基于.NET MAUI的ChatGPT客户端开发实战:从架构到发布

1. 项目概述与核心价值 最近在捣鼓 .NET MAUI,想找个有意思的练手项目,正好看到社区里 Daniel Monettelli 大佬开源的这个 ChatGPT 客户端。作为一个全栈老鸟,我第一眼就被它吸引了:这不仅仅是一个简单的 API 调用 Demo&#xff…

作者头像 李华