I'm writing this as a a rough for potential rewriting for the darcs wiki section on workflows. My post on getting the most out of Darcs 2, through feedback on the darcs mailing list has actually been rewritten into patches for the official manual of darcs. When those get accepted it will mark my first official contribution to the darcs repository, which is pretty cool.

One of the fascinating things about a DVCS is that first D, distributed. There are models for working with source control opened up by a good DVCS that would have been unimaginable under a centralized system. It's still hard to advocate them to users because they sometimes take a mental leap that sometimes seems unmanageable. I'm personally fascinated by these sorts of workflows and I think that darcs is still the best of breed when it comes to allowing projects to experiment with them.

I don't know of any group currently doing fully distributed development with darcs (however, I'd be happy to hear comments about such development), but I use partly-distributed development on my own projects and with darcs there are lessons here that apply to even partly-distributed development.

I will use http URIs because it is very easy to set up a simple web server solely for read-only file sharing on every developer's machine, in any operating system environment. I'll use three example developers on local hostnames generically named deva , devb and devc . The basic theory is that each developer keeps at least one private working repository for the project and one special public repository for the project accessible via http . I'll use the generic name project for an example project, thus the public repository for deva for this project will be available at http://deva/project/ . The only developer with write access to that repository is deva and for everyone else it is only read-only accessible via http . Notice that this is a very easy security setup. A good corporate firewall then should easily block as WAN-based (internet-origin) attempts to access the internal repositories.

Note Aside: I've mentioned before that I think the killer protocol to support for a distributed environment is XMPP (aka Jabber or GTalk), where you have a central server to ping for repository status updates (is this repository currently available for pulling from?), but changes themselves are still sent securely and directly between systems, without touching a central server. I'm not going to XMPP addresses, as no DVCS currently supports them. If someone wants to implement bots for doing it with darcs I'd be happy to point out where to start, and it should actually be a fairly simple thing to build. If you want to imagine it anyway, in the following just replace something like http://deva/project/ with xmpp:deva@corp.example.com/project/ . Note that in this case you can easily use XMPP authentication and authentication lists for some pretty powerful security setups.

The pull-only fully-distributed workflow for each developer is pretty simple (forgive the unix-isms, but they should be generally readable to Windows users as well, one benefit though is the standard user@system prompt):

# Update the latest public patches from fellow devs deva@deva:~/project/working/ $ darcs pull http://devb/project/ # ...interactively decide what to pull... # ...fix any immediate collisions with working code... deva@deva:~/project/working/ $ darcs pull http://devc/project/ # ...ditto... # Push reliable, tested patches to own public repository deva@deva:~/project/working/ $ darcs push ../public/ # ...interactively choose the good patches...

There are a couple things to note here as they become even more important later on and can't be overstated: Each developer only pushes to their public repositories patches that they've integrated, test and personally "trust". Because this is the repository every other developer pulls from, it needs to be kept extraordinarily clean. Requiring automated tests in each developer's public repository is one way to help insure this is always the case.

So the first easy complaint is that every developer ends up having to do a pull for each and every other developer, how can that be maintainable? This is a complaint I'll come back to in greater detail further down, but the easy early answers are: this can be automated in a quick script (there is also repository completion in some shells when working with darcs), but more importantly this is necessary an "every time I'm working" thing. A developer may only pull changes from other developers once a day or once a week, depending on the project and the project's needs. A lot of this precipitates out of normal development conversations and workflows: issue trackers highlight when new important fixes are available in a developer's repository, mailing list and hallway discussions include sentiments like "You really should grab feature x from devb" and "You need to pull bug fix y from devc ASAP."

This is also the perfect time to introduce a powerful weapon in the darcs arsenal: --intersection . Following the early assertion that developers only push patches that they vouch for, it is very easy for deva to check for patches that both devb and devc agree on:

deva@deva:~/project/working/ $ darcs pull --intersection http://devb/project/ http://devc/project/

There is still good reason to check each developers' individual repositories as well, but consensus checks can easily be done more often and developer to developer communication can help surface times when individual repositories need to be checked.

Release by Consensus The next easy question: how do you do release management in a fully-distributed system? I've just shown the key tool to do that: --intersection and "consensus repositories". A build manager with a smoke test build system that I'll nickname bbq , because it's tasty, on deadline day can very easily grab a consensus build, smoke test it, maybe build-bot it, tag it, and ship it with very little direct contact with the developers: buildman@bbq:project/ $ darcs get --intersection http://deva/project/ \ http://devb/project/ \ http://devc/project/ \ release- ` date +%F ` # ...testing, testing, more testing... buildman@bbq:project/release-2008-08-09/ $ darcs tag -m "Release `date +%F`" The other developers may be encouraged to grab the tag patch so that they can recreate the tag in case of bug reports, but that may or may not be necessary. Note all of that can be scripted and automated. You could following the same formula for automated daily builds (although you probably don't want to tag every daily build) and continuous integration build bots.