16

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

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

哪里C是从2及其祖先的合并。

我现在意识到我不应该合并。我可以回去B嫁接D……Z但那是很多工作。我可以退出C吗?

hg backout --merge C当我尝试中止时:无法退出合并变更集

这些更改已被推送到中央存储库,我不想修改历史或任何东西,我只是想要2它的反面,它的祖先回到与B.

4

6 回答 6

13

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

假设我们有这个已发布的提交历史(顶部是最新的):

                  revZ
                   |
                  ...  
                   |
                  revD
                   |
                  revC     <- unwated merge commit (rev2 to revB)
                   |   \    
wanted branch ->  revB  rev2    <- unwanted branch
                   |     |

相反,我们希望拥有顶级状态,就好像我们有这段历史一样:

                  revZ'
                   |
                  ...  
                   |
                  revD'
                   |       
wanted branch ->  revB  rev2    <- unwanted branch
                   |     |

如何实现这一点(一步一步)

  1. 将合并提交 (revD - revZ) 合并为一个提交后的历史记录

    $ hg update -r revC                # Update to merge commit
    $ hg revert --all -r revZ          # revert to the newest commit
    $ hg commit -m "collapsed commits" # Create new commit (revTmp1)
    
                       revZ
                        |  
                       ...
                        |  
               revTmp1 revD
                     \ /
                     revC
                      |  \    
                    revB  rev2
                      |    |
    
  2. 将合并后的更改 (revTmp1) 复制到想要的分支 (revB)

    $ hg update -r revB    # Update to the last "wanted" commit before merge
    $ hg graft -r revTmp1  # Copy changes from revTmp1 (create revTmp2 commit)
    
                       revZ
                        |  
                       ...
                        |  
               revTmp1 revD
                     \ /
            revTmp2  revC
                  \  / \    
                 revB  rev2
                   |     |
    
  3. 创建一个“退出”提交

    $ hg update -r revZ                   # Update to the top commit
    $ hg revert --all -r revTmp2          # Copy state revTmp2
    $ hg commit -m "reverted revC merge"  # Create revZ' commit
    
                       revZ'
                        |
                       revZ
                        |  
                       ...
                        |  
               revTmp1 revD
                     \ /
            revTmp2  revC
                  \  / \    
                  revB  rev2
                   |     |
    
  4. 清理临时提交

    $ hg strip revTmp1 revTmp2
    
                      revZ'          <- reverted revC merge
                       |  
                      revZ
                       |  
                      revD
                       |
                      revC     <- unwated merge commit (rev2 to revB)
                       |   \    
    wanted branch ->  revB  rev2    <- unwanted branch
                       |     |
    
于 2016-10-19T22:18:36.333 回答
10

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

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"

基本上,这正是 backout 的作用。

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

有关详细信息,请参阅退出 wiki 页面

于 2013-11-26T09:47:13.720 回答
2

使用回退工具,但要注意你在做什么:

  1. 更新合并变更集 (C)
  2. 右键单击该更改集->单击退出
    • 在分支上执行回退后,您不需要立即提交它。最好在之前检查一下,如果(在选择Backout选项后出现的更改中)不是您不想退出的其他分支的一些更改。如果是这样,请在提交之前取消选中它们。
  3. 单击提交
    • 如果您现在(或以后)将分支1-2(或“编号分支”)合并到分支A-Z中,您将丢失变更集(包括)之前“编号分支”的所有更改2- 这就是 @Marvin 答案中的警告。
    • 为避免这种情况,您需要将此撤销传播到“编号分支”并重做撤销的更改(后续步骤)。
  4. 如果分支A-Z不是“编号分支”的直接祖先,则找到和之间的第一个后代分支A-Z并将1-2工作台更新到其尖端。
  5. 右键单击A-Z(= backout) 中的最新修订 -> 单击与本地合并
    • A-Z如果和之间有更多分支1-2,请重复步骤 4. 和 5。
    • 不要将任何东西合并到分支1-2中。
    • 注意:始终只将任何分支合并到其起源的分支中!否则,您可能会在未来合并后丢失一些更改。
  6. 更新到“编号分支”的提示。
  7. 查找所有被回退更改的文件(在文件系统上)并将它们复制到某个临时目录。
  8. 右键单击编号分支的祖先的最新版本->单击与本地合并
  9. 将第 7 步中的文件复制回文件系统。
  10. 检查工作台中的更改并取消选中所有不是来自分支1-2的更改(例如来自修订版的更改D- Z)。
    • 不幸的是,这必须手动检查。但这是纠正两个分支的唯一安全方法。
  11. 点击提交

提示:要真正确定哪些文件受到任何合并的影响,请右键单击该修订并单击Diff to parent

这基本上是我们今天使用的场景,当我们发现一个分支(仍在开发中)意外合并到默认分支中(而不是另一个分支,在修订图中具有相同的颜色:)。(在这次合并之后,两个分支都推送了更改。)这可能看起来很耗时,但仍然比仅退出合并并在数天(或数周)后发现大量意外错误要好。(自己的经验。)

于 2016-08-12T16:42:35.540 回答
1

您可以D重新定位ZB. rebase的文档甚至讨论了一些类似的情况。这应该可以在一个命令中完成。

于 2013-08-09T14:40:32.757 回答
1

您可以使用 thg 退出工具。

  1. 更新合并变更集 (C)
  2. thg 退出
  3. 选择您要退出的父级(无论 (2) 的修订版是什么) -请注意,您实际上是在对话框中选择了您想要保留的更改的父级,而不是退出
  4. 点击下一步
  5. 单击提交

这将创建一个新的头,您需要将其与 Z 合并或重新定位到 Z。

于 2013-08-09T13:12:36.217 回答
1

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

命令语法为:

hg backout --rev MergeRevision --parent ParentRevision

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

该命令在 TortoiseHg Workbench 中不可用。

执行回退(并解决潜在冲突)后,请务必查看新修订并在必要时进行修改。

于 2018-04-09T10:25:49.173 回答