Reflections on SCM Branching strategies
Traditionally, in both CVS and Subversion, if you want to merge some changes from a branch back into the trunk, you need to specify the changes you want to apply. As in "I want to merge the changes made between revision 157 to and revision 189 on branch B back into the trunk". In Subversion 1.5 (which isn't out yet), you just say "Merge the changes from branch B back into the trunk". Subversion will figure out what has already been merged, and only apply the new stuff. This is very cool, and makes it a lot less disuasive to consider merging between branches. I discussed this in some detail in http://www.javaworld.com/javaworld/jw-01-2008/jw-01-svnmerging.html.
Anyway, this got me thinking about branching strategies. From what I've seen, there are two common strategies.
In the first approach, your development work goes in the main trunk. Branches are for releases or possibly for isolated changks of work. You create a new branch whenever you release a version into a new environment (UAT, production, whatever). Bug fixes made in the release branches can be merged back into the development trunk as required. This strategy has the great merit of simplicity.
In the second approach, your trunk contains the production-ready code. Branches are for milestone releases. This means you can have separate teams working on different releases, and theoretically work more efficiently in parallel, but this sounds a bit complicated to manage to me.
There are also other approaches, though. One interesting one is to adopt a much more agile stragegy. Create a new branch for each new user story/feature/whatever. Then merge it back into the trunk when it's ready to be integrated. You would also need branches for production releases as well, I suppose. This strategy would let individuals or small groups work on specific features/user stories, and merge them into the main trunk when they are ready.
One interesting question for this approach is how would you set up Continuous Integration with this approach. For example, you might have separate CI jobs hooked into each user story branch, as well as another job running against the main branch.