GitGitflow Workflow

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

main

Always represents production-ready code. Every commit is a tagged release.

Never directly

Never (only receives merges)

Develop

develop

Integration branch. All features land here first. Represents the latest delivered development.

main (via release branch)

Never (only receives merges)

Feature

feature/*

New features or non-emergency fixes. Lives until merged to develop.

develop

develop

Release

release/*

Prepare a release: bump version, final bug fixes. No new features.

main AND develop

develop

Hotfix

hotfix/*

Emergency production fix. Bypasses develop.

main AND develop

main

Full branch diagram

Git Flow complete branch topology

Text
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

Bash
# 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

Bash
# 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)

Bash
# 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

Bash
# 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

Bash
# 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.x with security patches while v2.x is 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
Git Flow adds significant complexity — only use it when you need it
Git Flow involves multiple long-lived branches, mandatory double-merges (release and hotfix branches merge into both main and develop), and a lot of ceremony for every release. For teams that deploy continuously or maintain only one production version, Git Flow is unnecessary overhead.
  • 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.

Git Flow's own creator recommends simpler models for web apps
In a 2020 addendum to his original post, Vincent Driessen noted that Git Flow was designed for explicitly versioned software with a long support lifecycle. For web applications with continuous delivery, he recommends simpler models like GitHub Flow.
Adopt Git Flow incrementally
If you are considering Git Flow, start by adopting just the `develop` + `feature/*` pattern (skipping formal release and hotfix branches). This gets you the main benefit — protecting `main` — without all the ceremony. Add release branches only when you genuinely need to prepare releases over multiple days.