Mercurial on a QNAP NAS

I spent some time today getting my QNAP NAS to serve mercurial repositories. My main motivation for this is that I like to create cheap copies of my projects and tinker around, then push them back to the main repository containing only the pertinent changes. I could, of course, have done this with Subversion but I like the challenge. And of course, prefer mercurial.

The steps involved seem to be poorly documented across the web, so the following is a fuller (though still rough) list of what I had to do to get things working. Your mileage may vary, as the saying goes.

  • ssh to your NAS, and use ipkg:
ipkg install py26-mercurial
  • create your repository area, e.g.:
mkdir -p /share/Public/repositories/mercurial
  • cd into this folder and create a shell script called reset_permissions.sh to reset permissions:
chgrp -R everyone *
chmod go+wx *
chmod go+wx */.hg
chmod -R g+rw *
  • Find and edit your apache.conf file, e.g. in /etc/config/apache/apache.conf, and add:
ScriptAlias /cgi-bin/ /share/Qweb/cgi-bin/
<Directory "/share/Qweb/cgi-bin">
 AllowOverride None
 Options ExecCGI
 SetHandler cgi-script
 AddHandler cgi-script .cgi .pl .py
 Order allow,deny
 Allow from all
</Directory>
  • Also add at the bottom:
Include /etc/config/apache/hg/main.conf
  • Create and edit: /etc/config/apache/hg/main.conf, with:
ScriptAliasMatch        ^/hg(.*)        /share/Qweb/cgi-bin/hgweb.cgi$1
<Directory  /share/Qweb/cgi-bin/> Options ExecCGI FollowSymLinks
 AllowOverride None
</Directory>
  • Create and edit: /share/Qweb/cgi-bin/hgweb.cgi
#!/usr/bin/env python
#
# 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 = "/share/Public/repositories/mercurial/hgrc"
# Uncomment and adjust if Mercurial is not installed system-wide:1
#import sys; sys.path.insert(0, "/share/MD0_DATA/.qpkg/Optware/lib/python2.6/site-packages")
# Uncomment to send python tracebacks to the browser if an error occurs:

import cgitb; cgitb.enable()
from mercurial import demandimport; demandimport.enable()
from mercurial.hgweb import hgweb, wsgicgi
application = hgweb(config)
wsgicgi.launch(application)
  • Create and edit /share/Public/repositories/mercurial/hgrc:
[hooks]
changegroup = hg update >&2
[web]
allow_push = *
push_ssl = false
[collections]
/share/Public/repositories/mercurial = /share/Public/repositories/mercurial
  • Restart apache:
/etc/init.d/Qthttpd.sh restart

The last issue to address is that you can’t actually create remote repositories via http, so you need to do the following step each time for a new repository:

mkdir -p /share/Public/repositories/mercurial/repo1
cd /share/Public/repositories/mercurial/repo1
hg init
cd ..
reset_permissions.sh

and you should be done.

You should now be able to see http://nas/hg and a list of repositories (in this case just ‘repo1′).

If you have an existing repository on your local desktop, create it with the same name on the NAS, following the steps above, then edit your local .hg/hgrc file to contain:

[paths]
default=http://nas/hg/repo1

Then hg push, and your repository should be safely stored on your NAS.

Presumably these steps will work for other server configurations, subject to changing some of the paths in some of the steps.

[Update - fixed some typos, and moved the cgi-bin location to the raid section of the NAS where the rest of the web pages are hosted from.]