November 20, 2007

Introducing Mercurial, a distributed version control system

Author: Amit Kumar Saha

According to its developers, "Mercurial is a fast, lightweight Source Control Management system designed for efficient handling of very large distributed projects." Dozens of projects already use the software. Here's how you can get started with some basic version control tasks using Mercurial.

Mercurial is a open distributed version control system. According to Wikipedia, distributed revision control takes a peer-to-peer approach, as opposed to the client-server approach of centralized systems. Rather than a single, central repository with which clients synchronize, each peer's working copy of the codebase is a bona fide repository. Synchronization is conducted by exchanging changesets, which define unique versions of every file, from peer to peer.

Mercurial is good for version control of both personal projects and large-scale enterprise projects.

Installing Mercurial is a breeze. Download the Mercurial tarball, extract the archive, change to the mercurial directory, and run:

$ make
$ sudo make install    # do a system-wide install
$ hg debuginstall      # sanity check
$ hg                   # see help

See the software's Web site for detailed installation instructions and platform-specific notes.

To begin exploring Mercurial, you can work with an existing repository or set up your own. To initialize a new local repository with the name "f00-repo," use the command hg init f00-repo. Note that I said "initialize," not "create"; if the directory already exists, hg initializes a new repository there. Otherwise, Mercurial creates a directory named .hg and then initializes it. Mercurial keeps all the metadata about the repository in this directory.

Once you have a repository, you can tell Mercurial about a file you want to track with the command hg add file1.txt. When you're satisfied with the file, check it in with a comment using a command like hg commit -m "Added new file".

You can view a log of your transactions by using the hg log command:

$ hg log
changeset:   0:4706e1104b96
tag:         tip
user:        amit@ubuntu-laptop
date:        Sun Nov 04 22:31:28 2007 +0530
summary:     Added new file

Cloning and pulling

If you want to create a working copy of a repository for yourself in which you can create, modify, and commit files before you commit them to the parent repository (so that you can keep working even when you are disconnected from the remote repository, or you just want experiment with the code), you can clone an existing repository, specifying the original and your new repository names:

$ hg clone f00-repo f00-repo-1
2 files updated, 0 files merge d, 0 files removed, 0 files unresolved

Other users can do the same thing, leading to disparate versions of files in diverse repositories on the server or the network. Suppose that John's working copy is f00-repo-1 and Jane's is f00-repo-2. If Jane wants to "pull" in the changes that John committed, she can first determine what things will be pulled with the following command:

$ hg incoming ../f00-repo-1
comparing with ../f00-repo-1
searching for changes
changeset:   3:5b2454e51e13
user:        amit@ubuntu-laptop
date:        Sun Nov 04 23:43:30 2007 +0530
summary:     Added file2

changeset:   4:8503fe7d3247
user:        amit@ubuntu-laptop
date:        Sun Nov 04 23:44:01 2007 +0530
summary:     Added file3

changeset:   5:5a26319e7c66
tag:         tip
user:        amit@ubuntu-laptop
date:        Sun Nov 04 23:48:28 2007 +0530
summary:     Added 1 line each

To pull in the changes and update the working copy, she would run:

$ hg pull ../f00-repo-1
pulling from ../f00-repo-1
searching for changes
adding changesets
adding manifests
adding file changes
added 3 changesets with 4 changes to 4 files
(run 'hg update' to get a working copy)

$ hg update
4 files updated, 0 files merged, 0 files removed, 0 files unresolved

Pushing

If, once she's made changes, if Jane wants to pass them along to another user, she can push her changes into someone else's repository. Again, the first step is to check what will be pushed:

$ hg outgoing ../f00-repo-3
comparing with ../f00-repo-3
searching for changes
changeset:   3:5b2454e51e13
user:        amit@ubuntu-laptop
date:        Sun Nov 04 23:43:30 2007 +0530
summary:     Added file2

changeset:   4:8503fe7d3247
user:        amit@ubuntu-laptop
date:        Sun Nov 04 23:44:01 2007 +0530
summary:     Added file3

changeset:   5:5a26319e7c66
tag:         tip
user:        amit@ubuntu-laptop
date:        Sun Nov 04 23:48:28 2007 +0530
summary:     Added 1 line each

$ hg push ../f00-repo-3
pushing to ../f00-repo-3
searching for changes
adding changesets
adding manifests
adding file changes
added 3 changesets with 4 changes to 4 files

If you're concerned about access control, Mercurial has you covered in threeways:

Remote repositories and other version control systems

Our discussions so far, has dealt only with local repositories. With remote repositories, nothing changes except the repository locations. You just have to specify a URL, which could be a remote Web server, an FTP server, or a domain name.

For example, to clone a remote repository, use the command:

$ hg clone http://selenic.com/hg working-rep0

Mercurial offers tools that provide automatic conversion of repositories from other SCMs to Mercurial. ConvertExtension bundled with mercurial supports branches, incremental imports, and only understands CVS, subversion, Darcs and git. This link will be useful for further information on the topic.

Help is never far away. The project has mailing lists and commercial support available. If you need further help, the book Distributed Revision Control with Mercurial is an excellent resource to have. The Mercurial Web site also lists some HOWTOs.

Conclusion

Mercurial is easy to set up, fast, and lightweight -- as good for your local version control needs as it is for maintaining large projects. Even going public with your repository is not a big hassle -- free Mercurial hosting is available.

Categories:

  • Desktop Software
  • Programming