I’ve changed my mind. It now seems that it is much more sensible to develop on branches rather than on master or trunk. What am I on about?
Well software source control or version control systems. I tend to use two: subversion and git. Actually, I tend to use git whenever I can including when I have to use subversion. git svn is, in US terms, awesum. One debate I have had on and off is whether to:
- Do development on trunk and put releases in branches — OR
- Do development on branches, merge to trunk, and tag releases (or put them in their own branches).
I’ve previously done the former, but I’m rapidly shifting to the latter. My rather simple reasoning is that I want trunk/master to be, to all intents and purposes, a working copy of the latest software. i.e. the software that is in trunk/master passes its tests, builds and basically does what it says it should on the tin. The developing software is done on a branch and only merged back to trunk/master when it passes its tests. Thus the process is:
- Branch
- Develop & test
- Merge from trunk/master to the branch (i.e. pull any updates)
- Test, test, test
- Review code with buddy, senior dev, etc. (depending on your set-up)
- Merge back into trunk as a finished feature.
Even better, only work on code that is actually described in a ticket, bug, or on something like pivotal. That way you stay focussed and only spend time on developing features/fixing bugs that the ‘customer’ actually wants.
The only question then is what you do with releases? My initial guess is to tag them as a release on trunk/master. Then if you get a bug and have to maintain the old release then to branch at that point and maintain the release as its own ‘master’ release branch.

I mostly agree with you, however the solution you are moving to needs a bit more refinement. Between steps 2-3 and 5-6, i.e. when merging, how do you know that just after you merged and while you’re testing that there has been no change in the trunk? If you don’t come up with a way to synchronize merges you’ll end up chasing your tail trying to keep track of which fix is in what branch. So, I guess you may need to implement some kind of freeze-before-merge system.
If everyone develops in branches exclusively, this is easier as trunk will not be modified on a daily basis by any team… And working on tickets is a must so you keep track of the feature and its patch-set.
As for releases, I’d definitely tag the release on the trunk. Now if you are on release 2.5 and you get a bug on 2.1 that was fixed on 2.4, you need to backport the fix for customers using 2.1-2.3. Then you simply work on the “tag”. At least in SVN the tag IS a branch. So you check it out and fix it. Downside: you have to do this for 2.2 as well (all intermediate tags).
You raise some interesting points which I think are a feature of any non-locking version control system. You’re right, it does have to be handled carefully. I think that the main thing is to ensure that the main trunk is controlled by one or two people who can test the merges before the are updated to the trunk. Obviously, this relies on a good test suite.
The SVN tag==branch is probably a design flaw. Tags ought to be immutable, and so it shouldn’t really be able to checkout a tag, work on it and then update to that tag.
I’m still pondering whether ‘develop’ in branches is the right idea. On subversion, branches feel to heavyweight, whereas it seems really easy in git to develop in a branch and then quickly merge back in.
So on reflection, in subversion, we develop on trunk, but ensure that it always ‘works’ by using a post-commit hook, but in git I tend to develop on a branch.
Hi,
Why would you need a trunk/tags at all? Can’t we just say we start developing at version/v1.0. All bugs and issues can then be connected to the version where you want it fixed. Any large development can still be done in branches, but the goal is to deliver v1.0 anyway, so that’s where you commit. Then someday you install a customer version (which is of course v1.0), that’s when you create v1.1 (a tag of v1.0) and continue developing there. If you discover some bug or even a new feature that simply has to be included on the already installed version v1.0, then this can be done easily, and can be merged to v1.1 as well. This can be continued on and on. The only thing is that all developers need to know in which version to do the development.
Is there anything against this approach?
It’s really about breakage, or rather your commit breaking somebody else’s code. I like to commit often which is why I use Git (but any DVCS will do). In effect, I’m always developing on a branch. Personally, I like trunk/master to always pass all it’s tests, and this isn’t likely if non-feature-complete commits are going back to trunk/master.
However, there’s nothing intrinsically wrong with the approach you suggest.