I don't like merging. When I merge I've got to retest. This is especially difficult if the merging occurs a few days/weeks after the original change. Come to think of it, I don't really like branching, but that depends. Do I have to merge whenever I branch? Do I use branching for a specific discipline or is it a catch-all operation which gives me all sorts of capabilities in return for a spaghetti-like spider web of branches and merges? And what about all the labeling that goes with it? There must be a better way, a way to reduce branching, and merging, while increasing automation and reducing complexity. What is it?
Branching is a tool. It's a good tool. It's just overloaded. Developers and CM Managers use branching for long term parallel development; for short term parallel development; to collect files into a change (a.k.a. labeled branch) or into a feature (a.k.a. labeled branch); to promote files to the next level, from which they are promoted to the next level, and so on; to collect files for a release or to collect an incremental release; to check in code that would otherwise have to sit on their hard drives because they don't want to break the build.
This is too much. If I've got branches of all types, I've got merges of all types, and I've also got labels of all types. There are baseline labels, release labels, change and feature/fix labels, promotion level labels, and so forth. Some can be applied multiply to the same file, some are one of, others need a whole set of files before they can make sense.
So... enter the branching strategy document. It helps make sense out of labels. It helps make sense out of branching. It tells me what happens when a new release stream is to be opened up. I can use it to implement triggers to help support and enforce the strategy. The problem is, it takes too long to put together and review, unless your team has been through this a number of times already. And it's too complex, not for developers to understand, but for developers to use their precious time trying to read/review, understand and apply it, when there are other, more urgent things to do. And then it the strategy changes to deal with the unforeseen. It should all just be intuitive. But then, how would you ever design the right configuration specification? You could borrow it from your peer, I suppose.
Well, there is a better way. It requires understanding and modeling the process better. Don't use branches for everything.
More Branches, Less Branching?
Let's start out by saying you can actually reduce branching and merging by using more branches. I know that sounds contradictory. What I'm refering to is the "main" branch strategy. Many will advocate keeping a single main branch always. Then most development is done on the same branch, "main." Sounds easy. I don't agree, at least in most cases. I prefer the "step" model, where each major release development stream has its own main branch. So instead of one "main" branch, you have a rel-1 branch, a rel-2 branch, and so forth. Maybe you introduce a rel-1.5 branch at a later point.
Some say, this is not really different. Instead of starting a rel-2 branch and continuing support on the rel-1 branch, you transition the "main" to handle "rel-2" and create a new branch for "rel-1" support, if and when necessary. Then your developers just continue to work on "main." But when it comes down to it, each feature implementation or problem/issue/defect fix has to be targeted to a given release (stream), and possibly more than one. Rather than implementing release 1 changes on a release 1 branch, release 2 changes on a release 2 branch, and so forth, you look at the state of "main" and decide where to make the change. So for a release 2 change, if "main" is still tracking release 1, you need to use a release 2 branch. That branch is then merged into the "main" when it starts tracking release 2. When "main" starts tracking release 3, you're back to using a release 2 branch again. On top of that, there are all sorts of