必须用rebase -i将pick改为edit才能在a和b间插入新提交;操作时指定a的哈希,git停在a后b前,此时提交新内容再--continue;该操作重写历史,仅限本地未推送分支,误删行会永久丢失提交,所有后续提交哈希均改变。

rebase -i 里用 edit 而不是 pick 才能插入提交
想在 A 和 B 两提交之间加一个新提交,不能直接 git commit —— 那只会追到最末尾。必须靠交互式变基把历史“掰开”,让 Git 在指定位置停住,你再塞进去。
操作步骤很固定:git rebase -i <commit-hash-of-a></commit-hash-of-a>(注意是 A 的哈希,不是 B 的),然后把目标提交 B 对应那行的 pick 改成 edit,保存退出。
- 改完后 Git 会停在 B 的父提交(也就是 A)之后、B 之前,此时工作区和暂存区都干净,相当于刚从 A 检出的状态
- 这时你可以
git add+git commit新提交,它就会被插进 A 和 B 中间 - 最后
git rebase --continue让 B 及后续提交重放 - 如果中途
git status显示有冲突或“you are editing a commit”,说明停对了;如果直接跑完了,大概率选错了 base 提交
别在已推送的分支上做这种 rebase
所有修改提交哈希的操作,本质都是重写历史。一旦原提交已推送到远程(尤其是多人协作分支),强行插入会导致别人 fetch 后出现重复提交、合并混乱、甚至丢失改动。
- 只在本地未推送的 feature 分支上操作,比如刚写完几个提交还没
git push - 如果已经推了,先确认没人基于你这些提交继续开发;否则得跟协作者同步,让他们也执行
git pull --rebase或手动 reset -
git push --force-with-lease是唯一安全的强制推送方式,比--force多一层保护,但依然不解决协作逻辑问题
rebase -i 时误删某行 = 彻底丢掉那个提交
交互式变基编辑器里每一行对应一个提交,删除某行就等于告诉 Git:“这个提交不要了”。这不是撤销,是永久剔除(除非你记得它的原始哈希,还能从 reflog 拯救)。
- 常见误操作:想跳过某个提交,顺手把它那行删了 —— 结果发现功能没了,再找不回来
- 正确做法是把
pick改成drop(Git 2.21+ 支持),或者用fixup/squash合并,而不是删行 - 执行前先
git log --oneline -n 10截图保存原始顺序,出错时好对照
插入提交后,原来 B 及之后所有提交的哈希都会变
Git 提交哈希由内容 + 父提交哈希共同决定。你在中间插一个,后面每个提交的父哈希全变了,所以整个链的哈希全部刷新。
- 这意味着:所有基于旧历史的 PR、CI 构建记录、代码审查链接,都会失效
- 如果你用过
git bisect,插入后必须重新开始,旧的bisect log无效 - 某些 CI 工具(如 GitHub Actions)靠 commit SHA 触发构建,重写后需手动重试或等下次推送
rebase -i 里填写的 base 提交到底该选哪个 —— 它必须是你要插入位置的前一个提交,而不是后一个。选错就插到别处,甚至失败退出。










