You're not currently signed in. Sign in.

Single-User svk

(It's recommended to read

Rafael Garcia-Suarez's article about single-user subversion first.)

svk is a decentralized version control system built on top of the Subversion libraries. The usage is pretty similar to Subversion.

This article describes the scenario for single-user usage of svk. Although svk is designed for distributed version controlling, It also simplifies some tasks in this scenario.

See also SingleUserSVKWithARemoteSVN, LocalSVKtoRemoteSVNHowto

Installing svk

Perl bindings of Subversion

In addition to the steps you needed for installing subversion, you should

add --with-swig-bindings=perl in the configure arguments.

Run make swig-pl-lib after make all. Go to the directory subversion/bindings/swig/perl (for subversion 1.0.x) or subversion/bindings/swig/perl/native (for subversion 1.1 and later)

and run:

$ perl Makefile.PL
# make all test install

Don't forget to run make install-swig-pl-lib after make install in the top level of the subversion distribution.

svk itself

Then it's pretty straightforward. Download the tarball and extract it. Run:

$ perl Makefile.PL
# make all test install

This should also install the depended modules from CPAN for you.

Mapping Repositories

svk provides a shorter name for you to access the repositories. So you need to define the mapping of real repository by:

$ svk depotmap

You should see a line like:

'': '/home/clkao/.svk/local'

That means the default repository (empty string) should map to the path /home/clkao/.svk/local.

Just close the editor and let svk create the repository for you.

The repository created is actually a Subversion repository. In other words, you could use any subversion commands with that repository.

Create additional repositories

You may want to have separate repositories for every project in order to keep a unique revision history.

First you need to relocate the default repository

$ svk depotmap --relocate // ~/svk-depots/default

Then create a new repository and map it to '/test-proj'

$ svk depotmap /test-proj/ ~/svk-depots/test-proj

Import now like this:

   
$ svk import /test-proj/trunk /path/to/test-proj 

Import Existing Project

Suppose I'm working on a project called pairang. Import the snapshot to the repository with:

$ svk import //pairang/trunk /tmp/pairang-20040103

The content of the files in /tmp/pairang-20040103 now resides in //pairang/trunk. The trunk part is for better repository layout management. This will be covered in branches and tags later.

Note that the depot spec //pairang/trunk refers to default repository (//) and

the path /pairang/trunk in it. So /another/path refers to the repository another and the path path. Of course you need to define which repository another should map to with svk depotmap.

Also the svk import command allows vendor branch creation. It automatically calculate the difference between the target directory in the repository and the path to import. So the command:

$ svk import //pairang/trunk /tmp/pairang-20040125

will incorporate the changes (including added and deleted files, but not renames) between

/tmp/pairang-20040125 and /tmp/pairang-20040103 (which is previously imported).

You could use svk log -v //pairang/trunk to see the log and changed path.

Checkout a Copy

Now for editing the content of the version-controlled files, you need to checkout things first:

$ svk checkout //pairang/trunk ~/pairang

~/pairang contains a copy of the latest version of the files from //pairang/trunk. You could now edit them. svk commit is used for committing changes to the repository. You'll need to use svk add and svk delete to add new files or delete versioned files. You might also want to use svk status and svk diff to preview the changes to be committed.

If you are unhappy with uncommitted changes you made, you could use svk revert to revert them.

For /committed/ changes that you want to revert, say revision 15:

$ svk merge -m 'revert r15' -r 15:14 //pairang/trunk //pairang/trunk

This means to generate the difference between revision 15 and 14 (hence the reversion of revision 15) from //pairang/trunk, and apply to //pairang/trunk directly. The second argument could be a depotpath, which behaves as above, or a path of a checkout copy, which will apply the changes to your uncomitted checkout copy.

Don't forget to use svk update to bring your checkout copy up-to-date after reverting a change in the repository directly.

Viewing Changes

Each commit generates a unique and increasing revision number. You could use -r REV or -r REV1:REV2 to refer to specific revisions in most commands.

svk update allows you to bring a certain directory to the specified revision.

svk log gives you the log messages and the changed path. You might also find -l N useful for showing the last N changes only.

svk diff shows the textual differences between two revisions, or between a certain revision and the checkout copy.

Branches and Tags

Branches and tags are effectively the same thing in svk. They are both cheap tree copies.

$ svk copy -m 'release 0.1' //pairang/trunk //pairang/pairang-0.1
$ svk copy -m 'branch for major refactor' //pairang/trunk //pairang/refactor
$ svk checkout //pairang/refactor ~/pairang-refactor

Now you have a branch called 'refactor', where you will do the heavy refactor to the existing code. While you might still do some minor fixes on trunk. From time to time you might want to merge them to the refactor branch. There are two ways doing so. Remember about reverting committed changes mentioned earlier? svk merge is the command for porting changes between branches. Just that you need to figure out the exact revision numbers for merging. svk smerge automatically tracks the merge history for you. It's very useful for mutually merged branches.

$ svk smerge -C //pairang/trunk //pairang/refactor

will incoporate all changes from trunk to the refactor branch. -C stands for check-only. replace it with -l to make the merge actually happen, as well as preload the relevant log messages to your editor before committing.

If conflicts are found, you won't be able to directly merge the changes to the repository. You need to use svk smerge //pairang/trunk ~/pairang-refactor and resolve the conflicts presented in your checkout copy.

When the refactor branch is ready for merging back to trunk, Use:

$ svk smerge //pairang/refactor //pairang/trunk

Now your trunk contains the code from refactor.