列出没有遥控器的所有本地分支

JC *_*ton 72 git git-remote

问题:我想要一种删除没有遥控器的所有本地分支的方法.很容易将分支的名称输入到a中git branch -D {branch_name},但我如何首先获得该列表?

例如:

我创建了一个没有远程的新分支:

$ git co -b no_upstream
Run Code Online (Sandbox Code Playgroud)

我列出了所有的分支,只有一个有远程

$ git branch -a
master
* no_upstream
remotes/origin/HEAD -> origin/master
remotes/origin/master
Run Code Online (Sandbox Code Playgroud)

我可以运行什么命令来获得no_upstream答案?

我可以跑git rev-parse --abbrev-ref --symbolic-full-name @{u},这将表明它没有遥控器:

$ git rev-parse --abbrev-ref --symbolic-full-name @{u}
error: No upstream configured for branch 'no_upstream'
error: No upstream configured for branch 'no_upstream'
fatal: ambiguous argument '@{u}': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'
Run Code Online (Sandbox Code Playgroud)

但由于这是一个错误,它不会让我使用它或将其传递给其他命令.我打算将它用作shell脚本别名git-delete-unbranched或者可以制作一个超级简单的Gemgit-branch-delete-orphans

任何帮助,将不胜感激!谢谢

Jer*_*ker 85

我最近发现git branch -vv哪个是命令的"非常详细"版本git branch.

它输出分支以及远程分支(如果存在),格式如下:

  25-timeout-error-with-many-targets    206a5fa WIP: batch insert
  31-target-suggestions                 f5bdce6 [origin/31-target-suggestions] Create target suggestion for team and list on save
* 54-feedback-link                      b98e97c [origin/54-feedback-link] WIP: Feedback link in mail
  65-digest-double-publish              2de4150 WIP: publishing-state
Run Code Online (Sandbox Code Playgroud)

一旦你有了这个格式良好的输出,它就像通过管道cutawk获得你的列表一样简单:

git branch -vv | cut -c 3- | awk '$3 !~/\[/ { print $1 }'
Run Code Online (Sandbox Code Playgroud)

结果如下:

25-timeout-error-with-many-targets
65-digest-double-publish
Run Code Online (Sandbox Code Playgroud)

cut部分通过*在传递之前从输出中删除前两个字符(包括)来规范化数据awk.

awk如果第三列中没有方括号,则该部分打印第一列.

额外奖励:创建别名

通过在全局.gitconfig文件(或任何地方)中创建别名,可以轻松运行:

[alias]
  local-branches = !git branch -vv | cut -c 3- | awk '$3 !~/\\[/ { print $1 }'
Run Code Online (Sandbox Code Playgroud)

重要说明:反斜杠需要在别名中进行转义,否则您将拥有一个无效的gitconfig文件.

奖励:远程过滤

如果由于某种原因,您有不同分支的多个跟踪遥控器,则可以轻松指定要检查的遥控器.只需将远程名称附加到awk模式即可.就我而言,origin我可以做到这一点:

git branch -vv | cut -c 3- | awk '$3 !~/\[origin/ { print $1 }'
Run Code Online (Sandbox Code Playgroud)

  • 这不会错过标记为“gone”的远程分支吗? (2认同)

Von*_*onC 33

git branch (没有任何选项)仅列出本地分支,但您不知道它们是否正在跟踪远程分支.

通常那些本地分支一旦合并就应该删除master(如本期git-sweep中所示):

git branch --merged master | grep -v master | xargs git branch -d
Run Code Online (Sandbox Code Playgroud)

这不是你想要的完整,但它是一个开始.

使用时--merged,只会将分支合并到命名提交中(即,可以从命名提交到达提示提交的分支).


Kar*_*bur 17

我有一个类似的问题.我想删除所有跟踪现在已删除的远程分支的本地分支.我发现这git remote prune origin不足以删除我想要的分支.删除遥控器后,我希望本地也消失.这对我有用:

从我的~/.gitconfig:

[alias]
  prune-branches = !git remote prune origin && git branch -vv | grep ': gone]' | awk '{print $1}' | xargs -r git branch -d
Run Code Online (Sandbox Code Playgroud)

编辑:根据要求,这是一个git config --global ...命令,可以轻松添加为git prune-branches:

git config --global alias.prune-branches '!git remote prune origin && git branch -vv | grep '"'"': gone]'"'"' | awk '"'"'{print $1}'"'"' | xargs -r git branch -d'
Run Code Online (Sandbox Code Playgroud)

注意:我在实际配置中更改-d-D,因为我不想听到Git抱怨未合并的分支.您可能也想要这个功能.如果是这样,只需使用-D而不是-d在该命令的末尾.

另外,FWIW,您的全局配置文件几乎总是如此~/.gitconfig.

编辑:(OSX修复) 如上所述,由于使用xargs -r(感谢,Korny),这在OSX上不起作用.

-r是为了防止xargsgit branch -d没有分支名称的情况下运行,这将导致错误消息" fatal: branch name required".如果你不介意错误信息,你可以简单地删除-r参数,xargs然后你就可以了.

但是,如果您不希望看到错误消息(实际上,谁可能会责怪您),那么您将需要其他检查空管道的东西.如果您可以使用moreutils中ifne.您ifne之前将插入xargs,这将停止xargs使用空数据运行.注意:ifne认为任何内容都不为空,这包括空行,因此您仍可能看到该错误消息.我没有在OSX上测试过这个.

这是以下git configifne:

git config --global alias.prune-branches '!git remote prune origin && git branch -vv | grep '"'"': gone]'"'"' | awk '"'"'{print $1}'"'"' | ifne xargs git branch -d'
Run Code Online (Sandbox Code Playgroud)


jth*_*ill 16

后期编辑:更好的是

git for-each-ref  --format='%(refname:short) %(upstream)'  refs/heads \
| awk '$2 !~/^refs\/remotes/'
Run Code Online (Sandbox Code Playgroud)

在GNU /任何东西上

for b in `git branch|sed s,..,,`; do
    git config --get branch.$b.remote|sed Q1 && echo git branch -D $b
done
Run Code Online (Sandbox Code Playgroud)

如果超过了一把树枝很可能有会是更好的方式,使用comm -23上的输出git branch|sed|sortgit config -l|sed|sort.


ebr*_*ebr 12

这对我有用:

git branch -vv | grep -v origin

(如果您的遥控器被命名为原点以外的其他任何东西,请替换它).

这将列出所有未跟踪遥控器的分支,这听起来像您正在寻找的.

  • 这将列出曾经有一个远程但没有的分支,即使您运行`git fetch --prune`。 (2认同)
  • 这个解决方案是我的最爱。 (2认同)
  • IMO,最好寻找“:消失]”而不是过滤掉“起源” (2认同)

fio*_*ing 8

我合成了自己的 Git 命令来获取origin/***: gone分支:

git remote prune origin && git branch -vv | cut -c 3- | grep ': gone]' | awk '{print $1}' | xargs -n1 -r echo git branch -d
Run Code Online (Sandbox Code Playgroud)

git remote prune origin && git branch -vv 将以详细模式打印分支。

cut -c 3- 将删除第一个字符。

grep ': gone]'将只打印消失的远程分支。

awk '{print $1}' 将打印分支名称。

xargs -n1 -r echo git branch -d将打印git branch -d删除分支的命令(-n1 将每次管理一个命令,-r 以避免在不存在分支时发出命令)。

提示:删除“echo”命令以运行命令而不是仅打印,我将其留在命令中以在向 git 发出之前检查命令。

提示 2:git branch -D当且仅当您确定要删除未合并的分支时才发出

  • 这是_迄今为止_我发现的最干净的解决方案,很好!我从来没有花时间研究“awk”,我不知道你能做到这一点。 (2认同)

Kev*_*ies 5

这里投票最多的答案在我的系统上不起作用,请参阅要点

以下内容确实有效并且相当干净。

git branch -v | awk '$3 == "[gone]" { print $1 }' | xargs git branch -D
Run Code Online (Sandbox Code Playgroud)

如果您不想删除未合并的分支,请使用 -d。


归档时间:

查看次数:

33770 次

最近记录:

5 年,10 月 前