默认情况下,rebase 尝试生成线性历史记录。此外,rebase 假定所有更改都在非合并提交中表示(除了冲突解决或“邪恶合并”,这应该是真的)。
有两个注意事项,您可以使用 --preserve-merges 选项说服 rebase 确认合并提交。需要注意的是:
1) rebase 仍然无法正确处理合并中所做的更改。它将尝试使用默认策略重新创建合并,并在必要时让您重新解决冲突。如果合并是使用 --no-commit 创建的,以便手动更改内容,即使它不会发生冲突,rebase 将默默地更改结果。
2) 将--preserve-merges 与-i 混合通常并不安全。在特定情况下,它是可以做到的,如果你小心地将你正在做的事情限制在需要做的事情上,这可能会起作用。
因此,您可以尝试使用--preserve-merges 进行变基并在 TODO 列表中更改 nothing,除了将 D 的命令设置为“reword”。
这将替换提交D 和F,因此如果其他引用指向它们中的任何一个,您也必须移动这些引用。但由于没有推送任何内容,因此重写应该不会引起任何其他重大问题。
还有其他方法可以进行重写,所以如果 --preserve-merges 不适合您(或者如果您只是不想弄乱它),您可以使用 git filter-branch 代替 @987654336 @。但是,这更难设置,因为您需要编写一个脚本来转换Ds 消息,同时传递任何其他提交的消息。见https://git-scm.com/docs/git-filter-branch
或者您可以手动重建历史记录。例如,如果您知道 D 和 F 是不冲突的默认合并,您可以说
git checkout myBranch
git reset --hard HEAD~2
git merge master^
# enter the new commit message for D
git merge master
# re-enter the commit message for E
如果您不确定提交是非冲突的默认合并,您可以执行类似的操作
git checkout myBranch
git tag temp
git reset --hard HEAD~2
git merge --no-commit master^
rm -rf *
git checkout temp^ -- .
git add .
git commit -m"new commit message for D"
git merge --no-commit master
rm -rf *
git checkout temp -- .
git add .
git commit -m"commit message for F"