Seems like we use similar staging/pre-production routine in our company.
Our branching strategy is (we use Git):
- master contains releases, marked by tags (1.0.0, 1.0.1, ...)
- small bugfixes (1 commit) go directly onto master
- next versions go to branches like "devel-x.y.z"
- features and bigger fixes are branched off version branches ("feature-foo" on top of "devel-x.y.z"), so noone steps on others' toes
Project managers decide which fixes/features must go into next release, then we merge all selected branches into master and roll out the next release semi-automatically with Maven release plugin. We often do rebases to keep repository's history as linear as possible.
So, in short, we do both branch-by-release (because we support different versions of our products) and branch-by-feature/bugfix. There is no contradiction.
- we can reject or skip a release without touching master because we merge feature branches into release branches, not into master
- you see which release you are working on
Cons: none I see
- you don't step on other's toes: just merge when you're done
- you can track progress of each feature (we use Jira)
- you can track changes of each feature in the past (we name branches after Jira issues and leave them be after merging and also we prefix commit message with the issue name)
- gets messy if there are a lot of features going at the same time and you merge something in the middle. It is kinda because of the fact that you CAN have as many branches as you want - you're not forced to implement features sequentially. Maybe it is not really a contrary, but it wouldn't be possible otherwise
Since you mentioned it... SVN will not work for what I described. I have just a little experience with it, and it was pain. Speaking of branching, SVN branches are heavy and slow, and you cannot commit offline. I'm not a hater, it's just lacks many features I need. I recommend Git, but you might also look at Mercurial or other DVCS's.