- 一句总结
git pull --rebase origin main = 先 fetch 更新 origin/main,再把你本地 main 上还没推送的提交一个一个“摘下来”并重新应用到远程最新的 origin/main 之上(即 rebase),最终使历史变成一条直线。1 先看一个简单图例(最直观)
假设远程和本地最初一致,都是
A → B:你在本地又提交了两个提交
C1、C2(还没push):此时远程有人推送了
D(你还没pull):执行
git pull --rebase origin main 后发生:fetch把远程更新到本地的origin/main(A-B-D)。
- rebase 的意思:把 main 上的独有提交 (C1, C2) 挪到 D 之后。Git的步骤是找到共同的祖先B,然后把本地的提交C1和C2摘下来,临时保存(patch)。然后将HEAD移动到origin/main(目标分支上)(也就是D)把之前摘下来的一个个提交应用到D之后。注意C1’\C2’不是原来的C1C2,而是新的提交对象(新的哈希值),因为它们的父节点变了。原来是基于B,现在是基于D。
结果:
2 rebase 和 merge 的对比(图示)
同样场景,使用
git pull(merge)会产生一个合并提交 M:用
rebase 则变成直线(没有 M):3 为什么 rebase 会“改提交”?
因为 rebase 是把每个本地提交“重新应用(replay)”在新的基底之上。重新应用会创建新的提交对象(新的父指向),所以这些提交的哈希会变——这是 重写历史 的行为。
-
git pull --rebase origin main实际等价于
先:
再(在本地 main 分支上):
4 什么时候应该用 rebase,什么时候不该用
推荐用 rebase:
- 你在本地做了一些未推送的提交,想把它们“接到”远程最新的基础上,保持线性历史(常见于 feature 分支整理历史)。
- 在把本地改动推到共享仓库前,把本地分支整理干净(例如在合并到主分支前用
rebase压缩/整理提交)。
不该用 rebase(或要小心):
- 不要对已经推送到公共远程并被其他人基于此继续开发的提交做 rebase —— 这会重写公共历史,给别人带来麻烦(需要强推
git push --force)。
- 在多人共享的长期
main分支上随意重写历史(危险)。
简单记法:可重写私人历史 / 不要重写公共历史。


