git merge --squash 和 git merge 的区别
区别
git merge --squash会把一个分支的所有提交“压扁成一次提交”,但不会保留分支历史;git merge会完整保留分支上的每一次提交和分支结构。
区别对比表
| 对比点 | git merge | git merge --squash |
|---|---|---|
| 提交历史 | 保留全部 commit | 不保留原 commit |
| 是否生成 merge commit | 通常 ✓(除 fast-forward) | 不生成 |
| 提交作者信息 | 原作者全部保留 | 只保留 squash 后的作者 |
| git log 是否能看到分支 | 能看到 | 看不到 |
| git blame 友好度 | 高 | 较低 |
| 是否自动 commit | 是 | 否(需手动 commit) |
| 是否记录“已合并状态” | 是 | 否 |
1. 普通 git merge(保留历史)
命令
git checkout main
git merge feature/login
发生什么?
feature/login的 每一个 commit 都进入main可能生成一个 merge commit
Git 知道这个分支已经合并过
提交历史示意
A---B---C---M
\ /
D---E
适合场景
团队协作
需要保留开发过程
代码审计 / 回溯
长期维护项目
2. git merge --squash(压缩提交)
命令
git checkout main
git merge --squash feature/login
git commit -m "Add login feature"
发生什么?
Git 把 feature/login 的代码改动一次性应用
不带任何 commit 历史
需要你 手动提交
提交历史示意
A---B---C---S
S= squash 后的一次提交
Squash merge 不会记录分支已合并
意味着:
git merge --squash feature/login
之后:
git merge feature/login
Git 会认为它从没合并过!
这可能导致:
重复冲突
重复代码
通常 squash 后应删除 feature 分支
3. fast-forward merge
如果 main 没有新提交:
git merge feature/login
会变成:
A---B---C---D---E
无 merge commit
历史非常干净
4. GitHub / GitLab 上的 Squash Merge
平台上的 Squash and merge:
原理等同
git merge --squash但:
会记录 PR 关联关系
更安全
更推荐
5. 什么时候用 squash?什么时候不用?
适合用 squash 的场景
功能分支提交杂乱
修 bug 提交很多
“WIP / fix typo / try again”
主分支追求 线性历史
主分支只关心“做了什么”,不关心“怎么做的”
不适合 squash 的场景
需要详细开发历史
开源项目
长期维护分支
需要精确 blame
6. 团队策略
最常见、最好用
feature 分支:随便 commit
合并到 main:Squash merge
main 永远干净、线性