Your Git workflow determines how your team collaborates, how quickly you can ship, and how painful your deployments are. We've seen teams using Gitflow when they ship daily (painful) and teams using trunk-based development with no tests (terrifying). The right workflow matches your team's size, release cadence, and testing maturity.
What We'll Cover
The Three Workflows at a Glance
| Aspect | Trunk-Based | GitHub Flow | Gitflow |
|---|---|---|---|
| Main idea | Everyone commits to main. Short-lived branches (hours) |
Feature branches → PR → merge to main → deploy |
develop + release + hotfix + feature branches |
| Deploy cadence | Multiple times per day | Multiple times per day to weekly | Weekly to monthly scheduled releases |
| Branch lifetime | Hours (ideally < 1 day) | 1-3 days typical | Days to weeks |
| Merge conflicts | Rare (branches are tiny) | Occasional | Frequent (long-lived branches diverge) |
| Requires | Strong CI, feature flags, high trust | CI, code review, branch protection | Release manager, disciplined branching |
| Best for | High-performing teams, SaaS, continuous deployment | Most teams — good default choice | Regulated releases, mobile apps, installed software |
Trunk-Based Development: The DORA Favourite
DORA research (State of DevOps reports) consistently shows trunk-based development correlating with high-performing teams. The practice is simple: everyone works off main, branches live for hours not days, and code ships to production as soon as it's merged.
How It Works in Practice
- Developer creates a branch:
git checkout -b add-payment-retry - Makes small, focused changes (under 200 lines). Takes 2-4 hours
- Opens PR, gets quick review (because it's small), merges to
main - CI runs tests, deploys to production automatically
- Feature flags control whether new code is visible to users
When Trunk-Based Works
- You have a solid CI/CD pipeline with fast tests (< 10 minutes)
- Your team has strong testing habits (you trust the tests)
- You use feature flags for incomplete work
- You deploy continuously (every merge → production)
- Your team is experienced enough to write small, safe changes
When It Doesn't
- Your tests are slow or unreliable (you can't trust that green means safe)
- You have junior-heavy teams without feature flag discipline
- You need multiple approval gates before deployment (compliance, QA sign-off)
- You ship mobile apps or installed software where "deploy to main" doesn't mean "deploy to users"
GitHub Flow: The Pragmatic Default
GitHub Flow is what most teams should start with. It's Gitflow minus the complexity.
The Entire Workflow
- Create a branch from
main - Make changes, commit, push
- Open a pull request
- Discuss and review
- Merge to
main - Deploy
That's it. No develop branch. No release branches. No hotfix branches. main is always deployable.
Why It Works for Most Teams
It's simple enough that everyone understands it on day one, flexible enough that you can add complexity later (feature flags, release tags) without changing the core workflow, and it maps naturally to GitHub/GitLab's PR-based review flow.
We use GitHub Flow for most of our client projects. The only additions we make: branch naming conventions and a PR template. That's enough structure without adding overhead.
Branch Naming Convention We Use
# Pattern: type/ticket-description
feature/PROJ-123-user-authentication
fix/PROJ-456-payment-timeout
refactor/PROJ-789-extract-email-service
chore/update-dependencies
docs/api-endpoint-reference
Gitflow: When You Actually Need It
Gitflow gets a lot of criticism. Some of it is deserved — it's complex, merge-heavy, and overkill for most SaaS applications. But it solves a real problem: managing parallel development with scheduled releases.
When Gitflow Is the Right Choice
- Mobile apps — You submit to the App Store weekly. You need a release branch to stabilize while features continue on
develop - Enterprise on-prem software — Customers run different versions. You need to support v2.3 and v2.4 simultaneously with different hotfix branches
- Regulated industries — Every release needs formal QA sign-off, compliance review, and audit trail. Release branches provide that structure
When Gitflow Is the Wrong Choice
- You deploy to production more than once a week (GitHub Flow is simpler)
- You have a small team (< 5 devs) — the overhead isn't justified
- You're building a SaaS product with continuous deployment
Decision Framework: Choosing Your Workflow
| Your Situation | Recommended Workflow | Why |
|---|---|---|
| SaaS, 2-5 devs, deploying weekly | GitHub Flow | Simple, low overhead, scales to daily deploys easily |
| SaaS, 10+ devs, deploying daily | GitHub Flow + feature flags | Feature flags decouple deployment from release, enabling trunk-based patterns |
| High-performing team, strong CI, continuous deployment | Trunk-based | Maximum velocity, minimal branch management |
| Mobile app, weekly App Store releases | Gitflow | Release branches let you stabilize while features continue |
| Enterprise product, multiple supported versions | Gitflow or release branches from main | You need parallel branch maintenance |
| Open source project, external contributors | GitHub Flow (fork-based) | Contributors fork, PR into main. Maintainers control merge |
Feature Flags: The Missing Piece
Feature flags are what make trunk-based development possible and what make GitHub Flow more powerful. They decouple deployment (code reaches production) from release (users see the feature).
// Simple feature flag implementation
const flags = {
newCheckoutFlow: {
enabled: process.env.NODE_ENV === 'production'
? ['staff@company.com'] // Only internal users in prod
: true, // Everyone in staging
},
darkMode: {
enabled: true, // Released to all users
},
};
// Usage
if (isEnabled('newCheckoutFlow', user)) {
return ;
}
return ;
Feature Flag Tools
| Tool | Cost | Best For |
|---|---|---|
| LaunchDarkly | From $10/month/seat | Enterprise features, targeting rules, experimentation. The category leader |
| Unleash | Free (open source) or hosted | Self-hosted option, good for privacy-conscious teams |
| ConfigCat | Free tier, then $39/month | Simple flags without the complexity. Good for small teams |
| Environment variables | Free | Good enough for 1-5 flags. Don't build a system around env vars for 50+ flags |
Branching Rules That Prevent Chaos
Regardless of which workflow you choose, these rules prevent the most common Git problems:
- Protect
main. No direct pushes. All changes via PR. This is non-negotiable - Require CI to pass before merge. Broken main is the single most disruptive event in a development workflow
- Delete branches after merge. Stale branches accumulate and confuse. Auto-delete on merge is a GitHub setting — turn it on
- Rebase feature branches on main daily. If your branch lives for 3 days, rebase daily. Small, frequent rebases beat one massive conflict at merge time
- Squash commits on merge (optional but recommended). "fix typo," "wip," "address review feedback" don't add value to the git history. One clean commit per PR makes
git logreadable
Frequently Asked Questions
Should we rebase or merge?
Rebase feature branches onto main to keep history clean. Merge main into feature branches if you want to preserve the exact commit history. For most teams, "squash and merge" PRs is the pragmatic choice — one commit per feature in the main branch history.
How do we handle long-running feature branches?
Avoid them. If a feature takes more than 3 days, split it into smaller PRs that can merge independently (using feature flags to hide incomplete work). If you must have a long-running branch, rebase on main daily and have other team members review intermediate PRs to catch drift early.
How many branches should we have at any time?
Roughly one active branch per developer. If your 5-person team has 15 active branches, something is wrong — either PRs aren't getting reviewed or branches are living too long. We set a soft limit: if your branch is older than 3 days, explain why in standup.
Can we switch workflows mid-project?
Yes, and it's common. Many teams start with Gitflow, realize they're deploying frequently enough that it's overhead, and migrate to GitHub Flow. The transition is straightforward: merge develop into main, delete develop, update CI to deploy from main. Do it on a quiet week.