I think I’ve made peace with how branching and tagging work in Subversion, and it makes sense. Here’s my thoughts… In subversion, your recommended directory structure is as follows:
In my previous article on subversion I said that this felt like a hack. Except it’s not - it’s genius. Here’s why.
To create a branch is Subversion you execute the following command:
With this command you’re asking the server to take the current revision at repo/trunk and copy it to the branches folder, in a subfolder named branchname. Now, copies in subversion are inexpensive, as only the diffs are stored, so this costs very little in terms of disk space. (Since there are no diffs from one revision to the next, in this particular case, this is very cheap indeed.)
You make a tag the exact same way
Now, here in Subversion-land, the concept to the end user is that all your files have been “copied” to this new area of the directory structure, which makes sense.
In CVS to move a file you either lose its historical changes (where you just check in a new file, with the same name, in a different location, losing changes), or its historical placement in the project (you SSH onto the CVS Server, manually move the file yourself, and hope nobody needs to build old versions of the product, because that file is no longer where the environment of the time expected it to be. Obvious disadvantages to both approaches.
In Subversion, moving files from location to location, while preserving historical location, is simple: There’s a
command. This way you don’t lose historical changes in the file. Since Subversion does Repository Wide Revisions, the historical placement of the file is preserved as well.
Tagging and branching in CVS seems, from an external user’s perspective, to be implemented with some form of metadata. Have you ever fought with a file in CVS that just wouldn’t update when you wanted it to, and then you remember to remove the sticky tags from the file or directory?
In Subversion you don’t have these problems with stickiness. On a tag and need to get to the next tag?
over there, then
. On a branch and need to get to the next revision of the branch?
All your files will be updated properly.
Why should it be implemented using folders, and not some sort of property-based scheme?
The disk space requirements for
are minimal. It’s nothing to be scared of, from an administrator’s perspective
A list of every branch and every tag in the project can easily be obtained - connect via WebDAV or a browser and browse into branches/ and/or tags/. Subversion’s proplist feature only works on the current revision.
As a sidenote, this is hard in CVS too - you usually end up keeping your own list of the branches and tags in your CVS repository, or have that one CVS guru who knows how to parse CVSROOT/tag-info, and everybody asks him stuff
- Properties require inhouse conventions being followed every time a tag or branch is created (although this could be worked around by building a svn tag command which sets a particular proplist item internally)
- How do you update (or switch) to a particular branch, then get “up” to the latest, so you can commit, without merging in the changes that have happened since? Good luck with that.
In summary: metadata works for relatively small things, but seems to fall apart for keeping track of branch and tag information. For proof of that just look at some of the weird commands and things you have to do in CVS when working with branches and tags. A folder structure, like that recommended by the Subversion team, while seemingly dumb at first glance, reveals its power after the first or second time you try to tag or branch in Subversion. Seeing it in action converted this non-believer.