All posts
MermaidGit BranchingGitflowVersion ControlDevOps

Gitflow diagram: visualizing release and hotfix workflows

7 min readThe MermaidCreator team

Gitflow is a battle-tested branching model that separates production releases from development work. It introduces two permanent branches (main and develop) and three temporary branches (feature, release, and hotfix), each serving a distinct purpose. Without a clear mental model of how these branches interact, teams either abandon the strategy or execute it inconsistently.

Mermaid gitGraph diagrams make gitflow crystal clear—visualizing exactly when branches split, merge, and rejoin. This guide shows you how to document your gitflow workflow so every team member understands the rules.

Why gitflow matters

Gitflow solves three problems:

  • Separation of concerns: Production code lives on main; development happens on develop. No "oops, I merged a half-finished feature to production."
  • Release readiness: A release branch lets you fix bugs and bump versions without blocking new feature development.
  • Urgent fixes: Hotfixes branch from main directly, fixing production bugs while development continues on develop.

Without a documented flow, developers guess. With a gitflow diagram, the rules are visual and enforceable.

The standard gitflow model

Gitflow has five key branch types:

BranchBranches fromMerges toLifetimePurpose
main(permanent)(production)PermanentStable, production-ready code
develop(permanent)(integration)PermanentIntegration branch for features
feature/developdevelopTemporaryNew features, isolated from production
release/developmain + developTemporaryPrepare a release (version bump, final testing)
hotfix/mainmain + developTemporaryFix critical production bugs

Here's the complete gitflow diagram:

gitGraph
    commit id: "v1.0.0 (release)"
    
    branch develop
    checkout develop
    commit id: "setup develop"
    
    branch feature/login
    checkout feature/login
    commit id: "add login form"
    commit id: "add validation"
    
    checkout develop
    merge feature/login
    commit id: "integrate login"
    
    branch feature/payment
    checkout feature/payment
    commit id: "add stripe integration"
    commit id: "add tests"
    
    checkout develop
    merge feature/payment
    
    branch release/1.1.0
    checkout release/1.1.0
    commit id: "bump version to 1.1.0"
    commit id: "update changelog"
    
    checkout main
    merge release/1.1.0 tag: "v1.1.0"
    
    checkout develop
    merge release/1.1.0
    
    branch feature/analytics
    checkout feature/analytics
    commit id: "add tracking"
    
    checkout main
    branch hotfix/security-patch
    checkout hotfix/security-patch
    commit id: "fix XSS vulnerability"
    
    checkout main
    merge hotfix/security-patch tag: "v1.1.1"
    
    checkout develop
    merge hotfix/security-patch
    
    checkout feature/analytics
    commit id: "finalize analytics"
    
    checkout develop
    merge feature/analytics

Here's what's happening:

  1. v1.0.0 starts on main (your first production release).
  2. develop branches off—this is your integration branch.
  3. feature/login and feature/payment branch from develop and merge back after work is done.
  4. release/1.1.0 branches from develop to prepare v1.1.0 (version bump, changelog, final tests).
  5. release/1.1.0 merges into main (tagged as v1.1.0) and back into develop.
  6. While the release is being prepared, feature/analytics continues on develop in parallel.
  7. A critical bug on main triggers hotfix/security-patch, which branches directly from main.
  8. The hotfix merges into main (tagged as v1.1.1) and back into develop so development has the fix.

Feature branch workflow (the daily cycle)

Most of your time is spent on feature branches. Here's a simplified view:

gitGraph
    commit id: "develop at v1.0"
    
    branch feature/user-profile
    checkout feature/user-profile
    commit id: "create schema"
    commit id: "add API endpoint"
    commit id: "add UI component"
    commit id: "add tests"
    
    checkout develop
    merge feature/user-profile
    commit id: "deploy to staging"

Key points:

  • Every feature gets its own branch off develop.
  • Work is isolated; if something breaks, it doesn't affect other features.
  • When the feature is ready (tested, reviewed), merge it back to develop.
  • Delete the feature branch after merging (no stale branches).

Release branch workflow

When you're ready to ship, create a release branch:

gitGraph
    commit id: "develop: feature complete"
    commit id: "develop: more features"
    
    branch release/1.2.0
    checkout release/1.2.0
    commit id: "bump version 1.1.0 -> 1.2.0"
    commit id: "update CHANGELOG"
    commit id: "fix typo in docs"
    commit id: "bump date in footer"
    
    checkout main
    merge release/1.2.0 tag: "v1.2.0"
    
    checkout develop
    merge release/1.2.0
    commit id: "post-release: ready for next cycle"

The release branch is not for new features—only for:

  • Version bumps
  • Changelog updates
  • Last-minute documentation fixes
  • Deployment scripts
  • Bugfixes specific to this release

If a serious bug is found during release testing, fix it on the release branch, and it'll merge back to both main and develop.

Hotfix branch workflow

When production breaks, use a hotfix:

gitGraph
    commit id: "v1.0 on main"
    commit id: "customer reports bug"
    
    branch hotfix/critical-bug
    checkout hotfix/critical-bug
    commit id: "debug issue"
    commit id: "fix root cause"
    commit id: "add regression test"
    
    checkout main
    merge hotfix/critical-bug tag: "v1.0.1"
    
    checkout develop
    merge hotfix/critical-bug
    commit id: "develop continues normally"

Hotfixes:

  • Branch directly from main (not from develop).
  • Fix and test quickly—this is urgent.
  • Merge into main (create a tag for the patch version).
  • Merge back into develop so development gets the fix too.
  • Delete the hotfix branch.

Anti-patterns to avoid

Anti-patternProblemFix
Feature branches live foreverDead branches clutter the repoMerge or delete within 1–2 weeks
Committing directly to mainSkips quality gates, breaks productionAll changes go through feature branches
Skipping develop mergesProduction fixes don't reach developmentAlways merge hotfixes back to develop
Multiple release branchesConfusion about which release is shippingOne release branch per version
Merging from main to developCreates historical confusionAlways go developfeature, featuredevelop, hotfix → both

Gitflow in a team

When multiple developers use gitflow:

  1. Create a PR from your feature branch to develop — get code review.
  2. Approve only if tests pass — CI should gate merges.
  3. Delete the branch after merging — keeps the repo clean.
  4. Release manager creates release branch — signals "code freeze for features."
  5. Developers can still fix bugs on the release branch — but no new features.
  6. Release manager merges releasemain + develop and tags it.
  7. On production incidents, release manager creates hotfix — urgent fix.

Comparing gitflow to other strategies

StrategyWhen to useBest for
GitflowScheduled releases, multiple versions in productionLarge teams, enterprise, version-gated deployments
GitHub FlowContinuous deployment, no version branchesStartups, web apps, deploy-on-merge
GitLab FlowEnvironment-based (staging, production)CI/CD-heavy teams, multiple environments
Trunk-basedVery frequent releases (hourly, daily)High-velocity teams, feature flags

Gitflow excels when:

  • You have scheduled releases (e.g., every 2 weeks).
  • You need to maintain multiple versions in production.
  • Your team is large (5+ developers).
  • You want a clear, enforceable branching model.

FAQ

Can I use gitflow with GitHub?
Yes. Use branch protection rules on main and develop to require pull requests and passing CI. GitHub's branch naming conventions are flexible—feature/, release/, and hotfix/ are just suggestions.

What if a hotfix is needed while a release is in progress?
Hotfixes always branch from main, regardless. The release branch continues as planned. Both will merge back to develop, and git will handle any conflicts gracefully.

How do I name feature branches?
Convention: feature/short-description (e.g., feature/user-auth, feature/payment-retry). Use lowercase, hyphens for spaces. Some teams add a ticket prefix: feature/JIRA-123-user-auth.

How long should a feature branch live?
Ideally 1–2 weeks. Longer branches = higher merge conflict risk. If a feature takes months, break it into smaller features, or use feature flags to merge often without shipping.

Can I rebase instead of merge?
Yes—many teams prefer git rebase for a linear history. Both work; just be consistent. Never rebase branches that others are using (e.g., after you've pushed).

Gitflow is battle-tested because it works. Use these diagrams to teach your team the model and enforce it consistently. Visualize your workflow in the MermaidCreator editor and link it in your repo's README.

Related posts