能否一次性执行git commit与git rebase --onto,仅变更一次master分支?
Git一次性删除旧提交并生成新提交的方案
问题
现在执行git commit和git rebase --onto会分两次修改/refs/heads/master分支引用,能不能一次性完成以下操作:
- 删除早期提交
2ef2d17 - 生成新提交(比如示例里的
fb65d19或921d9d4) - 只让
/refs/heads/master变更一次
效果要跟git commit --amend类似:删掉旧提交的同时一次性生成新提交。
用户提供的执行示例日志:
提交新文件后的日志
$ git add A.txt $ git commit -m A.txt [master 921d9d4] A.txt 1 file changed, 689 insertions(+) create mode 100644 A.txt $ git log --oneline --all --graph --decorate * 921d9d4 (HEAD -> master) A.txt * 48efbc2 C.txt * 2ef2d17 A.txt * 5ba51a1 B.txt * 77e423c B.txt * 83f803c A.txt
执行rebase后的日志
$ git rebase --onto 5ba51a1 2ef2d17 -Xtheirs Successfully rebased and updated refs/heads/master. $ git log --oneline --all --graph --decorate * fb65d19 (HEAD -> master) A.txt * f2b8932 C.txt * 5ba51a1 B.txt * 77e423c B.txt * 83f803c A.txt
解决方案
有两种可行方式可以一次性完成需求,避免分支引用两次变更:
方式一:交互式变基直接清理提交链
直接通过交互式变基定位到目标提交的父节点,一次性删除指定提交并生成新的提交链:
- 运行交互式变基命令:
git rebase -i 5ba51a1
- 在弹出的文本编辑器里,找到提交
2ef2d17那一行,把开头的pick改成drop(表示删除该提交);后续的48efbc2和921d9d4保持pick即可(如果要修改提交信息可以改成reword)。 - 保存并退出编辑器,Git会自动生成新的提交链,整个过程只会更新一次
master分支引用,最终的提交结构和你用git rebase --onto后的结果完全一致,但只触发一次分支变更。
方式二:软重置后重新提交(贴近commit --amend逻辑)
先把分支重置到要保留的提交节点,再把后续修改合并后一次性提交:
- 执行软重置,保留工作区和暂存区的所有修改:
git reset --soft 5ba51a1
- 重新提交所有修改(如果原提交的文件已经在暂存区,直接提交即可;否则先执行
git add把需要的文件加进去):
# 示例:如果C.txt和A.txt的修改都已在暂存区 git commit -m "C.txt && A.txt" # 如果需要重新添加文件 git add C.txt A.txt git commit -m "C.txt && A.txt"
这种方式会直接生成一条新的提交链,master分支只会被更新一次,相当于跳过2ef2d17,把后续的修改合并成新提交。
效果验证
执行完任意一种方式后,运行日志命令查看结果:
git log --oneline --all --graph --decorate
会得到类似如下的提交结构(新提交的哈希值会不同):
* [新提交哈希] (HEAD -> master) C.txt && A.txt * 5ba51a1 B.txt * 77e423c B.txt * 83f803c A.txt
内容的提问来源于stack exchange,提问作者Herman
相关产品推荐
相关产品推荐

