Merge 我如何处理Mercurial中的闭合拓扑头?

Merge 我如何处理Mercurial中的闭合拓扑头?,merge,mercurial,Merge,Mercurial,在尝试实现和之间的集成时,我遇到了一个问题,Fog Creek支持人员指出,这可能是因为我的存储库中有太多拓扑头的问题。我们通常有一种模式,即在合并回主分支之前关闭一个分支,但这显然会不时被忘记 $ hg head -t | grep ^changeset: | wc -l 1361 我的理解是,当从托管Mercurial服务器拉取数据时,这些头需要以某种方式进行通信,以了解哪些头需要通过同步。这是一个很大的浪费,因为超过1100个这样的脑袋对我们来说已经完全死了——所以我想把这些脑袋扔掉 确

在尝试实现和之间的集成时,我遇到了一个问题,Fog Creek支持人员指出,这可能是因为我的存储库中有太多拓扑头的问题。我们通常有一种模式,即在合并回主分支之前关闭一个分支,但这显然会不时被忘记

$ hg head -t | grep ^changeset: | wc -l
1361
我的理解是,当从托管Mercurial服务器拉取数据时,这些头需要以某种方式进行通信,以了解哪些头需要通过同步。这是一个很大的浪费,因为超过1100个这样的脑袋对我们来说已经完全死了——所以我想把这些脑袋扔掉

确定我想要消除的头部非常简单:

$ hg log -r "heads(all()) - ( head() and not closed() )" --template "{node}\n" | wc -l
1199
我最初认为清理这一问题相当简单:

  • 创建一个新的虚拟分支
  • 迭代地将所有闭合拓扑头合并到虚拟分支中(保持局部)
  • 不幸的是,我遇到了几个问题:

    • 如果我从我当前的默认负责人开始虚拟分支,那么合并需要很长时间(我估计完成所有1100多个合并需要几周时间)
    • 如果从变更集0开始,我会很快遇到一个不明确的合并问题,我不知道如何解决(“不明确的合并-拾取的m操作”?)
    对我应该如何进行有什么想法或建议吗?我的迭代合并想法明智吗?从哪里开始的两个想法中的一个比另一个更合理吗

    非常感谢您的帮助

    一些(可能不相关的)注释

    • 合并的分支不会产生拓扑头,因此-在合并之前关闭分支只是浪费时间,我认为1361个分支中的大多数只是被忽略和废弃的分支(这是“坏习惯”)
    • 不需要到grep heads输出的管道:
      hg heads
      是可模板化的命令,您可以(代替grep)在heads命令或类似命令中使用
      -t“{node | short}\n”
      (输出中每个变更集的字符串)
    解决方案

    可以创建临时合并分支(更好-从当前tip开始,见下文),并在此合并中执行所有不需要的头(虚拟合并快速且非交互式,即易于自动化),然后将合并合并合并回tip(当然也可以使用虚拟合并,但在这一步中不需要虚拟合并-合并头在所有合并之后都不会改变)

    将拓扑头合并到合并中可以(我想)自动化-我不能为您提供完整的工作代码,只有提示:

  • wiki中的三行程序可以用作shell脚本,带有单个参数“REV to merge”

  • hg-y merge--tool=internal:fail REV
    REV是合并修订的任何标识符(变更集id,本地修订号),您可以从
    hg heads-t-t“TEMPLATE”
    列表中获取该标识符,并将其导入xargs,xargs从上面执行shell脚本


  • 执行无操作合并的最快方法是通过
    hg debugsetparents
    。例如:

    hg update REV1
    hg debugsetparents . REV2
    hg commit -m "No-op merge"
    
    请注意,
    debugsetparents
    之后的
    不是打字错误,而是指当前签出的父项。此外,请注意,
    hg debugsetparents
    允许您执行伪“合并”针对合并通常不允许的直接祖先。虽然这不会对Mercurial本身产生任何有害影响,但与存储库交互的其他工具可能会混淆,因此您应该避免误用
    hg debugsetparents
    ,其中一个父版本将是另一个的祖先


    其次,请注意,使用
    --close branch
    关闭已合并的分支通常没有什么意义。实际上,关闭标志仅由
    hg branchs
    使用,您可以使用
    hg branchs--active
    hg branchs-a
    删除没有活动头的分支(类似地,
    head()和heads(all())和not closed()
    作为所有未激活或关闭的分支头的revset)。因此,一个更简单的解决方案可能是去掉所有只存在于关闭分支上的拓扑头。

    谢谢@Reimer Behrends-你能澄清你的第一段吗?你的建议对我来说很有意义,但随后你大声喊叫“您应该避免这样做。”“避免这样做”部分是关于使用
    debugsetparents
    与祖先进行合并。我将重写以澄清这一部分。啊,谢谢-我不认为我会有这个问题,因为我只是将一堆悬垂的头合并到这个虚拟分支中(根据定义,头不是任何东西的祖先).快速跟进--这种方法对我来说效果很好。我在一两分钟内关闭了1100多个坏头,现在我的HTTP pull请求小得多。再次感谢您的帮助。