GitFlow sucks, but we asked for it
GitFlow is not a technical choice. It is a cultural patch for organizations not ready for modern delivery.

Everyone loves to talk about Trunk-Based Development like it’s the universal silver bullet, until you actually need to ship something to production without dragging three unvalidated features along for the ride
Because yes, in the wonderful world of TBD, everything merges to main, we deploy twenty times a day, and everyone lives happily ever after thanks to a divine CI, flawless feature flags, and a team of developers who never break anything (still looking for those)
The real world problem
In real life, our life:
- Features and hotfixes go through the same UAT, validated by QA
- UAT only tests one version at a time (magic)
- Everything that enters UAT is potentially eligible for production
And here’s where it gets fun:
- A feature that’s done but not yet validated?
- An urgent hotfix to ship?
- Both need to go through UAT?
Congratulations: in TBD you ship both. Because everything is in main. Because there’s nothing else. Because it’s “modern”
And if you just wanted to deploy the hotfix without the feature? Well… too bad. TBD tells you that you should have had feature flags, iron discipline, and an E2E test pipeline sponsored by Google
The structural issue
The main problem is structural: if the feature and the hotfix share the same UAT pipeline, then a trunk-based model doesn’t let you ship one without the other
And as long as your QA needs to test a single version in a single environment before prod, the famous “one branch to rule them all” turns into:
“one branch to block everyone”

Hence the existence, surprise, of an integration branch (develop, staging, whatever). Not out of love for vintage GitFlow, but just to avoid shipping things to prod that nobody has validated
Why GitFlow exists
GitFlow compensates for organizational realities:
- QA is a separate team with a sign-off gate
- Releases happen weekly or monthly, not daily
- Production deployments are scary events
- Feature flags don’t exist or are half-baked
- Test coverage is too low to trust CI alone
- The codebase is a monolith with tight coupling
If your organization has these traits, trunk-based will fail. You’ll ship untested code. You’ll block hotfixes behind unvalidated features. You’ll break production
So you reach for GitFlow. Long-lived branches. A develop branch as a buffer. Release branches for stabilization. It works. It’s slow, but it works
The honest assessment
If you need GitFlow, ask why:
“We need a develop branch because QA tests before production” → Your QA process doesn’t support continuous delivery
“We need release branches for stabilization” → Your test coverage isn’t good enough to ship from main
“We can’t ship a hotfix without unrelated features” → You don’t have feature flags, or your UAT is a bottleneck
“Merges to main are risky” → Your deployment pipeline isn’t trustworthy
None of these are Git problems. They’re organization problems. GitFlow just makes them livable
The pragmatic take
I use GitFlow-light on projects where trunk-based would be suicidal. Not because I love it. Because the alternative is worse
When you have:
- Manual QA gates
- Weekly release cycles
- A single UAT environment
- Zero feature flag infrastructure
Then yes, a develop branch saves you from shipping garbage. A release branch lets you stabilize. Hotfix branches let you bypass the queue
Is it optimal? No. Does it work? Yes
Moving past GitFlow
GitFlow isn’t the goal. It’s a compromise while you fix the real problems
To kill GitFlow, you need:
- Feature flags so incomplete work can hide in main
- Test coverage so you trust CI to catch bugs
- Fast CI so you can run it on every commit
- Multiple UAT environments or parallel validation
- Smaller changes so merges stay simple
- Cultural buy-in that shipping small is better than shipping big
This takes months or years. It’s not a tooling change. It’s an organizational change
Until then, GitFlow keeps you shipping. Imperfect, but shipping
The bottom line
GitFlow sucks. The merge conflicts suck. The branch management sucks. The drift sucks
But we called GitFlow because we weren’t ready for the alternative. Don’t blame the patch for the wound
The problem isn’t Git. It’s that TBD assumes you have infrastructure and processes that most organizations simply don’t have. And until you do, that develop branch isn’t legacy thinking, it’s survival
Enjoyed this article? Share it!


