Delete local Git branches after deleting them on the remote repo
Solution 1
The quick way
git branch --merged | grep -v "\*" | xargs -n 1 git branch -d
NB: if you're not on master
, this has the potential to delete the branch. Keep reading for the "better way".
Make sure we keep master
You can ensure that master
, or any other branch for that matter, doesn't get removed by grep
ing for more. In that case you would go:
git branch --merged | grep -v "\*" | grep -v "YOUR_BRANCH_TO_KEEP" | xargs -n 1 git branch -d
So if we wanted to keep master
, develop
and staging
for instance, we would go:
git branch --merged | grep -v "\*" | grep -Ev "(\*|master|develop|staging)" | xargs -n 1 git branch -d
Make this an alias
Since it's a bit long, you might want to add an alias to your .zshrc
or .bashrc
. Mine is called gbpurge
(for git branches purge
):
alias gbpurge='git branch --merged | grep -Ev "(\*|master|develop|staging)" | xargs -n 1 git branch -d'
Then reload your .bashrc
or .zshrc
:
. ~/.bashrc
or
. ~/.zshrc
Solution 2
I use the same flow with GitHub, and didn't find the previous answers satisfying me, as git branch --merged
lists branches which were merged, but not every of them was removed remotely in my case.
So, this worked for me:
git fetch --all -p; git branch -vv | grep ": gone]" | awk '{ print $1 }' | xargs -n 1 git branch -d
where:
-
git fetch --all -p
: update local branches status -
git branch -vv
: list local branches status -
grep ": gone]"
: filter deleted ones -
awk '{ print $1 }'
: extract their names -
xargs -n 1 git branch -d
: pass the name to the delete command
Note: if you prefer, you could use -D instead of -d, which enforces the delete.
For example:
someUsr@someHost:~/repo$ git branch -a
basic-testing
integration-for-tests
* master
origin
playground-for-tests
test-services
remotes/origin/HEAD -> origin/master
remotes/origin/basic-testing
remotes/origin/master
remotes/origin/test-services
someUsr@someHost:~/repo$ git fetch --all -p; git branch -vv | grep ": gone]" | awk '{ print $1 }' | xargs -n 1 git branch -d
Fetching origin
Deleted branch integration-for-tests (was fbc609a).
Deleted branch playground-for-tests (was 584b900).
someUsr@someHost:~/repo$ git branch -a
basic-testing
* master
origin
test-services
remotes/origin/HEAD -> origin/master
remotes/origin/basic-testing
remotes/origin/master
remotes/origin/test-services
Reference:
http://git-scm.com/book/en/v2/Git-Branching-Remote-Branches
Solution 3
try:
git pull --prune
which deletes your local branch, if its corresponding remote branch is deleted.
Updated:
The statement above is not that correct.
In fact, running git pull --prune
will only REMOVE the remote-tracking branches such like
remotes/origin/fff remotes/origin/dev remotes/origin/master
Then, you can run git branch -r
to check the remote-tracking branches left on your machine. Suppose the left branches are:
origin/dev origin/master
which means the branch origin/fff
is deleted.
So, after running git pull --prune
, just run:
git branch --merged | grep -vFf <(git branch -r | cut -d'/' -f2-)
you can find out all the local branches which:
- have no correspoding remote branches any more;
- can be removed safely.
then, <the command above> | xargs git branch -d
can delete all of them.
Solution 4
This should work to avoid deleting the master and development branches with the accepted solution:
git branch --merged | egrep -v "^\*|master|development" | xargs -n 1 git branch -d
Solution 5
For people using powershell, this is the equivalent to the answer above:
git branch -vv | Select-String -Pattern ': gone]' | ForEach-Object{($_ -split "\s+")[1]} | %{ git branch -D $_ }
- Filter all the branches that are marked as gone
- Call
git branch -D
on each of the found branches (using-D
to delete a branch irrespective of its merged status).
Related videos on Youtube
sf89
Updated on October 05, 2020Comments
-
sf89 over 3 years
I want to have my local and remote repositories always in sync in terms of branches.
After a Pull Request review on GitHub, I merge and remove my branch there (remote). How could I fetch this information in my local repository and get Git to remove my local version of the branch as well?
-
Admin almost 11 yearsDo you want to delete your remote tracking branches, local branches, or both? You can actually write an alias (bash or git) that will take all of the deleted remote branches, and find local copies to delete too, all in one command.
-
Admin almost 11 yearsMaybe try using the following commands to come up with something,
git ls-remote
andgit show-ref
. -
Admin almost 11 yearsAlso, you might want to check out
git symbolic-ref
andgit update-ref
. -
sf89 almost 11 yearsthanks for your help, I ended up finding the answer somewhere else. See my response.
-
Andrew C over 9 yearspossible duplicate of How can I delete all git branches which have been merged?
-
Admin over 8 years
-
amaechler about 8 yearsPossible duplicate of Remove branches no longer on remote
-
-
Admin almost 11 yearsThis answer is not quite correct. The
--prune
flag will only delete remote-tracking branches, not local branches. -
sf89 almost 11 yearsAgreed with @Cupcake here, this doesn't achieve what I'm looking for here.
-
Admin almost 11 yearsYou can put the commands in an alias and make it a single command. However, since
branch
is a porcelain and not a plumbing command, watch out for any UI changes in future versions of Git that may break it. -
Spechal over 10 yearsNot going to upvote, but this is what I needed after having deleted local branches and then deleting from GitHub but them still existing as remotes in my git remote -v command.
-
Rubens Mariuzzo about 10 yearsPerfect! Note that following the Github Workflow the local branch
master
will be deleted. -
sf89 about 10 yearsNope pretty sure it stays there (I'm using it everyday and it doesn't seem to do that).
-
Chad almost 10 yearsI copy-pasted the command into my console and it deleted my local master branch
-
sf89 almost 10 yearsYup if your master is not pushed to your remote then it gets deleted like any other branch. Make sure you read carefully the question before you copy and paste anything: as I said, I needed a way to get rid of deleted branches on the remote (branches that no longer existed). That's why your master got blown up buddy.
-
sf89 almost 10 yearsOf course it has the potential of deleting master. Please read the question carefully. As I said there, I needed a way to clean things up on my local. That means deleting all the branches that no longer exist on remote. If master is no longer there, then it will disappear on your local machine as well.
-
shashwat over 9 yearsis there really a way to delete local branch for which remote tracking branch is deleted ?
-
Miguelgraz about 9 yearsI took the liberty to ensure that I'll always do that against master, therefore:
git checkout master; git pull origin master; git fetch --all -p; git branch -vv | grep gone | awk '{ print $1 }' | xargs -n 1 git branch -d
Great script and explanation, thank you for that :) -
chawkinsuf about 9 yearsNote that
branch -vv
shows the last commit message from the branch. If you happened to have "gone" in that message thegrep gone
would hit that branch too. So,grep ": gone]"
is probably a little safer to use. -
Matt Montag almost 9 yearsThis is exactly the answer I was looking for. The one-liner piped commands that delete branches scare me a bit. This is a nice safe option for routine cleanup.
-
catalyst294 almost 9 yearsIf you want to keep your master you and just add an additional grep of
grep -v "master"
after the first one. You can follow that pattern with any other branch you might want to keep. -
e_m0ney almost 9 yearsYou can also do
git fetch --prune
, that's my way of choice -
Andrii Gladkyi over 8 yearsThis is the actual answer to the question. Thank you.
-
Andrew Burns over 8 yearsFYI if you want to keep multiple branches you can use a single grep, like so:
grep -Ev '(\*|master|important-branch)'
-
profuel over 8 yearsI'd add one more thing - make to switch to most relevant branch you have. Otherwise, you will get notices:
error: The branch 'feature/SHOP-498' is not fully merged. If you are sure you want to delete it, run 'git branch -D feature/SHOP-498'.
-
Alessio over 8 years@profuel I'm not so sure if I get your comment right, whereas you say "most relevant branch". That type of output is exactly the warning I want to see, as it happens for local branches which I didn't push fully - so for me for example they contain some work in progress which is so experimental that is not even worth to be pushed. So either you push it, then it will get deleted, or you delete it manually, but the warning is needed as you've some unpushed commits into it.
-
3ocene over 8 yearsWhy so many downvotes? I mean obviously not efficient, especially with larger repos, but it does what OP asked. Is there some other reason not to do this?
-
dskrvk about 8 yearsIf you want to put this in your
~/.gitconfig
instead, add the following to the[alias]
section:gbpurge = !"git branch --merged | grep -Ev '\\*|master|develop|staging' | xargs -n 1 git branch -d"
(no need to use () in the grep expression). -
Attila Szeremi about 8 yearsit would be nice if you could automatically make it so you'd keep any branches whose remote equivalent haven't been deleted; that way you don't have to keep track of master|develop|staging|etc
-
jww almost 8 yearsYet another Git error from advice found on Stack overflow...
git pull --prune
resulted in "You asked to pull from the remote '--prune', but did not specify a branch. Because this is not the default configured remote for your current branch, you must specify a branch on the command line." -
jww almost 8 yearsMore bad advice on Stack Overflow... You just whacked Master with The quick way. Perhaps you should have stated that the The quick way deletes master even if its not deleted on remote...
-
PapaKai almost 8 years
git fetch origin --prune
may help in prev. comments case -
Jakub Bochenski over 7 yearsHow about getting rid of grep completely in favor of
git branch -vv | awk '{ if ($4 == "gone]") print $1 }'
-- one less pipe and it's slightly more exact as it only checks forgone]
in specific column -
Jakub Bochenski over 7 yearsEven better:
awk '$3 $4 ~ /:gone]$/ { print $1 }'
-
sevenseacat over 7 yearsBecause you'll lose all your local branches, stashes, unpushed commits... it's like fishing with dynamite.
-
Admin about 7 yearsThe same happens when the laptop you are working on somehow gets corrupted, lost, or stolen, so I tend not to keep nothing crucial locally. It seems better to me to just create a branch and push it, even for small features, and delete it after it is not useful anymore.
-
Alexar almost 7 yearsBE CAREFUL if you're a newbie. Adding a git alias and using it in other repositories requires extra care. Not every git repository would have "master|develop|staging" as main branches. I personally don't recommend this method.
-
Enrico almost 7 yearsthis is listing me
master
too, it doesn't work as expected; be careful -
Cas over 6 yearsApart from needing
-D
instead of-d
this is the perfect answer! -
Alessio over 6 years@Cas thanks to point that out! I will add a note about it, but given the --force option of -D, I would let the others to choose what's best for them :)
-
A.Wan over 3 yearsthank you, this worked for me where the other commands using
--merged
didn't! -
Alessio over 3 years@A.Wan you're welcome, I still use this very same nowadays :)
-
murchu27 about 3 yearsThis worked perfectly, except for on a particular shell where my user is not given access to
xargs
. For anyone else in that situation, you can pipe to a while loop instead ofxargs
, like so:...awk '{ print $1 }' | while read -r line; do git branch -D $line; done
-
SomeoneElse over 2 yearsThis does have the advantage over the other answers here of "actually answering the question as asked - in the singular: "get Git to remove my local version of the branch as well?".