Better Branching in Subversion
Mar 04
Miscellaneous branching, howto, Subversion No Comments
There are many perils involved with grafting your toes to your armpits. First of all, toes are meant to be connected to your feet – not placed in your armpits where it is both uncomfortable, and smelly. Aside from the olfactory stink, you also lose the benefit of being able to maintain good balance while walking. What might have seemed like a good idea at first is obviously a bad bio-engineering decision.
Grafting another arm onto your torso might have some merit as it isn’t just a sub-subsection of a given trunk (read: your leg); it’s actually a full trunk unto itself, which means you get more use out of it. About now you might be wondering what grafting of toes and arms has to do with tech. Besides the nifty bio-tech opportunities, it serves as a good metaphor for branching practices in Subversion.
I’m sure by now most of you have had an opportunity to create a branch and work with it. It’s a pretty simple affair; nothing more than a copy of one directory in subversion to another. For example:
svn copy trunk branches/branch-name
Subversion branches are great because they are cheap. Not cheap like the US Dollar; we’re talking practically free. Whether you are branching a deep tree or a shallow tree, it’s all the same (cheap) operation to subversion.
Branching Correctly and Why it Matters
The temptation with using branches is to only branch the directory that you are going to be working in instead of the complete trunk directory. While that might seem like a great idea, it really isn’t. By doing so, you make it much more difficult to merge safely. More importantly, you lose valuable contextual data.
Let’s say you want to work only in the /baz sub-directory of ../trunk/foo/bar (i.e., ../trunk/foo/bar/baz). If you branch only that directory, you have created two problems:
- /baz loses its context within the /trunk/foo/bar codebase. This means that it would not be immediately clear to someone looking at your branch where it was branched from. (note: there are means of figuring it out, but that’s not the point)
- if you find you need to make changes above /baz, you’ll have to create a new, independent branch.
This is where the value of cheap branching becomes clear. When you branch, subversion doesn’t actually copy any files, all it does is note a new directory in the branches directory and that it should contain the same data as the directory you branched from (effectively, it’s like a symlink in unix land). From there on out any change you make is stored against that branch, but only just changes. This is why branching is cheap; it doesn’t take up physical space until you make changes.
Perhaps you’re thinking, “I don’t care about how much space it takes up – I just don’t need to deal with the extra directories under trunk!” While that is a valid argument, keep in mind that what you gain in perceived simplicity, you lose in both flexibility and context.
Making Branches Work For You
We know it’s probably not a good idea to branch a sub-directory of the trunk; but, that still doesn’t help us when we only want that sub-directory. Have no fear; there is a simple solution: After branching off of the trunk directory, checkout the sub-directory you want from the branch.
As an example, say we want to create a branch of /trunk called “foo-widget” but we only want the /trunk/foo/bar sub-directory to work in. Here’s how you would do that:
svn copy https://domain.tld/svn/trunk https://domain.tld/svn/branches/foo-widget svn co https://domain.tld/svn/branches/foo-widget/foo/bar bar
This would first create a branch of the trunk directory called “foo-widget” and then checkout the sub-directory /foo/bar from the “foo-widget” branch into a local directory called ‘bar’. This allows maximum flexibility to switch gears and work on a different path in the branch should the need arise, while maintaining the simplicity you are looking for; and, more importantly, the desired consistent contextual path information for everyone who might look at this branch.