DarcsGit

Darcs-Git is effectively broken these days. If someone would like to do the work of resurrecting Darcs-Git, patches would be welcomed.

In the meantime you can use darcs-fastconvert (see also).

Darcs-Git was an effort to make Darcs work with Git repositories, in particular the Linux kernel repository. Git support in darcs has been removed..

Usage instructions

In order to build a Git-aware Darcs, get yourself a copy of Git (0.99 or later) and run make; this should build a libgit.a. Then copy (or link) the git directory under darcs/git/, and run

$ autoconf
$ ./configure --enable-git
$ make

A Darcs-Git tutorial, written for a very old version of Darcs-Git and Git-0.6. The information about Darcs-Git remains roughly current, but the Git commands have changed altogether.

Current Status

The following commands are believed to be fully functional on Git repositories:

  • darcs whatsnew
  • darcs changes
  • darcs pull
  • darcs apply
  • darcs add
  • darcs remove
  • darcs record
  • darcs send
  • darcs rollback

The following commands do not work on Git repositories, but should do soon:

  • darcs diff
  • darcs dist
  • darcs push
  • darcs unrecord
  • darcs unpull

The following commands don’t make sense on Git repositories (although they actually do work – go figure):

  • darcs move
  • darcs setpref
  • darcs replace

The following commands are not expected to work on Git repositories in the foreseeable future:

  • darcs initialize
  • darcs check
  • darcs repair
  • darcs get/put

TO DO

  • darcs diff and dist, and the other missing commands at some later time;
  • memoise GitCommit structures (probably requires support for weak hash tables in Haskell);
  • use Git hashes in native Darcs slurpies;
  • update the Git cache in sync_repo;
  • do something reasonable when attempting to push a move, replace or merger from Darcs into Git (darcs push –flatten ?).

Implementing diff efficiently will require some changes to the repository interfaces; see bug 552. This will result in speed improvements for native Darcs repositories too.

Darcs/Git interaction

The behaviour of Darcs-Git is defined in terms of flow of data from Git into Darcs and the other way around. For example, recording a patch in a Git repository is defined as getting the HEAD of the Git repository into Darcs, generating a Darcs patch, and getting the patch into Git. (This is not what actually happens; we take a few shortcuts in the implementation).

The mapping between Darcs and Git data structures is designed to satisfy the following property:

if a Darcs->Git mapping succeeds, then the Darcs->Git->Darcs roundtrip loses no information.

(If you’re into that sort of thing, you will recognise this as a partial retraction.)

In particular, this implies that a Darcs operation will always push all of the Darcs data into Git; if that cannot be done (for example because the Darcs data is a move or a replace patch), Darcs will simply fail.

On the other hand, there’s no requirement that the Git->Darcs mapping doesn’t lose information. This is by design: Darcs doesn’t totally order patches, while Git does, so a Darcs->Git translation might lose the ordering of history or structure of merges. On the other hand, going Git->Darcs->Git->Darcs is the same as Git->Darcs: you only lose information once (retractions are idempotent).

The interesting stuff happens when parsing Git data structures. As long as a Git branch is linear, this is a simple task of computing diffs. When a Git branch is the result of a merge, we need to compute a suitable common ancestor of the parents, then reverse-engineer a Darcs merge from the available Git data. The algorithm to do that was suggested by David Roundy and implemented by JuliuszChroboczek.

Tagging like crazy

David Roundy suggested an alternative mapping of Git to Darcs data structures, which he called the ‘’tagging like crazy’’(gmane) mapping:

This second approach has been referred to as the “tag-like-crazy” scheme, since we’d have both a darcs patch and a darcs tag for each Git commit. The first scheme would be appropriate if you want to allow git access to a primarily darcs repository. The latter may be better if a project is primarily hosted on Git, but you want to use darcs as a sort of Git client. Note that the second scheme hasn’t been implemented, but the hope is that the two schemes should have most code in common and should be able to interoperate as well as darcs and Git can interoperate with either scheme.

Note that while David’s mapping does preserve Git’s history, it does so by embedding the history of merges within dependencies between tags. The mapping used by Darcs-Git, on the other hand, avoids the use of tags and computes the minimal set of patch dependencies.