您可以捐助,支持我们的公益事业。

1元 10元 50元





认证码:  验证码,看不清楚?请点击刷新验证码 必填



  求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Model Center 汽车系统工程   模型库
    学习助手
会员   
   
AI智能体开发技术实践
厦门 9月17-18日;线上 10月22-23日
OCSMP 认证培训
9月23-24日 北京+线上
UAF架构体系实践
9月22-23日 北京+线上
     
   
 订阅
Git 提交历史太乱?分清 Merge、Rebase 和 Squash
 
作者: Nonoas
  10   次浏览      4 次
 2026-9-28
 
编辑推荐:
本文主要讲清了 Git 里 Merge、Rebase、Squash 三种"合入代码"方式各自解决什么问题——Merge 保留真实分支结构、Rebase 改写基线让历史成直线、Squash 把一堆零散提交压成一个完整提交——并给出各自的适用场景、常用命令和"别对多人共用的已推送分支乱用 Rebase"这类边界。希望对你的学习有帮助。
本文来自于微信公众号脑补空间,由火龙果软件Alice编辑、推荐。

同一个功能分支,最后都能“合进主分支”,为什么 Git 还要提供 Merge、Rebase 和 Squash?

因为它们处理的并不是同一件事。

Merge 负责汇合分支,Rebase 负责改写提交的起点,Squash 负责压缩提交数量。 三者都会影响最终代码,但留下的提交历史完全不同。

先记住这个简化版判断:

  • 想完整保留两条分支如何汇合,用 Merge。
  • 想让自己的功能分支跟上主分支,同时保持线性历史,用 Rebase。
  • 想把一串“修一下、再修一下”的提交收成一个完整功能,用 Squash。

Merge:把两条历史汇合起来

Merge 不会改写已有提交。它找到两个分支的共同祖先,把双方变化汇合,并在需要时生成一个 merge commit。

这意味着提交历史会保留真实的分支结构:功能从哪里开始、何时合入主线,都能看出来。

适合这些场景:

  • 多人共同维护、已经推送的分支;
  • 希望保留完整开发过程;
  • 发布分支、长期分支之间的合并;
  • 团队更看重操作稳妥,而不是提交图绝对整齐。

把feature/payment功能分支合入 main:

git switch main
git pull --ff-only
git merge --no-ff feature/payment
git push origin main

--no-ff 会明确生成一次 merge commit。以后回看历史时,可以一眼看出这批改动来自哪个功能分支。如果团队允许 fast-forward,也可以直接执行:

git merge feature/payment

发生冲突时:

git status
# 编辑冲突文件
git add <已解决的文件>
git merge --continue

不想继续这次合并:

git merge --abort

Merge 的代价也很直观:分支多、合并频繁时,提交图容易出现大量交叉线和 merge commit。它保留了现场,也保留了现场的复杂度。

Rebase:把提交搬到新的基线上

假设你从 main 拉出功能分支后,主分支又向前走了几个提交。Rebase 会先取下你的功能提交,把分支基线移动到最新的 main,再逐个重放这些提交。

结果看上去像是:你一开始就是基于最新主分支开发的。

同步最新主分支的常用命令:

git switch feature/payment
git fetch origin
git rebase origin/main

遇到冲突时:

git status
# 编辑冲突文件
git add <已解决的文件>
git rebase --continue

如果发现方向不对,可以退回 Rebase 开始前:

git rebase --abort

完成后,如果这个分支从未推送过:

git push -u origin feature/payment

如果分支之前已经推送,并且只有你自己在使用:

git push --force-with-lease origin feature/payment

这里不要随手换成 --force。--force-with-lease 会先确认远端分支仍是你预期的状态,能减少覆盖别人新提交的风险。

Rebase 适合个人功能分支,也适合提交合并请求前同步主线。它能让历史保持线性,代码审查和问题定位通常更轻松。

但它有一条明确边界:不要随意 Rebase 多人共用、已经发布的分支。 Rebase 会为被重放的提交生成新的哈希。别人如果仍基于旧提交继续工作,下一次同步会很难受。

Squash:把多个提交压成一个

Squash 不是另一种“同步主分支”的方法。它解决的是提交粒度问题,用于将多个提交合并成一个。

比如,开发过程中进行了4次提交,提交信息如下:

feat: add payment form
fix: correct button state
fix: lint
fix: really fix lint

这些记录可能都是开发同一个需求的时候产生的,对开发者当时有用,但对于主分支并不需要知道这么细节。Squash 可以把它们整理成一个完整提交:

feat: add payment flow

最省事的做法,是在合入主分支时执行 squash merge:

git switch main
git pull --ff-only
git merge --squash feature/payment
git commit -m "feat: add payment flow"
git push origin main

注意,git merge --squash 只会把功能分支的最终变化放入暂存区,不会自动提交,也不会生成 merge commit。因此下一条 git commit 不能省。

GitHub、GitLab 等平台里的 “Squash and merge”,通常就是把一个合并请求压成一个提交后再放进目标分支。

如果希望在提交合并请求前整理当前分支,可以使用交互式 Rebase。比如压缩最近 4 个提交:

git switch feature/payment
git rebase -i HEAD~4

编辑器打开后,保留第一行的 pick,把后续提交改成 fixup 或 squash:

pick   a1b2c3d feat: add payment form
fixup  b2c3d4e fix: correct button state
fixup  c3d4e5f fix: lint
fixup  d4e5f6g fix: really fix lint

fixup 会丢弃后续提交信息,squash 会让你重新整理提交信息。保存退出后,如果这个分支已经推送过,再执行:

git push --force-with-lease origin feature/payment

Squash 很适合短期功能分支。一个功能完成后,对应主分支中的一个提交,回滚和阅读都很直接。

它也有代价:中间提交的上下文会消失。对于需要保留阶段性决策、多人长期协作的分支,不要为了“历史好看”把所有东西都压平。

实际工作中怎么选

三者不是互斥选项。很多团队采用的是组合流程:

# 先在个人功能分支上同步最新主线
git switch feature/payment
git fetch origin
git rebase origin/main

# 测试通过后推送更新
git push --force-with-lease origin feature/payment

# 合并请求通过后,在平台选择 Squash and merge

这种方式让功能分支保持最新,同时让 main 中每个功能只留下一个清晰提交。

如果团队希望保留完整分支关系,则可以换成:

git switch main
git pull --ff-only
git merge --no-ff feature/payment
git push origin main

选择时看三个问题就够了:

  1. 这个分支是否已经被多人使用?是的话,优先 Merge,谨慎 Rebase。
  2. 中间提交是否有长期保留价值?有的话保留;没有的话可以 Squash。
  3. 团队希望看到真实分支结构,还是更偏好线性主线?前者用 Merge,后者常用 Rebase 配合 Squash。

一份可以保存的速查

合并分支并保留分支结构:

git switch feature/payment
git fetch origin
git rebase origin/main
git push --force-with-lease origin feature/payment

让个人功能分支基于最新主线:

git switch feature/payment
git fetch origin
git rebase origin/main
git push --force-with-lease origin feature/payment

把整个功能分支压成一个提交:

git switch main
git pull --ff-only
git merge --squash feature/payment
git commit -m "feat: add payment flow"
git push origin main

整理当前分支最近 4 个提交:

git rebase -i HEAD~4

真正需要统一的,不是所有人的 Git 历史长得一模一样,而是团队对历史用途有相同理解:哪些过程值得留下,哪些噪音应该收起,哪些已经公开的提交不能再随意改写。

 

 

 
   
10   次浏览       4 次
相关文章

每日构建解决方案
如何制定有效的配置管理流程
配置管理主要活动及实现方法
构建管理入门
相关文档

配置管理流程
配置管理白皮书
CM09_C配置管理标准
使用SVN进行版本控制
相关课程

配置管理实践
配置管理方法、工具与应用
多层次集成配置管理
产品发布管理

最新活动计划
AI智能体开发实践 9-17厦门/10-22在线
OCSMP 认证培训 9-23[在线]
企业架构方法与实践 9-15[深圳]
UAF架构体系与实践 9-22[北京]
AI系统的测试方法与工具 9-17[北京]
AI时代的软件架构师培养 9-19[上海]
AI时代的需求分析师培养 10-20[北京]
 
 
最新文章
git原理图解
Git分支管理实践
Git学习和项目应用实例
Git 天天用 但是 Git 原理你了解吗?
对比 Git 与 SVN,这篇讲的很易懂
最新课程
Git版本控制系统
配置管理与持续集成实践
配置管理方法、实践、工具与应用
持续集成与敏捷开发
配置管理实践(从组织级到项目级)
更多...   
成功案例
某单位研发中心 产品集成与服务平台
某电子制造商 配置管理与持续集成
北京 配置管理与持续集成实践
金雅拓 分布式持续集成工具链
北京 持续集成测试最佳实践
更多...