GitFlow sucks, but we asked for it

date: Nov 30 2025 4 min read

GitFlow is not a technical choice. It is a cultural patch for organizations not ready for modern delivery.

.git.devops.ci/cd.opinion

GitFlow branching

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”

Trunk-based development

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:

  1. Feature flags so incomplete work can hide in main
  2. Test coverage so you trust CI to catch bugs
  3. Fast CI so you can run it on every commit
  4. Multiple UAT environments or parallel validation
  5. Smaller changes so merges stay simple
  6. 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!

Sofiane Djerbi
Sofiane Djerbi

Cloud & Kubernetes Architect, FinOps Expert.

Comments