2011-12-23 60 views
4

我们在企业环境中得到了一个SVN仓库结构,看起来像这样:适应的svn:externals的使用情况迁移到水银

root 
    libs 
    shared_lib1 
    shared_lib2 
    private_lib 
    public_code 
    private_code 

其中public_code是一个外部存储库是开源的,人们从公司外部有读写访问权限。 shared_lib1和shared_lib2也是与其他公司的另一组程序员共享的外部存储库。我是维护者,基本上可以做任何技术上最好的,外部用户将不得不适应。

我现在想知道的最好的办法就是从这种结构转移到Mercurial库的内容。

1)我可以逼真地模拟使用水银subrepositories的旧体制。 OR
2)我可以让我们一个大的回购和三个新的更小,对于大的和独立的人之间的外部合作伙伴(所以基本上分叉项目),交流变更单独的存储库。

随着SVN设置1),分支是一场噩梦,因为我的策略始终有分支public_code,shared_lib1和shared_lib2当我支根。为此,我必须四次调用svn分支并手动修改svn:externals属性三次。我可以轻松地将主要repo分支到mercurial并自动获取所有子存储库的新分支吗?

当我设置2),文件系统将回购之间的不同。例如。我将在repo“root”中拥有public_code/Makefile,但该文件将在repo“public_code”中成为“Makefile”。 Mercurial仍然能够同步回购之间的变化吗?工作流程怎么样?

回答

5

随着SVN设置1),分支是一场噩梦,因为我的策略始终有分支public_codeshared_lib1shared_lib2当我分支root。为此,我必须拨打svn branch四次,并手动修改svn:externals属性。我可以轻松地在Mercurial中分支主库吗并自动获取所有子库的新分支机构?

不,subrepositories不起作用这样。顶层存储库中的命名分支不会自动传播到子存储库。如果您在代码中创建了1.x分支,则不清楚shared_lib1也应该具有1.x分支。实际上,它可能不应该同时分支顶级代码分支,特别是当库被几个不同的顶级项目使用时。

当我做设置2)时,文件系统将在回购之间不同。例如。我将在public_code/Makefile回购root但该文件将只是Makefile在回购public_code。 Mercurial仍然能够同步回购之间的变化吗?工作流程怎么样?

不,你不能在存储库之间进行推拉,如果你像这样创建它们。您只能在源自同一个“母亲”存储库的存储库之间进行推/拉操作。这听起来像你会创建三个不相关的存储库。


在这样的情况下,你应该你为什么svn:externals的颠覆,以及它们如何映射到Mercurial subrepositories仔细评估。他们不是svn:externals的1-1替代品。你还应该看看subrepos的工具支持 - 无论是在Mercurial本身还是你的Mercurial主机,你的继续构建系统等等。我写了Mercurial subrepo代码的一部分,从Mercurial 2.0开始,这里和那里仍然有一些尖锐的边缘。

简而言之,子系统给出的是一个子系统之间非常紧密的耦合。这通常是要避免的:-)我们尽力使我们的软件系统松散耦合,因为这给我们带来了灵活性。

子库的主要用例是一个“构建库”,您可以在其中跟踪您在给定构建中使用的组件的精确版本。您不能要求Mercurial跟踪子报表中给定分支的提示,它会始终跟踪给定存储库中的给定更改集。这可以在稍后重新创建给定结账:.hgsubstate文件跟踪每个子报告中签出的精确变更集。

因此,如果您的root存储库不用于开发,但仅用于构建版本,那么子存储库实际上可以为您工作。工作流会像

$ cd root 
$ cd libs/shared_lib1 
$ hg pull 
$ hg update 2.0 
$ cd ../.. 
$ make test && hg commit -m "Updated to sharedlib1 2.0" 
$ hg tag 2.3 

然后你发布你的软件的2.3版本和Mercurial知道,这取决于shared_lib1 2.0版本。如果负责子组件的人员告诉您他们已经为您准备好新版本,您会偶尔做一次。你的CI服务器当然可以每晚做这个,看看这些组件是否可以一起工作!

如果开发人员直接在root中工作,并且他们在root中作为他们工作的一部分对子部件进行了更改,则子分类库工作得不好。这表明组件之间的耦合太紧密:如果主代码依赖于子组件的确切变更集,那么子组件应该直接在主代码中。另外,顶层存储库中的hg commit将递归并在ui.commitsubrepos=True中使用subrepos中的相同提交消息。 (默认情况下,Mercurial 2.0中的默认值更改为False)。这通常是不期望的,当它确实有意义时,那么子报表就会非常紧密地耦合在一起,并应该成为顶级回购的一部分。

因此,总结一下:如果root是“构建库”,则使用subrepos。否则,您应该内联顶级存储库中的组件,或者应该使用类似Maven或类似的方法更松散地将这些组件连接在一起,以管理依赖关系。这些工具通常会让你说“请获取最新版本的root及其所有依赖项”,然后当你对测试感到满意时,你可以正式发布。这些“快照”版本无法精确复制,但这也不是必需的 - 只有最终版本需要严格和精确的依赖关系跟踪。

+0

感谢这个非常有帮助和详细的答案。 – fschmitt 2011-12-29 22:14:46

+0

+1使用像Maven这样的构建工具来管理依赖关系。 – 2012-01-02 17:40:52

相关问题