Stage 2 · Tools
Branching Strategies
GitFlow Workflow
A structured branching model with dedicated branches for features, releases, and hotfixes.
What Is GitFlow?
GitFlow is a branching model introduced by Vincent Driessen in 2010. It defines a strict branching structure designed around project releases. Unlike trunk-based development, GitFlow uses multiple long-lived branches with specific roles: main, develop, release, and hotfix.
GitFlow is not a Git command — it is a convention. The git-flow extension (and later git flow wrapper) automates the workflow, but you can follow the model with plain Git commands.
GitFlow solves a real problem: coordinating parallel development across multiple releases. If you ship versioned software (v1.0, v1.1, v2.0) and need to maintain older versions while developing new ones, GitFlow gives you a structured way to manage that complexity.
The Five Branch Types
GitFlow defines five branch types, each with a specific purpose and lifecycle.
| Branch | Lifetime | Purpose | Merges Into |
|---|---|---|---|
| main | Permanent | Production-ready code, tagged releases | — |
| develop | Permanent | Integration branch for next release | — (main via release) |
| feature/* | Temporary | New features developed in isolation | develop |
| release/* | Temporary | Stabilize a release (version bumps, docs) | main + develop |
| hotfix/* | Temporary | Emergency production fixes | main + develop |
main always reflects production. develop always reflects the next release. Feature branches are created from develop and merged back. Release branches are created from develop and merged to both main and develop. Hotfix branches are created from main and merged to both main and develop.
The GitFlow Lifecycle
A typical GitFlow cycle follows this sequence: feature development, release preparation, production deployment, and (if needed) hotfix.
main: ──●───────────────────●────────────●──
/ /
release/v1.0: ────●────●──── /
/ \ /
develop: ──●────●────●────●────●────●────●──
\ / \ / \ /
feature/a: ●──● / / / /
/ / / /
feature/b: ●──●──● / /
/
hotfix/x: ●──●This diagram shows how branches flow. Features branch from develop and merge back. A release branches from develop, stabilizes, then merges to main and back to develop. A hotfix branches from main and merges to both main and develop.
Workflow Commands
# Start a new feature from develop
git switch develop
git pull origin develop
git switch -c feature/user-profile
# Work on the feature
echo "Profile page" > src/profile.ts
git add src/profile.ts
git commit -m "feat: add user profile page"
# Push and create a PR to develop
git push origin feature/user-profile
gh pr create --base develop --title "Add user profile"
# After review, merge to develop
gh pr merge --squash --delete-branchFeature branches always start from develop and merge back to develop. Use --squash to keep the develop branch history clean.
# Start a release branch from develop
git switch develop
git pull origin develop
git switch -c release/v1.2.0
# Stabilize: version bump, changelog, final fixes
echo "1.2.0" > VERSION
git add VERSION
git commit -m "chore: bump version to 1.2.0"
# No new features — only bug fixes and documentation
git commit -m "fix: resolve login timeout"
# Merge to main (production) and tag
git switch main
git merge --no-ff release/v1.2.0
git tag -a v1.2.0 -m "Release v1.2.0"
git push origin main --tags
# Merge back to develop
git switch develop
git merge --no-ff release/v1.2.0
git push origin develop
# Delete the release branch
git branch -d release/v1.2.0
git push origin --delete release/v1.2.0Release branches stabilize code for production. The key step is merging to both main (with a tag) and back to develop so the fixes are not lost.
# Start a hotfix from main
git switch main
git pull origin main
git switch -c hotfix/critical-auth-fix
# Fix the issue
echo "patch" > src/auth.ts
git add src/auth.ts
git commit -m "fix: patch authentication bypass vulnerability"
# Merge to main and tag
git switch main
git merge --no-ff hotfix/critical-auth-fix
git tag -a v1.2.1 -m "Hotfix v1.2.1"
git push origin main --tags
# Merge to develop so the fix persists
git switch develop
git merge --no-ff hotfix/critical-auth-fix
git push origin develop
# Delete the hotfix branch
git branch -d hotfix/critical-auth-fix
git push origin --delete hotfix/critical-auth-fixHotfixes bypass the develop branch. They branch from main, get fixed, then merge to both main and develop. This ensures the fix is in production and in future development.
GitFlow vs Trunk-Based Development
| Dimension | GitFlow | Trunk-Based |
|---|---|---|
| Branch count | Many long-lived branches | One (main) + short-lived branches |
| Release model | Scheduled, versioned | Continuous, on-demand |
| Feature isolation | Dedicated feature branches | Feature flags |
| Merge frequency | Weekly or per-release | Multiple times per day |
| Complexity | High — many branches to track | Low — simple topology |
| Best for | Versioned software, mobile apps | SaaS, web apps, APIs |
| CI requirement | Moderate | High — fast builds required |
When to Use GitFlow
GitFlow is the right choice when you have versioned releases, need to maintain multiple production versions simultaneously, or release on a fixed schedule (weekly, biweekly, monthly).
Many teams adopt GitFlow by default and later realize it adds unnecessary complexity. If you deploy to production on every commit, you do not need release branches. If you can toggle features with flags, you do not need feature branches. Start simple and add structure only when you need it.
- You ship versioned software (v1.0, v1.1, v2.0).
- You maintain multiple active release versions.
- You release on a fixed cadence (weekly, monthly, quarterly).
- Mobile apps that require App Store review cycles.
- Desktop software with installer-based distribution.
- Teams that need explicit release stabilization periods.
Mark this lesson complete to store local progress and unlock a cleaner resume path the next time you visit.