Back
GitoryxGitoryx

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.

Intermediate11 min readUpdated

On this page

What is GitFlow?

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.

The short version

  1. 1Initialize: git flow init (creates main and develop)
  2. 2New feature: git flow feature start <name> → work → git flow feature finish <name>
  3. 3New release: git flow release start <version> → QA/fixes → git flow release finish <version>
  4. 4Emergency fix: git flow hotfix start <version> → fix → git flow hotfix finish <version>
  5. 5Result: main has tagged releases, develop has all integrated work

Why it matters

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.

Where it usually goes wrong

  • 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)

GitFlow, step by step

  1. Step 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.

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

    Tip: Install git-flow CLI for shorthand commands. On macOS: brew install git-flow-avh. It automates the branch creation, merging, and tagging steps.

  2. Step 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.

    Terminal
    # Start a new featuregit flow feature start user-authentication# Equivalent to: git checkout -b feature/user-authentication develop# Work on the feature, commit normallygit 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

    Tip: 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. Step 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).

    Terminal
    # Start a release from developgit flow release start 2.1.0# Equivalent to: git checkout -b release/2.1.0 develop# Only bug fixes and release prep heregit commit -m "Bump version to 2.1.0"git commit -m "Fix edge case in login flow"# Finish the releasegit 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

    Tip: 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. Step 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).

    Terminal
    # Start a hotfix from maingit flow hotfix start 2.1.1# Equivalent to: git checkout -b hotfix/2.1.1 main# Fix the critical buggit commit -m "Fix null pointer exception in payment module"# Finish the hotfixgit 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

    Careful: 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.

    GitFlow Explained: The Classic Branching Model: the same workflow in Gitoryx
    In Gitoryx: The commit graph shows all GitFlow branches simultaneously (feature, develop, release, hotfix, and main), color-coded and clearly labeled.How it works
  5. Step 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.

    Terminal
    # 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. Step 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.

    Tip: 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.

Mistakes to avoid with GitFlow

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.

GitFlow in 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.

  • 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, with no separate tagging step needed.

Free plan · no account required · macOS, Windows and Linux

GitFlow: 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.
All Git tutorials →
Gitoryx

Stop fighting Git. Start shipping.

Download the fast, native Git client that developers actually enjoy using.

v1.1.0 · macOS 12+ (Apple Silicon or Intel) · Windows 10+ · Linux x86_64