Chapter 4.6 — Deleting Branches — Local + Remote☕ 10 min read

Deleting Branches — Local + Remote

Merged branches delete karo, unmerged check karo. fetch.prune true set karo. Safai zaroori hai, branch ho ya ghar!

01Local Delete: -d Safe, -D Khatarnak

git branch -d <name> — safe delete. Git only deletes the branch if it has been fully merged into another branch. If there is unmerged work, Git refuses and warns you.

git branch -D <name> — force delete. Deletes the branch even if it contains unmerged commits. Those commits become orphaned and hard to find!

Always try -d first. If Git refuses, it means there is unmerged work on that branch. Decide: merge the work first, or force delete if you are absolutely sure the work is not needed.

You cannot delete the branch you are currently on. Switch to another branch first!

# Safe delete (only works if merged)
git branch -d feature/login
# Deleted branch feature/login (was abc1234).

# If branch is not merged:
git branch -d feature/unfinished
# error: The branch 'feature/unfinished' is not fully merged.
# If you are sure you want to delete it, run 'git branch -D feature/unfinished'.

# Force delete (DANGEROUS — loses unmerged work!)
git branch -D feature/unfinished

# Can't delete current branch
git branch -d main
# error: Cannot delete branch 'main' checked out at /path
Think of -d as Git's safety net. When Git refuses to delete, it is telling you: "Hey, this branch has work that isn't in any other branch yet." That refusal just saved you from losing work. Respect it. Only override with -D when you are absolutely certain the work is disposable.
02Remote Delete: GitHub Se Hatayen

git push origin --delete <branch> — deletes a branch on the remote repository (GitHub, GitLab, Bitbucket).

This removes the branch from the remote. Your local copy still exists until you delete it separately.

After deleting a remote branch, other developers' local remote-tracking references become stale. They need to run git fetch --prune to clean up.

Always notify your team after deleting a remote branch so they can clean up their stale references.

GitHub tip: Enable "Automatically delete head branches" in Settings → General. This auto-deletes the source branch after a PR is merged. Saves tons of manual cleanup!

# Delete remote branch
git push origin --delete feature/login
# - [deleted]         feature/login

# Verify it's gone
git branch -r
# origin/main
# origin/develop
# (feature/login is gone from remote)

# GitHub: Auto-delete after PR merge
# Settings -> General -> Automatically delete head branches
# This saves SO much manual cleanup!
💡 Pro Tip: Deleting a remote branch does NOT delete any teammate's local branch. It only removes the branch from the server. Teammates still have their local copy and a stale remote-tracking reference (origin/feature/login). They need git fetch --prune to clean up the stale reference.
03Prune: Stale References Saf Karo

After someone deletes a remote branch, your local Git still remembers it as a remote-tracking reference (origin/feature/done). This is called a stale reference.

git fetch --prune — fetches updates AND removes stale remote-tracking branches in one step.

git remote prune origin — removes stale references without fetching new data.

Auto-prune (recommended): git config --global fetch.prune true. Now every git fetch or git pull automatically removes stale references. Set it once, benefit forever.

Important: pruning only removes remote-tracking references (origin/*). It does NOT delete your local branches.

# See stale remote-tracking branches
git branch -r
# origin/main
# origin/feature/done  ← deleted on GitHub, still showing locally!

# Remove stale references
git fetch --prune
# x [deleted]         (none)     origin/feature/done

# Or prune without fetching
git remote prune origin

# Enable auto-prune (DO THIS NOW!)
git config --global fetch.prune true
# Now every fetch/pull auto-prunes stale refs
Stale references cause real confusion. Imagine trying to checkout a branch that looks like it exists on remote, only to get an error. Or seeing 30 ghost branches in your branch list. Auto-prune eliminates this problem entirely. Set it once today, never think about it again.
04Bulk Cleanup: Sab Ek Saath Hatayo

Over time, merged branches pile up. Cleaning them one by one is tedious. Here is how to bulk delete.

List merged branches: git branch --merged main shows all branches whose work is already in main.

Delete all merged local branches: pipe the list through grep and xargs. Exclude main and develop!

Find old branches: git for-each-ref with date formatting shows branch ages. Find anything older than N months.

Nuclear option: delete ALL branches except main. Use with extreme caution — this deletes unmerged work too!

Always review the list before bulk deleting. One wrong pipe and you lose unmerged work.

# List merged branches
git branch --merged main
# * main
#   feature/done-1
#   feature/done-2

# Delete all merged local branches (except main and develop)
git branch --merged main | grep -v "main\|develop\|\*" | xargs git branch -d

# Find branches older than 3 months
git for-each-ref --sort=-committerdate --format='%(refname:short) %(committerdate:relative)' refs/heads/ | grep "months ago"

# Nuclear: delete ALL local branches except main
# WARNING: This deletes unmerged work too!
git branch | grep -v "main" | xargs git branch -D
💡 Pro Tip: Before any bulk delete, run the list command first WITHOUT piping to xargs. Review the output. Then add the delete part. This two-step approach has saved countless developers from accidental data loss.
05Recovering Deleted Branches

Deleted a branch by mistake? Don't panic! The commits still exist in Git's object store. Deleting a branch only removes the pointer (label), not the commits themselves.

git reflog shows the history of where HEAD has been. The tip of your deleted branch is there.

git branch <name> <hash> — recreates the branch pointing to that commit hash.

If you just deleted it, HEAD@{1} in the reflog usually has the commit you need.

Remote branches can be restored by re-pushing the local branch to the remote.

Time limit: unmerged commits deleted with -D can be recovered via reflog, but only if they are recent. Reflog entries expire (default 90 days). After that, Git may garbage-collect the orphaned objects.

# Oops! Deleted a branch by mistake
git branch -D feature/important
# Deleted branch feature/important (was def5678)

# Find it in reflog
git reflog | head -5
# def5678 HEAD@{0}: checkout: moving from feature/important to main
# abc1234 HEAD@{1}: commit: important work

# Recreate the branch
git branch feature/important def5678

# Verify — all commits are back!
git log feature/important --oneline
Reflog is your safety net for -D. But don't rely on it forever. Reflog entries expire after 90 days by default, and then Git's garbage collector may permanently remove the orphaned objects. If you realize you deleted something important, recover it sooner rather than later.

Lo kar liya — Key Points:

  • ✅ git branch -d safely deletes merged branches; -D force-deletes unmerged branches
  • ✅ git push origin --delete removes a branch from the remote repository
  • ✅ git fetch --prune removes stale remote-tracking branch references after remote deletion
  • ✅ Auto-prune: git config --global fetch.prune true cleans up automatically on every fetch
  • ✅ Bulk cleanup: git branch --merged main | xargs git branch -d removes all merged branches
  • ✅ Deleted branches can be recovered via git reflog if the commits are recent
Course Search
Search across all chapters & stages
📖

Search the course

Type any topic — branching, stash, rebase, hooks — and jump straight to that chapter.

merge branchesgit stashundo commitrebase