git rebase --onto 参数顺序为 ,即“把中从之后的提交搬到后”,顺序颠倒会导致提取错误提交范围甚至丢commit。

git rebase --onto 参数顺序写反了,提交就丢了
很多人执行 git rebase --onto 后发现提交变少、分支“空了”,甚至 git log 看不到自己的改动——根本不是 Git 坏了,而是三个参数位置颠倒了。
它不是“把 A 改成基于 B”,而是“把 <top></top> 中从 <oldbase></oldbase> 开始的提交,搬到 <newbase></newbase> 后面去”。顺序错一个,Git 就会提取错误的提交范围。
-
git rebase --onto main feature bugfix✅ 正确:把bugfix分支中“从feature分叉之后”的所有提交,重放到main顶端 -
git rebase --onto main bugfix feature❌ 错误:Git 会尝试把feature中从bugfix开始的提交搬走——但bugfix很可能压根不在feature的祖先链上,结果提取为空,feature被重置到main,原提交“消失” - 执行前先用
git log --oneline --graph feature bugfix确认分叉点;再跑git merge-base feature bugfix看 Git 认为的共同祖先是否合理
旧基点(oldbase)选得太靠前,会漏掉本该保留的提交
比如 bugfix 是从 feature 的某个中间 commit 切出来的,但你直接用 feature 分支名作 oldbase,Git 就会把 feature 上所有在共同祖先之后的提交都当成“起点前”,导致 bugfix 里真正属于自己的那几个提交被排除在外。
- 查确切起点:用
git log --oneline feature..bugfix看bugfix独有的提交,再找第一个——它的父提交就是你要的oldbase - 用哈希代替分支名更稳妥:
git rebase --onto main abc1234 bugfix,其中abc1234是那个父提交的 SHA - 如果
bugfix曾经merge过main,或feature自身被 rebase 过,merge-base可能失效,必须手动确认
rebase --onto 过程中冲突不能跳过
哪怕只搬两个提交,只要它们改的文件在 <newbase></newbase> 上已被修改,Git 就会停在冲突处。这不是异常,是设计使然——每个提交都得被重新应用一次。
- 冲突时别碰
git rebase --skip:它会丢掉整个当前 commit,不是“跳过冲突”,是“跳过这个提交” - 正确流程:解决冲突 →
git add .→git rebase --continue - 中途想放弃?用
git rebase --abort,它会回退到 rebase 前状态(前提是没push过) - 注意
git status显示的是REBASING,不是ON BRANCH,别误以为还在原分支上操作
变基后历史“丢失”,其实是引用没了
执行完 git rebase --onto,原提交还在 Git 对象库里,只是没有分支或标签指向它们,过一阵会被 GC 清掉。所谓“丢失”,本质是引用断裂。
- 操作前务必备份:
git branch bugfix-backup bugfix - 万一出问题,用
git reflog bugfix找到 rebase 前的 HEAD,再git reset --hard HEAD@{1}恢复 - 已推送的分支禁止直接 rebase;若必须强制同步,用
git push --force-with-lease,不是--force











