monotone implementation notes ----------------------------- 1. general This branch contains an implementation of the monotone automation interface. It needs at least monotone version 0.47 (interface version 12.0) or newer. To set up a new project with monotone, all you need to do is to create a new monotone database with $ mtn db init -d project.mtn in the configured repository path ('mtn_repositories'). To have a really workable setup, this database needs an initial commit on the configured master branch of the project. This can be done easily with $ mkdir tmp && touch tmp/remove_me $ mtn import -d project.mtn -b master.branch.name \ -m "initial commit" tmp $ rm -rf tmp 2. current state / internals The implementation should be fairly stable and fast, though some information, such as individual file sizes or last change information, won't scale well with the tree size. Its expected that the mtn automation interface improves in this area in the future and that these parts can then be rewritten with speed in mind. Another area of improvement is the access pattern to the monotone database. While only one process is started per request, the time (and server resource) penalty for this could still be dramatic once many clients try to access the service. Luckily, monotone has an easy way to deliver its stdio protocol for automation usage over the network (mtn au remote_stdio), so the following scenarios are possible: a) setup a single mtn server serving one database on a different (faster) server and let the stdio client connect to that b) setup usher (available from branch net.venge.monotone.contrib.usher from the official mtn repository on monotone.ca) as proxy in front of several local monotone databases mirroring themselves c) like b), but use usher as proxy in front of several other remote monotone databases (forwarding) The scenario in a) might be needed anyways for a shared hosting environment, because a database which gets served via netsync cannot be accessed by another local process at the same time (its locked then), so ideally both, the network functionality as well as the indefero browsing functionality should be delivered from one single database per project via netsync. The only alternative for this setup is a two-database approach, where one database acts as network node and the other as backend for indefero. The synchronization between these two would then have to happen via standard tools (cron...) or a sync request from one database to the other. While the current implementation is ready for the two database approach, some code parts and configuration changes have to happen for the remote stdio usage. Bascially this is replacing the initial call to mtn -d project.mtn au stdio (Monotone.php, around line 74) with mtn au remote_stdio HOSTNAME which could be made configurable in conf/idf.php. But again, this heavily depends on the exact anticipated server setup. To scale things up a bit, multiple projects should of course use separated databases. The main reason for that is that while read access can be granted on a branch level, write access gives total write possibilities on the whole database. One approach would be to start one serve process for each database, but the obvious downside here is that each of those processes would need to get bound to another (non-standard) port making it hard for users to "just clone" the project sources without knowing the exact port. Usher comes to the rescue here as well. It has three ways to recognize the request for a particular database: a) by looking at the requested host name (similar to SNI for Apache) b) by evaluating the requested branch pattern c) by evaluating the path part from an mtn:// uri (new in mtn 0.48) The best way is probably to configure it with c) - instead of pulling a project like this $ mtn pull hostname branchname a user uses the URI syntax (which will, btw. be the default from mtn 0.99 onwards): $ mtn pull mtn://hostname/database?branchname Here, the "/database" part is used by usher to determine which backend database should be used for the network action. The "clone" command will also support this mtn:// uri syntax, but this didn't made it into 0.48, but will be available from 0.99 and later. 3. indefero critique: It was not always 100% clear what some of the abstract SCM API method wanted in return. While it helped a lot to have prior art in form of the SVN and git implementation, the documentation of the abstract IDF_Scm should probably still be improved. Since branch and tag names can be of arbitrary size, it was not possible to display them completely in the default layout. This might be a problem in other SCMs as well, in particular for the monotone implementation I introduced a special filter, called "IDF_Views_Source_ShortenString". The API methods getPathInfo() and getTree() return similar VCS "objects" which unfortunately do not have a well-defined structure - this should probably addressed in future indefero releases. While the returned objects from getTree() contain all the needed information, indefero doesn't seem to use them to sort the output f.e. alphabetically or in such a way that directories are outputted before files. It was unclear if the SCM implementor should do this task or not and what the admired default sorting should be.