| name | git-storytelling-branch-strategy |
| description | Use when planning git branching strategies or managing branches for development. Helps create clear development narratives through effective branch organization and workflow patterns. |
| allowed-tools | Bash, Read |
Git Storytelling - Branch Strategy
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...HEADWrite 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.