Hg子存储库依赖项

时间:2011-04-11 12:59:51

标签: mercurial dependencies subrepos

过去有一些关于Hg子回购依赖关系的问题(herehere)但是接受的答案似乎并没有解决我的问题。

我的一个项目有4个依赖项:A,B,C,D。D依赖于A,B和C;而B和C依赖于A:

dependency graph of A,B,C,D

我想使用Hg子存储库存储它们,以便我可以跟踪它们依赖的每个版本。这是因为,当我在这个项目中使用A,B,C和D时,其他项目只需要A和B 。因此,B和C必须独立于D来跟踪它们所需的A版本。同时,在我的应用程序中,给定版本的D引用的B和C版本必须始终使用与A引用的版本相同的A版本。给定版本的D(否则它将在运行时崩溃)。我真正想要的是允许他们在同一目录中作为兄弟姐妹互相引用 - 即D's .hgsub看起来像下面这样,而B和C看起来就像是第一行。

..\A = https:(central kiln repo)\A
..\B = https:(central kiln repo)\B
..\C = https:(central kiln repo)\C

然而,这似乎不起作用:我可以看到为什么(给人们足够的绳索让自己挂起来很容易),但我觉得它是我的依赖项的最佳解决方案,这是一种耻辱。我已经阅读了一些建议的解决方案,我会快速概述这些解决方案,以及它们为什么不能为我工作:

  1. 将副本包含为嵌套子目录,将这些副本引用为Hg子存储库。这产生了以下目录结构(我删除了A,B,C,B \ A,C \ A的主副本,因为我可以接受引用\ D中的副本而不是):

    • 项目\(所有主要项目文件)
    • 项目\ d
    • 项目\ d \ A
    • 项目\ d \乙
    • 项目\ d \ B \ A
    • 项目\ d \ C
    • 项目\ d \ C \ A

    这种方法存在问题:

    • 我现在在磁盘上有3个A副本,所有这些副本都可以进行独立修改,在推送到中央仓库之前必须同步并合并。
    • 我必须使用其他机制来确保B,C和D引用相同版本的A(例如D可以使用v1而D \ B可以使用v2)
  2. 变体:使用上述但指定.hgsub的RHS指向父副本中的副本(即B和C应该具有.hgsub):< / p>

    A = ..\A
    

    这种方法存在问题:

    • 我的磁盘上还有三个副本
    • 我第一次克隆B或C时会尝试递归地从“.. \ A”中提取A的引用版本,这可能不存在,可能会导致错误。如果它不存在,则不知道应该找到回购的位置。
    • 当我进行递归推送更改时,D \ B \ A中的更改不会进入共享的中央存储库;他们只是被推到D \ A而不是。因此,如果我连续两次推送,我可以保证所有更改都会正确传播,但这是一种软糖。
    • 同样地,如果我进行(手动)递归拉动,我必须得到正确的顺序以获得最新的更改(即在我拉D \ B \ A之前拉D \ A)
  3. 使用符号链接将文件夹\ D \ B \ A指向D \ A等。

    这种方法存在问题:

    • 符号链接无法在Hg repo本身中进行编码,因此每次团队成员克隆回购时,他们都必须手动/使用脚本重新创建符号链接。这可能是可以接受的,但我更喜欢更好的解决方案。另外(个人喜好)我发现符号链接非常不直观。
  4. 这些是最好的解决方案吗?我的初始.hgsub(参见顶部)是一个真正的梦想,还是有一种方法可以请求/实施此更改?

    更新以更好地解释A,B,C,D的广泛使用

2 个答案:

答案 0 :(得分:4)

不要尝试通过Mercurial(或任何SCM)来管理您的依赖关系,而是尝试使用依赖关系管理工具,例如Apache Ivy

使用基于常春藤的方法,你没有任何子回购,你只有项目A,B,C和D.产生一个工件(例如.jar,.so或.dll等) ,使用版本发布到工件存储库(基本上是保存构建工件的地方)。然后,项目B和C可以依赖于Avy的特定版本(通过每个项目中的ivy.xml文件控制),Ivy将从工件库中检索该版本。项目B和C还会生成发布到您的存储库的人工制品。项目D依赖于B和C,Ivy可以被告知可以传递地检索依赖项,这意味着它将获得B,C和A的工件(因为它们依赖于A)。

类似的方法可用于Apache MavenGradle(后者使用常春藤)

主要优点是:

  • 它非常清楚项目正在使用的每个组件的版本(有时人们忘记检查.hgsub,因此他们不知道他们正在使用子版本),
  • 它使得无法更改依赖项目(因为您正在使用工件,而不是代码)
  • 它使您不必重建依赖项目并且不确定您正在使用的版本。
  • 使您免于拥有其他项目使用的多个项目冗余副本。

编辑:类似的答案,在Best Practices for Project Feature Sub-Modules with Mercurial and Eclipse?

稍微不同的旋转

答案 1 :(得分:1)

你说你想跟踪他们每个人依赖的版本,但你也对B,C和D之间共享的A副本感到满意。这些是相互排斥的 - 只有A的一个副本,任何变化到A将导致B,C和D各自的.hgsub发生变化,因此版本控制没有独立性(因为所有B,C和D都会在更改为A后提交。)

单独复制也会很尴尬。如果您进行的更改同时影响B的A副本和C副本,然后尝试推送整个结构,则对(例如)B的更改将成功,但对C的更改将失败,因为它们需要合并您刚刚推送的更改B,避免创造新的头脑。这将是一种痛苦。

我这样做的方式(也许有更好的方法)是用A,B和C的子目录创建一个D repo.B和C中的每一个都有一些未跟踪的A位置文件(你可以'重新提示通过后克隆hook进入,告诉您的构建系统在哪里查找其A存储库。这有工作的优点,但是你失去了跟踪{B,C}和A的并发版本的系统的便利性。再一次,你可以用钩子更新的B或C中的A版本文件手动完成,从一个钩子读取,你可以做到这一点,但我不认为在hg中使用subrepos实现是可能的。我的建议实际上归结为实现自己的简化子系统。