Git Workflows Compared — Gitflow, Trunk-Based, and GitHub Flow 2026
Advertisement
Introduction
Why This Matters
The branching strategy your team uses shapes everything downstream: how long code sits unreviewed, how merge conflicts accumulate, how quickly bugs can be hotfixed, and how reliably you can deploy. Teams that mismatch their workflow to their release cadence end up with either chaotic main branches or months-long integration nightmares.
Choosing the right workflow is a force multiplier — the right choice makes CI/CD faster, deployments safer, and collaboration smoother.
Gitflow — Structured Releases with Long-Lived Branches
Gitflow uses two permanent branches (main and develop) plus three types of temporary branches (feature/, release/, hotfix/). It was designed for software with scheduled, versioned releases.
Branch structure:
main ──────────────────────────────────────► (production releases, tagged)
↑ merge release/1.0 ↑ merge hotfix/1.0.1
develop ──────────────────────────────────────► (integration branch)
↑ merge feature/auth ↑ merge feature/dashboardFeature development:
# Start from develop, not main
git checkout -b feature/user-auth develop
# Regular commits on the feature branch
git commit -m "feat: add JWT authentication"
git commit -m "feat: add refresh token logic"
git push origin feature/user-auth
# Open a pull request to develop, then after review:
git checkout develop
git merge --no-ff feature/user-auth
git push origin develop
git branch -d feature/user-authReleasing:
# Cut a release branch from develop
git checkout -b release/1.2.0 develop
# Only bugfixes and version bumps on this branch
npm version 1.2.0
git commit -am "chore: bump version to 1.2.0"
# Merge into main (production) and tag it
git checkout main
git merge --no-ff release/1.2.0
git tag -a v1.2.0 -m "Release version 1.2.0"
git push origin main --tags
# Back-merge into develop to keep it in sync
git checkout develop
git merge --no-ff release/1.2.0
git push origin develop
git branch -d release/1.2.0Hotfixing production:
git checkout -b hotfix/payment-bug main
git commit -m "fix: correct payment calculation rounding error"
# Merge to main (deploy immediately)
git checkout main
git merge --no-ff hotfix/payment-bug
git tag -a v1.2.1 -m "Hotfix 1.2.1"
git push origin main --tags
# Bring the fix into develop too
git checkout develop
git merge --no-ff hotfix/payment-bug
git push origin develop
git branch -d hotfix/payment-bugWhen to use Gitflow: Teams shipping mobile apps, desktop software, SaaS with multiple supported versions, or products with compliance-mandated release windows. Not recommended for teams deploying multiple times per day.
Trunk-Based Development — Speed and Continuous Deployment
In Trunk-Based Development (TBD), all developers commit directly to main (the "trunk") or use very short-lived branches (1–2 days maximum) before merging. CI runs on every commit and deployment is continuous.
# Create a short-lived branch (max 1-2 days)
git checkout -b feat/add-search-filter
# Small, focused commits
git commit -m "feat: add search filter component"
git push origin feat/add-search-filter
# Open PR immediately, merge the same day
# After merge, delete branch
git checkout main
git pull
git branch -d feat/add-search-filterFeature flags for incomplete work:
// Use flags to ship incomplete features safely
const isNewCheckoutEnabled = featureFlags.get('new-checkout-v2')
if (isNewCheckoutEnabled) {
return <NewCheckout />
}
return <LegacyCheckout />Feature flags let you merge unfinished code to main without exposing it to users. This keeps branches short-lived while decoupling deploy from release.
When to use TBD: Teams deploying multiple times per day, teams using continuous deployment pipelines, companies practicing DevOps at scale (Google, Meta, and Shopify use variants of this). Requires mature CI/CD and a culture of small commits.
GitHub Flow — Simple and Practical
GitHub Flow is a simplified model with one rule: main is always deployable. Every change goes through a pull request from a feature branch:
# 1. Create a branch from main
git checkout -b feature/dark-mode main
# 2. Develop with regular commits
git commit -m "feat: add dark mode toggle to settings"
git commit -m "feat: persist dark mode preference to localStorage"
git push origin feature/dark-mode
# 3. Open a PR — discuss, review, refine
# 4. Deploy to staging from the branch (optional)
# 5. Merge to main → auto-deploy to production
# 6. Delete the branch
git push origin --delete feature/dark-mode
git branch -d feature/dark-modeGitHub Flow removes the complexity of Gitflow (no develop branch, no release branches) while still enforcing code review via pull requests. It works best when you deploy frequently but do not need the rigidity of Gitflow.
When to use GitHub Flow: Web applications with frequent deployments, small-to-medium teams, open source projects on GitHub. Simpler than Gitflow, less rigorous than TBD.
Comparing the Three Workflows
| Dimension | Gitflow | Trunk-Based | GitHub Flow |
|---|---|---|---|
| Main always deployable | Only after release | Yes | Yes |
| Branch lifetime | Weeks–months | Hours–2 days | Days–1 week |
| Deployment frequency | Scheduled | Continuous | Frequent |
| Rollback mechanism | Previous tag | Feature flag off | Revert PR |
| Complexity | High | Low (needs discipline) | Low |
| Best for | Versioned software | High-velocity teams | Web SaaS |
Common Mistakes
- Using Gitflow for a web SaaS — If you deploy weekly or more, Gitflow adds overhead with no benefit. Switch to GitHub Flow or TBD.
- Long-lived feature branches in TBD — Branches lasting more than 2 days defeat the purpose of TBD and reintroduce merge conflict accumulation.
- Merging
developintomainwithout a release branch — This bypasses the QA stabilization phase that Gitflow's release branches provide. - No branch protection rules — All three workflows depend on
mainbeing stable. Always require PR reviews and CI passing before merging tomain. - Forgetting to back-merge hotfixes — In Gitflow, a hotfix merged to
mainwithout merging back todevelopcauses the fix to regress in the next release.
Best Practices
- Enforce branch protection: require at least one reviewer and green CI before any merge to
main. - Regardless of workflow, keep pull requests small — PRs under 400 lines get reviewed 2–3x faster than larger ones.
- Use conventional commits (
feat:,fix:,chore:) to auto-generate changelogs and drive semantic versioning. - Tag every production release with a semantic version so you can identify and roll back to any deployed state.
- In TBD and GitHub Flow, configure auto-deploy from
mainso deployment is a consequence of merging, not a separate manual step.
Key Takeaways
- Gitflow uses
main,develop,feature/,release/, andhotfix/branches — ideal for versioned, scheduled releases. - Trunk-Based Development keeps all branches alive for at most 1–2 days, relying on feature flags to ship incomplete work safely.
- GitHub Flow has one rule:
mainis always deployable, and all changes go through a pull request. - The correct workflow depends on release cadence: scheduled releases favor Gitflow, continuous deployment favors TBD or GitHub Flow.
- Feature flags are a key enabler of TBD — they decouple code deployment from feature release.
- In Gitflow, hotfixes must be merged back to both
mainanddevelopto prevent regressions in the next release. - All three workflows benefit from branch protection rules that require CI to pass and at least one reviewer to approve.
- Small, focused pull requests (under 400 lines) are reviewed faster and merge with fewer conflicts in any workflow.
Advertisement