A product ships versioned software that customers install and run themselves. Three major versions are under support and security fixes must reach all of them. Which branching model fits?
Show the full answer Hide the answer
The deciding property
Whether you control when the running version changes. Everything else about branching follows from this single fact.
A service you operate has exactly one version in production, so there is nothing to maintain in parallel and long-lived branches are pure cost. Installed software you do not control has as many live versions as you support, and each one is a codebase that must receive security fixes without receiving features. That is a maintenance branch, and there is no way around it.
Why this option wins
- Fix forward on trunk, then cherry-pick backwards. The fix exists once in the line of development that will continue, and the backport is a deliberate, reviewable act per supported version.
- The number of branches equals the number of supported versions, which is a business decision with a published end-of-life date rather than a branching preference. That makes the cost visible and boundable.
- Each branch's scope is explicit: security and severe defects only. A branch with a written admission policy does not accumulate drift the way a general-purpose branch does.
Why the other options fail
- "Trunk-based with feature flags." Correct for a service you operate, and it cannot express "version 3.2 gets this fix and does not get the last eighteen months of features". Flags decouple release from deploy for code you run; they do nothing for binaries already installed on customer machines.
- "Git flow for every release." Adds
develop, release branches and hotfix branches to every change, including those for the current version, so the whole team pays permanent overhead for a problem that only the supported older versions have. It is the right shape applied at the wrong scope. - "One branch per customer deployment." The end state is N products with a common ancestor, no shared fix path, and a security patch that must be applied N times. This is how enterprise software estates become unmaintainable, and it usually starts as one reasonable accommodation.
What would flip the decision
| If this changes | Choose | Because |
|---|---|---|
| Support drops to one version at a time | Trunk-based | There is nothing to backport to |
| Customers accept automatic updates | Trunk-based with staged rollout | You regain control of the running version |
| Backports exceed roughly 30% of merges | Fewer supported versions | The branch count, not the model, is the cost |
| The fix cannot be cherry-picked because the code diverged | Shorten the support window | Divergence is the real signal that the branch has outlived its policy |
When this is over-engineering
For a team that ships a service and nothing else, all of this is overhead. The default should be trunk with branches measured in hours, and the maintenance-branch machinery introduced only when something genuinely runs outside your control - a mobile app with users on old versions, an SDK, an on-premises product, a public API version you promised to keep.