Darcs is a revision control system, along the lines of CVS or arch. That means that it keeps track of various revisions and branches of your project, allows for changes to propagate from one branch to another. Darcs is intended to be an ``advanced'' revision control system. Darcs has two particularly distinctive features which differ from other revision control systems: 1) each copy of the source is a fully functional branch, and 2) underlying darcs is a consistent and powerful theory of patches.
Really, only the first of these three layers is of particular interest to
me, so the other two are done as simply as possible. At the database
layer, darcs just has an ordered list of patches along with the patches
themselves, each stored as an individual file. Darcs' distribution system
is strongly inspired by that of arch. Like arch, darcs uses a dumb server,
typically apache or just a local or network file system when pulling
patches. darcs has built-in support for using ssh
to write to a remote file
system. A darcs executable is called on the remote system to apply the patches.
Arbitrary other transport protocols are supported, through an environment
variable describing a command that will run darcs on the remote system.
See the documentation for DARCS_APPLY_FOO in Chapter
for details.
The recommended method is to send patches through gpg-signed email messages, which has the advantage of being mostly asynchronous.
In the last paragraph, I explained revision control systems in terms of three layers. One can also look at them as having two distinct uses. One is to provide a history of previous versions. The other is to keep track of changes that are made to the repository, and to allow these changes to be merged and moved from one repository to another. These two uses are distinct, and almost orthogonal, in the sense that a tool can support one of the two uses optimally while providing no support for the other. Darcs is not intended to maintain a history of versions, although it is possible to kludge together such a revision history, either by making each new patch depend on all previous patches, or by tagging regularly. In a sense, this is what the tag feature is for, but the intention is that tagging will be used only to mark particularly notable versions (e.g. released versions, or perhaps versions that pass a time consuming test suite).
Other revision control systems are centered upon the job of keeping track of a history of versions, with the ability to merge changes being added as it was seen that this would be desirable. But the fundamental object remained the versions themselves.
In such a system, a patch (I am using patch here to mean an encapsulated set of changes) is uniquely determined by two trees. Merging changes that are in two trees consists of finding a common parent tree, computing the diffs of each tree with their parent, and then cleverly combining those two diffs and applying the combined diff to the parent tree, possibly at some point in the process allowing human intervention, to allow for fixing up problems in the merge such as conflicts.
In the world of darcs, the source tree is not the fundamental object, but rather the patch is the fundamental object. Rather than a patch being defined in terms of the difference between two trees, a tree is defined as the result of applying a given set of patches to an empty tree. Moreover, these patches may be reordered (unless there are dependencies between the patches involved) without changing the tree. As a result, there is no need to find a common parent when performing a merge. Or, if you like, their common parent is defined by the set of common patches, and may not correspond to any version in the version history.
One useful consequence of darcs' patch-oriented philosophy is that since a
patch need not be uniquely defined by a pair of trees (old and new), we can
have several ways of representing the same change, which differ only in how
they commute and what the result of merging them is. Of course, creating
such a patch will require some sort of user input. This is a Good Thing,
since the user creating the patch should be the one forced to think
about what he really wants to change, rather than the users merging the
patch. An example of this is the token replace patch (See
Section ). This feature makes it possible to create a
patch, for example, which changes every instance of the variable
``stupidly_named_var'' to ``better_var_name'', while leaving
``other_stupidly_named_var'' untouched. When this patch is merged with
any other patch involving the ``stupidly_named_var'', that instance will
also be modified to ``better_var_name''. This is in contrast to a more
conventional merging method which would not only fail to change new
instances of the variable, but would also involve conflicts when merging
with any patch that modifies lines containing the variable. By more using
additional information about the programmer's intent, darcs is thus able to
make the process of changing a variable name the trivial task that it
really is, which is really just a trivial search and replace, modulo
tokenizing the code appropriately.
The patch formalism discussed in Appendix is what makes darcs'
approach possible. In order for a tree to consist of a set of patches,
there must be a deterministic merge of any set of patches, regardless of the
order in which they must be merged. This requires that one be able to
reorder patches. While I don't know that the patches are required to be
invertible as well, my implementation certainly requires invertibility. In
particular, invertibility is required to make use of
Theorem
, which is used extensively in the manipulation of
merges.
Darcs is refreshingly different from CVS.
CVS keeps version controlled data in a central repository, and requires that users check out a working directory whenever they wish to access the version-controlled sources. In order to modify the central repository, a user needs to have write access to the central repository; if he doesn't, CVS merely becomes a tool to get the latest sources.
In darcs there is no distinction between working directories and repositories. In order to work on a project, a user makes a local copy of the repository he wants to work in; he may then harness the full power of version control locally. In order to distribute his changes, a user who has write access can push them to the remote repository; one who doesn't can simply send them by e-mail in a format that makes them easy to apply on the remote system.
--dry-run
(summarize remote changes)
--summary
(summarize local changes)
^a
(list potential files to add)
Tools and instructions for migrating CVS repositories to darcs are provided on the darcs community website: http://darcs.net/DarcsWiki/ConvertingFromCvs
Although arch, like darcs, is a distributed system, and the two systems have many similarities (both require no special server, for example), their essential organization is very different.
Like CVS, arch keeps data in two types of data structures:
repositories (called ``archives'') and working directories. In order
to modify a repository, one must first check out a corresponding
working directory. This requires that users remember a number of
different ways of pushing data around -- tla
get
,
update
, commit
, archive-mirror
and so on.
In darcs, on the other hand, there is no distinction between working
directories and repositories, and just checking out your sources
creates a local copy of a repository. This allows you to harness the
full power of version control in any scratch copy of your sources, and
also means that there are just two ways to push data around:
darcs
record
, which stores edits into your local
repository, and pull
, which moves data between repositories.
(darcs
push
is merely the opposite of pull
;
send
and apply
are just the two halves of push
).
Because of the different models used by arch and darcs, it is
difficult to provide a complete equivalence between arch and darcs.
A rough correspondence for the everyday commands follows:
Tools and instructions for migrating arch repositories to darcs are provided on the darcs community website: http://darcs.net/DarcsWiki/ConvertingFromArch
darcs-stable 2007-06-16