Mercurial - 退出旧合并

时间:2013-08-08 22:07:18

标签: mercurial

我有一个看起来像这样的分支:

A->B->C->D->...->Z
     ^
1->2-^

其中C是来自2及其祖先的合并。

我现在意识到我不应该合并。我可以回到B并移植D ...... Z,但这是很多工作。我可以退出JUST C吗?

当我尝试hg backout --merge C时,我得到中止:无法撤销合并变更集

这些更改已被推送到中央仓库,我不打算修改历史记录或任何内容,我只想要2的倒数,它的祖先会回到B的共同后代。

5 个答案:

答案 0 :(得分:10)

合并是公开的,并且此合并有公共提交

假设我们已发布此提交的历史记录(顶部是最新的):

                  rev5
                   |  
                  rev4
                   |
                  rev3     <- unwated merge commit (rev2 to rev1)
                   |   \    
wanted branch ->  rev1  rev2    <- unwanted branch
                   |     |

相反,我们希望顶级状态好像我们有这样的历史:

                  rev5
                   |  
                  rev4
                   |       
wanted branch ->  rev1  rev2    <- unwanted branch
                   |     |

如何实现(逐步)

  1. 将合并提交(rev4 - rev5)后的历史记录折叠为一个提交

    $ hg update -r rev3                # Update to merge commit
    $ hg revert --all -r rev5          # Revert to the newest commit
    $ hg commit -m "collapsed commits" # Create new commit ('rev6')
    
                       rev5
                        |  
                  rev6 rev4
                     \ /
                     rev3
                      |  \    
                    rev1  rev2
                      |    |
    
  2. 将合并后的更改('rev6')复制到所需分支('rev1')

    $ hg update -r rev1    # Update to the last "wanted" commit before merge
    $ hg graft -r rev6     # Copy changes from 'rev6' (create 'rev7' commit)
    
                       rev5
                        |  
                  rev6 rev4
                     \ /
               rev7  rev3
                  \  / \    
                 rev1  rev2
                   |     |
    
  3. 创建“退出”提交

    $ hg update -r rev5                   # Update to the top commit
    $ hg revert --all -r rev7             # Copy state 'rev7'
    $ hg commit -m "Reverted rev3 merge"  # Create 'rev8' commit
    
                       rev8
                        |
                       rev5
                        |  
                  rev6 rev4
                     \ /
               rev7  rev3
                  \  / \    
                  rev1  rev2
                   |     |
    
  4. 清理临时提交

    $ hg strip rev6 rev7
    
                      rev8          <- reverted 'rev3' merge
                       |  
                      rev5
                       |  
                      rev4
                       |
                      rev3     <- unwated merge commit (rev2 to rev1)
                       |   \    
    wanted branch ->  rev1  rev2    <- unwanted branch
                       |     |
    

答案 1 :(得分:9)

有点晚了,但我前一段时间也有同样的情况。这对我很顺利:

hg update -C -r "revision-C"
hg revert --all -r "revision-B"
hg commit -m 'UNDO blah blah whatever the merge did'
hg update -C -r "revision-Z-or-whatever-the-current-head-is"
hg merge -r "the-new-revision-created-in-step-3"

基本上,这正是退出所做的。

免责声明:但请注意,如果您将来要再次合并1-&gt; 2分支,则很可能会遇到一些问题。而“一些问题”在这里是一个有点过分的术语。事实上,即使是 BIG PROBLEMS 也可能出现在这种情况下。这种情况很危险,主要是因为这些问题可能会在以后发生并且完全出乎意强烈建议完全放弃“1”分支以避免这些风险。 (另见下面的评论。)

有关详细信息,请参阅Backout wiki page

答案 2 :(得分:1)

你可以使用thg backout工具。

  1. 更新合并更改集(C)
  2. thg backout
  3. 选择要退出的父项(无论(2)的修订版本是什么) - 请注意,您实际上选择的对象是您想要保留的父项,而不是退出
  4. 点击下一步
  5. 点击提交
  6. 这将创建一个新的头部,您需要将其与Z合并或重新绑定到Z。

答案 3 :(得分:1)

您可以将D重新定位到ZB。 rebase的documentation甚至讨论了一些类似的情况。这应该在一个命令中可行。

答案 4 :(得分:1)

Mercurial确实允许退出合并修订版;但是,该功能已弃用。危险在于退出只会执行反向提交;如果您改变主意并希望重新添加已删除的合并,则无法通过再次合并分支来执行此操作。 (Hg将拒绝与当前版本的祖先进行合并;或者,如果在合并之后在分支上有其他一些提交,它将仅合并以下提交。)

命令语法为:

hg backout --rev MergeRevision --parent ParentRevision

其中ParentRevision是原始分支上的合并修订的父级(即不在合并的分支上);通常,这是合并的第一个父母。

该命令在TortoiseHg Workbench中不可用。

执行撤销(并解决潜在冲突)后,请务必查看新版本并在必要时进行修改。