Agent skill

git-branching-strategy

This skill should be used when starting new feature work, mid-feature when wanting to add unrelated changes, when a branch has grown beyond 20 commits, or when unsure whether to create a new branch. Covers one-feature-one-branch rule, branch size targets, and when to split branches.

Stars 163
Forks 31

Install this agent skill to your Project

npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/data/git-branching-strategy

SKILL.md

Git Branching Strategy

Prevent monster branches by following disciplined branching and merge practices.

When to Use This Skill

Invoke this skill when:

โœ… Starting New Work

  • About to implement a new feature
  • Planning to fix a bug
  • Starting refactoring work
  • Adding documentation

โš ๏ธ Mid-Feature Warning Signs

  • Thinking "while I'm here, I'll also..."
  • Wanting to add unrelated functionality
  • Branch has grown beyond 20 commits
  • Multiple unrelated files changed
  • Changes would be difficult to understand

๐ŸŽฏ Decision Points

  • Unsure whether to create new branch or continue current
  • Wondering if branch is getting too large
  • Considering adding "just one more thing"
  • Ready to merge but branch feels messy

โš ๏ธ Pre-Implementation Checklist

BEFORE writing ANY code, answer these questions:

1. Is this non-trivial work?

Non-trivial = ANY of these:

  • โœ… Changes >2 files
  • โœ… Refactoring existing code
  • โœ… Adding new features/functionality
  • โœ… Implementing planned tasks
  • โœ… Bug fixes requiring changes to multiple components

Trivial = ALL of these:

  • โŒ Fixing typo in single file
  • โŒ Updating documentation only (markdown, comments)
  • โŒ One-line fix in single file

2. If Non-Trivial โ†’ CREATE FEATURE BRANCH

bash
# Ensure main branch is up to date
git checkout main
git pull origin main

# Create feature branch (choose appropriate prefix)
git checkout -b feature/descriptive-name    # For new features
git checkout -b refactor/descriptive-name   # For refactoring
git checkout -b fix/descriptive-name        # For bug fixes

Examples:

  • feature/user-authentication - New auth implementation
  • refactor/error-handling - Standardize error handling
  • fix/login-redirect - Fix login redirect bug

3. Golden Rule

When in doubt, use a feature branch.

Feature branches provide:

  • ๐Ÿ“ Documentation of what changed and why
  • ๐Ÿ“Š Clear history of feature development
  • ๐Ÿ”„ Easy to revert if needed
  • ๐Ÿงช Isolated testing before merge

The Problem: Monster Branches

What Happens

Timeline:

  • Started as "add feature X"
  • Grew to include features Y, Z, refactoring, and bug fixes
  • 100+ commits, multiple intertwined features
  • Difficult to review, hard to merge, risky to revert

Symptoms:

  • โŒ Multiple distinct features mixed together
  • โŒ Hard to describe what the branch does in one sentence
  • โŒ Changes span unrelated systems
  • โŒ Commit history is difficult to follow
  • โŒ Rolling back one feature means losing others

Consequences:

  • Long-lived branch diverges from main
  • Merge conflicts accumulate
  • Testing becomes all-or-nothing
  • Can't ship features incrementally
  • Hard to isolate bugs introduced

Solution: Small, Focused Branches

The Golden Rule

One feature, one branch, one merge.

If you can't describe the branch in a single sentence without using "and", it's too big.

Good Examples

โœ… Good: feat/user-auth - "Add basic user authentication" โœ… Good: feat/smart-fields - "Implement smart field system" โœ… Good: fix/race-condition - "Fix optimistic update race condition" โœ… Good: refactor/scss-modules - "Convert SCSS to module system" โœ… Good: docs/contributing - "Add contributing guidelines"

Bad Examples

โŒ Bad: feat/improvements - Too vague, likely includes unrelated changes โŒ Bad: fix/various-bugs - Multiple unrelated fixes should be separate branches โŒ Bad: wip/stuff - Not descriptive, suggests unfocused work

Branch Size Guidelines

Target Size

Ideal: 5-15 commits, 1-5 files changed significantly Acceptable: Up to 30 commits, up to 10 files Too Large: 50+ commits, 20+ files

Exception: Large refactors that are purely mechanical

Commit Count Checkpoints

5 commits โ†’ Normal feature pace
10 commits โ†’ Check: Am I still focused on one feature?
20 commits โ†’ WARNING: Consider splitting or wrapping up
30 commits โ†’ CRITICAL: Finish and merge, or split into multiple branches
50+ commits โ†’ MONSTER: This should have been 3-5 separate branches

When Branch Size is Justified

โœ… Acceptable large branches:

  • Pure refactoring (converting styles, modularization)
  • Data migrations (changing structure across many files)
  • Framework version upgrades (mechanical API changes)
  • Initial feature implementation with tests and docs

โŒ Unacceptable large branches:

  • Multiple unrelated features
  • Feature + "while I'm here" improvements
  • Feature + unrelated bug fixes
  • Feature + refactoring that isn't required for feature

Decision Tree: New Branch or Continue?

Question 1: Is this change related to current branch?

New change โ†’ Related to current feature?
  โ†“ YES (same system, same goal)
  โ†’ Continue current branch

  โ†“ NO (different system, different goal)
  โ†’ Question 2

Question 2: Is current branch ready to merge?

Current branch โ†’ Ready to merge?
  โ†“ YES (feature complete, tests pass)
  โ†’ Merge current, then new branch for new work

  โ†“ NO (feature incomplete)
  โ†’ Question 3

Question 3: Is new work required for current feature?

New work โ†’ Required for current feature to work?
  โ†“ YES (dependency)
  โ†’ Continue current branch

  โ†“ NO (nice-to-have, improvement, unrelated)
  โ†’ Stash current, new branch, finish new, resume current

Branch Naming Conventions

Format

<type>/<short-description>

Types

  • feat/ - New feature or enhancement
  • fix/ - Bug fix
  • refactor/ - Code restructuring without behavior change
  • docs/ - Documentation only
  • test/ - Adding or fixing tests
  • chore/ - Build, tooling, dependencies

Examples

feat/user-auth
feat/smart-fields
feat/dashboard
fix/login-redirect
fix/memory-leak
refactor/scss-modules
refactor/modularization
docs/contributing
docs/api-guide
chore/update-deps

Avoid

โŒ feature/ - Use feat/ (shorter) โŒ bugfix/ - Use fix/ (shorter) โŒ wip/ - Work in progress is implied, use descriptive name โŒ my-branch - Not descriptive โŒ feat/add-feature - Redundant "add"

Branch Lifecycle

1. Plan and Scope

Before creating branch:

  • Can I describe this in one sentence?
  • Is this the smallest useful increment?
  • Does this depend on other incomplete work?
  • Will this take more than 30 commits?

If >30 commits expected: Break into smaller features first.

2. Create Branch

bash
# From main (or integration branch)
git checkout main
git pull origin main

# Create feature branch
git checkout -b feat/descriptive-name

3. Work on Feature

Commit discipline:

  • Small, focused commits
  • Clear commit messages
  • Commit related changes together
  • Don't mix formatting with logic changes

Check progress regularly:

bash
# How many commits?
git log main..HEAD --oneline | wc -l

# How many files changed?
git diff main --stat

# Am I still focused?
git log --oneline -10  # Review recent commits

4. Recognize When to Split

Warning signs:

  • Commit messages use "and" frequently
  • Multiple unrelated // TODO comments
  • You've forgotten what early commits did
  • Summary of changes needs 3+ bullet points for unrelated changes

How to split:

bash
# Option A: Finish current, branch for next
git commit -m "Complete X feature"
# Merge feat/x
git checkout -b feat/y  # Start next feature

# Option B: Stash incomplete, branch for urgent work
git stash
git checkout -b fix/urgent-bug
# Fix and merge
git checkout feat/original
git stash pop

5. Prepare for Merge

Before merging:

bash
# Rebase on latest main
git fetch origin
git rebase origin/main

# Review all changes
git diff origin/main

# Check commit history is clean
git log origin/main..HEAD --oneline

# Run tests if applicable
npm test  # or your test command

6. Merge to Main

bash
# Switch to main and merge
git checkout main
git pull origin main
git merge --no-ff feat/descriptive-name

# Push to remote
git push origin main

# Delete local branch
git branch -d feat/descriptive-name

Note: --no-ff creates a merge commit even for fast-forward merges, preserving branch history.

Commit Message Conventions

Format

<type>: <short description>

<optional body>

<optional footer>

Types

Same as branch types:

  • feat: - New feature
  • fix: - Bug fix
  • refactor: - Code restructuring
  • docs: - Documentation
  • test: - Tests
  • chore: - Build/tooling

Guidelines

Good commit messages:

feat: Add smart field system with lookups

Implements interactive fields that open selection dialogs
filtered by context. Includes helper and click handler integration.

Closes #42

Bad commit messages:

โŒ "Updates"
โŒ "Fix stuff"
โŒ "WIP"
โŒ "More changes"
โŒ "Final commit (hopefully)"

Commit Message Best Practices

  • Present tense: "Add feature" not "Added feature"
  • Imperative mood: "Fix bug" not "Fixes bug"
  • Capitalize first word: "Add feature" not "add feature"
  • No period at end: "Add feature" not "Add feature."
  • Body explains why, not what: Code shows what, message explains why

When to Split an Existing Branch

Recognize the Need

You should split if:

  • Branch has 40+ commits and isn't done
  • You can't summarize the changes coherently
  • Rolling back would lose multiple independent features
  • Commit history mixes unrelated changes

How to Split

Strategy A: Extract Completed Features

bash
# Current branch: feat/massive (50 commits)
# Goal: Extract first feature into separate branch

# 1. Create new branch from main
git checkout main
git checkout -b feat/extracted-feature

# 2. Cherry-pick relevant commits
git log feat/massive --oneline  # Find commit SHAs
git cherry-pick abc123 def456 ghi789

# 3. Merge the extracted feature
git checkout main
git merge --no-ff feat/extracted-feature
git push origin main
git branch -d feat/extracted-feature

# 4. Rebase massive branch to remove duplicates
git checkout feat/massive
git rebase main

Strategy B: Start Fresh, Reference Old

bash
# Current branch: feat/massive (too messy to salvage)

# 1. Create new branch from main
git checkout main
git checkout -b feat/feature-1-clean

# 2. Manually apply changes from massive branch
# (Copy files, make clean commits)

# 3. Repeat for each feature
git checkout main
git checkout -b feat/feature-2-clean

# 4. Abandon feat/massive after all features extracted
git branch -D feat/massive

Quick Checklist

Before Starting Work

  • One sentence description of what I'm building
  • Checked if this should be separate from current branch
  • Created appropriately named branch from main
  • Estimated this will take <30 commits

During Work

  • Commit messages are clear and focused
  • Not mixing unrelated changes in same commit
  • Checking commit count every 5-10 commits
  • Resisting "while I'm here" temptations

Before Merging

  • Branch has <30 commits (or justifiable if larger)
  • All commits are related to the same feature
  • Rebased on latest main
  • Can describe changes in 1-3 sentences
  • Commit history is clean and logical
  • Tests pass (if applicable)

Danger Signs (Stop and Split)

  • โš ๏ธ More than 30 commits
  • โš ๏ธ Changed more than 15 unrelated files
  • โš ๏ธ Commit messages have "also", "and", "while here"
  • โš ๏ธ Can't remember what early commits did
  • โš ๏ธ Summary needs multiple unrelated bullet points

Common Scenarios

"I'm halfway through feature X, noticed bug Y"

If bug blocks feature X: โ†’ Fix in current branch

If bug is unrelated: โ†’ Stash current work, create fix/bug-y, merge it, resume feature X

"I want to add feature B while working on feature A"

If B is required for A: โ†’ Continue current branch

If B is independent: โ†’ Finish A first, then branch for B

If B is urgent and A is incomplete: โ†’ Stash A, branch for B, merge B, resume A

"My branch has 40 commits, should I split?"

Yes. Options:

  1. Extract completed portions into separate branches (cherry-pick)
  2. Finish current branch as-is, vow to split next time
  3. Start fresh with clean branches for each feature

"I made formatting changes along with feature changes"

Separate them:

bash
# Approach 1: Amend last commit to remove formatting
git reset HEAD~1
git add <feature files only>
git commit -m "feat: add feature"
git add <formatting files>
git commit -m "chore: format code"

# Approach 2: Split into two branches
# - Branch 1: Formatting only (refactor/format-cleanup) - merge first
# - Branch 2: Feature only (feat/my-feature) - merge after

Remember: When in doubt, split it out. Smaller branches are easier to understand, safer to merge, and faster to ship.


Last Updated: 2026-01-05

Didn't find tool you were looking for?

Be as detailed as possible for better results