|Version 5 (modified by lele, 5 years ago) (diff)|
Darcs backend for Trac
Since I find Darcs the most powerful yet easy VC I met, I wrote a backend for Trac to allow me use that nice piece of webware on top of my ever increasing Darcs repositories.
The goal, met IMHO, was to minimize the impact on the upstream code base, to make it easier the adoption of my work.
To start, I tailorized the Trac Subversion repository, with this Tailor config file:
#!/usr/bin/env /home/lele/wip/tailor/tailor """ [DEFAULT] verbose = True [trac] patch-name-format = [trac %(revision)s]: %(firstlogline)s remove-first-log-line = True source = svn:trac target = darcs:trac root-directory = /wip/srv/darcs/taw/trac start-revision = INITIAL [svn:trac] repository = http://svn.edgewall.com/repos/trac module = /trunk subdir = svnside [darcs:trac] subdir = darcside """
then I started hacking on the Darcs backend, subclassing the various classes, Repository, Changeset and Node. Once the first draft implementation was ready, I rectified as little as possible of the pristine sources of Trac to introduce the possibility of having a different kind of repository. The patch below (see attachments) move the last Subversion details from a few sources into versioncontrol/api.py and opens the opportunity of specifying a different kind of repository, as I did for Darcs. For example, this instance of Trac have something like
repository_dir = darcs:/.../public_html/projects/tailor
in its trac.ini, and that's it.
Now and then I run tailor over it, to keep the Darcs repository in sync with the upstream as much as possible.
It's available at http://darcs.arstecnica.it/trac+darcs
This implementation assumes that the trac-ked repository has a stable history, in other words that nobody is going to do darcs unpull or other similar commands that alter the order and list of the changesets in the repository. Even if this is one of the strength of darcs, I think that it's easier to use established Trac usage of referring to any single patch with a simple integer number, like Subversion does.
As said, under darcs there is no notion of an exact history as in Subversion, but rather of a given set of patches that compose a repository, from which darcs magic patch commutation theory reproduce the actual tree. This is nice, but quickly becomes tedious and errorprone when you wanna use a tool like Trac, where you need a simple and effective way of referring to a particular changeset without resorting to cut&paste, like  for example.
So, for the purpose of tracking it, with the assumption above, the backend just consider the enumeration of the patches that comes out from darcs changes --reverse is stable, and thus the first patch will called , the second , and so on, without exceeding in fantasy ;-)
However, as of version 0.7 the backend properly recognizes also the hashname of the patches: this allows you to refer to any particular changeset either by its local cardinal numer or by its universal unique id. So, for example, the patch that introduced this functionality may be reached:
- by its number, 
- by its hash, : here I actually wrote [20080617165959-97f81-01b798f29e7c925e146c0876e73dc6879e4d9156], and Trac replaced that with its local cardinal number to avoid useless verbosity
- using the URL, changeset:20080617165959-97f81-01b798f29e7c925e146c0876e73dc6879e4d9156
To work reasonably fast, the backend automatically and incrementally builds a cache of all the needed versions of any file in the repository. It does not keep a copy of the whole repository, only the files effectively changed by any given changeset.
It uses a subdirectory of the _darcs metadir of the repository, trac_cache, that in turn will contains a directory named after the revision of the changeset. It can be erased at any time, the backed will recreate it and start rebuilding the version at the following request. The cache directory must have write permission for the user executing the trac process, usually www-data.
The cache is now kept in a table of the database: doing a resync will erase it.
Changesets  and  introduced a darcs configuration section in the TracIni file. It allows the customization of the actual external command to execute (command),
the location of the cache directory (cachedir) to use instead of keeping it under repository's _darcs metadir. Another option is dont_escape_8bit, that basically adds DARCS_DONT_ESCAPE_8BIT=1 as prefix to the command: other environment variables may be added for example with
[darcs] command = DARCS_DONT_ESCAPE_ANYTHING=1 darcs