Running Mercurial 2.x Web server on IIS 7.5

By | October 7, 2013

I don’t understand why Mercurial does not have proper instructions on running Mercurial Web server on IIS. All the tutorials that I found on internet was referring to older version of Mercurial (1.x) and some little parts were not relevant to this new release. So here is my couple of hours of trial and errors in one page. I have created my tutorial based on this tutorial and couple of links given in that tutorial which were close but not complete for Mercurial 2.x. If you are hounded by “ImportError: No module named mercurial”, this tutorial may help you fix it.

Environment

Program Name Download File Name Installation Path
Windows Server 2008 R2 Standard Service Pack 1 (64 bit) N/A N/A
Mercurial – 2.7.2 (64 bit) with TortoiseHg 2.9.1 Mercurial 2.7.2 Inno Setup installer – x64 Windows – does not require admin rights C:\Program Files\TortoiseHg
Python – 2.7.5 (64 bit) Python Windows X86-64 MSI Installer (2.7.5) C:\Program Files\Python27

Here are the steps for running Mercurial 2.x Web server

  1. Checkout the Python version used to create Mercurial. Open Windows Explorer, visit any repository or folder, right click on it, go to TortoiseHg > About TortoiseHg. It shows the Python version used to build Mercurial.
  2. Download the same Python version (I think major version is important) and install it. (Checkout the Installation Path in the above table)
  3. If you don’t have IIS 7.5 installed, install it
  4. Open Server Manager. Under “Roles”, click on “Add Role Services”.
  5. If you don’t have “Web Server” > “Application Development” > “CGI” installed, install it.
  6. At this point, your server is ready for CGI execution.
  7. As you may have seen in other tutorial, there is NO Mercurial Python module to install.
  8. In IIS Manager, create a Web application and call it as “hg”. The physical location is E:\inetpub\wwwroot\hg. (Please note that in my environment, Website is located in E drive but Mercurial and Python are installed on C drive)
  9. In IIS Manager, click on “hg” and in the Feature View, you will see “Handler Mappings” option. Double click on it to open.
  10. On the right hand side, under “Actions”, you will see “Add Script Map…”. Click on it and add as per following. Please note that you need to type your own Python installation path. Due to space character in Python path, I have used double quotes.
  11. Under “Request Restrictions…” dialog, keep Verbs to All Verbs, and Access to Script. Click OK to close this dialog.
  12. Click OK to complete adding script map. It may ask you something regarding ISAPI but I forgot what I pressed. Probably I clicked OK/Yes.
  13. Now in IIS Manager, click on server and in Features View, you will get “ISAPI and CGI Restrictions”. Double click on it to open it.
  14. If you don’t see Python here, you may add a new entry and allow that CGI script to run.
  15. Now go to “E:\inetpub\wwwroot\hg” and open Web.config file. (This file is created by IIS Manager when we added Python as CGI). It would have added handler named Python. Please take a close look at the “scriptProcessor” value because the quote character within the value must be replaced with “&quote;”. When I checked this, I had first “&quote;” missing. The final line should look like this. “<add name=”Python” path=”*.cgi” verb=”*” modules=”CgiModule” scriptProcessor=”&quot;C:\Program Files\Python27\python.exe&quot; -u &quot;%s&quot;” resourceType=”Unspecified” />“. You will see your Python installation path in this.
  16. Create a file “test.cgi” in E:\inetpub\wwwroot\hg and write following
    print 'Status: 200 OK'
    print 'Content-Type: text/html'
    print
    print '<html><body><h1>It Works!</h1></body></html>'
    
  17. Now visit http://localhost/hg/test.cgi and it should give you “It Works!” message.
  18. Now create a file “hgweb.cgi” at “E:\inetpub\wwwroot\hg” and copy and paste following content in it.
    # An example hgweb CGI script, edit as necessary
    # See also http://mercurial.selenic.com/wiki/PublishingRepositories
    # Path to repo or hgweb config to serve (see 'hg help hgweb')
    config = "E:\\inetpub\\wwwroot\\hg\\hgweb.config"
    # Uncomment and adjust if Mercurial is not installed system-wide
    # (consult "installed modules" path from 'hg debuginstall'):
    #import sys; sys.path.insert(0, "/path/to/python/lib")
    import sys; sys.path.insert(0, "C:\\Program Files\\TortoiseHg\\library.zip")
    # Uncomment to send python tracebacks to the browser if an error occurs:
    import cgitb; cgitb.enable()
    from mercurial.hgweb import hgweb, wsgicgi
    application = hgweb(config)
    wsgicgi.launch(application)
    
  19. In this file, you need to change the path of “library.zip” as per you installation or you may need to completely omit that statement by commenting it. It depends on your Mercurial installation. If you don’t know the location of library.zip file, you can run “hg debuginstall” command from commandline which will give you the path. You also need to change the value of “config” which points to the hgweb.config file. This file is working for me but if you want to use the same from Mercurial, it can be found at “http://www.selenic.com/hg”. Click on “Browse” on left hand side menu and you will see “hgweb.cgi” file.
  20. In my hgweb.config file, I have following items
    [web]
    templates = C:\Program Files\TortoiseHg\templates
    push_ssl = false
    allow_push = *
    [collections]
    E:\PARENT_DIRECTORY_OF_REPOSITORY\ = E:\PARENT_DIRECTORY_OF_REPOSITORY\
    
  21. In this file, you need to change “templates” value as per your Mercurial installation path and repository locations. This config mentions that ssl is not required for pushing and anyone can push it.
  22. The last thing is, you need to given full control to repository directory to “IUSR” user so that when someone is pushing to the repository using Web interface, they will be able to do it.

Once this basic stuff is working, you can add more to it.

One thought on “Running Mercurial 2.x Web server on IIS 7.5

Leave a Reply

Your email address will not be published. Required fields are marked *