# Mercurial notes Using Subversion as source control for personal files, I was finding it difficult to maintain contact with a single repository URL. Mercurial solves that problem nicely, and even plays well with Subversion. Mercurial commands are almost identical to Subversion, when the functionality is the same. Git solves the same problem, with more options but more complexity [[Git_notes.html]]. Mercurial is easy to use safely in a very short time. Projects using Mercurial include Mozilla, OpenSolaris, OpenJDK, Netbeans, and Pidgin. Mercurial is implemented in python, with some C for binary diffs. It is available on all platforms. This example shows the most important new functionality: http://www.selenic.com/mercurial/wiki/index.cgi/UnderstandingMercurial Interesting tutorial here: http://hginit.com/ See the main website here: http://www.selenic.com/mercurial/wiki/ * My install * On Ubuntu, just install with ``sudo apt-get install mercurial''. On CentOS, I found it necessary to get the source and install with make: => tar zxvf mercurial-1.1.2.tar.gz cd mercurial-1.1.2 sudo make install <= This installed ``/usr/local/bin/hg'' but did not put the python module in my path. Typing ``hg'' returned the error ``ImportError: No module named mercurial'' So to my login environment I added (for two different machines): => PYTHONPATH="/usr/local/lib/python2.4/site-packages:${PYTHONPATH}" PYTHONPATH="/usr/local/lib64/python2.4/site-packages:${PYTHONPATH}" <= * Making a Subversion working copy into an Hg respository * First check out a working copy of Subversion, and create a new Mercurial repository that shares the working copy: => svn co URL/trunk svn_hg_repo cd svn_hg_repo hg init cat > .hgignore <<EOF \.svn/ \.hgignore$ EOF hg status hg add hg status hg ci -A -m "imported from svn" hg log <= If you have a collegue who wants to share your Hg repository inside his SVN working copy, then he can do the following: => hg clone -U /path/to/svn_hg_repo_one svn_hg_repo_two svn co URL/trunk svn_hg_repo_two cd svn_hg_repo_two hg up <= Alternatively, if the subversion working copy already exists: => svn co URL/trunk svn_hg_repo_two hg clone -U /path/to/svn_hg_repo_one temp mv temp/.hg svn_hg_repo_two/ cd svn_hg_repo_two hg up <= Your final ``hg up'' will fail if there are inconsistencies between files in Hg and in SVN. Make sure all changes are checked into both respositories, and update again. (It is okay if some files are omitted.) After this, it is perfectly fine if the two repositories get out of synch. The ``hg clone -U'' does require that the target directory not yet exist. The ``-U'' flag copies the Hg repository without the files, so that SVN can update those files. Multiple developers can now merge their revisions through Hg before either checks into the centralized SVN repository. To update this double working copy, the second user could type => cd svn_hg_repo_two svn up svn st hg pull -u /path/to/svn_hg_repo_one hg st <= The first user can use exactly the same commands, exchanging ``svn_hg_repo_two'' and ``svn_hg_repo_one''. * Synchronizing with detachable media * I can make a copy of an Hg repository to a detachable disk. => cd /media/USBDISK hg clone /path/to/svn_hg_repo hg_only <= Here's a sample remote path: => hg clone ssh://host//full/path/svn_hg_repo hg_only hg clone ssh://host/svn_hg_repo hg_only # from home directory <= Assume that copy is modified offsite. => cd /media/USBDISK/hg_only echo foo > testfile hg add testfile hg ci -m test hg log <= Later that detachable disk is reconnected and you want the changes merged with the latest version of the SVN repository. First update the original SVN working copy, and save the changes into that Hg repository. => cd $HOME/svn_hg_repo svn up hg ci -m "updated from SVN" <= Then merge those SVN changes into the offsite Hg copy: => cd /media/USBDISK/hg_only hg pull $HOME/svn_hg_repo hg update # If the update fails, then you need a merge hg merge hg ci -m "merged SVN updates" <= Finally, pull the offsite changes into the SVN working copy and check in: => cd $HOME/svn_hg_repo hg pull /media/USBDISK/hg_only hg update svn ci -m "updated from Hg" <= You can also reverse the direction and ``push'' changes from one copy to another, as if you were checking into a central repository. But I find it simpler always to use ``pull'' Bill Harlan, January, 2009