SVN提交后钩子修改外部依赖。

3
我们有一个Subversion设置,该设置相当广泛地使用了svn:externals(一个项目中有多达5个外部引用,虽然大多数在同一存储库中,但其中一个或两个在不同的存储库中,但仍在同一服务器上)。目前,svn:externals属性的设置方式是它们具有被引用项目的完整URL(即“https://[server]:[port]/svn/Repository1/Projects/...”)。
最近,我使用svnsync设置了一个SVN镜像,将我们的存储库备份到一个外部远程设施。我们需要能够从远程站点读取只读检出,这在大多数情况下似乎运行良好,但当尝试提取外部引用时,它仍会引用我们本地的站点服务器。
不确定是否这是最佳解决方案,但我希望在远程位置设置某种后提交挂钩,该后提交挂钩将修改svn:externals的属性,并将此处本地服务器的主机名替换为远程服务器的主机名。此挂钩将在每次由svnsync进行的提交后运行。
理想情况下,我们希望避免修改主存储库中的svn:externals属性以不包括服务器名称。
有人遇到过这个问题吗?最佳方法是什么?
2个回答

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中发布的内容--我得到的是来自主干的最新版本。

更好的处理方式是创建一个发布存储库,将各个项目之间共同的代码构建为某种预编译的工件,并使您的项目依赖于该工件的该版本。这最终与依赖于特定版本的C程序所依赖的libz.so或依赖于版本1.6的Java项目所依赖的org.apache.commons.httpd没有任何区别。

这将消除svn:externals的使用,并简化您的镜像。您可以同时镜像发布存储库和源存储库。

如果您坚持使用svn:external,请不要使用完整的URL,而是使用相对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

我正在标记project1project2。现在,我的svn:external引用了http://vegibank.com/svn/tags/1.2.3/project2/foo
您需要的是以这种方式强制实施svn:externals,并且可以使用预提交钩子来拒绝引用trunkbranches目录但未指定实际修订版本的任何提交。

非常感谢您提供的所有建议!我们实际上不使用标签,但是我们遇到了您描述的与分支相同的问题。我们有一个稍微不太正统的分支结构,在启动期间我们不会将主干合并到生产分支中;相反,我们通过将其复制为“production”来“祝福”主干分支,并将旧的生产分支重命名为备份。这种方法存在许多问题,但我们现在不打算更改此流程,因为我们计划在接下来的6-12个月内迁移到Git,因此做所有工作使我们的SVN设置正确是没有必要的。 - Ruslan
1
如果你要转向Git,最好摆脱svn:externals的依赖。Git没有类似于svn:externals的功能。对我来说,这是Git的一个“特性”,因为svn:externals实际上是有问题的。这个想法很好,但实现起来非常麻烦,所以你需要避免使用它。 - David W.
我们使用.NET,将项目分解为许多单独的类库模块,生成DLL。在我们拥有的大约10个模块中,有3个是实际的项目引用,因为它们几乎总是在网站上工作时需要存在。其余的是“Dependencies”文件夹中的DLL引用。这两个项目引用也是组件,因此Site对它们有外部引用,以便在检出时包含它们(否则无法打开项目)。"Dependencies"文件夹也是一个外部文件夹...所以有点棘手。理想情况下,所有内容都应该是一个解决方案。 - Ruslan
将所有组件的项目引用放在一个文件夹和 SVN 项目下,这是一个相当大的变化,计划稍后实施... - Ruslan
“我一直以为标签不会变,但事实并非如此。”[使用明确的版本号](http://tortoisesvn.net/docs/nightly/TortoiseSVN_en/tsvn-dug-externals.html)。问题解决了。 - cp.engr
显示剩余7条评论

1
你正在使用哪个版本的svn?如果是最新版本,你可以避免在svn:externals中放置主机名阅读redbook,具体来说,使用/开头的外部检出。
强烈建议你摆脱svn:externals的困境......特别是如果链接指向同一仓库...你的分支和标记会更加困难。我看过很多svn实现,而svn:externals通常是一个不好的迹象。
此外,作为一般规则,我认为修改开发人员的本意的后提交钩子是次优的。虽然在这种情况下,你可能会没问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接