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

后端 未结 30 1061
离开以前
离开以前 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:06

    I use the following Ruby script to delete my already merged local and remote branches. If I'm doing it for a repository with multiple remotes and only want to delete from one, I just add a select statement to the remotes list to only get the remotes I want.

    #!/usr/bin/env ruby
    
    current_branch = `git symbolic-ref --short HEAD`.chomp
    if current_branch != "master"
      if $?.exitstatus == 0
        puts "WARNING: You are on branch #{current_branch}, NOT master."
      else
        puts "WARNING: You are not on a branch"
      end
      puts
    end
    
    puts "Fetching merged branches..."
    remote_branches= `git branch -r --merged`.
      split("\n").
      map(&:strip).
      reject {|b| b =~ /\/(#{current_branch}|master)/}
    
    local_branches= `git branch --merged`.
      gsub(/^\* /, '').
      split("\n").
      map(&:strip).
      reject {|b| b =~ /(#{current_branch}|master)/}
    
    if remote_branches.empty? && local_branches.empty?
      puts "No existing branches have been merged into #{current_branch}."
    else
      puts "This will remove the following branches:"
      puts remote_branches.join("\n")
      puts local_branches.join("\n")
      puts "Proceed?"
      if gets =~ /^y/i
        remote_branches.each do |b|
          remote, branch = b.split(/\//)
          `git push #{remote} :#{branch}`
        end
    
        # Remove local branches
        `git branch -d #{local_branches.join(' ')}`
      else
        puts "No branches removed."
      end
    end
    
    0 讨论(0)
  • 2020-11-22 15:06

    If you'd like to delete all local branches that are already merged in to the branch that you are currently on, then I've come up with a safe command to do so, based on earlier answers:

    git branch --merged | grep -v \* | grep -v '^\s*master$' | xargs -t -n 1 git branch -d
    

    This command will not affect your current branch or your master branch. It will also tell you what it's doing before it does it, using the -t flag of xargs.

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

    Note: I am not happy with previous answers, (not working on all systems, not working on remote, not specifying the --merged branch, not filtering exactly). So, I add my own answer.

    There are two main cases:

    Local

    You want to delete local branches that are already merged to another local branch. During the deletion, you want to keep some important branches, like master, develop, etc.

    git branch --format "%(refname:short)" --merged master | grep -E -v '^master$|^feature/develop$' | xargs -n 1 git branch -d
    

    Notes:

    • git branch output --format ".." is to strip whitespaces and allow exact grep matching
    • grep -E is used instead of egrep, so it works also in systems without egrep (i.e.: git for windows).
    • grep -E -v '^master$|^feature/develop$' is to specify local branches that I don't want to delete
    • xargs -n 1 git branch -d: perform the deletion of local branches (it won't work for remote ones)
    • of course you get an error if you try deleting the branch currently checked-out. So, I suggest to switch to master beforehand.

    Remote

    You want to delete remote branches that are already merged to another remote branch. During the deletion, you want to keep some important branches, like HEAD, master, releases, etc.

    git branch -r --format "%(refname:short)" --merged origin/master | grep -E -v '^*HEAD$|^*/master$|^*release' | cut -d/ -f2- | xargs -n 1 git push --delete origin
    

    Notes:

    • for remote, we use the -r option and provide the full branch name: origin/master
    • grep -E -v '^*HEAD$|^*/master$|^*release' is to match the remote branches that we don't want to delete.
    • cut -d/ -f2- : remove the unneeded 'origin/' prefix that otherwise is printed out by the git branch command.
    • xargs -n 1 git push --delete origin : perform the deletion of remote branches.
    0 讨论(0)
  • 2020-11-22 15:09

    As of 2018.07

    Add this to [alias] section of your ~/.gitconfig:

    sweep = !"f() { git branch --merged | egrep -v \"(^\\*|master|dev)\" || true | xargs git branch -d; }; f"
    

    Now you can just call git sweep to perform that needed cleanup.

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

    Using Git version 2.5.0:

    git branch -d `git branch --merged`
    
    0 讨论(0)
  • 2020-11-22 15:14

    UPDATE:

    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 all branches that were merged in remote.

    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
    
    0 讨论(0)
提交回复
热议问题