GitFlow is a structured Git workflow built around feature, develop, release, and hotfix branches. This guide explains every component and helps you decide if GitFlow is right for your team.
The Problem
Your team has multiple developers committing directly to main, hotfixes stepping on feature work, and releases that feel chaotic. Someone breaks production on a Friday. Another developer merges a half-finished feature by accident. There's no agreed structure — everyone does their own thing.
GitFlow gives your team a formal, predictable branching structure. It separates ongoing development from stable releases, isolates features from each other, and provides a clear path for hotfixes without disrupting in-progress work. It was the gold standard for release-based workflows for over a decade.
Common mistakes developers make with this:
Committing features directly to `develop` instead of creating feature branches
Merging a feature branch directly into `main` (bypassing `develop` and `release`)
Not creating a hotfix branch — patching `main` directly and forgetting to backport to `develop`
Using GitFlow for a small project or a team that ships continuously (where it adds friction without benefit)
Gitoryx: Gitoryx visualizes the full GitFlow branch structure in its commit graph. You can see feature, develop, release, and hotfix branches at a glance, and initiate any GitFlow operation — create feature, start release, open hotfix — directly from the UI.
What is Explained: The Classic Branching Model?
GitFlow is a branching model that organizes Git history around two permanent branches (`main` and `develop`) and three types of short-lived branches (`feature`, `release`, `hotfix`). It was introduced by Vincent Driessen in 2010 and is designed for projects with scheduled, versioned releases.
Step-by-Step Guide
1
Understand the two permanent branches
`main` (or `master`) always reflects production-ready code. Every commit on `main` is a tagged release. `develop` is the integration branch — it contains all completed features waiting for the next release. You never commit directly to either; all work flows through short-lived branches.
bash
# Initialize GitFlow (sets up main and develop)
git flow init
# Or manually:
git checkout -b develop main
# Branch structure after init:
# main ← production, tagged releases only
# develop ← integration of completed features
Install `git-flow` CLI for shorthand commands. On macOS: `brew install git-flow-avh`. It automates the branch creation, merging, and tagging steps.
2
Create and finish a feature branch
Every new feature starts from `develop` and merges back into `develop` when complete. Feature branches are never merged directly into `main`. Name them descriptively.
bash
# Start a new feature
git flow feature start user-authentication
# Equivalent to: git checkout -b feature/user-authentication develop
# Work on the feature, commit normally
git add .
git commit -m "Add JWT token generation"
# Finish the feature (merges into develop, deletes branch)
git flow feature finish user-authentication
# Equivalent to:
# git checkout develop
# git merge --no-ff feature/user-authentication
# git branch -d feature/user-authentication
Always use `--no-ff` when merging feature branches to preserve the history of the feature as a group of commits. GitFlow does this automatically.
3
Create a release branch
When `develop` has enough features for a release, branch off a `release` branch. This is a freeze period: only bug fixes, documentation, and release preparation go here. No new features. Once ready, it merges into both `main` (the release) and `develop` (to sync the fixes back).
bash
# Start a release from develop
git flow release start 2.1.0
# Equivalent to: git checkout -b release/2.1.0 develop
# Only bug fixes and release prep here
git commit -m "Bump version to 2.1.0"
git commit -m "Fix edge case in login flow"
# Finish the release
git flow release finish 2.1.0
# Equivalent to:
# git checkout main && git merge --no-ff release/2.1.0
# git tag -a 2.1.0 -m "Version 2.1.0"
# git checkout develop && git merge --no-ff release/2.1.0
# git branch -d release/2.1.0
The release branch is what separates GitFlow from simpler workflows. It gives QA a stable target to test while development on `develop` continues uninterrupted.
4
Create a hotfix branch for production bugs
When a critical bug is found in production, create a `hotfix` branch from `main` (not from `develop`). Fix the bug, then merge back into both `main` (new patch release) and `develop` (to keep the fix in ongoing work).
bash
# Start a hotfix from main
git flow hotfix start 2.1.1
# Equivalent to: git checkout -b hotfix/2.1.1 main
# Fix the critical bug
git commit -m "Fix null pointer exception in payment module"
# Finish the hotfix
git flow hotfix finish 2.1.1
# Equivalent to:
# git checkout main && git merge --no-ff hotfix/2.1.1
# git tag -a 2.1.1 -m "Version 2.1.1"
# git checkout develop && git merge --no-ff hotfix/2.1.1
# git branch -d hotfix/2.1.1
Never forget to merge the hotfix back into `develop`. If you only merge into `main`, the bug fix will be lost the next time `develop` is released.
See this workflow in Gitoryx. The commit graph shows all GitFlow branches simultaneously — feature, develop, release, hotfix, and main — color-coded and clearly labeled.
GitFlow is designed for scheduled, versioned releases. If your team deploys continuously (multiple times a day), GitFlow adds ceremony without benefit. Simpler workflows like GitHub Flow (feature branch → main) or trunk-based development are better suited for CI/CD.
GitFlow shines for: open-source libraries with versioned releases, enterprise software with monthly/quarterly releases, teams with separate QA phases. It's overkill for: SaaS apps with continuous deployment, small teams shipping daily, projects with no versioning concept.
Common Mistakes to Avoid
Merging features directly into main
The entire point of GitFlow is that `main` only ever receives merges from `release` or `hotfix` branches. Merging a feature directly to `main` bypasses QA, skips versioning, and breaks the model.
Fix: Features always merge into `develop`. From `develop` they flow to `release`, and from `release` to `main`. Never shortcut this flow.
Forgetting to backport the hotfix to develop
After merging a hotfix into `main`, teams sometimes forget to also merge it into `develop`. The next release will then reintroduce the bug that was just patched in production.
Fix: `git flow hotfix finish` handles this automatically. If done manually, always merge the hotfix branch into both `main` AND `develop` before deleting it.
Using GitFlow for continuous deployment
GitFlow was designed for projects with defined release cycles. If you deploy on every merge to `main`, the `release` branch becomes a pointless bottleneck and the workflow creates unnecessary friction.
Fix: Evaluate your release cadence before adopting GitFlow. For continuous deployment, GitHub Flow (feature branch → PR → main → deploy) is simpler and more effective.
Long-lived feature branches
Feature branches that stay open for weeks accumulate conflicts with `develop`. The longer they live, the more painful the merge back into `develop` becomes.
Fix: Keep feature branches short. Break large features into smaller, independently mergeable slices. Regularly rebase or merge `develop` into your feature branch to stay current.
Gitoryx — macOS, Windows & Linux
Visualize and Manage GitFlow in Gitoryx
The commit graph shows all GitFlow branches simultaneously — feature, develop, release, hotfix, and main — color-coded and clearly labeled.
Start a feature, release, or hotfix branch directly from the Gitoryx UI without remembering the `git flow` CLI commands.
Gitoryx warns you if you're about to merge a branch to the wrong target (e.g., feature → main instead of feature → develop).
The graph makes the two-way merge of hotfixes and releases (into both main and develop) visually obvious and easy to verify.
Tag releases directly from the graph after a `release finish` — no separate tagging step needed.
GitFlow is a Git branching model introduced by Vincent Driessen in 2010. It defines two permanent branches (main and develop) and three types of supporting branches (feature, release, hotfix) with strict rules about where each type branches from and merges back into.
What is the difference between main and develop in GitFlow?
`main` always reflects the current production state — every commit on main is a tagged release. `develop` is the integration branch where completed features accumulate before being bundled into a release. You never commit directly to either.
When should I use a hotfix branch vs a release branch?
Use a `hotfix` branch when you need to patch a critical bug in production immediately, without waiting for the next planned release. Use a `release` branch when you're preparing a scheduled release from `develop` — bundling features, bumping the version, and doing final QA.
Does GitFlow work with pull requests?
Yes. Instead of merging branches directly, you open a pull request for each step: feature → develop, release → main, hotfix → main. The PR process adds code review before each merge. This is the recommended way to use GitFlow on GitHub or GitLab.
Is GitFlow still relevant in 2025?
GitFlow remains relevant for projects with versioned releases — libraries, mobile apps, enterprise software. For SaaS products with continuous deployment, simpler models like GitHub Flow or trunk-based development are generally preferred. The model itself is sound; it's a question of fit.
What is the difference between GitFlow and GitHub Flow?
GitHub Flow is much simpler: feature branch → PR → merge into main → deploy. There's no `develop`, no `release` branch. It's designed for continuous deployment. GitFlow adds `develop`, `release`, and `hotfix` branches for teams that need versioned, scheduled releases.
Do I need the git-flow CLI tool to use GitFlow?
No. GitFlow is a branching convention, not a tool. You can follow it with plain `git` commands. The `git-flow` CLI (and `git-flow-avh`) simply automates the branch creation, merging, and tagging steps. GitFlow-aware GUIs like Gitoryx provide the same convenience visually.
How do I handle multiple features being developed simultaneously in GitFlow?
Each feature gets its own branch from `develop`. They are developed in parallel and merged back into `develop` independently when finished. The integration happens on `develop`, not between feature branches.
Everything in this tutorial is faster and clearer with a visual Git client. Gitoryx is free, runs natively on macOS, Windows, and Linux, and built for developers who want to move fast without breaking things.