26 April 2011
Setting up a Mercurial Repository under IIS

Setting up Mercurial to serve repositories using IIS has been on my to do list for months. I had a quick go at it late last year, but was thwarted by confusing solutions which quite frankly, just didn't work for me.

Many walkthroughs mention using a file named hgwebdir.cgi, but as of Mercurial 1.6, this no longer exists. Some walkthroughs mention copying the contents of a file into the website, or placing .dll files in there too. Nothing like this worked for me, and it seemed ridiculously complex.

Today, I've made a concerted effort to get things working, and guess what? It's REALLY EASY!

Before you start though, you should consider whether you really want to do this. Take a look at BitBucket which is a hosting site for Mercurial. It's ran by Atlassian and is completely free for up to five developers. If hosting your source code externally is not politically viable, you want more control over your repos, or you don't want to pay for BitBucket when scaling up beyond five users, then by all means follow the below instructions.

OK, what do you need?

And that's it.

Note that the version numbers of Python must match. I dare say that future versions of the Mercurial Python package may specify version 2.7 of Python… if that's the case, just get Python 2.7.x instead.

(UPDATE: On a 64-bit server, you can use the 64-bit version of Python and the 64-bit Python package without any issues. I've now repeated this exercise using Python 2.7.3 and Mercurial 2.3 Python 2.7 package.)

So, the steps to carry out on the server were pretty simple:

1. Install Python

2. Install the Mercurial Python package

3. Create a new web application in IIS.

4. From the Mercurial source release, copy the file hgweb.cgi to your web application, and rename it You don't have to rename it, but I just think the extension .py accurately reflects that this is a Python script, and as it's going to be the default document of the website, "index" seems a good name for it.

5. Create a subfolder called Repositories underneath your web application. This will be used to host your repositories.

6. Create a new file called hgweb.config in your web application's folder. It's contents should be something like this:

C:\PATH_TO_YOUR_WEB_APP\Repositories = C:\PATH_TO_YOUR_WEB_APP\Repositories

7. Edit so that the line which starts config = "some path" contains the full path to your hgweb.config file, i.e.:

config = "C:\PATH_TO_YOUR_WEB_APP\hgweb.config"

8. Configure IIS as follows:

You'll need to set the default document for your application to

You'll need to enable Basic Authentication for the web application and disable all other forms of authentication. Set the default domain to be the domain of your server, so that users don't need to qualify their usernames with the domain when logging on.

In IIS7 you'll need to use Add Script Map… (under Hander Mappings) to map *.py requests to C:\Python26\python.exe %s %s.

In IIS6, this is available by clicking "Configuration" on the Directory tab then adding a mapping so that "C:\Python26\python.exe" %s %s (note the quotes around the executable this time) is used to handle the extension py. Also in IIS6, you'll need to ensure that you have a web service extension for Python which is allowed and has the filename c:\Python26\python.exe %s %s.

9. Create a test repository in your Repositories folder.

10. Configure the test repository by editing its .hg\hgrc file to include:

allow_push = * # alternatively, a comma separated list of users with push privileges
allow_archive = zip # this allows users to download a .zip archive of the source code
push_ssl = false # this allows pushing over HTTP. You're advised to setup SSL though, and then remove this line

11. On your client machine, test out the new repo by executing the following (the program will prompt you for your credentials which is just your domain account):

hg clone http://YOUR_SERVER/YOUR_APP_NAME/ your_local_folder

12. Make some changes, check them in and push back to the repository.

13. Browse the repository in a web browser at http://YOUR_SERVER/YOUR_APP_NAME/

Exercises for the interested reader:

1. Setup URL rewriting so that the "" part of your path is invisible. (UPDATE: my post Using URL Rewrite in IIS7 to have all Requests Handled by a Script shows you how.)

2. Add a self-signed SSL certificate to your server, and get Mercurial to work with this (hint: Google for the hostfingerprints directive of Mercurial.ini).

3. Enable public read-only access to your repo, but require a login to push changes (I've not figured this out myself yet, so please comment if you work it out!)