Choosing the right Git branching strategy can make or break your team's productivity. The wrong choice leads to merge conflicts, delayed releases, and frustrated developers. This guide compares the three most popular strategies—GitFlow, GitHub Flow, and trunk-based development—helping you choose the right approach for your team.
Branching Strategy Overview
┌─────────────────────────────────────────────────────────────────────────┐
│ Branching Strategy Comparison │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ GITFLOW GITHUB FLOW TRUNK-BASED │
│ ───────────────────────────────────────────────────────────────────── │
│ │
│ main ─────●───────────── main ─────●─────── main ─────●───────── │
│ │ │ │ │
│ develop ──●──●──●──●──── ╱│╲ ╱│╲ │
│ │ │ ╱ │ ╲ ╱ │ ╲ │
│ feature ────● │ feat1 │ feat2 commit commit commit │
│ │ │ │ │
│ release ─────────● deploy deploy deploy │
│ │
│ Complexity: High Medium Low │
│ Release: Scheduled Continuous Continuous │
│ Team Size: Large Small-Medium Any (with discipline) │
│ │
└─────────────────────────────────────────────────────────────────────────┘
Strategy 1: GitFlow
GitFlow, created by Vincent Driessen in 2010, uses multiple long-lived branches to manage releases. It's designed for teams with scheduled release cycles.
Branch Structure
| Branch | Purpose | Lifetime |
|---|---|---|
main | Production code, tagged releases | Permanent |
develop | Integration branch for features | Permanent |
feature/* | New feature development | Days to weeks |
release/* | Release preparation | Days |
hotfix/* | Emergency production fixes | Hours to days |
GitFlow Workflow
┌─────────────────────────────────────────────────────────────────────────┐
│ GitFlow Branch Model │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ main ●───────────────────────●──────────────────●────────────── │
│ │ │ │ │
│ │ ┌──────────┘ ┌────────────┘ │
│ │ │ │ │
│ hotfix │ │ ●──●───────┘ │
│ │ │ │
│ release │ ●─────●─────────────────● │
│ │ ╱ │ │
│ develop ●────●──●──●──●────────────────●──●──●──●───────────────── │
│ │ │ │ │
│ feature ●────────● ●──●──● │
│ │
│ Legend: ● = commit/merge point │
│ │
└─────────────────────────────────────────────────────────────────────────┘
GitFlow Commands
# Initialize GitFlow (if using git-flow extension)
git flow init
# Start a feature
git checkout develop
git checkout -b feature/user-authentication
# Finish a feature (merge to develop)
git checkout develop
git merge --no-ff feature/user-authentication
git branch -d feature/user-authentication
# Start a release
git checkout develop
git checkout -b release/v1.2.0
# Finish a release (merge to main and develop)
git checkout main
git merge --no-ff release/v1.2.0
git tag -a v1.2.0 -m "Release version 1.2.0"
git checkout develop
git merge --no-ff release/v1.2.0
git branch -d release/v1.2.0
# Hotfix
git checkout main
git checkout -b hotfix/security-patch
# ... fix the issue
git checkout main
git merge --no-ff hotfix/security-patch
git tag -a v1.2.1 -m "Security patch"
git checkout develop
git merge --no-ff hotfix/security-patch
git branch -d hotfix/security-patch
When to Use GitFlow
Good for:
- Scheduled release cycles (monthly, quarterly)
- Teams needing formal QA periods
- Software with multiple supported versions
- Compliance requirements needing release documentation
- Teams already comfortable with Git
Not ideal for:
- Continuous deployment
- Small teams (< 5 developers)
- Rapid iteration environments
- Teams new to Git
Strategy 2: GitHub Flow
GitHub Flow is a simplified branching model designed for continuous deployment. Created by GitHub, it uses only main and feature branches.
Branch Structure
| Branch | Purpose | Lifetime |
|---|---|---|
main | Production-ready code | Permanent |
feature/* | All development work | Hours to days |
GitHub Flow Workflow
┌─────────────────────────────────────────────────────────────────────────┐
│ GitHub Flow Model │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ main ●────●────●────●────●────●────●────●────●────●─────────── │
│ │ │ │ │ │ │ │ │ │ │ │
│ │ ▼ │ ▼ │ ▼ │ ▼ │ ▼ │
│ deploy │ deploy │ deploy │ deploy │ deploy │ │
│ │ │ │ │ │ │
│ feature/ ●─────────┘ │ │ │ │
│ login │ │ │ │
│ │ │ │ │
│ feature/ ●─────────┘ │ │
│ dashboard │ │
│ │ │
│ feature/ ●───────────── │
│ api-v2 (in progress) │
│ │
│ Steps: 1. Branch → 2. Commit → 3. PR → 4. Review → 5. Merge → 6. Deploy │
│ │
└─────────────────────────────────────────────────────────────────────────┘
GitHub Flow Commands
# Create and switch to feature branch
git checkout main
git pull origin main
git checkout -b feature/add-user-dashboard
# Make changes and commit
git add .
git commit -m "feat(dashboard): add user statistics widget"
# Push branch and create PR
git push -u origin feature/add-user-dashboard
# Open PR on GitHub
# After PR approval and merge (on GitHub)
git checkout main
git pull origin main
git branch -d feature/add-user-dashboard
# Deploy happens automatically after merge to main
Pull Request Workflow
- Create branch from main
- Add commits with descriptive messages
- Open pull request describing changes
- Discuss and review with team
- Deploy from branch (optional, for testing)
- Merge after approval
- Deploy to production automatically
When to Use GitHub Flow
Good for:
- Continuous deployment
- Small to medium teams
- Web applications and SaaS
- Teams wanting simplicity
- Rapid iteration cycles
Not ideal for:
- Multiple supported versions
- Formal release processes
- Long feature development cycles
Strategy 3: Trunk-Based Development
Trunk-based development (TBD) is the most aggressive approach—all developers commit to a single main branch (the "trunk") with minimal or no branching.
Branch Structure
| Branch | Purpose | Lifetime |
|---|---|---|
main (trunk) | All development | Permanent |
release/* | Optional release branches | Days (if used) |
| Short-lived branches | Optional, < 1 day | Hours |
Trunk-Based Workflow
┌─────────────────────────────────────────────────────────────────────────┐
│ Trunk-Based Development │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ PURE TRUNK-BASED (no branches): │
│ │
│ main ●──●──●──●──●──●──●──●──●──●──●──●──●──●──●──●─────────── │
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │
│ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ │
│ deploy continuously or on every commit │
│ │
│ ───────────────────────────────────────────────────────────────────── │
│ │
│ SCALED TRUNK-BASED (short-lived branches): │
│ │
│ main ●──●──●──●──●──●──●──●──●──●──●──●─────────────────────── │
│ │ │ │ │ │ │
│ ● ● ● ● ● (branches live < 1 day) │
│ │
│ Key: All branches merge within 24 hours, CI runs on every commit │
│ │
└─────────────────────────────────────────────────────────────────────────┘
Trunk-Based Commands
# Pull latest, make change, push (no branch)
git checkout main
git pull origin main
# Make your change
vim src/feature.js
git add .
git commit -m "feat: add caching to API calls"
# Push directly to main
git push origin main
# --- OR with short-lived branch ---
git checkout -b quick-fix
# Make change
git add .
git commit -m "fix: resolve null pointer"
git push -u origin quick-fix
# Merge same day via PR
# After merge:
git checkout main
git pull
git branch -d quick-fix
Requirements for Trunk-Based
Trunk-based development requires:
- Excellent CI/CD: Tests must run fast and catch issues
- Feature flags: Hide incomplete work in production
- Small commits: Each commit should be deployable
- Pair programming: Replaces code review for speed
- Strong team discipline: Everyone must follow practices
Feature Flags Example
// Feature flag implementation
const features = {
newDashboard: process.env.FEATURE_NEW_DASHBOARD === 'true',
betaAPI: process.env.FEATURE_BETA_API === 'true',
};
// Usage in code
function renderDashboard() {
if (features.newDashboard) {
return <NewDashboard />;
}
return <LegacyDashboard />;
}
// Gradual rollout
const features = {
newDashboard: userId % 100 < 10, // 10% of users
};
When to Use Trunk-Based
Good for:
- High-performing teams with strong CI/CD
- Continuous deployment environments
- Teams practicing pair programming
- Organizations like Google, Facebook, Microsoft
Not ideal for:
- Teams without robust automated testing
- Open source with external contributors
- Teams unfamiliar with feature flags
- Compliance-heavy environments
Strategy Comparison
Decision Matrix
| Factor | GitFlow | GitHub Flow | Trunk-Based |
|---|---|---|---|
| Complexity | High | Low | Low |
| Release Frequency | Scheduled | Continuous | Continuous |
| Best Team Size | Large | Small-Medium | Any |
| Learning Curve | Steep | Gentle | Moderate |
| CI/CD Requirement | Optional | Important | Critical |
| Feature Flags | Optional | Helpful | Required |
| Merge Conflicts | Common | Occasional | Rare |
| Code Review | Pre-merge | Pre-merge | Often post-merge |
| Main Stability | Very stable | Stable | Must be stable |
| Hotfix Speed | Fast | Fastest | Fastest |
Choosing Your Strategy
┌─────────────────────────────────────────────────────────────────────────┐
│ Strategy Decision Tree │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ Do you deploy continuously? │
│ │ │
│ ├── NO → Do you have scheduled releases? │
│ │ │ │
│ │ ├── YES → GitFlow │
│ │ │ │
│ │ └── NO → GitHub Flow (aim for CD) │
│ │ │
│ └── YES → Is your team highly disciplined with excellent CI? │
│ │ │
│ ├── YES → Trunk-Based Development │
│ │ │
│ └── NO → GitHub Flow │
│ │
└─────────────────────────────────────────────────────────────────────────┘
Branch Protection Rules
Regardless of strategy, protect your main branch:
# GitHub branch protection recommendations
main:
required_pull_request_reviews:
required_approving_review_count: 1
dismiss_stale_reviews: true
required_status_checks:
strict: true
contexts:
- "ci/tests"
- "ci/lint"
enforce_admins: true
required_linear_history: true # For GitHub Flow/TBD
allow_force_pushes: false
allow_deletions: false
Migration Paths
GitFlow → GitHub Flow
- Prepare CI/CD for deploying from main
- Merge all active release branches
- Delete develop branch (merge to main first)
- Update branch protection rules
- Train team on simplified workflow
- Monitor for issues during transition
GitHub Flow → Trunk-Based
- Strengthen CI/CD pipeline (must be fast and reliable)
- Implement feature flag system
- Reduce PR review cycle time
- Start with short-lived branches (< 1 day)
- Gradually move to direct commits
- Consider pair programming for quality
Best Practices (All Strategies)
Branch Naming Conventions
# Feature branches
feature/PROJ-123-add-user-auth
feature/add-dashboard-widget
# Bug fixes
bugfix/PROJ-456-null-pointer
fix/login-redirect
# Hotfixes
hotfix/security-patch
hotfix/PROJ-789-critical-bug
# Releases (GitFlow)
release/v1.2.0
release/2026-q1
Commit Message Format
Follow Conventional Commits:
feat(auth): add OAuth2 login support
fix(api): resolve rate limiting issue
docs(readme): update installation instructions
refactor(core): simplify data processing pipeline
test(user): add integration tests for signup
chore(deps): update dependencies to latest versions
Keep Branches Short-Lived
| Strategy | Maximum Branch Age |
|---|---|
| Trunk-Based | 1 day |
| GitHub Flow | 3-5 days |
| GitFlow Feature | 2 weeks |
| GitFlow Release | 1 week |
Related Guides
- Git & GitHub Complete Guide - Overview of all Git topics
- Pull Request Best Practices - Effective code review
- GitHub Actions CI/CD - Automation for any strategy
- How to Squash Git Commits - Clean commit history
Conclusion
The best branching strategy depends on your team's size, release cadence, and deployment practices:
- GitFlow: Large teams with scheduled releases
- GitHub Flow: Most teams doing continuous deployment
- Trunk-Based: High-performing teams with excellent CI/CD
Start simple with GitHub Flow, and only add complexity (GitFlow) or remove it (trunk-based) based on specific needs. Whatever strategy you choose, consistency across the team matters more than the specific approach.
For more Git guidance, see our complete Git & GitHub Guide.