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

Switching to a DVCS in a corporate environment

After using Mercurial as a source control system as a replacement to SVN, I will just say that, yes it is that good as the hype would like you to believe and it contributes greatly to any development process in a company. I will talk more in another article why we picked Mercurial over the other DVCS alternatives. In this article I will focus more on the general DVCS workflows and benefits.

Although DVCS (Distributed version control system) conceptually has been around for a while, lately there have been a lot of hype around it with the explosion of GitHub and similar sites like BitBucket. In my corporate environment, we’ve been using SVN for a while, even though we did run into issues once in a while, it was working at a more or less acceptable level and we were rather content with it. This was of course until I happened to listen to a seminar on Git and became very curious to learn more about it. After having dug deeper into DVCS I can say that the reason why I have been content with SVN was that I didn’t know what a source control system could be capable of.

The DVCS concept was a bit difficult to grab at first, but as I dug deeper into it, I can easily say that it was like a paradigm shift of sorts and would be difficult to “unlearn” it. There are already numerous very good articles and tutorials about major DVCS systems on the web so I won’t go into any detail there about how they conceptually work. What I want to talk about more is how a DVCS could fit in a corporate environment.

I’ve read comments here and there that source control systems like Mercurial and Git are more appropriate for open source development where contributors to a project can be distributed across the globe and has usually a more relaxed pace of development. I actually see DVCS as being able to cope with any kind of development workflow, while a centralized VCS forces you to work within certain boundaries.

We did the switch to Mercurial basically by doing a fresh start, and creating the initial branches that were still active on the old SVN repository. We didn’t believe the SVN history was particularly valuable, and if it would be useful at some point we could always look it up. This also gave a good opportunity to trim the fat from the source base.

I see the biggest value in a DVCS with the way it manages changes and the ease of use in merging different branches together. It is so easy to create and merge branches that we ended up creating a branch for every major or minor feature we were going to add. This makes it very flexible with regards to when you want to merge your features and release them. It simply feels that SVN did not offer this kind of power, even though it supports branching and merging, it feels very cumbersome and heavy in comparison.

We found a good development workflow with having a main “integration” branch, which is where automated tests are run and automated builds are made. All feature branches are created out from that branch and later on merged back into that branch when they are completed. Before each release we also create a release-* branch. This is the branch that will be QA’d and released. All fixes and improvements are made against the release branch, and the release branch is merged back periodically into the default branch. The automated tests and builds are also made against the release branch. There is a central repository which all developers work against and where the automated build system is run against. I believe this workflow is flexible enough that it’s possible to run multiple threads of development (i.e. feature branches) simultaneously without affecting the work of other features.

Most of these workflows apply to any kind of DVCS system, be it Mercurial, Git or Bazaar, which are more or less all interchangable in my opinion with some differences in implementation details.