Reading time: 3 – 4 minutes
As I have previously written, I dislike branch based development (especially when it involves subversion and long lived feature branches). Sometimes projects have multiple teams concurrently working in the same codebase, each on different release schedules. For example, team “Delta Force” will go live in a year, with some super top secret and amazing functionality. (Do not get me started on how bad an idea this usually is. I believe in short, frequent releases and rapid customer feedback). All the while, team “Alpha Squadron” is working on periodic releases into production every few weeks or months. Nothing from Delta can go live with Alpha’s releases. How do you enable these teams to cooperate? Some may suggest a long lived feature branch for Delta Force’s code. And then “just” merge the changes from Alpha down to Delta. I believe this is a Bad Idea.
But, if you’re forced into this scenario, at least explain to people the importance of frequently merging (i.e. on a daily basis). The longer you wait between merges, the greater the danger of increasing complexity and merge difficulties.
Rather than using a long lived branch, I suggest the following solution: Trunk Based Development. This means you do not create actual branches. Everyone is on the same trunk. As my colleague Paul Hammant phrases it, you Branch By Abstraction. My other colleague Martin Fowler calls this Feature Toggles. First, this enables refactoring, because everyone is working in one codebase. Second, as feature toggles become permanently turned on, you can remove them, and the conceptual divergence between the two “branches” drops. This is a Good Thing.
Once again, if you have a long lived branch, and even if you frequently merge, the divergence will grow as the not-reintegrated changes accumulate in the long lived branch. This divergence is RISK. It inhibits refactoring and encourages technical debt.
Prefer Trunk Based Development. It is not perfect, as there still is additional complexity in the codebase. But you can mitigate this with polymorphism instead of if conditionals, and have multiple continuous integration pipelines for all deployable feature toggle combinations.
By using Trunk based development, we make it easier to do the right thing. This is an example of the Boy Scout Rule. The Boy Scouts of America have a simple rule that we can apply to our profession. “Leave the campground cleaner than you found it.”
If we all checked-in our code a little cleaner than when we checked it out, the code simply could not rot. The cleanup doesn’t have to be something big. Change one variable name for the better, break up one function that’s a little too large, eliminate one small bit of duplication, clean up one if statement.
Long lived feature branches make this difficult, because any changes you make to one branch needs to be replicated, or you may have merge difficulties. This is especially a problem for a “long lived receiving” branch, which by it’s nature does not reintegrate its changes into the mainline. (Thus that branch is limited in what it can refactor).