Blessed be darcs

January 15, 2006

During the last days I started to install some long-overdue updates to some webservers I manage. The problem was this: a long time ago I installed some webapps written mostly in php. People started to use them and demanded modifications. Nothing big really, but enough to make updates a pain - which led to no security updates in a long time. I started to use the brilliant version control software darcs along with the very convenient script darcs_load_dirs to install the updates. To get them on debian do apt-get install darcs darcs_load_dirs. I really recomend darcs for this (as opposed to e.g. subversion which I use at work) because it's very easy to setup/use from commandline and has a very powerfull automated merging mechanism.

Disclaimer: Although I use version management in one form or another for quite some time now, I am very new to darcs so some of the things I did could be cumbersome or wrong - read it at your own risk :). 

The process is basically this: create a new darcs dir somewhere that will receive the upstream updates of the software. I called it current.

mkdir current
cd current
darcs init

Now copy the base version (the version you started with originally) into the darcs managed dir. To find out which version you used, checkout changelog or some such file.

cp ~/base-version . -r
darcs add * -r
darcs record -am "Imported base version"

This adds the base version to the repository and creates the first revision. Now we will create a branch (a copy of the repository in darcs) to hold our modifications.

cd ..
mkdir currentWithLocalChanges
cd currentWithLocalChanges
darcs get ../current

Now copy all the relevant files from your modified install into the currentWithLocalChanges dir. You will probably have to add the new files, then you might want to review the changes and record them.

cd current
cp ~/installedVersion . -r
darcs add * -r
darcs whatsnew
darcs record -am "imported local changes"

Now apply all the new versions. For this, I simply downloaded every subsequent release (just to be sure, you can also do this directly with the new upstream version as shown in the example below) new source packages that contain the whole new source and unzipped them into
its own folder. Use darcs_load_dirs to check for differences and record them.

cd ../current
darcs_load_dirs ../newVersion

This automatically records the changes. You can take a look with darcs changes [-s]. Now you simply pull them over to your locally changed version:

cd ../currentWithLocalChanges/current
darcs pull ../../current

Bad packages (like phpbb, which really sucks) will have quite a few merge-conflicts that you have to resolve by hand now (altough darcs is really superb when it comes to automated merging). Good packages (like drupal) will work automatically because they can be extended with new pluginfiles, and not with changes to the original files.

When you need to make changes again, just do a

darcs add * -r
darcs record

again. BTW: fabian started to put the entire etc dir of the servers he administers under darcs control!