Use Cases

  • Projects with versioned, scheduled releases (libraries, desktop apps, firmware, mobile apps)
  • Teams managing multiple supported versions simultaneously (e.g., v1.x and v2.x both in production)
  • Enterprise projects requiring strict, auditable release control
  • When you need a structured hotfix workflow separate from ongoing development

Components

  • master (main-branch): Production-ready code reflecting released versions. Every commit is tagged with a version number. The original spec uses "master"; modern teams may rename to "main".
  • develop (main-branch): Integration branch for completed features. This is where day-to-day development activity is reflected.
  • feature branches (supporting-branch): Branches for developing new features, branched from develop and merged back into develop via pull request
  • release branches (supporting-branch): Branches created from develop for release preparation (version bump, docs, bug fixes). Merged to both master AND develop.
  • hotfix branches (supporting-branch): Emergency fixes for production issues, branched directly from master and merged to both master AND develop (and any active release branch)

Steps

  1. Step 1: Create feature branch: Branch from develop to start working on a new feature
  2. Step 2: Develop feature: Commit changes to the feature branch
  3. Step 3: Merge feature to develop: When complete, merge the feature back into develop using pull request
  4. Step 4: Create release branch: When develop is ready for release, create a release branch from develop
  5. Step 5: Prepare release: Finalize release in release branch (bump version, update docs, fix bugs)
  6. Step 6: Merge release to master: Merge release branch to master and tag the release
  7. Step 7: Merge release to develop: Merge release branch back to develop
  8. Step 8: Create hotfix (if needed): For urgent fixes, branch from master, fix, merge to both master and develop

Workflow Diagram

gitGraph commit id: "v1.0" tag: "v1.0" branch develop checkout develop branch feature/login checkout feature/login commit id: "add login" commit id: "add tests" checkout develop merge feature/login id: "merge login" checkout main branch hotfix/1.0.1 checkout hotfix/1.0.1 commit id: "fix crash" checkout main merge hotfix/1.0.1 tag: "v1.0.1" checkout develop merge hotfix/1.0.1 branch release/1.1 checkout release/1.1 commit id: "bump version" checkout main merge release/1.1 tag: "v1.1" checkout develop merge release/1.1
Step 1 of —

Common Gotchas

  • Complex branch structure: The multiple branch types can be confusing for new team members and lead to mistakes (e.g., branching feature from master instead of develop) important
  • Long-lived develop branch: The develop branch can become unstable if features are merged without proper testing, especially when many features land simultaneously before a release. critical
  • Release branch merges twice: Release branches must be merged to both master AND develop, and also into any active hotfix branches. Forgetting the develop merge-back causes master and develop to diverge. important
  • Hotfix must also merge into active release branches: If a hotfix lands while a release branch is active, the fix must go into the release branch too, not just master and develop. Teams commonly forget this. important
  • Over-engineering for teams doing continuous delivery: Vincent Driessen himself wrote in 2020 that he recommends simpler workflows (like GitHub Flow) for teams practicing continuous delivery or CD. mild
  • Feature branches can diverge significantly: Long-running features in Gitflow often lead to painful merge conflicts when finally integrating to develop important

Best Practices

  • Always use pull requests for merging to develop and master
  • Keep feature branches short and focused
  • Use semantic versioning for release tags (e.g., v1.2.0)
  • Use the git-flow CLI extension (git flow init, git flow feature start, git flow release finish) to automate branch creation and merge sequences
  • Protect master and develop with branch rules — no direct pushes
  • Document clear rules for when to create release branches

Pros and Cons

Pros

  • Excellent support for versioned, scheduled releases
  • Clear separation of concerns between branches
  • Simultaneous support for multiple production versions (v1.x maintenance while v2.x is in development)
  • Structured hotfix workflow that keeps emergency fixes isolated from development
  • Well-defined release preparation process with a stabilization period

Cons

  • Complex and difficult to learn — easy to merge to the wrong branch
  • Driessen's own 2020 recommendation: avoid Gitflow for teams doing continuous delivery
  • More overhead and slower development cycle than simpler workflows
  • Requires strict branch hygiene and team discipline
  • CI/CD integration more complex due to multiple branches needing separate pipelines

Real-World Examples

  • Linux kernel (pre-2005): Early kernel development used a model resembling Gitflow with release branches. After Linus created Git, the kernel moved to a more maintainer-tree model, but Gitflow remains common for projects shipping versioned packages.
  • Open-source libraries (e.g., Spring Framework, Hibernate): Many Java/JVM open-source libraries use Gitflow to maintain multiple LTS (long-term support) release branches simultaneously. The Spring Framework maintains active develop, main, and multiple release/* branches for 5.x, 6.x, etc.
  • Mobile app teams: iOS and Android teams often use Gitflow because app releases are gated by app store review (which takes days). A release branch is created, submitted for review, and only shipped when approved — while development continues on develop.