你能用Git在一个命令中删除多个分支吗?

Dou*_*oug 313 git

我想清理我的本地库,其中有一吨老枝:例如3.2,3.2.1,3.2.2等.

我希望以偷偷摸摸的方式立刻删除它们中的很多.由于他们大多遵循点发布惯例,我想也许有一条捷径可以说:

git branch -D 3.2.*
Run Code Online (Sandbox Code Playgroud)

并杀死所有3.2.x分支.

我尝试了这个命令,当然,它没有用.

sle*_*man 332

没有那种语法.但你可以这样做:

git branch -D 3.2 3.2.1 3.2.2
Run Code Online (Sandbox Code Playgroud)

基本上,git branch将通过一次调用为您删除多个分支.不幸的是,它没有完成分支名称.虽然,在bash中,你可以这样做:

git branch -D `git branch | grep -E '^3\.2\..*'`
Run Code Online (Sandbox Code Playgroud)

  • 而不是`git branch | ...`你可以使用`$(git for-each-ref --format ='%(refname:short)'refs/heads/3.*)`.它更长,我知道,但它保证是合适的输出,而`git branch`有很好的输出,例如`*`和` - >`(对于symrefs),这可能会让你陷入脚本/单行中. (18认同)
  • 也许我是唯一有这个问题的人,但是我有'grep`别名,总是包含标志`--color = always` - `git branch -D`正在抛出`错误:分支'my_branch'找不到. `直到我没有颜色标志跑. (3认同)
  • `git branch -D/-d`的完成对我来说很好.可能想要更新你的(可能来自最新的git.git contrib目录). (2认同)
  • 通过大括号扩展,您可以编写`git branch -D 3.2 {,。1,.2}​​`来删除所有三个分支https://www.gnu.org/software/bash/manual/html_node/Brace-Expansion.html (2认同)

gaw*_*awi 134

git branch  | cut -c3- | egrep "^3.2" | xargs git branch -D
  ^                ^                ^         ^ 
  |                |                |         |--- create arguments
  |                |                |              from standard input
  |                |                |
  |                |                |---your regexp 
  |                |
  |                |--- skip asterisk 
  |--- list all 
       local
       branches
Run Code Online (Sandbox Code Playgroud)

编辑:

一个更安全的版本(由JakubNarębski和Jefromi建议),因为git branch输出不适用于脚本:

git for-each-ref --format="%(refname:short)" refs/heads/3.2\* | xargs git branch -D
Run Code Online (Sandbox Code Playgroud)

......或者没有xargs:

git branch -D `git for-each-ref --format="%(refname:short)" refs/heads/3.2\*`
Run Code Online (Sandbox Code Playgroud)

  • 不要使用`git branch`输出来编写脚本.使用`git for-each-ref`. (14认同)
  • 对于那些不知道的人,值得注意的是,`-D` 是*强制* 删除,在大多数情况下应该使用 `-d` 以确保安全。 (2认同)

Car*_*rum 129

那么,在最坏的情况下,你可以使用:

git branch | grep '3\.2' | xargs git branch -d
Run Code Online (Sandbox Code Playgroud)

  • 对于对分支名称使用标准化前缀表示法的任何人来说,这是非常完美的方法(例如"fix/..."或"feature/..."). (19认同)
  • 简单高效!我建议尽管先运行而不使用`| xargs git branch -d`部分来检查实际要删除的内容。 (2认同)

50s*_*bae 95

您可以使用git branch --list列出符合条件的分支,并使用git branch -D/-d删除符合条件的分支.

一个班轮示例:

git branch -d `git branch --list '3.2.*'`
Run Code Online (Sandbox Code Playgroud)

  • 这个答案需要在列表中更高,超级干净,工作,没有grep (6认同)
  • 我发现一个有用的用例:如果您使用功能分支模型,则可以使用`gitbranch-d``gitbranch--mergedmaster| grep -v master``` 删除已经合并到master的分支 (3认同)
  • 很高兴这个很容易通过发出 `gitbranch --list '3.2.*'` 来首先测试 (3认同)
  • 在Windows上的git branch -d(git branch --list'3.2。*')。trim() (2认同)
  • @RannieAguilarPeralta -D delete 是一个强制删除分支,这不是操作系统变体。请参阅/sf/answers/140246081/ (2认同)

K J*_*Gor 38

最近,我正在寻找同样问题的解决方案,最后我找到了一个答案,它运作良好:

  1. 打开终端或等效终端.
  2. 输入git branch | grep"pattern"用于预览将被删除的分支.
  3. 输入git branch | grep"pattern"| xargs git branch -D

这个解决方案很棒,如果你想要完整解释每个命令及其工作方式,请在此处给出.


Ank*_*dal 31

要根据指定的模式删除多个分支,请执行以下操作:

打开终端或等效程序并输入以下命令:

git branch | grep "<pattern>" (preview of the branches based on pattern)

git branch | grep "<pattern>" | xargs git branch -D (replace the <pattern> with a regular expression to match your branch names)
Run Code Online (Sandbox Code Playgroud)

删除所有3.2.x分支,您需要键入

git branch | grep "3.2" | xargs git branch -D
Run Code Online (Sandbox Code Playgroud)

就这样!

你已准备好出发!


Jak*_*ski 26

使用

git for-each-ref --format='%(refname:short)' 'refs/heads/3.2.*' |
   xargs git branch -D
Run Code Online (Sandbox Code Playgroud)

  • 小提示是,如果删除命令"| xargs git branch -D"的后半部分,那么它将只输出匹配的分支.因此,您可以预览将被删除的分支 (7认同)

Fra*_*con 20

这是一个通用的解决方案:

git branch | grep "<pattern>" | xargs git branch -D
Run Code Online (Sandbox Code Playgroud)

我建议在执行上述命令之前运行以下命令行,以预览将被删除的分支。

git branch | grep "<pattern>"
Run Code Online (Sandbox Code Playgroud)

在这种情况下

git branch | grep "^3\.2\..*" | xargs git branch -D
Run Code Online (Sandbox Code Playgroud)


Dan*_*iel 13

保留“开发”并删除本地所有其他人

    git branch | grep -v "develop" | xargs git branch -D 
Run Code Online (Sandbox Code Playgroud)


Adr*_*ian 12

也许你会发现这很有用:

如果你想删除所有不是例如'master','foo'和'bar'的分支

git branch -D `git branch | grep -vE 'master|foo|bar'`
Run Code Online (Sandbox Code Playgroud)

grep -v'something'是一个带有反转的匹配器.


Ala*_*die 12

正是出于这个原因,我将我的首字母和破折号 (at-) 作为分支名称的前三个字符:

git branch -D `git branch --list 'at-*'`
Run Code Online (Sandbox Code Playgroud)


Imt*_*que 9

Powershell 解决方案:

如果您正在运行 Windows,则可以使用 PowerShell 一次删除多个分支...

git branch -D ((git branch | Select-String -Pattern '^\s*3\.2\..*') | foreach{$_.ToString().Trim()})
//this will remove all branches starting with 3.2.

git branch -D ((git branch | Select-String -Pattern 'feature-*') | foreach{$_.ToString().Trim()})
// this will delete all branches that contains the word "feature-" as a substring.
Run Code Online (Sandbox Code Playgroud)

您还可以使用 Powershell 的 Select-String 命令微调模式匹配的工作方式。查看powershell 文档


小智 8

您可以使用git gui一次删除多个分支。从命令提示符/Bash -> git gui-> 远程 -> 删除分支... -> 选择要删除的远程分支 -> 删除。

  • ...或者如果你想删除本地分支(如OP所要求的),请使用“git gui”中的“Branch”-&gt;“Delete”。 (3认同)

mcv*_*vkr 8

如果您想删除多个分支进行清理,这将起作用

 git branch -d branch1 branch2 branch3
Run Code Online (Sandbox Code Playgroud)

此外,如果您想将删除操作反映到远程,您可以使用它来推送它们

 git push origin --delete branch1 branch2 branch3
Run Code Online (Sandbox Code Playgroud)


Sau*_*Kar 8

长话短说

git branch -D $(git branch | grep '3\.2\..*')

解释

  1. git branch列出本地系统上的所有分支。
  2. grep '3\.2\..*'使用模式匹配查找当前工作目录中以3.2.. 用于\转义,.因为它是 grep 的特殊字符。
  3. git branch | grep '3\.2\..*'将所有 github 分支名称传递给 grep 命令,然后该命令将查找以提供的列表中的字符串开头的分支名称。
  4. $(git branch | grep '3\.2\..*')包含在其中的任何内容都$()将作为单独的 shell 命令运行,然后其结果可以传递给单独的命令。在我们的例子中,我们希望删除找到的文件列表。
  5. git branch -D $(git branch | grep '3\.2\..*')这只是执行上面第 4 点中解释的操作。


cod*_*ion 7

对于使用 PowerShell 的纯粹灵魂,这里有一个小脚本 git branch -d $(git branch --list '3.2.*' | %{$_.Trim() })


小智 6

如果您不仅限于使用git命令提示符,则可以始终运行git gui并使用Branch-> Delete菜单项.选择要删除的所有分支并将其翻录.


Log*_*gan 5

我根据@gawi(上面)提供的答案编写了一个可能有用的小函数.

removeBranchesWithPrefix() {
  git for-each-ref --format="%(refname:short)" refs/heads/$1\* | xargs git branch -d
}
Run Code Online (Sandbox Code Playgroud)

将其添加到您的.bash_profile并重新启动您的终端.然后你可以从命令行调用,如下所示:

removeBranchesWithPrefix somePrefix
Run Code Online (Sandbox Code Playgroud)

注意

我目前设置了软删除,这意味着它不会删除分支,除非它们已经合并.如果你想生活在边缘,-d改为-D,它将删除带有前缀的所有内容,无论如何!


Yul*_*lin 5

如果您确实需要清洁所有分支机构,请尝试

git branch -d $(git branch)

它将删除您当前正在签入的分支的所有本地合并分支。

这是使您的当地环境整洁的好方法


Von*_*onC 5

git branch -d branch1 branch2 branch3已经可以使用,但使用 Git 2.31(2021 年第一季度)会更快。
以前,当删除许多分支和标签时,代码通常一次只执行一个引用。
它还有另一个 API 可以用来删除多个引用,当引用被打包时,它会产生相当大的性能差异。

请参阅Phil Hord ( )的提交 8198907(2021 年 1 月 20 日)。(由Junio C Hamano 合并 -- --提交 f6ef8ba中,2021 年 2 月 5 日)phord
gitster

8198907795delete_refs:删除标签或分支时使用

确认人: Elijah Newren
签署人: Phil Hord

' git tag -d' ( man )接受一个或多个要删除的标记引用,但每次删除都是通过调用delete_ref每个argv.
从打包的引用中删除时,这非常慢。
使用delete_refs相反的方式,以便可以通过一次更新在单个事务内完成所有删除。

对' git branch -d' 男人做同样的事情。

由于delete_refs在单个事务中执行所有打包引用删除操作,因此如果任何删除失败,则所有删除操作都将被跳过。
实际上,它们都不应该失败,因为我们在调用之前验证了每个的哈希值delete_refs,但是在此更改之后,某些网络错误或奇怪的权限问题可能会产生不同的结果。

此外,由于文件支持的删除不是在同一事务中执行的,因此即使打包引用事务失败,这些删除也可能会成功。

删除分支后,仅当分支引用已被删除且随后未重新添加时,才删除分支配置。

使用 手动测试删除 24,000 个标签大约需要 30 分钟delete_ref
使用时大约需要5秒delete_refs