Branch naming conventions, Git Flow vs trunk-based development, feature branch lifecycle, and release strategies. Reference when creating branches, planning releases, or choosing a branching model.
Every branch name must follow a structured prefix convention. This keeps the repository navigable, enables CI/CD automation, and makes intent immediately clear.
| Prefix | Purpose | Example |
|---|---|---|
feature/ |
New functionality or capability | feature/user-avatar-upload |
fix/ |
Bug fixes for existing behavior | fix/login-redirect-loop |
hotfix/ |
Urgent production fixes | hotfix/payment-null-pointer |
release/ |
Release preparation and stabilization | release/2.4.0 |
chore/ |
Maintenance, dependencies, tooling | chore/upgrade-eslint-9 |
docs/ |
Documentation-only changes | docs/api-authentication-guide |
refactor/ |
Code restructuring without behavior change | refactor/extract-billing-service |
test/ |
Adding or fixing tests only | test/payment-edge-cases |
experiment/ |
Exploratory work, not intended for merge | experiment/graphql-federation |
feature/add-user-search not feature/Add_User_Searchfix/cart-total not fix/the-bug-where-cart-total-shows-wrong-amountfeature/PROJ-1234-user-avatar-uploadfeature/search-api not feature/anthonys-search-workfix/login-redirect-loop not fix/bug or fix/stuffWhen integrating with issue trackers, place the ticket number immediately after the prefix:
feature/PROJ-1234-user-avatar-upload
fix/GH-567-null-pointer-on-empty-cart
hotfix/INC-89-payment-gateway-timeout
This enables automated linking between branches, PRs, and issues.
The simplest model. All developers work on short-lived branches off main and merge back frequently.
main āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
\ / \ / \ /
āāā āāā ā
(feature) (fix) (feature)
When to Use Trunk-Based Development:
Rules:
main must pass all testsmainmain on every merge (or at minimum daily)Branch Lifecycle:
# Create branch from main
git checkout main && git pull
git checkout -b feature/PROJ-123-add-search
# Work in small increments, commit frequently
git add -p && git commit -m "Add search index configuration"
git add -p && git commit -m "Implement basic search query endpoint"
# Rebase onto main before merging
git fetch origin && git rebase origin/main
# Merge via PR (squash or merge commit per team convention)
# Delete branch immediately after merge
A structured model with multiple long-lived branches for teams that need formal release management.
main āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
| |
develop āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
\ / \ / | /
feature āā āā release ā
\ /
āāā
When to Use Git Flow:
Branch Structure:
| Branch | Lifetime | Merges Into | Purpose |
|---|---|---|---|
main |
Permanent | -- | Production-ready code, tagged releases |
develop |
Permanent | main (via release) |
Integration branch for features |
feature/* |
Temporary | develop |
New work in progress |
release/* |
Temporary | main and develop |
Release stabilization |
hotfix/* |
Temporary | main and develop |
Urgent production fixes |
Release Workflow:
# 1. Create release branch from develop
git checkout develop && git pull
git checkout -b release/2.4.0
# 2. Only bug fixes, documentation, and release prep on this branch
# No new features allowed
# 3. When stable, merge to main and tag
git checkout main && git merge --no-ff release/2.4.0
git tag -a v2.4.0 -m "Release 2.4.0"
# 4. Back-merge to develop
git checkout develop && git merge --no-ff release/2.4.0
# 5. Delete release branch
git branch -d release/2.4.0
Hotfix Workflow:
# 1. Branch from main
git checkout main && git pull
git checkout -b hotfix/payment-null-pointer
# 2. Fix the issue, commit
# 3. Merge to both main and develop
git checkout main && git merge --no-ff hotfix/payment-null-pointer
git tag -a v2.4.1 -m "Hotfix: payment null pointer"
git checkout develop && git merge --no-ff hotfix/payment-null-pointer
# 4. Delete hotfix branch
git branch -d hotfix/payment-null-pointer
A simplified model that sits between trunk-based and Git Flow.
When to Use GitHub Flow:
Rules:
main is always deployablemain for any workmain after review and CI passesmainbranch_protection:
main:
required_reviews: 1 # At least one approval
dismiss_stale_reviews: true # Re-review after new pushes
require_status_checks: true # CI must pass
required_checks:
- build
- test
- lint
restrict_pushes: true # No direct pushes
require_linear_history: true # Squash or rebase only
include_administrators: true # Rules apply to everyone
| Rule | main |
develop |
release/* |
feature/* |
|---|---|---|---|---|
| Require PR | Yes | Yes | Yes | No |
| Required reviewers | 1-2 | 1 | 1-2 | 0 |
| Require CI pass | Yes | Yes | Yes | Optional |
| Allow force push | No | No | No | Yes (owner) |
| Allow deletion | No | No | After merge | Yes |
| Require signed commits | Recommended | Optional | Optional | No |
MAJOR.MINOR.PATCH
| | |
| | āāā Bug fixes, no API changes
| āāāāāāāāā New features, backward compatible
āāāāāāāāāāāāāāā Breaking changes
MAJOR (breaking): Removing an API endpoint. Changing a response format. Renaming a public function. Dropping support for a platform.
MINOR (feature): Adding a new endpoint. Adding optional parameters. New configuration options. New UI features.
PATCH (fix): Bug fixes. Security patches. Performance improvements. Documentation corrections.
2.4.0-alpha.1 # Alpha pre-release
2.4.0-beta.2 # Beta pre-release
2.4.0-rc.1 # Release candidate
2.4.0+build.1234 # Build metadata (ignored in precedence)
Before creating a release tag:
# Annotated tag (preferred for releases)
git tag -a v2.4.0 -m "Release 2.4.0: Add user search, fix cart totals"
# Push tags to remote
git push origin v2.4.0
# Or push all tags
git push origin --tags
v: v2.4.0 not 2.4.01. CREATE āā Branch from main/develop with proper prefix
2. DEVELOP āā Commit regularly, push daily
3. SYNC āā Rebase/merge from upstream regularly
4. REVIEW āā Open PR, request review
5. REVISE āā Address feedback, push updates
6. MERGE āā Squash or merge commit per convention
7. CLEANUP āā Delete branch locally and remotely
# Option A: Rebase (cleaner history, use for personal branches)
git fetch origin
git rebase origin/main
# Option B: Merge (preserves history, use for shared branches)
git fetch origin
git merge origin/main
Use this flowchart to choose your branching model:
Do you deploy continuously to production?
āāā Yes: Do you need PR-based code review?
ā āāā Yes āāāŗ GitHub Flow
ā āāā No āāāŗ Trunk-Based Development
āāā No: Do you maintain multiple release versions?
āāā Yes āāāŗ Git Flow
āāā No: Do you have scheduled release cycles?
āāā Yes āāāŗ Git Flow (simplified)
āāā No āāāŗ GitHub Flow