如何删除已合并的分支?我可以一次删除所有分支,而不是逐个删除每个分支吗?


当前回答

下面创建一个别名gitcleanup,其中包含一个可选参数分支。默认情况下,它使用远程源的默认分支。已合并到此中的每个分支都将被删除。还有一个-d/-dryrun选项,用于显示将删除的内容。

安装程序

git config --global alias.cleanup '!COMMAND="git branch -D"; while [[ $# -gt 0 ]]; do case "$1" in -d|--dryrun) COMMAND="echo"; shift; ;; *) MAIN_BRANCH="$1"; shift;; esac; done; MAIN_BRANCH="${MAIN_BRANCH:-$(git symbolic-ref refs/remotes/origin/HEAD)}"; git for-each-ref --merged="$MAIN_BRANCH" --no-contains="$MAIN_BRANCH" --format="%(refname:short)" refs/heads/ | xargs -n1 -r $COMMAND;#'

用法:

git cleanup             # delete all branches that have been merged into origin/HEAD
git cleanup master2     # delete all branches that have been merged into master2
git cleanup master2 -d  # do a dryrun (show names of branches that would be delted)

可读代码

谁能读到那句“oneliner”?好了,给你

COMMAND="git branch -D";
while [[ $# -gt 0 ]]; do
  case "$1" in
    -d|--dryrun)
      COMMAND="echo"; 
      shift; 
      ;; 
    *)
      MAIN_BRANCH="$1";
      shift
    ;;
  esac;
done;
MAIN_BRANCH="${MAIN_BRANCH:-$(git symbolic-ref refs/remotes/origin/HEAD)}"; 
git for-each-ref --merged="$MAIN_BRANCH" --no-contains="$MAIN_BRANCH" --format="%(refname:short)" refs/heads/ | xargs -n1 -r $COMMAND;
#

与其他答案有什么不同?

使用--no contains选项过滤掉标识分支(所有其他被删除的分支都已合并到其中的分支),而不是grep-v(如果您特定于分支并指定refs/heads/master,则效果更好)使用远程HEAD检查默认分支名称具有一个参数,用于指定要用作合并主节点的分支具有干式运行选项

其他回答

要删除远程上已合并的所有分支,请执行以下操作:

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

在Git的最新版本中

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

UPDATE(通过@oliver;因为不适合注释,但已经有足够的答案了):如果您在分支ABC上,那么ABC将出现在git branch-r--merged的结果中,因为未指定分支,所以分支默认为当前分支,分支始终符合自身合并的条件(因为分支和自身之间没有区别!)。

因此,指定分支:

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

OR第一个结账主机:

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

注意:我对前面的回答不满意,(不在所有系统上工作,不在远程工作,不指定--merged分支,不完全过滤)。所以,我补充了我自己的答案。

主要有两种情况:

地方的

您要删除已合并到另一个本地分支的本地分支。在删除过程中,您希望保留一些重要分支,如master、develop等。

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

笔记:

git分支输出--格式“..”是去除空格并允许精确的grep匹配grep-E用于代替egrep,因此它也适用于没有egrep的系统(即:git for windows)。grep-E-v“^master$|^feature/develd$”是指定我不想删除的本地分支xargs-n 1 git branch-d:执行本地分支的删除(它不适用于远程分支)当然,如果您尝试删除当前签出的分支,会出现错误。所以,我建议提前切换到master。

遥远的

您要删除已合并到另一个远程分支的远程分支。在删除过程中,您希望保留一些重要的分支,如HEAD、master、releases等。

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

笔记:

对于remote,我们使用-r选项并提供完整的分支名称:origin/mastergrep-E-v'^*HEAD$|^*/master$|^*release'是为了匹配我们不想删除的远程分支。cut-d/-f2-:删除不需要的“origin/”前缀,否则将由gitbranch命令打印出来。xargs-n 1 git push--delete origin:执行远程分支的删除。

对于Windows,您可以使用以下命令安装Cygwin并删除所有远程分支:

git branch -r --merged | "C:\cygwin64\bin\grep.exe" -v master | "C:\cygwin64\bin\sed.exe" 's/origin\///' | "C:\cygwin64\bin\xargs.exe" -n 1 git push --delete origin

注意:如果您的工作流可能将master和dev作为祖先,则可以添加其他分支以排除它们。通常我从“sprint-start”标签分支出来,master、dev和qa都不是祖先。


首先,列出在远程中合并的本地跟踪分支(考虑使用-r标志列出所有远程跟踪分支)。

git branch --merged

您可能会看到一些不想删除的分支。我们可以添加一些参数来跳过我们不想删除的重要分支,比如master或develop。下面的命令将跳过master分支和其中包含dev的任何内容。

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

如果要跳过,可以将其添加到egrep命令中,如下所示。不会删除分支skip_branch_name。

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

要删除已合并到当前签出分支的所有本地分支,请执行以下操作:

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

您可以看到master和dev被排除在外,以防它们是祖先。


您可以通过以下方式删除合并的本地分支:

git branch -d branchname

如果未合并,请使用:

git branch -D branchname

要从远程使用中删除它,请执行以下操作:

git push --delete origin branchname

git push origin :branchname    # for really old git

从远程删除分支后,可以通过以下方式进行修剪以消除远程跟踪分支:

git remote prune origin

或者如另一个答案所示,通过以下方式修剪单独的远程跟踪分支:

git branch -dr branchname

Windoze友好的Python脚本(因为git sweep阻塞了Wesnoth存储库):

#!/usr/bin/env python
# Remove merged git branches. Cross-platform way to execute:
#
#   git branch --merged | grep -v master | xargs git branch -d
#
# Requires gitapi - https://bitbucket.org/haard/gitapi
# License: Public Domain

import gitapi

repo = gitapi.Repo('.')
output = repo.git_command('branch', '--merged').strip()
for branch in output.split('\n'):
  branch = branch.strip()
  if branch.strip(' *') != 'master':
    print(repo.git_command('branch', '-d', branch).strip())

https://gist.github.com/techtonik/b3f0d4b9a56dbacb3afc