在git中删除多个远程分支

155

我有一个团队成员无意中将他的 150 个本地分支推送到我们的中央仓库。幸运的是,它们都有相同的前缀。使用该前缀,是否有一种 git 命令或酷炫的小型 shell 脚本可以一次性删除所有这些分支?

22个回答

187

使用以下命令从远程服务器上删除所有以PREFIX前缀开头的分支。

git branch -r | awk -F/ '/\/PREFIX/{print $2}' | xargs -I {} git push origin :{}
您可能希望先进行试运行,以查看是否是您想要删除的分支:
git branch -r | awk -F/ '/\/PREFIX/{print $2}'

2
我喜欢这个命令,因为它只有一行,而且我可以先试运行一下。不幸的是,它出现了以下错误信息:$ git branch -r | awk -F/ '/\/APR/{print $2}' | xargs -I {} git push origin :{} error: unable to push to unqualified destination: APR-04-DPH The destination refspec neither matches an existing ref on the remote nor begins with refs/, and we are unable to guess a prefix based on the source ref. error: failed to push some refs to 'GIT_URL' - Jake A. Smith
1
好的,这是因为APR-04-DPH分支已经被删除了。请查看以下已回答的问题:这个这个这个。这些问题的答案都解决了同样的问题,您可以自己测试这些解决方案。 - neevek
40
如果您的分支名称中有“/”(如果您正在使用git-flow或类似工具),则应打印{$2"/"$3}。 - ajma
我不知道为什么它对我不起作用。 我发现使用grep可以解决问题。git branch -r | grep -Eo 'PREFIX/.*' | xargs -I {} git push origin :{} branch -r显示了origin/prefix/branchname。所以它将采用prefix/branchname - Kirby
5
我在Windows中使用msysgit,以下命令对我有效(结合@ajma的评论,用于删除包含正斜杠的分支名称:git branch -r | awk -F/ '/\/PREFIX/{print $2"/"$3}' | xargs -I % git push origin --delete %)。 - rikoe
显示剩余7条评论

123
如果你想采用更简单的方法,比如删除3或4个分支:
git push origin --delete <branch1> <branch2> <branch3>

重要提示:本功能仅适用于Git v1.7.0及以上版本。


6
我使用了git branch -r | awk -F/ '/\/PATTERN/{print $2}' | xargs git push origin --delete - Aram Kocharyan
这是一个比上面(已接受的)答案更好的解决方案,因为它将所有删除操作批处理在单个请求中,这在需要删除许多分支的情况下非常重要。 - Jai
简单、快速和安全。你通过的内容会被删除。 - akshay_sushir

52

感谢 Neevek 提供出色和优雅的解决方案!

但是我在分支名称中遇到了一些斜杠的问题(我正在使用 Git Flow),因为使用 awk 字段分隔符 /-F 选项)。

我的解决方案基于 Neevek 的解决方案,但可以正确解析带有 / 的分支名称。 在这种情况下,我假设您的远程名为 origin。 用于删除以 PATTERN 开头的远程分支的命令:

git branch -r | awk -Forigin/ '/\/PATTERN/ {print $2}' | xargs -I {} git push origin :{}

别忘了检查你要删除的内容:

git branch -r | awk -Forigin/ '/\/PATTERN/ {print $2}'

小贴士: 如果你的分支名称(不包括origin/前缀)已存储在一个文本文件中(每行一个分支名称),只需运行以下命令:

cat your_file.txt | xargs -I {} git push origin :{}

2
使用 xargs -a file -L 代替 cat file | xargs。更简单的方式是 xargs -a file git push --delete origin - musiKk
当运行许多与正则表达式匹配的远程分支时,由于每次删除单个分支,这可能需要一些时间。为了加快速度,可以使用以下命令并行运行(-P参数选择要并行运行的数量): git branch -r | awk -Forigin/ '/\/PATTERN/ {print $2}' | xargs -n 1 -P 8 -I {} git push origin :{} - DorHugi

51

这可能是一个重复的答案,但以下方法经过测试并且对我完美地起作用。

  1. 强制删除本地分支

git branch -D branch-name
  • 删除远程分支

    git push origin --delete branch-name
    
  • 删除多个本地分支

  • git branch -D branch-name1 branch-name2
    
  • 删除多个远程分支

  • git push origin --delete branch-name1 branch-name2
    
  • 删除带有前缀的本地分支。例如,feature/*

  • git branch -D $(git branch --list 'feature/*')
    
    列出带有前缀的远程分支。
    git branch -r | grep -Eo 'feature/.*'
    
  • 删除具有前缀的远程分支

  • git branch -r | grep -Eo 'feature/.*' | xargs -I {} git push origin :{}
    
  • 撤销/还原远程仓库中的最新提交

  • git reset HEAD^
    git push origin +HEAD
    

    2
    我认为你在第5步中意思是要转义反引号。 - user3456074
    如何添加反引号? - Naren
    1
    @Naren:问题在于Markdown格式会将反引号转换为样式命令。我用了另一种命令替代方法(例如,"$(command)"等同于`command`,但不会被Markdown转换成奇怪的东西)。你还可以使用''来转义反引号。 - Stabledog
    在使用多个远程仓库进行 fork 后,如果要删除以 feature/ 为前缀的分支,可以使用以下命令:git branch -r | grep -Po '(?<=fork/)feature/.*' | xargs -I {} git push fork :{} - Nafiur Rahman Khadem
    第7步是否缺少--delete选项? - mynameistechno
    第七步缺少 --delete 吗? - undefined

    17
    与grep命令相同: git branch -r | grep -Eo 'PREFIX/.*' | xargs -i git push origin :{}branch -r 显示了 origin/prefix/branchname。因此它将获取 prefix/branchname

    我认为你的意思是 xargs -I {} git push origin :{},而不是 -i - jojo
    2
    @jojo,据我所知,对于-i,它使用默认替换{},但是对于-I,您可以声明自己的替换方式。...刚在手册中找到:-i ...-I{}相同。 - Kirby

    12

    Neevek的解决方案很优雅,但它可以更好:所提出的解决方案每个分支都调用一次'git push',这意味着要删除一个分支需要额外的网络往返。既然你已经使用了awk,为什么不用它来给':'添加前缀,然后xargs可以一次性调用'git push'并一次性删除所有分支:

    运行干扰以列出将被删除的分支:

    git branch -r | awk -F/ '/\/PREFIX/{print ":" $2}'
    

    实际推送删除的最终解决方案:

    git branch -r | awk -F/ '/\/PREFIX/{print ":" $2}' | xargs git push origin
    

    2
    当你使用较低版本的bash或者使用Windows版本的Git Bash时,如果无法使用“-I”选项来运行xargs命令,本方法可以完美解决该问题。 - zchholmes
    我在使用Neevek的解决方案时遇到了“xargs:replstr可能为空”的问题,可能是git版本的问题.. git version 1.9.5但这对我非常有用。感谢你们两个。 - iamface

    9

    resource https://coderwall.com/p/eis0ba

        1 - List all your remote branches:
    
        $ git branch -r
    
        2 - Filter the branches by some regular expression. In this case I'm interested in deleting any branch with the 'feature-' prefix:
    
        $ git branch -r | awk -F/ '/\/feature-/{print $2}'
        3 - Pipe the last command to git push to delete them:
        # **Edit** - Removed extra colon, which is not needed
        $ git branch -r | awk -F/ '/\/feature-/{print $2}' | xargs -I {} git push origin {}
        4 - Grab a beer.
    
        5 - Remove any local reference to those branches:
    
        $ git remote prune origin
    

    谢谢,这对我很有用。在我的情况下,我能够删除多个本地分支。谢谢! - Prashant Kabade
    这篇coderwall上的答案实际上引用了这个stackoverflow页面作为它的第一个来源,因此这基本上是@neevek的被接受的答案。 - rturquier

    7

    感谢Steve和Neevek,我找到了一个对我来说相当有效的解决方案,我认为值得分享:

    Steve的解决方案对我有用,但需要进行一些小修改。我的远程分支名称为origin/feature/some-feature-name,所以我省略了你的awk命令:

    git branch -r | awk -Forigin/ '/\/feature/ {print $2 $3}' | xargs -I {} git push origin :{}
    

    现在它正在执行一个不错的删除流程:

    To github.com:project/project-name.git
    - [deleted]         feature/search-min-chars
    To github.com:project/project-name.git
    - [deleted]         feature/search-placeholder
    To github.com:project/project-name.git
    - [deleted]         feature/server-error-message
    To github.com:project/project-name.git
    - [deleted]         feature/six-point-asterisk
    

    想知道是否有更优雅的解决方案,可以输出类似于这样的内容(我的CLI脚本编写能力很差,所以需要一些时间来理解):

    git push origin :feature/search-min-chars :feature/search-placeholder :feature/server-error-message :feature/six-point-asterisk
    

    这将产生一个漂亮的单一输出,只需要进行一个网络请求:
    To github.com:project/project-name.git
    - [deleted]         feature/search-min-chars
    - [deleted]         feature/search-placeholder
    - [deleted]         feature/server-error-message
    - [deleted]         feature/six-point-asterisk
    

    6

    每个人都在使用 awk,但我不确定为什么。我觉得这更加复杂。以下是我用来删除所有在我的 fork 远程仓库上的分支的命令:

    $ git branch -r --list 'fork/*' | sed 's/fork\///' | xargs git push --delete fork
    

    xargssed之间加入grep,如果您需要将列表过滤为仅包含一部分远程分支。

    1
    非常感谢。在所有解决方案中,这个实际上对我有效。。grep也返回了带有远程名称的完整分支,例如 origin/blaprefix_anotherbla。但使用 sed 处理得很好。此方法的另一个优点是,我使用的是Bitbucket,我不需要为每个分支删除手动输入认证密码。这个可以一次性删除所有分支。 - Madhur Bhaiya
    1
    要删除所有的Greenkeeper分支,请使用以下命令:git branch -r | egrep 'origin/greenkeeper' | sed 's/origin\///' | xargs -I {} git push origin --delete {} - abhisekp

    6
    我知道这是关于git命令的,但如果你想寻找替代方法来实现相似或相同的结果,可以从这里开始(Git删除远程分支): 然后选择你想要的分支: 确保你有权限删除远程分支。

    这应该是一个顶级答案,它是平台无关的。 - karmington
    这个软件是什么,它是否适用于Linux? - abhisekp
    @abhisekp 这是 Git 中包含的标准功能,可以通过运行 git gui 来启动。 - trolzen
    @Trolzen 这在Ubuntu中不是标准的。我该怎么办? - abhisekp
    @abhisekp sudo apt install git-gui。顺便说一下,它是git包的建议之一。 - trolzen

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接