Git Branching: Trunk-Based vs GitFlow vs GitHub Flow
Choosing a branching strategy shapes how your team collaborates, ships features, and recovers from production incidents. The wrong model creates merge hell; the right one accelerates delivery. This guide covers every mainstream strategy, when each shines, and how to pick one for your team.
Why Branching Strategy Matters#
A branching model defines the contract between developers: which branches exist, how long they live, and what gates a change must pass before reaching production. The strategy you choose directly impacts:
- Merge frequency and conflict rate — Long-lived branches diverge. Short-lived branches stay close to trunk.
- Release cadence — Some models assume scheduled releases; others enable continuous deployment.
- CI/CD pipeline design — Branch topology determines which commits trigger builds, tests, and deployments.
- Rollback and hotfix speed — The path from "bug discovered" to "fix deployed" varies dramatically across models.
Trunk-Based Development#
Trunk-based development (TBD) is the simplest model: everyone commits to a single branch (main/trunk), either directly or via very short-lived feature branches that merge within hours, not days.
How It Works#
main ──●──●──●──●──●──●──●──●── (production)
\ / \ /
fb-1 fb-2 (hours, not days)
- Feature branches live for less than one day.
- Every merge to trunk triggers the full CI pipeline.
- Broken trunk blocks the entire team, enforcing collective ownership.
- Releases are cut from trunk using tags or release branches that receive zero new features.
When to Use TBD#
- Teams practicing continuous deployment.
- Codebases with strong test coverage and fast CI (under 10 minutes).
- Organizations that use feature flags to decouple deployment from release.
Tradeoffs#
TBD demands engineering maturity. Without comprehensive tests, a broken trunk halts everyone. Without feature flags, half-finished work leaks into production.
GitFlow#
GitFlow, introduced by Vincent Driessen in 2010, uses long-lived branches to manage parallel development and scheduled releases.
Branch Structure#
main ────────────────●───────────●──── (production tags)
/ \ / \
develop ──●──●──●──● ●──●──● ●── (integration)
\ / \ / |
fb-1 fb-2 hotfix
- main — Always reflects production. Tagged with version numbers.
- develop — Integration branch where features merge.
- feature/ — Branch from develop, merge back to develop.
- release/ — Branch from develop when a release is planned. Only bug fixes allowed. Merges into both main and develop.
- hotfix/ — Branch from main for urgent fixes. Merges into both main and develop.
When to Use GitFlow#
- Products with scheduled release cycles (mobile apps, enterprise software).
- Teams that need to support multiple versions simultaneously.
- Organizations where a QA phase gates every release.
Tradeoffs#
GitFlow introduces ceremony. Merge conflicts accumulate on long-lived feature branches. The model is poorly suited to continuous deployment because develop and main frequently diverge.
GitHub Flow#
GitHub Flow strips GitFlow down to its essence: one long-lived branch (main) and short-lived feature branches that merge via pull requests.
How It Works#
- Branch from main.
- Commit and push regularly.
- Open a pull request for code review.
- Merge to main after approval and passing CI.
- Deploy main to production.
When to Use GitHub Flow#
- Web applications with continuous deployment.
- Small to mid-size teams that ship multiple times per day.
- Projects where every merge to main is deployable.
Tradeoffs#
GitHub Flow assumes main is always deployable. If your CI is slow or flaky, broken code reaches production. It also lacks a built-in mechanism for staging a release candidate across multiple features.
GitLab Flow#
GitLab Flow extends GitHub Flow by adding environment branches (e.g., staging, production) or release branches. Changes flow downstream: main to staging to production. This gives teams a pull-request-driven workflow with explicit promotion gates.
Feature Flags vs. Feature Branches#
Feature branches isolate work in version control. Feature flags isolate work at runtime. They solve overlapping problems but are not interchangeable.
| Concern | Feature Branches | Feature Flags |
|---|---|---|
| Isolation mechanism | Git branch | Runtime toggle |
| Merge cost | Grows with branch lifetime | Near zero (code merges to trunk) |
| Partial rollout | Not possible | Percentage rollout, user targeting |
| Rollback speed | Revert commit or redeploy | Toggle off in seconds |
| Technical debt | Branch divergence | Stale flags in codebase |
The highest-performing teams combine both: short-lived branches for code review plus feature flags for progressive delivery.
Release Branches#
Release branches freeze a set of features for stabilization. They appear in GitFlow and GitLab Flow but can be used with any model.
Best Practices#
- Name branches consistently:
release/2.4.0orrelease/2026-03-29. - Allow only bug fixes on release branches — never new features.
- Merge fixes back to the main integration branch (develop or main) to prevent regression.
- Automate cherry-pick validation with CI checks on the release branch.
- Delete release branches after the version reaches end-of-life.
Hotfix Flow#
A hotfix is a patch applied directly to the production-facing branch when a critical bug cannot wait for the next release.
Standard Hotfix Process#
- Branch from the production tag or main.
- Apply the minimal fix. Avoid bundling unrelated changes.
- Run the full test suite against the hotfix branch.
- Merge into main (or the release branch) and tag a new patch version.
- Back-merge or cherry-pick the fix into develop or trunk to prevent regression.
In trunk-based development, a hotfix is simply a fast-tracked PR to main with an expedited review.
Monorepo Branching#
Monorepos (Google, Meta, Microsoft) add complexity because a single branch contains many projects. Key considerations:
- Affected-path CI — Only run tests for packages that changed. Tools like Nx, Turborepo, and Bazel provide dependency-aware task scheduling.
- Ownership boundaries — Use CODEOWNERS files to enforce per-package review requirements.
- Branch protection per path — Some platforms (GitHub, GitLab) support path-based rules so that changes to
packages/billing/require billing-team approval. - Trunk-based is dominant — Most large monorepos use trunk-based development because long-lived branches across hundreds of packages create untenable merge conflicts.
CI/CD Impact by Strategy#
Your branching model determines your CI/CD topology:
| Strategy | Build trigger | Deploy trigger | Pipeline complexity |
|---|---|---|---|
| Trunk-based | Every trunk commit | Every trunk commit (CD) | Low |
| GitHub Flow | Every PR + main merge | Main merge | Low-medium |
| GitFlow | PR, develop merge, release branch | Release branch merge to main | High |
| GitLab Flow | PR, main merge, env promotion | Merge to environment branch | Medium |
Pipeline Design Tips#
- Run fast linting and unit tests on every PR. Reserve integration and E2E tests for the merge-to-main pipeline.
- Use merge queues (GitHub merge queue, GitLab merge trains) to serialize merges and prevent broken trunk.
- Tag deployable artifacts with the git SHA so any commit can be promoted to any environment.
- Keep CI under 10 minutes for trunk-based workflows. If your pipeline exceeds that, parallelize or split test suites.
Choosing the Right Strategy#
Use this decision tree:
- Do you deploy continuously? Yes → trunk-based development or GitHub Flow.
- Do you ship on a schedule with QA gates? Yes → GitFlow or GitLab Flow with release branches.
- Do you maintain multiple production versions? Yes → GitFlow with long-lived release branches.
- Is your repo a monorepo? Strongly prefer trunk-based with affected-path CI.
- Is your team smaller than 10 engineers? GitHub Flow is almost always sufficient.
Migration Tips#
Switching strategies mid-project is possible but requires planning:
- GitFlow to trunk-based — Gradually shorten feature branch lifetimes. Introduce feature flags for incomplete work. Merge develop into main and delete develop once the team is comfortable.
- No strategy to GitHub Flow — Enforce branch protection on main. Require PR reviews. Set up CI to run on every PR.
- Monorepo adoption — Introduce affected-path CI before migrating repositories. Without it, every PR triggers every test and CI becomes a bottleneck.
Key Takeaways#
- Branching strategies are not one-size-fits-all. Match the model to your release cadence, team size, and deployment infrastructure.
- Short-lived branches reduce merge pain regardless of which strategy you choose.
- Feature flags and branching strategies are complementary — use both.
- CI/CD pipeline design must align with your branch topology.
- Monorepos strongly favor trunk-based development with path-aware tooling.
The best branching strategy is the one your team actually follows. Start simple, measure cycle time and deployment frequency, and evolve the model as your needs change.
Article #301 on Codelit — Keep building, keep shipping.
Try these templates
GitHub-like CI/CD Pipeline
Continuous integration and deployment system with parallel jobs, artifact caching, and environment management.
9 componentsCI/CD Pipeline Architecture
End-to-end continuous integration and deployment with testing, security scanning, staging, and production rollout.
10 componentsContinue learning
Go deeper on infrastructure and delivery
As an Amazon Associate I earn from qualifying purchases. Codelit may receive a commission at no extra cost to you.
The DevOps Handbook
Gene Kim, Jez Humble · 2021
Case studies from Etsy, Amazon, and Target on rewiring deployment pipelines and org structure.
Observability Engineering
Charity Majors, Liz Fong-Jones · 2026
2026 rewrite covering OpenTelemetry rollout, telemetry cost control, and tracing LLM calls.
#11 in Software Design ToolsKubernetes Patterns
Bilgin Ibryam, Roland Huss · 2023
A catalogue of named patterns, sidecars to operators to init containers, with runnable manifests.
The Mom Test
Rob Fitzpatrick · 2013
136 pages of exact customer questions, and the flattering answers you should throw away.