git-列出所有没有rem的本地分支

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

例如:

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

$ git co -b no_upstream

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

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

我可以运行什么命令来获取git-delete-unbranched作为答案?

我可以运行git-delete-unbranched,这将显示它没有远程:

$ 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>...]'

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

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

JC Denton asked 2019-10-14T12:46:00Z
8个解决方案
68 votes

我最近发现了origin,它是*命令的“非常详细”版本。

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

  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

获得格式正确的输出后,就很容易通过origin*用管道传输来获取列表:

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

结果如下:

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

origin部分仅通过将输出中的前两个字符(包括*)传递给awk来规范化数据。

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

奖励:创建别名

通过在全局origin104(或任意位置)中创建别名,可以轻松运行:

[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 }'
Jeremy Baker answered 2019-10-14T12:47:24Z
24 votes

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

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

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

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

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

VonC answered 2019-10-14T12:48:14Z
16 votes

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

从我的git config中:

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

编辑:根据要求,以下是git config6000命令,可轻松将其添加为ifne

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

注意:我在实际配置中将git config更改为ifne,因为我不想听到Git抱怨合并分支的问题。 您可能还需要此功能。 如果是这样,只需在该命令末尾使用xargs而不是ifne

同样,FWIW,您的全局配置文件几乎总是git config

编辑:(OSX修复)如所写,这在OSX上不起作用,因为使用了git config(谢谢,Korny)。

git config用于防止ifne运行没有分支名称的xargs,这将导致错误消息“ 256892076146137600600”。 如果您不介意错误消息,则只需将-r参数删除为xargs,即可完成所有设置。

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

这是git config6000行与ifne

git config --global alias.prune-branches '!git remote prune origin && git branch -vv | grep '"'"': gone]'"'"' | awk '"'"'{print $1}'"'"' | ifne xargs git branch -d'
Karl Wilbur answered 2019-10-14T12:49:51Z
15 votes

后期编辑:更好

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

如果可能有多个分支,那么会有更好的方法,在git branch|sed|sortgit config -l|sed|sort的输出上使用comm -23

jthill answered 2019-10-14T12:50:37Z
11 votes

这对我有用:

git branch -vv | grep -v origin

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

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

ebr answered 2019-10-14T12:51:28Z
2 votes

粗略的Powershell实施:(如果源是您唯一的远程用户)

@($branches = git br -r; git branch | %{ echo $_ | sed 's/..//' }) `
   | %{ if (($branches | ss "origin/$_") -eq $null) { `
          echo "git branch -D $_" `
        } `
      }
nbergen answered 2019-10-14T12:51:57Z
2 votes

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

$verboseList = @(git br -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
    }
}
grahamesd answered 2019-10-14T12:52:29Z
0 votes

我将自己的git命令综合起来以获取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将以详细模式打印分支

git branch -D将删除第一个字符

git branch -D将仅打印消失的远程分支

git branch -D将打印分支名称

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

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

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

fiorentinoing answered 2019-10-14T12:53:53Z
translate from https://stackoverflow.com:/questions/15661853/list-all-local-branches-without-a-remote