105

I want to delete all branches that get listed in the output of ...

$ git branch

... but keeping current branch, in one step. Is that possible? If so, how?

sensorario
  • 15,862
  • 24
  • 85
  • 131
  • 1
    possible duplicate of [Delete all local git branches](http://stackoverflow.com/questions/10610327/delete-all-local-git-branches) – Andrew C Feb 18 '15 at 00:38
  • 1
    possible duplicate of [How to remove all local git branches but keep master with one command line?](http://stackoverflow.com/questions/25112684/how-to-remove-all-local-git-branches-but-keep-master-with-one-command-line) – random Feb 18 '15 at 01:41
  • Possible duplicate of [How can I delete all git branches which have been merged?](https://stackoverflow.com/questions/6127328/how-can-i-delete-all-git-branches-which-have-been-merged) – Giulio Caccin Aug 01 '17 at 09:11

15 Answers15

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

will delete all branches except master (replace master with branch you want to keep, but then it will delete master)

Damjan Pavlica
  • 21,431
  • 6
  • 55
  • 65
pankijs
  • 4,935
  • 3
  • 14
  • 13
72

Based on @pankijs answer, I made two git aliases:

[alias]
    # Delete all local branches but master and the current one, only if they are fully merged with master.
    br-delete-useless = "!f(){\
        git branch | grep -v "master" | grep -v ^* | xargs git branch -d;\
    }; f"
    # Delete all local branches but master and the current one.
    br-delete-useless-force = "!f(){\
        git branch | grep -v "master" | grep -v ^* | xargs git branch -D;\
    }; f"

To be added in ~/.gitconfig


And, as @torek pointed out:

Note that lowercase -d won't delete a "non fully merged" branch (see the documentation). Using -D will delete such branches, even if this causes commits to become "lost"; use this with great care, as this deletes the branch reflogs as well, so that the usual "recover from accidental deletion" stuff does not work either.

Basically, never use the -force version if you're not 300% sure you won't lose anything important. Because it's lost forever.

nealio82
  • 2,581
  • 1
  • 15
  • 19
Vadorequest
  • 12,672
  • 17
  • 87
  • 183
  • 2
    commits to a deleted branch should still be in the reflog for a while. – CaptRespect Nov 16 '17 at 18:53
  • Indeed, the commits would stay in reflog. But not the branch itself. I wouldn't try it, but I guess you may find your commits, but go back to the branch state? I doubt so. Cherry-pick could be used to retrieve commits in a deleted branch, but you won't be able to restore the branch itself. – Vadorequest Feb 19 '18 at 23:28
  • 1
    @Vadorequest you can re-create the branch pointing a certain commit by doing `git branch branchname commitid` – pqnet Mar 26 '18 at 09:26
  • @pqnet I didn't know that would recreate all the history for that branch, thanks, good to know! – Vadorequest Mar 26 '18 at 12:54
  • 1
    @Vadorequest since commit objects are immutable (and indexed as hashes), every edit requires creating a new object (with a different hash) – pqnet Apr 04 '18 at 13:45
44

first (switch to the branch you want to keep > ex: master):

git checkout master

second (make sure you are on master)

git branch -D $(git branch)
KhogaEslam
  • 1,383
  • 16
  • 18
13

git branch -d (or -D) allows multiple branch names, but it's a bit tricky to automatically supply "all local branches excluding the one I'm on now" without writing at least a little bit of code.

The "best" (formally correct) method is to use git for-each-ref to get the branch names:

git for-each-ref --format '%(refname:short)' refs/heads

but then it's even harder to figure out which branch you're on (git symbolic-ref HEAD is the "formally correct" method for this, if you want to write a fancy script).

More conveniently, you can use git branch, which prints your local branch names preceded by two spaces or (for the current branch) by an asterisk *. So, run this through something to remove the * version and you're left with space-separated branch names, which you can then pass to git branch -d:

git branch -d $(git branch | grep -v '^*')

or:

git branch | grep -v '^*' | xargs git branch -d

Note that lowercase -d won't delete a "non fully merged" branch (see the documentation). Using -D will delete such branches, even if this causes commits to become "lost"; use this with great care, as this deletes the branch reflogs as well, so that the usual "recover from accidental deletion" stuff does not work either.

torek
  • 330,127
  • 43
  • 437
  • 552
  • It should be `git branch -D $(git branch | grep -v '^*')`, if you want to delete those branches which have merged. – Pratik Singhal Sep 08 '18 at 12:24
  • @PratikSinghal: that deletes *all* other branches, not just branches Git considers "merged". **This is rarely a good idea.** I already pointed out both of these items in my answer. – torek Sep 08 '18 at 17:15
12

To remove all merged branches(except current -v ‘*’):

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

also I made such command for repo complete clean up:

alias git-clean="git branch  | grep -v '*' | grep -v 'master' | xargs git branch -D  && git reset --hard && git clean -d -x -f"

taken from here.

Stepan Suvorov
  • 21,636
  • 25
  • 93
  • 166
12

Delete all branches except a specific branch:

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

Delete all local branches except develop and master

git branch | grep -v "develop" | grep -v "master" | xargs git branch -D
Asad Manzoor
  • 959
  • 8
  • 16
10

To delete all branches except for the current branch in one step:

git branch | grep -v $(git rev-parse --abbrev-ref HEAD) | xargs git branch -D

Dan Dye
  • 617
  • 6
  • 15
9

For Windows, in Powershell use:

git branch | %{ $_.Trim() } | ?{ $_ -ne 'master' } | %{ git branch -D $_ }
Robert Corvus
  • 1,784
  • 18
  • 26
4

Delete all merged branch locally:

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

Delete all branches except a specific branch:

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

Delete all local branches except develop and master

git branch | grep -v "develop" | grep -v "master" | xargs git branch -D
Asad Manzoor
  • 959
  • 8
  • 16
3

I once created this construct for my Windows environment. Maybe it'll help someone else. During execution, the master and current branch are not deleted. All other merged branches will be deleted regardless.

@echo off
cd PATH_TO_YOUR_REPO

REM -- Variable declerations
set "textFile=tempBranchInfo.txt"
set "branchToKeep=master"
set "branchToReplaceWith="
git branch --merged > %textFile%

REM -- remove "master" from list to keep the branch
for /f "delims=" %%i in ('type "%textFile%" ^& break ^> "%textFile%" ') do (
    set "line=%%i"
    setlocal enabledelayedexpansion
    >>"%textFile%" echo(!line:%branchToKeep%=%branchToReplaceWith%!
    endlocal
)

REM -- execute branch delete commands
for /f "delims=" %%a in (%textFile%) do (
    git branch -D %%a
)

REM -- remove temp-file with branch information inside
DEL %textFile%

REM -- show local branches after the cleaning
echo Local branches:
git branch

pause 
exit
Userino
  • 863
  • 7
  • 28
3

I use this because I get to be more selective in what I do not want to delete. This below command removes every branch except master, develop and the current branch.

BRANCHES=$(git branch | egrep -v "(master|develop|\*)" | xargs git branch -D)
echo $BRANCHES

So I put this in my ~/.zshrc

delete_branches() {
  BRANCHES=$(git branch | egrep -v "(master|develop|\*)" | xargs git branch -D)
  echo $BRANCHES
}

alias cleanup_branches=delete_branches
Justin Rice
  • 791
  • 9
  • 12
2

Assuming git branch shows the current branch prefixed with *; Using Powershell the following one liner will delete all branches that don't start with *.

git branch | ? { $_ -lt "*" } | % { git branch -D $_.Trim() }

? = Where-Object

% = Foreach-Object

Aaron
  • 587
  • 9
  • 17
1

So I see a lot of hard coded branch names here... And I think my answer here is more accurate to the "current branch" part of the question whilst keeping it single line and readable to bash newbies like me. Just to place credit where it's due, the answer is rather obviously also based on @pankijs's answer.

git branch | grep -v $(git branch --show-current) | xargs git branch -d

and I have it aliased on one line in my .bash_aliases in debian aswell.

alias gitbclean='git branch | grep -v $(git branch --show-current) | xargs git branch -d'

(Though I thinks some bash features need to be enabled for the sub command to run on some command lines)

0

IMHO, the safest way of removing local branches is:

git branch -av | grep "\[gone\]" | awk '{print $1}' | xargs git branch -d

Also, more info related to this topic you can find Delete all local git branches

elbik
  • 1,050
  • 8
  • 15
  • to print the `gone` marker you should use `-vv` (verbose twice), while `-a` won't help you (it lists also remote branches) – pqnet Apr 23 '18 at 19:25
0

Easiest of all of the above:

  1. Get a list of all the branches by using - "git branch" command in your project folder
  2. Copy the list of branches which you get
  3. Remove "master" from the list and the ones which you want to keep
  4. Write commands to delete all branches together separated by "&&" (see example below)
  5. If you want to delete even those branches which have not been fully merged use "-D" instead of "-d" in below command. "-D" deletes branches forcefully

Example:

  • git branch -d branch1 && git branch -d branch2 && git branch -d branch3 && git branch -d branch4 && git branch -d branch5 && ...

This works for me and I find it super easy to remove many branches together and I also get a message for each branch which gets deleted and error messages for those branches which fail to get deleted.

SagarG
  • 11
  • 5