Git Rebase:程序员又爱又怕的神器
很多程序员第一次听到 git rebase,心里都会有点发怵。
因为它不像 git merge 那样直观。
Merge 像是“把两条分支合到一起”,而 Rebase 听起来像是在“重写历史”。
更可怕的是,你可能还听过一句劝告:
不懂 Rebase,千万别乱用。
这话没错,但也容易让人错过一个非常好用的工具。
Rebase 的核心价值其实很简单:让提交历史更干净。
如果你理解了它在做什么,就会发现它不是洪水猛兽,而是一个能让团队协作更清爽的 Git 神器。
Rebase 到底是什么意思?
rebase 直译是“重新设置基底”。
听起来有点抽象,我们用一个例子。
假设你从 main 拉了一个功能分支:
main: A -> B
feature: \-> C -> D
这时候,你在 feature 分支上开发了两个提交:C 和 D。
与此同时,同事往 main 合并了新代码:
main: A -> B -> E -> F
feature: \-> C -> D
现在你的 feature 分支已经落后于 main 了。
如果你执行:
git rebase main
Git 会做一件事:
把你的提交 C、D 先“拿下来”,再放到最新的 main 后面。
结果变成:
main: A -> B -> E -> F
feature: \-> C' -> D'
注意,这里的 C' 和 D' 不是原来的 C、D,而是重新应用后的新提交。
这就是为什么说 Rebase 会“重写历史”。

Rebase 和 Merge 最大的区别
如果用 merge,历史会变成这样:
main: A -> B -> E -> F
feature: \-> C -> D
\
M
Git 会创建一个新的 merge commit:M。
这没有错,也很安全。但当团队频繁合并时,提交历史会变得比较绕:
Merge branch 'main' into feature
Merge branch 'feature/login'
Merge branch 'main' into feature/payment
看日志时,你会看到很多合并节点。
而 Rebase 的效果更像这样:
A -> B -> E -> F -> C' -> D'
历史是一条直线。
所以两者区别可以简单理解:
| 操作 | 特点 | 适合场景 |
|---|---|---|
| Merge | 保留真实分支历史 | 团队合并、主分支集成 |
| Rebase | 让提交历史更线性 | 整理个人分支、同步最新 main |
| Interactive Rebase | 修改、合并、删除提交 | 提交 PR 前整理历史 |
Merge 更像“如实记录发生了什么”。
Rebase 更像“把故事讲得更清楚”。
为什么程序员喜欢 Rebase?
因为它能让 Git 历史更好看,也更好查。
比如你开发一个登录功能,过程中提交了这些 commit:
feat: add login api
fix: typo
fix: really fix
test
wip
fix again
如果直接提交 PR,review 的人可能会很痛苦。
但你可以用交互式 Rebase 整理:
git rebase -i HEAD~6
把几个零散提交合并成:
feat(login): add sms login api
feat(login): add login page
test(login): add login tests
这样别人看你的 PR,会清楚很多。
Rebase 帮你做的,不只是“变好看”,而是降低协作成本。
干净的提交历史意味着:
- Review 更轻松
- 回滚更准确
- 排查问题更方便
- 项目日志更有意义
为什么程序员又怕 Rebase?
因为 Rebase 会改写提交历史。
这意味着,如果你对已经推送到远程、并且别人也在使用的分支做 Rebase,就可能制造麻烦。
比如你把 feature/login 推到了远程,同事也基于它继续开发。
这时你执行 Rebase,并强推:
git push --force
同事本地的历史就可能和远程对不上。
所以 Rebase 最重要的原则是:
不要随便 Rebase 公共分支。
尤其不要对这些分支乱来:
main
master
develop
release
也不要随便对多人协作中的远程分支 Rebase。
你自己的本地分支,怎么整理都相对安全。
公共分支一旦重写历史,就可能影响别人。
更安全的强推:force-with-lease
有时候 Rebase 之后,确实需要推送到远程。
这时很多人会用:
git push --force
但更推荐:
git push --force-with-lease
它比 --force 安全。
--force 的意思是:不管远程现在是什么,我都覆盖。
--force-with-lease 的意思是:只有远程分支没有被别人更新过,我才覆盖。
如果别人已经推了新提交,它会拒绝覆盖。
这能避免你一不小心把同事的提交冲掉。
所以如果你必须强推,优先记住:
git push --force-with-lease
常用 Rebase 命令速查
git rebase main
# 把当前分支的提交移动到 main 最新提交之后
git rebase origin/main
# 基于远程 main 重新整理当前分支
git rebase -i HEAD~3
# 交互式整理最近 3 个提交
git rebase --continue
# 解决冲突后继续 rebase
git rebase --abort
# 放弃本次 rebase,回到开始前状态
git rebase --skip
# 跳过当前冲突提交,继续后续 rebase
git push --force-with-lease
# Rebase 后更安全地强制推送
这几条命令足够覆盖大多数日常场景。
Rebase 遇到冲突怎么办?
Rebase 遇到冲突并不奇怪。
因为它是在把你的提交一个个重新应用到新的基底上。如果某个提交改动和 main 冲突,Git 就会停下来让你处理。
流程通常是:
git rebase main
出现冲突后,打开冲突文件,处理类似内容:
<<<<<<< HEAD
const timeout = 3000
=======
const timeout = 5000
>>>>>>> feature/login
处理完后:
git add .
git rebase --continue
如果你发现这次 Rebase 太乱,不想继续:
git rebase --abort
这条命令非常重要。
它能让你回到 Rebase 开始前的状态。
所以新手练 Rebase 时,不用太怕。只要记住 --abort,就有回头路。
什么时候该用 Rebase?
适合用 Rebase 的场景:
- 个人 feature 分支同步最新 main。
- 提交 PR 前整理 commit。
- 合并多个零碎提交。
- 修改最近几次 commit message。
- 让提交历史更线性。
不适合随便 Rebase 的场景:
main、develop这类公共分支。- 多人共同开发的远程分支。
- 你不确定别人是否基于该分支开发。
- 已经发布上线的历史提交。
- 自己还没理解当前分支关系。
一句话记:
本地个人分支大胆用,公共共享分支要谨慎。
一个推荐工作流
日常开发可以这样用:
git checkout main
git pull origin main
git checkout -b feature/login
# 开发、提交代码
git fetch origin
git rebase origin/main
# 如果有冲突,解决后:
git add .
git rebase --continue
# 提交 PR 前整理历史:
git rebase -i HEAD~3
git push origin feature/login
如果这个分支之前已经推送过,并且 Rebase 后需要更新远程:
git push --force-with-lease
这个流程适合个人 feature 分支。
团队是否要求最终用 merge、squash merge,还是 rebase merge,要看项目规范。
结尾:Rebase 不是危险,乱用才危险
Git Rebase 之所以让人又爱又怕,是因为它确实强大,也确实有风险。
它能让提交历史更干净,让 PR 更容易 review,也能让个人分支更顺地跟上主线。
但它也会重写历史。如果你在公共分支上乱用,就可能影响整个团队。
这篇文章可以总结成三个关键点:
- Rebase 的本质是把当前分支提交重新应用到新的基底上。
- Rebase 适合整理个人分支和提交 PR 前清理 commit。
- 不要随便 Rebase 公共分支,必须强推时优先用
--force-with-lease。
如果你以前一直害怕 Rebase,可以先在测试仓库里练习:
git rebase -i HEAD~3
git rebase --abort
git rebase --continue
真正理解它之后,你会发现:Rebase 不是 Git 里的禁术,而是让协作历史更清楚的一把锋利工具。
本文由 楸木 原创,转载请注明出处。