Git Workflows: Git Flow, GitHub Flow, and Trunk-Based Development
A Git workflow strategy defines how your team collaborates using branches, pull requests, and releases. The right choice depends on your release cadence, team size, deployment infrastructure, and tolerance for process overhead. Picking the wrong workflow leads to merge hell, blocked deployments, and frustrated developers.
This guide compares the three dominant Git workflows and helps you choose the right one for your team.
Git Flow
Git Flow is a structured branching model designed for projects with scheduled releases. It uses multiple branch types to organize development.
Branch Structure
main
▲
│
release/v2.0
▲
│
develop ◄── feature/feature-x
▲
│
hotfix/urgent-fix- main — production-ready code, every commit is a release
- develop — integration branch for features
- feature/* — new features, branch from develop, merge back to develop
- release/* — prepare a release, branch from develop, merge to main and develop
- hotfix/* — urgent production fixes, branch from main, merge to main and develop
Commands
# Start a new feature
git checkout develop
git checkout -b feature/user-auth
# Work on feature, commit as usual
git add .
git commit -m "Add user authentication"
# Finish feature
git checkout develop
git merge --no-ff feature/user-auth
git branch -d feature/user-auth
# Start a release
git checkout develop
git checkout -b release/v2.0.0
# Bump version, fix last-minute bugs
# Finish release
git checkout main
git merge --no-ff release/v2.0.0
git tag -a v2.0.0 -m "Version 2.0.0"
git checkout develop
git merge --no-ff release/v2.0.0
git branch -d release/v2.0.0
# Hotfix
git checkout main
git checkout -b hotfix/security-fix
# Fix, commit
git checkout main
git merge --no-ff hotfix/security-fix
git tag -a v2.0.1 -m "Hotfix 2.0.1"
git checkout develop
git merge --no-ff hotfix/security-fix
git branch -d hotfix/security-fixWhen to Use Git Flow
| ✅ Good For | ❌ Not Ideal For |
|---|---|
| Scheduled releases (monthly/quarterly) | Continuous deployment |
| Multiple concurrent versions | Single-version SaaS products |
| Mobile apps (app store releases) | Small teams (too much overhead) |
| Large teams with clear roles | Teams new to Git |
GitHub Flow
GitHub Flow is a simpler, more streamlined workflow designed for continuous deployment. It has one main branch and short-lived feature branches.
Branch Structure
main ── feature-1 ── feature-2 ── hotfixProcess
# 1. Create a branch from main
git checkout main
git pull
git checkout -b feature/notification-system
# 2. Make changes, commit regularly
git add .
git commit -m "Add notification model"
git commit -m "Implement notification service"
# 3. Push and open a pull request
git push -u origin feature/notification-system
# Open PR on GitHub, request review
# 4. Review, discuss, update
git commit -m "Address review feedback"
git push
# 5. Merge to main and deploy
# GitHub merge button (squash, merge commit, or rebase)
git checkout main
git pull
# 6. Delete the feature branch
git branch -d feature/notification-system
git push origin --delete feature/notification-systemKey Rules
- Everything in
mainis deployable - Create feature branches for every change
- Open PRs early for visibility
- Deploy immediately after merging
- Keep branches short-lived (hours or days, not weeks)
When to Use GitHub Flow
| ✅ Good For | ❌ Not Ideal For |
|---|---|
| Continuous deployment | Multiple release versions |
| SaaS products | Need for release branches |
| Small to medium teams | Strict audit/compliance requirements |
| Startups and agile teams | Mobile apps with release cycles |
Trunk-Based Development
Trunk-based development (TBD) takes simplicity further. Developers work directly on main (the trunk) or on very short-lived branches (hours, not days).
Branch Structure
main ───────────────────────────────────────
│ ┌──────┐ ┌──────┐ ┌──────┐
└──┤Commit├──┤Commit├──┤Commit├─ ...
└──────┘ └──────┘ └──────┘Key Practices
- Small, frequent commits — every commit is a deployable unit
- Feature flags — hide incomplete features behind flags instead of using branches
- Short-lived branches — if you branch, merge back within hours
- Automated testing — CI must catch regressions immediately
// Feature flags enable trunk-based development
if (featureFlags.isEnabled('new-checkout')) {
// New checkout flow
--- else {
// Old checkout flow
---When to Use Trunk-Based Development
| ✅ Good For | ❌ Not Ideal For |
|---|---|
| CI/CD and DevOps maturity | Manual release processes |
| Microservices | Large monoliths |
| Experienced teams | Teams without strong testing culture |
| High deployment frequency | Regulatory environments needing approvals |
Hybrid Approaches
Not every team fits neatly into one of the three models. Many organizations adopt hybrid approaches:
Git Flow with Continuous Deployment: Use Git Flow’s branch structure but deploy every merge to main automatically, skipping the release branch phase for most changes. Reserve release branches for major version bumps.
GitHub Flow with Release Branches: Use GitHub Flow day-to-day but create release branches for compliance-driven releases that need audit trails. After the release, merge the release branch back into main and delete it.
Trunk-Based with Feature Branches for Large Changes: Use trunk-based for small changes and bug fixes, but allow longer-lived feature branches for significant rewrites that cannot be hidden behind feature flags.
The best approach is to start with the simplest model and add complexity only when you experience a specific pain point.
Comparison
| Aspect | Git Flow | GitHub Flow | Trunk-Based |
|---|---|---|---|
| Branch lifetime | Weeks to months | Days | Hours |
| Complexity | High | Low | Minimal |
| Release model | Scheduled | Continuous | Continuous |
| Merge conflicts | Frequent | Moderate | Rare (short branches) |
| CI requirements | Moderate | High | Very high |
| Best for | Large teams, releases | Teams, SaaS | DevOps teams |
| Learning curve | Steep | Shallow | Moderate |
Choosing the Right Workflow
function chooseWorkflow(team) {
if (team.releaseCycle === 'scheduled' || team.maintainsMultipleVersions) {
return 'Git Flow';
}
if (team.deploysContinuously && team.ciCdMaturity === 'high') {
if (team.experience === 'advanced' && team.testCoverage > 80) {
return 'Trunk-Based';
}
return 'GitHub Flow';
}
// Default for most teams
return 'GitHub Flow';
---Migration Path
- Start with GitHub Flow — it works for most teams
- Move to Git Flow if you need multiple release versions or have many concurrent developers
- Move to Trunk-Based when you have strong CI/CD, feature flags, and a mature testing culture
Common Pitfalls
Mixing workflows within a team creates confusion. If half the team uses GitHub Flow and the other half uses Git Flow, merge conflicts and miscommunication multiply. Pick one workflow and document it in your contributing guide.
Long-lived feature branches are the enemy of every workflow. Regardless of which strategy you choose, branches that live longer than a few days accumulate merge conflicts, drift from main, and become painful to integrate. The solution is to merge (or rebase) main into your feature branch daily and keep feature branches as short as the work allows.
Ignoring the human factor — the best workflow is the one your team will actually follow. A team that consistently follows GitHub Flow will outperform a team that inconsistently follows Git Flow. Invest in documentation, pair programming sessions, and automated tooling (like branch protection rules and CI checks) to reinforce whichever workflow you choose.
Conclusion
There is no single best workflow. Git Flow provides structure for scheduled releases. GitHub Flow simplifies continuous deployment. Trunk-Based maximizes deployment frequency. Consider your release cadence, team size, and DevOps maturity. Start simple (GitHub Flow), and adopt more structure only when you need it. The most important factor is consistent execution — a simple workflow everyone follows beats a complex workflow everyone ignores.
Related: Check our Advanced Git Commands guide.
FAQ
Q: What is the simplest Git workflow for a solo developer? A: GitHub Flow or even just working directly on main with occasional feature branches. Solo developers rarely need the overhead of Git Flow.
Q: Can I use trunk-based development without feature flags? A: Technically yes, but it is not recommended. Without feature flags, incomplete code cannot be merged to main without breaking production. Feature flags are the key enabler of trunk-based development.
Q: How do I migrate from Git Flow to GitHub Flow?
A: Start by eliminating release branches and deploying directly from main. Keep the develop branch initially if your team is not comfortable going straight to main, then phase it out gradually.
Q: What is the most common Git Flow mistake?
A: Letting develop and main diverge significantly. If you use Git Flow, merge main back into develop after every release to keep them synchronized.
Q: How do you handle urgent hotfixes in GitHub Flow? A: Create a feature branch from main, fix the issue, open a PR, get it reviewed, and merge. The key difference from Git Flow is that the fix goes through the same PR process as any other change.
Q: Which workflow is best for open source projects? A: Git Flow or a simplified variant. The release branch model works well for open source because it separates ongoing development from stable releases that users depend on.
For a comprehensive overview, read our article on Git Advanced Commands.