我有一个旧的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,然后根据url将apacheredirect,所以:
http://myserver.com/svn/trunk
redirect到
http://myserver.com/svn/repo/trunk
透明。 我可以把它redirect到基于IP的URL,但是当我尝试使用域名本身进行redirect时,它给了我禁止的消息或“无法打开请求的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>
如何解决这个问题的想法?
简短的回答:使用您的RewriteRule上的PT标志。
首先是一个小小的阿帕奇故事。 当Apache收到一个请求时,它会经过一个将请求映射到本地存储的过程。 在那之后,Apache实际上有两个关于你所要求的数据。 请求url和文件path。 所以/svn/blah的请求被翻译成/var/www/vhosts/myserver.com/html/svn/blah并且这个path被单独存储。 mod_rewrite允许你调整这个行为来路由你想要的url。
现在,你在那里的两个RewriteRules隐含地做了不同的事情。
你在那里的第一个是重写。 它需要像/svn/blah这样的URL,而不是使用上面的行为,它将它映射为如果实际上请求/svn/myrepo/blah ,那么生成的文件path将是/var/www/vhosts/myserver.com/html/svn/myrepo/blah 。 然而,这里的关键点, 它不会修改所请求的url 。 请求url仍然是/svn/blah ,apache刚刚认为这个文件是在.../svn/myrepo/blah而不是在.../svn/blah 。
为什么你要问这个问题? 因为subversion模块不使用文件path。 它看起来在请求的url。 所以Apache和mod_rewrite只是浪费时间做这一切,因为mod_dav_svn只是忽略它。 你需要的是mod_rewrite来改变请求的URL。 这就是PT所做的。 它修改请求的URL和文件path,所以稍后当它到达mod_dav_svn,它会看到更改的url。
第二个是redirect。 由于replace以http://开头,并且apache没有一个名为192.168.0.1的虚拟主机,所以它假设你实际上是想把R放到你的标志中,因为它不能把它转换成文件path。 这是发送一个“嘿,这是在这里”的消息给颠覆客户端,这是另一个请求。
现在,说了这么多,除非你强迫mod_rewrite跳过其他仓库的URL,否则你永远不会有多于一个仓库。 /svn/bignewproject/blah mod_rewrite都会将/svn/bignewproject/blah更改为/svn/myrepo/bignewproject/blah 。 您可以在RewriteRule之前添加一条规则,例如:
RewriteRule ^/svn/(myrepo|myotherrepo|coolproject|stuff|etc)/ - [S=1]
这将导致它跳过下一个规则。 但是,你将会从这里手动更新它。 你也许可以用一些RewriteCond的魔法来自动化一些东西,但这可能会很棘手。 我并不是很熟悉,所以别人也不得不在那里帮助你。
如果这只被一小部分人使用,那么你可能更好地跳过这个重写的东西,只是更新每个人的工作副本。 svn switch --relocate是专门用于回购的情况下,你只是想更新你的工作副本而不再检出它。 我知道有些情况下,这根本不可行。
不幸的是,Subversion使用的不仅仅是简单的GET和POST命令,所以我认为最好的redirect方式是使用Apache的mod_proxy来反向代理请求。 我不确定有更好的方法
本页描述的Apache / Subversion反向代理http://silmor.de/49