假设我有一个这样的存储库:
I --- C --- M master
\ /
`- A -´ topic
其中M
是将topic
合并到master
的合并提交。
稍后我在C
中发现了一个错误,因此我在master
的{{1}}分支上修改了它:
M
但理想情况下我希望历史看起来像这样:
I --- C --- M --- C1 master
\ /
`- A -´ topic
如何重写历史记录,以便在合并I --- C --- C1 --- M master
\ /
`- A --------´ topic
之前显示C1
?
我可以移除M
,应用M
制作的补丁,然后再将C1
合并到topic
,再次解决所有冲突,但我想避免这种努力,如果可能的话,我宁愿保留原始的提交信息(作者,日期等),这会再次排除master
。我希望git commit
能够实现,但我失败了,git rebase
和-p
中的一个或两个都有。
答案 0 :(得分:2)
这可以通过单个rebase来移动提交(或任意数量的提交),然后从主题重做合并。
# Create some branches just for readability
git branch mergeCommit master^
git branch beforeMerge master^^
# Run the rebase
git rebase --onto beforeMerge mergeCommit master
# After the rebase master will have the replayed commits on top of C
# Redo the merge
git merge topic
使用此rebase,您可以在合并之前移动更多的提交。您可以在计划英语中阅读rebase指令:
将提交从
mergeCommit
抓取到master
并在beforeMerge
之上重新定位。
答案 1 :(得分:1)
第3张图中的提交M与第2张中的M不同,因为它具有不同的祖先。因此,您必须在M之前重置主服务器,或使用rebase执行此操作。
首先提交您的修补程序,然后使用git rebase -i
在M。
为避免再次解决冲突,请确保将rerere.enabled
设置为让git记住分辨率。在你第一次解决它之前你必须这样做,所以它会被记住。 Rerere(重用录制的分辨率)是一个很棒的功能。
答案 2 :(得分:1)
我发现的最好方法是:
git checkout -b tmp master^^
# Now tmp is on top of C
git cherry-pick master
# Now tmp is on top of C1', a copy of C1
git rebase -p tmp master
# Now master is on top of a merge commit from C1' and A
git branch -d tmp
我不知道为什么git rebase
如果没有git cherry-pick
就不能同时执行此操作,但至少我知道这有效。