简体   繁体   English

如何撤消两个要素分支之间的合并?

[英]How to undo a merge between two feature branches?

OK, here is the situation: Two of my colleagues worked on two new features ( feature_1 and feature_2 ). 好的,情况是这样的:我的两个同事研究了两个新功能( feature_1feature_2 )。 Now there were some changes in one branch feature_1 , the other developer want to see in his branch feature_2 . 现在,一个分支feature_1进行了一些更改,另一位开发人员希望在其分支feature_2进行查看。 So he merged the branch feature_1 into his branch feature_2 . 因此,他将分支feature_1合并到他的分支feature_2 It can be illustrated as so: 可以这样说明:

Before the merge: 合并之前:

P--o--o--o    master
\\     
 \\B--C--D    feature_1
  \
   \A--E      feature_2

After the merge: 合并后:

P--o--o--o    master
\\     
 \\B--C--D    feature_1
  \       \
   \A--E---M  feature_2

He pushes the merge commit and both developers are going to continue working on their branches. 他推动合并提交,并且两个开发人员都将继续在其分支机构上工作。

P--o--o--o--o--o--o    master
\\     
 \\B--C--D--o--o--o    feature_1
  \       \
   \A--E---M---o--o    feature_2

Now it's time to merge feature_2 back into master. 现在是时候将feature_2合并回master了。 But if we would just do that, all changes from feature_1 (at least those from the last merge from feature_1 into feature_2 ) would be merged back into master. 但是,如果我们只是做到这一点,所有的变化feature_1 (至少是那些从上次合并feature_1feature_2 )将被合并到主。 But as feature_1 is not ready yet, that should not happen. 但是由于feature_1尚未准备就绪,因此不应该发生。

So how can we "unmerge" feature_1 from feature_2 , so the commits from feature_1 will not be merged into master. 因此,我们如何才能从feature_2 “取消合并” feature_1 ,因此来自feature_1的提交将不会合并到master中。

I tried to do a git rebase master on feature_2 , but this would only remove the merge commit M, but leave the commits B, C and D (or more precice B', C' and D') on feature_2 . 我试图做一个git rebase masterfeature_2 ,但这只会删除合并提交男,但离开提交B,C和d(或以上precice B“ C”和d')上feature_2

Any ideas on how to get the commits from feature_1 out of feature_2 ? 如何获得从提交任何想法feature_1feature_2 We wouldn't mind to rebase and force push or create a new branch with only the commits from feature_2 . 我们不介意仅使用来自feature_2的提交来重新设置基础并强制执行推送或创建新分支。

UPDATE (my solution): 更新(我的解决方案):

Thanks to @kan, who provided a nice solution for my merge issue. 感谢@kan,他为我的合并问题提供了一个很好的解决方案。 In the comments we also discussed, how to solve it, when multiple merges from feature_1 to feature_2 happend. 在注释中,我们还讨论了从feature_1feature_2发生多次合并时如何解决。 I have found a solutions in a single command, that would to the trick. 我已经在一个命令中找到了解决方案,这可以解决问题。 So let's assume, we have the following scenario: 因此,假设有以下情形:

P--o--o--o--o--o--o--o    master
\\     
 \\B--C--D--o--o--o--o    feature_1
  \       \     \
   \A--E---M--o--M2--o    feature_2

So we have merged twice. 所以我们已经合并了两次。 No a rebase also have to be done twice. 无需重新设置基准也必须执行两次。 The first one -with --onto M2^ M2 and the second one with --onto M^ M . 第一个--onto M2^ M2 ,第二个--onto M^ M This can be done with this single command: 这可以通过以下单个命令完成:

git rev-list --ancestry-path master..HEAD --merges | xargs -I % git rebase --onto %^ % feature_2

This will basically get all the merge commits from the range master to the HEAD of feature_2 two and runs the rebase on "from right to left". 基本上,这将从范围master到特征feature_2HEAD的所有合并提交,并在“从右到左”上运行重新设置。 So it will first use M2 and than M in the rebase. 因此,它将首先使用M2,而不是在基准库中使用M。 This command can also be used, if there is only one merge commit, but than you can simply use the shorter git rebase --onto M^ M command. 如果只有一个合并提交,也可以使用此命令,但是比起您可以简单地使用较短的git rebase --onto M^ M命令。

The most visible way to do it - do rebase -i and manually drop feature_1's commits. 最可见的方式-重新设置rebase -i并手动删除feature_1的提交。 If there are too many commits to filter manually, let me know, I'll try think harder... 如果提交的提交过多,无法手动过滤,请告诉我,我会努力考虑的...

Ok. 好。 Thinking harder... ;) 认真思考...;)

I suggest, there is only one merge point M. In this case you should rebase all commits after merge commit onto the commit right before merge point. 我建议只有一个合并点M。在这种情况下,应将合并提交后的所有提交重新设置为合并点之前的提交。 Use git rebase --onto EM feature_2 . 使用git rebase --onto EM feature_2

Since this particular merge has been pushed, you are going to want to revert the merge commit . 由于已经推送了此特定的合并,因此您将要还原合并提交

git revert -m 1 <SHA-of-M>

Should you want to reintroduce any of the changes from feature_1 again, you will have to revert the revert , but this is the safest option, as it preserves the history of your commits. 如果您想再次从feature_1重新引入任何更改,则必须还原revert ,但这是最安全的选择,因为它保留了提交的历史记录。

To clarify a bit on "revert the revert": suppose that you've merged this branch to master. 为了澄清“还原还原”:假设您已将此分支合并到master。

P--o--o--o--o--o--o---F2 master
\\                    /
 \\B--C--D--o--o--o  /   feature_1
  \       \         /
   \A--E---M---o--R/     feature_2

If you want to merge feature_1 into master , you will have to first revert the revert commit that came along with the merge into master (so, you'd have to revert the R commit). 如果要将feature_1合并到master ,则必须首先还原与合并到master中一起的还原提交(因此,您必须还原R提交)。

P--o--o--o--o--o--o---F2--R'-F1   master
\\                    /     /
 \\                  /     /
  \\                /     /
   \A--E---M---o--R/     /        feature_2
    \       \           /
     \B--C---D--o--o--o/          feature_1 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM