我有一个旧的 Subversion 存储库,它被设置为计算机上的唯一存储库。我们像这样访问 URL:
http://myserver.com/svn/trunk/...
http://myserver.com/svn/branches/...
我们正在转移到一个新服务器,该服务器在 apache2 下的 dav-svn 安装下设置了几个存储库,因此默认情况下我们像这样访问它们:
http://myserver.com/svn/repo/trunk/
http://myserver.com/svn/repo/branches/
or
http://192.168.0.1/svn/repo/trunk/
http://192.168.0.1/svn/repo/branches/
我需要将旧的 repo 移动到新机器而不更改 URL,因此我想设置一个 repo,然后让 apache 根据 url 重定向它,因此:
http://myserver.com/svn/trunk
重定向至
http://myserver.com/svn/repo/trunk
透明地。我可以让它重定向到基于 IP 的 URL,但当我尝试让它使用域名本身进行重定向时,它会给我禁止的消息或“无法打开请求的 SVN 文件系统”:
<VirtualHost *:80>
ServerName myserver.com
ServerAlias www.myserver.com
DocumentRoot /var/www/vhosts/myserver.com/html
CustomLog /var/www/vhosts/myserver.com/logs/access_log combined
ErrorLog /var/www/vhosts/myserver.com/logs/error_log
RewriteEngine On
RewriteRule ^/svn(.*)$ /svn/myrepo$1 [L,QSA]
# THE FOLLOWING WORKS, BUT IS NOT TRANSPARENT
# RewriteRule ^/svn(.*)$ http://192.168.0.1/svn/myrepo$1 [L,QSA]
<Directory /var/www/vhosts/myserver.com/html>
AllowOverride All
</Directory>
</VirtualHost>
以及 subversion.conf 文件:
<Location /svn>
DAV svn
SVNParentPath /var/svn/repository
AuthType Basic
AuthName "Subversion Repository"
AuthUserFile /var/svn/repository/.htpasswd
Require valid-user
</Location>
关于如何解决问题的想法?
答案1
简短回答:使用PT
RewriteRule 上的标志。
首先,介绍一下 Apache 的背景。当 Apache 收到请求时,它会将该请求映射到本地存储。之后,Apache 实际上会获得有关您请求的两部分数据。请求 URL 和文件路径。因此,请求/svn/blah
被转换为/var/www/vhosts/myserver.com/html/svn/blah
,并且该路径单独存储。mod_rewrite 允许您调整此行为以将 URL 路由到您想要的位置。
现在,那里的两个 RewriteRule 隐式地执行着不同的事情。
第一个是重写。它接受一个类似 的 URL
/svn/blah
,而不是使用上面的行为,而是将其映射为实际请求/svn/myrepo/blah
,因此生成的文件路径将是/var/www/vhosts/myserver.com/html/svn/myrepo/blah
。但是,关键在于,它不会修改请求的 URL。请求 URL 仍然是/svn/blah
,apache 现在认为文件位于.../svn/myrepo/blah
而不是.../svn/blah
。你可能会问,这有什么关系?因为 subversion 模块不使用文件路径。它查看请求 URL。因此,apache 和 mod_rewrite 只是浪费时间做这些事情,因为 mod_dav_svn 会忽略它。你需要的是让 mod_rewrite 更改请求 URL。这就是它的作用
PT
。它修改请求 URL 和文件路径,因此稍后当它到达 mod_dav_svn 时,它将看到更改后的 URL。第二个是重定向。由于替换以 开头
http://
,而 apache 没有名为 的虚拟主机192.168.0.1
,因此它假定您实际上想R
在标志中放置一个,因为它无法将其转换为文件路径。这会向 subversion 客户端发送回“嘿,它在这里”消息,并且它会发出另一个请求。
现在,说了这么多,无论如何,除非你采取一些措施强制 mod_rewrite 跳过其他存储库的 URL,否则你永远不会通过此设置拥有多个存储库。mod_rewrite 每次都会愉快地为你更改/svn/bignewproject/blah
为/svn/myrepo/bignewproject/blah
。你可以在已有的 RewriteRule 之前添加一条规则,例如:
RewriteRule ^/svn/(myrepo|myotherrepo|coolproject|stuff|etc)/ - [S=1]
这将导致它跳过下一条规则。但是,从现在开始,您将手动更新它。您可能能够使用一些 RewriteCond 魔法自动完成某些操作,但这可能很棘手。我对此不太熟悉,所以其他人必须帮助您。
如果只有一小部分人使用,那么你最好完全跳过重写部分,只更新每个人的工作副本。 svn switch --relocate
专门用于存储库被移动并且你只想更新工作副本而不再次签出的情况。我知道有些情况下这根本不可行。
答案2
不幸的是,Subversion 使用的不仅仅是简单的 GET 和 POST 命令,所以我认为重定向的最佳方法是使用 Apache 的 mod_proxy 来反向代理请求。我不确定有没有更好的方法
本页描述的 Apache / Subversion 反向代理http://silmor.de/49