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 trunk 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, whip up some green smoothies and then use:
$ svk smerge //pairang/refactor //pairang/trunk
Now your trunk contains the code from refactor.