In part 1 I covered how to install Python, Mercurial and mod_wsgi. In this article I’ll explain how to publish your repositories.
Configure Apache + mod_wsgi
Load up your apache httpd.conf file into your favourite editor and add the following lines:
LoadModule wsgi_module modules/mod_wsgi.so AddHandler wsgi-script .wsgi WSGIPythonHome /opt/python2.7.2
That last line ensures that mod_wsgi knows which Python to invoke.
On my system I’m using named virtual hosts, this is what my Mercurial’s site virtual host configuration looks like:
<VirtualHost 172.16.3.21:80> ServerName mercurial ServerAlias hg.mydomain.com ServerAdmin root@localhost DocumentRoot /sites/mercurial/htdocs WSGIScriptAlias / /sites/mercurial/htdocs/cgi-bin/hgweb.wsgi </VirtualHost>
Under your document root create a folder called cgi-bin and create a file in there called hgweb.wsgi.
To verify that mod_wsgi is working I used the trouble-shooting script found on the “Installation Issues” section of the mod_wsgi site. So drop that code into the newly created hgweb.wsgi file and save it:
import sys
def application(environ, start_response):
status = '200 OK'
output = 'Hello World!'
response_headers = [('Content-type', 'text/plain'),
('Content-Length', str(len(output)))]
start_response(status, response_headers)
print >> sys.stderr, 'sys.prefix = %s' % repr(sys.prefix)
print >> sys.stderr, 'sys.path = %s' % repr(sys.path)
return [output]
When you browse to your site you should see: Hello World! in my browser. So far so good.
Mercurial Configuration
If the above works then replace the contents of hgweb.wsgi with the following:
# An example WSGI for use with mod_wsgi, edit as necessary # See http://mercurial.selenic.com/wiki/modwsgi for more information # Path to repo or hgweb config to serve (see 'hg help hgweb') config = "/sites/mercurial/htdocs/cgi-bin/hgweb.config" # Uncomment and adjust if Mercurial is not installed system-wide: #import sys; sys.path.insert(0, "/path/to/python/lib") # Uncomment to send python tracebacks to the browser if an error occurs: #import cgitb; cgitb.enable() # enable demandloading to reduce startup time from mercurial import demandimport; demandimport.enable() from mercurial.hgweb import hgweb application = hgweb(config)
You can find this file in the Mercurial source in the contrib folder. If you’ve followed my instructions to the word
Next create a new file in the cgi-bin folder called hgweb.config and add the following:
[paths] / = /sites/mercurial/htdocs/repos/** [web] allow_push = * push_ssl = false
Create a folder for your repositories under your document root and initialise a new repository:
mkdir repos cd repos hg init testrepo
You should now be able open the Mercurial repository browser by opening: http://hg.mydomain.net
You also need to ensure that your web server’s user can read and write to your repositories. On a default apache install on CentOS this should look like:
chown -R apache:apache /sites/mercurial/htdocs/repos chmod -R g+rw /sites/mercurial/htdocs/repos chmod g+x /sites/mercurial/htdocs/repos
You also need to make each repository folder and it’s .hg folder executable as well:
chmod g+x /sites/mercurial/htdocs/repos/testrepo chmod g+x /sites/mercurial/htdocs/repos/testrepo/.hg
For more info see: Mercurial – 8. Troubleshooting
To test your Mercurial server go to a different machine and do:
E:\>md hg_test
E:\>cd hg_test
E:\hg_test>hg clone http://hg.zygonia.net/testrepo
destination directory: testrepo
no changes found
updating to branch default
resolving manifests
0 files updated, 0 files merged, 0 files removed, 0 files unresolved
E:\hg_test>cd testrepo
E:\hg_test\testrepo>copy con test.txt
Hello World!
^Z
1 file(s) copied.
E:\hg_test\testrepo>hg add test.txt
adding test.txt
E:\hg_test\testrepo>hg commit test.txt -m "Test commit"
test.txt
committed changeset 0:1904a8ab9a97
E:\hg_test\testrepo>hg push http://hg.zygonia.net/testrepo
pushing to http://hg.zygonia.net/testrepo
searching for changes
1 changesets found
remote: adding changesets
remote: adding manifests
remote: adding file changes
remote: added 1 changesets with 1 changes to 1 files
E:\hg_test\testrepo>
If we browse to our repository we can see the file we just pushed:
Fin
If you follow all of the steps exactly you should end up with a basic but working Mercurial server that you can use to push and pull changesets to.
Obviously you should secure this server if it’s public facing (mine is secured with a simple .htaccess/.htpassword affair for now).
There were a number of sites and documents online that helped me to get this far, these included:
- Installing and Setting Up Mercurial on RHEL/CentOS/Apache 2 running Python
- Setup Python 2.5, mod_wsgi, and Django 1.0 on CentOS 5 (cPanel)
- CentOS 5.5 x86_64 install Python 2.7
- modwsgi Installation Issues
The following Mercurial articles also helped:

