如何删除所有已合并的Git分支?


1933

我有很多Git分支。如何删除已经合并的分支?有没有一种简单的方法可以将它们全部删除,而不是一个一个地删除它们?


46
具体来说,git branch -D删除任何分支(无论是否已合并)。
PhilT

12
如果转到存储库的“分支”部分(例如github.com/<username>/<repo_name>/branches),也可以直接从GitHub执行此操作。应该有所有分支的列表,侧面有一个红色的垃圾桶图标,它将删除所选的分支。比在终端上快得多!还将显示master每个分支的前/后距离。但是,如果您运行,您的本地客户端仍会列出旧分支git branch -a;用于git fetch --prune删除它们(按照此答案)。
user5359531

3
在本地或远程执行此操作的脚本-具有安全检查和预先配置的“安全分支”:github.com/fatso83/dotfiles/tree/master/utils/… git delete-merged --doit origingit delete-merged --doit --local
oligofren

您也可以使用此应用程序自动删除合并的分支。
Sebass van Boxel

rm -fr work && git clone http://example.com/work.git多年来,已成为使用git摆脱泡菜的最简单方法。
Reactgular

Answers:


3114

更新:

如果您的工作流程可能将其作为祖先,则可以添加其他分支以排除像master和dev这样的分支。通常,我从“ sprint-start”标签分支出来,而master,dev和qa不是祖先。

首先,列出所有在远程中合并的分支。

git branch --merged

您可能会看到几个不想删除的分支。我们可以添加一些参数来跳过不想删除的重要分支,例如master或developer。以下命令将跳过master分支以及其中包含dev的所有内容。

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

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

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

删除所有已经合并到当前签出分支中的本地分支:

git branch --merged | egrep -v "(^\*|master|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

希望这可以帮助。


46
警告:如果您刚刚创建了一个分支,它也会删除该分支。在运行最顶部的命令之前,请确保列表中没有新创建的分支。
加里·哈兰

153
反对警告:reflog将保存您的培根。所以不用担心
亚当·迪米特鲁克

33
请记住,第一个命令仅删除本地分支,因此它并不像某些人所指出的那样“危险”。
ifightcrime 2014年

79
PowerShell变体,以便下次我用git branch --merged | %{$_.trim()} | ?{$_ -notmatch 'develop' -and $_ -notmatch 'master'} | %{git branch -d $_}
谷歌

23
fatal: branch name required如果您没有应删除的分支,则会产生错误。为避免这种情况,您可以传递-r给,xargs以便git branch -d如果stdin为空,它将不会运行。(根据手册页,这是GNU xargs扩展名)。
Marius Gedminas'2

455

要删除远程上已合并的所有分支:

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 ...

或第一个结帐管理员:

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

18
迄今为止最好的答案。请注意,我的主分支的名称dev如此,所以我不得不更改它
Dorian

41
我必须添加| grep origingrep -v master才能防止将其他遥控器的分支推到原点。强烈建议您使用git branch -r --merged | grep -v master | grep origin | sed 's/origin\//:/' | xargs -n 1 echo
L0LN1NJ4

9
我稍加修改以排除develop分支。git branch -r --merged | grep -v master | grep -v develop | sed 's/origin\///' | xargs -n 1 git push --delete origin。现在,事实证明这是我的别名。
sarat 2015年

8
使这个最佳答案成为我所读过的,是-r我在其他任何地方都没有提到的论点。只有本地分支机构值得做一些内务处理,这是理所当然的。但是遥控器也充满了垃圾。
阿斯比约恩Ulsberg

19
注意-刚意识到:这显然会发现分支合并到当前分支,而不是主分支,因此如果在myFeatureBranch它上面,则将擦除origin/myFeatureBranch。也许最好git checkout master先。
jakub.g,2016年

190

只是扩大了亚当的答案:

通过运行将其添加到您的Git配置 git config -e --global

[alias]
    cleanup = "!git branch --merged | grep  -v '\\*\\|master\\|develop' | xargs -n 1 git branch -d"

然后您可以删除所有本地合并分支,并执行简单操作git cleanup


11
第一个命令不应该是:git branch --merged master既然您想查看已合并到master中的内容,而不是当前未检出的分支?
乔·菲利普斯

@JoePhilllips有些人的主分支不是master,而是developor dev,在这种情况下,该命令将失败,fatal: malformed object name最好是有一个通用命令,而您有责任运行它

1
@JoePhilllips此答案的重点是将有用的git别名打包为Adam的答案(此问题的最高答案)。亚当的答案没有您的建议,因此很多人发现它很有用,所以我倾向于不改变我的想法。如果您对此有强烈的
看法,

13
添加-rxargs会出现不必要的错误(branch name required)多次运行此别名或时有没有留下分支被删除时。我的别名如下:cleanup = "!git branch --merged | grep -v -P '^\\*|master|develop' | xargs -n1 -r git branch -d"
spezifanta

1
当前命令不会过滤掉master并开发分支
Andriy F.

83

这也适用于删除除master以外的所有合并分支。

git branch --merged | grep -v '^* master$' | grep -v '^  master$' | xargs git branch -d

3
现在它不会删除其中的任何分支master。尝试grep -v ^master$中间。
wchargin

| grep -v '^\*'如果您不在主
服务器

5
太好了,谢谢!使用此工具的任何人都需要注意的一件事:请注意,中有两个空格grep -v '^ master$'。如果您自己输入并错过其中一项,那么master如果您不在其中,则将其删除。
sty14 2014年

3
@ Mr.Polywhirl您的编辑将中断命令,您应该将其还原。这两个空格是必需的,因为git branch如果不是当前签出的分支,它将在新行上列出每个分支名称,并在左边添加两个空格。基本上,您可以确保运行此命令的任何人都将删除其master分支,除非它是当前已签出的分支。
样式2015年

79

您将要从这些命令中排除masterdevelop分支。

本地git clear:

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

远程git clear:

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

同步远程分支机构的本地注册表:

git fetch -p

3
远程版本也为+1(但因为有远程--prune而需要的较少)。另外值得一提的是,thoose不会与旧版本的git的工作
malko

4
git config --global --add fetch.prune true在获取或拉取时自动修剪。
T3rm1 2015年

1
请注意,修剪与远程清除不同。远程清除实际上删除了与当前分支完全合并的远程分支。Prune仅清除已删除的远程分支的本地注册表。
Guido Bouman

完全这个词有点误导,因为分支在合并之前会被视为已合并,但在合并后会有新的提交(未合并)。
烤饼

要在一个呼叫中删除所有始发远端,我使用了:git branch -r --merged | grep -v '\*\|master\|develop' | grep '^\s*origin/' | sed 's/origin\///' | tr "\n" " " | xargs git push --delete origin
GPHemsley

48

对于那些使用Windows并喜欢PowerShell脚本的用户,以下是一种删除本地合并分支的方法:

function Remove-MergedBranches
{
  git branch --merged |
    ForEach-Object { $_.Trim() } |
    Where-Object {$_ -NotMatch "^\*"} |
    Where-Object {-not ( $_ -Like "*master" )} |
    ForEach-Object { git branch -d $_ }
}

13
为了好奇,可以将其缩短为 git branch --merged | ?{-not ($_ -like "*master")} | %{git branch -d $_.trim()}
Iain Ballard 2014年

5
@IainBallard当然,我可以使用别名。如果要最大程度地提高可读性,则不建议这样做。github.com/darkoperator/PSStyleGuide/blob/master/English.md
Klas Mellbourn 2014年

1
当然。我发现您的答案非常有帮助:-)但是,有时长格式的powershell语法会影响代码块中发生的事情。但主要是我提出了一些您可以复制/粘贴或一次性输入的内容。再次感谢。
伊恩·巴拉德

4
这是用于Windows cmd shell的单行代码,保留了master和当前分支:(for /f "usebackq" %B in (``git branch --merged^|findstr /v /c:"* " /c:"master"``) do @git branch -d %B叹息,用单引号替换双反引号,我不确定如何格式化包含反引号的文字)
yoyo

42

我已经使用亚当的答案多年了。就是说,在某些情况下,它的行为不符合我的预期:

  1. 包含单词“ master”的分支被忽略,例如“ notmaster”或“ masterful”,而不仅仅是master分支
  2. 包含单词“ dev”的分支将被忽略,例如“ dev-test”,而不仅仅是dev分支
  3. 删除当前分支的HEAD可以访问的分支(即不一定是主节点)
  4. 在分离的HEAD状态下,从当前提交中删除每个可到达的分支

1和2很容易解决,只是对正则表达式进行了更改。3取决于您想要的上下文(即,仅删除尚未合并到master或当前分支中的分支)。git reflog如果您无意中以分离的HEAD状态运行此命令,则4可能会造成灾难性的后果(尽管可以使用恢复)。

最后,我希望所有这些都在一个单一的代码中,不需要单独的(Bash | Ruby | Python)脚本。

TL; DR

创建一个git别名“ sweep”,它接受一个可选-f标志:

git config --global alias.sweep '!git branch --merged $([[ $1 != "-f" ]] \
&& git rev-parse master) | egrep -v "(^\*|^\s*(master|develop)$)" \
| xargs git branch -d'

并使用以下命令调用它:

git sweep

要么:

git sweep -f

详细而详尽的答案

对于我来说,最简单的方法是创建带有某些分支的示例git repo并提交以测试正确的行为:

一次提交即可创建一个新的git repo

mkdir sweep-test && cd sweep-test && git init
echo "hello" > hello
git add . && git commit -am "initial commit"

创建一些新分支

git branch foo && git branch bar && git branch develop && git branch notmaster && git branch masterful
git branch --list
  bar
  develop
  foo
* master
  masterful
  notmaster

期望的行为:选择所有合并的分支,除了:母版,开发版或当前版

原始正则表达式会错过分支“ masterful”和“ notmaster”:

git checkout foo
git branch --merged | egrep -v "(^\*|master|dev)"
  bar

使用更新的正则表达式(现在不包括“开发”而不是“开发”):

git branch --merged | egrep -v "(^\*|^\s*(master|develop)$)"
bar
masterful
notmaster

切换到foo分支,进行新的提交,然后基于foo签出新的分支foobar:

echo "foo" > foo
git add . && git commit -am "foo"
git checkout -b foobar
echo "foobar" > foobar
git add . && git commit -am "foobar"

我当前的分支是foobar,如果我重新运行以上命令以列出要删除的分支,则即使没有将其合并到master中,也将包括分支“ foo”:

git branch --merged | egrep -v "(^\*|^\s*(master|develop)$)"
  bar
  foo
  masterful
  notmaster

但是,如果我在master上运行相同的命令,则不包括分支“ foo”:

git checkout master && git branch --merged | egrep -v "(^\*|^\s*(master|develop)$)"
  bar
  masterful
  notmaster

这仅仅是因为git branch --merged如果没有另外指定,则默认为当前分支的HEAD。至少对于我的工作流,除非本地分支已合并到master分支,否则我不希望删除它们,因此我更喜欢以下变体:

git checkout foobar
git branch --merged $(git rev-parse master) | egrep -v "(^\*|^\s*(master|develop)$)"
  bar
  masterful
  notmaster

分离的HEAD状态

git branch --merged在分离的HEAD状态下,依赖于的默认行为会产生更大的后果:

git checkout foobar
git checkout HEAD~0
git branch --merged | egrep -v "(^\*|^\s*(master|develop)$)"
  bar
  foo
  foobar
  masterful
  notmaster

这将删除我刚才所在的分支“ foobar”和“ foo”,这几乎肯定不是期望的结果。但是,使用我们修改后的命令:

git branch --merged $(git rev-parse master) | egrep -v "(^\*|^\s*(master|develop)$)"
  bar
  masterful
  notmaster

一行,包括实际删除

git branch --merged $(git rev-parse master) | egrep -v "(^\*|^\s*(master|develop)$)" | xargs git branch -d

全部打包成一个git别名“ sweep”:

git config --global alias.sweep '!git branch --merged $([[ $1 != "-f" ]] \
&& git rev-parse master) | egrep -v "(^\*|^\s*(master|develop)$)" \
| xargs git branch -d'

别名接受一个可选-f标志。默认行为是仅删除已合并到master的-f分支,但是该标志将删除已合并到当前分支的分支。

git sweep
Deleted branch bar (was 9a56952).
Deleted branch masterful (was 9a56952).
Deleted branch notmaster (was 9a56952).
git sweep -f
Deleted branch foo (was 2cea1ab).

为什么需要创建一个函数?不是git config原子的吗?
VasiliNovikov

处理可选的“ -f”参数(如果我正确理解了您的问题)
促成

1
但这有什么帮助?我的意思是表达式的开头!f(){ git branch ...。这是一个函数声明,对吗?为什么不直接开始git branch ...呢?
VasiliNovikov

1
你是绝对正确的。相应地编辑了我的答案。感谢您的指导!
涡流

以下内容与非强制模式不同吗? git checkout master && git branch -d `git branch --merged` && git checkout - 除了会删除develop,但可能是一种更简单的方法。
Guido Bouman


18

使用Git 2.5.0版本:

git branch -d `git branch --merged`

16
可以删除master分支顺便说一句!
Wazery 2015年

4
真正。我只有在确定要开机时才使用它master
drautb

11
git branch -d $(git branch --merged | grep -v master)
alexg

1
如果有流程,这是危险的,想象您拥有主<-阶段<-dev。仍然是最简单的解决方案imo
Joseph Briggs

14

您可以将提交添加到--merged选项。这样,您可以确保仅删除合并到原点/母版中的分支

以下命令将从您的来源中删除合并的分支。

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

您可以测试将删除哪些分支,将git push origin --delete替换为echo

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

2
我喜欢测试选项
iwein

12

我使用以下Ruby脚本删除我已经合并的本地和远程分支。如果我要对具有多个远程服务器的存储库执行此操作,而只想从其中删除,则只需将select语句添加到远程服务器列表中,即可获取所需的远程服务器。

#!/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

介意我是否可以窃取这个git助手库的小知识?github.com/yupiq/git-branch-util
logan

1
去吧,如果我关心人们以某种​​方式重用代码的话,我不会把它放在这里
mmrobins

@mmrobins \/在该remote_branches行的拒绝语句的开头有一个额外的内容。那是错字还是有目的?
Jawwad

@mmrobins,哦,没关系,我b.split(/\//)现在看到了
Jawwad

如果您基本上想通过香草味浓汤而不是红宝石来做到这一点:stackoverflow.com/a/37999948/430128
拉曼

11

如何在PowerShell控制台中删除合并的分支

git branch --merged | %{git branch -d $_.Trim()}

如果要排除名称或其他任何分支名称,则可以使用PowerShell这样的PowerShell Select-String进行管道传输并将结果传递给git branch -d

git branch -d $(git branch --merged | Select-String -NotMatch "master" | %{$_.ToString().Trim()})

1
更高的答案表明过滤主节点或其他分支。对于那些希望在Powershell中执行此操作的人:git branch --merged | findstr / v“大师” | %{git branch -d $
_。trim

@tredzko好点。FTR更高的答案是stackoverflow.com/questions/6127328/…-您可以使用链接的内容重新发表评论,然后我将其删除
Ruben Bartelink,2016年

它还尝试删除* master:)
iesen

9

kuboon的答案缺少删除分支名称中包含单词master的分支。以下是对他的回答的改进:

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

当然,它不会删除“ master”分支本身:)


8

Git中没有命令可以自动为您执行此操作。但是您可以编写一个使用Git命令的脚本,以提供所需的内容。根据您使用的分支模型,可以通过多种方式完成此操作。

如果您需要知道分支是否已合并到master中,则如果myTopicBranch已合并(例如,您可以将其删除),则以下命令将不会产生任何输出

$ git rev-list master | grep $(git rev-parse myTopicBranch)

您可以使用Git branch命令并解析Bash中的所有分支,并for在所有分支上循环。在此循环中,使用上述命令检查是否可以删除分支。



7

注意:我对以前的答案不满意(不能在所有系统上使用,不能在远程上使用,没有指定--merged分支,没有完全过滤)。因此,我添加了自己的答案。

主要有两种情况:

本地

你想删除本地分支已经合并到另一个地方分支。在删除期间,您要保留一些重要的分支,例如master,develop等。

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

注意事项

  • git branch output --format “ ..”是去除空格并允许精确的grep匹配
  • grep -E使用代替 egrep,因此它也可以在没有egrep的系统中使用(例如:git for Windows)。
  • grep -E -v '^master$|^feature/develop$' 是指定我不想删除的本地分支
  • xargs -n 1 git branch -d:执行本地分支的删除(不适用于远程分支)
  • 当然,如果您尝试删除当前已签出的分支则会收到错误消息。因此,我建议事先切换为大师。

远程

你想删除远程分支机构那些已经合并到另一个远程分支。在删除期间,您想保留一些重要的分支,例如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

注意事项

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

7

如果您使用的是Windows,则可以将Windows Powershell或Powershell 7与Out-GridView一起使用,以获取漂亮的分支列表,并使用鼠标选择要删除的分支:

git branch --format "%(refname:short)" --merged  | Out-GridView -PassThru | % { git branch -d $_ }

在此处输入图片说明 单击确定后,Powershell会将此分支名称传递给git branch -d命令并删除它们 在此处输入图片说明


6

您可以使用git-del-br 工具

git-del-br -a

您可以pip使用安装

pip install git-del-br

PS:我是该工具的作者。欢迎任何建议/反馈。


1
@ stackoverflow.com/users/100297/martijn-pieters:为什么删除和拒绝这个答案?
tusharmakkar16年

1
您的答案和工具无效。我花了几个小时。没有。
SpoiledTechie.com

@ SpoiledTechie.com:你能告诉我你到底面对什么问题吗?我定期使用它。
tusharmakkar17年

如果您想离线使用此功能,可以共享一个屏幕截图吗?那个谷歌邮件的东西宠坏了。:)
SpoiledTechie.com

5

如果您想删除已经合并到您当前所在的分支中的所有本地分支,那么基于较早的答案,我想出了一个安全的命令来执行此操作:

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

此命令不会影响您当前的分支或主分支。它还使用xargs的-t标志告诉您它在做什么之前。



5

我使用git-flow esque命名方案,因此这对我来说非常安全:

git branch --merged | grep -e "^\s\+\(fix\|feature\)/" | xargs git branch -d

它基本上会查找以string fix/feature/。开头的合并提交。


4

尝试以下命令:

git branch -d $(git branch --merged | grep -vw $(git rev-parse --abbrev-ref HEAD))

通过使用git rev-parse将获得当前分支名称以将其排除。如果收到错误,则意味着没有要删除的本地分支。

要对远程分支机构执行相同操作(更改origin您的远程名称),请尝试:

git push origin -vd $(git branch -r --merged | grep -vw $(git rev-parse --abbrev-ref HEAD) | cut -d/ -f2)

如果您有多个遥控器,请添加 grep origin |之前cut以仅过滤origin

如果以上命令失败,请尝试首先删除合并的远程跟踪分支:

git branch -rd $(git branch -r --merged | grep -vw $(git rev-parse --abbrev-ref HEAD))

然后 git fetch再次使用遥控器,并再次使用上一个git push -vd命令。

如果您经常使用它,请考虑将其作为别名添加到~/.gitconfig文件中。

如果您错误地删除了一些分支,请使用git reflog查找丢失的提交。


4

基于这些答案,我也制作了自己的Bash脚本

它使用git branch --mergedgit branch -d删除已合并的分支,并在删除之前提示您输入每个分支。

merged_branches(){
  local current_branch=$(git rev-parse --abbrev-ref HEAD)
  for branch in $(git branch --merged | cut -c3-)
    do
      echo "Branch $branch is already merged into $current_branch."
      echo "Would you like to delete it? [Y]es/[N]o "
      read REPLY
      if [[ $REPLY =~ ^[Yy] ]]; then
        git branch -d $branch
      fi
  done
}

4

下面的查询对我有用

for branch in  `git branch -r --merged | grep -v '\*\|master\|develop'|awk 'NR > 0 {print$1}'|awk '{gsub(/origin\//, "")}1'`;do git push origin --delete $branch; done

这将过滤grep管道中的任何给定分支。

在http克隆上运行良好,但对于ssh连接则效果不佳。


4

截至2018.07

将此添加到[alias]您的部分~/.gitconfig

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

现在,您可以致电git sweep执行所需的清理。


对我而言,调用git scan仅列出应清除的分支,但不会删除它们
Victor Moraes

4

在安装了git bash的 Windows上,egrep -v将不起作用

git branch --merged | grep -E -v "(master|test|dev)" | xargs git branch -d

这里grep -E -v是等效egrep -v

使用-d已删除合并分支机构或 -D删除未合并分支


egrep -v为我工作。我正在使用gitextensions安装程序中的gitbash
Joe Phillips

4

我一直在使用以下方法在一个cmd中删除合并的本地和远程分支

我的bashrc文件中包含以下内容:

function rmb {
  current_branch=$(git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/')
  if [ "$current_branch" != "master" ]; then
    echo "WARNING: You are on branch $current_branch, NOT master."
  fi
  echo "Fetching merged branches..."
  git remote prune origin
  remote_branches=$(git branch -r --merged | grep -v '/master$' | grep -v "/$current_branch$")
  local_branches=$(git branch --merged | grep -v 'master$' | grep -v "$current_branch$")
  if [ -z "$remote_branches" ] && [ -z "$local_branches" ]; then
    echo "No existing branches have been merged into $current_branch."
  else
    echo "This will remove the following branches:"
    if [ -n "$remote_branches" ]; then
      echo "$remote_branches"
    fi
    if [ -n "$local_branches" ]; then
      echo "$local_branches"
    fi
    read -p "Continue? (y/n): " -n 1 choice
    echo
    if [ "$choice" == "y" ] || [ "$choice" == "Y" ]; then
      # Remove remote branches
      git push origin `git branch -r --merged | grep -v '/master$' | grep -v "/$current_branch$" | sed 's/origin\//:/g' | tr -d '\n'`
      # Remove local branches
      git branch -d `git branch --merged | grep -v 'master$' | grep -v "$current_branch$" | sed 's/origin\///g' | tr -d '\n'`
    else
      echo "No branches removed."
    fi
  fi
}

原始资料

这不会删除master分支,但是会删除合并的本地AND远程分支。将其保存在rc文件中后,只需运行rmb,就会显示一个合并分支的列表,这些分支将被清除并要求对操作进行确认。您也可以修改代码以不要求进行确认,但是最好保留它。


3

编写一个脚本,Git在其中检查出已合并到master的所有分支。

然后做git checkout master

最后,删除合并的分支。

for k in $(git branch -ra --merged | egrep -v "(^\*|master)"); do
  branchnew=$(echo $k | sed -e "s/origin\///" | sed -e "s/remotes\///")
  echo branch-name: $branchnew
  git checkout $branchnew
done

git checkout master

for k in $(git branch -ra --merged | egrep -v "(^\*|master)"); do
  branchnew=$(echo $k | sed -e "s/origin\///" | sed -e "s/remotes\///")
  echo branch-name: $branchnew
  git push origin --delete $branchnew
done

3

公认的解决方案非常好,但是有一个问题,即它还删除了尚未合并到远程中的本地分支。

如果您查看输出,将会看到类似

$ 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)

分支blaissue_248是本地分支,将被静默删除。

但是您还可以看到单词[gone],它表示分支已被推送到远程(现已消失),因此表示可以删除分支。

因此可以将原始答案更改为(分割成多行以缩短行长)

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

保护尚未合并的分支。另外,也不需要为保护主机而对主机进行grepping操作,因为它起源远方,并且不会消失。


3

对我来说git branch --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

说明:

  • git branch --format "%(refname:short)" 给出本地分支机构的列表
  • git branch -r | grep -v HEAD | cut -d/ -f2- 给出远程分支的列表,过滤掉 HEAD
  • diff <(...) <(...) 给出括号内两个命令输出的差异
  • grep '<' 筛选存在于第一个列表中但不存在于第二个列表中的分支
  • cut -c 3- 给出从第三个字符开始的行,从而删除前缀 <
  • xargs git branch -Dgit 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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.