What Is Git Flow?
Git Flow defines two permanent (long-lived) branches and three types of temporary (short-lived) branches. Each type has a specific purpose and specific rules about where it branches from and merges to.
| Branch type | Lifespan | Purpose |
|---|---|---|
main | Permanent | Production-ready code only. Every commit is a release. |
develop | Permanent | Integration branch. Next release is built here. |
feature/* | Temporary | New features. Branches from develop, merges to develop. |
release/* | Temporary | Release preparation. Branches from develop, merges to main + develop. |
hotfix/* | Temporary | Urgent production fixes. Branches from main, merges to main + develop. |
The Two Permanent Branches
# Initialize Git Flow in a new or existing repo
git switch -c main
git switch -c develop
# Or using the git-flow CLI tool
git flow init
# Accepts defaults: main=main, develop=develop,
# feature prefix=feature/, release prefix=release/,
# hotfix prefix=hotfix/
main always contains production-ready code. It should be deployable at any time. Every merge to main is tagged with a version number.
develop is the integration branch where completed features accumulate before the next release. It's the base for all feature branches.
Feature Branches
Each new feature gets its own branch. Feature branches branch from develop and merge back to develop when the feature is complete.
# Start a feature (manual approach)
git switch develop
git pull origin develop
git switch -c feature/user-authentication
# ... develop the feature, make commits ...
# Merge back to develop when complete
git switch develop
git merge --no-ff feature/user-authentication
git push origin develop
git branch -d feature/user-authentication
# Using git-flow CLI
git flow feature start user-authentication
# ... work ...
git flow feature finish user-authentication
# (automatically merges to develop, deletes feature branch)
The --no-ff flag forces Git to create a merge commit even when a fast-forward is possible. This preserves the historical evidence that a feature branch existed and groups all the feature's commits together — making it easy to revert an entire feature if needed.
Release Branches
When develop has accumulated enough features for a release, a release branch is created. Only bug fixes, documentation, and release preparation go in here — no new features.
# Create a release branch from develop
git switch develop
git switch -c release/1.2.0
# Bump version numbers, update CHANGELOG, fix last-minute bugs
# No new features allowed here
# When release is ready: merge to BOTH main AND develop
git switch main
git merge --no-ff release/1.2.0
git tag -a v1.2.0 -m "Release v1.2.0"
git switch develop
git merge --no-ff release/1.2.0
git branch -d release/1.2.0
# Push everything
git push origin main develop --follow-tags
Hotfix Branches
When a critical bug is found in production, a hotfix branch is created directly from main — you can't wait for the next planned release cycle.
# Create hotfix branch directly from main
git switch main
git switch -c hotfix/1.1.1
# Fix the bug, bump the patch version
# Merge to BOTH main AND develop (or current release branch)
git switch main
git merge --no-ff hotfix/1.1.1
git tag -a v1.1.1 -m "Hotfix v1.1.1 – fix critical auth bypass"
git switch develop
git merge --no-ff hotfix/1.1.1
git branch -d hotfix/1.1.1
git push origin main develop --follow-tags
When to Use (and Not Use) Git Flow
| Git Flow works well for | Git Flow is overkill for |
|---|---|
| Apps with versioned releases (v1.0, v2.0) | Continuous deployment (deploy many times/day) |
| Supporting multiple versions simultaneously | Small teams (1–3 developers) |
| Mobile apps, desktop software, npm packages | Web apps with one production environment |
| Long release cycles (weeks/months) | Startups moving fast with frequent deploys |
Vincent Driessen added a note to his original 2010 blog post: if your team is delivering software continuously (not versioned releases), the simpler Feature Branch Workflow or trunk-based development is a better fit. Git Flow was designed for software that cannot be easily rolled back or that needs to support multiple versions simultaneously.
📋 Summary
- Git Flow uses two permanent branches:
main(production) anddevelop(integration). - Feature branches: branch from
develop, merge back todevelopvia--no-ff. - Release branches: branch from
develop, merge to bothmainanddevelop, then tag onmain. - Hotfix branches: branch from
main, merge to bothmainanddevelop, then tag. - Every merge to
maingets an annotated version tag. - Best for: projects with discrete versioned releases, multiple supported versions.
- Avoid for: continuous deployment, small teams, frequently deployed web apps.
FAQ
No. The git flow CLI tool is a convenience wrapper that automates the branch creation, merging, and deletion steps. Everything it does can be done with standard Git commands. The tool is helpful for reducing mistakes (e.g., forgetting to merge a hotfix back to develop), but many teams use Git Flow conventions with plain Git commands and rely on PR/code review processes on GitHub/GitLab to enforce the rules.
After a release is merged to both main and develop, development continues on the develop branch for the next release. The develop branch is never deleted — it's permanent. Immediately after a release merge, develop should be identical to main, and then it starts accumulating new feature merges for the next release cycle.
Breaking changes are handled through semantic versioning. When a release includes breaking changes, increment the MAJOR version (e.g., v1.5.0 → v2.0.0). Teams often create a separate long-lived maintenance branch (e.g., support/1.x) to continue supporting the previous major version with security patches while the new major version is developed on develop.
No — they're quite different. GitHub Flow is a much simpler model: there's only one long-lived branch (main), and all work happens in feature branches that are merged directly to main via pull requests. It's designed for continuous deployment. Git Flow has the full structure with develop, feature, release, and hotfix branches for versioned release management. GitHub Flow is simpler and more appropriate for most web projects; Git Flow is more structured and suited for software with versioned releases.