Git Branching Strategies: Git Flow, GitHub Flow, Trunk-Based
Practice4 minInnovialabs editorial team
In short
Git Flow fits infrequent versioned releases, GitHub Flow fits web products deployed often via short branches, and trunk-based suits teams with strong automation and feature flags.
The short answer
A branching strategy is a team agreement on which branches exist, where they branch from and how code reaches a release. The three most common ones:
- Git Flow — many long-lived branches, versioned releases. Fits when releases are infrequent and several versions need support.
- GitHub Flow — one main branch plus short feature branches merged via pull requests. Fits most web projects.
- Trunk-based development — everyone merges small changes straight into the main branch, often. Fits teams with good tests, CI and feature flags.
The choice depends not on fashion but on release frequency, team size and automation maturity.
Git Flow
Two permanent branches: main (what is in production) and develop (integration). Plus supporting ones: feature/*, release/*, hotfix/*.
main ●──────────────●──────────●
\ / \ /
release \ ●──● \ /
\ / hotfix
develop ●──●──●──●──●──●
\ /
feature ●─●
Pros: a clear release process, convenient for maintaining several versions (mobile apps, boxed software, libraries).
Cons: many merges and conflicts, changes take a long time to reach production, hard to combine with continuous delivery.
GitHub Flow
One permanent branch, main, that is always deployable. All work is a short branch, a pull request, review, CI checks, merge, deploy.
main ●───●───────●───●───────●
\ / \ /
feature ●──● ●──●
Pros: easy to explain to a newcomer, a fast path to production, pull request review built into the process.
Cons: if branches live for weeks, conflicts come back; there is no separate place to prepare a release, so reliable CI is a must.
Trunk-based development
All developers merge into the main branch (the trunk) often — at least once a day. Branches, if any, live for hours rather than days.
main ●─●─●─●─●─●─●─●─●─●
\ / \ /
● ● (branches lasting a few hours)
Pros: minimal conflicts, code is integrated constantly, you can release at any moment.
Cons: requires discipline, good test coverage and fast CI. Without them the main branch breaks frequently.
Feature flags: how trunk-based handles unfinished work
The main question about trunk-based is how to merge a feature into main that is not finished yet. The answer is feature flags.
The new feature's code lands in the main branch but is switched on by a condition:
if (flags.isEnabled("new-checkout", user)) {
renderNewCheckout();
} else {
renderOldCheckout();
}
What this gives you:
- Deploy is decoupled from release. The code is already on the server, but users do not see it.
- Gradual rollout. Turn it on for the team first, then for a share of users, then for everyone.
- Fast rollback. Switching a flag off is simpler and faster than rolling back a deploy.
Flags must be removed after a full rollout, otherwise the code gets overgrown with branches nobody remembers.
Comparison
| Criterion | Git Flow | GitHub Flow | Trunk-based |
|---|---|---|---|
| Permanent branches | main, develop | main | main |
| Feature branch lifetime | days to weeks | days | hours |
| Release frequency | rare, versioned | frequent | very frequent |
| CI and test requirements | moderate | high | very high |
| Best for | mobile apps, libraries, multiple versions | most web projects | mature teams with continuous delivery |
How to choose
- Need to support several versions at once? Git Flow, or a simplified variant with release branches.
- A web product, deployed several times a week, small team? GitHub Flow.
- Strong CI, fast tests, willing to adopt feature flags? Trunk-based.
- Not sure? Start with GitHub Flow and keep branches short — it is a natural path towards trunk-based.
Common mistakes
- Picking Git Flow "because that is how it is done" for a site that deploys daily.
- Keeping a feature branch for a month and then spending a week on conflicts.
- Switching to trunk-based without automated tests.
- Leaving dozens of stale feature flags in the code.