More Thoughts on Feature Branching vs Trunk Based Development

Recent posts by Dave Farley and Jim Kinsey, and the release of the Accelerate book by Forsgren et al appear to be bringing dysfunctional development practices firmly into the spotlight once again, most specifically the practice of combining feature branching and automated builds, while calling it “continuous integration". I have already written my own opinion piece on the practice. In summary, I hate it - in a modern, collocated team it is wasteful, suppresses fast feedback, and completely undermines the advantages of powerful teamwork enabled by continuous integration. It harks back to a software dark age that I honestly thought our industry had finally left behind. It really is Continuing Isolation.

But perhaps the most damning piece of research about Feature Branching that has come out in recent years is best summarised by Dave Farley:
If you are not merging your changes to Trunk at least daily, [the research] predicts that your outcomes are more closely aligned with “Lower Performing Teams”.
So that’s it. Some limited edge cases aside, if you are not continually integrating to a common trunk at least daily, you are choosing to be a low performer. It is now a conscious choice based on hard data. Who actually wants to be a low performer?

Well, it would appear a significant number of companies and teams do. From my experience, heavyweight feature branching practices are rife, even when totally inappropriate.

Which, for me, raises the much deeper question. Why would otherwise perfectly sane, competent, conscientious people deliberately choose to be "lower performing”? And perhaps more telling, why would they choose to be lower performing and passionately defend the practices shown to be causing it? I believe Jez Humble (co-author of ‘Accelerate’) hits the nail squarely on the head here:

(The whole Twitter thread is worth a read, with some interesting insights)

In short (and kind of inevitably, in my not very humble opinion), it’s culture. That amorphous, difficult to define, "emergent property of interactions over time” (thanks due to Dave Snowden for the definition). So basically your team/company/personal decisions have been shaped by valuing certain narratives and interactions over others - perceived convention, fitting in & peer pressure, pressure from performance reviews, painful failures, habit, and so on. I cannot emphasise enough that culture is THE most pervasive, entrenched barrier to team improvement. Hence the apparent conflict between a declared wish to improve, yet defending dysfunctional practices. Yet it is also the most difficult to change precisely because it is emergent, and because going against local cultural norms is damned scary.

Jez correctly points out a key difference between feature branch development, and trunk based development. Feature branch based flows are optimised for individual developers. They can shut themselves away, with minimal collaboration, and eventually, magically conjure something at the end that may or may not work. It actively encourages solo, "hero programmer" behaviours and hence culture. Adding automated integration patterns to this (note, this is categorically not "continuous integration") will not help performance much because of the integrate-late, test-late nature of the flow.

"Trunk Based Development", with an entire team working on a single branch, encourages an entirely different kind of approach and behaviour; it is about team collaboration and communication. It has to - without these skills, quite simply, it will not work. Period. It requires a team. A real, functioning team, and not just a group of individuals.

As such, feature branching tends to be symptomatic of a company culture of broken teamwork, and as a result, low performance.

So, given the difficulty in changing an embedded culture, and how scary this kind of change is, how can a team move from feature branching approaches like GitFlow, and successfully change to Trunk Based Development and continuous integration? Well, the good news is you have already taken an enormous step forward by recognising a need to change. Unsurprisingly, the next step is to carry out a health-check on the team.

How do you recognise a healthy team? A useful starting point for assessing team health is the excellent Lencioni’s 5 Dysfunctions of a Team, which suggests that a healthy, functioning team has these traits. Each relies on the previous.
  • Trust. A willingness to be vulnerable within the team.
  • Constructive conflict. It’s OK to disagree and discuss. It is OK to have “constructive, passionate debate”.
  • Commitment. All team members buy-in to joint decisions.
  • Accountability. Team members call others out on counterproductive behaviour.
  • Attention to results. Team success first, over and above personal success and ego.
Having successfully installed Trunk Based Development and Continuous Integration practices into many teams (and with my fair share of failures over the years as well!), I can safely say that these provide a good guideline for success. At very least TBD/CI development needs teams aspiring to this baseline, with a little help from an experienced agile technical coach.

That’s it for now. In the second instalment, I will go through some of the practices and tricks that make TBD/CI work for a team, and link them back to how the 5 Dysfunctions undermine the chances of success.