Git Branching Strategies: A Practical Comparison
Choosing a branching strategy affects how fast your team ships, how stable your releases are, and how much overhead developers deal with daily. There's no universally correct answer — the right strategy depends on your team size, deployment frequency, and product maturity.
The Three Main Strategies
1. Trunk-Based Development
Everyone commits to a single branch (main or trunk) frequently — at least once per day. Short-lived feature branches (1–2 days max) are allowed, but merging is rapid.
main: A──B──C──D──E──F──G (deploys happen from here)
│
feature/x: C──D (merged in < 48 hours)
Core practices:
- Feature flags hide incomplete work from users
- Automated test suite runs on every commit
- CI/CD deploys every green commit to production (or staging)
- Code reviews happen fast (same day)
When to use:
- High-performing teams with strong automated testing
- SaaS products with continuous deployment
- Teams of 1–30 engineers
- When deployment frequency matters most (DORA metrics)
Real-world users: Google, Facebook, Netflix
# Trunk-based: simple workflow
git checkout main
git pull
# make changes
git add .
git commit -m "feat: add user export endpoint"
git push origin main
# Short-lived feature branch
git checkout -b feat/user-export
# work for 1-2 days
git push origin feat/user-export
# open PR, get review, merge same day
git checkout main && git pull
git branch -d feat/user-export
2. GitHub Flow
A simplified strategy: one main branch, feature branches for every change, merged via pull requests. No release branches.
main: ────A────────B────────C──── (always deployable)
│ │
feature1: A──x──x──(PR) │
feature2: B──x──(PR)
Steps:
- Branch from
mainwith a descriptive name - Make commits (branch lives until merged)
- Open a pull request
- Discuss, review, and iterate
- Deploy from the branch to staging/preview
- Merge to
mainand deploy
When to use:
- Web apps or APIs with continuous deployment
- Teams that deploy directly from main
- Open source projects (familiar to contributors)
- When you want a workflow that's simple to learn
# GitHub Flow
git checkout -b feat/oauth-login
# work, commit, push
git push -u origin feat/oauth-login
# open PR on GitHub/GitLab
# after review and CI pass:
# merge via PR UI
# deploy main
# Cleanup
git checkout main
git pull
git branch -d feat/oauth-login
git push origin --delete feat/oauth-login
3. Gitflow
A structured strategy with dedicated branches for features, releases, and hotfixes. Developed by Vincent Driessen in 2010.
main: ───────────────────────1.0.0──────────2.0.0──
│ │
release: ─────────────────────1.0-rc──merge── │
│
develop: ──A──B──C──D──E──F──G──────merge────H──I──J──
│ │
feature/x: A──x──x──(merge)│
feature/y: B──x──x──(merge)
Branches:
main— production releases only, taggeddevelop— integration branch, all features merge herefeature/*— individual features, branch from developrelease/*— release preparation, branch from develophotfix/*— urgent production fixes, branch from main
# Install gitflow tool
brew install git-flow-avh
# Initialize
git flow init
# Start a feature
git flow feature start user-authentication
# ... develop ...
git flow feature finish user-authentication # merges to develop
# Start a release
git flow release start 1.2.0
# bump versions, update changelog
git flow release finish 1.2.0 # merges to main and develop, tags main
# Start a hotfix
git flow hotfix start fix-payment-bug
# ... fix ...
git flow hotfix finish fix-payment-bug # merges to main and develop
When to use:
- Software with versioned releases (libraries, mobile apps, desktop apps)
- Teams that support multiple versions simultaneously
- Projects with scheduled release cycles
- When you need a clear audit trail of what went into each release
Strategy Comparison
| Aspect | Trunk-Based | GitHub Flow | Gitflow |
|---|---|---|---|
| Branches in flight | Near zero | Several | Many |
| Release cadence | Continuous | Continuous | Scheduled |
| Merge conflicts | Rare | Occasional | Common |
| Complexity | Low | Low | High |
| Feature flags needed | Yes | Sometimes | No |
| Multi-version support | No | No | Yes |
| Best for | SaaS/web apps | Web apps | Versioned software |
| Team size | Any | Small-medium | Medium-large |
Commit Message Conventions
Consistent commit messages improve git log readability and enable automated tooling (changelogs, semantic versioning).
Conventional Commits Format
<type>(<scope>): <subject>
[optional body]
[optional footer]
Types:
| Type | When to use |
|---|---|
feat |
New feature |
fix |
Bug fix |
docs |
Documentation only |
style |
Formatting, no logic change |
refactor |
Code restructure, no feature/fix |
perf |
Performance improvement |
test |
Adding or fixing tests |
chore |
Build, tooling, dependency updates |
ci |
CI configuration |
revert |
Revert a previous commit |
feat(auth): add OAuth2 login with Google
fix(api): handle null response from payment gateway
docs(readme): update setup instructions for Docker
chore(deps): upgrade React to 18.3.1
feat!: redesign user API (BREAKING CHANGE)
The ! suffix marks a breaking change. This integrates with semantic versioning: feat bumps minor, fix bumps patch, breaking changes bump major.
Branch Naming Conventions
# Feature branches
feat/user-authentication
feat/TICKET-123-add-export
# Bug fixes
fix/login-redirect-loop
fix/TICKET-456-null-pointer
# Releases
release/1.2.0
release/2026-Q2
# Hotfixes
hotfix/payment-timeout
hotfix/1.1.1
# Chores/infrastructure
chore/upgrade-dependencies
ci/add-integration-tests
Merge vs Rebase
# Merge: preserves full history, creates merge commit
git checkout main
git merge feature/oauth-login
# Rebase: linear history, rewrites commits
git checkout feature/oauth-login
git rebase main
git checkout main
git merge feature/oauth-login # fast-forward
# Squash merge: one commit per PR
git merge --squash feature/oauth-login
git commit -m "feat: add OAuth login"
Guidelines:
- Use merge for merging completed features to shared branches
- Use rebase to update a feature branch with latest main (before PR)
- Use squash when a PR has many fixup commits you don't want in history
- Never rebase shared branches (
main,develop)
→ Use the Git Memo to look up Git commands on demand.