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

后端 未结 30 1060
离开以前
离开以前 2020-11-22 14:22

I have many Git branches. How do I delete branches which have already been merged? Is there an easy way to delete them all instead of deleting them one by one?

相关标签:
30条回答
  • 2020-11-22 15:20

    You'll want to exclude the master & develop branches from those commands.

    Local git clear:

    git branch --merged | grep -v '\*\|master\|develop' | xargs -n 1 git branch -d
    

    Remote git clear:

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

    Sync local registry of remote branches:

    git fetch -p
    
    0 讨论(0)
  • 2020-11-22 15:21

    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 ...
    
    0 讨论(0)
  • 2020-11-22 15:23

    Alias version of Adam's updated answer:

    [alias]
        branch-cleanup = "!git branch --merged | egrep -v \"(^\\*|master|dev)\" | xargs git branch -d #"
    

    Also, see this answer for handy tips on escaping complex aliases.

    0 讨论(0)
  • 2020-11-22 15:24

    For those of you that are on Windows and prefer PowerShell scripts, here is one that deletes local merged branches:

    function Remove-MergedBranches
    {
      git branch --merged |
        ForEach-Object { $_.Trim() } |
        Where-Object {$_ -NotMatch "^\*"} |
        Where-Object {-not ( $_ -Like "*master" )} |
        ForEach-Object { git branch -d $_ }
    }
    
    0 讨论(0)
  • 2020-11-22 15:24

    You can add the commit to the --merged option. This way you can make sure only to remove branches which are merged into i.e. the origin/master

    Following command will remove merged branches from your origin.

    git branch -r --merged origin/master | grep -v "^.*master" | sed s:origin/:: |xargs -n 1 git push origin --delete 
    

    You can test which branches will be removed replacing the git push origin --delete with echo

    git branch -r --merged origin/master | grep -v "^.*master" | sed s:origin/:: |xargs -n 1 echo
    
    0 讨论(0)
  • 2020-11-22 15:24

    The accepted solution is pretty good, but has the one issue that it also deletes local branches that were not yet merged into a remote.

    If you look at the output of you will see something like

    $ git branch --merged master -v
      api_doc                  3a05427 [gone] Start of describing the Java API
      bla                      52e080a Update wording.
      branch-1.0               32f1a72 [maven-release-plugin] prepare release 1.0.1
      initial_proposal         6e59fb0 [gone] Original proposal, converted to AsciiDoc.
      issue_248                be2ba3c Skip unit-for-type checking. This needs more work. (#254)
      master                   be2ba3c Skip unit-for-type checking. This needs more work. (#254)
    

    Branches bla and issue_248 are local branches that would be deleted silently.

    But you can also see the word [gone], which indicate branches that had been pushed to a remote (which is now gone) and thus denote branches can be deleted.

    The original answer can thus be changed to (split into multiline for shorter line length)

    git branch --merged master -v | \
         grep  "\\[gone\\]" | \
         sed -e 's/^..//' -e 's/\S* .*//' | \
          xargs git branch -d
    

    to protect the not yet merged branches. Also the grepping for master to protect it, is not needed, as this has a remote at origin and does not show up as gone.

    0 讨论(0)
提交回复
热议问题