Building Mercurial from Source, and First Impressions
Having heard a lot about the source control management tool Mercurial lately, I thought I’d try it out. So far it has really impressed me, and I already like it a lot more than Subversion and Git. As someone who primarily uses Subversion, I have found it to be extremely easy to use (especially when compared to Git, which has been nothing but a pain for me). I love the distributed nature of it (as with Git, all working copies are full repositories in themselves, which can be branched offline), the fact that it doesn’t litter your directories with hidden SCM-related files and directories, and the ease with which you can set up new repositories. I also like how easy it is to make and use branches.
What I don’t like about it is having to install it as a python library, but that’s just a quibble that comes down to personal taste. As someone who is a fanatic about installing things from source, I found the process to be a little odd, so I’ll share my easy recipe for building and installing Mercurial from source here (both OS X and Ubuntu Linux were essentially the same).
1. Grab the source, unarchive it and enter the source directory in the terminal
2. Inside the source directory, issue the following command:
python setup.py install --force --home=$HOME
This command will build Mercurial, placing the core executable file “hg” (the periodic table symbol for Mercury) in ~/bin, and other necessary program files and tools in ~/lib. From here there are probably dozens of different ways to get things working, but the following has worked reliably for me.
3. Move everything that the Mercurial install program placed in ~/lib to a directory that is part of your $PYTHONPATH environment variable. For me, this usually means hunting down the python site-packages directory, because I’d rather not mess with augmenting that variable with other directories. On my Mac, this is found in /Library/Python/2.6/site-packages. On Ubuntu, for python 2.5, use /usr/local/lib/python2.5/site-packages; for python 2.6, use /usr/local/lib/python2.6/dist-packages (apparently, you can also use /usr/share/python-support, but I haven’t tried it).
4. The last step is to either add the ~/bin directory (where the hg executable is) to your PATH variable, or move the hg executable to a system-wide bin directory. Which one you choose depends on how you will be using it. On my Mac, (my typical working computer), I simply added ~/bin to my path. However, for my Ubuntu server (where I will host my repositories, and will need to access the hg executable via SSH) it wasn’t so easy. When you SSH to your server to clone a repository, you may get the following error:
bash: hg: command not found
This is because your ~/bin will not be found by the non-interactive shell. In other words, the file where you set the PATH variable to include ~/bin (.profile or .bashrc) is not being read by the non-interactive shell started by SSH. My solution to this issue was to check the PATH variable in the non-interactive shell by issuing:
ssh user@myserver.com "echo $PATH"
Doing this enabled me to see firsthand that /usr/local/bin was in my non-interactive bash PATH, so I moved the hg executable to /usr/local/bin (symbolic linking the file from ~/bin did not work, for some reason) and everything worked flawlessly.
5. One more gotcha. When you SSH to your repository to make a clone, use a double-forward-slash between your server and the remote path to your repository. For example, use:
hg clone ssh://user@myserver.com//home/mydir/merc_repos/my_repository my_working_copy
Thanks to Ted Naleid for that last tip, who writes, “If you don’t use a ‘//’ it assumes that the location of the repository is relative to the user’s home directory.”
Lastly, it integrates beautifully with Changes, once you download the SCM integration script from this wiki page. Highly recommended, since it makes merges and diffs a lot easier.