【问题标题】:Git Branch Status via Plumbing Command通过 Plumbing 命令的 Git 分支状态
【发布时间】:2019-04-29 10:12:02
【问题描述】:

有没有办法将git branch -v 的输出作为管道命令?确切地说,我只对分支的状态感兴趣,即是否为[gone]

例如给定以下git branch -v 输出:

> git branch -v 
  master            32c59ad4 Some other comment
  someDeletedBranch 6aacba47 [gone] Some Comment

我如何获得someDeletedBranch 参考?

请注意,这git branch --merged 相同,例如,如果您将拉取请求压缩到您的主服务器中,那么this solution 不会这样做。

这主要与this question 有关,因为这将是能够创建可靠脚本以删除远程不再存在的本地分支的缺失部分。

【问题讨论】:

  • 我不确定这是否会对您有所帮助,但有一种方法可以列出所有本地和远程分支。 git branch -a -v。这样你就可以看到远程上不再存在哪些分支。另一种选择是在本地和远程分支之间进行差异。如果它抛出错误,则远程分支不存在。 git diff <local branch> <remote>/<remote branch>。如果我没有完全理解这个问题,请提前道歉。
  • @Nemanja 问题在于git branch 是一个不应在脚本中解析的瓷器命令,因为您的方法仍然使用它,因此没有任何改进。而且我不必在遥控器和参考文献之间进行所有这些手动比较——这并不像你想象的那么简单。 git branch -v 已经帮我完成了,并告诉我哪些分支消失了,哪些没有。
  • @NemanjaGlumac - 除了 Voo 的反对意见之外,这些解决方案的一个更实际的问题是,对于任何尚未推送的本地分支,它们都会得到误报。
  • @MarkAdelsberger - 感谢更新和澄清。

标签: git


【解决方案1】:

git branch 的管道替代品通常是 git for-each-ref

$ git fetch --prune
$ git for-each-ref --format '%(refname) %(upstream)' refs/heads refs/remotes/origin

此输出将包括每个本地分支的条目,以及每个指向原点的远程跟踪引用的条目;因此,如果在fetch --prune 之后运行,如此处所示,它可以显示本地存在的内容,但服务器上不存在。

当然有一个问题:“存在于本地但不在服务器上”可能意味着“从服务器中删除”,或者可能意味着“在本地创建但尚未推送”。为了区分,您还需要知道您的本地分支是否“认为”它有上游。 (如果是这样,假设它已从服务器中删除是相当安全的,因为git 拒绝设置不存在的上游;所以如果它是错误的,基本上有人必须故意用损坏的配置“欺骗”你的脚本.)

这就是--format 选项的用途。你可以处理这个输出,寻找

refs/heads/somebranch refs/remotes/origin/somebranch

并且,对于每个这样的条目,如果没有一个单独的条目,例如

refs/remotes/origin/somebranch

那么这是一个标记为[gone]的分支

【讨论】:

  • 很好的解决方案。我想知道git branch -v 是如何决定哪些分支消失的(因为你说的幼稚解决方案行不通),所以很高兴了解背景。我会尽快接受。
  • [gone] 只是 v2.13.2+ 中 %(upstream)%(upstream:track) 输出的一部分
  • @LightBender 很好的例子,为什么解析瓷器命令将是一个非常糟糕的主意。
【解决方案2】:

仅限 Git v2.13.2+

基于 Mark 的回答和 this post,这是一个非常干净的解决方案(为了便于阅读而拆分行):

git for-each-ref \
    --format='%(if:equals=[gone])%(upstream:track)%(then)%(refname:short)%(end)' \
    refs/heads

好处:

删除不在远程的本地分支的简单方法

一个简单的使用方法是用git branch -D 替换命令。请注意,如果没有要删除的分支,git 会抱怨

git branch -D $(git for-each-ref --format='%(if:equals=[gone])%(upstream:track)%(then)%(refname:short)%(end)' refs/heads)

这是一个稍长的版本,如果没有要删除的分支,git 不会抱怨。

for branch in $(git for-each-ref --format='%(if:equals=[gone])%(upstream:track)%(then)%(refname:short)%(end)' refs/heads); do git branch -D $branch; done

或者,您可以将git for-each-ref 的输出保存到一个变量中,然后如果它不为空,则有条件地删除分支,如果是则显示一条消息。

【讨论】:

  • if then 语法至少可以说很有趣。这绝对应该是规范的答案,我希望马克不会因为我改变接受把它放在首位而感到沮丧:-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-08-23
  • 2021-10-08
  • 2011-06-22
  • 2015-11-14
  • 1970-01-01
  • 1970-01-01
  • 2023-04-06
相关资源
最近更新 更多