As described in the previous post in this series, Subversion is a great way for people to collaborate on projects together using a central server.
However Subversion, being chiefly designed largely as a stable and
clean replacement for CVS, had some somewhat peculiar design decisions
made along the way. One of them was the implementation of
"disconnected operations". Being an inherantly centralised system, it
only had a few operations which would work disconnected, such as
status, diff, and anything else that didn't have to
save to the central depository. A major annoyance was the way that it
achieved this - by keeping the repository versions of files as full
copies at every directory level, using the apologist line "disk is
cheap". This meant that any given checkout was guaranteed to be twice
the size of the files checked out, and everything from 'grep
-r' to tab completion were interfered with by these
In September 2003, Kao Chia-liang aka clkao decided that he wanted disconnected operation to be a bit smarter. Instead of keeping the server-side versions of files separately per-checkout, SVK will mirror revisions from the remote Subversion repository in a local Subversion repository (or 'depot') in your ~/.svk. The guaranteed availability of a local repository meant that you did not need to keep lots of files in every checkout path - in fact, SVK checkouts are spotless. The only way you can even tell a directory is a checkout is because of information in ~/.svk/config.
SVK tool the general Subversion CLI look and feel, and introduced some new keywords as were required for the new operations that this approach allowed you to do; so, now you have terms like mirror to tie a reference to a remote repository to a local SVK path, sync to fetch revisions from a remote repository, smerge or "source merge" to copy revisions or changes from one path to another within a repository, pull to fetch and merge from the centre, and push to copy revisions back towards the centre. "Centre" in this case meaning the Subversion repository which the other branches stem from.
SVK puts little cookies in subversion properties to track this information, called "merge tickets" - though sadly, a consequence of the design is that these tickets must refer to the UUID and revisions in your SVK depot - making them quite useless to anyone without a copy of it¹.
SVK and development team interaction
SVK suits the "star merge" pattern of distributed developers well. "Star Merge" refers to a set of distributed repositories, all merging back to a central server that holds the master copies of each branch. People are expected to make branches within this repository to precede each new chains of development or for "release" branches, and within a single one of these branches, you are expected to keep up to date and only ever commit back based on what the latest version of a particular file is.
A logical extension of this is that SVK also supports the "tree merge" pattern well. People can share their SVK depots via Subversion, and so long as people are not allowed to commit to "mirrored" paths within the depot, they can safely form another star of committers around the secondary depot. The flow of commits then becomes an acyclic graph or tree.
SVK fixes a key design flaw in Subversion - the indecent punting on attempting automatic merge tracking. Being written in Perl, more advanced user interface features have been added - including interactive commit, a darcs-bourne system of guiding the developer through generating high quality change sets, and integration with over 13 different merge tools. These features are a boon for committing to a project using Subversion - You could say that SVK has moved the Subversion approach an evolutionary step forward, - and as a result, for those familiar with Subversion already, SVK offers a big advantage and few downsides for virtually every normal application of the Subversion client.