Decentralized version control with SVK

Posted by Jonathan

While working on my ruby-gems integration in the FreeBSD ports tree and discovering that it was more complicated that I’d hoped, I got distracted by a very good tutorial to SVK.

SVK is build in Perl around Subversion and Subversion is the successor of CVS. I used Subversion for my recent projects and heard about SVK before but never got the chance to see what’s the difference. SVK adds some nice features like star-merging, lightweight checkout copy management (no .svn or CVS directories), changeset signing and verification to Subversion while being faster and smaller in space.

These are nice good-to-have’s but the real power of SVK is its ability to mirror remote Subversion repositories. Actually it also can mirror CVS and perforce repositories, but I will concentrate on Subversion.

This means that a developer can mirror the main repository then disconnect this PC and work offline while using source control features like branches, tags, commits and backouts on his local computer. Eventually he will reconnect to the network, sync his mirror, merge the changes to his local copy/working directory. He can continue to work on his local version until he wants to commit the changes to the “real”, remote repository.

This is very useful if you do not always have a network connection to the main repository or when you want to develop independently of the main repository while still using source control and still sync with the main server. The second case is useful if you do not have a commit bit and locally develop a patch.

Hopefully the advantage is clear. you can get a glimpse on the workflow here.

I will give a very short intro, please read the mentioned tutorial for details.

After installing SVK (cd /usr/ports/devel/svk && make install clean on FreeBSD, fink install svk on OS X), I initialize the depot (repo in svn):

svk depotmap—init

Then I mirror and sync the remote Subversion repository:

svk mirror http://svn.example.com/project/trunk //project/trunk
svk sync //project/trunk

//project/trunk is the local repository that you can freely choose. Now I create a branch for local editing. If I wouldn’t do that and just checkout the trunk to a working copy, SVK will sync every commit I make to the local repository to the remote one. Often this is not what was intented. so create a local branch:

svk cp -m ‘local branch’ //project/trunk //project/local

Now I can checkout a working copy and work like I used with Subversion:

cd /tmp/work
svk co //project/local project
vim project/somefile
vim project/another
svk commit
...

Say in the meanwhile the project evolved and I want to sync with it in order to get the latest features and code:

svk sync //project/trunk

The local repository is now synced but my branch isn’t. So I merge the changes to my branch. This can get dirty with Subversion after several merges as you have to explicitly name the revision since you last merged from the trunk. With SVK and it’s star-merge this is easy:

svk smerge //project/trunk //project/local

The only thing left to do is merging the branch with the working copy through a svk up if you have one. Otherwise were officially synced!

To sync the repositories in the other way round, that means to commit your local changes to the remote server, just change the repositories-arguments to svk smerge.

So we merge our branch with our local trunk:

svk smerge //project/local //project/trunk

and we’re done as SVK syncs the local repository automatically with the remote one (in both ways).

This was only a small introduction, look for the svk push and pull commands to ease your work with SVK. But using the smerge command you have a better understanding of what is really going on.

Comments

Leave a response