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


当前回答

对于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

其他回答

tl;dr:git branch--format='%(if:notequals=main)%(refname:short)%(then)%(if:notequals=master)%。

看,妈妈,没有工具!

Git可以在不使用外部工具的情况下过滤分支,这意味着有一种跨平台、相对简单的方法可以从搜索中排除默认分支。要列出合并到“main”分支中的分支,不包括“main”分行本身:git branch--format='%(if:notequals=main)%(refname:short)%(then)%(refname:short,%(end)'--merged=main。对于“master”分支:git branch--format='%(如果:notequals=master)%(refname:short)%

我们还可以将两者结合起来,仅当分支名称既不匹配“main”也不匹配“master”时才打印分支名称:git branch--format='%(if:notequals=main)%(refname:short)%(then)%

最后一个附带一个小警告:您应该首先检查默认分支(在本例中为“main”或“master”),因为--merged没有值意味着“merged into HEAD”,它可能指向您要删除的分支之一。但是尝试删除当前的本地分支无论如何都不会起作用,因此如果您正在这样做,这不会有风险。

这种方法的另一个优点是没有多余的前导空格或星号可以过滤掉。

这些命令将为排除的分支打印空行,而不是不打印任何内容,但xargs会处理这一点。如果要使用xargs以外的其他方法处理行,可能需要对空行进行特殊处理(例如通过sed'/^$/d')

有关--format的更多信息,请参阅每个ref的git帮助。

假设我有一个名为upstream的远程和一个origin(GitHub风格,我的fork是origin,upstream是upstream)。

我不想从上游删除任何主机、HEAD或任何内容。我也不想删除开发分支,因为这是我们创建PR的公共分支。

列出所有远程分支,按合并的分支进行筛选:

git branch -r

从该列表中删除包含我知道不想删除的分支名称中的单词的行:

sed '/develop\|master\|HEAD\|upstream/d'

从引用名称中删除远程名称(origin/somebranch变为somebranch):

sed 's/.*\///'

使用xargs调用单线:

xargs git push --delete origin

把所有这些都放在一起,你会得到:

git branch -r --merged | sed '/develop\|master\|HEAD\|upstream/d' |  sed 's/.*\///' | xargs git push --delete origin

这将使我只剩下一些我曾经工作过但尚未合并的分支。然后,您可以逐个删除它们,因为它们不应该太多。

查找不再需要的分支:

git branch -ar

假设找到要删除的branch1、branch2和branch3:

git push --delete origin branch1 branch2 branch3

注意:如果您的工作流可能将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

Adam更新答案的别名版本:

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

此外,请参阅此答案以获得有关转义复杂别名的实用提示。

对于我来说,gitbranch--merged不显示通过GitHub PR合并的分支。我不确定原因,但我使用以下行删除所有没有远程跟踪分支的本地分支:

diff <(git branch --format "%(refname:short)") <(git branch -r | grep -v HEAD | cut -d/ -f2-) | grep '<' | cut -c 3- | xargs git branch -D

说明:

gitbranch--格式“%(refname:short)”提供本地分支列表gitbranch-r | grep-v HEAD | cut-d/-f2-提供远程分支列表,过滤掉HEADdiff<(…)<(grep“<”筛选第一个列表中存在但第二个列表中不存在的分支cut-c 3-给出从第3个字符开始的行,从而删除前缀<xargs git branch-D针对每个分支名称执行git branch-D

或者,可以这样避免grep-v“<”:

diff --old-line-format="%L" --new-line-format="" --unchanged-line-format="" <(git branch --format "%(refname:short)") <(git branch -r | grep -v HEAD | cut -d/ -f2-) | xargs git branch -D