Darcs 2

Darcs 2 was released in April 2008 and is the currently maintained version of Darcs.

Darcs 2 introduces format changes that improve performance and safety: the “hashed” repository format and the darcs-2 patch format.

Hashed repository format

The hashed repository format has a number of visible changes:

  1. darcs clone is now much faster, and always operates in a “lazy” fashion, copying first the working copy, and then downloading patches on demand.
  2. All data files inside of _darcs are hashed. This dramatically reduces the danger of third-party programs recursing into it and corrupting files.
  3. Darcs automatically caches patches and file contents to reduce bandwidth use and save disk space. This greatly speeds up operations like clone and pull. The cache lives in ~/.cache/darcs and can be deleted anytime.

Darcs-2 the patch format

The new darcs-2 patch format features a merge algorithm that introduces two major user-visible changes

  1. It should no longer be possible to confuse darcs or freeze it indefinitely by merging conflicting changes.
  2. Identical primitive changes no longer conflict (see below).

Creating a repository in the darcs-2 patch format

By default, darcs init creates repositories with the darcs-2 patch format.

Converting an existing repository to the darcs-2 patch format is as easy as:

darcs convert oldrepo newrepo

Perform this command once per project, since the result of the conversion depends on the order of patches in your repository. Projects should switch to darcs-2 patch format in unison.

Changes in semantics

When using the darcs-2 patch format, darcs treats identical primitive patches as the same patch. In particular, dependencies (except those explicitly created by the use with –add-deps) are always dependencies on a given primitive patch, not on a given named patch. This means that the change named “foo” may in effect depend on either the change named “bar” or the change named “baz”.

A simple example

Let me illustrate what could happen with a story. Steve creates changes “A” and “B”:

steve$ echo A > foo
steve$ darcs record -lam Anote
steve$ echo B > foo
steve$ darcs record -am Bnote

Meanwhile, Monica also decides she’d like a file named foo, and she also wants it to contain A, but she also wants to make some other changes:

monica$ echo A > foo
monica$ echo Z > bar
monica$ darcs record -lam AZnote

At this point, Monica pulls from Steve:

monica$ darcs pull ../steve

but she decides she prefers her AZ change, to Steve’s A change, and being a harsh person, she decides to obliterate his change:

monica$ darcs obliterate  --match 'exact Anote' --all

At this point, with the darcs-1 patch format, darcs would complain, pointing out that patch B depends on patch A. However, with the darcs-2 patch format, darcs will happily obliterate patch A, because patch AZ provides the primitive patches that B depends upon.

Upgrading from a repository created with Darcs 1

Upgrading can be done in two different ways:

Simplest: hashed repositories

This provides you:

  • darcs clone --lazy (a safer alternative to partial repositories)
  • more corruption-proofing of repositories
  • full compatibility with existing repositories
  • better handling of case-insensitive file systems

More advanced: the darcs-2 patch format

You should consider this phase if conflicts are a problem for you in practice. See the FAQ entry on upgrading formats

If you switch to the new darcs-2 patch format, you lose backwards compatibility, but then you also get

  • improved merging (no more ‘exponential’ merges)
  • no more hidden conflicts causing data loss
  • more intuitive handling of duplicate patches (identical patches no longer conflict)