Branching Fundamentals
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
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
| State | Meaning |
|---|---|
HEAD → main → C3 | Normal: you're on branch main at commit C3 |
HEAD → C3 (no branch) | Detached HEAD: you're not on any branch (dangerous for new commits) |
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
| Pattern | When to Use | Example |
|---|---|---|
feature/<name> | New feature | feature/user-dashboard |
fix/<name> | Bug fix | fix/login-timeout |
hotfix/<name> | Urgent production fix | hotfix/security-patch |
docs/<name> | Documentation changes | docs/api-guide |
refactor/<name> | Code restructure | refactor/database-layer |
test/<name> | Adding tests | test/auth-integration |
chore/<name> | Maintenance tasks | chore/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 Want | Command |
|---|---|
| Create a new branch | git switch -c <name> |
| Switch to existing branch | git switch <name> |
| List all branches | git branch -a |
| Delete merged branch | git branch -d <name> |
| Delete unmerged branch | git branch -D <name> |
| Rename current branch | git branch -m <new-name> |
| See which branch you're on | git branch (asterisk marks current) |
Best Practices
- Branch from
mainfor 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 switchovergit checkout(clearer intent, Git 2.23+)
What's Next
- Merge Strategies — Combine branches with fast-forward, three-way, and squash merges
- Rebase Explained — Rewrite history for a linear commit graph