ð git-storytelling-branch-strategy
Use when planning git branching strategies or managing branches for development. Helps create clear development narratives through effective branch organization and workflow patterns.
Overview
This skill helps you implement effective branching strategies that tell the story of your development process through organized, purposeful branch management. Good branching creates a clear narrative of parallel development efforts.
Core Concepts
Why Branch Strategy Matters
A good branching strategy:
- Creates clear development narratives - Each branch tells a specific story
- Enables parallel work - Multiple features can develop simultaneously
- Facilitates code review - Changes are isolated and reviewable
- Supports deployment workflows - Different branches for different environments
- Reduces merge conflicts - Smaller, focused branches are easier to merge
- Documents development history - Branch names and structure show intent
The Story of Branches
Think of branches as parallel storylines in your codebase:
- Main branch: The canonical story, always working and deployable
- Feature branches: Side quests that eventually merge into the main story
- Release branches: Chapters being prepared for publication
- Hotfix branches: Emergency patches to the published story
- Development branch: The staging area where stories come together
Branch Naming Conventions
Standard Prefixes
Use consistent prefixes to categorize branches:
feature/ - New features
fix/ - Bug fixes
hotfix/ - Production emergency fixes
refactor/ - Code refactoring
test/ - Testing changes
docs/ - Documentation
chore/ - Maintenance tasks
release/ - Release preparation
Naming Best Practices
Good branch names are:
# GOOD: Clear, descriptive, kebab-case
feature/user-authentication
fix/payment-processing-timeout
refactor/extract-validation-logic
hotfix/critical-security-patch
# BAD: Vague, unclear, inconsistent
feature/new-stuff
fix-thing
my-branch
temp
Including Issue Numbers
Reference tracking system issues:
feature/123-add-user-authentication
fix/456-resolve-memory-leak
hotfix/789-patch-security-vulnerability
Branch Name Format
Follow a consistent pattern:
<type>/<issue-number>-<short-description>
Examples:
feature/234-oauth-integration
fix/567-null-pointer-exception
refactor/890-simplify-error-handling
Common Branching Strategies
Git Flow
A robust branching model for release-based software:
# Main branches (permanent)
main # Production-ready code
develop # Integration branch for features
# Supporting branches (temporary)
feature/* # New features
release/* # Release preparation
hotfix/* # Production fixes
Git Flow Workflow:
# Start new feature
git checkout develop
git checkout -b feature/user-profile
# Work on feature with commits
git commit -m "feat: add user profile model"
git commit -m "feat: add profile update endpoint"
# Finish feature
git checkout develop
git merge --no-ff feature/user-profile
git branch -d feature/user-profile
# Start release
git checkout develop
git checkout -b release/v1.2.0
# Prepare release
git commit -m "chore: bump version to 1.2.0"
git commit -m "docs: update CHANGELOG"
# Finish release
git checkout main
git merge --no-ff release/v1.2.0
git tag -a v1.2.0 -m "Release version 1.2.0"
git checkout develop
git merge --no-ff release/v1.2.0
git branch -d release/v1.2.0
# Emergency hotfix
git checkout main
git checkout -b hotfix/v1.2.1
# Fix and release
git commit -m "fix: critical security issue"
git checkout main
git merge --no-ff hotfix/v1.2.1
git tag -a v1.2.1 -m "Hotfix version 1.2.1"
git checkout develop
git merge --no-ff hotfix/v1.2.1
git branch -d hotfix/v1.2.1
GitHub Flow
A simpler model for continuous deployment:
# Only one main branch
main # Always deployable
# All work in feature branches
feature/* # Features, fixes, everything
GitHub Flow Workflow:
# Create feature branch from main
git checkout main
git pull origin main
git checkout -b feature/add-search
# Make commits
git commit -m "feat: add search component"
git commit -m "test: add search tests"
git commit -m "docs: document search API"
# Push and create pull request
git push -u origin feature/add-search
# After review and CI passes, merge via PR
# Then deploy main branch
# Clean up
git checkout main
git pull origin main
git branch -d feature/add-search
Trunk-Based Development
Minimal branching with short-lived feature branches:
# Main branch
main # The trunk, always deployable
# Short-lived feature branches (< 1 day)
feature/* # Small, quick features
Trunk-Based Workflow:
# Create short-lived feature branch
git checkout main
git pull origin main
git checkout -b feature/update-button-text
# Make focused change
git commit -m "feat: update CTA button text"
# Push and merge same day
git push -u origin feature/update-button-text
# Merge via PR or direct merge
git checkout main
git merge feature/update-button-text
git push origin main
# Delete branch immediately
git branch -d feature/update-button-text
GitLab Flow
Environment branches for deployment stages:
# Main development branch
main # Integration branch
# Environment branches
staging # Staging environment
production # Production environment
# Feature branches
feature/* # Features merge to main
GitLab Flow Workflow:
# Develop feature
git checkout main
git checkout -b feature/notification-system
git commit -m "feat: add notification system"
# Merge to main
git checkout main
git merge feature/notification-system
# Deploy to staging
git checkout staging
git merge main
git push origin staging # Triggers staging deployment
# After testing, deploy to production
git checkout production
git merge staging
git push origin production # Triggers production deployment
Code Examples
Example 1: Starting a Feature Branch
# Update main branch
git checkout main
git pull origin main
# Create feature branch with descriptive name
git checkout -b feature/456-implement-two-factor-auth
# Verify you're on new branch
git branch --show-current
# Output: feature/456-implement-two-factor-auth
# Make initial commit
git commit --allow-empty -m "feat: initialize two-factor authentication feature"
# Push branch to remote
git push -u origin feature/456-implement-two-factor-auth
# Continue development
git commit -m "feat: add TOTP token generation"
git commit -m "feat: add token verification endpoint"
git commit -m "test: add 2FA integration tests"
Example 2: Keeping Feature Branch Updated
# While working on feature branch, main has moved forward
git checkout feature/789-user-dashboard
# Option 1: Rebase (creates linear history)
git fetch origin
git rebase origin/main
# If conflicts occur
git status # See conflicting files
# Fix conflicts in editor
git add .
git rebase --continue
# Option 2: Merge (preserves branch history)
git fetch origin
git merge origin/main
# Resolve any merge conflicts
git add .
git commit -m "merge: resolve conflicts with main"
# Push updated branch
git push --force-with-lease origin feature/789-user-dashboard
Example 3: Release Branch Workflow
# Create release branch from develop
git checkout develop
git pull origin develop
git checkout -b release/v2.0.0
# Prepare release
git commit -m "chore: bump version to 2.0.0"
git commit -m "docs: update CHANGELOG for v2.0.0"
git commit -m "chore: update dependencies"
# Fix bugs found during release testing
git commit -m "fix: resolve edge case in user validation"
git commit -m "fix: correct API response format"
# Merge to main and tag
git checkout main
git merge --no-ff release/v2.0.0
git tag -a v2.0.0 -m "Release version 2.0.0
Major changes:
- New user authentication system
- Improved performance
- Updated API endpoints
See CHANGELOG.md for details."
# Merge back to develop
git checkout develop
git merge --no-ff release/v2.0.0
# Push everything
git push origin main
git push origin develop
git push origin v2.0.0
# Clean up
git branch -d release/v2.0.0
Example 4: Emergency Hotfix
# Production is broken, need immediate fix
git checkout main
git pull origin main
# Create hotfix branch
git checkout -b hotfix/critical-login-bug
# Make the fix
git commit -m "fix: resolve null pointer in login handler
Users unable to log in when email field contains trailing
whitespace. Add trim() to email input processing.
Critical production issue affecting 15% of login attempts.
ð€ Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>"
# Test the fix
npm test
# Merge to main
git checkout main
git merge --no-ff hotfix/critical-login-bug
git tag -a v1.5.1 -m "Hotfix: Login bug fix"
# Deploy immediately
git push origin main
git push origin v1.5.1
# Merge to develop so fix isn't lost
git checkout develop
git merge --no-ff hotfix/critical-login-bug
git push origin develop
# Clean up
git branch -d hotfix/critical-login-bug
git push origin --delete hotfix/critical-login-bug
Example 5: Collaborative Feature Branch
# Developer A starts feature
git checkout -b feature/payment-integration
git commit -m "feat: add payment gateway client"
git push -u origin feature/payment-integration
# Developer B joins the work
git fetch origin
git checkout feature/payment-integration
# Developer B makes changes
git commit -m "feat: add webhook handler"
git pull --rebase origin feature/payment-integration
git push origin feature/payment-integration
# Developer A pulls updates
git checkout feature/payment-integration
git pull --rebase origin feature/payment-integration
# Continue collaborating until complete
git commit -m "test: add payment integration tests"
git commit -m "docs: document payment webhook API"
# Create pull request for review
git push origin feature/payment-integration
Example 6: Experimental Branch
# Trying a risky approach
git checkout -b experiment/new-architecture
# Make experimental commits
git commit -m "experiment: try event-driven architecture"
git commit -m "experiment: add message queue integration"
# Test the approach
npm test
npm run benchmark
# Decision 1: Experiment failed, abandon it
git checkout main
git branch -D experiment/new-architecture
# Decision 2: Experiment succeeded, integrate it
git checkout -b feature/event-driven-refactor
git merge experiment/new-architecture
git commit -m "refactor: migrate to event-driven architecture"
git push -u origin feature/event-driven-refactor
# Clean up experiment branch
git branch -d experiment/new-architecture
Example 7: Stacked Branches
# Large feature requires multiple PRs
git checkout main
# First part: Database schema
git checkout -b feature/schema-updates
git commit -m "feat: add new database tables"
git commit -m "feat: add migration scripts"
git push -u origin feature/schema-updates
# Second part: API (depends on schema)
git checkout -b feature/api-endpoints
git commit -m "feat: add user API endpoints"
git commit -m "test: add API integration tests"
git push -u origin feature/api-endpoints
# Third part: UI (depends on API)
git checkout -b feature/user-interface
git commit -m "feat: add user management UI"
git commit -m "test: add UI component tests"
git push -u origin feature/user-interface
# Merge order: schema -> API -> UI
# As each PR is approved and merged, rebase next branch onto main
Example 8: Branch Cleanup
# List all branches
git branch -a
# Delete local branches that are merged
git branch --merged main | grep -v "main" | xargs git branch -d
# Delete remote branch
git push origin --delete feature/old-feature
# Prune remote tracking branches
git fetch --prune
# Delete local branches that no longer exist on remote
git remote prune origin
# Interactive cleanup
git branch -vv | grep ': gone]' | awk '{print $1}' | xargs git branch -D
# See stale branches
git for-each-ref --sort=-committerdate refs/heads/ \
--format='%(committerdate:short) %(refname:short)'
When to Use This Skill
Use this skill when:
- Starting a new project and establishing branching conventions
- Planning feature development across multiple developers
- Setting up CI/CD pipelines with branch-based deployments
- Coordinating release schedules and version management
- Managing hotfixes to production environments
- Onboarding new team members to git workflow
- Resolving complex merge situations
- Refactoring large portions of codebase
- Experimenting with architectural changes
- Maintaining multiple versions of software simultaneously
Best Practices
-
Keep branches short-lived - Merge within days, not weeks, to reduce merge conflicts
-
Use descriptive branch names - Future you will thank present you
-
Delete merged branches - Keep repository clean and navigable
-
One purpose per branch - Don't mix features, fixes, and refactoring
-
Update from main regularly - Frequent rebasing/merging reduces conflict pain
-
Protect main branch - Require PR reviews, passing tests before merge
-
Use branch prefixes consistently - Enables automation and filtering
-
Include issue numbers - Creates traceability to requirements
-
Push branches early - Enables collaboration and provides backup
-
Create PR early as draft - Get early feedback on approach
-
Review changes before creating PR - Use
git diff main...HEAD -
Write meaningful merge commits - Explain what the branch accomplished
-
Tag releases - Mark important points in history
-
Document branching strategy - In README or CONTRIBUTING guide
-
Automate branch cleanup - Use tools to delete stale branches
Common Pitfalls
-
Long-lived branches - Weeks-old branches become nightmare to merge
-
Inconsistent naming - Mix of conventions confuses everyone
-
Working directly on main - Bypasses review and CI checks
-
Forgetting to pull before branching - Start from stale base
-
Creating branches from wrong base - Feature from feature instead of main
-
Not updating feature branches - Drift from main causes conflicts
-
Keeping too many local branches - Clutters workspace
-
Force pushing shared branches - Destroys collaborator's work
-
Mixing unrelated changes - One branch does too many things
-
Not cleaning up merged branches - Repository becomes graveyard
-
Creating nested branch hierarchies - Overly complex dependencies
-
Merging without testing - Breaks main branch
-
No branch protection rules - Anyone can push to main
-
Using generic branch names - "fix" or "update" tells nothing
-
Forgetting to push branches - Work exists only locally
Resources
Git Commands for Branch Management
# Create and switch to new branch
git checkout -b <branch-name>
git switch -c <branch-name> # Modern alternative
# Switch branches
git checkout <branch-name>
git switch <branch-name> # Modern alternative
# List branches
git branch # Local branches
git branch -r # Remote branches
git branch -a # All branches
git branch -vv # Verbose with tracking info
# Delete branches
git branch -d <branch> # Delete if merged
git branch -D <branch> # Force delete
git push origin --delete <branch> # Delete remote
# Rename branch
git branch -m <old> <new> # Rename local
git push origin -u <new> # Push renamed
git push origin --delete <old> # Delete old remote
# Track remote branch
git branch -u origin/<branch>
git checkout --track origin/<branch>
# Compare branches
git diff main...feature-branch
git log main..feature-branch
git log --graph --oneline --all
# Merge strategies
git merge <branch> # Regular merge
git merge --no-ff <branch> # Force merge commit
git merge --squash <branch> # Squash into one commit
# Rebase
git rebase main # Rebase onto main
git rebase -i main # Interactive rebase
git rebase --continue # Continue after conflicts
git rebase --abort # Abandon rebase
# Cherry-pick
git cherry-pick <commit-hash> # Apply specific commit
Branch Protection Rules
Configure on GitHub/GitLab:
Protected Branch: main
- Require pull request reviews: 2 reviewers
- Require status checks to pass: true
- Tests
- Linting
- Build
- Require branches to be up to date: true
- Include administrators: true
- Restrict push: true
- Allow force pushes: false
- Allow deletions: false
Git Aliases for Branch Management
Add to .gitconfig:
[alias]
# Branch management
br = branch
co = checkout
cob = checkout -b
# Branch cleanup
bclean = "!f() { git branch --merged ${1-main} | grep -v " ${1-main}$" | xargs git branch -d; }; f"
# Branch status
bstat = branch -vv
# Recent branches
recent = branch --sort=-committerdate --format='%(committerdate:short) %(refname:short)'
# Current branch name
current = branch --show-current
# Push current branch
pub = "!git push -u origin $(git current)"
# Update branch from main
update = "!git fetch origin && git rebase origin/main"
Visualization Tools
# View branch structure
git log --graph --oneline --all --decorate
# Detailed branch graph
git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --all
# See all branches with last commit
git branch -v
# Branch topology
git show-branch
# Visual git tools
gitk --all # Built-in visualizer
git gui # Built-in GUI
Related Skills
- git-storytelling-commit-strategy: When to commit on branches
- git-storytelling-commit-messages: Writing clear commit messages
- code-reviewer: How branches facilitate code review
Advanced Patterns
Feature Flags for Trunk-Based Development
Instead of long-lived branches, use feature flags:
// feature-flags.js
export const features = {
newUserDashboard: process.env.ENABLE_NEW_DASHBOARD === 'true',
betaPaymentFlow: process.env.ENABLE_BETA_PAYMENT === 'true',
};
// component.jsx
import { features } from './feature-flags';
function Dashboard() {
if (features.newUserDashboard) {
return <NewDashboard />;
}
return <LegacyDashboard />;
}
This allows merging incomplete features to main without exposing them:
# Commit partial feature to main
git checkout main
git commit -m "feat: add new dashboard (behind feature flag)"
git push origin main
# Feature is deployed but not active
# Enable when ready via environment variable
Branch Strategy Documentation
Document in CONTRIBUTING.md:
## Branching Strategy
We use GitHub Flow with the following conventions:
### Branch Types
- `feature/*` - New features
- `fix/*` - Bug fixes
- `hotfix/*` - Production emergency fixes
- `refactor/*` - Code improvements
- `docs/*` - Documentation
### Workflow
1. Create branch from `main`: `git checkout -b feature/123-description`
2. Make commits following our commit message guidelines
3. Keep branch updated: `git rebase origin/main`
4. Push and create PR: `git push -u origin feature/123-description`
5. After approval and CI passes, merge via PR
6. Delete branch after merge
### Branch Naming
Format: `<type>/<issue>-<description>`
Examples:
- `feature/456-user-authentication`
- `fix/789-memory-leak`
- `hotfix/101-critical-security-patch`
### Branch Lifecycle
- Create branches from up-to-date `main`
- Keep branches under 3 days old
- Delete immediately after merge
- Never force push to `main`
Conclusion
Effective branch strategy is essential for telling a clear development story. By following consistent naming conventions, keeping branches focused and short-lived, and choosing the right branching model for your team's needs, you create a git history that is navigable, understandable, and valuable.
Remember: Branches are temporary workspaces for focused development. Use them to isolate changes, enable parallel work, and facilitate code review. Then merge them and clean them up. A clean branch structure is a sign of a healthy, well-managed codebase.