Back
GitoryxGitoryx
Intermediate11 min read

GitFlow Explained: The Classic Branching Model

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 — Gitoryx screenshot

See this workflow in Gitoryx. The commit graph shows all GitFlow branches simultaneously — feature, develop, release, hotfix, and main — color-coded and clearly labeled.

Free download
5

Understand the full GitFlow lifecycle

This is the complete flow from feature to production. Visualizing it helps make the branch naming and merge directions intuitive.

bash
# Full GitFlow branch topology:
#
#   main ──────────────────●─────────────────────●──── (tags: v2.0, v2.1, v2.1.1)
#                         /|                    /|
#                        / |                   / |
#  release/2.1 ─────────●  |  hotfix/2.1.1 ──●  |
#                       |  |                  |  |
#  develop ─────────────●──●──────────────────●──●───
#                      /|                    /
#  feature/auth ──────● |  feature/search ──●
#                       |
#                  (merged features accumulate on develop)
6

Know when NOT to use GitFlow

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 — visual Git client for macOS & Windows
GitoryxGitoryx — macOS & Windows

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.
Download Gitoryx — FreemacOS · Windows · No subscription

Frequently Asked Questions

What is GitFlow?

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.

See it in action with Gitoryx

Everything in this tutorial is faster and clearer with a visual Git client. Gitoryx is free, runs natively on macOS and Windows, and built for developers who want to move fast without breaking things.