Hosting Mercurial On IIS7

For those wondering how to host a mercurial server in a windows corporate environment, it is possible to host mercurial 1.7.2 on IIS7 using CGI, and surprisingly smooth as well. It’s been running flawlessly in a corporate production environment for a while now.

I followed the steps which were posted on Stack Overflow and the steps from Jeremy Skinner’s blog. Be aware that Jeremy Skinner’s steps include hgwebdir.cgi, but this is from an older version of mercurial, so you should be using hgweb.cgi instead.

There are some points that need special consideration:

Local vs Global Configuration

There are two scopes of configuration for mercurial when running it through hgweb. The “global” configuration is controlled by the config file that is fed into hgweb.cgi. I will call this file hgweb.config. This holds all the default settings for any repository that is served through hgweb.cgi. Note that these settings will be different that the global mercurial settings on the server machine. They are only applied when mercurial is running through hgweb.cgi.

The other scope is the per repository configuration. These are controlled by hgrc files that reside within the .hg folder of each repository.

Multiple Repositories

The way hgweb maps repositories to urls is configured within the hgweb.config. Within hgweb.config, you can create a section called [paths] that does the mapping. There also needs to be a [web] section containing the baseurl for the server (see hgweb documentation for more information about this). It was a bit tricky to get the paths working properly as there seems to be conflicting information about this on various sources. What worked for me was this:

[web]
baseurl = http://<server>/hg/
style = monoblue

[paths]
/ = c:\hg\**

What this does is maps all repositories under c:\hg to http://server/hg/repo_name. Quite neat.

Authentication

If you want push/pull authentication around mercurial when running it under IIS, then you need to enable Basic Authentication and Windows Authentication for the mercurial application that you created when following the steps earlier.

Another important point is that the “Impersonate” under CGI settings for the application that you created should be set to False as you want Mercurial itself to handle authorization for push or pull, you don’t want the actual cgi application running as that user.

Within each repository, you can create a list of users who allowed to push under the [web] item using allow_push=. See mercurial documentation for more info about this.

Maximum bundle size

You might need to change the maximum post size on IIS when pushing large (e.g. initial commit for a large codebase) bundles to the server. Otherwise IIS gives a strange 404 not found error.

The default maximum size is 30mb, and you need to increase that by editing the web.config file for the mercurial application, in the section system.webServer.

<security>
 <requestfiltering>
  <requestlimits maxAllowedContentLength="2000000000" />
 </requestFiltering>
</security>

Notification

It is also possible set mercurial to notify users about new pushes to repositories. Everytime something is pushed to the central server it can send out a mail with a summary of the commits within the bundle.

To set this up, you need to enable the notify extension in hgweb.config and configure smtp, as well as hooks.

These are the elements in the hgweb.config :

[extensions]
notify = 
[smtp]
host = smtp-hostname
[email]
from = mercurial@server.com
[notify]
#multiple sources can be specified as a whitespace separated list
sources = serve push pull bundle
strip = 2
config = 
test = False

After this, within each repository, you need to edit the hgrc file for that repository and add:

[reposubs]
# key is glob pattern, value is comma-separated list of subscriber emails
* = user1@address.com, user2@address.com

You can look at the Notify Extension for Mercurial documentation for more information.

SSL

It is possible to setup SSL rather trivially, using standard IIS7 procedure, which I won’t go into detail. If you are serving both HTTP and HTTPS, within your hgweb.config, you can set

[web]
push_ssl = True

to enforce push only over SSL.

Advertisements