我有一个团队成员无意中将他的 150 个本地分支推送到我们的中央仓库。幸运的是,它们都有相同的前缀。使用该前缀,是否有一种 git 命令或酷炫的小型 shell 脚本可以一次性删除所有这些分支?
git branch -r | awk -Forigin/ '/\/PATTERN/ {print $2 "/" $3}' | xargs -I {} git push origin :{}
我还需要考虑文件夹结构。我的特性分支位于像origin/feature/PREFIX-FEATURENUMBER这样的文件夹结构中。因此,我必须从$2=文件夹+$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
到目前为止,所有的回答都要求远程仓库已经被本地获取或克隆。如果要删除的分支表示需要下载几个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
添加即可。在删除分支之前,不必先从其拉取或提取!
git branch -r | grep "origin/users/YOURNAME" | sed -r 's/^.{9}//'| xargs -i sh -c 'git push origin --delete {}'
Github也有一个漂亮的UI和机制可以快速删除分支,如果您更喜欢使用UI的话。
查看远程分支,以便查看我们将要删除的列表:
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_branch
→ name_of_the_branch
之前的答案帮助我删除了2018年的所有发布分支。我在Windows 10命令提示符上运行了这个命令。我安装了clink,因此Linux命令对我也适用。
模拟运行:
git branch -a | grep -o "release-.*2018" | xargs -I {} echo {}
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
,那么运行之前的修剪命令,然后再试一次。main
、develop
这样的分支之外,你可以尝试这个方法:git branch -r | sed 's/origin\/\(.*\)/\1/g' | cut -c 3- | grep -v 'main\|develop' | xargs -I {} git push origin :{}
我经常使用这个工具来删除远程仓库中不需要的分支:
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
git branch -r | grep 'PATTERN' | cut -c 10- | xargs git push origin --delete