在git中删除多个远程分支

155

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

22个回答

5
感谢 Neevek。在重新配置它以适应我的目的后,这个方法非常有效:
git branch -r | awk -Forigin/ '/\/PATTERN/ {print $2 "/" $3}' | xargs -I {} git push origin :{}

我还需要考虑文件夹结构。我的特性分支位于像origin/feature/PREFIX-FEATURENUMBER这样的文件夹结构中。因此,我必须从$2=文件夹+$3=分支名称构建我的模式。


3

演练:

git branch -r --list 'origin/your-branch-name/*' | sed "s/origin\///" | xargs -I {} echo {}

删除远程分支:

git branch -r --list 'origin/your-branch-name/*' | sed "s/origin\///" | xargs -I {} git push origin --delete {}

仅删除已完全合并的远程分支:

git branch -r --merged --list 'origin/your-branch-name/*' | sed "s/origin\///" | xargs -I {} git push origin --delete {}

解释:

sed "s/origin\///"将从分支名称中去除origin/。如果不去掉,我会得到:remote ref does not exist


2

到目前为止,所有的回答都要求远程仓库已经被本地获取或克隆。如果要删除的分支表示需要下载几个G字节的额外数据,则需要获取远程仓库。为什么不直接删除它们呢?

有办法可以避免这种情况。使用git ls-remote命令可以通过查询远程列表来生成远程分支列表。它不会下载提交记录,因此比获取快得多。

格式看起来像:

c7a0e482a175b632bfd5522bc6d5bfe7785ee9a9        refs/heads/5.0.x+fslc

我们需要去掉哈希值,但是refs/heads/可以完全传递给git push。实际上更好,因为它避免了分支与标签的歧义。
以下是示例:
git push origin -d `git ls-remote --refs -h origin | cut -f2 | grep "pattern"`

这将删除所有名称中带有pattern的分支。如果必须以模式开头,则可以使用refs/heads/pattern。或者使用另一个正则表达式,例如heads/v[234]\.来删除所有旧的2.x、3.x和4.x内核分支。

这也可以删除标签。将-h更改为-t,所有标签都将像这样列出:

1b608b9c630e0795995670aaa10895772001c222        refs/tags/v5.0.3
839630dffddbb49137028da3a09b42a9b74c07bd        refs/tags/v5.0.5

除此之外,它与删除分支的操作完全相同。

标签和分支一样都会在服务器上保留提交记录,因此您需要删除标签以从存储库中获得额外的提交记录。

当然,您可以使用与origin不同的其他远程。只需使用git remote add添加即可。在删除分支之前,不必先从其拉取或提取!


1
我无法使用awk,因为我们使用斜杠结构作为分支的名称。
git branch -r | grep "origin/users/YOURNAME" | sed -r 's/^.{9}//'| xargs -i  sh -c 'git push origin --delete {}'

获取所有远程分支,只获取单个用户的分支,去除“origin/”字符串并对每个分支执行删除操作。

1

Github也有一个漂亮的UI和机制可以快速删除分支,如果您更喜欢使用UI的话。


1
是的,这里有文档记录链接,但你仍然需要为每个单独的分支点击一次。在这里得到的最高投票解决方案是处理多个分支的最佳方式,你可以编写一个正则表达式来匹配它们。 - thewoolleyman

1

查看远程分支,以便查看我们将要删除的列表:

git branch -r | sed 's/origin\/\(.*\)/\1/g' | cut -c 3- | grep -E 'fix_*'

fix_ 是一个用于过滤的关键词

结果:

fix_01032022_2
fix_01042022
fix_01042022_1
fix_01042022_2

删除所有内容:

git push origin -d `git branch -r | sed 's/origin\/\(.*\)/\1/g' | cut -c 3- | grep -E 'fix_*'`

→ 再次提醒,要过滤的关键词为fix_

结果:

- [deleted]           fix_01032022_2
- [deleted]           fix_01042022
- [deleted]           fix_01042022_1
- [deleted]           fix_01042022_2

注意:
这部分是关于字符串的子串:| sed 's/origin\/\(.*\)/\1/g' | cut -c 3- | 结果: origin/name_of_the_branchname_of_the_branch

1

之前的答案帮助我删除了2018年的所有发布分支。我在Windows 10命令提示符上运行了这个命令。我安装了clink,因此Linux命令对我也适用。

模拟运行:

git branch -a | grep -o "release-.*2018" | xargs -I {} echo {}

如果干扰运行显示了不在remote/origin的分支,请运行以下git prune命令进行修复,并再次检查。
git remote prune origin

在你对上面的结果感到满意后,删除它:

git branch -a | grep -o "release-.*2018" | xargs -I {} git push origin --delete {}

如果你看到:error: unable to delete 'release-...2018': remote ref does not exist,那么运行之前的修剪命令,然后再试一次。

0
删除多个远程分支,除了像maindevelop这样的分支之外,你可以尝试这个方法:
git branch -r | sed 's/origin\/\(.*\)/\1/g' | cut -c 3- | grep -v 'main\|develop' | xargs -I {} git push origin :{} 

0

我经常使用这个工具来删除远程仓库中不需要的分支:

git branch -r --list origin/some/prefix/* | sed 's/origin\///' | xargs git push origin --delete

以某些/前缀开头的分支是不需要的。

以下内容:

  • 可以处理名称中带有(多个)/的分支,并且
  • 更新远程分支列表(因此在运行此命令后无需运行git remote update origin --prune

例如:

git branch -r --list origin/bug/* | sed 's/origin\///' | xargs git push origin --delete

删除以'bug/'开头的所有分支。

enter image description here


0
git branch -r | grep 'PATTERN' | cut -c 10- | xargs git push origin --delete

2
你的回答可以通过增加代码的作用和如何帮助提问者来完善。 - Tyler2P

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