Back
Interactive Explainer

Git Flow

A branching model with main, develop, and supporting branches for features, releases, and hotfixes—ideal for versioned releases and multiple supported versions.

Git Flow

A branching model with main, develop, and supporting branches for features, releases, and hotfixes—ideal for versioned releases and multiple supported versions.

~2 min read
Be the first to complete!

Lesson outline

What is Git Flow?

Two long-lived branches (main and develop) plus short-lived feature, release, and hotfix branches. Main = production; develop = next release.

Git Flow: main branches and supporting branches

Long-lived

main

Production-ready; every commit is a release

develop

Integration branch for the next release

Supporting (short-lived)

feature/*from develop → into developNew features
release/*from develop → into main + developStabilize & version
hotfix/*from main → into main + developUrgent production fix

Feature and release branches merge with --no-ff to keep history clear.

Why use Git Flow?

Fits teams that release on a schedule, need a clear split between production and development, and want a dedicated path for emergency fixes.

📅

Scheduled releases

Release on a cadence

Clear split

Production vs next release

🚑

Hotfix path

Emergency fixes without blocking dev

🌐

Multiple versions

Support older lines in the wild

Main branches: main and develop

main: every commit is a tagged release. develop: integration branch for the next release; features merge here, then you cut a release branch.

Production line

main

Every merge into main is a release and is tagged (for example 1.2.0). History here is clean and only contains shipped versions.

Tags mark exactly what runs in production.

Next release line

develop

All feature branches merge into develop. When develop is stable enough, you cut a release/* branch from it.

Think of develop as “what will be in the next release.”

Supporting branches: feature, release, hotfix

See the comparison table below for branch-from, merge-into, lifetime, and use case for each type.

Branch
Branch from
Merge into
Lifetime
Use case
feature/*
develop
develop
Short (days)
New functionality
release/*
develop
main + develop
Medium
Stabilize for a release
hotfix/*
main
main + develop
Very short
Critical production bug

Merge with --no-ff to keep a clear merge commit in history.

From feature to production: the full path

feature → develop → release branch → main (tag) → merge back into develop. Diagram below shows the steps.

End‑to‑end flow for a new feature

# 1) Start from develop
git checkout develop
git checkout -b feature/user-notifications

# 2) Build the feature on the feature branch
git commit -m "Add notifications panel"

# 3) Merge feature into develop (after review)
git checkout develop
git merge --no-ff feature/user-notifications

# 4) Cut a release branch when develop is ready
git checkout -b release-1.2 develop

# 5) Stabilize, bump version, then release
git commit -m "Bump version to 1.2.0"
git checkout main
git merge --no-ff release-1.2
git tag 1.2.0

# 6) Bring release fixes back to develop
git checkout develop
git merge --no-ff release-1.2

Visually: feature/* → develop → release/* → main (tagged) and back into develop so the next release inherits all fixes.

Release branches and parallel releases

You can run release-1.2 and release-2.0 in parallel; each merges only to main and back into develop when shipped.

Current minor

release-1.2

  • • Branched from develop when 1.2 features were done.
  • • Only bug fixes and hardening allowed here.
  • • Will merge to main and be tagged 1.2.0.

Next big release

release-2.0

  • • May be open in parallel with 1.2.
  • • Stabilizes breaking changes and major features.
  • • Also merges back into main and develop when shipped.

Version numbering: major, minor, patch, and more

MAJOR.MINOR.PATCH on main; snapshot/alpha and RC on develop or release branches. Diagram below shows where each applies.

Major

2.0.0

Big, breaking changes. Usually a new release branch like release-2.0.

Minor

1.3.0

New, backward‑compatible features. Tagged on main after a release branch.

Patch

1.2.1

Backward‑compatible bug fix, often coming from a hotfix branch.

Snapshot / in progress

1.2.0-snapshot

On develop or a release branch while you are still stabilizing.

Release candidate

1.2.0-rc1

“Looks ready.” If no major bugs appear, this becomes 1.2.0 on main.

Fixed in production

1.2.0

The tag on main that represents what users are actually running.

How hotfix and bug-fix versions are tagged

Hotfix: from main → fix → main + develop, tag patch (e.g. 1.2.1). Normal bug fix: via feature/release, tag when that release ships.

Hotfix path (urgent)

Branch from main, fix, bump patch, merge back to main and develop.

# Live is 1.2.0 on main
git checkout main
git checkout -b hotfix-1.2.1

# Fix the production bug, then:
git commit -m "Fix login crash"
./bump-version.sh 1.2.1

git checkout main
git merge --no-ff hotfix-1.2.1
git tag 1.2.1

git checkout develop
git merge --no-ff hotfix-1.2.1

Normal bug fix (non‑urgent)

Fix on a feature or release branch and let it ship in the next planned version.

  • • Fix is committed on feature/* or release/*.
  • • When the release branch is merged to main, the new tag (for example 1.3.0) includes the bug fix.
  • • No separate hotfix tag is needed because it was never an emergency.

Support branches for older versions

Long-lived support/1.x from last 1.x tag; apply fixes, tag (e.g. 1.2.2); merge fix back into develop when possible.

Supporting an older line while 2.x is current

main (2.x)Current major line (for example 2.1.0, 2.1.1, …).
support/1.xLong‑lived branch from the last 1.x tag to support customers who have not upgraded yet.

Critical fixes are applied on support/1.x and tagged (for example 1.2.2, 1.2.3). Whenever possible, the same fix is also applied to develop so future versions stay consistent.

Pros and cons of Git Flow

Pros: Clear roles, dedicated hotfix path, good for versioned/scheduled releases. Cons: More branches and steps; not ideal for many deploys per day.

Git Flow vs Trunk-Based Development

Traditional

Git Flow

Multiple long‑lived branches (main, develop, release/*, hotfix/*). Features live on branches for days or weeks before merging.

In practice

  • Branches live days to weeks before merge.
  • Merges are batched (e.g. at release).
  • High merge complexity; main not always deployable.

Recommended

Trunk‑based development

Single mainline (trunk / main) plus short‑lived feature branches. Branches live hours or 1–2 days; merge as soon as CI + review pass.

In practice

  • Branches live hours to 1–2 days before merge.
  • Merges are frequent (small PRs, as soon as CI passes).
  • Low merge complexity; main always green and deployable.

Detailed comparison

Branch structure
main, develop, release/*, hotfix/*, feature/*
main (trunk) + short-lived feature branches only
Feature branch lifetime
Days to weeks; merge when feature is “done”
Hours to 1–2 days; merge as soon as CI + review pass
Release cadence
Scheduled; release branches stabilized then merged
From trunk anytime; multiple deploys per day possible
Hotfix path
Dedicated hotfix/* from main → main + develop
Fix on trunk or short-lived hotfix branch → trunk
Merge complexity
High; long-lived branches → big merges, conflict risk
Low; small, frequent merges, tiny diffs
CI/CD fit
Build from develop/release/main; more branch logic
Single pipeline from trunk; simpler, faster feedback
Best for
Versioned products, scheduled releases, multiple supported versions
Continuous delivery, web apps, many deploys per day
Git Flow: versioned, scheduled, multi-version supportTBD: continuous delivery, many deploys per day

When Git Flow fits—and when to consider alternatives

Good when you version explicitly or support multiple versions. For single-trunk, many deploys per day, consider trunk-based development (link below).

Explore an alternative: Trunk-based development

Prefer a single trunk, short-lived branches, and releases from main? See how trunk-based development keeps integration fast and merges simple.

Read Trunk-based development

Related concepts

Explore topics that connect to this one.

Suggested next

Often learned after this topic.

Trunk-based development

Ready to see how this works in the cloud?

Switch to Career Paths for structured paths (e.g. Developer, DevOps) and provider-specific lessons.

View role-based paths

Sign in to track your progress and mark lessons complete.

Discussion

Questions? Discuss in the community or start a thread below.

Join Discord

In-app Q&A

Sign in to start or join a thread.