As you know, I’m tortured by the pseudo requirement to layout your projects a certain way with svn. Some more thought (and chats with my svn friends) have led me to think that the tool doesn’t really force you to lay things out a certain way, since you could (and should I guess) checkout your projects at a lower level than the top.

eg
ft/
ft/cgi
ft/www

in svn would be

ft.repo/trunk/ft/
ft.repo/trunk/ft/cgi
ft.repo/trunk/ft/www

So you make the project called ft.repo, and make the svn directories under that of trunk, tags and branches. Then ft is my top level directory, and so I check it out with

svn checkout svn://…/ft.repo/trunk/ft ft

and this way my directories are arranged the way I want in my workspace, and tagging will not clutter up my workspace.

But I’m still not overly happy with this, and couldn’t be bothered moving my stuff around, so I decided to write a small shell script that associates the current revision with a tag that is saved into the file .tags in current directory (and committed). It doesn’t let you tag files, but certainly sub-directories are fine. I also merged in the svnignore program from a previous post. Suggestions for improvement are welcome, as this is the first version 🙂

This works by writing version=tag to the file .tags in the current directory.
It is not a "real tag"

Usage:
svn tag “version-1.0”
This will write a “tag” to the current directory as version-1.0

svn listtags
This will list the “tags” for the current directory.

Put this in your path ahead of the real svn (or rename this file)
File: $HOME/bin/svn

#!/bin/sh
# @author Cameron Gregory. http://www.bloke.com/

SVN=/usr/bin/svn
if [ "$1" == "ignore" ]; then
        shift;
        #Usage svn ingore [file|dir|pattern]+
        echo "Intercept ignore"

        if [ $# -eq 0 ]; then
                svn propget svn:ignore .
                exit 0;
        fi
        FILE="/tmp/svnignore.$$"
        $SVN propget svn:ignore . > $FILE
        i=0;
        while [ $i -lt $# ]; do
                echo "$1" >> $FILE
                shift
        done
        sort -u $FILE | grep -v "^$" > $FILE.2
        $SVN propset svn:ignore -F $FILE.2 .
        $SVN propget svn:ignore .
        /bin/rm -f $FILE $FILE.2
        exit 0;
fi
if [ "$1" == "tag" ]; then
        shift;
        echo "Intercept tag"

        TAG="$1"
        $SVN update .
        VER=`svnversion .`
        echo "$VER=$TAG" >> .tags
        $SVN add .tags  2> /dev/null
        $SVN commit .tags -m "saving tag: $TAG"
        tail -5 .tags
        exit 0;
fi
if [ "$1" == "listtags" ]; then
        echo "Intercept listtags"
        if [ -f .tags ]; then
                cat .tags
        else
                echo no tags
        fi
        exit 0;
fi

$SVN $*
exit $?

So if you want to checkout with a tag, then lookup the revision
and checkout using that. Hmm .. perhaps a little grep in the .tags file would be useful. Next time 🙂

Leave a Reply