6

让我们来看三个案例:

  1. 这个说法很好。999是一个挂钩。这就是所谓的“旧格式”:

    foo -r999 http://myrepo/foo

  2. 或者,也可以像这样指定挂钩(以“新格式”),并且也很好:

    http://myrepo/foo@999 foo

  3. 但这里有一个“新格式”的并发症:-r999可以放在前面,这完全改变了它的含义,从一个钉子变成了一个“操作版本”。根据SVN Book ,实际挂钩变为 HEAD (即不再是确定性的) :

    -r999 http://myrepo/foo foo

    这就是为什么我认为这种格式可能是一个非常糟糕的主意:如果在 rev 999 之后将“bar”重命名为“foo”,实际上会签出哪些内容?重命名的版本,bar@999。这真的有用吗?然后,又发生了另一个重命名,将“baz”命名为“foo”。现在用户将检查 baz@999。因此,随着时间的推移,用户将永远无法确定 999 指的是同一个代码。

#3是一个等待引起麻烦的漏洞吗?是否应该用明亮的红旗警告用户以避免使用#3 的格式?或者它是否真的有用,尽管它具有不确定性?这几乎太容易被误解和出错,因此似乎需要指定最佳实践。

SVN Book中,如果您真的深入研究它,它会巧妙地提示用户要小心:

小心避免天真地重新定位定义的 -rNNN 部分 - 旧格式使用该修订作为挂钩修订,但新格式将其用作操作修订(除非另有说明,使用 HEAD 的挂钩修订;参见名为“Peg and Operative Revisions” 对这里的区别进行了完整的解释)。

4

2 回答 2

8

使用外挂?最佳实践?

这很容易!不要这样做!

svn:externals是其中一件看似不错的主意,但最终导致了各种问题。我发现有比使用svn:externals. 例如,您可以使用 Maven 或 Ivy 为您做依赖管理。

但是,如果我必须使用svn:externals,我将使用标签而不是绝对修订。这在较新版本的 Subversion 中效果更好,而且我通常不必担心使用特定版本,但是随着文件被重命名和移动,文件的 URL 都会发生变化。对我来说,标签是不可变的,一旦创建,它们就永远不会改变。

这也鼓励您将自己的svn:externals项目视为完全独立的项目。例如,您可以谈论 Foundation 4.3 版本。你的svn:externals命令看起来像这样:

$ svn propset svn:externals `^/tags/4.3/foundation foundation` .

注意我没有将 URL 方案放在标签或服务器名称中。如果外部与项目在同一个存储库中,我几乎总是使用相对路径。想象一下,如果您使用 to use http://,然后转到 using https://,或者您的 Subversion 存储库机器的名称发生更改。外部仍然可以使用这个方案,但是如果我这样做了就会中断:

$ svn propset svn:externals "http://server.com/svn//tags/foundation foundation" .

我是一个可悲的骗子

我目前正在一个项目中工作,我没有做我上面提到的事情。我不为 my 使用标签,svn:externals我们所有的项目都必须有它们。

在这家公司,他们在 jar 依赖管理方面遇到了一个可怕的问题。他们生产了十几个用于多个项目的基础罐子。这些项目中的每一个都有不同的方式来指定这些罐子

为了解决这个问题,我建立了一个名为ivy.dir. 开发人员被告知使用以下命令将此项目合并到他们当前的项目中:

$ svn propset svn:externals "../ivy.dir ivy.dir" .

里面ivy.dir是一个完整的设置,用于将您的项目集成到 Ivy。Ivy 已预先配置为使用我们新的企业 Maven 存储库。我们所有的各种构建工具都在这里。

这种方法使将 Ivy 和良好的依赖管理融入我们的项目变得轻而易举。您只需<import>ivy.dir/ivy.tasks.xml文件放入您的 currentbuild.xml中,并用于<ivy:cachepath>创建您的类路径。一个良好的、良好的格式build.xml只需要稍加修改即可运行。

我什至创建了一个特殊的<jar.macro>宏定义。它与<jar>宏几乎 100% 兼容,但它会自动创建一个pom.xml文件ivy.xml并将其嵌入到构建的 Jar 中(并且还将包括 Jenkins 项目名称、构建日期和构建号。)

通过使用相对 URL,我可以轻松地对所有内容进行分支或标记(并且 ivy.dir 项目也被标记)。

这是一种奇怪的使用方式svn:externals,但它让我们摆脱了以前的糟糕使用方式,其中许多项目过去常常svn:externals拉入存储在存储库中的 jar。

于 2013-10-04T02:53:16.477 回答
6

我同意你的观点,应该避免没有挂钩的修订号。我知道没有理由不指定明确的挂钩修订版(如果您使用的是明确的修订版,无论如何),它确保您始终可以毫无歧义地回滚到该修订版。在我工作的地方,我们总是以您列出的第二种格式指定我们的外部文件,其中 peg 既是 peg 又是操作修订版。或者,我们指向一个标签。因为标签不应该在提交后更改(并且可能调整外部等),并且在项目存储库路径中的如此高级别不太可能更改,这应该实现与使用显式修订相同的目标更有意义(对人类)格式。

请注意,您可以组合格式 2 和 3,但这不是必需的,例如-r 123 http://example.com/svn/proj@123 proj.

于 2013-10-03T22:27:34.907 回答