git rebase 是什么
git rebase 把当前分支上独有的提交逐个取出,在目标分支顶端重新应用一遍,得到一条没有分叉的线性历史。它适合「把个人分支更新到主干最新状态」这类场景:重放后的提交像是刚从最新代码上开发出来的,评审时不会混入无关的合并提交。
代价是改写哈希
重放会为每个提交生成新的哈希,也就是说变基等同于重写这段历史。只要这些提交还没被别人拉取过,改写就没有副作用;一旦他人已经基于旧提交继续工作,改写会让他们手里的历史变成孤儿,需要强行对齐。判断标准很简单:这条分支是不是只有你在用。
基本信息
| 适用平台 | Linux / macOS / Windows(Git 2.x) |
|---|---|
| 语法 | git rebase <上游> [<待重放分支>] |
| 原理 | 逐个摘取提交后重放,提交哈希全部变化 |
| 常用参数 | -i 交互整理;--continue/--skip/--abort;--autostash |
| 影响范围 | 只改本地历史,推送前不影响远端 |
| 适用边界 | 个人分支与未共享的分支 |
典型使用场景
- 跟进主干:把个人分支叠到最新 main 之上,保持线性
- 提交前整理:用 -i 合并零散提交、改写信息、删掉调试提交
- 减少噪声:合入主干前把分叉抹平,让历史更易读
- 同步远端:把本地分支变基到 origin/main 的最新位置
- 处理中断:冲突解决后 --continue,整体放弃用 --abort
- 清理历史:删除误提交的敏感文件路径,注意旧对象仍可能残留
常用示例
常用示例
git switch feature/login # 切到需要整理的分支
git fetch origin # 先取回最新上游
git rebase origin/main # 把本地提交叠到最新主干之上
git log --oneline --graph -10 # 核对变基后的线性历史
git status # 冲突时先看哪些文件需要处理
git add <已解决文件> # 标记某个冲突文件已解决
git rebase --continue # 继续重放剩下的提交
git rebase --abort # 放弃,恢复到变基前状态变基中断的几种出口
| 命令 | 作用 | 何时用 |
|---|---|---|
| --continue | 解决冲突后继续重放 | 已 add 完所有冲突文件 |
| --skip | 丢弃当前这条继续 | 确认该提交内容已无价值 |
| --abort | 回到变基开始前 | 想整体放弃这次变基 |
| --autostash | 变基前后自动收藏与恢复 | 本地有零散未提交改动 |
| --edit-todo | 重新打开待办清单 | 中途想调整整理方案 |
| --onto | 换一个基点范围重放 | 把一段提交迁移到别处 |
变基会改写提交哈希。他人已基于该分支工作时会引起历史分叉,团队规范里应先约定「仅限个人分支可改写历史」。
变基期间仓库处于临时状态,HEAD 停在分离头指针上。不要在这个阶段提交无关改动,冲突解决完立即 --continue 推进。
变基后推送需要强推,用 --force-with-lease 而不是 --force:远端存在你没见过的提交时它会被拒绝,避免覆盖别人的工作。
变基到一半想退出,先看 git status:首行会提示正在变基,并列出可以使用的 --continue、--skip、--abort 选项,照提示走即可。
变基与合并怎么选
把上游改动拿进自己的分支有两个选择:合并保留分叉事实并生成一个合并提交,变基把本地提交挪到上游顶端、抹平分叉。个人分支上变基更清爽,评审时看到的都是本次改动;公共分支上合并更安全,因为它不会改写别人已经拉取过的历史。
变基之后本地提交的哈希全部变化,之前分享出去的提交号会失效。分享代码之前先变基、分享之后避免再变基,是团队里比较省心的做法。