我们来看三个案例:
这句话很好。 999是一个挂钩。这就是所谓的“旧格式”:
foo -r999 http://myrepo/foo
或者,也可以像这样指定peg(“新格式”),也很好:
http://myrepo/foo@999 foo
但是这里有一个“新格式”的复杂功能:-r999
可以放在前面,这完全是从一个挂钩变成一个“操作版本”。根据to SVN Book,实际挂钩变为HEAD(即不再具有确定性):
-r999 http://myrepo/foo foo
这就是为什么我认为这种格式可能是一个非常糟糕的主意:如果在999之后将“bar”重命名为“foo”,实际上会检出哪些内容?重命名的版本,@ 999吧。这真的有用吗?然后,另一个重命名发生,将“baz”命名为“foo”。现在用户将查看baz @ 999。因此,随着时间的推移,用户永远不会确定999是指相同的代码。
#3是一个等待制造麻烦的漏洞吗?是否应该用鲜红色警告用户以避免使用#3的格式?或者它是否真的有用,尽管它具有非确定性?这几乎容易误解和出错,因此似乎需要指定最佳实践。
从SVN Book开始,如果你真的深入研究它,它会巧妙暗示用户要小心:
小心避免天真地重新定位定义的-rNNN部分 - 旧格式使用该修订作为peg修订版,但较新的格式将其用作操作修订版(除非另有说明,否则使用HEAD的挂钩修订版;请参阅“Peg and Operative Revisions”这一部分是对这里区别的完整解释。)
答案 0 :(得分:7)
使用外部?最佳做法?
这很简单! 不要这样做!
svn:externals
是其中一个似乎是个好主意的事情,但最终导致了各种各样的问题。我发现有比使用svn:externals
更好的方法。例如,您可以使用Maven或Ivy为您进行依赖管理。
但是,如果我必须使用svn:externals
,我将使用标签而不是绝对修订版。这在较新版本的Subversion中效果更好,我通常不必担心使用特定的修订,但随后文件的URL会随着文件重命名和移动而改变。对我来说,标签是不可变的,一旦创建,它们就永远不会改变。
这也鼓励您将svn:externals
视为完全独立的项目。例如,您可以谈论基金会的4.3版。您的svn:externals
命令看起来像这样:
$ svn propset svn:externals `^/tags/4.3/foundation foundation` .
注意我没有将URL方案放在标记或服务器名称中。如果外部与项目位于同一个存储库中,我几乎总是使用相对路径。想象一下,如果您使用http://
,然后转到使用https://
,或者Subversion存储库机器的名称发生变化。外部仍然可以使用这个方案,但是如果我这样做了就打破了:
$ svn propset svn:externals "http://server.com/svn//tags/foundation foundation" .
我目前正在一个项目中工作,我没有按照上面提到的那样做。我没有为我的svn:externals
使用标签,我们所有的项目都必须拥有它们。
在这家公司,他们遇到了jar依赖管理的严重问题。他们生产了大约十二个基础罐子,用于多个项目。这些项目中的每一个都有不同的方式来指定这些罐子
为了解决这个问题,我设立了一个名为ivy.dir
的特殊常春藤项目。开发人员被告知使用以下命令将此项目合并到他们当前的项目中:
$ svn propset svn:externals "../ivy.dir ivy.dir" .
内部ivy.dir
是一个完整的设置,可以将您的项目集成到Ivy中。 Ivy已预先配置为使用我们新的企业Maven存储库。我们所有的各种构建工具都在这里。
这种方法将常春藤和良好的依赖管理融入我们的项目中变得轻而易举。您只需将<import>
ivy.dir/ivy.tasks.xml
个文件放入当前build.xml
,然后使用<ivy:cachepath>
创建类路径。一个好的,格式良好的build.xml
只需要稍加修改就可以运行。
我甚至创建了一个特殊的<jar.macro>
宏定义。它与<jar>
宏几乎100%兼容,但它会自动从pom.xml
创建一个ivy.xml
文件并将其嵌入到构建的Jar中(并且还将包含Jenkins项目名称) ,构建日期和内部版本号。)
通过使用相对URL,我可以轻松地分支所有内容或标记它(并且ivy.dir项目也会被标记)。
使用svn:externals
这是一种奇怪的方式,但它允许我们摆脱之前使用svn:externals
拉入存储库中存储的jar的许多项目之前的糟糕使用。 / p>
答案 1 :(得分:6)
我同意你的意见,应该避免没有挂钩的修订号码。我知道没有理由不指定显式的peg修订版(如果你完全使用显式修订版),它确保你可以总是回滚到那个修订版而不含糊。在我工作的地方,我们总是以你列出的第二种格式指定我们的外部,其中peg是peg和操作修订版。或者,我们指向一个标签。因为标签在提交之后永远不应该改变(并且可能调整外部等),并且在项目存储库路径中如此高的级别不太可能改变,这应该实现与使用更有意义的显式修订相同的目标(格式化。
注意,您可以组合格式2和3,但这不是必需的,例如-r 123 http://example.com/svn/proj@123 proj
。