svk in a nutshell

by gldnspud on November 29, 2006

For a while now, I've been using SVK to manage my use of Subversion repositories.

During the last span of time I used it, I don't think I was using it "properly", which is probably why I stopped using it for a while.

Now I'm in a comfortable groove with it though, so I thought I'd share my mini-HOWTO that I wrote for a friend a couple of months ago.

This HOWTO is geared toward Linux/BSD/OSX users, and assumes that you've already installed SVK for your platform.

Getting Started

  1. Make sure your $EDITOR environment variable is set appropriately.

  2. After installing SVK, run "svk depotmap" and save the file's default contents to initialize the depot.

  3. Create local and remote dirs in your depot:

    $ svk mkdir -m "" //l
    $ svk mkdir -m "" //r
  4. Mirror repositories. For example, mirroring Schevo's to //l/schevo:

    $ svk mirror //r/schevo
    $ svk sync -a

Checking out remote branches

At this point, you can check out any path in //r/schevo you wish, such as trunk as the checkout path schevo-trunk:

$ svk co //r/schevo/trunk schevo-trunk

Nearly all commands work just as they would using svn, although at times their more esoteric command-line options differ. Common operations:

svk up
svk add
svk rm
svk log
svk diff
svk stat

Of note is that svk commit on a checkout from a remote repository will immediately commit to the remote server. To work locally, which is where svk shines, see below.

Checkout directories are "attached" to a cache that svk keeps for performance. If you are going to delete a checkout directory, first change to it then detach it before removing it:

$ cd schevo-foo
$ svk co -d
$ cd ..
$ rm -rf schevo-foo

New remote branch, corresponding local branch

This example creates a new branch of trunk directly in the repository.

  1. Create the branch remotely:

    $ svk cp //r/schevo/trunk //r/schevo/branches/header-move
  2. Copy the remote branch to a local branch:

    $ svk cp //r/schevo/branches/header-move //l/schevo-header-move
  3. Check out the local branch:

    $ svk co //l/schevo-header-move
  4. Perform changes, commit:

    $ cd schevo-header-move
    $ ...
    $ svk commit
  5. If working on a branch with others, periodically sync their work while inside the checkout dir:

    $ svk pull
  6. Commit your changes to the remote branch. Each local commit you made will correspond to one remote commit by default:

    $ svk push -C
    $ svk push

New local branch, conversion to remote branch

When you're on a good clip, you'll probably want to make new features on the fly or when you're disconnected. The ones you don't like you can discard. The ones you like can be converted to remote branches for co-development, review, and merge.

  1. Create the branch locally:

    $ svk cp //r/schevo/trunk //l/schevo-pyqt4
  2. Check out the branch:

    $ svk co //l/schevo-pyqt4
  3. Perform changes and commit:

    $ cd schevo-pyqt4
    $ ...
    $ svk commit
  4. Create remote branch:

    $ svk cp //r/schevo/trunk //r/schevo/branches/pyqt4
  5. Star-merge local branch to remote branch. Optionally, begin by using -C to do a check-only listing. Since it's a new branch, it is not strictly necessary but can be nice for your own quick review:

    $ svk smerge -C //l/schevo-pyqt4 //r/schevo/branches/pyqt4

    Now perform the merge. The -l switch uses your commit logs as the basis for a commit message that you will be allowed to edit. The merge will occur as one commit on the remote side:

    $ svk smerge -l //l/schevo-pyqt4 //r/schevo/branches/pyqt4
  6. Replace the local branch with a copy of the remote branch:

    $ svk rm -m "" //l/schevo-pyqt4
    $ svk cp -m "" //r/schevo/branches/pyqt4 //l/schevo-pyqt4
  7. Update your checkout directory, which should result in a no-op:

    $ svk up

After converting a local-only branch to a local copy of a remote branch, you can continue working in it as in the "New remote branch, corresponding local branch" section.

Local sandbox for combining multiple branches

When using a one-feature-per-local-branch workflow, it is helpful to see how several branches developed in tandem look like when combined into one. This simulates how "trunk" would operate after each branch was reviewed and merged.

  1. Copy the remote trunk to a local test branch:

    $ svk cp -m "" //r/schevo/trunk //l/schevotest
  2. Check out the local test branch:

    $ svk co //l/schevotest
    $ cd schevotest
  3. Merge any other branch, local or remote, whose lineage can be traced back to trunk:

    $ svk smerge -C //l/schevo-header-move //l/schevotest
    $ svk smerge -l //l/schevo-header-move //l/schevotest
    $ svk smerge -C //l/schevo-pyqt4 //l/schevotest
    $ svk smerge -l //l/schevo-pyqt4 //l/schevotest
  4. Update the local checkout:

    $ svk up

Do not use "svk push" in this area or you'll push these changes to the trunk!

To start over from trunk in the same local branch, just do this from within the test checkout dir:

$ svk rm -m "" //l/schevotest
$ svk cp -m "" //r/schevo/trunk //l/schevotest
$ svk up

Reviewing and merging a branch to trunk

  1. Copy trunk to local version:

    $ svk cp -m "" //r/schevo/trunk //l/schevomerge
  2. Verify the merge operation:

    $ svk smerge -C //r/schevo/branches/branchname //l/schevomerge
  3. Perform the merge. This is where you will want to use the raw commit log from the branch to craft the changelog-style commit message for the merge to trunk:

    $ svk smerge -l //r/schevo/branches/branchname //l/schevomerge
  4. Check out:

    $ svk co //l/schevomerge
  5. Run tests:

    $ cd schevomerge/Schevo
    $ python develop
    $ nosetests
    $ ...
  6. Review diffs:

    $ (cd back to top of checkout)
    $ svk diff
  7. Merge to remote trunk:

    $ svk push -C
    $ svk push
  8. Cleanup local and remote remnants of branch:

    $ svk co -d
    $ cd ..
    $ rm -rf schevomerge
    $ svk rm -m "" //l/schevomerge
    $ svk rm -m "merged" //r/schevo/branches/branchname

Note that merging can happen across several branches, as long as they share common ancestry. So, if you had trunk branching to branch-a and branch-b, and branch-a branched to branch-a1 and branch-a2, you could merge branch-a2 to either branch-a, branch-b, or trunk.


Tom February 7, 2007 at 9:43 pm

Great page! Finally, someone publishes some sensible use cases. Wish the svk book had something similar.

gldnspud March 2, 2007 at 11:48 am

Tom, thanks for the comments :) I wish svk was more supported with Python’s setuptools as far as adding proper revision numbers to end of version numbers for in-development packages, but alas, it is not. Lately though I’ve been finding a good cross between using svn for checkouts, and then using svk for easy branching and (the incredibly useful) star-merging.

Comments on this entry are closed.

Previous post:

Next post: