使用grep和xargs和git一次删除多个分支

afdcj2ne  于 2022-12-10  发布在  Git
关注(0)|答案(2)|浏览(142)

我已经在我的Windows机器上使用了一些Linux工具有一段时间了,因为它是git安装自带的,使用起来非常有趣。我特别喜欢这个命令,理论上它可以让我一次性删除所有无关的git分支:

git branch | grep -v 'master' | xargs git branch -d

然而,不久前,这个方法停止了工作,取而代之的是,我得到了一系列关于每个分支的错误消息沿着如下所示:

error: branch 'extraneous-branch-1?' not found.
error: branch 'extraneous-branch-2?' not found.
error: branch 'extraneous-branch-3?' not found.
...

请注意,问号不是分支名称的一部分--显然是在值从grep传输到xargs时添加的。当我在交互模式下运行xargs以查看它实际生成了什么时,我得到了如下所示的输出:

git branch -d 'extraneous-branch-1'$'\r' 'extraneous-branch-2'$'\r' 'extraneous-branch-3'$'\r' ...

看起来grep在每次匹配时都会将行尾和回车符条目作为管道传输,尽管我不知道如何阻止它这样做。令我困惑的是,我确实记得以前是这样的--我不知道会发生什么变化。说实话,我对Linux命令行工具几乎一无所知,所以如果我忽略了什么我也不会感到惊讶。不管怎样,谢谢你的建议。

编辑

当我运行git branch | cat -A时,得到以下结果:

extraneous-branch-1$
 extraneous-branch-2$
 extraneous-branch-3$
whlutmcx

whlutmcx1#

这里问题的根源是一个更一般情况下的具体例子:一些Git命令产生的输出是为了让“人类”阅读,而另一些Git命令产生的输出是为了让“计算机”阅读。2用计算机程序阅读人类的输出会产生惊喜,所以:别这样。
特别是,git branch可能会在分支名称中添加 color encoding,或者通过一个 pager 来运行它的输出。这是因为git branch是Git所称的 * ceramine * 命令,这意味着它会产生人类可读的输出。幸运的是,还有一个类似的 plumbing 命令git for-each-ref,因为它是“plumbing”,所以默认情况下会产生计算机可读的输出。
for-each-ref命令使用起来有点麻烦,因为你必须更加明确。要获得 * 分支names*,而不需要更多的细节,你需要:

git for-each-ref --format="%(refname:short)" refs/heads

您可以通过grep -v '^master$'运行此输出,以删除名称master。(您现有的grep有点松散。它也会被删除,例如,分支名称stairmaster_bugfix。)
有关git for-each-ref命令的更多信息,请参见its documentation。注意,默认情况下,如果git branch的stdout不是由C库isatty函数确定的“tty设备”,则git branch * 会尝试 * 删除一些花哨的功能,如颜色化和默认使用寻呼机,但您可以使用配置设置覆盖这些默认设置。很可能您已经这样做了。因为git branch | grep通常会导致C库isatty说“不,不是tty”。

w1e3prcc

w1e3prcc2#

感谢anubhava为我指出了正确的方向。看起来grep返回了一堆在运行git branch | cat -A时可见的非打印字符。结果表明,只要在其中添加cat就可以消除所有这些字符。现在它运行得很好。

git branch | grep -v master | cat | xargs git branch -d

比以前更罗嗦了,但我没有抱怨。

相关问题