Branching is a coping mechanism.
There is a lot of branching and release-time cherry-picking of features in the commercial software world. It seems to alleviate some pain and make the process more manageable, but I fear this is at too great a cost. Many development groups branch due to dysfunction.
Note that I am not talking about open source projects. I'm specifically speaking about commercial projects where programming talent is not free. I'm also not talking down distributed version control, where every checkout is really a separate branch. I am concerned more about use of branches for the wrong reasons and at a high cost.
Often branching is used to put off integration. This is a losing game. After so many changes to the trunk a branch will no longer slide seamlessly into the release stream. We can work around that problem (itself a work-around) if we merge forward all branches periodically so that they track the trunk more closely. This activity is time spent on features that may not be released this week or even next. Or maybe ever.
Branching can seem like a handy way to create flexibility for product team, as they can de-/re-prioritize as they please up until the last minute . This would follow the lean principle of deferring decisions to the latest responsible minute, if it were not for the word "responsible". They've already spent the money to have the features implemented by the time they decide not to release the feature. Wouldn't it have been more responsible to only spend developer time and effort on things they definitely need to deliver?
In several businesses, the branches are a vote of no-confidence in the development team. If a team regularly accepts more work than it can complete, it makes sense to keep the work separated until it really completes.This is clearly a failing both in planning and execution. Better to only assign work that is completable in a reasonable time, and to build with techniques like TDD that give a better sense of real completion.
In some cases, branching is required because the QA team is so backlogged that it may be weeks or months before they will have the opportunity to test the work that has been done. In this case, the answer is probably not to make an even larger backlog for the QA team. Unfinished work is waste. There is little reason for piling waste up on top of waste.
The underlying problem is that branches are a perishable inventory. More is not better. Each incomplete branch has to be maintained or eliminated. Tossing out the work is obvious waste. Continuing to maintain branches you're not releasing is also waste. Letting the code rot until it no longer can merge to the trunk is also waste.
If a team takes on small, immediately-releasable units of work, and completes them quickly then branching becomes unnecessary. If the work they do is the most important work they can do, then the flexibility for *not* release that work is unwelcome. If the team practices CI so that it always has something ready to release, then it is hard to find reasons to branch. If your agile team became truly agile, you could obviate most branching and free up a lot of manpower for other important tasks.
But imagine that you had to ask developers to make a new branch for their work and had to explain that it was because you didn't bother to break their task into reasonably-sized slices, because you want to de-prioritize it, that they would have to maintain the branches until someone gets around to testing, and that you don't really expect to be able to release it.
There are good reasons for branching, such as when making experimental changes you may very well want to discard. Alternatively if you examine your reasons for branching, you may not like what you learn.
If you find yourself in a dysfunctional branching hell, the answer is not to stop branching. The answer is to obviate branching by producing less, producing it better (with more and better testing), and integrating it sooner. Eliminate the need, then the practice.