SVN did a great job for me for at least four years now. Lately, I stumbled upon Mercurial and decided to have a closer look. It turned out that Mercurial (also called “hg”) comes with some great advantages, namely:
- Not a “Version Control System” (VCS), but a “Distributed Version Control System” (DVCS) enabling you to check in changes locally (offline, without an internet connection). The advantages of this one are also discussed in detail in PEP 374 (Python Foundation).
- Available in pure Python, therefore installable on a standard shared web server without root access (not a virtual server, just a “web host”). Thereby cutting my costs of maintaining a root server on my own or being charged by a specialized host for an SVN/VPS plan.
This post is a small guide on how to accomplish the mission of installing Mercurial (the pure Python version) on a shared web host. In this exemplary case a “WebPack Pro” that we rent from our ISP of choice, HostEurope, is going to be used. However, what is described herein should basically work for any web hosting plan that fulfills the following requirements. This article is therefore most interesting for people who already own a shared web hosting plan and wish to use that plan for hg hosting also.
Requirements
- Source version of Mercurial
- A shared web server at an arbitrary web host enabling execution of CGI scripts written in Python (HostEurope provides Python 2.4 which appears to be sufficient).
mod_pythonormod_wsgi(better).- SSH access to that host. This is required to setup Mercurial on your shared web server. No need for root privileges.
Installation (Step by Step)
- Unpack the Mercurial source tarball on your local system.
- Create a temporary directory on your web server and transfer the extracted Mercurial source tree to that directory. You can do so via SSH or FTP.
- SSH into the server (if you did not so already) and create a top-level directory named “python”. This is going to hold all the Python modules you would like to use, but which are not currently installed on the server’s root Python distribution.
- Change to the Mercurial source directory and build the module in pure Python mode (instructions adopted from Mercurial Wiki) :
$ python setup.py --pure build_py -c -d . build_ext -i build_mo --force
- Likewise, install the module. Here, it is essential to enter the correct prefix path, as you want an alternate installation following the prefix scheme, not a standard installation. Please specify the path to your “python” directory, which you created in step 3 (in my case this is “../../python”):
$ python setup.py --pure install --prefix ../../python --force
- If everything went well
setup.pyhas installed the Mercurial module files topython/lib/python2.4/site-packagesand thehgbinary topython/bin. - In order to get the
hgbinary running via SSH you have to export your customPYTHONPATHso Python knows where to look for the hg modules. Via SSH go to your home directory on the web host and create a.bash_profilefile as follows:$ cd ~ $ touch .bash_profile
Open the file in a text editor and add the following line to it (adjust the path so that it fits your configuration):
export PYTHONPATH=/is/htdocs/wpXXXXX_XXX/python/lib/python2.4/site-packages
In order to make
hgaccessible from any directory within the shell, add the following line (adjust path corresponding to your environment again):export PATH=/is/htdocs/wpXXXXX_XXX/python/bin:$PATH
- Logout and login again via SSH. Type
hg. If you get the Mercurial Distribution SCM help screen you now have finished installation and are ready to go for setting up Mercurial web access.
Setting up hgwebdir.cgi
- First of all, create a directory on your webspace for hg. This directory must be reachable via HTTP. You may also want to set up a subdomain, e.g. hg.yourdomain.com and link that to your hg web directory.
- Get hgwebdir.cgi from the root of the Mercurial source tree or download hgwebdir.cgi from the Mercurial website, upload it to your hg directory and rename it to
index.cgi. - Make sure your web host is configured appropriately to handle .cgi files and index.cgi files. (You should be able to configure these settings in the scripts settings of your ISP’s administrative UI.)
- Open index.cgi using your text editor of choice. It is a good idea to check the script environment statement that is located in the first line of the file. It should look like the following:
#!/usr/bin/env python
This should work on most servers. However, if your python binary is not linked (or located) in /usr/bin/python you may have to correct for this.
- Find the following comment
# enable importing on demand to reduce startup time. Beneath the comment line there should be two commented lines. Change these lines to something like this:import sys sys.path.insert(0, "/is/htdocs/wpXXXXX_XXX/python/lib/python2.4/site-packages")
Replace the absolute path to the site-packages directory with your own one.
- If everything works as intended, the script should now be callable via HTTP. Enter the address of your hg web directory into your web browser and check whether the script runs correctly.
Setting Up Your First Repository and Configuring hgweb.config
- Via SSH you can setup a first test repository like this:
$ cd /path/to/www/hg $ hg init test
hg will create a directory named
testand place a.hgsubdirectory in it containing repository-specific configuration and payload data. hgwebdir.cgihas to know which repositories to serve. You tell this by creating a file namedhgweb.config. Simply put the config file into the directory ofhgwebdir.cgi.- Open the config file with a text editor and add the following lines:
[paths] test=test
Note: more info on how to configure
hgwebdir.cgican be found on HgWebDirStepByStep (in the Mercurial Wiki). - Finally, the repository itself needs some configuration. In
test/.hgcreate a new file namedhgrcand add the following lines to it:[ui] user = Firstname Lastname
[web] push_ssl = false allow_push = * This will register a first user, allow for HTTP pushing, and allow pushing for everyone (we will take care of security later on).
- That’s it. Your first repository is served via Mercurial on your shared web host.
Testing the Whole Thing
You may want to do a simple test to check whether your repository is working and you are able to pull and push changes as intended. You can do so by opening a terminal and type something like the following:
$ hg clone http://hg.yourdomain.com/index.cgi/test $ cd test $ touch testfile $ echo "This is just a test" > testfile $ hg add testfile $ hg commit -m 'Testing...' -u username $ hg push
If everything went right, this should add the file testfile to the repository root and push it to the web server.
For now, you hopefully have a working Mercurial repository directory service up and running on your shared web host. However, there are two major flaws. Firstly, the repository address is not as beautiful as it could be, because of the index.cgi contained in any path. Secondly, the repositories are accessible for everyone. We will fix these issues in what follows.
Beautifying hgwebdir Paths
In order to strip index.cgi from the repository URLs we will have to use mod_rewrite (and your server needs to support that apache module).
Go to your hg webdir root directory and create a file named .htaccess. Open the file in a text editor and add the following lines:
# Taken and adapted from http://www.pmwiki.org/wiki/Cookbook/CleanUrls#samedir
# Used at http://ggap.sf.net/hg/
RewriteEngine On
#write base depending on where the base url lives
RewriteBase /
RewriteRule ^$ index.cgi [L]
# Send requests for files that exist to those files.
RewriteCond %{REQUEST_FILENAME} !-f
# Send requests to hgwebdir.cgi, appending the rest of url.
RewriteRule (.*) index.cgi/$1 [QSA,L]
Note: this apache script rewrites URLs so that any directory queried in the form hg.yourdomain.com/directory is automatically rewritten to hg.yourdomain.com/index.cgi/directory internally. Consequently, users can omit disturbing repetitive typing of index.cgi in hg repository URLs. Please note that you may have to adapt RewriteBase to your specific server environment. If you do not serve hg repositories via a subdomain you should specify the relative base directory of your hg webdir here instead (this may e.g. be /hg if you serve hg repositories via www.yourdomain.com/hg). The approach is also discussed in PublishingMultipleRepositories on the Mercurial Wiki.
Securing hgwebdir
You can secure your hg web directory in multiple ways. You may want to allow pulling by anyone and pushing only to specific core developers. Detailed information about hg authentication can be found on PublishingMultipleRepositories.
However, my intention is to have private repositories, which I share only with my friends (no public pulling). Me and my friends will use HTTP authentication and I will create a user and password for everyone who is allowed to pull and push. Fortunately, this scenario is relatively simple to configure for everyone who knows about apache authentication configuration using htaccess files.
First of all, use htpasswd to create a password file for hg users. Name the file .hgusers and place it in a location that is not accessible via HTTP. For example, you may want to do it this way:
$ cd /private-path $ htpasswd -c hgusers username Enter password twice, etc...
Since we already have a .htaccess file, it is even more simple. Re-open the file using a text editor and add the following lines at the end of the file:
# Authentication AuthName "Please enter your username and password." AuthType Basic Require valid-user AuthUserFile /is/htdocs/wpXXXXX_XXX/.hgusers
Please change the path to the .hgusers file conforming to your server environment.
Congratulations! You now have a running, secured, beautified, pure-python hg repository server on your cheap web hosting account.
Remarks
Building Mercurial in pure Python may have drawbacks in terms of performance. This has more thoroughly been discussed on the Mercurial mailing list, see mailing list archive on pure python Mercurial.





15 responses so far ↓
1 Installing Mercurial on a Shared Web Server without Root Access … | SSH Hosting Apr 12, 2010 at 4:48 pm
[...] more here: Installing Mercurial on a Shared Web Server without Root Access … Posted in Create, Custom, Uncategorized, for, home, host, in, or, ssh, web, your | Tags: [...]
2 Keith May 5, 2010 at 5:28 pm
fantastic walkthrough I spend a bunch of time following other people’s instructions.
this worked perfectly on hostgator. thanks for the write-up.
3 basketball jerseys May 24, 2010 at 3:13 am
I hope you will keep updating your content constantly as you have one dedicated reader here.
4 Martin Geisler Jun 7, 2010 at 10:26 am
Nice guide. Let me just note that if the webhost has the standard set of development tools installed (GCC, make, Python header files, etc), then a simple
make local
will give you a completely self-contained installation right where you’ve unpacked Mercurial.
If you cannot compile Mercurial, then
make local PURE=–pure
will prepare a pure-Python version of Mercurial. The preparation is really just a matter of moving the files from mercurial/pure/ up to mercurial/ — that will make Mercurial find them.
In both cases, you should put the top-level hg script into your patch via a symlink. It is important that you use a symlink instead of copying the file, since otherwise the hg script wont be able to find all the other Python files.
5 Sam Sep 18, 2010 at 3:27 pm
Thanks Tobias, that guide helped me a lot!
6 pioj Nov 28, 2010 at 11:22 pm
Help! I can’t get the online repository at Hostgator to pull from the local clone.
Keith, can I contact you?
7 Haqqi Dec 6, 2010 at 4:57 pm
I cannot do htpasswd command in hostgator for creating authentication. Any other way?
8 Du Dec 16, 2010 at 11:58 pm
Hello, thanks for the nice tutorial but i dont have ssh access to my host, at least at the current one, so can i perform part of the ssh steps through ftp (file related) and through cron jobs ?
Thanks in advance!
9 admin Dec 28, 2010 at 5:21 pm
Hello Du, I think this could be kind of fiddling without SSH access… Of course everything file related can be done via FTP, but once you have done that probability is high you will run into privilege problems using cron. I am very sorry, but I suggest you spend a few dollars for a host with SSH access…
Tobias
10 hg-gateway: Supporting multiple Mercurial users on a Shared SSH account | Untyped Feb 21, 2011 at 12:20 am
[...] of being in this situation, download and compile hg as non-root user (without access to gcc) as detailed here. That works with GoDaddy’s [...]
11 Roshan Mar 1, 2011 at 9:28 am
Shameless Plug: If you care, there is also hg-gateway for scenarios where you don’t have root access on the machine, such as the case with shared hosting accounts.
http://parametricity.net/b/2011/02/20/hg-gateway-supporting-multiple-mercurial-users-on-a-shared-ssh-account/
12 sk Aug 28, 2011 at 6:49 pm
Hey, thanks for the writeup.
I’m just using the first part of this walkthrough so that I can version control my site, and push/update it from my local terminal. However, I cannot push to the server, because hg push ssh://admin@example.com/path/to/project returns “hg: command not found”. I know hg is working because I’ve scp’d a repo up there, and its able to check the status etc… I know its a different scenario, but do you have any hints? It seems that .bash_profile isn’t run? at least, the hg binary isn’t found.
Many thanks
13 Geier Sep 25, 2011 at 7:12 am
Installing mercurial on a shared webhost without SSH access is also possible: All the SSH-commands posted by you can also be executed using php’s shell_exec() function!
14 ac repair in verona Jan 5, 2012 at 9:07 am
What is a blogging site that allows you to sync with facebook for comments?
15 danne34 Feb 4, 2012 at 10:42 am
Give it a chance, I realy like your way to post
Leave a Comment