Categories
branch feature-branch git version-control

How do I delete all Git branches which have been merged?

2392

How do I delete branches which have already been merged? Can I delete them all at once, instead of deleting each branch one-by-one?

6

  • 49

    To be slightly more specific git branch -D deletes any branch whether it as been merged or not.

    – PhilT

    Feb 8, 2017 at 9:48

  • 16

    You can also do this directly from GitHub, if you go to the ‘branches’ section of your repo (e.g. github.com/<username>/<repo_name>/branches). There should be a list of all your branches, with a red trashcan icon on the side which will delete the selected branch. Much faster than doing it in the terminal! Will also show how far ahead/behind master each branch is. However, your local client will still list the old branches if you run git branch -a; use git fetch --prune to remove them (as per this answer ).

    Feb 24, 2017 at 16:13


  • 3

    Script to do this locally or remotely – with safety checks and pre-configured “safe branches”: github.com/fatso83/dotfiles/tree/master/utils/… git delete-merged --doit origin or git delete-merged --doit --local

    – oligofren

    Jun 27, 2017 at 15:10


  • 4

    rm -fr work && git clone http://example.com/work.git over the years has become the easiest way to get out of a pickle with git.

    Apr 19, 2020 at 11:33

  • 1

    More recent question How can I delete all git branches which have been “Squash and Merge” via GitHub?, because “squashing and merging” was not available when this question was asked.

    – koppor

    Mar 28, 2021 at 16:22

3695

NOTE: You can add other branches to exclude like master and dev if your workflow has those as a possible ancestor. Usually I branch off of a “sprint-start” tag and master, dev and qa are not ancestors.


First, list locally-tracking branches that were merged in remote (consider using -r flag to list all remote-tracking branches).

git branch --merged

You might see few branches you don’t want to remove. We can add few arguments to skip important branches that we don’t want to delete like master or a develop. The following command will skip master branch and anything that has dev in it.

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

If you want to skip, you can add it to the egrep command like the following. The branch skip_branch_name will not be deleted.

git branch --merged| egrep -v "(^\*|master|main|dev|skip_branch_name)"

To delete all local branches that are already merged into the currently checked out branch:

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

You can see that master and dev are excluded in case they are an ancestor.


You can delete a merged local branch with:

git branch -d branchname

If it’s not merged, use:

git branch -D branchname

To delete it from the remote use:

git push --delete origin branchname

git push origin :branchname    # for really old git

Once you delete the branch from the remote, you can prune to get rid of remote tracking branches with:

git remote prune origin

or prune individual remote tracking branches, as the other answer suggests, with:

git branch -dr branchname

34

  • 73

    WARNING: If you just created a branch it will also delete that one. Make sure to not have a newly created branch in the list before you run the top most command.

    May 24, 2013 at 14:01

  • 199

    OPPOSITE OF WARNING: reflog will save your bacon. So don’t worry.

    Aug 20, 2014 at 1:05

  • 37

    Keep in mind that the first command only deletes local branches, so it isn’t as ‘dangerous’ as some have pointed out.

    Sep 15, 2014 at 23:21

  • 104

    PowerShell variant, so that I could find it here next time I googled the answer: git branch --merged | %{$_.trim()} | ?{$_ -notmatch 'develop' -and $_ -notmatch 'master'} | %{git branch -d $_}

    – vorou

    Dec 20, 2015 at 8:12

  • 28

    This produces an error fatal: branch name required if you have no branches that should be deleted. To avoid that you can pass -r to xargs so it won’t run git branch -d if the stdin is empty. (This a GNU xargs extension, according to the man page).

    Feb 9, 2016 at 14:40

551

To delete all branches on remote that are already merged:

git branch -r --merged | grep -v master | sed 's/origin\//:/' | xargs -n 1 git push origin

In more recent versions of Git

git branch -r --merged | grep -v master | sed 's/origin\///' | xargs -n 1 git push --delete origin

UPDATE (by @oliver; since does not fit in comment, but enough answers already): if you are on branch ABC then ABC will appear in the results of git branch -r --merged because the branch is not specified, so branch defaults to current branch, and a branch always qualifies as merged to itself (because there are no differences between a branch and itself!).

So either specify the branch:

git branch -r --merged master | grep -v master ...

OR first checkout master:

git checkout master | git branch -r --merged | grep -v ...

19

  • 20

    Best answer by far. Just a note, my master branch is named dev so I had to change that

    – Dorian

    Feb 13, 2014 at 21:33

  • 44

    I had to add | grep origin after grep -v master to prevent pushing branches of other remotes to origin. Highly recommending testing the output beforehand, using git branch -r --merged | grep -v master | grep origin | sed 's/origin\//:/' | xargs -n 1 echo

    – L0LN1NJ4

    Jun 8, 2015 at 8:06

  • 9

    I slightly modified to exclude develop branch as well. git branch -r --merged | grep -v master | grep -v develop | sed 's/origin\///' | xargs -n 1 git push --delete origin. Now this turned out to be my alias.

    – sarat

    Aug 15, 2015 at 12:19


  • 9

    What made this the best answer I’ve read, is the -r argument, which I’ve not seen mentioned anywhere else. It’s taken for granted that only local branches are worth doing some housekeeping on. But remotes are full of garbage too.

    Nov 2, 2015 at 17:49

  • 21

    Caution – just realized: this will obviously find branches merged to current branch, not master, so if you are on myFeatureBranch it will wipe origin/myFeatureBranch. Probably it’s best to git checkout master first.

    – jakub.g

    Feb 5, 2016 at 14:40

268

Just extending Adam’s answer a little bit:

Add this to your Git configuration by running git config -e --global

[alias]
    cleanup = "!git branch --merged | grep  -v '\\*\\|master\\|develop' | xargs -n 1 -r git branch -d"

And then you can delete all the local merged branches doing a simple git cleanup.

13

  • 15

    shouldn’t the first command be: git branch --merged master since you want to look at what has been merged into master, not currently checked out branch?

    Aug 12, 2016 at 16:23

  • @JoePhilllips Some people has the main branch not master but instead develop or dev and in that case the command will fail with fatal: malformed object name it’s better to have a generic command and you have the responsibility to run it

    – smohamed

    Aug 13, 2016 at 1:14


  • 1

    @JoePhilllips the point of this answer is to package up Adam’s answer (the top answer for this question) in helpful git alias. Adam’s answer doesn’t have what you are suggesting and so many people have found that useful so I would be inclined not to change mine. I would recommend opening the discussion on Adam’s answer if you feel strongly about it

    – real_ate

    Aug 16, 2016 at 7:39

  • 19

    Adding -r to xargs will prevent unnecessary errors (branch name required) when running this alias multiple times or when there is no branch left to be deleted. My alias looks like this: cleanup = "!git branch --merged | grep -v -P '^\\*|master|develop' | xargs -n1 -r git branch -d"

    Jun 23, 2017 at 9:14

  • 2

    Current command doesn’t filter out master and develop branches

    – Andriy F.

    Mar 2, 2019 at 9:52