Merge mercurial中合并子存储库中多个分支的合并历史

Merge mercurial中合并子存储库中多个分支的合并历史,merge,mercurial,Merge,Mercurial,我从一个Mercurial存储库开始,它有多个子存储库,我正试图将它们合并到其中,就好像它们一直是主存储库的一部分一样。它们本来就不应该是子存储库 我整合了一个将旧历史转换为单个存储库的过程: 获取一个子repo并使用--filemap将其转换为子目录,将所有内容移动到一个子目录中,该子目录的名称应为其最终所在的目录,如下所述: 使用Clay Lenhart的答案从每个存储库中获取修订列表: 按日期对所有要合并的存储库中的所有修订进行排序 将每个修订逐个拉入单个新存储库 使用python脚本在生

我从一个Mercurial存储库开始,它有多个子存储库,我正试图将它们合并到其中,就好像它们一直是主存储库的一部分一样。它们本来就不应该是子存储库

我整合了一个将旧历史转换为单个存储库的过程:

  • 获取一个子repo并使用--filemap将其转换为子目录,将所有内容移动到一个子目录中,该子目录的名称应为其最终所在的目录,如下所述:
  • 使用Clay Lenhart的答案从每个存储库中获取修订列表:
  • 按日期对所有要合并的存储库中的所有修订进行排序
  • 将每个修订逐个拉入单个新存储库
  • 使用python脚本在生成的存储库上执行hg转换,如下所述:,以去除.hgsub和.hgsubstate文件中对子存储库的引用
  • 手动合并分支
  • 我留下的问题是历史记录不可用,也就是说,我无法返回并更新到特定的版本,因为每个分支只有自己的数据。假设我的主回购协议是A,子回购协议是B和C:如果我更新到分支A的历史记录,它没有来自分支B或分支C的文件,如果我更新到分支B的历史记录,它没有来自分支A或分支C的文件


    我想要的是某种方式将整个历史合并在一起,因此它主要是一个分支,来自所有分支的文件都出现在每个提交中。有没有办法将其转换为合并所有分支的历史记录,而不仅仅是最后的一次合并?

    虽然我没有一个固定的流程供您使用,但我可以告诉您哪里出了问题,这在步骤3-6中。您要做的是:

  • 列出所有子项目中的所有修订,使用超级项目/主回购来控制哪些修订按什么顺序分组。(作为步骤4的一部分,您可以随时执行此操作。)

  • 根据步骤3中获得的顺序,从下一个存储库引入(拉入)下一个版本。如果超级项目说下一次提交使用了子项目A的版本41、子项目B的版本97和子项目C的版本11,那么这三个版本就是引入的版本。然后将它们向下折叠为一个不引用任何子项目的修订版(例如,如果合适,使用
    hg histedit


  • 没有第5步,也没有第6步,因为此时没有要合并的内容:合并发生在第4步。

    我现在有一个工作流程。而不是对每一步都施加拉力:

  • 首先确定从每个存储库导入的总体顺序。[]中的内容是变量
  • (在源repo中,导出变更集):hg export--git-r[OldID]-o[TempPath]\patch[OldID]
  • (在目标回购中,选择父项):hg update--clean[ParentID]
  • (在目标repo中,导入变更集):hg import[TempPath]\patch[ID]--导入分支--旁路
  • (在目标repo中,抓取节点供以后使用):hg log-T“{rev}{node}”-r[NewID]
  • 这是因为补丁不包含完整的版本信息,只包含已更改的内容。它不希望父级与导出它的位置匹配,只希望与正在修补的文件匹配。由于每个补丁只影响一个存储库中一个分支的文件,所以这是一个完全合理的假设

    作为合并的变更集有点棘手。我必须编辑补丁文件,使其源节点ID与新导入的节点ID相匹配。这就是为什么我们必须在上面的步骤5中捕获节点ID。只要使用--exact,就可以导入合并变更集,但除非修补程序文件中的3个节点与存储库中的实际节点匹配,否则无法导入合并变更集

    因此,在合并的情况下,在上面的步骤2之后,修改补丁文件,使每个“#Parent”匹配目标存储库中正确的父节点ID。导入后,再次更新补丁文件,这次用导入的节点ID替换“#节点ID”

    此时,补丁文件应该具有所有3个精确的节点ID,“hg import--exact--bypass”将起作用。第二次导入修补程序时,它将覆盖已导入的现有节点,但会将其标记为适当节点之间的合并


    另一个稍微棘手的部分是确保合并的父级设置正确。每个合并都是根据一个分支合并到另一个分支来定义的。如果选择错误的父级,合并将失败。因此,我们将主分支定义为所有其他分支合并到的分支。当将两个存储库合并在一起时,您必须从头开始,然后沿着主分支返回到开始。只有来自每个存储库的主分支应该连接在一起,而其他分支作为单独的分支保留。

    此解决方案最终放弃了来自子项目的大量更改历史记录。主存储库有相当稀疏的签入,比如每20个子回购签入1个,因此这意味着丢弃大部分历史。我实际上正在研究另一种解决方案,但我仍然不确定我是否能让它正常工作。嗯,是的,这是真的-在“超级项目控制的概览历史”和“子项目中的个人历史”之间存在根本不匹配,这在一般情况下是无法解决的。但是,如果超级项目历史记录没有随机选择子项目历史记录,则可以在分支上进行合成,以保持一定的分离—一系列线性(或大部分线性)子项目提交导入。如果您通过单独执行步骤3来创建一种全局视图,那么这将是一个很好的控制。