There are two main ways to access a Mercurial repository over the network: HTTP and SSH. Managing private repositories over SSH is damn convenient – if I’m working on even a very small toy program and it’s time to go home, the most convenient thing to do is to turn it into a Mercurial repository and “push” it onto any server that I can SSH into from both home and work.

If you want to share your work with others, giving the world read-only access to a Mercurial repository over HTTP is only a little harder. This is how we now offer most of our open source software, via hg.opensource.lshift.net. You can “pull” your own copy of any of the repositories there, make changes of your own, and publish an updated repository with your changes – and if we like what you’ve done you can invite us to “pull” your changes into our repository, thanks to the wonder of distributed version control

This provides everything that a lot of open source projects need without any further work. However, it was a poor fit for our needs. We want a canonical central repository that is the only thing you need to pull from to get up to date. We need lots of people to have access to that repository. And we need all those people to be properly authenticated.

Options for doing this over HTTP are not attractive, simply because there’s no particularly attractive solution for HTTP authentication. We don’t want to ask people to type in a password every time they pull or push, and we don’t want the hassle of X.509 certificates – which would still leave us with the choice of leaving the private keys unencrypted or re-typing a password multiple times.

SSH is much more attractive here because of the existence of ssh-agent, which stores your credentials in memory when you log in, but destroys them on logout or power down. However, done in the most straightforward way this would give all developers total control over our most precious resource – our version control archives – which to my eyes represented a terrible accident waiting to happen. Maintaining the large and ever-growing list of authorized keys would also become painful quickly.

mercurial-server started life as a script called “hg-ssh” which ships with Mercurial. hg-ssh is a special restricted shell designed to be invoked via SSH. You add an entry to your ~/.ssh/authorized-keys file with a key you want to give access to and a prefix redirecting all requests to hg-ssh. The command line you give hg-ssh then controls what access that key has. This is a good, secure way to give lots of developers read/write access to your repositories, but maintaining the authorized-keys file becomes even more painful than before.

So I wrote a set of tools called “hg-admin-tools” which built you an authorized-keys file from a specification. The nice thing about this is that you put the specification into a Mercurial repository, and set up a hook to rebuild the authorized-keys file every time it changes. This tool formed the heart of our Mercurial adoption in the office.

Over time, it grew features, and changed its name along the way. I took inspiration from an extension called “access.py” to add fine-grained access control, and extended the way we build authorized-keys to look at files in /etc as well as in the repository, to give admins a way to break in to repositories they’ve become “locked out” of – which also works to get started when the initial state of the repository is to admit no-one.

In the last couple of days, I’ve smoothed off a number of rough edges, and made one big improvement: finally got working something I’ve wanted for a long time – mercurial-server is finally available as a Debian package, in a form that lintian approves of. This hopefully paves the way for getting the package included in Debian and Ubuntu themselves, making creation of a shared development hub easy for anyone with root access to a Debian/Ubuntu server.

If the documentation describe something that’s useful to you, give it a go and let me know how you get on; several problems that bugged early adopters should now be fixed. And if you are able to help get the package into Debian Sid or Ubuntu Lucid Lynx, please do get in touch and help me shepherd it along – many thanks!

Update: Steve Kemp, who I have known for many years, has offered to sponsor the package – many thanks Steve!