如何在合并提交中移动提交?

时间:2014-01-18 06:10:51

标签: git git-merge git-rebase revision-history

假设我有一个这样的存储库:

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中的一个或两个都有。

3 个答案:

答案 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就不能同时执行此操作,但至少我知道这有效。