从Git stash创建分支多出两个父提交,如何删除这两个空提交?
问题原因说明
Git的stash提交本质是特殊的合并提交,默认结构包含多个父提交:
- 第一个父提交是执行stash时所在的分支提交(也就是你场景中的c)
- 第二个父提交存储stash执行时暂存区的内容(对应你场景的y,为空说明当时暂存区无改动)
- 如果你stash时加了
-u/--include-untracked参数,会生成第三个父提交存储未跟踪文件(对应你场景的z,为空说明当时无有效未跟踪文件)
你直接从stash创建分支时,会完整保留这个合并提交的多父结构,所以出现了多余的两个父提交。
解决方法
根据你当前的操作进度,对应两种处理方案:
方案1:仅创建了tmp分支,还未执行main的变基操作
直接重写tmp分支的提交,去掉多余父提交即可:
- 切换到tmp分支:
git switch tmp - 执行以下命令,将当前tmp的所有有效改动合并为一个基于c的单父提交:
# 先记录当前tmp对应的提交哈希,后续复用它的提交信息 OLD_TIP=$(git rev-parse HEAD) # 软重置到c提交,所有改动会保留在暂存区 git reset --soft <替换为c提交的哈希值> # 用原来的提交信息生成新提交 git commit -C $OLD_TIP
执行完成后tmp分支的提交历史就符合预期:a -> b -> c -> x',x'内容和原x完全一致,无多余父提交。
方案2:已经将main分支变基到了tmp分支上
直接对main分支执行交互式变基删除多余的空提交即可:
- 切换到main分支:
git switch main - 启动交互式变基:
git rebase -i <替换为c提交的哈希值>
- 在弹出的编辑界面中,直接删除y、z对应的两行记录,保留x、d、e、f对应的行,保存退出即可。如果出现冲突,解决冲突后执行
git rebase --continue继续完成变基。
替代快捷方案
如果你不需要保留tmp分支的中间操作,也可以直接通过cherry-pick提取stash的有效改动:
# 切换到要合入改动的分支 git switch main # 提取stash提交的有效改动,-m 1指定取和第一个父提交(c)的差异 git cherry-pick -m 1 <替换为原tmp分支x提交的哈希值>
执行完成后会直接在main上生成一个包含所有stash改动的单父提交,不会引入多余的父提交结构。
内容的提问来源于stack exchange,提问作者mdcq
相关产品推荐
相关产品推荐

