September 8th, 2007

  • evan

extensibility in VCSes

(I've promised myself I'd write less about version control, because it's one of those subjects that are endlessly debatable and discussable by people who like to talk about doing rather than doing. [Just like programming languages! I seem to have become one of those people...] In my own defense, this post isn't really about version control.)

With the proliferation of version control systems that all solve more or less the same problem, it's been interesting to see how they deal with scriptability/extensibility. Their approaches are surprisingly different. Observe:
  • darcs: no support(?).
  • monotone: lua for extension on the inside, and a sort of text protocol for driving it from the outside.
  • mercurial: you can install Python modules as extensions and they can add subcommands as well as (since it's all Python) access internal APIs.
  • subversion: client is a wrapper on top of a library, and then an emphasis on exposing their libraries as bindings.
  • git: (as far as I understand it) each subcommand is a separate binary and it's common to hook them together with shell scripts. (monotone can be run like this too, but their automation interface means when you have a lot of commands to run all together you only have to start the process once. Perhaps because of the lua bits they don't expose as many internals as git does via this interface.)
The problem of extension is at some level similar to the problem of customization: there's a trade-off between providing for users' needs and not uglying up the internals to support all possible situations. With free software there's always the option of editing the source, so what ends up distinguishing these solutions are less-interesting problems such as the learning curve and ease of use.

At the extreme of extensibility lies solutions like git (again, I don't follow it too closely so my impressions could be wrong), which effectively exposes its guts to the world and has version control as just one application of the tools it provides. In git's case this has prompted wrapper suites with differing interfaces. There's surprisingly a similar story with subversion, as SVK uses some of subversion's APIs and throws out other bits. On the other extreme you see systems where they try to do just one thing well, which can make their command set simpler to follow (though I notice that darcs help is now two pages!) or may just be necessary for the complexity of what's happening (e.g. monotone, certs, and key management).

From personal experience: I've hacked a bit of Lua for monotone and found it painful. It's not that hard for me to learn Yet Another Scripting Language at a basic level but when I'm trying to just get something done I don't want to be digging through API references trying to figure out how to concatenate a list (er, table) of strings. Mercurial's approach has produced tons of extensions and from a user perspective feels quite clean: you load in an extension module and the top-level hg help command suddenly provides new subcommands. Yet git seems to be the one getting most of the contribution from third parties, perhaps because it's so simple to get started; you can run the commands yourself from a shell to see what'll happen. (Or, perhaps because it was developed alongside its killer app...)