【问题标题】:How do I list all remote branches which don't have a local branch?如何列出所有没有本地分支的远程分支?
【发布时间】:2023-01-07 20:48:10
【问题描述】:

我想列出所有没有相应本地分支的远程 Git 分支。

例如,如果 git branch --all 的输出是:

  remotes/origin/alpha
* beta
  main
  remotes/origin/beta
  remotes/origin/main

我想结束的是:

remotes/origin/alpha

最好的方法是什么?

【问题讨论】:

  • 试试git remote showstackoverflow.com/a/15630478/7976758可能是git remote show origin | grep -Fv trackedstackoverflow.com/search?q=%5Bgit%5D+list+remote+branches找到
  • 您可能需要准确定义“没有相应的本地分支机构”的含义。但是,请注意,在 Git 中不需要有分支名称:可以在 Git 中使用根本没有分支名称.不要创建不需要的分支名称:没有意义。创建你想要的分支名称,尽可能多,因为分支名称没有磁盘空间成本,但不要创建你不需要的分支名称,因为拥有大量分支名称会导致你的大脑空间问题. :-)
  • @phd:你的建议似乎返回跟踪远程分支的本地分支,但我希望显示没有本地跟踪分支的远程分支。我在问题中添加了一个示例以帮助澄清。
  • @countermeasure grep -v 过滤掉跟踪,因此整个命令返回没有上游的本地分支和尚未获取的远程分支。
  • @GinoMempin Git 命令是理想的,但我也怀疑可能没有,所以我对 shell 脚本很满意。

标签: git


【解决方案1】:

据我所知,在发布此答案时,没有直接的 Git 命令或选项。

但是,受grep using output from another command 的启发,您可以使用grep 获取远程分支refname 列表中缺少的本地分支refname 的列表:

$ grep -v -F -f <(git for-each-ref --format='%(refname:lstrip=2)' refs/heads) <(git for-each-ref --format='%(refname:lstrip=3)' refs/remotes/origin) | grep -vF HEAD

例子:

$ git branch
  feature/C
  feature/D           # local-only branch, not pushed to remote
* master

$ git branch -r
  origin/HEAD -> origin/master
  origin/develop      # no corresponding branch on local
  origin/feature/A    # no corresponding branch on local
  origin/feature/B    # no corresponding branch on local
  origin/feature/C    # is already on local
  origin/master       # is already on local

$ grep -v -F -f <(git for-each-ref --format='%(refname:lstrip=2)' refs/heads) <(git for-each-ref --format='%(refname:lstrip=3)' refs/remotes/origin) | grep -vF HEAD
develop
feature/A
feature/B

命令的结构是:

$ grep -v -F -f <(command 2) <(command 1)
  • command 2列出所有本地分行
    $ git for-each-ref --format='%(refname:lstrip=2)' refs/heads
    feature/C
    feature/D
    master
    
  • command 1列出所有拿来的远程分支
    $ git for-each-ref --format='%(refname:lstrip=3)' refs/remotes/origin
    HEAD
    develop
    feature/A
    feature/B
    feature/C
    master
    

-f &lt;(command 2) 告诉grepcommand 1(远程分支模式)的输出中搜索command 2(本地分支模式)的输出中的模式。那应该返回已经有相应本地分支的远程分支,然后 -v 选项反转结果。管道 git -vF HEAD 仅用于排除 HEAD

您也可以使用 git branch,但我更喜欢使用 git for-each-ref 来编写脚本和自动化。请参阅有关 Git 的 "plumbing" vs "porcelain" commands 之间区别的相关帖子。

这可能并不总是有效因为:

  • 这仅按名称比较分支,特别是 refname's,并假设您始终跟踪远程分支与名称相似的本地分支 which may not always be the case
  • 该命令使用 Bash 5.x,并使用 process substition (&lt;(...)) 允许将命令的输出称为文件名,以与 grep-f 选项一起使用。这使得它有点不可移植,并且很难(不可能?)放入 git 别名。

为方便起见,我通过 git fetch 调用将它变成了一个常规的 shell 别名:

$ alias git-new-branches="git fetch; grep -v -F -f <(git for-each-ref --format='%(refname:lstrip=2)' refs/heads) <(git for-each-ref --format='%(refname:lstrip=3)' refs/remotes/origin) | grep -vF HEAD"

$ git-new-branches 
develop
feature/A
feature/B

您可能更愿意将其转换为 shell 脚本,embed that into a Git alias

【讨论】:

    猜你喜欢
    • 2013-03-17
    • 2022-11-05
    • 2018-04-27
    • 2010-09-27
    • 2014-06-09
    • 2013-04-30
    • 2014-08-09
    • 2013-11-15
    • 2020-06-11
    相关资源
    最近更新 更多