How to Delete Any Branch in Git: Local, Remote, and Everything In Between
Git branches are cheap to create and essential to modern development workflows — but they pile up fast. Knowing how to delete them cleanly, and understanding what actually happens when you do, saves you from cluttered repositories and the occasional panic when something disappears unexpectedly.
What a Git Branch Actually Is
Before deleting anything, it helps to know what you're removing. A Git branch isn't a copy of your code — it's a lightweight pointer to a specific commit. Deleting a branch doesn't destroy the commits it pointed to (at least not immediately). It removes the pointer itself, which means the commits become unreferenced and will eventually be cleaned up by Git's garbage collection.
This distinction matters because it affects how reversible a deletion is, and what risks you're actually taking.
Deleting a Local Branch
A local branch exists only on your machine. This is the most common deletion you'll perform, typically after merging a feature branch into main.
The standard command:
git branch -d branch-name The -d flag (lowercase) is the safe delete. Git will refuse to delete the branch if it hasn't been fully merged into its upstream or the current branch. This is a guardrail worth respecting.
Force deleting a local branch:
git branch -D branch-name The -D flag (uppercase) forces the deletion regardless of merge status. Use this when you're certain you no longer need the work — for example, if you abandoned an experimental approach entirely.
⚠️ If you force-delete an unmerged branch and later realize you needed something from it, you can often recover it using git reflog, which tracks recent HEAD movements. But this window is limited, so don't rely on it as a safety net.
Deleting a Remote Branch
A remote branch lives on the server (typically GitHub, GitLab, or Bitbucket). Deleting it locally doesn't touch the remote — they're separate references.
The command:
git push origin --delete branch-name Or the shorthand form:
git push origin :branch-name Both do the same thing: they tell the remote to remove the specified branch. Once done, that branch is gone from the server and won't appear in other collaborators' remote listings after they fetch.
Important: If other team members have checked out that branch locally, their local copy still exists. They'd need to delete it separately. Communication matters here — deleting shared remote branches without coordination can cause confusion.
Deleting Multiple Branches at Once
Git doesn't have a built-in multi-delete command, but you can chain or filter using standard shell tools.
Delete several local branches in one line:
git branch -d branch-one branch-two branch-three Delete all local branches that have been merged into main:
git branch --merged main | grep -v "^* " | grep -v "^ main$" | xargs git branch -d This is a commonly used cleanup pattern. It lists merged branches, filters out main and the currently checked-out branch, then passes the rest to git branch -d. Always review the output of git branch --merged main before piping it — the grep filters need to match your actual branch names and habits.
Cleaning Up Stale Remote-Tracking References
After remote branches are deleted (by you or a teammate), your local Git still holds stale remote-tracking references — entries like origin/old-feature that no longer exist on the server.
To prune them:
git fetch --prune Or set this to happen automatically on every fetch:
git config --global fetch.prune true This doesn't delete your local branches. It only cleans up the outdated references to remote branches that are already gone. It's good hygiene, especially on active teams.
Key Differences at a Glance 🗂️
| Action | Command | Scope |
|---|---|---|
| Safe local delete | git branch -d name | Local only |
| Force local delete | git branch -D name | Local only |
| Delete remote branch | git push origin --delete name | Remote only |
| Prune stale references | git fetch --prune | Local cache of remotes |
Variables That Change How You Should Approach This
The right deletion approach shifts depending on several factors:
- Merge status — whether the branch has been merged determines whether
-dor-Dis appropriate. Unmerged branches carry more risk. - Team size — solo developers can move faster and more aggressively. On shared repositories, remote branch deletion should be communicated or governed by conventions (e.g., only delete after a merged pull request is closed).
- Branch protection rules — platforms like GitHub and GitLab let you protect branches from deletion. If your delete command errors, protection rules may be in play.
- Git hosting platform — some platforms offer automatic branch deletion after a PR merges, which removes the need for manual cleanup entirely.
- Workflow conventions — GitFlow, trunk-based development, and other strategies treat branch lifecycles differently. What's routine in one workflow might be a footgun in another.
The Part That Depends on Your Setup
The commands here are consistent across Git versions and platforms — but whether you should be the one deleting a given branch, and when, is entirely a function of your team's conventions, your repository's protection settings, and how confident you are in the merge history. A developer working alone on a side project has a very different risk profile than someone managing branches on a production codebase with multiple contributors. The mechanics are the same; the judgment around them isn't.