I've found that forcing all development on one branch forces the developers to be careful and to take in account all work. I've seen using a branch-per-feature, but I've always found issues with it:
- There's a lot of time with me playing mother hen. "Have you checked in your changes?", "Did you deliver your changes to trunk", "Have you been keeping your branch up to date with the changes in trunk". I rather do actual CM work instead of pestering developers.
- There's always the last minute delivery of code into trunk that causes merge issues. You think you're all set for the release, and suddenly an avalanche of work comes pouring into trunk two days before the release date.
- One idea of working on a branch is that it lets you pick and choose what you want to release. You can work on Feature A, Feature B, and Feature C, then decide if you want to release only one of those features, two of them, or all three of them! The problem is that these features are not independent of each other, and you can end up with as many as 50 or more branches all happening at once. The merge is never as smooth as in theory.
- Speaking of merges: Merging is the most rough and awful aspect of development. It is fraught with danger, and most developers are bad at it.
When you have all developers work on a single branch, you stop merging because there's nothing to merge. Developers are never unaware of someone's changes because it's in the branch. Developers will keep each other in line. Yes, you lose the ability to pick and choose features, but this is best done before the sprint.
So, I release from trunk? No. I release from a branch. There will come a time when you do most of the development work for the next release. Now, it's just bug fixes, and you only need one or two developers to swat bugs that are found in testing.
This is when you make your release branch. Most of your developers will continue working on trunk (or whatever you call it), and the bugs found in the release are fixed on the branch. When you make a release, you tag and release off the branch. If you need to make an intermediate release for bug fixes, you can use that same branch.
For example: We work on trunk for our 1.2 release. When we get the work to feature complete, I'll make a Release 1.2 branch. Now, all work on Release 1.2 is on the branch and work for my future release (probably 1.3) will continue on trunk. When we complete work on Release 1.2, we tag the branch and release from the branch.
Sooner or later, bugs found in Release 1.2 need to be fixed. Trunk is already 1.3. However, we'll just do the bug fixes on the 1.2 branch and do 1.2.1 from there.
There are times when I need a feature branch. For example, I have a feature that will take a while to work on, and be implemented in the future. In this case, I'll create a feature branch, and allow the developers to work on that. However, the developers must keep merging the parent branch into that feature branch to keep up with all of the changes. AND, when they have finished work on that feature, we merge the parent branch into the feature branch, test and make sure everything works, then merge the feature branch into the parent, and make sure the parent branch matches the feature branch.
So, to recap:
- We do all of our work on trunk together as a team.
- When we get to some magical mystery point (feature complete, or last sprint) we branch to the release branch.
- Work continues on trunk for some future release while the release branch is for the next release.
- When the release work is finished, we release and tag from the branch.
- We are not dogmatic. There are times when we will do feature branching. Maybe, if you have a very small development team, you might not branch on release. You simply release off of trunk, and if you need to make a patch, you branch at the release point and make a patch.
The main point is that we try to avoid branching when we don't have to, and keep merging to a minimum. I don't care how great a merging algorithm is, or how automated the merges, merging is a sloppy process and few people know how to do it correctly (or at least take the effort to do it correctly).
Creating a branch is like creating a child: Once you create one, you have to watch it and tend to it and make sure it stays out of trouble.