The Gitflow Branching Model: How It Works, and When to Use Something Simpler
Gitflow's own author added a note telling most teams to use something simpler. So the useful question is not how to use it. It is whether your team should.
Updated August 2026
Gitflow is one of the most-searched branching models on the internet, and one of the most misapplied. Its own author added a note years after publishing it, telling most teams to use something simpler. So the useful question is not "how do I use Gitflow," it is "should my team use it at all."
This post answers both, starting with how Gitflow works, commands and merge rules correct, and moving to how you tell whether it still fits the way your team ships in 2026.
What Gitflow actually is
Gitflow is a branching model, first described by Vincent Driessen in 2010. It defines a set of long-lived and short-lived branches, assigns each a role, and specifies exactly how and when they merge. It is a convention, not a feature of Git.
It is a deliberately strict model built around a scheduled release cycle. Each branch gets one job, and the rules say when branches may interact. That strictness is the point: on a project with several versions live at once, it is what keeps an urgent production patch from dragging half-finished work into the release.
The model rests on two permanent branches. main holds the official release history, with every release tagged. develop is the integration branch where finished work accumulates between releases.
A note on branch naming. Driessen's original 2010 article called the release branch master. Git and every major host default to main for repositories created since 2020.
It is the same branch doing the same job under a different name. If you are working in an older repository you will see master, and every rule in this post applies unchanged.
Installing the git-flow toolset (and why you may not need it)
Gitflow the model needs nothing installed. Gitflow the toolset is a separate set of shell scripts that adds shorthand commands like git flow feature start. It does not ship with Git, so you install it yourself.
The version to install is git-flow-avh, a maintained fork. Driessen's original scripts have not been updated in years.
# macOS
brew install git-flow-avh # Debian / Ubuntu
sudo apt-get install git-flow # Windows: included with Git for Windows, run it from Git Bash Then, inside an existing repository:
git flow init That prompts you for your branch names and naming prefixes, writes them into the repository's Git config, and creates develop if it does not exist. It rewrites no history and changes no existing commits. It is a helper layer over ordinary Git.
Worth saying plainly: you do not need the tool. Every Gitflow operation is an ordinary branch, merge, and tag. The scripts save typing and keep branch naming consistent across a team, which matters more on a large team than a small one.
If you would rather see exactly what Git is doing, run the plain commands and skip the install.
The five branch types, done right
Gitflow uses two permanent branches and three kinds of temporary ones. Getting the merge directions right is the whole point, so this is where most teams go wrong.
You create develop once, off main, and push it so the team shares one integration point:
git branch develop
git push -u origin develop - main
Holds the official release history. Every release on it is tagged with a version. Nothing merges into it except a release or a hotfix.
permanent - develop
The integration branch where finished work accumulates between releases. Created once off
permanentmain, then shared by the whole team. - Feature branches
Hold work on a single feature. They branch off
develop → feature → developdevelop, never offmain, and merge back intodevelopwhen the work is done, with afeature/<name>prefix that keeps them easy to find. A feature branch that never touchesmaindirectly is the rule that keeps unreleased work out of production. - Release branches
Stage a set of features for a dated release. You cut a release branch from
develop → release → main + developdeveloponce the features you want are in, and from that point you add only bug fixes, documentation, and release prep, no further features. When it is ready, it merges intomain(tagged with a version) and back intodevelopso those fixes are not lost. - Hotfix branches
Patch production. They are the one temporary branch that starts from
main → hotfix → main + developmain, notdevelop, because they fix what is live right now. When the fix is done, it merges into bothmainanddevelop(or the active release branch), andmaingets a bumped version tag.
The value of this discipline is separation. One team can stabilize a release while another builds the features in development, and an urgent production fix never has to wait on either.
The Gitflow branching model
Solid arrows are the primary merge. Dashed arrows are the merge back into develop that keeps release and hotfix work from being lost.
What the model actually buys you
Five things, and it is worth being concrete about them because they are also the test for whether you need it. If none of these describe a problem you have, the model is overhead.
- 1Parallel work that does not collide. One group hardens a release while another builds what comes after it. Both have a branch that means something, so neither has to wait on the other.
- 2A review surface per unit of work. A feature branch is a sandbox holding only the changes for that feature, which makes each contributor's work reviewable and traceable on its own instead of as part of one large shared diff.
- 3A staging area with a real gate. The release branch is where "finished" becomes "shippable". Once it is cut, only fixes go in, so the release stops being a moving target while it is being tested.
- 4A path for urgent fixes that skips the queue. Because a hotfix branches from
main, you can patch production without inheriting anything unreleased that happens to be sitting indevelop. - 5Cheap context switching. Prefixed, named, short-lived branches mean moving between an urgent fix and a half-finished feature is bookkeeping rather than archaeology.
Working with a central repository
Gitflow assumes a shared remote, on GitHub, GitLab, Bitbucket, Azure Repos, or a self-hosted equivalent. The host holds the canonical repository, and everyone clones from it.
The part that matters: both main and develop must live on the remote. A develop branch that exists only on one laptop is not an integration point, it is a personal habit, and two engineers will end up integrating against different baselines without noticing. Pushing develop once, at setup, is what makes it shared.
Feature branches belong on the remote too, even before the work is finished. Pushing them gives you backup, lets a colleague look at work in progress, and is what starts a pull request for review:
git switch develop
git pull --ff-only
git switch -c feature/payment-retry
git push -u origin feature/payment-retry Treat shared history as append-only. Rebasing or force-pushing a branch other people have pulled rewrites history under them, which is the one Gitflow mistake that costs other people their afternoon. Rebase your own unpublished feature branch freely; leave develop and main alone.
Tag every release on main. Tags are what let you say which commit is running in production six months later, and they are the cheapest part of the whole model to get right.
Handling merges and conflicts
Because several people commit against shared branches, conflicts are normal, not a failure. Gitflow does not remove them; it contains them to predictable points, mainly the merges into develop and main.
When you push and someone else has pushed first, Git rejects your push so you do not overwrite their work. You fetch their commits, then either merge or rebase your branch on top of the updated base before pushing again. Teams that prefer a linear history rebase feature branches on develop; teams that prefer to preserve context merge.
During a rebase or merge, Git pauses on any conflicting file and asks you to resolve it. You fix the file, mark it resolved, and continue, or you abort and start over with nothing lost. Short-lived branches are the real defense: the longer a feature branch lives, the further it drifts from develop, and the more painful the eventual merge.
This is also where team size shows up. Conflict resolution that a team of four absorbs in an afternoon becomes a standing tax on a team of forty, which is an argument for smaller branches rather than a heavier process.
When Gitflow still fits, and when it does not
Gitflow was designed for software with explicit versions and multiple releases live at once. That shape still exists, and Gitflow still serves it well.
Gitflow fits when
You ship versioned software: mobile apps going through store review, desktop or on-premise products, SDKs and libraries, or any system where several versions run in the wild and need parallel support. The release and hotfix branches map directly to that reality.
Gitflow gets in the way when
You run a web app on continuous delivery and support one live version. The release and hotfix machinery turns into ceremony around a pipeline that already deploys on every merge, and the staging branches slow down the thing they were meant to protect.
Driessen's own walk-back is on the original article, where he recommends a lighter workflow like GitHub Flow for continuously delivered web apps. A 2023 JetBrains developer survey put Gitflow adoption around 22 percent, well below its peak, as the industry shifted toward continuous delivery.
Two lighter alternatives cover most modern teams.
GitHub Flow
One main branch plus short-lived feature branches that merge on review and deploy immediately. Suits SaaS teams shipping many times a day.
Trunk-based development
Everyone commits to a single trunk behind feature flags. The DORA research identifies it as a practice of elite-performing engineering teams, because it minimizes the merge debt that long-lived branches create.
The honest read: if you deploy to production several times a week and support one live version, Gitflow's release and hotfix machinery is overhead you do not need. Pick it for what it was built for, not by default.
Branching when your team ships with AI assistance
This choice matters more now, not less. When engineers work with Claude Code, Cursor, and GitHub Copilot, code lands faster, which means feature branches accumulate change and drift from the integration branch more quickly than they used to.
Faster generation makes short-lived branches and review on every merge the safer default, and it makes AI-assisted code review on each pull request a practical way to keep merges clean. The branching model you pick should keep pace with how fast your team now commits.
The takeaway
A branching model is not the goal. Protecting your release cadence is, and the branches are just the mechanism.
Gitflow earned its reputation on versioned, multi-release software, and it still holds up there. For a continuously delivered web app, reach for the simplest model your release reality allows, usually GitHub Flow or trunk-based development. The best branching strategy is the one your team can follow without thinking about it.
Weighing branching and CI/CD trade-offs for your release cadence?
Send us the shape of your release reality. Our engineers will talk through what fits, in writing, within a business day.
Talk to our engineersAnAr Solutions builds and maintains production software with AI-assisted engineering teams. See how we approach product engineering and AI-assisted development.








