Introduction

Subversion [1] can be used in many different ways which are described in Subversion's Red Book [2]. For example, Chapter 4 (Branching and Merging) of the Red Book describes how Subversion can be used to manage the releases of different versions of a collection of files.

When doing this, Subversion uses the following terminology:

trunk
This is a directory containing the collection of files. Any edits to the files should be performed on the files in this directory.
branches
This is a directory that has subdirectories. Each subdirectory contains a variant of the collection of files in the trunk directory. The branches directory is useful when people want to work on their changes in an independent fashion. Each person copies the files from the trunk directory to a separate subdirectory of the branches subdirectory. The Red Book describes some of the issues that are involved when you later wish to merge these branches. This is an area where Subversion acknowledges itself as being deficient.
tags
This is a directory that has subdirectories. Each subdirectory contains the collection of files that existed in the trunk directory at some point in time. When you want to release a new version of the collection of files, the files can be stored in a new subdirectory of the tags directory.

I have not yet explored the creation of branches. So the rest of these notes are about how the tags directory can be used.

Although Subversion's Red Book documents how to use the commands for creating tags (and branches), these commands can easily be misused: there are no safeguards built in to ensure that they are used appropriately.

So, in my view, Subversion works at too low a level. It does not force a work practice on me. These notes explain how I use combinations of these low level commands and how this has led me to produce scripts (that effectively work at a higher level).

Creating the initial tag

If you are wanting to do some work on a piece of software, there will already be a collection of files. It it likely to be in a tarball called:

First go to the appropriate place in your working copy of the Subversion repository, e.g.;

    cd $HOME/svn/projects

And then create a new directory for this project:

    mkdir $productname

And, in this directory, create empty subdirectories called branches and tags (although the branches subdirectory will not be used):

    cd $productname
    mkdir branches tags

And then unzip the tarball:

    tar zxf ~/$productname-$productversion.tar.gz

If this has been created 'properly', the untarring will produce a subdirectory called:

So change its name:

    mv $productname-$productversion trunk

This has created the initial collection of files.

We can transfer these files to Subversion repository using:

    cd ..
    svn add $productname
    svn -m "trunk contains original and branches and tags are empty" \
        commit $productname
    cd $productname

We can also make a copy of the original files in the tag directory:

    url=https://svn.oucs.ox.ac.uk/projects
    svn copy $url/$productname/trunk \
$url/$productname/tags/upstream-$productname-$productversion \
-m "original source"

We can then ensure that our working copy has a copy of this new version of the tags directory:

    svn update tags

Changing the files

If we want to change the collection of files, we move to the trunk directory and edit those files:

    cd trunk
    use favourite editor on the files in this directory

When we want to ensure that the Subversion repository has the latest version, we can do:

    cd ..
    svn --force -q add trunk
    svn -m "some appropriate message" commit trunk

Note: the first of these svn commands recursively descends the trunk subdirectory adding any new files to the working copy.

After the svn commit command, the files will be available at:

Releasing a new version

At some stage, when we are happy with the files in the trunk directory, we will want to release them as a new version. This can be done as follows.

First get to the right directory, e.g.:

    cd $HOME/svn/projects
    cd $productname

Then ensure that there is an up-to-date copy of the files of the trunk subdirectory in the Subversion repository:

    svn --force -q add trunk
    svn -m "some appropriate message" commit trunk

Then create a new tags subdirectory in the Subversion repository:

    svn copy $url/$productname/trunk \
             $url/$productname/tags/$version \
             -m "$version: some appropriate message"

This command assumes that $version has been set to some appropriate string. I use:

where $oxversion is increased by 1 at each release.

Finally, ensure that our working copy has the latest version of the tags subdirectory:

    svn update tags

These files are now available at:

Introducing new commands

I think it is tricky to get all the above commands right. So, in order to ensure that I do, I have created two shell scripts:

mkmrbsinit has contents similar to the following:

oxversion=1
productname=mrbs
productversion=1.2.3
url=https://svn.oucs.ox.ac.uk/projects
cd $HOME/svn/projects
mkdir $productname
cd $productname
mkdir branches tags
tar zxf ~/$productname-$productversion.tar.gz
mv $productname-$productversion trunk
cd ..
svn add $productname
svn -m "trunk contains original and branches and tags are empty" \
    commit $productname
cd $productname
svn copy $url/$productname/trunk \
   $url/$productname/tags/upstream-$productname-$productversion \
   -m "original source"
svn update tags

mkmrbstag has contents similar to the following:

oxversion=$1
shift
message="$*"
productname=mrbs
productversion=1.2.3
url=https://svn.oucs.ox.ac.uk/projects
version=$productversion-$oxversion.ox.1
cd $HOME/svn/projects
cd $productname
svn --force -q add trunk
svn -m "$message" commit trunk
svn copy $url/$productname/trunk \
    $url/$productname/tags/$version \
    -m "$version: $message"
svn update tags

I use them like this:

mkmrbsinit
cd $HOME/svn/projects/mrbs/trunk
patch --no-backup-if-mismatch <$HOME/mrbs/patches/2.patch
mkmrbstag 2 add changes made by sysdev to the previous system
patch --no-backup-if-mismatch <$HOME/mrbs/patches/3.patch
mkmrbstag 3 fix bug in SQL when repeat table is empty

Building from scratch

As you can see from the above, I have stored the changes from one version of the files to the next in a patch file. As shown above, this allows the latest version to be built by starting from the original source and then applying the patches in turn.

A patch file is produced by doing something like:

   diff -x '.svn' -Naur tags/$productversion-2.ox.1 \
                        tags/$productversion-3.ox.1 \
                              >$HOME/mrbs/patches/3.patch

References

  1. Subversion http://subversion.tigris.org/

  2. Subversion's Red Book http://svnbook.red-bean.com/

Comments

Those are my (BarryCornelius) thoughts about the use of tags in Subversion. Please add your comments about this below. Thanks.

OSSWatchWiki: ThoughtsAboutTagsInSubversion (last edited 2013-04-15 13:56:20 by localhost)

Creative Commons License
The content of this wiki is licensed under the Creative Commons Attribution-ShareAlike 2.0 England & Wales Licence.

OSS Watch is funded by the Joint Information Systems Committee (JISC) and is situated within the Research Technologies Service (RTS) of the University of Oxford.