学会使用 git rebase -i 整理提交历史,掌握 pick、squash、reword、edit、fixup、drop 六大指令,让 Git 历史干净清晰。
变基 — 给你的提交历史做一次整容手术
你是否有过这样的经历:一个功能开发完,回头看提交历史,全是 “fix”、”update”、”again” 这样的碎片提交?
交互式变基(rebase -i)就是用来整理和优化提交历史的利器。它可以让你合并、删除、重排、修改历史提交,让 Git 历史变得干净清晰。
一、
什么是交互式变基?
普通 rebase vs 交互式 rebase
1 | |
把当前分支的提交”搬”到 main 分支最新提交的后面,主要用于同步主分支。
1 | |
打开编辑器,让你逐个决定每个提交怎么处理,主要用于整理提交历史。
一个真实场景
假设你开发了一个登录功能,产生了 5 个提交:
1 | |
这 5 个提交其实都是同一个功能,合并成一个更合理:
1 | |
二、
基本语法
1 | |
| 部分 | 解释 |
|---|---|
rebase | 变基操作,重新应用提交到新的基准上 |
-i | --interactive 的缩写,交互式模式,打开编辑器 |
HEAD~N | 从当前提交往回数 N 个。~ 是”往回”的意思 |
常用写法
1 | |
注意:
HEAD~N 中的 N 必须大于等于 2,因为变基至少需要 2 个提交才有意义。
三、
六大指令详解
执行 git rebase -i HEAD~5 后,编辑器会出现类似内容:
1 | |
重要:提交列表是从上到下按时间顺序排列的,最上面的是最早的提交,最下面的是最新的。
指令速查表
| 指令 | 全称 | 含义 | 使用场景 |
|---|---|---|---|
pick | pick | 保留这个提交(默认) | 不需要修改 |
r | reword | 保留内容,修改提交信息 | 改提交描述 |
e | edit | 保留内容,暂停让你修改代码 | 需要改代码 |
s | squash | 合并到前一个提交,保留双方信息 | 合并小提交 |
f | fixup | 合并到前一个提交,丢弃本次信息 | 合并修复提交 |
d | drop | 删除这个提交 | 不需要的提交 |
四、
实战:压缩 5 个提交成 1 个
这是最常见的用法,把零碎提交合并成一个完整提交。
第 1 步:执行 rebase -i
1 | |
第 2 步:编辑指令
编辑器中会出现 5 个提交,把后 4 个改为 s(squash):
1 | |
为什么第一个保留 pick,其余用 s?
因为 squash 是”合并到前一个提交”,所以需要一个”前一个”作为基础。第一个提交用 pick 保留,后面的都会被揉进去。
第 3 步:编写新的提交信息
保存关闭后,Git 会打开另一个编辑器让你写合并后的提交信息:
1 | |
你可以把上面的内容全部删掉,写一个新的:
1 | |
保存退出,5 个提交就变成了 1 个!
1 | |
五、
实战:修改提交信息(reword)
有时候提交信息写错了,需要修改。
修改单个提交信息
1 | |
1 | |
保存后,Git 会在 reword 的提交处暂停,让你修改提交信息:
1 | |
修改完保存退出即可。
六、
实战:暂停修改代码(edit)
当你发现某个提交有代码错误,需要修改代码时:
1 | |
1 | |
保存后,Git 会在 edit 的提交处暂停:
1 | |
这时你可以修改代码:
1 | |
七、
实战:删除提交(drop)
如果某个提交完全不需要了:
1 | |
1 | |
保存后,drop 的提交会被永久删除,就像从未存在过。
drop 是危险操作:被删除的提交中的代码改动也会丢失。如果只是不想保留提交记录但想保留代码,用
fixup 合并到其他提交中。
八、
squash vs fixup 的区别
这两个指令都是合并到前一个提交,区别在于提交信息:
| 指令 | 代码 | 提交信息 |
|---|---|---|
squash(s) | 合并到前一个提交 | 保留两个提交的信息,让你编辑 |
fixup(f) | 合并到前一个提交 | 丢弃当前提交的信息,只保留前一个的 |
什么时候用 fixup?
当你提交了一堆 “fix typo”、”fix again” 这种修复提交时,用 fixup 最干净:
1 | |
结果:
1 | |
九、
实战:重新排序提交
你可以通过改变行的顺序来重排提交:
1 | |
重排序可能导致冲突,因为后面的提交可能依赖前面提交的代码。如果出现冲突,Git 会暂停让你解决。
十、
变基冲突处理
变基过程中经常遇到冲突,别慌,按以下步骤处理:
1 | |
git rebase --continue:解决冲突后继续git rebase --skip:跳过当前提交(代码会丢失)git rebase --abort:完全放弃变基,回到之前的状态
十一、
变基的注意事项
黄金法则:不要对已推送到远程的公共分支执行变基!
变基会重写提交历史(生成新的 commit hash),如果你已经 push 到远程,别人基于你的提交做了开发,你变基后他们的分支就会出问题。
什么时候可以变基?
| 场景 | 可以变基? |
|---|---|
| 本地分支,还没 push | 可以 |
| 个人分支(feature/xxx),还没合并 | 可以 |
| 已经 push 到远程的公共分支 | 不可以 |
| 别人正在基于开发的分支 | 不可以 |
如果已经 push 了怎么办?
变基后只能强制推送:
1 | |
--force-with-lease 比 --force 更安全,它会检查远程分支是否有别人的新提交,避免覆盖别人的代码。
十二、
IDEA 中的变基操作
如果你使用 IntelliJ IDEA / WebStorm,变基操作可以在图形界面中完成:
压缩提交
在 Git 提交记录面板中:
- 选中要压缩的提交
- 右键 → 压缩提交(Squash Commits)
- 输入新的提交信息
交互式变基
- 选中一个提交
- 右键 → 从这里执行交互式变基(Interactively Rebase from Here)
- 在弹出窗口中拖拽排序、修改指令(pick/squash/drop 等)
- 点击 Start Rebase
其他右键菜单
| 菜单项 | 等价命令 | 说明 |
|---|---|---|
| 撤销提交 | git reset --soft HEAD~1 | 保留修改,撤销提交 |
| 删除提交 | git reset --keep HEAD~1 | 删除提交,保留不冲突的文件 |
| 压缩提交 | git rebase -i (squash) | 合并多个提交 |
| 修改提交信息 | git rebase -i (reword) | 修改提交描述 |
| 从这里执行交互式变基 | git rebase -i <commit> | 完整变基操作 |
总结:变基指令速查卡
1 | |