darcs-2.8.0: doc/src/best_practices.tex
% This file (unlike the rest of darcs) is in the public domain.
\chapter{Best practices}
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.
\section{Creating patches}
This section will lay down the concepts around patch creation.
The aim is to develop a way of thinking
that corresponds well to how darcs is behaving
--- even in complicated situations.
In a single darcs repository you can think of two ``versions'' of the source tree.
They are called the \emph{working} and \emph{pristine} trees.
\emph{Working} is your normal source tree, with or without darcs alongside.
The only thing that makes it part of a darcs repository
is the \verb!_darcs! directory in its root.
\emph{Pristine} is the recorded state of the source tree.
The pristine tree is constructed from groups of changes,
called {\em patches\/} (some other version control systems use the
term {\em changeset\/} instead of {\em patch\/}).\footnote{If
you look inside \_darcs you will find files or directories named
{\tt patches} and {\tt inventories}, which store all the patches
ever recorded. If the repository holds a cached pristine tree, it
is stored in a directory called {\tt pristine.hashed}.}
Darcs will create and store these patches
based on the changes you make in \emph{working}.
\subsection{Changes}
If \emph{working} and \emph{pristine} are the same,
there are ``no changes'' in the working copy.
Changes can be introduced (or removed) by editing the files in \emph{working}.
They can also be caused by darcs commands,
which can modify \emph{both} \emph{working} and \emph{pristine}.
It is important to understand for each darcs command
how it modifies \emph{working}, \emph{pristine} or both of them.
\verb!whatsnew! (as well as \verb!diff!) can show
the difference between \emph{working} and \emph{pristine} to you.
It will be shown as a difference in \emph{working}.
In advanced cases it need \emph{not} be \emph{working} that has changed;
it can just as well have been \emph{pristine}, or both.
The important thing is the difference and what darcs can do with it.
\subsection{Keeping or discarding changes}
If you have a difference in \emph{working}, you do two things
with it: \verb!record! it to keep it, or \verb!revert! it to lose the changes.%
\footnote{%
Revert can undo precious work in a blink.
To protect you from great grief,
the discarded changes are saved temporarily
so the latest revert can be undone with unrevert.}
If you have a difference between \emph{working} and \emph{pristine}%
---for example after editing some files in \emph{working}---%
\verb!whatsnew! will show some ``unrecorded changes''.
To save these changes, use \verb!record!.
It will create a new patch in \emph{pristine} with the same changes,
so \emph{working} and \emph{pristine} are no longer different.
To instead undo the changes in \emph{working}, use \verb!revert!.
It will modify the files in \emph{working} to be the same as in \emph{pristine}
(where the changes do not exist).
\subsection{Unrecording changes}
\verb!unrecord! is a command meant to be run only in private
repositories. Its intended purpose is to allow developers the flexibility
to undo patches that haven't been distributed yet.
If you \verb!unrecord! a patch, that patch will be deleted from \emph{pristine}.
This will cause \emph{working} to be different from \emph{pristine},
and \verb!whatsnew! to report unrecorded changes.
The difference will be the same as just before that patch was \verb!record!ed.
Think about it.
\verb!record! examines what's different with \emph{working}
and constructs a patch with the same changes in \emph{pristine}
so they are no longer different.
\verb!unrecord! deletes this patch;
the changes in \emph{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 \emph{working} too,
with \verb!revert!.
\verb!revert! will update \emph{working} to the state of \emph{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 \verb!unrecord! makes it impossible to track
what changes you \emph{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 \emph{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 \emph{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.
\subsection{Special patches and pending}
The patches described in the previous sections have mostly been hunks.
A \emph{hunk} is one of darcs' primitive patch types,
and it is used to remove old lines and/or insert new lines.
There are other types of primitive patches,
such as \emph{adddir} and \emph{addfile}
which add new directories and files,
and \emph{replace}
which does a search-and-replace on tokens in files.
Hunks are always calculated in place with a diff algorithm
just before \verb!whatsnew! or \verb!record!.
But other types of primitive patches need to be explicitly created
with a darcs command.
They are kept in \emph{pending}, ie, in the file {\tt\_darcs/patches/pending},
until they are either recorded or reverted.
\emph{Pending} can be thought of as a special extension of \emph{working}.
When you issue, e.g., a darcs \verb!replace! command,
the replace is performed on the files in \emph{working}
and at the same time a replace patch is put in \emph{pending}.
Patches in \emph{pending} describe special changes made in \emph{working}.
The diff algorithm will fictively apply these changes to \emph{pristine}
before it compares it to \emph{working},
so all lines in \emph{working} that are changed by a \verb!replace! command
will also be changed in \emph{pending} and \emph{pristine}
when the hunks are calculated.
That's why no hunks with the replaced lines will be shown by \verb!whatsnew!;
it only shows the replace patch in \emph{pending} responsible for the change.
If a special patch is recorded, it will simply be moved to \emph{pristine}.
If it is instead reverted, it will be deleted from \emph{pending}
and the accompanying change will be removed from \emph{working}.
Note that reverting a patch in pending is \emph{not} the same as
simply removing it from pending.
It actually applies the inverse of the change to \emph{working}.
Most notable is that reverting an addfile patch
will delete the file in \emph{working} (the inverse of adding it).
So if you add the wrong file to darcs by mistake,
\emph{don't} \verb!revert! the addfile.
Instead use \verb!remove!, which cancels out the addfile in pending.
\section{Using patches} % still basics
This section will lay down the concepts around patch distribution and branches.
The aim is to develop a way of thinking
that corresponds well to how darcs is behaving
--- even in complicated situations.
A repository is a collection of patches.
Patches have no defined order,
but patches can have dependencies on other patches.
Patches can be added to a repository in any order
as long as all patches depended upon are there.
Patches can be removed from a repository in any order,
as long as no remaining patches depend on them.
Repositories can be cloned to create branches.
Patches created in different branches may conflict.
A conflict is a valid state of a repository.
A conflict makes the working tree ambiguous until the conflict is resolved.
\subsection{Dependencies}
There are two kinds of dependencies.
Implicit dependencies is the far most common kind.
These are calculated automatically by darcs.
If a patch removes a file or a line of code,
it will have to depend on the patch that added that file or line of code.
If a patch adds a line of code,
it will usually have to depend on the patch or patches that added the adjacent lines.
Explicit dependencies can be created if you give the \verb|--ask-deps| option to \verb|darcs record|.
This is good for assuring that logical dependencies hold between patches.
It can also be used to group patches---%
a patch with explicit dependencies doesn't need to change anything---%
and pulling the patch also pulls all patches it was made to depend on.
\subsection{Branches: just normal repositories}
Darcs does not have branches---it doesn't need to.
Any two repositories are ``branches'' in darcs,
but it is not of much use unless they have a large portion of patches in common.
If they are different projects they will have nothing in common,
but darcs may still very well be able to merge them,
although the result probably is nonsense.
Therefore the word ``branch'' isn't a technical term in darcs;
it's just the way we think of one repository in relation to another.
Branches are \emph{very} useful in darcs.
They are in fact \emph{necessary} if you want to do more than only simple work.
When you \verb|get| someone's repository from the Internet,
you are actually creating a branch of it.
But darcs is designed this way, and it has means to make it efficient.
The answer to many questions about how to do a thing with darcs is: ``use a branch''.
It is a simple and elegant solution with great power and flexibility,
which contributes to darcs' uncomplicated user interface.
You create new branches (i.e., clone repositories)
with the \verb|get| and \verb|put| commands.
\subsection{Moving patches around---no versions}
Patches are global, and a copy of a patch either is or is not present in a branch.
This way you can rig a branch almost any way you like,
as long as dependencies are fulfilled---%
darcs \emph{won't} let you break dependencies.
If you suspect a certain feature from some time ago introduced a bug,
you can remove the patch/patches that adds the feature,
and try without it.\footnote{%
darcs even has a special command, {\tt trackdown}
that automatically removes patches
until a specified test no longer fails.}
Patches are added to a repository with \verb|pull|
and removed from the repositories with \verb|obliterate|.
Don't confuse these two commands with \verb|record| and \verb|unrecord|,
which constructs and deconstructs patches.
It is important not to lose patches when (re)moving them around.
\verb|pull| needs a source repository to copy the patch from,
whereas \verb|obliterate| just erases the patch.
Beware that if you obliterate \emph{all} copies of a patch
it is completely lost---forever.
Therefore you should work with branches when you obliterate patches.
The \verb|obliterate| command can wisely be disabled in a dedicated main repository
by adding \verb|obliterate disable| to the repository's defaults file.
For convenience, there is a \verb|push| command.
It works like \verb|pull| but in the other direction.
It also differs from \verb|pull| in an important way:
it starts a second instance of darcs to apply the patch in the target repository,
even if it's on the same computer.
It can cause surprises if you have a ``wrong'' darcs in your PATH.
\subsection{Tags---versions}
While \verb|pull| and \verb|obliterate| can be used to
construct different ``versions'' in a repository,
it is often desirable to name specific configurations of patches
so they can be identified and retrieved easily later.
This is how darcs implements what is usually known as versions.
The command for this is \verb|tag|,
and it records a tag in the current repository.
A tag is just a patch, but it only contains explicit dependencies.
It will depend on all the patches in the current repository.\footnote{%
It will omit patches already depended upon by other patches,
since they will be indirectly depended upon anyway.}
Darcs can recognize if a patch is as a tag;
tags are sometimes treated specially by darcs commands.
While traditional revision control systems tag versions in the time line history,
darcs lets you tag any configuration of patches at any time,
and pass the tags around between branches.
With the option \verb|--tag| to \verb|get| you can easily get
a named version in the repository
as a new branch.
\subsection{Conflicts}
A conflict \emph{happens} when two conflicting patches meet in the same repository.
This is no problem for darcs; it can happily pull together just any patches.
But it is a problem for the files in \emph{working} (and \emph{pristine}).
The conflict can be thought of as
two patches telling darcs different things about what a file should look like.
Darcs escapes this problem
by ignoring those parts of the patches that conflict.
They are ignored in \emph{both} patches.
If patch~A changes the line ``FIXME'' to ``FIXED'',
and patch~B changes the same line to ``DONE'',
the two patches together will produce the line ``FIXME''.
Darcs doesn't care which one you pulled into the repository first,
you still get the same result when the conflicting patches meet.
All other changes made by A and B are performed as normal.
Darcs can mark a conflict for you in \emph{working}.
This is done with \verb|mark-conflicts|.
Conflicts are marked such that both conflicting changes
are inserted with special delimiter lines around them.
Then you can merge the two changes by hand,
and remove the delimiters.
When you pull patches,
darcs automatically performs a \verb|mark-conflicts| for you if a conflict happens.
You can remove the markup with \verb|revert|,
Remember that the result will be the lines from
the previous version common to both conflicting patches.
The conflict marking can be redone again with \verb|mark-conflicts|.
A special case is when a pulled patch conflicts with unrecorded changes in the repository.
The conflict will be automatically marked as usual,
but since the markup is \emph{also} an unrecorded change,
it will get mixed in with your unrecorded changes.
There is no guarantee you can revert \emph{only} the markup after this,
and \verb|mark-conflicts| will not be able to redo this markup later if you remove it.
It is good practice to record important changes before pulling.
\verb|mark-conflicts| can't mark complicated conflicts.
In that case you'll have to use \verb|darcs diff| and other commands
to understand what the conflict is all about.
If for example two conflicting patches create the same file,
\verb|mark-conflicts| will pick just one of them,
and no delimiters are inserted.
So watch out if darcs tells you about a conflict.
\verb|mark-conflicts| can also be used to check for unresolved conflicts.
If there are none, darcs replies ``No conflicts to mark.''.
While \verb|pull| reports when a conflict happens,
\verb|obliterate| and \verb|get| don't.
\subsection{Resolving conflicts}
A conflict is resolved
(not marked, as with the command \verb|mark-conflicts|)
as soon as some new patch depends on the conflicting patches.
This will usually be the resolve patch you record after manually putting together the pieces
from the conflict markup produced by \verb|mark-conflicts| (or \verb|pull|).
But it can just as well be a tag.
So don't forget to fix conflicts before you accidentally ``resolve'' them by recording other patches.
If the conflict is with one of your not-yet-published patches,
you may choose to amend that patch rather than creating a resolve patch.
If you want to back out and wait with the conflict,
you can \verb|obliterate| the conflicting patch you just pulled.
Before you can do that you have to \verb|revert| the conflict markups
that \verb|pull| inserted when the conflict happened.
\section{Global and per-repository caches}
Darcs uses a global cache, as this is one of its biggest performance
enhancing tools. The global
cache acts as a giant patch pool where darcs first looks for a patch when
grabbing new patches. This saves time by not downloading the same patch
twice from a remote server. It also saves space by storing the patch only
once, if you ensure your cache and your repositories are on the same
hardlink-supporting filesystem.
Darcs now enables a global patch cache under your home directory by default.
Older darcs 2.x versions required this manual step:
\begin{verbatim}
$ mkdir -p $HOME/.darcs/cache
$ echo cache:$HOME/.darcs/cache > $HOME/.darcs/sources
\end{verbatim}
On MS Windows~\ref{ms_win}, using \verb|cmd.exe| (Command Prompt under Accessories):
\begin{verbatim}
> md "%APPDATA%\darcs\cache" (notice double quotes!)
> echo cache:%APPDATA%\darcs\cache > "%APPDATA%\darcs\sources"
\end{verbatim}
Individual repositories also contain cache location information.
Each time a repository is got, its location is added as an
entry in \verb!_darcs/prefs/sources!. If one of these repositories were to
become totally or temporarily unreachable, it can cause darcs to hang
for a long time trying to reach it. Fortunately darcs has a mechanism
which helps us to deal with that problem: if an unreachable entry is
discovered, darcs stops using it for the rest of the session and then
notifies the user to take further action. It will display a message
like the following:
\begin{verbatim}> I could not reach the following repository:
> http://darcs.net/
> If you're not using it, you should probably delete
> the corresponding entry from _darcs/prefs/sources.
\end{verbatim}
There are some other advanced things you can do in \verb!_darcs/prefs/sources!,
such as create read-only caches and even set a
primary source repository above any used in a \verb|darcs get| or
\verb|darcs pull| command.
\section{Distributed development with one primary developer}
\label{darcs-development-practices}
This is how a project with many contributors, but every contribution is reviewed
and manually applied by the project leader, can be run.
For this sort of a situation, \verb|darcs send| is ideal, since the barrier for
contributions is very low, which helps encourage contributors.
One could simply set the \verb!_darcs/prefs/email! value to the project
mailing list, but you may also want to use darcs send to send your changes to the main
server, so instead the email address could be set to something like
``\verb!Darcs Repo <maintainer@host.com>!''. Then the
\verb-.procmailrc-
file on the server should have the following rule:
\begin{verbatim}
:0
* ^TODarcs Repo
|(umask 022; darcs apply --reply project-mailing-list@host.com \
--repodir /path/to/repo --verify /path/to/allowed_keys)
\end{verbatim}
This causes darcs apply to be run on any email sent to ``Darcs Repo''.
\verb'apply' actually applies them only if they are signed by an
authorized key.
The central darcs repository contains the following values in its
\verb!_darcs/prefs/defaults!:
\begin{verbatim}
apply test
apply verbose
apply happy-forwarding
\end{verbatim}
The first line tells apply to always run the test suite. The test suite can
be a reason to use send rather than push, since it allows to
easily continue working (or put one's 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 the maintainer gets 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 \verb!darcs-devel!.
On one's development computer, one can have in their \verb!.muttrc! the following
alias, which allows to easily apply patches received via email
directly to one's darcs working directory:
\begin{verbatim}
macro pager A "<pipe-entry>(umask 022; darcs apply --no-test -v \
--repodir ~/darcs)"
\end{verbatim}
\section{Sending signed patches by email}
Darcs send can be configured to send a cryptographically signed patch by email.
You can then set up your mail system to have darcs verify that patches were
signed by an authorized user and apply them when a patch is received by
email. The results of the apply can be returned to the user by email.
Unsigned patches (or patches signed by unauthorized users) will be
forwarded to the repository owner (or whoever you configure them to be
forwarded to\ldots).
This method is especially nice when combined with the \verb!--test! option
of darcs apply, since it allows you to run the test suite (assuming you
have one) and reject patches that fail---and it's all done on the server,
so you can happily go on working on your development machine without
slowdown while the server runs the tests.
Setting up darcs to run automatically in response to email is by far the
most complicated way to get patches from one repository to another\ldots\ so it'll
take a few sections to explain how to go about it.
\paragraph{Security considerations}
When you set up darcs to run apply on signed patches, you should assume
that a user with write access can write to any file or directory that is
writable by the user under which the apply process runs. Unless you
specify the \verb!--no-test! flag to darcs apply (and this is \emph{not}
the default), you are also allowing anyone with write access to that
repository to run arbitrary code on your machine (since they can run a test
suite---which they can modify however they like). This is quite a
potential security hole.
For these reasons, if you don't implicitly trust your users, it is
recommended that you create a user for each repository to limit the damage
an attacker can do with access to your repository. When considering who to
trust, keep in mind that a security breach on any developer's machine could
give an attacker access to their private key and passphrase, and thus to
your repository.
\paragraph{Installing necessary programs}
You also must install the following programs: gnupg, a mailer configured to
receive mail (e.g.\ exim, sendmail or postfix), and a web server (usually
apache).
\paragraph{Granting access to a repository}
You create your gpg key by running (as your normal user):
\begin{verbatim}
$ gpg --gen-key
\end{verbatim}
You will be prompted for your name and email address, among other options.
%%To add your public key to the allowed keys keyring.
Of course, you can
skip this step if you already have a gpg key you wish to use.
You now need to export the public key so we can tell the patcher about it.
You can do this with the following command (again as your normal user):
\begin{verbatim}
$ gpg --export "email@address" > /tmp/exported_key
\end{verbatim}
And now we can add your key to the \verb!allowed_keys!:
\begin{verbatim}
(as root)> gpg --keyring /var/lib/darcs/repos/myproject/allowed_keys \
--no-default-keyring --import /tmp/exported_key
\end{verbatim}
You can repeat this process any number of times to authorize multiple users
to send patches to the repository.
You should now be able to send a patch to the repository by running as your
normal user, in a working copy of the repository:
\begin{verbatim}
$ darcs send --sign http://your.computer/repos/myproject
\end{verbatim}
You may want to add ``send sign'' to the file \verb!_darcs/prefs/defaults!
so that you won't need to type \verb!--sign! every time you want to
send\ldots
If your gpg key is protected by a passphrase, then executing \verb!send!
with the \verb!--sign! option might give you the following error:
\begin{verbatim}
darcs failed: Error running external program 'gpg'
\end{verbatim}
The most likely cause of this error is that you have a misconfigured
gpg that tries to automatically use a non-existent gpg-agent
program. GnuPG will still work without gpg-agent when you try to sign
or encrypt your data with a passphrase protected key. However, it will
exit with an error code 2 (\verb!ENOENT!) causing \verb!darcs! to
fail. To fix this, you will need to edit your \verb!~/.gnupg/gpg.conf!
file and comment out or remove the line that says:
\begin{verbatim}
use-agent
\end{verbatim}
If after commenting out or removing the \verb!use-agent! line in your
gpg configuration file you still get the same error, then you probably
have a modified GnuPG with use-agent as a hard-coded option. In that
case, you should change \verb!use-agent! to \verb!no-use-agent! to
disable it explicitly.
\paragraph{Setting up a sendable repository using procmail}
If you don't have root access on your machine, or perhaps simply don't want
to bother creating a separate user, you can set up a darcs repository using
procmail to filter your mail. Let us assume that you already use procmail
to filter your email. If not, you will need to read up on it, or perhaps
should use a different method for routing the email to darcs.
To begin with, you must configure your repository so that a darcs send to
your repository will know where to send the email. Do this by creating a
file in \verb!/path/to/your/repo/_darcs/prefs! called \verb!email!
containing your email address. As a trick (to be explained below), we will
create the email address with ``darcs repo'' as your name, in an email
address of the form ``User Name $<$user@host.com$>$.''
\begin{verbatim}
$ echo 'my darcs repo <user@host.com>' \
> /path/to/your/repo/_darcs/prefs/email
\end{verbatim}
The next step is to set up a gnupg keyring containing the public keys of
people authorized to send to your repository. Here is a second way of
going about this (see above for the first). This time let us assume you
want to give someone write access to your repository. You can do this by:
\begin{verbatim}
gpg --no-default-keyring \
--keyring /path/to/the/allowed_keys --recv-keys FFFFFFFF
\end{verbatim}
With ``FFFFFFFF'' being the ID of the gpg key of the person to be
authorised, if this person has uploaded their key to the gpg keyservers.
Actually, this also requires that
you have configured gpg to access a valid keyserver. You can, of course,
repeat this command for all keys you want to allow access to.
Finally, we add a few lines to your \verb!.procmailrc!:
\begin{verbatim}
:0
* ^TOmy darcs repo
|(umask 022; darcs apply --reply user@host.com \
--repodir /path/to/your/repo --verify /path/to/the/allowed_keys)
\end{verbatim}
The purpose for the ``my darcs repo'' trick is partially to make it easier
to recognize patches sent to the repository, but is even more crucial to
avoid nasty bounce loops by making the \verb!--reply! option have an email
address that won't go back to the repository. This means that unsigned
patches that are sent to your repository will be forwarded to your ordinary
email.
Like most mail-processing programs, Procmail by default sets a tight umask.
However, this will prevent the repository from remaining world-readable;
thus, the ``umask 022'' is required to relax the umask.
(Alternatively, you could set Procmail's global \verb!UMASK! variable
to a more suitable value.)
\paragraph{Checking if your e-mail patch was applied}
After sending a patch with \verb!darcs send!, you may not receive any feedback,
even if the patch is applied. You can confirm whether or not your patch was applied
to the remote repository by pointing \verb!darcs changes! at a remote repository:
\begin{verbatim}
darcs changes --last=10 --repo=http://darcs.net/
\end{verbatim}
That shows you the last 10 changes in the remote repository. You can adjust the options given
to \verb!changes! if a more advanced query is needed.