您可以使用Git在一个命令中删除多个分支吗?


355

我想清理我的本地库,其中有一吨老枝:例如3.23.2.13.2.2等。

我希望以一种偷偷摸摸的方式立即删除其中的许多内容。由于他们大多遵循点发布约定,所以我认为也许有一个捷径可以说:

git branch -D 3.2.*

并杀死所有3.2.x分支。

我尝试了该命令,但它当然不起作用。


11
git branch -D $(git branch | grep 3.2*)-这对我有用。删除名称以“ 3.2”开头的分支。grep-输出中的模式匹配(git branch在这种情况下为)。$()-表示执行并放置结果。|-链接。
爱德华

4
值得注意的是那些不知道的事,那-D就是强制删除,-d在大多数情况下应该首先使用起来更安全。
redfox05 '19

Answers:


363

不能使用该语法。但是您可以这样做:

git branch -D 3.2 3.2.1 3.2.2

基本上,git branch将通过一次调用为您删除多个分支。不幸的是,它没有完成分支名称。尽管可以使用bash进行以下操作:

git branch -D `git branch | grep -E '^3\.2\..*'`

2
完成对git branch -D/-d我来说很好。可能想更新您的文件(可能来自最新的git.git contrib目录)。
卡斯卡贝尔

19
相反,git branch | ...您可以使用$(git for-each-ref --format='%(refname:short)' refs/heads/3.*)。我知道,它更长,但可以保证是合适的输出,同时git branch具有诸如*->(对于symrefs)之类的漂亮输出,可能会使您陷入脚本/单行代码中。
卡斯卡贝尔

3
也许我是唯一一个遇到此问题的人,但我已经grep别名总是包含该标志--color=always- git branch -D一直抛出error: branch 'my_branch' not found.直到我没有颜色标志运行为止。
eebbesen 2015年

@eebbesen是否已全局禁用它?我在运行时遇到了同样的问题git branch --merged ${1-$(current_branch)} | grep -v ${1-$(current_branch)} | xargs git branch -d
qmmr

2
使用括号扩展,您可以编写git branch -D 3.2{,.1,.2}删除所有三个分支的命令gnu.org/software/bash/manual/html_node/Brace-Expansion.html
robstarbuck

147

好吧,在最坏的情况下,您可以使用:

git branch | grep '3\.2' | xargs git branch -d

22
对于对分支名称使用标准化前缀表示法的任何人(例如“ fix / ...”或“ feature / ...”),这几乎是一种完美的方法。
哈兹(Haz)2015年

4
简单高效!我建议尽管首先运行而不| xargs git branch -d需要检查实际要删除的内容。
mathielo '18

建议不要使用grep的输出git branch,因为它的意思是读取而不是解析。可以随时更改。结合使用其他答案中建议for-each-ref--format参数和params,然后结合此答案中的建议。
redfox05 '19

138
git branch  | cut -c3- | egrep "^3.2" | xargs git branch -D
  ^                ^                ^         ^ 
  |                |                |         |--- create arguments
  |                |                |              from standard input
  |                |                |
  |                |                |---your regexp 
  |                |
  |                |--- skip asterisk 
  |--- list all 
       local
       branches

编辑:

一个更安全的版本(由JakubNarębski和Jefromi建议),因为git branch输出并不打算在脚本中使用:

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

...或无xargs的:

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

14
不要将git branch输出用于脚本。使用git for-each-ref
JakubNarębski2010年

1
删除带有@符号的标签:git for-each-ref --format="%(refname:short)" refs/tags/\*@\* | xargs git tag -d
thaddeusmt 2012年

有错别字。应该是“ /3.2/*”而不是“ /3.2*”。另外,似乎您已将其他答案粘贴到自己的答案中。
Max MacLeod 2014年

这里没有错字。从手册页:If one or more patterns are given, only refs are shown that match against at least one pattern, either using fnmatch(3) or literally, in the latter case matching completely or from the beginning up to a slash
gawi 2014年

1
值得注意的是那些不知道的事,那-D就是强制删除,-d在大多数情况下应该首先使用起来更安全。
redfox05 '19

115

您可以使用git branch --list列出合格分支,并使用git branch -D / -d删除合格分支。

一个班轮示例:

git branch -d `git branch --list '3.2.*'`

尝试此操作时,我收到一堆错误消息,如error: branch 'package.json' not found.。*似乎扩展得太早了,它试图删除与每个文件和目录的名称相对应的分支。

这很好用!我在使用别名作为别名时遇到问题gitconfig...
whoaniac

6
这个答案需要在列表中更高,超级干净,有效,没有问题
jemiloii

1
尼斯,这一个很容易测试首先只有在发出git branch --list '3.2.*'
威尔

3
在窗户上git branch -d (git branch --list '3.2.*').trim()
Mattias Josefsson

38

最近,我一直在寻找相同问题的解决方案,最后我找到了一个答案,并且效果很好:

  1. 打开终端或等效终端。
  2. 键入git branch | grep“ pattern”用于将要删除的分支的预览。
  3. 键入git branch | grep“模式” | xargs git分支-D

这个解决方案很棒,如果您想全面解释每个命令及其运行方式,请在此处给出。


28

采用

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

7
一个小技巧是,如果删除命令“ | xargs git branch -D”的后半部分,则它将仅输出匹配的分支。因此,您可以预览将要删除的分支
Max MacLeod 2014年

1
我还添加了一个别名来简化此操作:alias grefs='git for-each-ref --format="%(refname:short)"'这样我就可以做到grefs | grep 'regexpattern' | xargs git branch -D
angularsen

爱它。漂亮又简单!
Bhargav Ponnapalli

15

也许您会发现这很有用:

如果要删除所有非“ master”,“ foo”和“ bar”等分支

git branch -D `git branch | grep -vE 'master|foo|bar'`

grep -v'something'是一个具有反转的匹配器。


我个人喜欢将-D选项与其他答案进行比较。感谢您在这里@Adi的回答。解决方案对我有用。
AMIC MING

9

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

git branch -D `git branch --list 'at-*'`

所有答案基本上都这样说,这恰好是最简单的。
tfantina

7

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


不过,这只能让您删除本地分支机构
Stealth Rabbi

7

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.

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


6

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

    git branch | grep -v "develop" | xargs git branch -D 

5

根据@gawi提供的答案,我做了一个小功能,可能有用(上面)。

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

将其添加到您.bash_profile的终端,然后重新启动终端。然后,您可以像这样从命令行调用:

removeBranchesWithPrefix somePrefix

注意

我目前已将其设置为软删除,这意味着除非分支已经合并,否则它不会删除分支。如果您希望生活在边缘,请更改-d-D,它将删除所有带前缀的内容!


5

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

git branch -d $(git branch)

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

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


这对我来说足够好了。它留下了两个分支,除了我是那个分支之外,然后使用相同的命令但使用大写字母“ -D”而不是“ -d”将其删除。我遇到一些有关git找不到文件但分支被删除的错误。
Lurifaxel

3

您可能会喜欢这个小项目...它会拉列表并要求您确认每个项目,然后最终删除所有选择...

git branch -d `git for-each-ref --format="%(refname:short)" refs/heads/\* | while read -r line; do read -p "remove branch: $line (y/N)?" answer </dev/tty; case "$answer" in y|Y) echo "$line";; esac; done`

使用-D强制删除(像往常一样)。

为了便于阅读,这里是逐行分解的内容...

git branch -d `git for-each-ref --format="%(refname:short)" refs/heads/\* |
    while read -r line; do 
        read -p "remove branch: $line (y/N)?" answer </dev/tty;
        case "$answer" in y|Y) echo "$line";; 
        esac; 
    done`

这是xargs方法...

git for-each-ref --format="%(refname:short)" refs/heads/\* |
while read -r line; do 
    read -p "remove branch: $line (y/N)?" answer </dev/tty;
    case "$answer" in 
        y|Y) echo "$line";; 
    esac; 
done | xargs git branch -D

最后,我喜欢在我的.bashrc中包含它

alias gitselect='git for-each-ref --format="%(refname:short)" refs/heads/\* | while read -r line; do read -p "select branch: $line (y/N)?" answer </dev/tty; case "$answer" in y|Y) echo "$line";; esac; done'

这样我就可以说

gitSelect | xargs git branch -D.

3

对于在此处使用PowerShell的纯净灵魂 git branch -d $(git branch --list '3.2.*' | %{$_.Trim() })


2

它对我来说正常工作:

git branch | xargs git branch -d

git branch | xargs git branch -D

删除所有本地分支


2

使用以下命令删除所有分支(签出的分支不会被删除)。

git branch | cut -d '*' -f 1 | tr -d " \t\r" | xargs git branch -d

编辑:我正在使用Mac OS


0

如果您在Windows上,则可以使用powershell进行此操作:

 git branch | grep 'feature/*' |% { git branch -D $_.trim() }

feature/*您喜欢的任何模式替换。


6
grep对我来说是无法识别的cmdlet ...因此我已为此git分支进行了更改| 其中{$ _。Trim()。StartsWith(“ bug”)} | %{git branch -D $ _。Trim()}起作用了!
亚历克斯(Alex)


0

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


0

我今天刚刚清理了一大堆陈旧的本地/远程分支机构。

以下是我的操作方法:

1.将所有分支名称列出到一个文本文件中:

git branch -a >> BranchNames.txt

2.将要删除的分支附加到命令“ git branch -D -r”:

git branch -D -r origin / dirA / branch01 origin / dirB / branch02 origin / dirC / branch03(...附加任何分支名称)

3.执行cmd

而且它比“ git push origin --delete ” 更快,更可靠。

这可能不是其他答案中列出的最聪明的方法,但是这种方法很简单,并且易于使用。


0

如果您已经安装了Git GUI(这是Windows的默认加载项),那么它是最简单的。您可以使用ctrl选择多个分支,并一键删除它们。


0

如果使用的是Fish shell,则可以利用以下string功能

git branch -d (git branch -l "<your pattern>" | string trim)

这与其他一些答案中的Powershell选项没有太大区别。


0

如果您要在文本文件(branches-to-del.txt)中删除所有分支(每行一个分支),则可以这样做以从远程(来源)中删除所有这些分支: xargs -a branches-to-del.txt git push --delete origin


-1

就像在Git中,通过引用git repo一样,所有分支都不是什么,为什么不删除要跳转的分支.git/ref,然后如果遗漏了任何在存储库中不感兴趣的东西,则会自动进行垃圾收集,因此您不会需要打扰。



-4

您可以删除所有分支,删除所有不必要的引用:

rm .git/refs/heads/3.2.*


2
被拒绝的原因有两个:1.它使用实现细节(当前版本的Git将分支作为文件存储在特定目录中的事实)。这可能会在将来的版本中更改,从而使答案无效。2.如果存储库位于单独的目录中,则无法使用。
axiac

另外,如果您在打包的存储库(git gc)上运行,则会产生非常意外的结果。不要那样做
马修·莫伊
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.