交互式Rebase后feature分支基准意外重置的Git原因咨询
问题的核心原因
你遇到的问题本质是交互式变基的基准提交指定错误,导致Git将feature分支的提交重新附着到了旧的master节点C上,而非更新后的master节点G。
Git层面的详细拆解
第一次变基的本质
当你执行git rebase master时,Git实际做了这些操作:- 找出feature与master分支的最近公共祖先——提交C。
- 复制feature分支中C之后的所有提交(D、E),生成全新的提交D'、E'(它们的哈希值和原D、E完全不同)。
- 将feature分支的指针从原E移动到新的E',此时feature的提交链变为:
A→B→C→F→G→D'→E'。 - 原提交D、E不会被立即删除,只是变成了「悬空提交」(没有分支指针指向),仍保存在Git的对象数据库里。
交互式变基的基准错误
你执行git rebase -i HEAD~3时,HEAD~3是从当前HEAD(E')往前回溯3个父提交的结果:HEAD→ E'HEAD~1→ D'HEAD~2→ GHEAD~3→ F
你的实际结果显示feature回到了C下方,大概率是你误将基准指定为了C(比如写成HEAD~4),或是在交互式变基的编辑界面中,错误选择了原悬空提交D、E而非新生成的D'、E'。
更关键的点:如果想基于最新的master(G)合并feature的提交,正确做法是直接指定基准为
master,而非HEAD~n。HEAD~n是基于当前提交的相对位置,很容易因提交数量变化指向错误节点;而指定master作为基准,Git会明确以master的最新提交(G)为起点,重新应用feature独有的提交,合并后自然附着在G下方。错误变基的结果
当交互式变基的基准被指定为C时,Git会将你选择的提交(原D、E)重新应用到C上,生成合并后的提交DE,同时把feature分支指针移到DE上,最终就出现了你看到的结果:feature分支从C分叉,而非从最新的master节点G分叉。
正确的操作方式
如果想合并feature分支的D'、E'提交并保持其附着在最新master上,应该执行:
git rebase -i master
在编辑界面中处理D'、E'的合并即可,合并后的提交会自然附着在master的最新提交G下方。
内容的提问来源于stack exchange,提问作者Mickey
相关产品推荐
相关产品推荐

