【问题标题】:Show git ahead and behind info for all branches, including remotes显示所有分支的 git 前后信息,包括遥控器
【发布时间】:2011-10-14 21:48:51
【问题描述】:

在 github 项目上,您可以转到 /branches 页面并查看类似这样的漂亮图表,每个分支显示每个分支相对于 master 的落后和领先程度。

有没有类似的命令行工具?也适用于遥控器的东西?例如,

git branch -v -v

与我正在寻找的内容接近,但仅适用于本地分支机构。

【问题讨论】:

  • 您可以将“-r”和“-a”仅用于遥控器和所有分支分别添加到git branch...so git branch -v -v -a
  • @seth - 他在要求 master 和远程分支......我不喜欢他想要的,但你说的不会这样做......
  • 注意:Git1.9/2.0 将提供另一种显示“领先/落后”状态的方式。见my answer below
  • 所以你基本上希望所有分支,包括远程分支,都与单个参考分支进行比较,例如master?
  • 使用 Git 2.5+(2015 年第二季度),实际命令将是 git for-each-ref --format="%(push:track)" refs/heads。见my revised answer below

标签: git


【解决方案1】:

我也对此很好奇,所以我刚刚编写了一个git branch-status 脚本,它使用git for-each-ref 提供此信息

#!/bin/bash
# by http://github.com/jehiah
# this prints out some branch status (similar to the '... ahead' info you get from git status)
 
# example:
# $ git branch-status
# dns_check (ahead 1) | (behind 112) origin/master
# master (ahead 2) | (behind 0) origin/master
 
git for-each-ref --format="%(refname:short) %(upstream:short)" refs/heads | \
while read local remote
do
    [ -z "$remote" ] && continue
    git rev-list --left-right "${local}...${remote}" -- 2>/dev/null >/tmp/git_upstream_status_delta || continue
    LEFT_AHEAD=$(grep -c '^<' /tmp/git_upstream_status_delta)
    RIGHT_AHEAD=$(grep -c '^>' /tmp/git_upstream_status_delta)
    echo "$local (ahead $LEFT_AHEAD) | (behind $RIGHT_AHEAD) $remote"
done

用法:

$ git branch-status
dns_check (ahead 1) | (behind 112) origin/master
master (ahead 2) | (behind 0) origin/master

【讨论】:

  • 太棒了,谢谢耶希亚!这个脚本很棒。不是我想要的,所以我修改了它:git-branches-vs-origin-master
  • 有没有办法在 Windows 上使用这个脚本?看起来很棒。 :-)
  • @kortina - 您的 gist 链接现已损坏,您有机会更新它吗?谢谢,
  • 感谢git branch-status Jehiah,我创建了my own(基于lth2h's),它只显示当前分支并且只在分支是领先或落后。它还添加了显示所有分支的选项,即使分支不在前面或后面也显示输出并显示帮助。当您的应用程序分布在多个 git 存储库中并且您希望快速查看所有需要注意的状态时,这非常有用。
【解决方案2】:

2015 年更新

我在下面的初步答案并不理想,因为上游分支不一定是您要推送的分支,它可能与您从中拉出的分支不同。

使用 Git 2.5+,正确的命令是:

git for-each-ref --format="%(refname:short) %(upstream:track) %(upstream:remotename)" refs/heads

在“Viewing Unpushed Git Commits”查看更多信息。

(正如the comments中的void.pointer所指出的,upstream:trackpush:track更精确,具体取决于default push policy

(upstream:remotename) 部分来自HankCAcomment,用于查看是否已推送分支(或通常具有上游等效项)。)


Git 2.13(2017 年第二季度)使用更通用的 ref-filter API 和更完整的git for-each-ref push

commit 3d9e4cecommit 949af06commit 56b4360commit 6eac70fcommit 1a34728commit 1a0ca5ecommit 3a42980commit 17938f1commit 3ba308ccommit 01f9582commit b180e6f,@987654338 @、commit 7743fcccommit ffd921dcommit 99c6a71commit d4919bbcommit 42d0eb0commit 4f3e3b3commit c58fc85(2017 年 1 月 10 日)Karthik Nayak (KarthikNayak)
(由@98765 合并@in commit 93e8cd8,2017 年 2 月 27 日)

push:

本地引用的名称,代表所显示引用的@{push} 位置。
尊重 :short:lstrip:rstrip:track:trackshort 选项,就像 upstream 一样。
如果没有配置@{push} ref,则生成一个空字符串。

如果附加了lstrip=&lt;N&gt; (rstrip=&lt;N&gt;),则从引用名的前(后)去除&lt;N&gt; 斜线分隔的路径组件
(例如,%(refname:lstrip=2)refs/tags/foo 变成 foo%(refname:rstrip=2)refs/tags/foo 变成 refs)。

如果&lt;N&gt; 是负数,则从指定的一端剥离尽可能多的路径组件,以留下-&lt;N&gt; 路径组件
(例如%(refname:lstrip=-2)refs/tags/foo 变成tags/foo%(refname:rstrip=-1)refs/tags/foo 变成refs


原始答案(2014 年)

Git 1.9/2/0(2014 年第一季度)将提供另一种方式。
commit b28061c 来自Ramkumar Ramachandra (artagnon)

for-each-ref:介绍%(upstream:track[short])

介绍:

  • %(upstream:track) 显示“[ahead M, behind N]”和
  • %(upstream:trackshort) 适当地显示“=”、“&gt;”、“&lt;”或“&lt;&gt;”(灵感来自contrib/completion/git-prompt.sh)。

现在您可以在 for-each-ref 中使用以下格式:

%(refname:short) %(upstream:trackshort)

显示带有简洁跟踪信息的参考。

请注意,:track:trackshort 仅适用于“upstream”,与其他任何内容一起使用时会出错。


在 Git 2.30(2021 年第一季度)之前,提交和标记对象可能在每一行的末尾都有 CR(您可以使用 hash-object 或使用 --cleanup=verbatim 创建这样的对象来拒绝默认清理action),但它不可能有一个空行来分隔邮件的标题和正文。

宽容一点,也可以接受带有单独 CR 的行作为空行。

参见commit e2f8958commit 9f75ce3(2020 年 10 月 29 日)Philippe Blain (phil-blain)
(由 Junio C Hamano -- gitster -- 合并到 commit 4c7eb63,2020 年 11 月 9 日)

ref-filter:在行尾更优雅地处理 CRLF

帮助者:Junio C Hamano
帮助者:Eric Sunshine
签字者:Philippe Blain

引用过滤器代码无法正确处理使用 CRLF 作为行终止符的提交或标记消息。

可以使用 git commit(man)git tag(man)--cleanup=verbatim 选项创建此类消息,或者使用直接git commit-tree(man)

ref-filter.c 中的函数 find_subpos 查找两个连续的 LF 来查找主题行的结尾,而使用 CRLF 的消息中不存在这个序列。
这会导致整个邮件被解析为主题行 (%(contents:subject)),而邮件正文 (%(contents:body)) 为空。

此外,copy_subject 中想要将主题作为单行返回,'\n' 被替换为空格,但 '\r' 未触及。

这会影响git branch(man)git tag(man)git for-each-ref(man) 的输出) `.

此行为是 git branch --verbose(man) 的回归,它平分至 949af0684c(“branch:使用 ref-filter 打印 API”,2017-01- 10、Git v2.13.0-rc0——merge列在batch #1)。

通过强化copy_subjectfind_subpos 中的逻辑以正确解析包含CRLF 的消息,将ref-filter 代码调整为更宽松。

【讨论】:

  • 有没有办法限制它只显示%(push:track) 不为空的分支?
  • 我发现这个问题是one I asked 的建议副本,所以我修改了自己的问题。
  • 请注意,如果您使用 push.defaultcurrent(用于分散工作流)并期望状态反映 origin 上的远程分支,则 push:track 不是正确的解决方案。在这种情况下,upstream:track 将是正确的解决方案,假设您的跟踪分支设置为远程 origin 上的相应分支。
  • 我用它来快速检查我可以安全删除哪些本地分支,但是这个脚本根本没有表明一个分支只是本地的并且还没有被推送(即使它已经提前提交)。是否可以更改此脚本以便也显示此信息?
  • @Episodex 你的意思是 2.5+ git for-each-ref 命令吗?它只会显示本地分支的上游分支。
猜你喜欢
  • 2018-06-25
  • 2016-11-08
  • 2021-02-26
  • 2013-12-24
  • 1970-01-01
  • 2019-03-02
  • 2018-12-12
  • 1970-01-01
  • 2017-08-20
相关资源
最近更新 更多