【问题标题】:Mercurial - How to manage multiple modulesMercurial - 如何管理多个模块
【发布时间】:2013-01-03 08:57:03
【问题描述】:

我在一个使用 Subversion 的团队中工作,我们正在考虑改用 Mercurial。

我们有多个独立的代码项目,以及一些项目之间共享的一些代码。为简单起见,假设有两个项目,SpaceGame 和 SeaGame,它们都使用来自 GraphicsEngine 的代码。 GraphicsEngine 的开发在某种程度上独立于游戏。假设我们需要将几个月前的 SpaceGame 更新为修订版 467; SpaceGame 需要回到 467 版,GrpahicsEngine 需要回到 SpaceGame 467 时的版本,GraphicsEngine 不能停留在最新版本。使用 Subversion 实现这一点的唯一方法是我们将所有项目都放入一个大存储库(外部不会给我们所需的行为)。但是,这给我们的团队带来了很多问题;仓库很大,几乎没有人想对其进行全面检查,他们只检查他们需要的项目。

如何使用 Mercurial 处理这种情况?

【问题讨论】:

    标签: svn version-control mercurial


    【解决方案1】:

    这听起来像是Mercurial subrepositories 的用例。

    这意味着您可以将GraphicsEngine 作为子存储库放入SpaceGame。
    (或者如果您关注the recommended structure,请创建一个包含GraphicsEngine 和@ 的精简“包装”存储库987654327@ 和子存储库)

    子存储库的工作方式,SpaceGame 并不总是包含GraphicsEngine 的最新版本...它指向某个固定修订,如果同时更新GraphicsEngine,SpaceGame 会不自动获取这些更改...您必须进行显式更新才能获取它们。
    这意味着SpaceGame 永远不会因为别人对GraphicsEngine 的更改而意外中断。

    这也意味着(这就是你问的问题),当你将 SpaceGame 更新为“几个月前的修订版 467”时,GraphicsEngine 子存储库 is automatically updated to the revision that it was at when SpaceGame was at 467。


    编辑:

    不,GraphicsEngine 仍然是一个单独的存储库,不为任何人“拥有”。
    如果您将它用作子存储库,它只是从父存储库“链接”(并且它可以从多个父存储库链接)。它仍然是一个单独的存储库。

    使用子存储库,这样的事情是可能的:

    GraphicsEngine      // main GraphicsEngine repo, current revision: 300
    
    SpaceGame           // main SpaceGame repo
      └ GraphicsEngine  // GraphicsEngine subrepo, current revision: 265
    
    SeaGame             // main SeaGame repo
      └ GraphicsEngine  // GraphicsEngine subrepo, current revision: 241
    

    SpaceGame 和 SeaGame 都有一个 GraphicsEngine 子仓库。
    每个子存储库“指向”GraphicsEngine 的某个修订版(在我的示例中为 265 和 241)。
    GraphicsEngine 中的开发仍在继续(GraphicsEngine 是 rev 300),但最近的更改在 SpaceGame 和 SeaGame 中不可见,因为它们都指向较旧的 GraphicsEngine 修订版。

    【讨论】:

      【解决方案2】:

      请注意:Christian 是对的,但我建议至少尝试使用 GuestRepo,而不是 Subrepo,它是针对某些 subrepos 限制和缺点而创建的。

      顺便说一句:

      外部不会给我们我们需要的行为

      只是错误的答案,是不良研究的结果。您可以通过两种不同的方式使用 svn:externals,两种方式(通过一些手工操作)都会为您提供所需的结果

      类似Subrepo的方式

      GraphicsEngine 作为外部链接,定义为 fixed revision。每次,当您必须并且必须在“SuperRepository”(带有外部的存储库)中使用更多新修订时,您必须更新外部定义并提交父项目。有了这样的硬链接,Superrepo 总是为父外部定义了一对修订。

      免费链接,时光倒流机中手动更新外链

      如果您不想担心在场景 1 中监视外部更新(在 singe externals 的情况下,可以使用钩子自动更新定义),您可以使用外部链接到GraphicsEngine 的 HEAD(不要在定义中使用修订版)用于手动(或通过某些脚本)更新包含外部数据的目录的成本。懒得写了,所以-这里只写工作流

      使用 HEAD-linking,对于过去主 repo 的修订版 N,externals 必须处于修订版 M 的状态,这是修订版 N 时链接 repo 的最新修订版。幸运的是,svn 可以使用 date-specifications (不同形式)作为 -r 选项的参数。您只需要确定提交 N 的日期时间并更新外部目录(获取“混合修订工作副本”)

      svn log -q -r N 在主仓库中会给出类似的东西

      ------------------------------------------------------------------------
      r34 | lazybadger | 2012-03-24 12:28:12 +0600 (Сб, 24 мар 2012)
      ------------------------------------------------------------------------
      

      暂时只记得日期字段“2012-03-24 12:28:12 +0600”。

      svn help up 确认,我们可以使用日期作为修订说明符

      -r [--revision] ARG      : ARG (some commands also take ARG1:ARG2 range)
                                   A revision argument can be one of:
                                   ...       
                                      '{' DATE '}'
                                   ...
      

      在SVN-Book,“修订日期”一章中,我们将为我们的 (date-time-TZ) 案例找到正确的格式

      ...
      $ svn checkout -r {"2006-02-17 15:30 +0230"}
      ...
      $ svn checkout -r {2006-02-17T15:30-04:00}
      ...
      $ svn checkout -r {20060217T1530-0500}
      

      第一种格式对我们来说是最好的选择(因为我们已经从 svn 日志中获得了它),因此 - 我们可以在 WC 中使用外部(仍然不与主版本同步)

      cd EXTERNAL-DIR
      svn up -r {"2012-03-24 12:28:12 +0600"}
      

      并以与过去相同的状态进入外部,当时主要修订版(在我的示例中)为 34

      PS:svn log ...| gawk {...} 可以轻松提取和存储基础修订的日期时间

      【讨论】:

        猜你喜欢
        • 2011-06-13
        • 2012-01-05
        • 2021-11-27
        • 2016-10-22
        • 2019-11-24
        • 2010-11-10
        • 2017-10-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多