This chapter is intended to review various scenarios and describe in each case effective ways of using darcs. There is no one ``best practice'', and darcs is a sufficiently low-level tool that there are many high-level ways one can use it, which can be confusing to new users. The plan (and hope) is that various users will contribute here describing how they use darcs in different environments. However, this is not a wiki, and contributions will be edited and reviewed for consistency and wisdom.
Darcs is change based. Changes are recorded in patches. Patches are copied to other branches to incorporate the changes there. Patches can be thrown away to make a branch go back in time. Patches are, as much as possible, independent; you can include some patches but exclude others in a branch. This can be used to find out exactly what patch introduced a bug.
_darcs
directory in its root.
Pristine is the recorded state of the source tree.
The pristine tree is constructed from groups of changes,
called patches (some other version control use the
term changeset instead of patch).footnoteIf you look inside _darcs you will find files or directories named
`patches' and `inventories', which store all the patches
ever recorded. If the repository holds a cached pristine tree, it
is stored in a directory called pristine or current;
otherwise, the fact that there is no prisine tree is marked
by the presence of a file called pristine.none or current.none.
whatsnew
(as well as diff
) can show
the difference between working and pristine to you.
It will be shown as a difference in working.
In advanced cases it need not be working that has changed;
it can just as well have been pristine, or both.
The important thing is the difference and what darcs can do with it.
record
it to keep it, or revert
it to lose the changes.5.1
If you have a difference between working and pristine--for example after editing some files in working--whatsnew
will show some ``unrecorded changes''.
To save these changes, use record
.
It will create a new patch in pristine with the same changes,
so working and pristine are no longer different.
To instead undo the changes in working, use revert
.
It will modify the files in working to be the same as in pristine
(where the changes do not exist).
unrecord
is a command meant to be run only in private
repositories. It's intention is to allow developers the flexibility
to undo patches that haven't been distributed yet.
However, darcs does not prevent you from unrecording a patch that has been copied to another repository. Be aware of this danger!
If you unrecord
a patch, that patch will be deleted from pristine.
This will cause working to be different from pristine,
and whatsnew
to report unrecorded changes.
The difference will be the same as just before that patch was record
ed.
Think about it.
record
examines what's different with working
and constructs a patch with the same changes in pristine
so they are no longer different.
unrecord
deletes this patch;
the changes in pristine disappear and the difference is back.
If the recorded changes included an error, the resulting flawed patch can be unrecorded. When the changes have been fixed, they can be recorded again as a new--hopefully flawless--patch.
If the whole change was wrong it can be discarded from working too,
with revert
.
revert
will update working to the state of pristine,
in which the changes do no longer exist after the patch was deleted.
Keep in mind that the patches are your history,
so deleting them with unrecord
makes it impossible to track
what changes you really made.
Redoing the patches is how you ``cover the tracks''.
On the other hand,
it can be a very convenient way to manage and organize changes
while you try them out in your private repository.
When all is ready for shipping,
the changes can be reorganized in what seems as useful and impressive patches.
Use it with care.
All patches are global, so don't ever replace an already ``shipped'' patch in this way! If an erroneous patch is deleted and replaced with a better one, you have to replace it in all repositories that have a copy of it. This may not be feasible, unless it's all private repositories. If other developers have already made patches or tags in their repositories that depend on the old patch, things will get complicated.
This is how darcs itself is developed. There are many contributors to darcs, but every contribution is reviewed and manually applied by myself. For this sort of a situation, 'darcs send' is ideal, since the barrier for contributions is very low, which helps encourage contributors.
One could simply set the _darcs/prefs/email
value to the project
mailing list, but I also use darcs send to send my changes to the main
server, so instead the email address is set to
``Davids Darcs Repo <droundy@abridgegame.org>
''. My .procmailrc
file on the server has the following rule:
:0: * ^TODavids Darcs Repo |(umask 022; darcs apply --reply darcs-devel@abridgegame.org \ --repodir /path/to/repo --verify /path/to/allowed_keys)This causes darcs apply to be run on any emails sent to ``Davids Darcs Repo''. Apply actually applies them only if they are signed by an authorized key. Currently, the only authorized key is mine, but of course this could be extended easily enough.
The central darcs repository contains the following values in its
_darcs/prefs/defaults
:
apply test apply verbose apply happy-forwardingThe first line tells apply to always run the test suite. The test suite is in fact the main reason I use send rather than push, since it allows me to easily continue working (or put my computer to sleep) while the tests are being run on the main server. The second line is just there to improve the email response that I get when a patch has either been applied or failed the tests. The third line makes darcs not complain about unsigned patches, but just to forward them to
darcs-devel
.
On my development computer, I have in my .muttrc
the following
alias, which allows me to easily apply patches that I get via email
directly to my darcs working directory:
macro pager A "<pipe-entry>(umask 022; darcs apply --no-test -v --repodir ~/darcs)"
This section describes the development method used for the density
functional theory code DFT++, which is available at
http://dft.physics.cornell.edu/dft
.
We have a number of workstations which all mount the same /home
via NFS.
We created a special ``dft'' user, with the central repository living in that
user's home directory. The ssh public keys of authorized persons are added to
the ``dft'' user's .ssh/allowed_keys
, and we commit patches to this
repository using darcs push. As in Section ,
we have the central repository set to run the test suite before the push goes
through.
Note that no one ever runs as the dft user.
A subtlety that we ran into showed up in the running of the test suite.
Since our test suite includes the running of MPI programs, it must be run
in a directory that is mounted across our cluster. To achieve this, we set
the $DARCS_TMPDIR
environment variable to ~/tmp
.
Note that even though there are only four active developers at the moment, the distributed nature of darcs still plays a large role. Each developer works on a feature until it is stable, a process that often takes quite a few patches, and only once it is stable pushes to the central repo.
David Roundy 2005-02-04