调整svn:externals用法以移动到Mercurial

fsc*_*itt 4 svn mercurial branch externals subrepos

我们在企业环境中有一个svn存储库结构,如下所示:

root
  libs
    shared_lib1
    shared_lib2
    private_lib
  public_code
  private_code
Run Code Online (Sandbox Code Playgroud)

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

我现在想知道从这个结构转移到mercurial存储库的最佳方法是什么.

1)我可以使用mercurial子存储库来密切模拟旧的设置.或者
2)我可以为我们制作一个大型仓库,为外部合作伙伴创建三个新的小型独立存储库(基本上是分支项目),并在大型和独立的交换机之间交换变更集.

使用svn中的setup 1),分支是一场噩梦,因为当我分支root时,策略总是必须分支public_code,shared_lib1和shared_lib2.为此,我必须调用svn分支四次并手动修改svn:externals属性三次.我可以轻松地将主仓库分支到mercurial并自动获取所有子仓库的新分支吗?

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

Mar*_*ler 5

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

不,子存储库不能像那样工作.顶级存储库中的命名分支不会自动传播到子存储库.如果你1.x在代码中创建了一个分支,那么还不清楚shared_lib1是否还应该有1.x分支.事实上,它可能不应该同时分支顶级代码分支,特别是如果库被几个不同的顶级项目使用.

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

不,如果您创建它们,则无法在存储库之间进行推送和拉取.只有当存储库来自同一个"母"存储库时,才能在存储库之间推/拉.这听起来像你将创建三个不相关的存储库.


在这种情况下,您应该仔细评估svn:externalsSubversion中的原因以及它们如何映射到Mercurial子库.它们不是1-1的替代品svn:externals.您还应该查看subrepos的工具支持 - 包括Mercurial本身和Mercurial托管,继续构建系统等.我编写了Mercurial子代码的一部分,从Mercurial 2.0开始,这里和那里仍然有一些尖锐的边缘.

简而言之,子仓库给你的是子系统之间非常紧密的耦合.这通常是应该避免的:-)我们努力使我们的软件系统松散耦合,因为这给了我们灵活性.

主要用例subrepositories是你跟踪你在一个特定的build使用您的组件的精确版本"建库".您不能要求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
Run Code Online (Sandbox Code Playgroud)

然后,您发布了2.3版本的软件,Mercurial知道它取决于版本2.0 shared_lib1.当负责子组件的人员告诉您他们已为您准备好新版本时,您偶尔会执行此操作.您的CI服务器当然可以每晚进行此操作以查看组件是否协同工作!

Subrepositories作用不佳,如果开发商在工作root直接,如果他们进行更改子作为自己工作的一部分root.这表明组件之间的耦合过于紧密:如果主代码依赖于子组件的精确变更集,那么子组件应该直接在主代码中.此外,hg commit在顶级存储库中将递归并在subrepos中使用相同的提交消息ui.commitsubrepos=True.(默认值False在Mercurial 2.0中更改.)这通常是不希望的,当它确实有意义时,那么subrepo非常紧密耦合,应该是顶级repo的一部分.

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