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/