我必须编辑合并提交的父级的提交消息(父级实际上本身就是一个合并)。我该怎么做呢 ?
这里F是我当前的HEAD,E和D合并的结果。D本身是A和C合并的结果,D是我需要编辑其消息的提交。
...A-D-F - branch where I work
/ /
...B-C-E - master
git rebase -i D~ 只显示来自主编辑的提交 - E、C、B ...
没有一个被推动。有什么希望吗?
默认情况下,rebase
尝试生成线性历史。此外,rebase 假定所有更改都以非合并提交表示(除了冲突解决或“邪恶合并”之外,这应该是真的)。
有两个警告,您可以通过使用该选项说服rebase
承认合并提交。--preserve-merges
警告是:
1)rebase
仍然无法正确处理合并中所做的更改。它将尝试使用默认策略重新创建合并,并在必要时让您重新解决冲突。如果合并是为了手动更改而创建--no-commit
的,即使它不会发生冲突,rebase
也会默默地更改结果。
2) 混合通常不安全--preserve-merges
。-i
在特定情况下,它可以做到,如果你小心地将你正在做的事情限制在需要做的事情上,这可能会起作用。
因此,您可以尝试使用 rebase并在 TODO 列表中进行任何--preserve-merges
更改,除了将命令设置为“reword”。D
这将替换 commitsD
和F
,因此如果其他 refs 指向它们中的任何一个,您也必须移动这些 refs。但由于没有推动任何内容,因此重写不应该引起任何其他重大问题。
还有其他方法可以进行重写,所以如果--preserve-merges
不适合您(或者如果您只是不想弄乱它),您可以git filter-branch
使用--msg-filter
. 但是,这更难设置,因为您需要编写一个脚本来转换D
s 消息,同时传递任何其他提交的消息。见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"