Git Branching Strategies: GitFlow vs Trunk-Based Development
Why Branching Strategy Matters
A branching strategy is a team agreement about how code flows from a developer's machine to production. Bad strategies cause: merge conflicts that take longer to resolve than the feature took to build, broken main branches, and deployments that bundle unrelated changes.
---
GitFlow
GitFlow uses two permanent branches (main and develop) and several types of short-lived branches.
main ──────────────────────────────────────── (released versions)
↑ ↑
develop ──────────────────────────────────── (integration branch)
↑ ↑
feature/login feature/search
Branch types:
main- production code only. Tagged with version numbers.develop- integration target for featuresfeature/*- one branch per feature, branched fromdeveloprelease/*- branched fromdevelopwhen ready to ship, merged to bothmainanddevelophotfix/*- branched frommain, merged to bothmainanddevelop
When GitFlow makes sense:
- Products with scheduled release cycles (mobile apps, packaged software)
- Multiple major versions supported simultaneously
- Regulated industries where releases require formal sign-off
- Large teams where features need to bake in develop for weeks
When it does not make sense:
- Web applications deploying multiple times per day
- Small teams (the overhead of release branches costs more than the structure helps)
- Continuous delivery pipelines where every merge to main should deploy
---
Trunk-Based Development
All developers commit to main (the "trunk") either directly or via very short-lived feature branches (less than 2 days).
main ─────────────────────────────────────── (always releasable)
↑ ↑ ↑ ↑ ↑
short-lived feature branches (1-2 days max)
How it handles incomplete features: feature flags. Code ships to production but is hidden behind a flag until ready.
When it makes sense:
- High-frequency deployment (multiple times per day)
- Strong CI/CD and automated test coverage
- Continuous delivery is the goal
- Teams that want to avoid the complexity of long-lived branches
Requirements: good test coverage (you cannot merge to main without it), feature flags for incomplete work, team discipline to keep branches short.
---
GitHub Flow
A simplified version of GitFlow without develop or release branches:
main ──────────────────────────────
↑ ↑
feature/login feature/search
(PR → review → merge → deploy)
- Branch from
main - Make changes, push, open a pull request
- Review, merge to
main - Deploy immediately
When it makes sense: web applications, SaaS products, teams deploying continuously. Simpler than GitFlow, less disciplined than trunk-based.
---
Choosing a Strategy
| Factor | Trunk-Based | GitHub Flow | GitFlow |
|---|---|---|---|
| Deploy frequency | Multiple/day | Multiple/week | Scheduled releases |
| Team size | Any | Small-medium | Medium-large |
| Test coverage needed | High | Medium | Medium |
| Feature flags | Yes | Optional | No |
| Release management | Simple | Simple | Complex |
---
Practical Transition: GitFlow → GitHub Flow
The most common transition for growing teams:
- Stop creating
release/*branches — deploy directly frommain - Merge features to
mainvia PRs (same as before) - Delete
developafter all teams are usingmainas the integration point - Add CI/CD to gate merges on passing tests
Practice branching in the ShellGenius Git Labs — the git-branch-merge and git-undo-changes challenges use real branching scenarios.