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

Nya*_*baa 1782 git version-control branch github feature-branch

我有很多Git分支.如何删除已合并的分支?是否有一种简单的方法可以删除它们而不是逐个删除它们?

Ada*_*ruk 2878

更新:

如果您的工作流将那些分支作为可能的祖先,您可以添加其他分支以排除master和dev.通常我分支出一个"sprint-start"标签和master,dev和qa不是祖先.

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

git branch --merged
Run Code Online (Sandbox Code Playgroud)

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

git branch --merged| egrep -v "(^\*|master|dev)"
Run Code Online (Sandbox Code Playgroud)

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

git branch --merged| egrep -v "(^\*|master|dev|skip_branch_name)"
Run Code Online (Sandbox Code Playgroud)

要删除已合并到当前已检出分支的所有本地分支:

git branch --merged | egrep -v "(^\*|master|dev)" | xargs git branch -d
Run Code Online (Sandbox Code Playgroud)

您可以看到master和dev被排除在它们是祖先的情况下.


您可以删除合并的本地分支:

git branch -d branchname
Run Code Online (Sandbox Code Playgroud)

如果没有合并,请使用:

git branch -D branchname
Run Code Online (Sandbox Code Playgroud)

要在旧版本的Git中从远程删除它,请使用:

git push origin :branchname
Run Code Online (Sandbox Code Playgroud)

在更新版本的Git中使用:

git push --delete origin branchname
Run Code Online (Sandbox Code Playgroud)

从远程删除分支后,您可以修剪以删除远程跟踪分支:

git remote prune origin
Run Code Online (Sandbox Code Playgroud)

或者修剪个别远程跟踪分支,正如另一个答案所暗示的那样:

git branch -dr branchname
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助.

  • 相反的警告:reflog将保存您的培根.所以不要担心. (140认同)
  • PowerShell变种,以便我可以在下次搜索答案时找到它:`git branch --merged | %{$ _.trim()} | ?{$ _ -notmatch'development'-and $ _ -notmatch'master'} | %{git branch -d $ _}` (72认同)
  • 警告:如果您刚刚创建了一个分支,它也将删除该分支.在运行最顶层命令之前,请确保列表中没有新创建的分支. (41认同)
  • 请记住,第一个命令只删除本地分支,因此它不像某些人指出的那样"危险". (32认同)
  • 如果没有应删除的分支,则会产生错误`fatal:branch name required`.为了避免这种情况,您可以将`-r`传递给`xargs`,这样如果stdin为空,它就不会运行`git branch -d`.(这是一个GNU xargs扩展,根据手册页). (19认同)
  • 是的,我知道怎么删除一个分支.但是我有100个分支机构,其中50个已经合并到主机,另外50个尚未合并.所以我想删除合并到主服务器的分支.所以我在这里问,如何删除它们比删除它们更快. (2认同)
  • git branch --merged | sed's/\\*//'| xargs -n 1 git branch -d - 摆脱那个讨厌的asteryx (2认同)
  • reflog 救不了你的命。删除分支会删除其引用日志。您可以取回最新的分支提示,但您不能再说“master@{1}”或“master@{昨天中午}” (2认同)
  • 如果默认使用颜色,请添加“--no-color”。示例:```git分支--merged开发--no-color | 猫 | grep -v "\* 开发" | xargs -n 1 git 分支 -d``` (2认同)
  • @Akarienta - `alias git-branch-clean="git branch --merged | egrep -v \"(^\*|master|dev|staging|production)\" | xargs git branch -d"` (2认同)
  • 我大约每周一次来这里 (2认同)
  • egrep 模式排除包含 master 的所有分支,而不仅仅是 master 本身,通过使用 `egrep -v "^(\* .*| *master| *dev)$"` 进行修复 (2认同)

kub*_*oon 424

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

git branch -r --merged | grep -v master | sed 's/origin\//:/' | xargs -n 1 git push origin
Run Code Online (Sandbox Code Playgroud)

在更新版本的Git中

git branch -r --merged | grep -v master | sed 's/origin\///' | xargs -n 1 git push --delete origin
Run Code Online (Sandbox Code Playgroud)

  • 我不得不添加`| grep origin`在`grep -v master`之后,以防止将其他遥控器的分支推送到原点.强烈推荐使用`git branch -r --merged |预先测试输出 grep -v master | grep起源| sed's/origin\//:/'| xargs -n 1 echo` (41认同)
  • 注意 - 刚刚意识到:这显然会发现分支合并到*current branch*,而不是master,所以如果你在`myFeatureBranch`它将擦除`origin/myFeatureBranch`.可能最好首先给'gout checkout master`. (19认同)
  • 到目前为止最佳答案.只需注意,我的主分支名为`dev`,所以我不得不改变它 (18认同)
  • 我略微修改了以排除`develop`分支.`git branch -r --merged | grep -v master | grep -v开发| sed's/origin\///'| xargs -n 1 git push --delete origin`.现在这变成了我的别名. (9认同)
  • 是什么让我读到的最好的答案是`-r`论证,我在其他任何地方都没有提到过.这是理所当然的,只有当地的分支机构值得做一些家务.但遥控器也充满了垃圾. (8认同)
  • 警告:这也会关闭打开的拉取请求。 (3认同)
  • 您可以通过使用 `--format` 仅包含引用 `gitbranch --format "%(refname:lstrip=3)" --remotes --merged` 所需的部分来消除 `sed` 步骤。字段名称记录在[此处](https://git-scm.com/docs/git-for-each-ref#_field_names)。它们与其他 git sub 命令的格式*不*相同。 (2认同)

rea*_*ate 178

只是简单地扩展了Adam的答案:

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

[alias]
    cleanup = "!git branch --merged | grep  -v '\\*\\|master\\|develop' | xargs -n 1 git branch -d"
Run Code Online (Sandbox Code Playgroud)

然后你可以删除所有本地合并的分支做一个简单的git cleanup.

  • 不应该是第一个命令:`git branch --merged master`,因为你想查看已经合并到master中的内容,而不是当前检出的分支? (11认同)
  • 将`-r`添加到`xargs`可以防止多次运行此别名或者没有剩余分支要删除时出现不必要的错误(需要`分支名称`).我的别名如下:`cleanup ="!git branch --merged | grep -v -P'^ \\*| master | develop'| xargs -n1 -r git branch -d"` (11认同)
  • 当前命令不会过滤掉 master 和 develop 分支 (2认同)

Ism*_*reu 81

这也可以删除除master之外的所有合并分支.

git branch --merged | grep -v '^* master$' | grep -v '^  master$' | xargs git branch -d
Run Code Online (Sandbox Code Playgroud)

  • 这很好,谢谢!使用此功能的任何人都需要注意:请注意`grep -v'^ master $'`中有两个空格.如果你自己输入并错过了一个,如果你没有,你将删除`master`. (5认同)
  • 现在它不会删除任何带有`master`的分支.尝试`grep -v ^ master $`为中间. (3认同)
  • @ Mr.Polywhirl你的编辑打破命令,你应该还原它.这两个空格是必要的,因为`git branch`将在新行上列出每个分支名称,如果它不是当前签出的分支,则左侧有两个空格.您基本上保证运行此命令的任何人都将删除其主分支,除非它是当前签出的分支. (3认同)

Gui*_*man 75

您将要从这些命令中排除master&develop分支.

本地git清除:

git branch --merged | grep -v '\*\|master\|develop' | xargs -n 1 git branch -d
Run Code Online (Sandbox Code Playgroud)

远程git清除:

git branch -r --merged | grep -v '\*\|master\|develop' | sed 's/origin\///' | xargs -n 1 git push --delete origin
Run Code Online (Sandbox Code Playgroud)

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

git fetch -p
Run Code Online (Sandbox Code Playgroud)

  • ``git config --global --add fetch.prune true``在fetch或pull上自动修剪. (4认同)
  • 远程版本也是+1(但由于我们有远程版本,所以不太需要--prune).另外值得注意的是,thoose不适用于较旧的git版本 (3认同)
  • 请注意,修剪与远程清除不同。远程清除实际上是删除与您当前分支完全合并的远程分支。Prune 只清理您本地已删除远程分支的注册表。 (2认同)

Kla*_*urn 47

对于那些在Windows上并且更喜欢PowerShell脚本的人来说,这里是删除本地合并分支的人:

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

  • 出于好奇的缘故,这可以缩短为`git branch --merged | ?{ - not($ _ -like"*master")} | %{git branch -d $ _.trim()}` (12认同)
  • @IainBallard当然,我可以使用别名.当您想要最大化可读性时,不建议这样做.https://github.com/darkoperator/PSStyleGuide/blob/master/English.md (5认同)
  • 这是Windows cmd shell的单线程,它保留了master和你当前的分支:`for/f"usebackq"%B in(``git branch --merged ^ | findstr/v/c:"*"/ c:" master"``)做@git branch -d%B`(叹气,用单个替换双反引号,我不知道如何格式化包含反引号的文字) (4认同)
  • 当然。我发现您的回答非常有帮助 :-) 但是,有时长格式的 powershell 语法会妨碍块中发生的事情。但主要是,我提出了一些您可以一次性复制/粘贴或键入的内容。再次感谢。 (2认同)

edd*_*ies 39

多年来我一直使用亚当的答案.也就是说,在某些情况下,它没有像我预期的那样行事:

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

只需更改正则表达式,即可轻松解决1和2问题.3取决于您想要的上下文(即只删除尚未合并到master或当前分支的分支).4有可能是灾难性的(虽然可以恢复git reflog),如果你无意中以独立的HEAD状态运行它.

最后,我希望这一切都在一个单行内容中,不需要单独的(Bash | Ruby | Python)脚本.

TL; DR

创建一个接受可选-f标志的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'
Run Code Online (Sandbox Code Playgroud)

并使用以下命令调用它:

git sweep
Run Code Online (Sandbox Code Playgroud)

要么:

git sweep -f
Run Code Online (Sandbox Code Playgroud)

详尽的答案

我最简单的方法是使用一些分支和提交来创建一个示例git repo来测试正确的行为:

使用单个提交创建一个新的git仓库

mkdir sweep-test && cd sweep-test && git init
echo "hello" > hello
git add . && git commit -am "initial commit"
Run Code Online (Sandbox Code Playgroud)

创建一些新的分支

git branch foo && git branch bar && git branch develop && git branch notmaster && git branch masterful
git branch --list
Run Code Online (Sandbox Code Playgroud)
  bar
  develop
  foo
* master
  masterful
  notmaster
Run Code Online (Sandbox Code Playgroud)

期望的行为:选择所有合并的分支,除了:master,develop或current

最初的正则表达式错过了"masterful"和"notmaster"的分支:

git checkout foo
git branch --merged | egrep -v "(^\*|master|dev)"
Run Code Online (Sandbox Code Playgroud)
  bar
Run Code Online (Sandbox Code Playgroud)

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

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

切换到分支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"
Run Code Online (Sandbox Code Playgroud)

我当前的分支是foobar,如果我重新运行上面的命令列出我想删除的分支,即使它尚未合并到master中,也包含分支"foo":

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

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

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

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

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

独立的HEAD状态

依赖于默认行为git branch --merged在分离的HEAD状态中具有更显着的后果:

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

这将删除我刚才的分支,"foobar"和"foo",这几乎肯定不是理想的结果.但是,通过我们修订的命令:

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

一行,包括实际删除

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

所有包装成git别名"扫描":

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

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

git sweep
Run Code Online (Sandbox Code Playgroud)
Deleted branch bar (was 9a56952).
Deleted branch masterful (was 9a56952).
Deleted branch notmaster (was 9a56952).
Run Code Online (Sandbox Code Playgroud)
git sweep -f
Run Code Online (Sandbox Code Playgroud)
Deleted branch foo (was 2cea1ab).
Run Code Online (Sandbox Code Playgroud)


Tim*_*mmm 29

这里有很多不好的答案。这可能是您想要的:

git branch --delete $(git branch --merged master --no-contains master --format='%(refname:short)')
Run Code Online (Sandbox Code Playgroud)

这将选择已合并到master(包括master不是其后代master(排除master其自身)的所有本地分支。这--format是必要的,因为默认情况下 Git 会为当前签出的分支打印星号。您也许也可以这样做,git for-each-ref但它似乎更复杂(它也列出了远程分支)。

想要:

  • git branch --merged(不带master):这将列出已“合并”到您当前签出的提交(即HEAD)中的分支,这可能是意外的,而不是您想要的。
  • | grep -v master: 没有这个必要;你可以只使用--no-contains.
  • | xargs: 再说了,没必要。git branch --delete可以删除多个分支。

更新:我已经使用这个有一段时间了,效果很好。有两个小缺陷:

  1. 如果没有要删除的分支,则会出现错误。在我看来,这对于交互式使用来说很好。无论如何,您不应该在脚本中使用它,因为它是 Bash,并且 Bash不应该用于脚本编写

  2. 它不会删除指向与 相同提交的分支master。我有一个工具可以自动对所有分支进行变基,对于已合并的分支,它可以使它们保持这种状态。这对你来说可能并不重要。


小智 21

Git Sweep做得很好.

  • 现在,这个项目不再维护。见 https://github.com/arc90/git-sweep/pull/43 (2认同)

Vik*_*iev 19

我最喜欢的简单脚本:

git branch --merged | grep -E -v "(master|main|develop|other)" | xargs git branch -d
Run Code Online (Sandbox Code Playgroud)


Mar*_*ski 17

如果您使用的是 Windows,您可以使用带有Out-GridView 的Windows Powershell 或 Powershell 7来获得一个不错的分支列表,然后用鼠标选择要删除的分支:

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

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


dra*_*utb 16

使用Git版本2.5.0:

git branch -d `git branch --merged`
Run Code Online (Sandbox Code Playgroud)

  • 这可以删除`master`分支btw! (16认同)
  • `git branch -d $(git branch --merged | grep -v master)` (11认同)
  • 真正.当我确定我在'master`时,我才使用它. (4认同)
  • 如果您有流程,这很危险,想象一下您拥有 master <- stage <- dev。仍然是最简单的解决方案imo (2认同)

Jör*_*des 14

您可以将提交添加到--merged选项.这样你就可以确保只删除合并到的分支,即origin/master

以下命令将从您的原点删除合并的分支.

git branch -r --merged origin/master | grep -v "^.*master" | sed s:origin/:: |xargs -n 1 git push origin --delete 
Run Code Online (Sandbox Code Playgroud)

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

git branch -r --merged origin/master | grep -v "^.*master" | sed s:origin/:: |xargs -n 1 echo
Run Code Online (Sandbox Code Playgroud)

  • 我喜欢测试选项 (2认同)

mmr*_*ins 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
Run Code Online (Sandbox Code Playgroud)


Kon*_*kus 11

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

git branch --merged | %{git branch -d $_.Trim()}
Run Code Online (Sandbox Code Playgroud)

请参阅GitHub for Windows


Elm*_*mer 11

我用这个:

git branch --delete $(git branch --format '%(refname:short)' --merged | grep --invert-match 'main\|master\|branch-to-skip')
Run Code Online (Sandbox Code Playgroud)

它以指定的格式列出所有合并的分支,然后将该列表提供给 gitbranch --delete。


psu*_*zzi 10

注意:我对以前的答案不满意(不适用于所有系统,不适用于远程,未指定 --merged 分支,未完全过滤)。所以,我添加我自己的答案。

主要有两种情况:

当地的

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

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

注意事项

  • git branch output --format “..”是去除空格并允许精确的grep匹配
  • grep -E用于代替 egrep,因此它也适用于没有 egrep 的系统(即:git for windows)。
  • grep -E -v '^master$|^feature/develop$' 是指定我不想删除的本地分支
  • 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
Run Code Online (Sandbox Code Playgroud)

注意事项

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


Par*_*ras 9

kuboon的回答错过了删除分支名称中包含master字样的分支.以下改进了他的答案:

git branch -r --merged | grep -v "origin/master$" | sed 's/\s*origin\///' | xargs -n 1 git push --delete origin
Run Code Online (Sandbox Code Playgroud)

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


Dan*_*.K. 9

gbda如果您将OhMyZSHgit plugin一起使用,则可以使用别名。


ral*_*nja 8

Git中没有自动执行此操作的命令.但是你可以编写一个使用Git命令的脚本来为你提供所需的东西.这可以通过多种方式完成,具体取决于您使用的分支模型.

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

$ git rev-list master | grep $(git rev-parse myTopicBranch)
Run Code Online (Sandbox Code Playgroud)

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


sty*_*ger 7

git branch --merged | grep -Ev '^(. master|\*)' | xargs -n 1 git branch -d将删除除当前签出分支和/或之外的所有本地分支master.

对于那些希望了解这些命令的人来说,这是一篇有用的文章:Git Clean:删除已经合并的分支,Steven Harman.


ear*_*ils 6

基于其中一些答案,我也制作了自己的 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
}
Run Code Online (Sandbox Code Playgroud)


tus*_*r08 6

你可以使用git-del-br 工具.

git-del-br -a
Run Code Online (Sandbox Code Playgroud)

您可以通过pip使用安装它

pip install git-del-br
Run Code Online (Sandbox Code Playgroud)

PS:我是这个工具的作者.欢迎任何建议/反馈.


Dev*_*vWL 6

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

git branch --merged | grep -E -v "(master|test|dev)" | xargs git branch -d
Run Code Online (Sandbox Code Playgroud)

其中grep -E -v相当于egrep -v

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


小智 5

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

git branch --merged | grep -v \* | grep -v '^\s*master$' | xargs -t -n 1 git branch -d
Run Code Online (Sandbox Code Playgroud)

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


Cha*_*d M 5

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

git branch --merged | grep -e "^\s\+\(fix\|feature\)/" | xargs git branch -d
Run Code Online (Sandbox Code Playgroud)

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


Eli*_*iot 5

别名版本的亚当更新答案:

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

另外,请参阅此答案以获取有关转义复杂别名的方便提示.


ken*_*orb 5

尝试以下命令:

git branch -d $(git branch --merged | grep -vw $(git rev-parse --abbrev-ref HEAD))
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

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

git branch -rd $(git branch -r --merged | grep -vw $(git rev-parse --abbrev-ref HEAD))
Run Code Online (Sandbox Code Playgroud)

然后git fetch再次遥控并git push -vd再次使用之前的命令。

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

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


小智 5

以下查询对我有用

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
Run Code Online (Sandbox Code Playgroud)

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

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


Hei*_*upp 5

接受的解决方案非常好,但有一个问题,它还会删除尚未合并到远程的本地分支。

如果你看一下你的输出,你会看到类似的东西

$ 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)
Run Code Online (Sandbox Code Playgroud)

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

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

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

git branch --merged master -v | \
     grep  "\\[gone\\]" | \
     sed -e 's/^..//' -e 's/\S* .*//' | \
      xargs git branch -d
Run Code Online (Sandbox Code Playgroud)

保护尚未合并的分支。此外,不需要 master 的 grepping 来保护它,因为它在原点有一个遥控器并且不会显示为消失。