Subsections

Getting started

This chapter will lead you through an example use of darcs, which hopefully will allow you to get started using darcs with your project.

Creating your repository

Creating your repository in the first place just involves telling darcs to create the special directory (called _darcs) in your project tree, which will hold the revision information. This is done by simply calling from the root directory of your project:

% cd my_project/
% darcs initialize
This creates the _darcs directory and populates it with whatever files and directories are needed to describe an empty project. You now need to tell darcs what files and directories in your project should be under revision control. You do this using the command darcs add:
% darcs add *.c Makefile.am configure.ac
When you have added all your files (or at least, think you have), you will want to record your changes. ``Recording'' always includes adding a note as to why the change was made, or what it does. In this case, we'll just note that this is the initial version.
% darcs record --all
What is the patch name? Initial revision.
Note that since we didn't specify a patch name on the command line we were prompted for one. If the environment variable `EMAIL' isn't set, you will also be prompted for your email address. Each patch that is recorded is given a unique identifier consisting of the patch name, its creator's email address, and the date when it was created.

Making changes

Now that we have created our repository, make a change to one or more of your files. After making the modification run:

% darcs whatsnew
This should show you the modifications that you just made, in the darcs patch format. If you prefer to see your changes in a different format, read Section 6.5.1, which describes the whatsnew command in detail.

Let's say you have now made a change to your project. The next thing to do is to record a patch. Recording a patch consists of grouping together a set of related changes, and giving them a name. It also tags the patch with the date it was recorded and your email address.

To record a patch simply type:

% darcs record
darcs will then prompt you with all the changes that you have made that have not yet been recorded, asking you which ones you want to include in the new patch. Finally, darcs will ask you for a name for the patch.

You can now rerun whatsnew, and see that indeed the changes you have recorded are no longer marked as new.

Making your repository visible to others

How do you let the world know about these wonderful changes? Obviously, they must be able to see your repository. Currently the easiest way to do this is typically by http using any web server. The recommended way to do this (using apache in a UNIX environment) is to create a directory called /var/www/repos, and then put a symlink to your repo there:
% cd /var/www/repos
% ln -s /home/username/myproject .

As long as you're running a web server and making your repo available to the world, you may as well make it easy for people to see what changes you've made. You can do this by running make installserver, which installs the program darcs_cgi at /usr/lib/cgi-bin/darcs. You also will need to create a cache directory named /var/cache/darcs_cgi, and make sure the owner of that directory is the same user that your web server runs its cgi scripts as. For me, this is www-data. Now your friends and enemies should be able to easily browse your repos by pointing their web browsers at http://your.server.org/cgi-bin/darcs. You can read more about this interface in Chapter 7.

Getting changes made to another repository

Ok, so I can now browse your repository using my web browser... so what? How do I get your changes into my repository, where they can do some good? It couldn't be easier. I just cd into my repository, and there type:
% darcs pull http://your.server.org/repos/yourproject
Darcs will check to see if you have recorded any changes that aren't in my current repository. If so, it'll prompt me for each one, to see which ones I want to add to my repository. Note that you may see a different series of prompts depending on your answers, since sometimes one patch depends on another, so if you answer yes to the first one, you won't be prompted for the second if the first depends on it.

Of course, maybe I don't even have a copy of your repository. In that case I'd want to do a

% darcs get http://your.server.org/repos/yourproject
which gets the whole repo.

Get, pull and push also work over ssh. Ssh-paths are of the same form accepted by scp, namely [username@]host:/path/to/repository.

Moving patches from one repo to another

Darcs is flexible as to how you move patches from one repo to another. This section will introduce all the ways you can get patches from one place to another, starting with the simplest and moving to the most complicated.

All pulls

The simplest method is the ``all-pull'' method. This involves making each repository readable (via http, ftp, nfs-mounted disk, whatever), and you run `darcs pull' in the repo you want to move the patch to. This is nice, as it doesn't require you to give write access to anyone else, and is reasonably simple.

Send and apply manually

Sometimes you have a machine on which it is not convenient to set up a web server, perhaps because it's behind a firewall or perhaps for security reasons, or because it is often turned off. In this case you can use darcs send from that computer to generate a patch bundle destined for another repository. You can either let darcs email the patch for you, or save it as a file and transfer it by hand. Then in the destination repository you (or the owner of that repo) run darcs apply to apply the patches contained in the bundle. This is also quite a simple method since, like the all-pull method, it doesn't require that you give anyone write access to your repository. But it's less convenient, since you have to keep track of the patch bundle (in the email, or whatever).

If you use the send and apply method with email, you'll probably want to create a _darcs/prefs/email file containing your email address. This way anyone who sends to your repository will automatically send the patch bundle to your email address.

If you receive many patches via email, you probably will benefit by running darcs apply directly from your mail program. I have in my .muttrc the following

macro pager A "<pipe-entry>darcs apply --verbose \
        --reply droundy@abridgegame.org --repodir ~/darcs
which allows me to apply patches directly from mutt, sending a confirmation email to the person who sent me the patch.

Push

If you use ssh (and preferably also ssh-agent, so you won't have to keep retyping your password), you can use the push method to transfer changes (using the scp protocol for communication). This method is again not very complicated, since you presumably already have the ssh permissions set up. Push can also be used when the target repository is local, in which case ssh isn't needed. On the other hand, in this situation you could as easily run a pull, so there isn't much benefit.

Note that you can use push to administer a multiple-user repository. You just need to create a user for the repository (or repositories), and give everyone with write access ssh access, perhaps via .ssh/authorized_keys. Then they run

% darcs push repouser@repo.server:repo/directory

Push --apply-as

Now we get more subtle. If you like the idea in the previous paragraph about creating a repository user to own a repository which is writable by a number of users, you have one other option.

Push --apply-as can run on either a local repository or one accessed via ssh, but uses sudo to run a darcs apply command (having created a patch bundle as in send) as another user. You can add the following line in your sudoers file to allow the users to apply their patches to a centralized repository:

ALL     ALL = (repo-user) NOPASSWD: /usr/bin/darcs apply --repodir /repo/path*
This method is ideal for a centralized repository when all the users have accounts on the same computer, if you don't want your users to be able to run arbitrary commands as repo-user.

Sending signed patches via email

Most of the previous methods are a bit clumsy if you don't want to give each person with write access to a repo an account on your server. Darcs send can be configured to send a cryptographically signed patch via 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 via email. The results of the apply can be returned to the user via 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...).

This method is especially nice when combined with the --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 repo to another... so it'll take a few sections to explain how to go about it.

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 --no-test flag to darcs apply (and this is 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 via 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.

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). If you want to be able to browse your repository via the web you must also configure your web server to run cgi scripts and make sure the darcs cgi script was properly installed (via either a darcs-server package, or `make install-server').

Setting up a repository with its own user

To create a repository, as root run the `darcs-createrepo'. You will be prompted for the email address of the repository and the location of an existing copy of the repository. If your desired email is ``myproject@my.url'', this will create a user named ``myproject'' with a home directory of /var/lib/darcs/repos/myproject. FIXME: I have no idea if the darcs-createrepo program will even run on any system other than debian. Success reports would be appreciated (or of course bug reports if it fails).

The ``myproject'' user will be configured to run the darcs patcher on any emails it receives. However, the patcher will bounce any emails which aren't signed by a key in the /var/lib/darcs/repos/myproject/allowed_keys gpg keyring (which is empty). To give yourself access to this repository you will need to create a gpg key. If you don't know about public key cryptography, take a look at the gnupg manual.

Granting access to a repository

You create your gpg key by running (as your normal user):

% gpg --gen-key
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):

% gpg --export "email@address" > /tmp/exported_key
And now we can add your key to the allowed_keys:
(as root)> gpg --keyring /var/lib/darcs/repos/myproject/allowed_keys \
               --no-default-keyring --import /tmp/exported_key
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:

% darcs send --sign http://your.computer/repos/myproject
You may want to add ``send sign'' to the file _darcs/prefs/defaults so that you won't need to type --sign every time you want to send...

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. I will 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 /path/to/your/repo/_darcs/prefs called 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 ``David Roundy $<$droundy@abridgegame.org$>$.''

% echo 'my darcs repo <user@host.com>' > /path/to/your/repo/_darcs/prefs/email

The next step is to set up a gnupg keyring containing the public keys of people authorized to send to your repo. Here I'll give a second way of going about this (see above for the first). This time I'll assume you want to give me write access to your repository. You can do this by:

gpg --no-default-keyring \
    --keyring /path/to/the/allowed_keys --recv-keys D3D5BCEC
This works because ``D3D5BCEC'' is the ID of my gpg key, and I have uploaded my 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 .procmailrc:

:0:
* ^TOmy darcs repo
|(umask 022; darcs apply --reply user@host.com --no-resolve-conflicts \
             --repodir /path/to/your/repo \
             --verify /path/to/the/allowed_keys)
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 --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.

I find that I need the ``umask 022'' in order to keep procmail from setting the umask incorrectly, which causes the repository to no longer be world-readable.

Isaac Jones 2004-09-16