Skip over navigation

The Lost continent of

You've found a bug on my site!

The fear of capitalism has compelled socialism to widen freedom, and the fear of socialism has compelled capitalism to increase equality.

Ariel Durant

Darcs Revision Control System

Programming with a parachute

2008 Update. Darcs is dead, long live Git...

It had a good run, but darcs (the first version control system I actually enjoyed using) has been retired in favour of the latest SCM de jour, git, of Linux fame. It was just a performance thing in the end. I still like darcs, but it was taking 45 seconds to check my main project's source tree for changes. Git now does it in less than half a second, two orders of magnitude faster. Goodbye darcs old friend, you shall be missed... I'll get around to adapting this article to use git, once I feel I have enough expertise with it.

Everyone knows that Real Programmers™ use a revision control system. I was forced into daily battle with CVS at my previous job. I tend to rename and move files around a lot, especially when working on a new project, and CVS makes that a pain. Since then, I've eschewed any form of version control more sophisticated than backups. In the back of my mind I knew it was the wrong thing to do, but I was working alone, and the alternatives seemed like too much strain.

That all changed at the start of this year. There are a whole new generation of RCS systems out there, and I found some time over of my summer break to evaluate some promising candidates. The one that fit my needs best is David Roundy's Darcs. In this article I'll briefly introduce version control, show a typical day of work while using one, and finally consider some alternative systems.

Why bother, or Revision whats-it what?

Any computer based project consists of a number of files. This can range from one to thousands (this website contains over 5,000). Version control systems keep track of and help you manage, changes that you make to these files, as well as maintaining a complete history of all the changes you have ever made.

Here's a (not very) fictional scenario: I have a computer at my desk at work, and a laptop I take home. Say I worked on a project during the day at work. When I get home inspiration strikes, so I do some work on the laptop. Now I have a problem. How do I combine the changes I've made? I can compare times, but it's a nightmare of a job.

Version control systems arose to help solve these sorts of problems, especially when you have more than one person working on a project, in more than one place (like all over the Internet).

The Daily Grind

I like to break the programming work I do into functional 'chunks'. That is, start and finish one 'thing' before moving onto another. For example, fix an outstanding bug, or finish implementing one new feature before moving on. Darcs philosophy meshes rather well with this pattern of work.

Getting ready

First I get a nice, fresh cup of coffee, then update my local copy of the project just in case any of my co-workers did any work while I've been busy.

$ darcs pull
Pulling from ...[snip]...
No remote changes to pull in!

No surprises there...

Now we're working!

Now that my working copy of the project is up-to-date I can start work. Although Darcs handles file deletions automatically, it's neater if I tell Darcs about any file moves or additions.

$ darcs add brand-new-file.html

This command tells darcs that we want it to look after brand-new-file.html. We can either do this as we go, or get Darcs to do it automatically later.

$ darcs mv old-file-name.html new-file-name.html

File moves/renames were one of the things that drove me crazy about CVS (an older version control system). In Darcs it's simplicity itself. I can either just do it myself, in which case Darcs will treat it as separate file deletion/creation, or I can use the command above and preserve the file's history.

Patches — a quick aside...

In Darcs' world the central object is the 'patch'. A patch is just a file that represents all the changes and additions you have made to a project. It's up to you how often you make patches. When I finish a 'chunk' of work I create a patch. I try to approach problems in bite sized pieces — if it takes me more than one day to finish some chunk, then I probably need to rethink my approach to the problem.

Recording my changes

Let's get Darcs to tell us what we have done so far (the '-sl' argument tells Darcs to give just a summary, and to look for any file additions I may have overlooked).

$ darcs whatsnew -sl
M ./htdocs/main.css -2 +2
M ./layout/layout -8 +8

I'm happy with that. Those two small changes fixed a small bug, so I want to save them by creating a patch. Darcs uses the term 'record' for the process of saving one's changes. At this point Darcs gets interactive. Asking me if I'm sure, and prompting me to give it a name for my fix. My responses are in bold.

$ darcs record
hunk ./htdocs/main.css 39
-#nav { width: 200px; }
+#nav { float: left; width: 200px; }
Shall I record this patch? (1/4) [ynWsfqadjk], or ? for help: a

What is the patch name?
Better compatibility with screen readers/lynx

Do you want to add a long comment? [yn] n

Finished recording patch
    'Better compatibility with screen readers/lynx'

Sharing my changes with my team (or the world)

At this point my changes are safely under the care of Darcs on my own machine. I now want the rest of the team to get a copy of my bug fix. Darcs provides two main methods of doing this. You can either 'send' your changes (as a patch file) in an email, or 'push' them via SSH. We use SSH in the office.

$ darcs push
Pushing to ...[snip]...

Thu Feb 24 12:10:00 NZDT 2005  Leon
  * Better compatibility with screen readers/lynx
Shall I push this patch? (1/1) [ynWvxqadjk], or ? for help: y
Finished applying...

Now the next times someone in the office runs the first command in this article (darcs pull) they will get my little fix.

Alternative Systems

Over the last few months I've played with a couple of different RCS systems. The best of these were probably Monotone and GNU's Arch. Monotone is written in C++, keeps everything in a SQLite database, and looks very promising. Arch has been around longer, and is probably the best suited to large projects. A recent article on LWN provides a good overview of the field.

I ended up choosing Darcs over these (and other) alternatives because it meshed nicely with the way I do work. There is no central database in Darcs. Every project is given a new sub-folder (called _darcs) that contains the whole repository. Branch management consists of just copying patches from one branch to another. As I've tried to illustrate here day to day interaction with it is extremely simple. Just to summarise:

$ darcs pull   [Get changes from central repositry]
$ ...          [Do some work]
$ darcs record [Save your changes locally]
$ darcs push   [Save your changes to central repositry]

If you don't use a central repositry, then you don't even have to do the first and last steps.