Mercurial's and Darcs' basic features compared

A while ago I wrote a small tutorial on Darcs. In the meantime I’ve used it heavily, but I’ve also noted some minor issues. It hangs sometimes when I try to push a few patches to a remote server.

Anyway Darcs is still one of the leading distributed version control systems around, so this article is not meant to dismiss Darcs in any way.

I like to explore new things from time to time, occasionally I switch technologies when it seems to be a good decision. It happened before and may happen again – in this case with source-control.

So, what is the purpose of this article? Mercurial is new to me too, but I’ve read some interesting articles and saw a nice video about it which made me curious about it. The interesting thing is, that Darcs is often considered as the standard everyone looks up to (except for a few issues, as mentioned before). Mercurial is a very active and interesting approach so here is my take to become familiar with it.

Coming from Darcs, I’ll take my Darcs-workflow and try to translate it to Mercurial.

Creating a repository (darcs init)

hg init

It seems as if Mercurial doesn’t come with any defaults, so you have to configure your repository from scratch.

To do that, create a .hgignore in your repository-root and insert patterns for files you wish to be ignored. For example to ignore object files insert

syntax: glob
*.o

Ignoring files is not necessary, you can choose to ignore these files yourself, and don’t add them to version control.

Additionally, it’s a good idea to create a configuration file for Mercurial in your home directorty (~/.hgrc). This should at least contain your email address:

[ui]
username = Author Name <email@address>

Adding files to version control (darcs add)

hg add *

In contrast to darcs add you don’t need to supply a recursive parameter since Mercurial traverses the directory tree by default. Note that this only works when you add all files.

Commiting your work (darcs record)

hg commit

The commit command simply takes all changes and commits them (unless you supply filenames), Darcs asks which patches it should commit.

Getting the changes to another repository (darcs get/put/pull/push)

hg clone REPO1 REPO2

Clone is the pendant to Darcs’ get or put commands. It allows you to copy the contents of REPO1 to REPO2, where REPO2 is non-existant.

hg push [-r REV] REPO

This command pushes all commited changes to the destination repository. You can add a parameter which specifies the revision to push. Darcs provides the ability to select independent patches and push only these.

Darcs stores the last repository used for push/pull. In Mercurial, clone sets the default repository (used for push and pull), but you can specify a different repository for push. push and pull don’t alter these settings, but you can do it in the .hg/hgrc config file within your project:

[paths]
default-push = ssh://hg@example.com/path

(Note: the default for pull is simply default).

hg pull works similar.

One very important thing to remember: after pulling or pushing, you have to run hg update to update your working directory. Without this, you have the patches in your repository, but you don’t see the changes in your files! For convenience, it is possible to add the parameter -u to the pull command to these operations to update the working directory immediately.

  • hg pull -u

Final note

These are the commands I use most of the time. Of course both programs offer far more than that.

The conceptual difference between Darcs and Mercurial is, that Mercurial treats the whole code base as a revision (much like Subversion), where Darcs juggles it’s patches. Each Darcs repository could be unique because it holds different patches. In Mercurial you have one revision you can distribute (even it it’s not the head).

I think that Mercurials approach is more intuitive, but leaving out a feature can only reduce the expressive power so Darcs is more powerful since it allows both.

Some people started ranting about performance of these tools. Honestly I don’t think that matters. On one hand, the lengthy operations can almost always happen in parallel (in another terminal window for example) while I’m coding again. On the other hand, how big is the difference? A few seconds?

Anyways, both projects are well documented and stable. I think it’s more a matter of taste and peer pressure1.

I didn’t look at the advanced features of the systems because I rarely use them. Of course it’s nice to have them if I need them.

I just need a version control system which is simple enough, but scales when I need more. It should be easily available on my machines, even if I’m not root. I want to be able to work offline so CVS and Subversion are no options for me2. There are still more options to explore… . Darcs and Mercurial seem to do a very good job at it, with slight advantages/disadvantages on both sides.

Other resources:

This quick writeup should not be biased towards one of these systems, but since I know Darcs better it surely is. Maybe I’ll use Mercurial for my next project and – who knows – maybe switch to it if I’m pleased.

Yesterday I was pretty sure that Darcs is the way to go, but I’ve got a pretty harsh feedback which got me to re-evaluate some points.

1 If you happen to be a Haskell developer you are more likely to use Darcs, if you develop in Python you may be biased towards Mercurial.

2 Again, leaving out a feature can only reduce the power of such a system, so the ability to work offline is crucial for me. Installing a CVS or SVN server on my laptop is possible, but how could I sync the repositories? I’d rather take a system designed for such a task.


Darcs makes the simple things tough, the difficult things near impossible, and the impossible merely really slow. —Quote from a Bazar IRC chatlog

Comments