Over the past couple of years, since David Roundy handed over control of the darcs revision control system to a talented team of developers, it has come a long way in stability and performance.

I began using darcs essentially out of necessity, simply because it was the revision control system of choice for much of the Haskell community. I have always found my use of it to be somewhat clunky, and lately I’ve been migrating most of my remaining Haskell projects away from it.

In day to day use, in a single-developer repository on a single machine, darcs has always been pretty decent, and in fact a few aspects of its user interface have been influential. Its record command, for instance, is sufficiently nifty that I wrote the record extension for Mercurial. I’m fairly sure that my enthusiasm for record also led me to ask for the feature that became the interactive change selection feature of the marvelous TortoiseHg GUI. Even git acquired a similar change selection feature at some point.

However, for a team of developers, or even a single individual working across several machines, darcs isn’t so great. It presents two challenges that I find troublesome: dealing with concurrent conflicting changes to files is a mess, and its much-touted patch theory often makes poor engineering sense.

My idea of a good merge process is the one I get with Mercurial (git and svn can be configured to act similarly, but don’t present nearly as nice a default experience). In brief: I start a merge by hand, most of it proceeds automatically, and I get dropped into a nice GUI whenever something funky needs fixing up. With darcs, dealing with conflicts is messy, confusing, and something I usually get wrong. I’m not alone in this; several of my collaborators dread submitting patches to GHC because it’s so hard to merge changes against a fast-moving upstream. After enough bad experiences, I have a subconscious view of a darcs merge as a way to lose bits of work.

As for patch theory, my principal point of discomfort with it is that I have little idea what was in someone’s repository when they created a patch. People grouse about the fact that the history of a Mercurial project often contains a lot of merges, but those merges mean that I can reconstruct what another developer was able to see when they were writing code. That’s a long way to say "merges are debugging gold", especially when coupled with liberal use of the bisect command. The rebase command provided by git and Mercurial provides a nice balance: history is explicit by default, but can be tidied if necessary.

I am not by any means trying to belittle the work of the darcs developers. Darcs is a good piece of software, and I appreciate the work its team has put into it over the past few years. I’ve soldiered along with it for long enough that I could obviously do so indefinitely, but the experience I have with other tools is now sufficiently better that I simply don’t want to use darcs. For day to day work, TortoiseHg is the best GUI I’ve had the good fortune to use with any revision control tool. It makes committing changes and browsing history a snap. And for collaboration, of course both github and bitbucket are fabulous. I particularly appreciate the hg-git plugin, which lets me collaborate almost seamlessly with git users, while enjoying Mercurial’s UI. Unfortunately, the darcs community has nothing on a comparable level of quality for either fluid use or collaboration.

8 comments on “Why I don’t use darcs any more (much)”

Maybe time to put Darcs to bed ? I’ve often wondered what it brings to the table beyond what Mercurial, Git and Bazaar offer. Your experience, it seems, is: not much. I suspect that it hampers Haskell projects, because would-be contributors are put off by having to use Darcs.

I suspect there’s an element of hair-shirted FSF purism about the insistence on using Darcs for all Haskell projects.

I really like the idea of darcs and the patch theory and started to use it for home projects. But I have to admit that it still does not feel ready to go prime time. I somehow agree with the statement that it might hamper haskell projects since its performance is quite bad most of the time (it took me 25 minutes to annotate a single file).

I’m honest, I would not use darcs at work. I need my revision control system to be blindingly fast, and darcs isn’t. It’s hard for me to imagine that anyone with a large project can be happy with darcs. For home use however I really like the way it works. Spontaneous branches and preparation branches are workflows that feel very natural to me.

For now I decided to go geeky and give darcs a shot and maybe even contribute some code since it really feels worthy to pursue the idea of the patch theory.

Bryan, I’m a bit surprised at your tone in this post, despite
your somewhat biased position as a long-time Hg developer.
Why not just report issues that need improvement?
That is the value of this post. I am familiar enough with the
high professionalism of the Darcs team to know that they
will appreciate that aspect of your post, and they will fix every
one of these issues.

You understand better than most that revision control is far
from trivial, and that building a new system from scratch
based on totally new first principles is a huge undertaking.
Extrapolating the rate of progress of Darcs along that road,
especially since Eric took the helm and turned Darcs into one
of the best managed open source projects in the world, the
distance until Darcs becomes a full competitor of Hg and Git is
closing fast.

It’s great to hear that Darcs is influencing other revision
control systems, just as Haskell had profound influence on
other programming languages even before it was ready
for production use. Just as the full impact of Haskell is
yet to be felt as a production programming language,
the full impact of Darcs is yet to be felt as a production
revision control system.

Whether or not you continue to “soldier along” is your
own personal decision, of course. And I have no doubt
you will vote your conscience when decisions are to be
made about revision control for projects in which you are involved, and that is as it should be.

Yitzhak, I was very careful to couch everything I said in terms of my own experience, and even to say that I think darcs is a good piece of software. In fact, I wrote this post because Eric Kow asked me to, precisely so the darcs team could take whatever they might find useful from it. I’m not sure what more I could have done to pull my punches and maintain a constructive tone, while also describing why I’ve moved on.

I started using darcs, because of its ties to Haskell, and switched to Mercurial because of your book. Mercurial is much more intuitive. I can’t explain why, but I have more of a sense that my data is really there, with Mercurial. First tries at unfamiliar operations always go smoothly.

First, if you’d like to migrate from Darcs, you could think about cabal installing darcs-fastconvert and playing around with the fastexport/fastimport support.

To (very partially) address your principle point of discomfort, you can see exactly the state of the repository that somebody else wrote their patch in by using a context file.

darcs get repo –context /tmp/the-context-file

The question here is how to obtain these context files in the first place, and that’s where I have good and bad news. The good news is that patch bundles sent via darcs send double as context files, so if you somebody sends you a dpatch file and you pass it to darcs get, you see exactly the pristine state (and set of patches) that the bundle was built on.

Now, this isn’t as useful as debugging gold as having an explicit merge history. It does the job if you’re about to apply somebody else’s patch, but what if you want to look back to a patch you applied three weeks ago? There’s where the bad news comes in. You either have to hold on to the email and the patch bundle, or you have to ask the submitter to make you a new context file with darcs changes –context.

We’ve been discussing a future “patch annotation” feature that allows you to associate optional and perhaps free-form metadata with patches. The sort of metadata I have in mind would be things like “who signed off on this patch?” and “what was the original context of the patch?”, and “when was it applied”. This is the sort of thing that history-based DVCSes do naturally, but that Darcs with its emphasis on the set-of-patches view does not. But we could come to this from the patch-annotation angle. If other DVCS could somehow add a notion of higher-level patches to its commits, the two worlds could converge.