我们有一个Subversion设置,可以相当广泛地使用svn:externals(在一个项目中有超过5个外部引用,虽然大多数都在同一个存储库中,但是一个或两个存在于不同的存储库中但仍在同一个服务器上)。目前,svn:externals属性的设置方式是它们具有引用项目的完整URL(即“https:// [server]:[port] / svn / Repository1 / Projects / ...)
最近,我使用svnsync建立了一个SVN镜像,它将我们的存储库备份到外部的场外设施。我们需要能够从远程站点上的那些镜像存储库执行只读检出,这似乎在大多数情况下工作正常,除非它试图拉动外部时,它仍然引用我们的本地现场服务器。
不确定这是不是最好的方法,但我想在远程位置设置某种后提交挂钩,这将修改svn:externals的属性并替换我们本地的主机名服务器在这里使用远程服务器的主机名。这个钩子将在svnsync进行每次提交后运行。
理想情况下,我们希望避免在主存储库中修改我们的svn:externals属性,使其不包含服务器名称。
之前有没有人遇到过这个问题?最好的方法是什么?
答案 0 :(得分:4)
您必须了解svn:externals
是文件的属性,修改它们需要提交。如果您有镜像,并且修改了svn:external
,那么您将创建一个新的远程版本并破坏镜像。修订将不再排列。
虽然当时看起来似乎是一个很好的想法,svn:externals
在项目中可能非常糟糕。想象一下像这样的项目:
http://vegibank.com/svn/trunk/project1
我在此目录中有一个svn:external
$ svn pset svn:external "^/trunk/project2/foo foo" .
我这样做是因为foo
目录是多个项目的共享文件集。
现在,我为project1创建一个标记:
$ svn cp http://vegibank.com/svn/trunk/project1 http://vegibank.com/svn/tags/1.2.3
看起来不错 - 除了project1/foo
目录没有标记。 它与project2/foo
的主干相关联。
我对标签的假设是标签永远不会改变,但事实并非如此。在主干上的project2/foo
上仍在进行工作,这会更改我的标记所代表的内容。如果我在版本1.2.3中有一个错误,并且我决定签出我的标签以查看可能存在的问题,我不一定得到我在project1/foo
中发布的内容 - 我从中继线。
更好的方法是创建一个发布存储库,将各种项目之间通用的代码构建为某种预编译工件,并让您的项目依赖于该工件的该版本。它最终与依赖于特定版本libz.so
的C程序或依赖于org.apache.commons.httpd
版本1.6的Java项目没有区别。
这将消除svn:externals
的使用并简化您的镜像。您可以镜像发布存储库以及源存储库。
如果您坚持使用svn:external
,请不要使用完整的网址。相反,请使用相对URL。
例如,如果你已经设置了`svn:external而不是这个:
$ svn pset svn:external "^/trunk/project2/foo foo" .
这样做:
$ svn pset svn:external "../project2/foo foo" . #property on ^/trunk/project1
现在,如果我创建一个这样的标签:
$ svn cp http://vegibank.com/svn/trunk http://vegibank.com/svn/tags/1.2.3
我正在标记project1
和project2
。现在,我的svn:external
引用http://vegibank.com/svn/tags/1.2.3/project2/foo
。
您需要的是以这种方式强制执行svn:externals的方法,并且您可以使用预提交挂钩来拒绝任何具有引用svn:external
或{trunk
的{{1}}集的提交{1}}目录,没有指定实际修订版。
答案 1 :(得分:1)
你在运行什么版本的svn?如果你是最新的,你可以避免将主机名放在svn:externals
read the redbook专门检查以/
你应该强烈考虑退出svn:externals
泥潭...特别是如果链接指向相同的回购...你的分支和标记更难。我见过很多svn实现和svn:externals通常都是难闻的气味。
另外,作为一般规则,我认为使用后提交挂钩改变开发人员的意图是不太理想的。虽然在这种情况下你可能会没事的。