Serving Mercurial using Apache on Ubuntu

If you have even the slightest interest in revision control systems chances are you have been keeping an eye on the development of distributed systems. The dust has not settled yet but I think that Sun’s decision to go with Mercurial for OpenSolaris and OpenJDK makes that particular program a fairly safe choice. Some history on Sun’s choice here. A good and fairly recent comparison here. Don’t miss out on Linus Torvald’s recommendations to the KDE people.

I have only very briefly tried out distributed revision control systems. The point that stands out for me is the powerful idea of the dual push-pull model. First there is the pull model; sandboxed development where one or more developers collaborate, pulling sources from each other. Each user is responsible for pulling changes from others and the model requires close collaboration and communication. This is the development model usually described and advertised for distributed revision control systems.

The second development model is the push model where changes are pushed to one or more central, master repositories, much like you would check in sources into Subversion or any other centralized version control system. For commercial projects, you will probably want to support this second mode, setting up master repositories that represents the stable state of your project. Sooner or later you will need HTTP read access to the masters. If nothing else, how else will your Hudson build server access the stable branch?

I really like Mercurial’s serve command that starts serving your repository over HTTP. Just type hg serve and others can access your repository for pulling over the net, just like that. This is not what you want for your master repositories though. For those you will want a permanent solution and that means using CGI scripts.

The Mercurial book contains a chapter about serving HTTP using CGI that is a good starting point. There are also a few posts on the net that I also found useful, here and here. The instructions below have been tested on a blank Ubuntu 7.10 (Jeos) box. I have chosen Apache as the web server.

I choose to place the root of the Mercurial repositories at /srv/hg/. See the FHS for more information on that choice. Serving HTTP access is made using a CGI script, shipped with Merurial. I prefer to place the script next to the repositories in a directory called /srv/hg/cgi-bin/.


  # mkdir /srv/hg
  # mkdir /srv/hg/cgi-bin

Below, I’ve chosen to copy the hgwebdir.cgi script which enables access to multiple repositories using the same root.


  # cp /usr/share/doc/mercurial/examples/hgwebdir.cgi /srv/hg/cgi-bin/
  # chmod a+x /srv/hg/cgi-bin/hgwebdir.cgi

Create a file /srv/hg/cgi-bin/hgweb.config that contains the following two lines:


  [collections]
  /srv/hg/ = /srv/hg/

And that’s it as far as Mercurial goes. Just remember that it is Apache that will run the mercurial commands through the CGI scripts. It means that you will need to give read access to the world for the repositories


  # chmod a+rX /srv/hg/your repo(s)

All that’s left to do is setting up a web server to serve the Mercurial CGI script above. There are several servers to choose from. I’ve chosen to use Apache:


  # apt-get install apache2

Rather than edit the default site, I find it cleaner to setup a separate, new Merurial site. Create a new file /etc/apache2/sites-available/hg and add the following lines:


  NameVirtualHost *
  <VirtualHost *>
    ServerAdmin webmaster@localhost

    DocumentRoot /srv/hg/cgi-bin/

    <Directory "/srv/hg/cgi-bin/">
      SetHandler cgi-script
      AllowOverride None
      Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
      Order allow,deny
      Allow from all
    </Directory>

    ErrorLog /var/log/apache2/hg.log
  </VirtualHost>

Disable the default site, enable our new Mercurial site and reload the Apache server.


  # a2dissite default
  # a2ensite hg
  # /etc/init.d/apache2 reload

That’s it. You should now be able to see all your repositories if you point your browser to http://yourhost/hgwebdir.cgi/

16 Responses to “Serving Mercurial using Apache on Ubuntu”

  1. cg Says:

    Hmm.. doesn’t quite work for me … are you sure thats the right web browser address to go to?

  2. cg Says:

    Never mind. Got it working :-) Had the directory path wrong and some of the permissions on the directories as well …

  3. Martin Altenstedt Says:

    Glad you got it working, cg. If I remember correctly, I ran the entire setup as described above on a fresh install but if you found any errors above, please let me know and I’ll correct them.

  4. Marco Massenzio Says:

    I get the following error:

    : ‘hgweb’ object is not callable
    args = (“‘hgweb’ object is not callable”,)
    message = “‘hgweb’ object is not callable”

    (BTW – this is the same error I got following the Mercurial’s Definitive Guide).
    I am guessing Python is running, as the ‘colourful’ error page shows on the heading:

    Python 2.5.2: /usr/bin/python
    Mon May 25 13:53:19 2009

    Any ideas / suggestions?

  5. Marco Massenzio Says:

    There was HTML escaping… in the error message, I got:

    <type ‘exceptions.TypeError’>

  6. Martin Altenstedt Says:

    So did you get it working, Marco? If not, are you running a Debian system?

  7. yrahan Says:

    Thanks a lot man :)

  8. george Says:

    The easiest setup i found so far!!

    Thanks man :D

  9. Sergey Says:

    Thanks a lot!!! Just one thing /srv/hg = /srv/hg you should finish each with / like /srv/hg/ = /srv/hg/ because mine didn’t work until I made it.
    Thanks

  10. Martin Altenstedt Says:

    Thanks Sergey, I just made the change you suggested.

  11. steve Says:

    Thank you, the instructions are very clear! However, i have what I am sure is a minor problem.

    I’m on the latest Ubuntu. I followed everything carefully but when i navigate to http://localhost i get a 403 Forbidden error.

    there’s only two chmods so i can’t imaginve where i went wrong.

  12. Martin Altenstedt Says:

    Steve, I’ll bring up a fresh Ubuntu and have a look as soon as possible.

  13. M@ Says:

    Steve, what about using http://localhost/hgwebdir.cgi as per the instructions?

  14. Martin Altenstedt Says:

    Well, time has obviously not been permitting but I’ll give it a shot tonight. Follow me on twitter if you want updates. http://twitter.com/maltenstedt

  15. Martin Altenstedt Says:

    Steve, I just brought up a fresh Ubuntu 9.10 (Jeos) and followed the instructions above to the letter and it works for me. Perhaps you have a more complex Apache setup than the one I describe?

  16. LR Says:

    Thank you for this nice guide. Made life alot easier for a linux noob like myself. :)

Leave a Reply