= 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. == Darcs repository == 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 == Assumption == 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. === Revision number === 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 [700] 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 [1], the second [2], 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, [120] * by its hash, [20080617165959-97f81-01b798f29e7c925e146c0876e73dc6879e4d9156]: 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 As you can see, the ''hashname'' is missing the ending `.gz`: the backend understands both forms (as [http://permalink.gmane.org/gmane.comp.version-control.darcs.user/12360 darcs does]). == Cache == 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. == Configuration == Changesets [1862] and [1863] 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 [http://www.abridgegame.org/darcs/manual/node5.html#SECTION00520000000000000000 environment variables] may be added for example with {{{ [darcs] command = DARCS_DONT_ESCAPE_ANYTHING=1 darcs }}}