views:

83

answers:

1

We have a hook in Mercurial that posts the changeset message and a link the changeset to our bug tracking software. We are using separate repos for each branch. When we are done with a branch we would like to push it to an archive repository and delete the original repo so that the Mercurial page of repositories doesn't get cluttered with old repositories. We would also like to reclaim the space that the old repositories take up. I would like to configure Apache so that it redirects to an existing changeset if the changeset cannot be found.

For example, if it can't find http://hg/hg/repo1/rev/c36b1c72fc6e, it would try the following in order:

http://hg/hg/repo1/rev/c36b1c72fc6e  
http://hg/hg/repo2/rev/c36b1c72fc6e  
http://hg/hg/repo3/rev/c36b1c72fc6e  
http://hg/hg/archive/rev/c36b1c72fc6e

until it finds an existing changeset.

I think I should be able to use mod_rewrite rules to do this but it didn't work. This is my latest attempt:

RewriteEngine on  
RewriteLog /var/log/httpd/rewrite.log  
RewriteLogLevel 9  

# Re-map URLs that aren't found

RewriteCond %{REQUEST_URI}   !-U
RewriteRule ^/hg/repo1/(.*)$ http://hg/hg/archive/$1

Here are is the log of an an attempt using the above configuration:

(2) init rewrite engine with requested uri /hg/repo1/rev/c36b1c72fc6e
(3) applying pattern '^/hg/repo1/(.*)$' to uri '/hg/repo1/rev/c36b1c72fc6e'
(2) init rewrite engine with requested uri /hg/repo1/rev/c36b1c72fc6e
(3) applying pattern '^/hg/repo1/(.*)$' to uri '/hg/repo1/rev/c36b1c72fc6e'
(4) RewriteCond: input='/hg/repo1/rev/c36b1c72fc6e' pattern='!-U' => matched
(2) rewrite '/hg/repo1/rev/c36b1c72fc6e' -> 'http://hg/hg/archive/rev/c36b1c72fc6e'
(2) implicitly forcing redirect (rc=302) with http://hg/hg/archive/rev/c36b1c72fc6e
(1) escaping http://hg/hg/archive/rev/c36b1c72fc6e for redirect
(1) redirect to http://hg/hg/archive/rev/c36b1c72fc6e [REDIRECT/302]
(5) RewriteCond URI (-U) check: path=/hg/repo1/rev/c36b1c72fc6e -> status=302
(4) RewriteCond: input='/hg/repo1/rev/c36b1c72fc6e' pattern='!-U' => not-matched
(1) pass through /hg/repo1/rev/c36b1c72fc6e
(2) init rewrite engine with requested uri /repo1/rev/c36b1c72fc6e
(3) applying pattern '^/hg/repo1/(.*)$' to uri '/repo1/rev/c36b1c72fc6e'
(1) pass through /repo1/rev/c36b1c72fc6e

It looks like it modifies the URL properly but it doesn't properly redirect and I don't know why. Any ideas?

I am using hgwebdir to serve my Mercurial repos on Apache.

+1  A: 

It's not the answer you asked for, but if the reason really is just to keep the hgwebdir page from getting overfull, and I know how that goes we have 600+ long done repos in ours, you could consider just putting

[web]
hidden=true

in the done repos .hg/hgrc files. That would keep them out of the list, but keep the URLs to them valid without the slowness and hassle of redirects.

From the hgrc man page:

   hidden

          Whether to hide the repository in the hgwebdir  index.   Default
          is False.
Ry4an
I've used your suggestion to reduce the clutter temporarily. However, it's not just to reduce the clutter. It's also to reduce the space usage by the repositories as well.
Stephen Rasku
Space? Assuming you're paid as a developer the time you spent writing that comment can buy a TiB nowadays. ;)One trick to save on space is to 'hg update null' which eliminates working directories on repos (same as doing a clone -U), and also you can re-hardlink your repos under the covers using the relink extension: http://mercurial.selenic.com/wiki/RelinkExtension for further space savings.
Ry4an
My boss agrees with you about space and the use of my time. I am going to abandon my original quest.
Stephen Rasku