Delete all local git branches

GitBashUbuntuVersion ControlGrep

Git Problem Overview


I follow a development process where I create a new local branch for every new feature or story card. When finished I merge the branch into master and then push.

What tends to happen over time due to a combination of laziness or forgetfulness, is that I end up with a large list of local branches, some of which (such as spikes) may not have been merged.

I know how to list all my local branches and I know how to remove a single branch but I was wondering if there was a git command that allows me to delete all my local branches?

Below is the output of the git branch --merged command.

user@machine:~/projects/application[master]$ git branch --merged
  STORY-123-Short-Description
  STORY-456-Another-Description
  STORY-789-Blah-Blah
* master

All attempts to delete branches listed with grep -v \* (as per the answers below) result in errors:

error: branch 'STORY-123-Short-Description' not found.
error: branch 'STORY-456-Another-Description' not found.
error: branch 'STORY-789-Blah-Blah' not found.

I'm using:

git 1.7.4.1  
ubuntu 10.04  
GNU bash, version 4.1.5(1)-release  
GNU grep 2.5.4  

Git Solutions


Solution 1 - Git

The 'git branch -d' subcommand can delete more than one branch. So, simplifying @sblom's answer but adding a critical xargs:

git branch -D `git branch --merged | grep -v \* | xargs`

or, further simplified to:

git branch --merged | grep -v \* | xargs git branch -D 

Importantly, as noted by @AndrewC, using git branch for scripting is discouraged. To avoid it use something like:

git for-each-ref --format '%(refname:short)' refs/heads | grep -v "master\|main" | xargs git branch -D

Caution warranted on deletes!

$ mkdir br
$ cd br; git init
Initialized empty Git repository in /Users/ebg/test/br/.git/
$ touch README; git add README; git commit -m 'First commit'
[master (root-commit) 1d738b5] First commit
 0 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 README
$ git branch Story-123-a
$ git branch Story-123-b
$ git branch Story-123-c
$ git branch --merged
  Story-123-a
  Story-123-b
  Story-123-c
* master
$ git branch --merged | grep -v \* | xargs
Story-123-a Story-123-b Story-123-c
$ git branch --merged | grep -v \* | xargs git branch -D
Deleted branch Story-123-a (was 1d738b5).
Deleted branch Story-123-b (was 1d738b5).
Deleted branch Story-123-c (was 1d738b5).

Solution 2 - Git

The simpler way to delete all branches but keeping others like "develop" and "master" is the following:

git branch | grep -v "develop" | grep -v "master" | xargs git branch -D

very useful !

Solution 3 - Git

I found a nicer way in a comment on this issue on github:

git branch --merged master --no-color | grep -v "master\|stable\|main" | xargs git branch -d

Edit: Added no-color option and excluding of stable branch (add other branches as needed in your case)

Solution 4 - Git

Parsing the output of git branch is not recommended, and not a good answer for future readers on Stack Overflow.

  1. git branch is what is known as a porcelain command. Porcelain commands are not designed to be machine parsed and the output may change between different versions of Git.
  2. There are user configuration options that change the output of git branch in a way that makes it difficult to parse (for instance, colorization). If a user has set color.branch then you will get control codes in the output, this will lead to error: branch 'foo' not found. if you attempt to pipe it into another command. You can bypass this with the --no-color flag to git branch, but who knows what other user configurations might break things.
  3. git branch may do other things that are annoying to parse, like put an asterisk next to the currently checked out branch

The maintainer of git has this to say about scripting around git branch output

> To find out what the current branch is, casual/careless users may have > scripted around git branch, which is wrong. We actively discourage > against use of any Porcelain command, including git branch, in > scripts, because the output from the command is subject to change to > help human consumption use case.

Answers that suggest manually editing files in the .git directory (like .git/refs/heads) are similarly problematic (refs may be in .git/packed-refs instead, or Git may change their internal layout in the future).

Git provides the for-each-ref command to retrieve a list of branches.

Git 2.7.X will introduce the --merged option to so you could do something like the below to find and delete all branches merged into HEAD

for mergedBranch in $(git for-each-ref --format '%(refname:short)' --merged HEAD refs/heads/)
do
    git branch -d ${mergedBranch}
done

Git 2.6.X and older, you will need to list all local branches and then test them individually to see if they have been merged (which will be significantly slower and slightly more complicated).

for branch in $(git for-each-ref --format '%(refname:short)' refs/heads/)
do
    git merge-base --is-ancestor ${branch} HEAD && git branch -d ${branch}
done

Solution 5 - Git

Try the following shell command:

git branch | grep -v "master" | xargs git branch -D

Explanation:

  • Get all branches (except for the master) via git branch | grep -v "master" command
  • Select every branch with xargs command
  • Delete branch with xargs git branch -D

Solution 6 - Git

To delete every branch except the one that you currently have checked out:

for b in `git branch --merged | grep -v \*`; do git branch -D $b; done

I would recommend changing git branch -D $b to an echo $b the first few times to make sure that it deletes the branches that you intend.

Solution 7 - Git

The below command will delete all the local branches except master branch.

git branch | grep -v "master" | xargs git branch -D

The above command

  1. list all the branches
  2. From the list ignore the master branch and take the rest of the branches
  3. delete the branch

Solution 8 - Git

Just a note, I would upgrade to git 1.7.10. You may be getting answers here that won't work on your version. My guess is that you would have to prefix the branch name with refs/heads/.

CAUTION, proceed with the following only if you made a copy of your working folder and .git directory.

I sometimes just go ahead and delete the branches I don't want straight from .git/refs/heads. All these branches are text files that contain the 40 character sha-1 of the commit they point to. You will have extraneous information in your .git/config if you had specific tracking set up for any of them. You can delete those entries manually as well.

Solution 9 - Git

To delete all local branches in linux except the one you are on

// hard delete

git branch -D $(git branch)

Solution 10 - Git

I found it easier to just use text editor and shell.

  1. Type git checkout <TAB> in shell. Will show all local branches.
  2. Copy them to a text editor, remove those you need to keep.
  3. Replace line breaks with spaces. (In SublimeText it's super easy.)
  4. Open shell, type git branch -D <PASTE THE BRANCHES NAMES HERE>.

That's it.

Solution 11 - Git

From Windows Command Line, delete all except the current checked out branch using:

for /f "tokens=*" %f in ('git branch ^| find /v "*"') do git branch -D %f

Solution 12 - Git

If you want to delete all your local branches, here is the simple command:

git branch -D `git branch`

Note: This will delete all the branches except the current checked out branch

Solution 13 - Git

I had a similar kind of situation and recently found the following command useful.

git branch -D `git branch | awk '{ if ($0 !~ /<Branch_You_Want_to_Keep>/) printf "%s", $0 }'`

If you want to keep multiple branches, then

git branch -D `git branch | awk '{ if ($0 !~ /<Branch_You_Want_to_Keep1>|<Branch_You_Want_to_Keep2>/) printf "%s", $0 }'`

hope this helps someone.

Solution 14 - Git

Here's the Powershell solution for anyone running on a Windows machine

git checkout master # by being on the master branch, you won't be able to delete it
foreach($branch in (git branch))
{
    git branch -D $branch.Trim()
}

Solution 15 - Git

If you work with NodeJS, I wrote this command:

npx git-clear-branch

The command clears all of your local branch except master and current branch.

Solution 16 - Git

If you don't need to go through Git itself, you can also delete heads under .git/refs/heads manually or programmatically. The following should work with minimal tweaking under Bash:

shopt -s extglob
rm -rf .git/refs/heads/!(master)

This will delete every local branch except your master branch. Since your upstream branches are stored under .git/refs/remotes, they will remain untouched.

If you are not using Bash, or want to recurse a lot of Git repositories at once, you can do something similar with GNU find:

find . \
    -path remotes -path logs -prune -o \
    -wholename \*.git/refs/heads/\* \! -name master -print0 |
xargs -0 rm -rf

The find solution is probably more portable, but pruning paths and filenames is tricky and potentially more error-prone.

Solution 17 - Git

None of the answers satisfied my needs fully, so here we go:

git branch --merged | grep -E "(feature|bugfix|hotfix)/" | xargs git branch -D && git remote prune origin

This will delete all local branches which are merged and starting with feature/, bugfix/ or hotfix/. Afterwards the upstream remote origin is pruned (you may have to enter a password).

Works on Git 1.9.5.

Solution 18 - Git

Although this isn't a command line solution, I'm surprised the Git GUI hasn't been suggested yet.

I use the command line 99% of the time, but in this case its either far to slow (hence the original question), or you don't know what you are about to delete when resorting to some lengthy, but clever shell manipulation.

The UI solves this issue since you can quickly check off the branches you want removed, and be reminded of ones you want to keep, without having to type a command for every branch.

From the UI go to Branch --> Delete and Ctrl+Click the branches you want to delete so they are highlighted. If you want to be sure they are merged into a branch (such as dev), under Delete Only if Merged Into set Local Branch to dev. Otherwise, set it to Always to ignore this check.

GitUI: delete local branches

Solution 19 - Git

Based on a combination of a number of answers here - if you want to keep all branches that exist on remote but delete the rest, the following oneliner will do the trick:

git for-each-ref --format '%(refname:short)' refs/heads | grep -Ev `git ls-remote --quiet --heads origin | awk '{print substr($2, 12)}'| paste -sd "|" -` | xargs git branch -D

Solution 20 - Git

git branch -l |grep -v master | xargs git branch -D

But what care deleting branch ; just remove the workspace and re clone it if it t is a small repository !!

Solution 21 - Git

If you want to keep master, develop and all remote branches. Delete all local branches which are not present on Github anymore.

$ git fetch --prune

$ git branch | grep -v "origin" | grep -v "develop" | grep -v "master" | xargs git branch -D

1] It will delete remote refs that are no longer in use on the remote repository.

2] This will get list of all your branches. Remove branch containing master, develop or origin (remote branches) from the list. Delete all branches in list.

Warning - This deletes your own local branches as well. So do this when you have merged your branch and doing a cleanup after merge, delete.

Solution 22 - Git

git branch -d [branch name] for local delete

git branch -D [branch name] also for local delete but forces it

Solution 23 - Git

For powershell, this will work:

git branch --format '%(refname:lstrip=2)' --merged `
    | Where-Object { $_ -ne 'master' } `
    | ForEach-Object { git branch -d $_ }

Solution 24 - Git

I don't have grep or other unix on my box but this worked from VSCode's terminal:

git branch -d $(git branch).trim()

I use the lowercase d so it won't delete unmerged branches.

I was also on master when I did it, so * master doesn't exist so it didn't attempt deleting master.

Solution 25 - Git

I recommend a more moderate answer. Many of the answers here use -D which is forced delete regardless of whether changes have been merged or not. Here is a one liner which leaves untouched the branches which have un-merged changes.

git branch --merged | egrep -v "(^\*|master|dev)" | xargs git branch -d

Or you can try other examples listed but just change the -D to -d. I know the OP asked how to delete, but in most use cases, its safer to use -d.

Solution 26 - Git

For this purpose, you can use git-extras

$ git delete-merged-branches
Deleted feature/themes (was c029ab3).
Deleted feature/live_preview (was a81b002).
Deleted feature/dashboard (was 923befa).

Solution 27 - Git

Deleting many local branches at once

# delete all local unmerged branches
git branch --no-merged | egrep -v "(^\*|master|dev)" | xargs git branch -D
# delete all local branches (merged and unmerged).
git branch | egrep -v "(^\*|master|dev)" | xargs git branch -D  

Deleting remote branches

# Deleting non-existent tracking branches
git remote prune <remote> --dry-run
# Deleting a single remote branch
git push <remote> --delete <branch>
# Deleting many remote branches at once
git branch -r --merged | egrep -v "(^\*|master|dev)" | sed 's/origin\///' | xargs -n 1 git push origin --delete

Source

Solution 28 - Git

The following script deletes branches. Use it and modify it at your own risk, etc. etc.

Based on the other answers in this question, I ended up writing a quick bash script for myself. I called it "gitbd" (git branch -D) but if you use it, you can rename it to whatever you want.

gitbd() {
if [ $# -le 1 ]
  then
    local branches_to_delete=`git for-each-ref --format '%(refname:short)' refs/heads/ | grep "$1"`
    printf "Matching branches:\n\n$branches_to_delete\n\nDelete? [Y/n] "
    read -n 1 -r # Immediately continue after getting 1 keypress
    echo # Move to a new line
    if [[ ! $REPLY == 'N' && ! $REPLY == 'n' ]]
      then
        echo $branches_to_delete | xargs git branch -D
    fi
else
  echo "This command takes one arg (match pattern) or no args (match all)"
fi
}

It will offer to delete any branches which match a pattern argument, if passed in, or all local branches when called with with no arguments. It will also give you a confirmation step, since, you know, we're deleting things, so that's nice.

It's kind of dumb - if there are no branches that match the pattern, it doesn't realize it.

An example output run:

$ gitbd test
Matching branches:

dummy+test1
dummy+test2
dummy+test3

Delete? [Y/n] 

Solution 29 - Git

I wrote a shell script in order to remove all local branches except develop

branches=$(git branch | tr -d " *")
output=""
for branch in $branches 
do
  if [[ $branch != "develop" ]]; then
    output="$output $branch"
  fi
done
git branch -d $output

Solution 30 - Git

Above answers works fine. Here is another approach when we have lot of branches in local repo and we have to delete many branches except few which are lying in local machine.

First git branch will list all the local branches.

To transpose the column of branch names into single row in file by running a unix command
git branch > sample.txt
This will save it in sample.txt file. And run
awk 'BEGIN { ORS = " " } { print }' sample.txt
command in shell. This will transform the column to row and copy the list of branch names in single row.

And then run
git branch -D branch_name(s).
This will delete all listed branches present in local

Solution 31 - Git

To remove all your local git branches but keep main

git branch | grep -v "main" | xargs git branch -D 

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionLouthView Question on Stackoverflow
Solution 1 - GitGoZonerView Answer on Stackoverflow
Solution 2 - GitgeoomView Answer on Stackoverflow
Solution 3 - GitmBardosView Answer on Stackoverflow
Solution 4 - GitAndrew CView Answer on Stackoverflow
Solution 5 - GitPravin BansalView Answer on Stackoverflow
Solution 6 - GitsblomView Answer on Stackoverflow
Solution 7 - GitHunterView Answer on Stackoverflow
Solution 8 - GitAdam DymitrukView Answer on Stackoverflow
Solution 9 - GitAshish YadavView Answer on Stackoverflow
Solution 10 - GitculebrónView Answer on Stackoverflow
Solution 11 - GitkiewicView Answer on Stackoverflow
Solution 12 - GitkgsnaiduView Answer on Stackoverflow
Solution 13 - Git4u.AnsView Answer on Stackoverflow
Solution 14 - GitKellen StuartView Answer on Stackoverflow
Solution 15 - GitRudy HuynhView Answer on Stackoverflow
Solution 16 - GitTodd A. JacobsView Answer on Stackoverflow
Solution 17 - Gituser4401817View Answer on Stackoverflow
Solution 18 - GitDane BouchieView Answer on Stackoverflow
Solution 19 - GitSrishan BhattaraiView Answer on Stackoverflow
Solution 20 - GitforvaidyaView Answer on Stackoverflow
Solution 21 - GitkapilView Answer on Stackoverflow
Solution 22 - GitDimitar GrivovView Answer on Stackoverflow
Solution 23 - GitLucasView Answer on Stackoverflow
Solution 24 - GitRon NewcombView Answer on Stackoverflow
Solution 25 - GitScottyBladesView Answer on Stackoverflow
Solution 26 - GitAndriy OrehovView Answer on Stackoverflow
Solution 27 - GitPremrajView Answer on Stackoverflow
Solution 28 - GitdhermanView Answer on Stackoverflow
Solution 29 - GitnhpView Answer on Stackoverflow
Solution 30 - GitDeepak GView Answer on Stackoverflow
Solution 31 - GitAli HamadView Answer on Stackoverflow