GitHub

How to Delete a Branch in GitHub

How to Delete a Branch in GitHub

Deleting a branch in GitHub takes the trash icon on the repository’s branches page or one command: git push origin --delete feature-login. Either one removes the branch from GitHub. Your local branch stays where it is.

Delete on GitHub.com and your clone keeps its local branch and the origin/feature-login reference until you delete or prune them. That’s why a branch removed on GitHub still shows up in git branch -a. Run the push command from your own clone and it also clears that clone’s origin/feature-login reference, though other clones hang on to theirs until they prune.

You need write access at minimum. A default branch, a protected branch, or a branch with an open pull request needs extra steps first.

Which copies of a branch exist, and which one does each deletion remove?

Deleting a branch removes a pointer. The commits already merged into another branch stay put. A branch is only a movable pointer to a commit, so merged history survives its removal.

Your own clone holds the local branch, the one git branch lists. GitHub holds the remote branch. Then there’s the remote-tracking reference, the origin/feature-login kind of name, which is just your clone’s bookmark of where the remote branch was last seen.

Each deletion method targets one of those copies. The only side effect is that git push --delete also drops the remote-tracking reference in the clone you run it from.

Deleting a branch on GitHub.com changes the hosted copy of the repository and nothing else. Your clone keeps the local branch and the remote-tracking reference until you remove or prune them.

It works the other way too. git branch -d never reaches GitHub.

Unmerged work is the one real hazard. Commits that no branch reaches become unreachable, and a git gc run can eventually remove them from a repository (the git-push manual makes this point about the origin repository in its force-push example).

How to delete a branch on GitHub.com

YouTube player

Open the repository’s branches page and click the trash icon next to the branch. If GitHub shows a warning, read it and click Delete. The remote branch is gone once the deletion completes.

Why is GitHub the heart of open source?

Uncover GitHub statistics: developer community growth, repository trends, collaboration patterns, and the platform that powers modern software development.

Explore GitHub Data →
  1. Open the repository’s main page on GitHub.
  2. Open the branch selector and click View all branches.
  3. Find the branch in the list and click the trash icon next to it.
  4. If GitHub shows a warning, which it does when the branch is associated with an open pull request, read it, then click Delete.

A merged or closed pull request also has a Delete branch button near the bottom of the page. GitHub hides it while an open pull request still uses the same branch.

GitHub Docs set write access as the minimum for deleting branches tied to closed or merged pull requests, so read-only collaborators are out of luck.

The default branch is its own case. Choose a new default before deleting the old one, as the GitHub Docs instruct.

Tutorials disagree on one detail. Linux Handbook says the web interface asks for no confirmation, while GitHub Docs describe a warning you read before clicking Delete, shown when the branch is associated with an open pull request.

Trust the documentation, and check the branch name before you click either way.

Looking to sharpen your Git skills? Branching, merging, rebasing, and everything else you need - including git rebase, git stash, and commit workflows - is on one page in the Git Cheat Sheet.

Deleting the head branch of a merged pull request has one documented side effect. Open pull requests in the same repository that used that branch as their base get retargeted to the merged pull request’s base branch (GitHub Docs).

How to delete local and remote branches with git

For the local copy, run git branch -d feature-login. The copy on GitHub goes with git push origin --delete feature-login. Do them in either order, since neither depends on the other.

Deleting a local branch

Git won’t delete the branch you are standing on, so switch to a different branch first.

CommandMerge checkUse it when
git branch -dRefuses unless the branch is fully merged into its upstream, or into HEAD when no upstream is setThe work already landed
git branch -DNone (shortcut for –delete –force)You are abandoning the work on purpose

Both flags are defined in the git-branch manual.

The pointer isn’t all that goes. According to the same manual, either flag also deletes the branch’s reflog.

▶ GIT EXPLAINED

If you commit, branch, or merge code every day, it helps to know how Git came to be. This video covers how Linus Torvalds created Git in just 10 days after a license dispute and explains how its data model actually works.

Linus Torvalds Built Git in Days Out of Spite
Built in 10 Days Out of Spite. Git and its data model explained in plain language.

Git prints the abbreviated hash of the tip commit when it deletes a branch. Keep that line before you force-delete unmerged work, since it is your way back to the commit.

The current git-branch manual (2.56.0) also lists git branch --delete-merged <pattern>, which removes local branches whose tip is already reachable from the upstream they track. The pattern selects the upstream, for example origin/*. Add --dry-run first and Git prints the branches it would delete without touching any ref.

One gap: the option skips a branch whose upstream ref no longer exists, so branches already deleted on GitHub still need git branch -d. Check git --version before relying on it.

Deleting a remote branch

The command is git push origin --delete feature-login. Here origin, the default name for the remote you cloned from, tells Git where to send the deletion.

The git-push manual defines --delete as the same as prefixing all refs with a colon. So git push origin :feature-login does the same job.

A successful push marks the deleted ref with a minus sign in its output line. If the branch is already gone from GitHub, Git reports that the remote ref does not exist.

GitHub rejects the push for the default branch and for protected branches.

A successful push also removes origin/feature-login from the clone you pushed from, so that clone needs no cleanup. Other clones still list the reference until they prune it.

How to delete a branch with GitHub CLI or the REST API

Send a DELETE request to the repository’s git/refs endpoint with heads/branch-name as the ref. One line does it:

gh api --method DELETE repos/OWNER/REPO/git/refs/heads/feature-login

Working from the GitHub CLI suits scripts and terminal-only sessions. For a single branch, the web interface is faster.

The call itself is GitHub’s REST API endpoint for deleting a reference, documented as DELETE /repos/{owner}/{repo}/git/refs/{ref}.

The ref reads heads/branch-name for a branch and tags/tag-name for a tag. A fine-grained token needs repository Contents permission with write access. And because the endpoint takes only owner, repo and ref, it runs no merged check, so your script has to supply one.

As of the October 2026 REST reference, a successful delete returns 204 No Content. A 409 signals a conflict. A 422 covers validation failures and spam protection, and it also shows up when you try to delete the default branch.

Scripts earn their keep when you clear many branches at once.

Which deletion method fits which situation?

GitHub.com suits a single branch after a merge. Git handles your own clone. For bulk work on the remote, reach for the API or GitHub CLI.

Only git branch -d and git branch --delete-merged check merge status. The web interface leaves that check to you and the API relies on your script.

MethodRemovesNeedsBest for
GitHub.comRemote branchWrite accessOne branch after a merge
git CLILocal copy and remote copy (two commands)A clone and push rightsCleaning your own machine
GitHub CLIRemote branchAn authenticated gh sessionTerminal-only sessions
REST APIRemote branchToken with Contents writeAutomation and bulk cleanup

Just merged a pull request? Use its Delete branch button, or turn on automatic deletion.

A pile of stale remote branches calls for a script, then a prune in each clone. And if you can’t tell whether the work landed, run git branch -d first and let Git refuse if it did not.

Why GitHub will not delete a branch

GitHub refuses a deletion when the branch is the default branch, when a branch protection rule or a ruleset covers it, when it is locked, or when an open pull request uses it. Each one has a different way out.

The default branch has a catch. Switching the default is the documented fix, but a ruleset that blocks force pushes also stops owners and admins from changing or renaming the default branch unless they can bypass it (GitHub rulesets reference, as of October 2026).

Protected branches have a carve-out most tutorials skip. By default, a protection rule’s restrictions do not apply to people with admin permissions or a custom role holding the “bypass branch protections” permission, unless the rule turns on the setting that forbids bypassing.

BlockerWhat GitHub doesWay out
Default branchRejects the deletionSet another default first
Branch protection ruleBlocks deletion by defaultTurn on Allow deletions in the rule
RulesetRestrict deletions limits it to the bypass listGet added to the bypass list, or edit the ruleset
Locked branchRead-only, even for people with permissionUnlock the branch first
Open pull requestNo Delete branch buttonMerge or close the pull request

Once Allow deletions is on, anyone with at least write permissions can delete the protected branch. In a ruleset, the Restrict deletions rule is selected by default.

Only one branch protection rule applies to a branch at a time. Rulesets carry no such limit, so a branch can be covered by several at once.

The docs contradict each other on open pull requests. GitHub’s page on deleting and restoring branches in a pull request says a branch tied to an open pull request cannot be deleted. GitHub’s page on managing branches within your repository says the same in a note, yet its delete steps say that deleting a branch with an open pull request closes the pull request.

Merge or close the pull request first, and the question never comes up.

How to restore a deleted branch

A deleted branch can come back through the Restore branch button on its closed pull request, or through a new branch created from a commit hash found in your local reflog. The reflog route also covers branches that never had a pull request.

For the button, open the repository’s pull requests, click Closed, pick the pull request, and click Restore branch near the bottom (GitHub Docs).

Time limits are where sources split. Linux Handbook says the restore link on the branches page works only right after deletion, until you reload, while GitHub Docs describe the pull request’s button without any deadline.

Without a pull request, you need the commit hash at the branch tip. Your clone’s reflog is the place to find it.

The deleted branch’s own reflog went with it. HEAD’s reflog stays, and the git-reflog manual says it records branch switching.

  1. Run git reflog and find the entry from the last time you had the branch checked out or committed on it.
  2. Copy the commit hash from that entry.
  3. Run git branch feature-login abc1234 to recreate the branch at that commit.
  4. Run git push origin feature-login to put it back on GitHub.

Reflog entries expire after 90 days by default, and after 30 days when they are no longer reachable from the branch tip (git-reflog manual, via gc.reflogExpire and gc.reflogExpireUnreachable).

A commit that only the deleted branch reached is unreachable once the branch is gone, so the 30-day limit is the one to plan around.

No local copy? A hash from a pull request or a CI log is enough to recreate the branch on GitHub directly:

  • git push origin COMMIT_HASH:refs/heads/feature-login (a SHA works as the source of a refspec, per the git-push manual)
  • gh api --method POST repos/OWNER/REPO/git/refs -f ref=refs/heads/feature-login -f sha=COMMIT_HASH (the create-a-reference endpoint, which needs a token with Contents write)

How to clean up stale references and delete merged branches automatically

Run git fetch --prune origin to clear stale remote-tracking branches, and switch on Automatically delete head branches in repository settings so merged branches stop piling up.

Pruning stale remote-tracking branches

Git keeps references to branches a remote has already deleted until you prune them.

git fetch --prune origin removes remote-tracking references that no longer exist on the remote, then fetches. git remote prune origin does the pruning without fetching. To remove a single reference by hand, use git branch -d -r origin/feature-login, though a later fetch recreates it if the branch still exists on GitHub.

Pruning during the fetch you run anyway costs nothing extra. Set fetch.prune to true, or remote.origin.prune for one remote, and every fetch prunes on its own (git-fetch manual).

Use the remote subcommand when you want to prune without downloading anything. The two also report differently. git fetch --prune marks a pruned reference with a minus sign ( – [deleted]), while git remote prune marks it with an asterisk ( \* [pruned]).

Watch the refspec. With refs/tags/*:refs/tags/* or the --prune-tags option, pruning deletes local tags that do not exist on the remote, including tags that never came from it (git-fetch manual).

Turning on automatic deletion of head branches

The Automatically delete head branches setting removes a pull request’s head branch once the pull request is merged.

  1. Open the repository’s Settings tab.
  2. On the General page, find the Pull Requests section.
  3. Select Automatically delete head branches.

Anyone with admin permissions can switch it on or off. Branch protection rules and repository rules can still stop the deletion (GitHub Docs, as of October 2026).

The setting acts after merges. Branches whose pull requests were closed unmerged, or that never had one, still need manual cleanup.

I’d turn it on for most repositories and leave it off only where merged branches double as long-lived release lines.

Common Questions About Deleting a Branch in GitHub

Can I delete a branch that has not been merged?

Yes. git branch -D forces the local deletion, and GitHub.com and the API do not check merge status at all.

Copy the tip commit hash first, since commits that no branch reaches become unreachable.

How do I find out which branches are safe to delete?

Run git branch --merged main. It lists branches whose tips are reachable from main. The git-branch manual says merged branches can be safely deleted because they are fully contained by HEAD, so check out main first.

Swap in --no-merged to see the ones that still need a decision.

How can I delete several branches in one command?

Pass every name to a single command. git branch -d old-one old-two removes several local branches, and git push origin --delete old-one old-two removes several remote branches in one push.

Both manuals accept multiple names.

Does GitHub Desktop let me delete a branch?

Yes. Select the branch, then choose Branch, then Delete in the menu bar (Shift+Command+D on Mac, Ctrl+Shift+D on Windows).

GitHub’s documentation says the app cannot undo the deletion and refuses branches tied to an open pull request.

Checking a Branch Before You Delete It

Deleting a branch in GitHub is safe once its commits sit in another branch and no open pull request uses it.

Start by merging or closing the open pull request. Then confirm the commits reached the target branch. Delete the remote copy after that, and prune each clone.

The pull request comes first because an open one hides the Delete branch button. The remote copy goes before the pruning because pruning only removes references the remote no longer has.

Tie every deletion to a pull request when possible. Its Restore branch button carries no stated deadline, while a branch without one depends on a local reflog that expires.

Unmerged work needs merging first, which a guide to merging branches in GitHub covers. These steps match GitHub’s documentation as of October 2026, which differs across pages on open pull requests, so test on a throwaway branch.

Bogdan Sandu

Stay sharp. Ship better code.

Every week: one curated article, one tool worth knowing, one tip you can use tomorrow. No noise, no padding.