Git Notes
Learn how to safely delete Git branches locally and remotely, understand branch deletion safety mechanisms, recover deleted branches, and maintain clean repository.
Branch management is one of those housekeeping tasks that separates organized developers from those drowning in a sea of stale feature branches. After you merge a pull request, the feature branch has served its purpose. Leaving it around clutters your repository, confuses team members, and makes it harder to find active work.
Think of branches like scaffolding on a building. Once construction is complete, you remove the scaffolding. The building stands on its own. Similarly, once your feature is merged into main, the branch is no longer needed.
Deleting Local Branches
Git provides two flags for local branch deletion, and understanding the difference between them is important:
# Safe delete - Git checks if the branch is fully merged
git branch -d feature/user-auth
# Output if merged:
# Deleted branch feature/user-auth (was a3b4c5d).
# Output if NOT merged:
# error: The branch 'feature/user-auth' is not fully merged.
# If you are sure you want to delete it, run 'git branch -D feature/user-auth'.The lowercase -d flag is your safety net. Git verifies that every commit on that branch has been incorporated into the current branch or the upstream tracking branch. If you have unmerged work, Git refuses to delete and warns you.
# Force delete - skips the merge check entirely
git branch -D feature/experimental-idea
# This WILL delete even if the branch has unmerged commits
# Use when you intentionally want to discard unmerged workThe uppercase -D is equivalent to --delete --force. Use it only when you consciously want to throw away work that was never merged, such as an experimental branch that did not pan out.
Deleting Remote Branches
Remote branches live on GitHub (or your Git server) and require a push command to delete:
After deleting a remote branch, other team members still see a stale reference locally called a remote-tracking branch. They need to clean up their local references:
# Other team members should run this to clean stale references
git fetch --prune
# Or configure Git to always prune during fetch
git config --global fetch.prune trueCleaning Up Stale Remote-Tracking Branches
Over time, your local repository accumulates references to remote branches that no longer exist. This happens when teammates delete branches on GitHub after merging PRs:
# See all remote-tracking branches (including stale ones)
git branch -r
# Output might show branches that no longer exist on remote:
# origin/feature/old-feature <- deleted on GitHub weeks ago
# origin/feature/merged-stuff <- deleted after PR merge
# origin/main
# Clean up stale remote-tracking references
git remote prune origin
# Or use fetch with prune (does both fetch and prune)
git fetch --pruneBulk Branch Cleanup
Real-world repositories accumulate dozens of merged branches. Here are powerful one-liners for cleaning house:
# Delete ALL local branches that have been merged into main
git branch --merged main | grep -v "main" | grep -v "develop" | xargs git branch -d
# Preview what would be deleted (dry run)
git branch --merged main | grep -v "main" | grep -v "develop"
# Delete all local branches except main and develop
git branch | grep -v "main\|develop" | xargs git branch -D
# Delete multiple specific remote branches
git push origin --delete feature/old-1 feature/old-2 feature/old-3A word of caution with bulk operations: always preview before executing. The --merged filter is your friend because it ensures you only delete branches whose work is already safely in main.
Recovering a Deleted Branch
Mistakes happen. Maybe you deleted a branch that was not actually merged, or you need to reference some code from a branch you cleaned up last week. Git has your back:
# Step 1: Find the last commit of the deleted branch in the reflog
git reflog
# Look for entries like:
# a3b4c5d HEAD@{5}: checkout: moving from feature/important to main
# f6g7h8i HEAD@{6}: commit: add critical validation logic
# Step 2: Recreate the branch from that commit hash
git branch feature/important a3b4c5d
# The branch is restored with all its commits intact!
git checkout feature/important
git log --oneline
# a3b4c5d add critical validation logic
# b2c3d4e implement form component
# ...For remote branches that were deleted, if no one has the commits locally, you cannot recover them (the reflog is local only). This is why it is good practice to only delete remote branches after merging.
Automating Branch Cleanup
You can configure GitHub to automatically delete branches after PR merge:
For local automation, many developers add a Git alias:
When NOT to Delete Branches
Not every branch should be deleted immediately:
- Release branches like
release/v2.1should remain until that release is no longer supported - Long-lived branches like
developorstagingare permanent - Branches under active review should stay until the PR is resolved
- Branches with open dependent PRs that other branches are based on
Common Mistakes
Mistake 1: Deleting a branch before confirming the PR was merged. Always verify with git branch --merged main first.
Mistake 2: Force-deleting without checking. Using -D habitually instead of -d bypasses safety checks. Prefer -d and only escalate to -D when you understand what you are losing.
Mistake 3: Forgetting to prune remote-tracking branches. Your git branch -r list grows endlessly if you never run git fetch --prune.
Interview Questions
Q1: What is the difference between git branch -d and -D?
The lowercase -d performs a safe delete that verifies the branch is fully merged into HEAD or its upstream tracking branch. If unmerged commits exist, Git refuses the deletion. The uppercase -D forces deletion regardless of merge status, which means you could permanently lose unmerged work if you have not pushed those commits elsewhere.
Q2: How do you clean up stale branches in a team environment?
Run git fetch --prune to remove local remote-tracking references that no longer exist on the server. For local branches, use git branch --merged main | xargs git branch -d to safely remove all branches whose work is already in main. Configure fetch.prune = true globally so pruning happens automatically.
Q3: Can you recover a deleted branch, and for how long?
Yes, locally deleted branches can be recovered using git reflog to find the commit hash, then git branch <name> <hash> to recreate it. Reflog entries persist for approximately 90 days before garbage collection removes them. Remote branches cannot be recovered once deleted from the server unless someone has the commits locally.
Q4: What is your branch cleanup strategy on a team?
Enable auto-delete of head branches after PR merge in GitHub settings. Run periodic local cleanup with git fetch --prune and git branch --merged deletion. Establish a team convention that branches should not live longer than one sprint, and use branch naming conventions that include dates or ticket numbers for easy identification of stale branches.
Exam Focus
Revise definitions, diagrams, examples, and short-answer points for Delete Branch - Clean Up Branches.
Interview Use
Prepare one clear explanation, one practical example, and one common mistake for this Git & GitHub topic.
Search Terms
git-github, git & github, git, github, undoing, changes, delete, branch
Related Git & GitHub Topics