2

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

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

Mercurial 将如何处理这种情况?

4

2 回答 2

4

这听起来像是Mercurial 子存​​储库的用例。

这意味着您可以将GraphicsEngine作为子存储库放入SpaceGame.
(或者如果您遵循推荐的结构,请创建一个包含GraphicsEngineandSpaceGame和子存储库的精简“包装器”存储库)

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

这也意味着(这就是您所问的)当您SpaceGame“从几个月前更新到修订版 467”时,GraphicsEngine子存储库会自动更新到它SpaceGame在 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),但最近的更改在 中不可见SpaceGameSeaGame因为它们都指向旧GraphicsEngine版本。

于 2013-01-03T10:36:50.740 回答
1

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

顺便提一句:

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

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

类似 Subrepo 的方式

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

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

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

使用 HEAD-linking,对于过去主 repo 的修订版 N,externals 必须处于修订版 M 的状态,这是修订版 N 时链接 repo 的最新修订版。幸运的是,svn 可以使用日期规范(不同的形式) 作为 -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

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

于 2013-01-03T14:33:01.313 回答