A Dummy's way of doing CVS tagging in Subversion

User story:

As a developer, I want to tag my code every so often, so that other people can get code that's stable, not bleeding edge.


This is the classic CVS usecase: Commit your code, and then tag it as 'Production' or 'Released' or whatever. In CVS, that entails touching every file. In Subversion, that's a constant-time operation you can do wholly on the server.

Let's say you want to copy your current /trunk to /tags/release-1.0 tag. Issue this sort of command

svn copy http://server.foo.com/Repo/trunk http://server.foo.com/Repo/tags/release-1.0


Great huh?

Thing is, that's great for leaving a trail of tags in your wake (Beta 1 -> Beta 'N', Release 1.0 -> 2600). What it's NOT good for is for the 'moving tag' usecase: I want to tag my code and then change that tag to point at a new revision of code. This is useful for when 2 modules are evolving towards a release:


\module1
\trunk
\common

\module2
\trunk
\common <-- grabs code from module1 via an svn:externals link


Typically, you want that external in module 2 to point at a /tag, not at /trunk (You can always have your external specify an explicit revision number, but that smells bad to me...it's a maintenance point)

An alternate solution, using a /tag:


\module1
\tags
\PRODUCTION
\trunk
\common

\module2
\trunk
\common <-- grabs code from module1 via an 'svn:externals' link


in the above, the svn:external points at /tags/PRODUCTION, instead of /trunk. Great...so what happens when you're on the team responsible for module1 and you want to publish the next baseline of code? You can do one of two things, based on your environment:

  1. Create a new tag and have everyone alter their svn:externals defintion

  2. Delete the old tag (using svn delete) and then create the same tag again with a new revision (svn copy, as shown above)



#1 is the 'opt in' solution where the consuming team makes a conscious choice to get the new code. This is better if they need to do integration work.

#2 is some great sleight-of-hand for when you want things to all share code invisibly, without resorting to pointing at /trunk.

Finally, the punchline: That #2 item above is so fall-off-the-log obvious, I couldn't even conceptualize it until this week. Made a 1 line change to my 'tagger' ruby script that wraps the svn command line and now I can overwrite my old PRODUCTION tag with a new baseline and all the downstream components see the change when they 'svn up'.

Popular posts from this blog

Monday Mope

RegisterForPrintAsyncNotifications

Review: The Southeast Christian Church Easter Pageant