4

I have an old subversion repository that was set up as the only repo on a machine. We accessed the URLs like this:

http://myserver.com/svn/trunk/...
http://myserver.com/svn/branches/...

We're moving to a new server where we have several repositories set up under a dav-svn installation under apache2, so by default we access them like this:

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/

I need to move the old repo to the new machine without changing the URLs, so I want to set up a repo and then have apache redirect it depending on the url, so:

http://myserver.com/svn/trunk

redirects to

http://myserver.com/svn/repo/trunk

transparently. I can get it to redirect to the IP-based URL, but when I try to get it to redirect using the domain name itself, it gives me forbidden messages or "Could not open the requested SVN filesystem":

<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>

And the subversion.conf file:

<Location /svn>
  DAV svn
  SVNParentPath /var/svn/repository

  AuthType Basic
  AuthName "Subversion Repository"
  AuthUserFile /var/svn/repository/.htpasswd
  Require valid-user
</Location>

Ideas on how to solve the problem?

1
  • "but when I try to get it to redirect using the domain name itself, it seems to cause problems" Can you clarify what the problem is?
    – Swoogan
    Oct 30, 2009 at 16:48

2 Answers 2

3

Short answer: Use the PT flag on your RewriteRule.

First, a little Apache backstory. When Apache receives a request, it goes though a process of mapping that request to the local storage. After that, Apache actually has two pieces of data on what you requested. The request url, and the file path. So a request for /svn/blah is translated into /var/www/vhosts/myserver.com/html/svn/blah and that path is stored separately. mod_rewrite lets you tweak this behavior to route urls where you want.

Now, the two RewriteRules you have there are implicitly doing different things.

  • The first one you have there is a rewrite. It takes a url like /svn/blah and instead of using the behavior above, it maps it as if you actually requested /svn/myrepo/blah, so the resulting filepath would be /var/www/vhosts/myserver.com/html/svn/myrepo/blah. However, and here's the sticking point, it does not modify the requested url. The request url is still /svn/blah, apache just now thinks that file is to be found at .../svn/myrepo/blah rather than .../svn/blah.

    Why does this matter you ask? Because the subversion module doesn't use the filepath. It looks at the request url. So apache and mod_rewrite just wasted time doing all that, because mod_dav_svn just ignores it. What you need is for mod_rewrite to change the request url. And that's what PT does. It modifies both the request url and the file path, so later when it gets to mod_dav_svn, it will see the changed url.

  • The second one is a redirect. Since the substitution starts with http:// and apache doesn't have a virtualhost named 192.168.0.1, it assumes you actually meant to put an R in your flags, since it can't translate that into a filepath. That is sending back a "Hey, it's over here" message to the subversion client, and it's making another request for it.

Now, having said all that, you're never going to have more than one repository on there anyway with this setup unless you do something to force mod_rewrite to skip the urls of the other repositories. mod_rewrite will cheerfully change /svn/bignewproject/blah into /svn/myrepo/bignewproject/blah for you every time. You could add a rule before the RewriteRule you have such as:

RewriteRule ^/svn/(myrepo|myotherrepo|coolproject|stuff|etc)/ - [S=1]

That will cause it to skip the next rule. However, you're going to be updating it by hand from here on out. You might be able to pull off something automated with some RewriteCond magic, but it'll probably be tricky. I'm not really familiar with that, so someone else would have to help you out there.

If this is only used by a small group of people, then you might be better off skipping this rewriting stuff entirely and just update everyone's working copies. svn switch --relocate is meant specifically for situations where the repos is moved and you just want to update your working copy without checking it out again. I understand there are situations where this simply isn't feasible though.

0

Subversion uses more than just simple GET and POST commands unfortunately, so I think maybe the best way to redirect is to use Apache's mod_proxy to reverse proxy the requests. I'm not sure there's a better way

Apache / Subversion reverse proxy described on this page http://silmor.de/49

2
  • That would work if he were still running a second server. It looks like he wants to move the repository to the new server and just not change the URL. Oct 30, 2009 at 18:34
  • 2
    You can proxy to the local machine. Oct 30, 2009 at 23:31

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .