TL;DR
merge是把两个分支的历史 合并,并生成一个 merge commit
rebase是把当前分支的提交 重新应用到目标分支后面,从而 重写提交历史
1️. merge 的特点
例如:
A---B---C main
\
D---E feature
执行:
git merge feature结果:
A---B---C------F main
\ /
D---E---
特点:
- 会产生 merge commit
- 不会修改历史
- 能看到真实的分支结构
- 适合团队协作
2️. rebase 的特点
执行:
git rebase main结果:
A---B---C---D'---E' feature
特点:
- 把 feature 的提交复制到 main 后面
- commit hash 会改变
- 历史变成线性
- 没有 merge commit
3️. 使用建议
一般实践是:
- 公共分支(main / develop) → 用 merge
- 个人开发分支 → 可以用 rebase 整理历史
同时有一个重要原则:
不要 rebase 已经 push 的公共分支,因为会改写历史
问题1:为什么 rebase 会改变 commit hash?
因为 Git 的 commit hash 是由以下内容计算的:
commit hash = hash(commit内容 + parent commit)
rebase 会改变:parent commit,所以 hash 一定会变
问题2:为什么团队开发不建议 rebase?
假设:你 push 了:
A---B---C
\
D---E
别人已经 pull
如果你 rebase:
A---B---C---D'---E'
别人本地是:D E,远程是:D' E'
Git 会认为:两条完全不同的历史,结果就是 大量冲突或重复 commit
问题3:为什么很多项目喜欢线性历史?
因为 git log 更清晰:
A
B
C
D
E
而不是:
A
|\
| D
| E
C
例如 Linux kernel, LLVM, Chromium 都会在 merge 前 rebase