Skip to main content

Branching Fundamentals

Quick Summary

A branch in Git is a lightweight, movable pointer to a commit. Creating a branch takes milliseconds and costs almost nothing. This makes branching the primary tool for working on features, fixes, and experiments without disturbing stable code.


Mental Model

gitGraph
commit id: "C1"
commit id: "C2"
branch feature/auth
commit id: "C3 (auth)"
commit id: "C4 (auth)"
checkout main
commit id: "C5 (hotfix)"
merge feature/auth id: "C6 (merge)"

Key insight: Branches are just labels that automatically advance when you make commits. main and feature/auth are both just 40-character pointers to specific commits.


Core Branch Commands

Create a Branch

# Create a branch (stays on current branch)
git branch feature/login

# Create AND switch to a new branch
git checkout -b feature/login

# Modern alternative (Git 2.23+)
git switch -c feature/login

Switch Branches

# Classic
git checkout feature/login

# Modern (Git 2.23+)
git switch feature/login

# Switch back to previous branch
git switch -

List Branches

# Local branches
git branch

# All branches (local + remote)
git branch -a

# Branches with last commit info
git branch -v

# Branches already merged into current branch
git branch --merged

# Branches NOT yet merged
git branch --no-merged

Expected output:

$ git branch -v
* main a1b2c3d feat: add user authentication
feature/login d4e5f6a WIP: login form validation
fix/typo b2c3d4e fix: correct email regex

Delete a Branch

# Delete a merged branch
git branch -d feature/login

# Force-delete an unmerged branch
git branch -D feature/experiment

# Delete a remote branch
git push origin --delete feature/login
Before deleting

Always verify the branch is merged: git branch --merged. Deleting an unmerged branch with -D may lose commits.

Rename a Branch

# Rename current branch
git branch -m new-name

# Rename a specific branch
git branch -m old-name new-name

# Update remote after rename
git push origin -u new-name
git push origin --delete old-name

Understanding HEAD

HEAD is a special pointer that tells Git which branch (or commit) you're currently on:

flowchart LR
HEAD["HEAD"] --> main["main"]
main --> C3["Commit C3"]
feature["feature/api"] --> C5["Commit C5"]
C5 --> C4["Commit C4"]
C4 --> C2["Commit C2"]
C3 --> C2
C2 --> C1["Commit C1"]
# See where HEAD points
cat .git/HEAD
## Output: ref: refs/heads/main
StateMeaning
HEAD → main → C3Normal: you're on branch main at commit C3
HEAD → C3 (no branch)Detached HEAD: you're not on any branch (dangerous for new commits)
Detached HEAD

If you checkout a specific commit hash (not a branch name), you enter "detached HEAD" state. Any commits you make here will be orphaned when you switch away. To keep them, create a branch: git switch -c save-my-work.


Branch Naming Conventions

PatternWhen to UseExample
feature/<name>New featurefeature/user-dashboard
fix/<name>Bug fixfix/login-timeout
hotfix/<name>Urgent production fixhotfix/security-patch
docs/<name>Documentation changesdocs/api-guide
refactor/<name>Code restructurerefactor/database-layer
test/<name>Adding teststest/auth-integration
chore/<name>Maintenance taskschore/update-deps

Rules for good branch names:

  • Use lowercase with hyphens (not underscores or spaces)
  • Keep names short but descriptive
  • Include ticket numbers if applicable: feature/PROJ-123-user-auth

Decision Guide

What You WantCommand
Create a new branchgit switch -c <name>
Switch to existing branchgit switch <name>
List all branchesgit branch -a
Delete merged branchgit branch -d <name>
Delete unmerged branchgit branch -D <name>
Rename current branchgit branch -m <new-name>
See which branch you're ongit branch (asterisk marks current)

Best Practices

  • Branch from main for features — keep a clean starting point
  • One branch per task — don't mix unrelated work
  • Delete branches after merging — keep the branch list clean
  • Use descriptive names — future-you will thank present-you
  • Prefer git switch over git checkout (clearer intent, Git 2.23+)

What's Next

  1. Merge Strategies — Combine branches with fast-forward, three-way, and squash merges
  2. Rebase Explained — Rewrite history for a linear commit graph