open atlas
↑ Back to track
Git, from zero to senior GIT · 06 · 05

Choosing a workflow

How to pick a branching workflow: weigh release model (continuous vs versioned), team size, CI maturity, feature-flag infrastructure, and repo structure. Web app + CD + small team to GitHub flow; large org to trunk-based; versioned library, desktop, or firmware to git-flow.

GIT Senior ◷ 18 min
Level
FoundationsJuniorMiddleSenior

You now know three workflows. The senior skill is not reciting them — it is walking into a team, reading their constraints, and saying “you should be running this one, and here is why,” then recognising the anti-pattern when someone proposes the wrong one. Most workflow pain in real companies is not a bad workflow executed poorly; it is a mismatched workflow executed faithfully — git-flow’s full ceremony bolted onto a web app that deploys hourly.

By the end of this lesson you will have a decision procedure: the handful of factors that actually determine the answer, the rules of thumb that map them to a workflow, and the anti-patterns that signal a mismatch before it costs you months.

Goal

After this lesson you can run a workflow-selection decision: identify the deciding factors (release model, team size, CI and flag maturity, repo structure), map them to git-flow, GitHub flow, or trunk-based development with defensible reasoning, and name the anti-patterns that flag a mismatch.

1

The release model is the dominant factor — decide it first. Before team size, before anything, ask: do you ship a continuously deployed service or a versioned product? A web app or SaaS that deploys whatever is on main, potentially many times a day, has no concept of “version 1.5.0 in the field” — there is only what is live. A library on npm, a desktop app, or device firmware ships discrete versioned releases, and often must support several versions in the field at once (a customer on 1.4 who cannot upgrade yet). This single distinction does most of the sorting: continuous deployment points at GitHub flow or trunk-based; versioned releases with multiple live versions are the one case that genuinely wants git-flow’s structure.

2

Then weigh four more factors that break the remaining ties. Once the release model narrows the field, these decide the rest:

  • Team size and velocity. A handful of engineers vs thousands. Scale is what pushes you from GitHub flow toward trunk-based, because merge-conflict cost grows super-linearly with concurrent branches.
  • CI maturity. Trunk-based and GitHub flow both lean entirely on automated tests as the safety net. Weak or flaky CI makes either dangerous and is a prerequisite to fix first.
  • Feature-flag infrastructure. Trunk-based is impossible without real flags; GitHub flow strongly wants them. No flag system caps how short your branches can be.
  • Repo structure. A monorepo with thousands of committers strongly favours trunk-based (long branches against a constantly-changing tree are unworkable); many small repos give you more freedom.

None of these overrides the release model, but together they choose between the continuous-deployment options.

3

Apply the rules of thumb. These map the factors to a default answer you can defend:

  1. Web app or service + continuous deployment + small-to-medium team → GitHub flow. One deployable main, short PR branches, flags for big work. This is the correct default for the large majority of product teams.
  2. Large org + high velocity + strong CI + real feature flags (often a monorepo) → trunk-based development. Push branch lifetime toward zero so integration cost stays flat at scale.
  3. Library, desktop, firmware, or any product with versioned releases and multiple supported versions → git-flow (or at least long-lived release branches). The develop/release/hotfix structure earns its weight when you must stabilise and patch discrete versions.

Treat these as defaults, not laws: a small team with excellent CI and flags can run trunk-based, and a large team without them should stay on GitHub flow.

Why this works

Notice GitHub flow and trunk-based are not really rivals — they are the same idea (one deployable line, short branches) at different scales, with trunk-based adding the flag-and-CI rigor that scale forces. The honest framing is a spectrum: start at GitHub flow, and as team size, commit rate, and CI maturity grow, you tighten branch lifetime and lean harder on flags until you are effectively doing trunk-based. Git-flow sits apart on a different axis entirely — it answers “how do I maintain several shipped versions at once,” a question continuously-deployed services never ask. That is why the release model is the first cut: it decides whether you are even on the git-flow axis.

4

Learn the anti-patterns — they are how you catch a mismatch early. Each is a faithful execution of the wrong choice:

  • Git-flow on a CD web app. Pure overhead: develop, release branches, and tagging ceremony for a product that has no versions. The tell: “we cut a release branch” for something that deploys hourly.
  • Long-lived feature branches anywhere. The universal anti-pattern. A branch open for weeks diverges and detonates at merge time, under any workflow. The fix is always: smaller increments, flags, faster integration.
  • No protected main. Any workflow on an unprotected main is a workflow in name only — one bad push breaks everyone. A protected branch (required CI + review before merge) is the non-negotiable floor under all three models.
  • Adopting trunk-based’s branch rule without its enablers. Committing unfinished, unflagged code to trunk with weak CI gives you a permanently broken trunk, not velocity.

Spotting these is the senior contribution: the workflow on the wiki may be fine, but its execution has drifted into one of these failure shapes.

Worked example

Three teams, three correct answers.

Team A — a 7-person SaaS startup, deploys to prod several times a day, decent CI, a basic LaunchDarkly setup. Release model: continuous. Scale: small. Answer: GitHub flow — protected main, short PR branches, flags for anything multi-day. Proposing git-flow here would be the classic anti-pattern; there is no version to stabilise.

Team B — 400 engineers in one monorepo, thousands of commits a day, mature CI, a first-class flag platform. Release model: continuous, but at a scale where day-long branches would constantly collide. Answer: trunk-based development — near-zero branch lifetime, everything behind flags, release branches only when a specific deployment must be pinned and patched.

Team C — a 12-person team shipping an installed desktop app, supporting versions 3.2, 3.3, and 3.4 in the field simultaneously. Release model: versioned, multiple live versions. Answer: git-flow (or at least durable release branches) — they genuinely need to patch 3.2 for a customer who cannot upgrade while 3.5 is in development on develop. The same ceremony that is overhead for Team A is load-bearing for Team C.

The lesson: the workflow did not change because of taste — it fell out of each team’s release model and scale.

Common mistake

The most expensive mistake is choosing a workflow by prestige instead of fit. “FAANG uses trunk-based, so we should too” ignores that you may lack the CI and flag infrastructure that makes trunk-based safe — you will get a broken trunk, not their velocity. Equally, “git-flow is the professional standard” (a belief left over from 2012) saddles a continuously-deployed web app with version ceremony it will never use. Choose for your release model, scale, and infrastructure — not for the logo of the company that popularised the workflow. The right workflow is the one whose preconditions you actually meet.

Check yourself
Quiz

A 10-person team ships an installed desktop app and must keep patching versions 4.1 and 4.2 in the field while building 4.3. Which workflow fits, and why?

Recap

Choosing a workflow is a decision, not a preference. Decide the release model first — continuous deployment vs versioned releases with multiple live versions — then let team size, CI maturity, feature-flag infrastructure, and monorepo vs many repos break the ties. The rules of thumb: web app + CD + small/medium team → GitHub flow; large, high-velocity, strong-CI, flag-equipped org → trunk-based development; versioned library, desktop, or firmware → git-flow. Guard against the anti-patterns — git-flow on a CD web app, long-lived branches anywhere, and the cardinal sin of an unprotected main. GitHub flow and trunk-based are one idea at two scales; git-flow answers a different question entirely. Match the workflow to the preconditions you actually meet, and the team’s git pain mostly disappears.

Practice

Start at the top. Tasks go easiest → hardest: recall a fact, apply it to a case, then a senior-level stretch. Open one, attempt it, then reveal.

recallapplystretch0 of 4 done

Something unclear?

Ask a question about this lesson. Questions are anonymous and go straight to the author to make the lesson better.

shortcuts expand
search
K
prev piece
k
next piece
j
cycle tier
t
this menu
?
sources2
expand
  1. 01
  2. 02

Trademarks belong to their respective owners. Editorial reference only.