列出所有本地分支而不带远程


91

问题:我想要一种删除我所有没有遥控器的本地分支的方法。将分支的名称通过管道传递到中很容易git branch -D {branch_name},但是首先如何获取该列表?

例如:

我创建一个没有遥控器的新分支:

$ git co -b no_upstream

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

$ git branch -a
master
* no_upstream
remotes/origin/HEAD -> origin/master
remotes/origin/master

我可以运行什么命令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>...]'

但是由于这是一个错误,它不会让我使用它或将其通过管道传递给其他命令。我打算将其用作shell脚本的别名,git-delete-unbranched或者使之成为超级简单的Gem,例如git-branch-delete-orphans



1

Answers:


103

我最近发现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

一旦获得了格式正确的输出,就可以像通过管道传输cutawk获得列表一样简单:

git branch -vv | cut -c 3- | awk '$3 !~/\[/ { print $1 }'

结果如下:

25-timeout-error-with-many-targets
65-digest-double-publish

cut部分只是通过将*输出中的前两个字符(包括)删除(然后将其传递到)来规范化数据awk

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

奖励:创建别名

通过在全局.gitconfig文件(或任意位置)中创建别名来使其易于运行:

[alias]
  local-branches = !git branch -vv | cut -c 3- | awk '$3 !~/\\[/ { print $1 }'

重要提示:需要在别名中转义反斜杠,否则您将拥有无效的gitconfig文件。

奖励:远程过滤

如果由于某种原因您在不同分支机构具有多个跟踪远程服务器,那么很容易指定要检查的远程服务器。只需将远程名称附加到awk模式即可。就我而言,origin是这样的:

git branch -vv | cut -c 3- | awk '$3 !~/\[origin/ { print $1 }'

那到底是什么WIP:..?这不是存储命令创建的..?
igrek

@igrek这只是我在提交消息中使用的前缀。没有特定于git的内容。
杰里米·贝克

当我这样做时git branch -vv,即使存在远程分支并且与我的本地分支匹配,我也不会看到[origin/branch-name]结果旁边的内容。我必须有diff两个分支列表才能真正弄清楚什么是本地的。
ryantuck

git branch -vv | grep -v origin/对我来说足够了
不要惊慌

2
这不是错过标记了远程分支gone吗?
里德

36

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

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

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

这不是您想要的那样完整,但这只是一个开始。

使用--merged,将仅列出合并到命名提交中的分支(即,可以从命名提交到达其尖端提交的分支)。


1
要也包含没有本地分支的远程分支,请使用git branch -a --merged
Acumenus

21

我有一个类似的问题。我想删除所有正在跟踪已删除的远程分支的本地分支。我发现这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

这是一个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'

:我改变了-d-D我的实际配置,因为我不希望听到的Git抱怨未合并的分支。您可能还需要此功能。如果是这样,只需在该命令末尾使用-D而不是即可-d

同样,FWIW,您的全局配置文件几乎总是~/.gitconfig

(OS X修复)

如所写,由于使用xargs -r(感谢Korny),因此在OS X上不起作用

-r是为了防止xargsgit branch -d没有分支名称的情况下运行,这将导致错误消息“ fatal: branch name required”。如果您不介意错误消息,则只需删除-rto的参数就xargs可以了。

但是,如果您不想看到错误消息(实际上是谁会责怪您),那么您将需要其他检查空管的信息。如果您可以使用moreutils中ifne。您将在ifne之前插入xargs,这将停止xargs使用空数据运行。注意ifne认为任何东西都不为空,其中包括空行,因此您仍然可能会看到该错误消息。我尚未在OS X上对此进行测试。

这是git config一行ifne

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

1
是否可以将其转换为“ git config --global ...”命令?从指令/如何对虚拟人进行操作的角度来看,它很容易传递,而不是说“找出git config文件,使用编辑器对其进行编辑然后运行命令”
Kannan Ekanath


很高兴知道。我不知道OSX的“如果为空则不运行”选项将是什么。
Karl Wilbur '18

18

后期编辑:

更好的是

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

在GNU /任何东西上

for b in `git branch|sed s,..,,`; do
    git config --get branch.$b.remote|sed Q1 && echo git branch -D $b
done

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


1
@nmr s / git。* Q1 / test $(git config --get branch。$ b.remote | sed q | wc -1)= 1 /
jthill 2014年

15

这对我有用:

git branch -vv | grep -v origin

(如果您的遥控器的名称不是原始名称,请替换为该名称)。

这将列出所有未跟踪远程站点的分支,这听起来像您在寻找什么。


2
这将列出曾经具有远程功能的分支,但即使您运行了,也不会再有git fetch --prune
RusinaRange

2
海事组织,最好是寻找“:走了”,而不是过滤掉“起源”
佛罗伦萨,

3

我综合自己的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

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仅当您确定要删除未合并的分支时才发出


从这开始,我没有做我的私人混帐
佛罗伦萨,

2

这是我在PowerShell中使用的带有注释的内容,以解释其功能。为了弄清楚发生了什么,我没有使用任何缩写的PowerShell命令(别名)。随意将其压缩到所需的加密程度:)

$verboseList = @(git branch -vv)
foreach ($line in $verboseList)
{
    # Get the branch name
    $branch = [regex]::Match($line, "\s(\S+)\s").Captures.Groups[1].Value
    # Check if the line contains text to indicate if the remote is deleted
    $remoteGone = $line.Contains(": gone]")
    # Check if the line does not contain text to indicate it is a tracking branch (i.e., it's local)
    $isLocal = !($line.Contains("[origin/"))
    if ($remoteGone -or $isLocal)
    {
        # Print the branch name
        $branch
    }
}

0

结合一些现有的答案:

[alias]
        branch-local = !git branch -vv | cut -c 3- | egrep '([0-9a-f]{7} [^[])|(: gone\\])' | sed -E 's/(^.+[0-9a-f]{7} (\\[.+\\])?).*$/\\1/'

例如:

$ git branch-local
autogen_autoreconf      fcfb1c6 [github/autogen_autoreconf: gone]
autotools_documentation 72dc477 [github/autotools_documentation: gone]
cray-mpich-messy        2196f4b
epel-sphinx             cfda770
lammps                  07d96a7 [github/lammps: gone]
lark-error              9ab5d6c [github/lark-error: gone]
no-root2                c3894d1
openmpi-cray            69326cf [github/openmpi-cray: gone]
shellcheck-cleanup      40d90ec
travis-python36         cde072e
update_vagrant_default  4f69f47 [github/update_vagrant_default: gone]
web-docs                e73b4a8
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.