前置知识: Git

交互式rebase

00:00
4 min Advanced 2026/6/14

Git交互式rebase详解:reword、squash、fixup、drop等操作改写提交历史。

1. 交互式 rebase 基础

1.1 启动交互式 rebase

# 修改最近 3 个提交
git rebase -i HEAD~3

# 修改从某个提交之后的所有提交
git rebase -i abc1234

# 修改从根提交开始的所有提交
git rebase -i --root

启动后 Git 会打开编辑器,显示待修改的提交列表:

pick f7f3f6d feat: add user model
pick 310154e fix: correct validation logic
pick a5f4a0d docs: update README

# Rebase abc1234..a5f4a0d onto abc1234
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup [-C | -c] <commit> = like "squash" but keep only the previous
#                    commit's log message, unless -C is given, in which case
#                    keep only this commit's message
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]

1.2 执行顺序

提交列表从上到下对应从旧到新的时间顺序。修改命令后,Git 按新顺序依次执行。

2. reword — 修改提交信息

2.1 使用场景

  • 修正拼写错误
  • 补充遗漏的上下文
  • 使提交信息符合约定式提交规范

2.2 操作流程

pick 改为 reword(或 r):

pick f7f3f6d feat: add user model
reword 310154e fix: corret validation logic  # 拼写错误
pick a5f4a0d docs: update README

保存退出后,Git 会为 reword 的提交打开编辑器,让你修改提交信息:

fix: correct validation logic

# 原始信息有拼写错误,修正为 correct

2.3 非交互式 reword

# 修改最近一个提交的信息
git commit --amend -m "fix: correct validation logic"

# 修改指定提交的信息(需要 rebase)
GIT_SEQUENCE_EDITOR="sed -i 's/pick abc1234/reword abc1234/'" git rebase -i abc1234^

3. squash — 合并提交

3.1 使用场景

  • 将细碎提交合并为有意义的原子提交
  • 将”修复上一个提交的提交”合并进去
  • 保持提交历史整洁

3.2 操作流程

pick f7f3f6d feat: add user model
squash 310154e fix: correct validation in user model
squash a5f4a0d refactor: clean up user model code

保存后,Git 会打开编辑器让你编辑合并后的提交信息:

# This is a combination of 3 commits.
# This is the 1st commit message:

feat: add user model

# This is the commit message #2:

fix: correct validation in user model

# This is the commit message #3:

refactor: clean up user model code

# 请编辑为最终合并后的信息

合并结果:

# 之前
f7f3f6d feat: add user model
310154e fix: correct validation in user model
a5f4a0d refactor: clean up user model code

# 之后
b4a2c1d feat: add user model with validation and cleanup

3.3 squash 顺序

squash 将当前提交合并到前一个提交。因此第一个提交必须是 pick

# 正确
pick   A  feat: add feature
squash B  fix: typo in feature
squash C  refactor: clean up feature

# 错误 — 第一个不能是 squash
squash A  feat: add feature
pick   B  fix: typo in feature

4. fixup — 静默合并

4.1 与 squash 的区别

操作合并提交信息交互编辑
squash合并所有提交信息
fixup丢弃当前提交信息
fixup -C保留当前提交信息替代之前的
fixup -c保留当前提交信息替代之前的

4.2 使用场景

适用于”修前一个提交的小问题”的场景,不需要保留中间提交信息:

# 开发过程中
git commit -m "feat: add login form"
# 发现遗漏
git add forgotten-file.js
git commit -m "fix: forgot to add file"  # 这个提交信息无保留价值

交互式 rebase 时:

pick   abc1234 feat: add login form
fixup  def5678 fix: forgot to add file

结果保留 feat: add login form,第二个提交信息被丢弃。

4.3 fixup -C 保留后者的信息

pick   abc1234 WIP: add login form
fixup -C def5678 feat: add login form with validation

结果保留 feat: add login form with validation,前者信息被丢弃。

4.4 自动 fixup 标记

提交时使用 --fixup标记

git commit --fixup=abc1234 -m "fix: typo in login form"

rebase 时使用 --autosquash 自动排列:

git rebase -i --autosquash HEAD~3

编辑器自动显示:

pick   abc1234 feat: add login form
fixup  def5678 fix: typo in login form  # 自动标记为 fixup

5. drop — 删除提交

5.1 使用场景

  • 移除误提交调试代码
  • 删除不再需要的功能提交
  • 清理中间产物

5.2 操作方式

方式一:将 pick 改为 drop

pick   abc1234 feat: add user model
drop   def5678 debug: add console.log statements
pick   ghi9012 feat: add user service

方式二:直接删除该

pick   abc1234 feat: add user model
pick   ghi9012 feat: add user service
# def5678 行已删除

5.3 注意事项

删除提交可能导致后续提交产生冲突,因为后续提交可能依赖于被删除提交的代码。

6. edit — 拆分提交

6.1 拆分流程

pick   abc1234 feat: add user model and service
edit   def5678 feat: add user controller

当 rebase 在 edit 处暂停时:

# 1. 回退当前提交但保留更改
git reset HEAD^

# 2. 分多次提交
git add src/models/user.js
git commit -m "feat: add user model"

git add src/services/user.js
git commit -m "feat: add user service"

# 3. 继续 rebase
git rebase --continue

6.2 修改提交内容

edit 暂停时修改文件

# 修改文件
vim src/models/user.js

# 追加到当前提交
git add src/models/user.js
git commit --amend

# 继续
git rebase --continue

7. rebase 冲突处理

7.1 冲突解决流程

# rebase 过程中出现冲突
git rebase -i HEAD~5
# CONFLICT (content): Merge conflict in src/app.js

# 1. 手动解决冲突
vim src/app.js

# 2. 标记为已解决
git add src/app.js

# 3. 继续 rebase
git rebase --continue

7.2 跳过或中止

# 跳过当前提交(等效于 drop)
git rebase --skip

# 完全放弃 rebase,恢复原始状态
git rebase --abort

7.3 使用 git rerere 复用冲突解决方案

# 启用 rerere
git config --global rerere.enabled true

# Git 会记住之前的冲突解决方案
# 下次遇到相同冲突时自动应用

8. 安全实践

8.1 黄金法则

永远不要推送远程公共分支执行 rebase。

# 危险!
git rebase -i main  # 如果 main 是共享分支

# 安全
git rebase -i HEAD~3  # 仅修改自己的本地提交

8.2 强制推送的替代方案

如果必须 rebase 已推送分支,使用 --force-with-lease

git push --force-with-lease origin feature/xxx
# 比 --force 更安全,会检查远程是否有他人新提交

8.3 rebase 前备份

# 创建备份分支
git branch backup-before-rebase

# rebase 失败时恢复
git reset --hard backup-before-rebase

知识检测

学习进度

-- 已学文档
--% 知识覆盖率

学习推荐

专注模式