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

git-pull-or-pull—rebase

git-diff

git-revert-or-reset