Skip to content

January 5, 2011


Getting Mercurial Running on DreamHost

A while back, Joel Spolsky wrote a fantastic tutorial on distributed version control systems. It’s a really clear and honest overview of Mercurial from the perspective of a recently converted skeptic. DVCS has many advantages over the old client-server model of source control, but I think the one killer advantage is that it works with or without a central server. This means that whenever I’m working on a personal project, I can just type “hg init” in the directory and BOOM, I’m tracking my changes. Later on, if I want to go through the whole process of remembering passwords to my web host, installing Mercurial, and setting up my local copy to push to a central server, I can. The real magic of DVCS though is that central server really means anything here, I could start pushing code to my analog watch if I could get Mercurial running on it.

Terrorism is also distributed

Joel’s tutorial had me intrigued, Mercurious if you will. So when I finally got some time to work on personal projects, I started using it. And I’m hooked. I haven’t had much need for the D in DVCS yet though because I’m the only one committing any code. I’ve been using Mercurial as local revision control, but I’ve been using it for EVERYTHING; my resume redesign, Arduino code, even Movable Type theme modifications. I can’t get over how easy and quick it is to turn any normal project into a legitimate source controlled juggernaut. And there’s no guilt about polluting the codebase! After a while, I started thinking that maybe I should version control my OkCupid profile, or my Facebook friends. I know I’m addicted because sometimes when I’m at the bar, I think “I wish I could hg commit right now and revert if it turns out that I drank too much.”

I started to get nervous though. Any important data that’s not in the cloud makes me nervous. I had some time on my hands the other day, so I decided to try to install Mercurial on my DreamHost account and keep a main repository there. It would also give me a chance to commit code from different machines, or different partitions on a single machine without breaking the flow of work. I was thirsting for that all-powerful D.

Usually when I want to do something new with DreamHost, I pray that they have a one-click install in their web panel and if they don’t I give up. I’ve been writing software for most of my life and am embarrassed to say, installing things in Unix baffles me. I wasn’t so lucky on this one, there is no one-click install, but they did have the next best thing. One of the great things about DreamHost is that they have a large user base and their support wiki is packed with enough documentation to hang yourself. Sure enough, there’s a page on installing Mercurial. That’s not the end of the story though, there are really three things I want to do here:

  1. Install Mercurial on my DreamHost account
  2. Configure Mercurial to allow me to push and pull code from the server
  3. Clone my existing local repositories to the server and then make that server the parent

1. Install Mercurial on my DreamHost account

Turtles are shell users too

In order to do this, we’re going to need a shell account and we’re going to need to log in to it. If you don’t already have a shell account, go to the DreamHost web panel and click Users > Manage Users. Now click Add User and set the Type of User Account to Shell.

Next, we need to SSH into the account. Our trusty DreamHost support wiki also has an entry for configuring SSH for passwordless login, which you can do to make it dead simple to login to your DreamHost shell:


Now that we’re logged in, we can actually install Mercurial from the source code. This part is pretty much just following the instructions from this page of the support wiki. I’m going to repeat the steps here with some explanations so we’ll have everything in one place.

First, make a directory for the Mercurial source and download it. I wanted to make things easier for myself so I went with the same version that’s in the tutorial.

mkdir -p ~/srcs
cd ~/srcs

Mercurial’s latest stable release is 1.7.3, so we’re not that far off. Or are we? Who cares, I’m new to Mercurial, I won’t notice the difference. Next, unzip, make and make install it.

tar xvzf mercurial-1.6.3.tar.gz
cd mercurial-1.6.3
make all
make install-home

Now do some bash configuration stuff, changing the default path for Python and the Mercurial configuration file or something.

vi ~/.bash_profile

* add these lines at the bottom:
export PYTHONPATH=~/lib/python
export PATH=~/bin:$PATH
export HGRCPATH=TheBestHuman/.hgrc

Make sure to replace TheBestHuman with your DreamHost username because, well, there can be only one. After all this, you should be able to do

hg --version

and get 1.6.3 or whatever version you decided to go rogue and install.

So now we have Mercurial installed on the server. Badass. It’s only accessible if we’re shelled into our account though; we want to be able to push and pull code from Malaysia if we happen to be there and the McDonald’s has free wifi.

2. Configure Mercurial to allow us to push and pull code from the server

The heart of Mercurial’s code publishing capabilities is a Python script called HgWeb.cgi. It’s a nice little piece of code that not only serves the repos up to remote users, but also provides you with a slick read-only web interface to your revisions (basically a friendly web version of the hg log command). Sounds awesome, right? Let’s set it up!

First, make a subdirectory for your repos.

mkdir -p ~/hg/repos

Now create the configuration file for the publishing script.

vi ~/hg/hgweb.config

* ...and add the following lines:
repos/ = repos/
style = gitweb

The default script is packaged with the Mercurial source, so copy it from there to your hg directory and add execute privileges to the copied file.

cp ~/srcs/mercurial-1.6.3/hgweb.cgi ~/hg
chmod +x ~/hg/hgweb.cgi

At this point, the wiki tells you to change the python version in hgweb.cgi, but I followed the directions and eventually (after a painful 20 minutes) had to switch this back to its original value. I’d recommend leaving the script as-is at first. If you’re getting a 500 error trying to access the hgweb.cgi page later on, you can go back and force the script to use python 2.4.

Next, change the following lines in hgweb.cgi

config = "/path/to/repo/or/config"
#import sys; sys.path.insert(0, "/path/to/python/lib")


config = "/home/TheBestHuman/hg/hgweb.config"
import sys; sys.path.insert(0, "/home/TheBestHuman/lib/python")

Remember to replace TheBestHuman with your shell user name. Next, do some Apache crap:

vi ~/hg/.htaccess

* ...add the following lines (Comments optional) and then save the file 

# Taken from
# Used at
Options +ExecCGI
RewriteEngine On
#write base depending on where the base url lives
RewriteBase /hg
RewriteRule ^$ hgweb.cgi  [L]
# Send requests for files that exist to those files.
RewriteCond %{REQUEST_FILENAME} !-f
# Send requests for directories that exist to those directories.
RewriteCond %{REQUEST_FILENAME} !-d
# Send requests to hgweb.cgi, appending the rest of url.
RewriteRule (.*) hgweb.cgi/$1  [QSA,L]

After that, all that’s left to do is map the hg directory to somewhere on your domain. You can do this by creating a symbolic link to it from a sub directory of your domain.

cd ~/
ln -s ~/hg

You might need to change some permissions.

 chmod 755 ~
 find ~/ -type d -print0 | xargs -0r chmod 755
 find ~/ -type f -print0 | xargs -0r chmod 644

At this point, you should be able to see an empty Mercurial page if you navigate to http://yourdomain/hg. Don’t worry, when you get some projects in there, it’ll look like this:

A preview of what's to come

So right now, we have an empty Mercurial installation with no repositories that’s absolutely useless. Mission Accomplished!

Not really, the next post will show you how to move an existing repo to your newly pimped Mercurial server and making it the root repo.

Continue on to Getting Mercurial Running on DreamHost Part II: Cloning an Existing Local Repo to the Server and Making it the Parent

Leave a Reply

Your email address will not be published.