如何将一组mercurial存储库转换为git存储库?

时间:2015-10-30 17:54:19

标签: git version-control mercurial reposurgeon

我拥有什么

我目前有一组包含源代码的mercurial存储库。他们使用分支的“分叉存储库”方案。因此,功能“分支”可能如下所示:

master repo           A→B→C
                    ———————↘—————
cool_feature repo           D→E→F

一旦cool_feature准备好迎接黄金时段,我们hg pull将其变为主人,这样它就会显示如下:

master A→B→C→D→E→F

此时,cool_feature将与master具有相同的内容,并且可以将其丢弃。

虽然D→E→F在某些时间点位于单独的存储库中,但它们始终位于mercurial中的“默认”分支上。我们不使用命名分支来管理这些数据。

这在mercurial中运行良好,但我们计划转向git,git做的事情有点不同。当然,你仍然可以在git中使用fork repos,但git branch是短暂的,因此可用于短期分支。

我想要什么

我想将其转换为单个git存储库,该存储库使用分支来管理仍在库存中的工作。在流程方面,我们将基本上使用“git flow”。拉取请求将在分支之间进行,一旦工作完成,分支将被删除。

master branch           A→B→C
                     ————————↘—————
cool_feature branch           D→E→F

我尝试了什么

我不能简单地使用hg的convert,因为它不了解多个存储库。实际上,整个hg-git生态系统中的每个工具似乎都希望将git分支转换为hg分支,反之亦然。 (尽管有证据表明各社区在实践中使用它们的方式非常不同。)

一个想法是将它们拉入单个存储库,转换它,然后让git对其进行排序。毕竟,git只需要标记头部。这个想法的问题是大多数工具拒绝转换多头存储库,如果他们这样做,git会悄悄地丢弃未经标记的头部。如果有可能在事后标记它们,我还没弄明白。

另一个想法是,在mercurial中,将这些变更集移动到命名分支,并让存储库转换器完成工作。这很棘手,因为分支并不总是从一个点开始:

master repo            A→B→C→F→G→H
                     ———————↘—————↘————————
nifty_feature repo           D→E   I→J
                                \    ↓
                                 +——→K→L→M (K is a merge of E and J)

当两个开发人员一起开始一个项目的工作时,通常会出现这种情况,但最终不会出现与他们的起点完全相同的变更集。但是没有必要选择作为创建分支的“上线”。

另一个粗糙的情况是第一次修订是合并时:

master repo          A→B———→C
                        \    \
                         +→D  \
                    ————————\——↘—————————
gnarly_feature repo          +—→E→F

此处,分支的“根”是ECD之间的合并。鉴于它是一个合并版本,我不会立即明白你如何将它变为新分支。

由于其他原因,我已经通过reposurgeon运行转换,所以我可以访问一些相当奇特的工具来在飞行中修改它。但是每次转换大约需要20个小时,所以尝试一堆没有成功的东西已经证明是非常昂贵的。

但似乎因为人们确实从hg转换为git并且这些都是常用的分支方案,所以有人确实解决了这个问题。有关使用什么工具或尝试什么策略的任何想法都是受欢迎的。如何实现这一目标?

1 个答案:

答案 0 :(得分:1)

  

它们始终位于mercurial中的“默认”分支上。我们不使用命名分支来管理此数据

这是一个很大的错误:你可以同时使用命名分支+单独的克隆

  

我想将此转换为使用分支管理仍在广告资源中的工作的单个git存储库

可能是大错误2(方向/从Hg到Git /和方法/单个回购/)

  

整个hg-git生态系统中的每个工具似乎都希望将git分支转换为hg分支,反之亦然。

错了。我手里拿着Git-repo,用a set of Git-branches用hg-git克隆。在Mercurial的一面,我(正如预期的那样)有一个分支

>hg branches
default                     5266:1ffe854c93c1

和Git-branches,以hg书签形式呈现(他们确实是这样)

>hg book
   1.6                       2344:fc32e948fcba
   1.7                       5140:1c58e9bfa3d5
   2.0                       5219:683d072d02b6
   feature_dbpluginapi       4986:a855a635e17f
   feature_indexCleanup      5207:7ec7ee38ef2f
   feature_preview           4806:d40ade50b113
   feature_updateAll         4807:97ea12fea917
   master                    4620:de0053588acf
  

我不能简单地使用hg的转换,因为它不了解多个存储库

将其用于每个存储库转换:

  • 使用--branchmap option将每个feature-repo转换为中间Mercurial-repo(将default分支重命名为另一个... feature-name?)
  • 将转换后的repo拉入master-repo;您必须获得完整的历史记录,与旧的相同,但有一个例外:所有功能开发都将出现在唯一的命名分支
  • 使用hg-git或Git-Hg bridge
  • 将聚合回购推送到Git