Delete all local git branches
Solution 1
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
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
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
Parsing the output of git branch
is not recommended, and not a good answer for future readers on Stack Overflow.
-
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. - 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 setcolor.branch
then you will get control codes in the output, this will lead toerror: branch 'foo' not found.
if you attempt to pipe it into another command. You can bypass this with the--no-color
flag togit branch
, but who knows what other user configurations might break things. -
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
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
Comments
-
Louth almost 2 years
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 -
Louth almost 12 yearswith this command I get
error:branch 'a_branch_name' not found.
I can see what you're trying to do and I've been playing around with the command but for some reason git doesn't seem to like the branch names supplied... -
Matti almost 12 yearshmmm. to help troubleshoot, it would be useful to see some example output from
git branch --merged
-
Louth almost 12 yearsmy branch names are of the format
STORY-123-Short-Description
-
Matti almost 12 yearsand when you run
git branch --merged
, you get a list with one of those on each line? -
Matti almost 12 yearsdoes it literally say
error:branch 'a_branch_name' not found.
? Or does it complain about one of the branch names from yourgit branch
output above? -
Louth almost 12 yearsit says
error:branch 'STORY-123-Short-Description' not found.
for each of the branches listed above. -
Louth almost 12 yearsThis command still reports the same errors as mentioned in the comments for the answer below.
error:branch 'STORY-123-Short-Description' not found.
for each of the branches listed. -
Louth almost 12 yearsAll the steps you've shown work for me, right up until
git branch --merged | grep -v \* | xargs git branch -D
and then I get the errors I've shown in the answer. -
GoZoner almost 12 yearsSo, did using git 1.7.10 solve your problem or do you prefer working directly in the .git repository?
-
tassinari about 10 yearsNice one but I needed backticks to get it to work
git branch -D `git branch | awk '{ if ($0 !~ /master/) printf "%s", $0 }'`
--Actually I think you did have them originally but they got lost in the SO formatting. -
wheresrhys almost 10 yearsI've tried this but keep getting
error: branch 'my-branch-name' not found.
for every branch. Using git version 1.8.3.4 (Apple Git-47). Any idea why? -
mBardos almost 10 yearstry 'git branch --merged master | grep -v master | xargs echo' to debug what exactly it is trying to delete? have no better ideas...
-
wheresrhys almost 10 yearsIt's something to do with special characters added as part of colour coding. trying all sorts of
sed
variations to get rid of them -
Andrew C over 9 yearsYou have resurrected an ages old thread and posted a virtually identical answer to an existing one, that is buggy and is missing the safety changes that it had. This is not a good answer.
-
Brent Bradburn over 9 years
git branch --no-color 2>/dev/null
? -
Andrew C over 9 yearsIt's an improvement for sure. You will always have the problem of needing to filter out the *, and it does amusing things if somebody runs it from detached head. The main problem though is
git branch
is a porcelain command, and there is no guarantee that the output won't change in some future version of git. -
Pam over 8 yearsThis answer is clear in piping output from git branch, modifying it, and passing to git branch -D. No need to be mean.
-
Павел Тявин over 8 yearsSo.
git for-each-ref --format '%(refname:short)' refs/heads/ | grep -v master | xargs git branch -d
-
Alexander Bird over 8 yearsThis will not work if you have packed refs, or even if you cloned from a remote server sometimes (which will provide you packed files). If you refs are packed, then the refs will not be stored in .git/refs/heads, they will be stored in a file called "packed-refs". See git-scm.com/docs/git-pack-refs.
-
Jason over 8 yearsThank you @AndrewC - this is both answers the question bout the mysterious "branch not found" errors and provides a working solution using a more appropriate command! 👍
-
marcok about 8 yearsIf you get a
error:branch 'STORY-123-Short-Description' not found.
error, this is probably due to the git color settings. This worked for me (note the--no-color
option):git branch --no-color --merged | grep -v \* | xargs git branch -D
-
GoZoner about 8 yearsHow are 'Porcelain' and 'non-Porcelain' GIT commands identified?
-
GoZoner about 8 yearsMan pages for
git
on Mac OS... how quaint! :-) -
mBardos almost 8 years@wheresrhys see the
--no-color
switch for git branch (edited my response too) -
Volem about 7 yearsLearned xargs usage together with this. Thanks
-
Igor Mironenko over 6 yearsProbably would be a useful enhancement to exclude 'dev' and 'master' by default?
-
Andrew C over 6 years@PandaWood - git branch -d will refuse to delete the currently checked out branch (error: Cannot delete branch 'master' checked out). Any other branch is fair game if it is merged.
-
Dong Thang almost 6 yearsI don't think you can remove the branch which you are stand on.
-
krozaine over 5 yearsInstead of
--merged
there is another option--no-merged
for other branches, if anyone is looking for it. You will need to usegit branch -D ${noMergedBranch}
instead -
Jonas Lomholdt over 5 yearsI would use
git branch | grep -v "master" | xargs git branch -d
first so I don't delete unmerged branches, just to be safe. But nice answer! -
Jonas Lomholdt over 5 yearsHere is a powershell version
,@(git branch | Select-String -Pattern "[^(*?)\s? master]") | ForEach-Object{$_.Line.Trim()} | %{git branch -D $_}
-
Moberg over 5 yearsIt seems like a bad idea to remove the branch you have checked out at the moment
-
Melanie over 5 years@Dong There's a * beside that branch so you just remove it from the copied list!
-
Romain Valeri about 5 years@Moberg Just checkout a commit beforehand, and your detached HEAD will float all right.
-
nelsontruran almost 5 yearsThis one feels safer than going into .git and removing stuff.
-
Prad almost 5 yearsThis solution worked for me. Deleted all local branches.
-
KthProg almost 5 years@baklazan this would only work in Windows 10 command line if you have some tools installed. You probably have MINGW or some other such thing and you don't know it.
-
django over 4 yearsThis will not delete any branch contains word develop or master like 'develop_feature' or 'master_feature'.
-
RyanNerd over 4 yearsAlthough this may be a correct answer. One line of code isn't very useful without an explanation of what and how it solves the original question. Please provide details to your answer.
-
Brett Rowberry almost 4 yearsConfirmed: If not on
master
, this command WILL deletemaster
. -
its4zahoor almost 4 yearsHow to delete all other branches except
master
and some other branch saybranchA
using this one line command? Currently I dogit branch | grep -v "master" | grep -v "branchA" | xargs git branch -D
-
Julian over 3 yearsI would also put a
git checkout master
in front:git checkout master; git branch | grep -v "master" | xargs git branch -D
-
JmLavoier over 3 yearsAfter a long time, I'm here to share another solution for Node.js developers. github.com/jmlavoier/clear-branches
npx clear-branches
. -
Michael Berry over 3 yearsNot an issue in 2012, but these days probably makes sense to use
grep -Ev 'main|master'
instead, to capture both the common options. -
SeleM over 3 yearsthis wont delete a branch named "developX" (any
develop*
ormaster*
branches wont be deleted as well) -
perepm about 3 yearsHas anyone managed to turn this into a git alias? That would be extremely convenient
-
perepm about 3 years1. Substitute single quotes for double quotes like this:
for mergedBranch in $(git for-each-ref --format "%(refname:short)" --merged HEAD refs/heads/) do git branch -d ${mergedBranch} done
2.git config --global alias.delete-merged-branches 'for mergedBranch in $(git for-each-ref --format "%(refname:short)" --merged HEAD refs/heads/)
note: open the single quote but don't close it. This lets you enter more than one line of text -
aloisdg about 3 yearsI remove all my features with
foreach($branch in (git branch)) { if ($branch.trim().startswith("feature")) {git branch -D $branch.trim()} }
. Thank you :) -
andreas.herz almost 3 yearsDid not work for me. Got the following error:
fatal: branch name required
-
bvdb almost 3 yearson windows 10, when I put this in a
.bat
or.cmd
file, it says:f was unexpected at this time.
Do, I need to change something about the%f
parameters ? -
kiewic almost 3 yearsFrom a
.cmd
file, you need to replace%f
with%%f
-
arni almost 3 yearsJust for reference, this will delete all branches containing "chore":
for /f "tokens=*" %f in ('git branch ^| find "chore"') do git branch -D %f
-
Brian Leishman over 2 yearsIf your branch has quotes in it, this doesn't work
-
LeGEC over 2 years@ppicom : an alternative way to aliases is : create a script named
git-foo
, accessible from your path.git
will now execute that script when you invokegit foo
. -
jthill over 2 years
git checkout @^0; git for-each-ref --merged --format='delete %(refname)' refs/heads | git update-ref --stdin
; git will re-set-up any remote branches you check out. -
melvio over 2 yearsIf you are reading this in 2021. It is likely that you'll encounter
fatal: malformed object name master, fatal: branch name required
. This is because a lot of github projects don't have amaster
branch anymore. They often usemain
instead. In this case, replace thegit branch --merged master
bygit branch --merged main
. -
Robin Bastiaan over 2 yearsHow could you make this into an alias for easy use? I tried
git config --global alias.dbr "the command..."
but I got anerror: unknown switch 'v'
. This is because this is not a git thing. -
Jefferson Lima over 2 yearsI believe it should be
-D
(capital D) -
Ali Alizade over 2 yearsThis command very useful
-
mBardos over 2 years@JeffersonLima afaik
-D
deletes remote branches too. The question was about local branches. -
Jefferson Lima over 2 years@mBardos you are right. In fact, the
-D
option issues a-d -f
, i. e. according to the docs "allow deleting the branch irrespective of its merged status, or whether it even points to a valid commit" -
shanti about 2 yearsWhy do I get errors like these? error: branch '<branch-name>' not found. These branches exist on local that's why it is trying to find them...
-
Rodrigo almost 2 yearsI completely disagree with Andrew C's comment, I am here in 2022 and the solution worked perfectly for me. Thanks geoom
-
Nick almost 2 yearsadd "--force" at the end if you really mean it.