强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

Git 完全指南 / 11 - 变基进阶:interactive rebase、autosquash、onto

第十一章:变基进阶

交互式变基是 Git 中最强大的历史重写工具,掌握它可以让你的提交历史清晰优雅。


11.1 交互式变基(Interactive Rebase)

11.1.1 基本语法

# 对最近 N 个提交进行交互式变基
$ git rebase -i HEAD~5

# 基于某个提交
$ git rebase -i abc1234

# 对整个分支进行变基
$ git rebase -i main

11.1.2 交互式变基指令

执行 git rebase -i HEAD~5 后,编辑器会打开:

pick abc1234 feat: add user model
pick def5678 feat: add user controller
pick ghi9012 fix: typo in controller
pick jkl3456 refactor: clean up user model
pick mno7890 feat: add user tests

可用指令:

指令简写说明
pickp保留该提交
rewordr保留提交但修改提交信息
edite保留提交但暂停以便修改
squashs与前一个提交合并,保留两者的提交信息
fixupf与前一个提交合并,丢弃此提交的信息
execx在该位置执行 shell 命令
dropd删除该提交
breakb在此处暂停
labell为当前 HEAD 添加标签
resett重置 HEAD 到标签
mergem创建合并提交

11.1.3 压缩提交示例

# 原始提交
pick abc1234 feat: add user model
squash def5678 fix: typo in user model
squash ghi9012 feat: add user validation

# 结果:三个提交合并为一个
# 编辑器让你编辑合并后的提交信息
feat: add user model with validation

11.1.4 调整提交顺序

# 重新排列提交顺序(交换行即可)
pick ghi9012 feat: add user tests        # 原来在第三个
pick abc1234 feat: add user model         # 原来在第一个
pick def5678 feat: add user controller    # 原来在第二个

⚠️ 调整顺序可能会导致冲突,需要手动解决。

11.1.5 修改提交内容

# 使用 edit 指令暂停在某个提交
edit abc1234 feat: add user model
pick def5678 feat: add user controller

# Git 会暂停
Stopped at abc1234... feat: add user model

# 修改文件
$ vim src/user/model.js

# 追加修改到当前提交
$ git add -A
$ git commit --amend

# 继续变基
$ git rebase --continue

# 或跳过某个提交
$ git rebase --skip

# 或中止变基(回到原始状态)
$ git rebase --abort

11.2 Autosquash(自动压缩)

--autosquash 让 fixup 和 squash 提交自动与目标提交配对。

11.2.1 使用 fixup 提交

# 正常开发
$ git commit -m "feat: add login page"

# 后续发现需要修复,创建 fixup 提交
$ git commit --fixup=abc1234
# 提交信息自动变为:fixup! feat: add login page

# 或使用 squash
$ git commit --squash=abc1234
# 提交信息自动变为:squash! feat: add login page

11.2.2 自动整理

# 启用 autosquash 进行交互式变基
$ git rebase -i --autosquash main

# 交互式界面会自动排列:
pick abc1234 feat: add login page
fixup def5678 fixup! feat: add login page    # 自动排在目标后面
pick ghi9012 feat: add register page

11.2.3 配置自动启用

# 全局启用 autosquash
$ git config --global rebase.autosquash true

# 之后 git rebase -i 会自动使用 --autosquash

11.3 --onto 参数

--onto 允许你精确控制变基的目标基础点。

11.3.1 基本语法

$ git rebase --onto <newbase> <upstream> <branch>

11.3.2 常见用法

移植分支到新的基础点

场景:feature 分支是从 develop 拉出的,现在需要基于 main 重新变基

main:     M1 → M2 → M3
develop:       D1 → D2 → D3
feature:              F1 → F2 → F3
# 将 feature 基于 main 重新变基
$ git rebase --onto main develop feature

# 结果:
main:     M1 → M2 → M3
feature:                    F1' → F2' → F3'

删除中间提交

# 删除第二个到第四个提交之间的所有提交
$ git rebase --onto HEAD~4 HEAD~3 HEAD

摘取分支范围

# 只将 feature 中不属于 develop 的提交移到 main
$ git rebase --onto main develop feature

11.4 变基工作流

11.4.1 功能开发工作流

# 1. 从主分支创建功能分支
$ git switch -c feature/auth main

# 2. 开发过程中产生多个提交
$ git commit -m "feat: add auth controller"
$ git commit -m "fix: typo in controller"
$ git commit -m "feat: add auth tests"
$ git commit -m "fix: fix test assertions"
$ git commit -m "refactor: clean up auth logic"

# 3. 合并前整理提交历史
$ git rebase -i main

# 编辑器中操作:
pick abc1234 feat: add auth controller
squash def5678 fix: typo in controller
pick ghi9012 feat: add auth tests
squash jkl3456 fix: fix test assertions
squash mno7890 refactor: clean up auth logic

# 4. 编写清晰的最终提交信息
feat: implement authentication module

- Add auth controller with login/register endpoints
- Implement JWT token generation and validation
- Add comprehensive test coverage
- Clean up auth logic and error handling

# 5. 推送并创建 PR
$ git push origin feature/auth

11.4.2 同步主分支更新

# 1. 获取主分支最新代码
$ git fetch origin

# 2. 将功能分支变基到最新主分支
$ git rebase origin/main

# 3. 解决冲突(如有)
$ git rebase --continue

# 4. 强制推送更新后的分支
$ git push --force-with-lease origin feature/auth

11.5 变基冲突处理

# 变基过程中遇到冲突
$ git rebase -i main
CONFLICT (content): Merge conflict in src/auth.js

# 查看冲突状态
$ git status

# 方法 1:手动解决
$ vim src/auth.js   # 编辑冲突
$ git add src/auth.js
$ git rebase --continue

# 方法 2:使用工具
$ git mergetool

# 方法 3:使用某个版本
$ git checkout --ours src/auth.js    # 保留主分支版本
$ git checkout --theirs src/auth.js  # 使用功能分支版本
$ git add src/auth.js
$ git rebase --continue

# 中止变基,回到原始状态
$ git rebase --abort

# 跳过当前提交
$ git rebase --skip

11.6 变基 vs 合并决策

场景推荐方式原因
个人功能分支 → 主分支Rebase保持线性历史
多人协作的公共分支Merge不重写他人历史
同步主分支到功能分支Rebase便于最终合并
回顾特定功能的所有修改Merge保留合并记录
发布分支合并到主分支Merge记录发布点

⚠️ 黄金法则永远不要 rebase 已经推送到远程的公共分支!


业务场景

场景推荐方案
PR 提交前清理历史git rebase -i 压缩和整理
同步上游代码git rebase origin/main
将功能移到新的基础git rebase --onto
修复历史中的错误提交git rebase -i + edit/reword
持续开发中的修复git commit --fixup + --autosquash

扩展阅读


🔗 上一章10 - 子模块 | 下一章12 - 工作树