Git Flow
Git Flow is a rigorous branching model introduced by Vincent Driessen in 2010. It defines a strict set of branch types and merge rules designed for projects with scheduled releases, versioned software, and the need to maintain multiple live versions simultaneously. Git Flow shines in enterprise software, desktop applications, mobile apps, and libraries — anywhere a release is a planned event, not a continuous stream.
The five branch types
Branch type | Pattern | Purpose | Merges into | Branches from |
|---|---|---|---|---|
Main |
| Always represents production-ready code. Every commit is a tagged release. | Never directly | Never (only receives merges) |
Develop |
| Integration branch. All features land here first. Represents the latest delivered development. | main (via release branch) | Never (only receives merges) |
Feature |
| New features or non-emergency fixes. Lives until merged to develop. | develop | develop |
Release |
| Prepare a release: bump version, final bug fixes. No new features. | main AND develop | develop |
Hotfix |
| Emergency production fix. Bypasses develop. | main AND develop | main |
Full branch diagram
Git Flow complete branch topology
main: ─── 1.0 ──────────────────────── 1.1 ──── 1.1.1 ───▶
↑ (tagged) ↑ (tagged) ↑
│ merge merge (hotfix)
│ │ │
develop: ─── ───┼──── A ─── B ──── C ────────┼────── D ─┼── E ──▶
│ ↑ ↑ │ ↑
│ (merged (merged │ (merged
│ feature/x) feature/y) release hotfix)
│ /1.1.0
feature/x: ───────┴─ fx1 ─ fx2 ─ fx3 ──────┘
feature/y: ─ fy1 ─ fy2 ─ fy3 ──────┘
release/1.1.0: ─ r1 ─ r2 ─┘
(version bump, release notes)
hotfix/1.1.1: ─ h1 ─┘
(emergency fix)Full release cycle walkthrough
Here is a complete walkthrough of a typical Git Flow release from feature development through hotfix.
Step 1: Start a feature
# Feature branches always start from develop git switch develop git pull origin develop git switch -c feature/dark-mode # ... develop the feature across many commits ... git add . git commit -m "feat: add dark mode toggle component" git commit -m "feat: persist dark mode preference in localStorage" git commit -m "test: add dark mode unit tests" # Merge back to develop (no fast-forward to preserve branch history) git switch develop git merge --no-ff feature/dark-mode -m "Merge feature/dark-mode into develop" git push origin develop git branch -d feature/dark-mode
Step 2: Create a release branch
# When develop has all the features for the next release, # branch off a release branch git switch develop git switch -c release/1.1.0 # On the release branch: only bug fixes, version bumps, documentation # NO new features! # Bump version number npm version minor # or edit package.json manually git add package.json package-lock.json git commit -m "chore: bump version to 1.1.0" # Fix a last-minute bug found during release testing git commit -m "fix: correct date formatting in export" git push origin release/1.1.0
Step 3: Finish the release (merge to main AND develop)
# Merge release branch into main git switch main git merge --no-ff release/1.1.0 -m "Merge release/1.1.0 into main" git tag -a v1.1.0 -m "Release 1.1.0" git push origin main git push origin v1.1.0 # IMPORTANT: also merge back into develop so fixes are not lost git switch develop git merge --no-ff release/1.1.0 -m "Merge release/1.1.0 back into develop" git push origin develop # Clean up the release branch git branch -d release/1.1.0 git push origin --delete release/1.1.0
Step 4: Apply a hotfix to production
# Critical bug found in production — hotfixes start from main git switch main git pull origin main git switch -c hotfix/1.1.1 # Fix the bug git commit -m "fix: resolve payment processing null pointer" # Bump patch version npm version patch git commit -m "chore: bump version to 1.1.1" # Merge into main AND develop git switch main git merge --no-ff hotfix/1.1.1 -m "Merge hotfix/1.1.1 into main" git tag -a v1.1.1 -m "Hotfix release 1.1.1" git push origin main git push origin v1.1.1 git switch develop git merge --no-ff hotfix/1.1.1 -m "Merge hotfix/1.1.1 into develop" git push origin develop # Clean up git branch -d hotfix/1.1.1 git push origin --delete hotfix/1.1.1
The git flow CLI tool
The git flow CLI automates many of the above steps, reducing the chance of missing a required merge. It is an optional extension — Git Flow works perfectly without it.
Using the git flow CLI tool
# Install (macOS) brew install git-flow-avh # Initialize Git Flow in a repo (one-time setup) git flow init # Branch name for production releases: [main] # Branch name for "next release" development: [develop] # Feature branch prefix: [feature/] # Release branch prefix: [release/] # Hotfix branch prefix: [hotfix/] # Support branch prefix: [support/] # Version tag prefix: [v] # Start a feature (creates feature/dark-mode from develop) git flow feature start dark-mode # Finish a feature (merges to develop, deletes branch) git flow feature finish dark-mode # Start a release git flow release start 1.1.0 # Finish a release (merges to main, tags, merges to develop) git flow release finish 1.1.0 # Start a hotfix git flow hotfix start 1.1.1 # Finish a hotfix git flow hotfix finish 1.1.1
When Git Flow shines
Scheduled releases — software that ships on a calendar (monthly, quarterly, per sprint) rather than continuously.
Versioned products — mobile apps, desktop software, npm libraries, APIs where consumers depend on specific version numbers.
Multiple supported versions — when you must maintain
v1.xwith security patches whilev2.xis in active development.Regulated industries — healthcare, finance, and government software where a release must pass audits before reaching users.
Large teams — the strict branching rules reduce coordination overhead when many developers work in parallel.
When Git Flow is overkill
Continuous deployment — if you deploy on every merge to main, Git Flow's release branch adds delay without benefit.
Small teams (1–4 people) — the coordination overhead of Git Flow is disproportionate to the team size.
SaaS web applications — a single production version at all times; GitHub Flow or Trunk-Based is simpler.
Rapid iteration — if you need to ship multiple times per day, Git Flow's release branching is a bottleneck.
Microservices — each service is versioned and deployed independently; Git Flow's rigid structure fights this.