The Hook (The "Byte-Sized" Intro)
Merged branches are like used boarding passes — they served their purpose, now they're clutter. A repo with 200 stale branches is a repo where nobody can find anything. Cleaning up after yourself isn't just tidy — it's professional. Delete merged branches. Your future self (and your teammates) will thank you.
📖 What is Deleting Branches?
Deleting a branch removes the pointer (label), not the commits. If the branch is merged, its commits are safely reachable from the target branch. Git has two levels: safe delete (-d) that refuses if work would be lost, and force delete (-D) for when you're sure.
Conceptual Clarity
| Command | What It Does | Safety |
|---|---|---|
git branch -d <name> | Deletes if fully merged | ✅ Safe — refuses if unmerged |
git branch -D <name> | Force deletes regardless | ⚠️ Destructive — loses unmerged work |
git push origin --delete <name> | Deletes a remote branch | Affects the team |
Key insight: Deleting a branch only removes the pointer. The commits remain in the repository until Git's garbage collector removes unreachable objects (typically after 30 days).
Real-Life Analogy
Deleting a branch is like removing a bookmark from a book. The pages (commits) are still there — you just removed the label pointing to them. If the chapters were already merged into the main story, nothing is lost.
Visual Architecture
Why It Matters
- Hygiene: A clean branch list makes navigation and review easier.
- Signal: Stale branches signal abandoned work. Cleaned-up repos signal a healthy team.
- Remote cleanup: Old remote branches confuse new team members and clutter CI pipelines.
- Safety:
-dprotects you from accidentally deleting unmerged work.
Code
# ─── Delete a merged local branch ───
git branch -d feature/login
# Output: Deleted branch feature/login (was e4f5g6h).
# ─── Attempt to delete an unmerged branch (safe) ───
git branch -d experiment/risky
# Output: error: branch 'experiment/risky' is not fully merged.
# Git protects you from losing work!
# ─── Force-delete an unmerged branch ───
git branch -D experiment/risky
# Output: Deleted branch experiment/risky (was a1b2c3d).
# ⚠️ Unmerged commits may become unreachable
# ─── Delete a remote branch ───
git push origin --delete feature/login
# Output: Deleted remote branch origin/feature/login
# ─── Clean up stale remote-tracking references ───
git fetch --prune
# Removes local references to remote branches that no longer exist
# ─── See which branches are safe to delete ───
git branch --merged main
# Lists branches whose work is fully in main — safe to delete
# ─── Bulk delete all merged branches (except main) ───
git branch --merged main | grep -v "main" | xargs git branch -dCleanup Cheat Sheet
| Task | Command |
|---|---|
| Delete merged local branch | git branch -d <name> |
| Force-delete unmerged local branch | git branch -D <name> |
| Delete remote branch | git push origin --delete <name> |
| Remove stale remote references | git fetch --prune |
| List merged branches | git branch --merged main |
| Bulk delete merged branches | git branch --merged main | grep -v "main" | xargs git branch -d |
Key Takeaways
- Use
git branch -dfor safe deletion (only merged branches). - Use
git branch -Dfor force deletion (when you're sure you don't need the work). - Clean up remote branches with
git push origin --deleteandgit fetch --prune. - Run
git branch --mergedto find branches safe to clean up.
Interview Prep
-
Q: What is the difference between
git branch -dand-D? A:-d(lowercase) is safe — Git refuses if the branch has unmerged commits that would become unreachable.-D(uppercase) force-deletes regardless, even if commits would be lost. -
Q: Does deleting a branch delete the commits? A: No. Deleting a branch only removes the pointer. If the commits are reachable from another branch (e.g., they were merged), they remain in the repository. Unreachable commits are eventually garbage collected (typically after 30+ days).
-
Q: How do you clean up remote branches that have been deleted on the server? A: Run
git fetch --prune(orgit fetch -p). This removes local remote-tracking references (e.g.,origin/feature/old) for branches that no longer exist on the remote.