To delete a Git branch locally, run git branch -d branch-name (or -D to force it if the work is unmerged). To delete it on the remote, run git push origin --delete branch-name; the two are separate, so a branch on GitHub stays until you remove it there as well.
git switch main # you can't delete the branch you're on
git branch -d feature/login # delete the local branch
git push origin --delete feature/login # delete the remote branch
All command output below was produced with Git 2.45 in a throwaway test repository.
Delete a local branch: git branch -d
The git-branch manual describes -d like this: "The branch must be fully merged in its upstream branch, or in HEAD if no upstream was set." When that's true, Git deletes it and prints the commit it pointed to. Example output:
$ git branch -d merged
Deleted branch merged (was 63c8bb9).
Keep that hash until you're sure. git branch merged 63c8bb9 brings the branch back.
Error: the branch is not fully merged
If the branch has commits that exist nowhere else, -d refuses. Example output:
$ git branch -d wip
error: the branch 'wip' is not fully merged
hint: If you are sure you want to delete it, run 'git branch -D wip'
This is the safety net doing its job. Before forcing it, look at what you would lose:
git log main..wip --oneline
That lists the commits on wip that are not on main. If they really are throwaway, force the delete. -D is "shortcut for --delete --force":
$ git branch -D wip
Deleted branch wip (was 047c0cb).
A common false alarm: the branch was merged on GitHub with "Squash and merge" or "Rebase and merge". Those create new commits on main, so your local branch's original commits look unmerged even though the changes are in. -D is fine in that case once you've confirmed the pull request was merged.
Error: cannot delete the branch you are on
Git won't delete the branch currently checked out. Example output:
$ git branch -d main
error: cannot delete branch 'main' used by worktree at 'C:/work/project'
Switch first with git switch main (or git checkout main), then delete. If the path in the message is a different folder, the branch is checked out in another worktree; remove or switch that worktree first.
Delete a remote branch: git push origin --delete
$ git push origin --delete feature/login
To github.com:alex/project.git
- [deleted] feature/login
origin is the remote's name; run git remote -v if yours is called something else. The git-push manual describes --delete as "the same as prefixing all refs with a colon", which is why you'll also see the older form:
git push origin :feature/login
Both do the same thing. The --delete form is easier to read and harder to get wrong.
If the branch is already gone on the remote, Git says so. Example output:
error: unable to delete 'feature/login': remote ref does not exist
error: failed to push some refs to 'github.com:alex/project.git'
Someone (or GitHub's automatic delete after merging) already removed it. Your local list is just out of date; see pruning below.
Deleting on GitHub instead
On GitHub, a merged or closed pull request has a Delete branch button near the bottom of the page. GitHub's docs note the button is only available when no other open pull request uses that branch, and that a deleted head branch can be brought back with Restore branch on the same closed pull request.
Error: refusing to delete the current branch
A remote won't let you delete its default branch. Against a plain Git server it looks like this (example output, trimmed):
remote: error: refusing to delete the current branch: refs/heads/master
! [remote rejected] master (deletion of the current branch prohibited)
On GitHub, change the default first: Settings, then under Default branch click the switch icon, pick the new branch and click Update. Then the old branch can be deleted.
Clean up stale origin/ branches: git fetch --prune
Your repository keeps remote-tracking branches such as origin/old as a snapshot of the remote. When someone else deletes old on the server, your origin/old stays until you prune. Example session:
$ git branch -r
origin/main
origin/old
$ git fetch --prune
From github.com:alex/project
- [deleted] (none) -> origin/old
$ git branch -r
origin/main
The git-fetch manual: --prune will "remove any remote-tracking references that no longer exist on the remote". To make every fetch do this automatically:
git config --global fetch.prune true
To delete a single remote-tracking branch by hand, git branch -d -r origin/old works, but the manual notes it only makes sense if the branch no longer exists on the remote; otherwise the next fetch brings it back.
Delete local branches whose remote is gone
After pruning, local branches that tracked a deleted remote branch are marked gone. Example output:
$ git branch -vv
* main 63c8bb9 init
old 63c8bb9 [origin/old: gone] init
On macOS, Linux or Git Bash, this deletes all of them in one go (it uses -d, so anything unmerged is kept and reported):
git branch -vv | grep ': gone]' | awk '{print $1}' | xargs git branch -d
Run the first three parts alone first to see which names it will pass on, and switch to main before running it: the current branch's line starts with *, so awk would pass * instead of its name.
Which command for which branch
| What you want to delete | Command |
|---|---|
| Local branch, merged | git branch -d name |
| Local branch, unmerged work you don't need | git branch -D name |
| Branch on the remote | git push origin --delete name |
Stale origin/name entries | git fetch --prune |
| One stale remote-tracking ref | git branch -d -r origin/name |
If the branch keeps coming back
A remote branch that reappears after you delete it is usually being re-pushed: a teammate's local branch still tracks it, or a CI job pushes to it. A local origin/name that reappears means the branch still exists on the server; check with git ls-remote --heads origin name. If you deleted a branch only to rename it, there's a shorter path: how to rename a Git branch. And if the real goal was to throw away a commit rather than a whole branch, see how to undo the last commit.
Frequently asked questions
- Does deleting a local branch delete it on GitHub?
- No. git branch -d only removes the branch from your own repository. The copy on GitHub, GitLab or any other remote stays until you run git push origin --delete branch-name or delete it in the web interface. The reverse is also true: deleting it on the remote does not touch your local branch.
- Can I recover a branch I deleted with git branch -D?
- Usually, if you act before Git garbage-collects the commits. git branch -D prints the commit the branch pointed to, for example 'Deleted branch wip (was 047c0cb)'. Run git branch wip 047c0cb to recreate it. If the message has scrolled away, git reflog lists recent commits you had checked out.
- How do I delete several branches at once?
- git branch -d accepts several names: git branch -d feature-a feature-b feature-c. On the remote, git push origin --delete feature-a feature-b works the same way. Review the list before using -D, because it skips the merge check for every branch you name.
- What is the difference between git branch -d and -D?
- -d (--delete) refuses to delete a branch whose commits are not merged into its upstream, or into HEAD if it has no upstream. -D is short for --delete --force and deletes the branch regardless, which can leave its unmerged commits unreachable.