Use when a team has scheduled releases, maintains multiple supported versions simultaneously, or operates in a regulated environment requiring formal release approval gates.
Scanned 9/8/2026
Install to Claude Code
npx -y skills add jeffreytse/grimoire-core --skill apply-gitflow --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Apply Gitflow?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/jeffreytse-apply-gitflow)More formats (shields.io, HTML) on the badges page.
---
name: apply-gitflow
description: Use when a team has scheduled releases, maintains multiple supported versions simultaneously, or operates in a regulated environment requiring formal release approval gates.
source: Driessen "A Successful Git Branching Model" (nvie.com, 2010); git-flow CLI (Petersen, 2010); DORA State of DevOps Report 2019
tags: [git, branching, gitflow, release-management, versioning, scheduled-releases, regulated]
---
# Apply GitFlow
Implement the GitFlow branching model — two permanent branches (`main`, `develop`) plus short-lived `feature/`, `release/`, and `hotfix/` branches — to manage scheduled releases with clean separation between in-progress work and production code.
## Why This Is Best Practice
**Adopted by:** GitFlow became the de facto standard for scheduled-release software after Driessen's 2010 blog post; git-flow CLI (Petersen) ships natively in Homebrew, apt, and most git clients; widely used in enterprise Java, PHP, and regulated-industry software where batch QA gates and formal release approvals are required
**Impact:** GitFlow's branch model provides a provable audit trail — every production change traces to either a tagged release merge or a named hotfix — a requirement in SOC 2, ISO 27001, and FDA 21 CFR Part 11 regulated software environments; separating `develop` from `main` eliminates the "I deployed unreleased features by accident" class of incident common in single-branch models
**Why best:** GitHub Flow has no release stabilization concept — a hotfix on a busy `main` can inadvertently ship unreleased features; trunk-based development requires feature-flag infrastructure that teams in regulated or batch-release environments often cannot adopt; GitFlow's release branch gives teams a dedicated stabilization window with a hard boundary against new feature inclusion
Sources: Driessen "A Successful Git Branching Model" (nvie.com, 2010); Forsgren, Humble & Kim "Accelerate" (IT Revolution, 2018) §2 — identifies GitFlow as appropriate for release-gated environments; git-flow CLI (github.com/nvie/gitflow)
## Steps
### 1. Initialize the two permanent branches
```bash
git checkout -b develop main # if develop does not yet exist
git push -u origin develop
```
Configure branch protections on both:
- `main`: no direct push, require CI pass, require at least 1 approval
- `develop`: require CI pass, require at least 1 approval
`main` = production. `develop` = integration target for all feature work. Never commit directly to either.
### 2. Feature development
```bash
# Start
git checkout -b feature/PROJ-42-user-auth develop
# Finish — open PR targeting develop, squash-merge on approval
git checkout develop
git merge --squash feature/PROJ-42-user-auth
git commit -m "feat(auth): add user authentication"
git branch -d feature/PROJ-42-user-auth
```
**Rules for feature branches:**
- Branch from `develop` only — never from `main` or a release branch
- PR target is `develop` — never `main`
- Delete after merge
- No feature branch lives beyond 2 days without an active PR; use feature flags for longer work
### 3. Release branch
Cut a release branch when `develop` has all features for the next version and the team is ready for QA:
```bash
# Cut
git checkout -b release/2.1.0 develop
```
On the release branch, only bug fixes are allowed — **no new features**. This is the stabilization window.
```bash
# Bug fix discovered during QA — commit directly to release branch
git checkout release/2.1.0
git commit -m "fix(auth): handle null token on logout"
```
When QA passes:
```bash
# Merge to main and tag
git checkout main
git merge --no-ff release/2.1.0
git tag -a v2.1.0 -m "Release 2.1.0"
# Merge back to develop (captures QA bug fixes)
git checkout develop
git merge --no-ff release/2.1.0
# Delete
git branch -d release/2.1.0
git push origin --delete release/2.1.0
git push origin main develop --tags
```
### 4. Hotfix branch
Production-only emergency fix — branches from `main`, not `develop`:
```bash
# Cut from main
git checkout -b hotfix/auth-bypass main
# Fix and commit
git commit -m "fix(auth): prevent token reuse after logout"
```
When the fix is ready:
```bash
# Merge to main and tag
git checkout main
git merge --no-ff hotfix/auth-bypass
git tag -a v2.0.1 -m "Hotfix 2.0.1"
# Merge to develop (critical: keeps develop in sync)
git checkout develop
git merge --no-ff hotfix/auth-bypass
# If a release branch is currently active, merge there too
# git checkout release/2.1.0 && git merge --no-ff hotfix/auth-bypass
# Delete
git branch -d hotfix/auth-bypass
git push origin main develop --tags
```
### 5. Branch naming conventions
| Branch | Pattern | Example |
|--------|---------|---------|
| Feature | `feature/<ticket>-<description>` | `feature/PROJ-42-user-auth` |
| Release | `release/<semver>` | `release/2.1.0` |
| Hotfix | `hotfix/<description>` | `hotfix/auth-bypass` |
Never use bare `fix/`, `bugfix/`, or `patch/` prefixes at top level — route through `feature/` (if targeting `develop`) or `hotfix/` (if targeting `main`).
### 6. Document in CONTRIBUTING.md
Add a one-section summary to CONTRIBUTING.md covering:
- Branch types and their purpose
- Where to branch from and where to merge to
- The release cut process (who cuts, on what trigger)
- Hotfix escalation path
Every contributor must be able to answer "where do I branch from?" from CONTRIBUTING.md alone.
## Rules
- `main` is production only — its history must be a sequence of tagged release merges and hotfix merges, nothing else
- `develop` is the integration branch — all feature PRs target `develop`
- Release branches are feature-freeze — no new features, only bug fixes
- Hotfix merges must land on **both** `main` and `develop` (and any active `release/*` branch) — skipping `develop` causes the bug to reappear in the next release
- Every merge to `main` must be tagged — untagged `main` commits are a sign GitFlow is not being followed
- Feature branches that outlive 2 days without a PR are a smell — break the work smaller or use a feature flag
## Common Mistakes
- **Feature PR targeting `main`** — bypasses `develop`; unreleased features can reach production in the next hotfix
- **Forgetting to merge release branch back to `develop`** — QA bug fixes are lost; they reappear in the next release
- **Hotfix merged to `main` only** — the fixed bug resurfaces when `develop` is next released
- **Cutting a release branch from `main` instead of `develop`** — the release contains only previous release content, not current features
- **No branch protection on `develop`** — direct commits bypass CI and code review; `develop` becomes unreliable as an integration target
## When NOT to Use
- When the team deploys more than once a week — GitFlow's batch pipeline adds overhead that blocks fast delivery; use trunk-based development or GitHub Flow instead
- When the team is ≤5 engineers with no formal QA gate — the release branch stabilization window adds process without proportional benefit; GitHub Flow suffices
- When the codebase has no CI pipeline — GitFlow assumes CI guards both `main` and `develop`; without it, the model provides structure but no safety
- When maintaining only one production version at a time with no patch support requirements — the multi-branch model adds complexity that trunk-based with tags handles more simply
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!