在 git 中删除多个远程分支

我有个队员不小心把他当地的150多家分支机构推给了我们的中央回购部门。谢天谢地,它们的前缀都一样。使用这个前缀,是否有一个 git 命令或者很酷的 shell 脚本,我可以使用它们来一次性删除所有这些内容?

69131 次浏览

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

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

你可能需要先进行一次试运行,看看是否需要移除这些树枝:

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

感谢 尼维克的伟大和优雅的解决方案!

但是由于 awk字段分隔符 /(-F选项) ,我在分支名称中使用斜杠时遇到了一些麻烦(我使用的是 Git Flow)

因此,我的解决方案基于 尼维克的,但使用 /正确地解析分支名称。在这种情况下,我假设你的遥控器称为 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 :{}

如果你喜欢更简单的方法,例如删除3或4个分支:

git push origin --delete <branch1> <branch2> <branch3>

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

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

我尝试删除所有起源/release/r1-1 * 远程分支,因此下面的命令行工作得很好。

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

资源 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

多亏了 Neevek,在按照我的目的重新配置之后,这个方法很有效:

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

我还需要考虑文件夹结构。我的功能分支是在一个文件夹结构中,比如 source/Feature/PREFIX-FEATURENUMBER。所以我必须从 $2 = 文件夹 + $3 = 分支名构建我的模式。

我无法使用 awk,因为我们对分支名称使用了斜杠结构。

git branch -r | grep "origin/users/YOURNAME" | sed -r 's/^.{9}//'| xargs -i  sh -c 'git push origin --delete {}'

这将获取所有远程分支,只获取单个用户的分支,远程获取“ source/”字符串,并对每个分支执行 delete 操作。

Grep 也是一样: git branch -r | grep -Eo 'PREFIX/.*' | xargs -i git push origin :{}.

branch -r显示 origin/prefix/branchname。所以它将采取 prefix/branchname

Github 还有一个很好的用户界面和快速删除分支的机制,如果你更愿意使用用户界面的话

多亏了史蒂夫和尼维克,我找到了一个非常适合我的解决方案,我认为值得分享:

史蒂夫的解决方案对我来说只需要一个小小的调整。我的遥控器被命名为 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

每个人都在使用 awk,不知道为什么。我觉得那更复杂。下面是我用来删除 fork远程控制器上所有远程分支的方法:

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

如果需要将列表过滤到只包含远程分支的子集,则在 xargssed之间添加一个 grep

我知道这是针对 git 命令的,但是如果您正在寻找其他解决方案来实现类似或相同的结果:

你可以从这里开始(Git 移除远程分支) :

然后选择你想要的树枝:

确保您具有删除远程分支的权限。

这可能是一个重复的答案,但以下测试和工作为我完美。

  1. 强制删除本地分支

分支名称

  1. 删除远程分支

Git 推送源——删除分支名

  1. 删除多个本地分支

Git 分支-D 分支-名称1分支-名称2

  1. 删除多个远程分支

Git 推送源——删除 Branch-name1 Branch-name2

  1. 删除带前缀的本地分支

Git 分支-D $(git 分支—— list‘ Feature/*’)

Git 分支-D 退票 $(git 分支—— list‘ Feature/*’退票)

  1. 列出带前缀的远程分支。

Git Branch-r | grep-Eo‘ Feature/. *’

  1. 删除带前缀的远程分支

Git Branch-r | grep-Eo‘ Feature/. *’| xargs-I {} git 推送源 :{}

演练:

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/

以前的答案帮助我从2018年起删除了所有的发布分支。我在 windows 10命令提示符下运行这个命令。我已经安装了 干杯,所以我可以使用类似 Linux 的命令。

演习:

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

如果模拟运行显示不在远程/原点的分支,请在 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。然后运行前面的 prune 命令,再试一次。

很好的解决方案的情况下,多个远程,我们可以找到几个前缀组合。 如果您有许多(比如说数百个)自动创建的分支,例如这样的模式: build/XXXX。此外,还有 upstream远程和分叉 origin,使 branch -r返回 origin/build/XXXXupstream/build/XXXX以及。

可以通过命令 cut -f2- -d/ More 使用解决方案: https://unix.stackexchange.com/a/354984

可以组合安全正则表达式的模式,如: 33[1-3][0-9][0-9]{4}:

git branch -r | grep -Eo "upstream/build/33[0-9][0-9]" | cut -f2- -d/ | xargs -I {} echo {}

上游的真正删除也是如此:

git branch -r | grep -Eo "upstream/build/33[0-9][0-9]" | cut -f2- -d/ | xargs -I {} git push upstream --delete {}

我经常用它来移除远程系统中不需要的分支:

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

观察远程分支查看我们要删除的列表:

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

到目前为止的所有响应都要求在本地获取或克隆远程回购。如果获取远程,要删除的分支可能代表要下载的附加数据的千兆字节。为什么要这么做,只是为了删除它们吗?

这是可以避免的。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。或者使用另一个 regex,比如 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就行了。在删除分支之前,没有必要首先从它拉或取出!