我写了一个命令来删除所有 git 分支,而不需要手动全部写入,目前是这样的:
git branch -d $(git branch)
它按照我的要求进行操作,但还尝试删除当前目录中以文件命名的分支,因此输出如下:
error: branch 'angular.json' not found.
error: branch 'assembly.xml' not found.
error: branch 'ci-settings.xml' not found.
error: branch 'coverage' not found.
error: branch 'cypress.json' not found.
error: branch 'Dockerfile.angular' not found.
error: branch 'Dockerfile.spring' not found.
error: branch 'e2e' not found.
error: branch 'examples' not found.
error: branch 'mvnw' not found.
error: branch 'mvnw.cmd' not found.
error: branch 'nginx' not found.
error: branch 'node' not found.
error: branch 'node_modules' not found.
error: branch 'package.json' not found.
error: branch 'package-lock.json' not found.
error: branch 'pom.xml' not found.
error: branch 'README.md' not found.
error: branch 'scripts' not found.
error: branch 'serve-proxy.conf.json' not found.
error: branch 'src' not found.
error: branch 'target' not found.
error: branch 'to-do.txt' not found.
error: branch 'tsconfig.json' not found.
error: branch 'web.config' not found.
error: Cannot delete branch 'dev' checked out at 'D:/Documentos/oreons/Rise/archivekeeper-ui'
Deleted branch test (was 729628a).
如果我 echo $(git branch)
,输出如下:
$ echo $(git branch)
angular.json assembly.xml ci-settings.xml coverage cypress.json Dockerfile.angular Dockerfile.spring e2e examples mvnw mvnw.cmd nginx node node_modules package.json package-lock.json pom.xml README.md scripts serve-proxy.conf.json src target to-do.txt tsconfig.json web.config dev
这解释了命令的输出。但是为什么$(git branch)
除了 git 分支之外还输出所有这些文件名?
答案1
作为@steeldriver上面提到评论,在其输出中git branch
有一个星号(*
),以标记当前签出的分支。
$ git branch
* main
test
当以 方式运行时$(git branch)
,输出中的星号将扩展为当前所在目录中的所有非隐藏文件和目录。
要删除星号,您可以通过传递选项来格式化输出--format
,仅显示引用名称的短格式。
$ git branch --format='%(refname:short)'
main
test
因此您要使用的命令如下。
git branch -d $(git branch --format='%(refname:short)')
答案2
不要git branch
在脚本中使用。相反,请使用低级命令,例如git for-each-ref
:
git for-each-ref --shell --format='%(refname:short)' refs/heads | \
while read branch; do git branch -d "$branch"; done
或者
git for-each-ref --shell --format='%(refname:short)' refs/heads | \
xargs git branch -d
这避免了问题中的命令问题,因为它正确地引用了参数扩展。不引用参数扩展(或命令替换)将执行路径名扩展扩大价值。
由于git branch
是面向用户的命令,它用 标记当前分支*
。您可能知道,*
作为通配符/通配符,可解析为任意 0 个或多个字符。执行 时echo *
,您的 shell 首先扩展并替换*
当前目录中的所有(非隐藏)文件,然后将此文件列表作为参数传递给echo
。
结论:总是引用“美元表达”(不是一个真正的术语,我说的是参数扩展和命令替换)来防止字段拆分和路径名扩展——除非你有很好的理由不这样做(并且知道你在做什么)
答案3
我在 shell 函数中使用它,目的基本相同,尽管它保留了main
、master
和当前分支(用星号标记,如较早的答案和评论中所述)。您可能会发现它很有用。
git branch |
grep -v '^\*' |
grep -oE '[^ ]+' |
grep -vE '^(master|main)$' |
while read branch_name; do
git branch -D $branch_name
done