如何获得git-branch -avv之类的标签列表? [英] How to get a git-branch -avv like list of tags?

查看:305
本文介绍了如何获得git-branch -avv之类的标签列表?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

git branch -avv显示所有分支(包括远程分支),并用跟踪分支,短SHA和提交标题来装饰它们.是否有类似的命令来显示所有标签及其指向的提交(可选地包括是否将其推送到上游),以及是否显示标签是否带注释的消息?

git branch -avv shows all branches (including remote ones), decorating them with the tracking branch, short-SHA and commit title. Is there a similar command to display all tags together with the commit they point to, optionally including whether it is pushed upstream, and additionally with the message if the tag was annotated?

到目前为止,我能得到的最好的是:

The best I could get so far is:

git tag --format '%(color:green)%(refname:short)%09%(color:white)%(objectname:short) %(contents:subject)'

但这有几个问题:

  • 取决于标签长度,通过%09(a \t)的对齐失败
  • 无法查看标签是否轻巧(%(objecttype)将其显示为committag,但我希望在下一行添加类似标签注释的内容)
  • %(objectname:short)原来是带注释的标签的标签的 SHA,而我想知道它们指向的内容.
  • Depending on tag-length, the alignment via %09 (a \t) fails
  • No way to see whether the tag is lightweight or not (%(objecttype) displays this as either commit or tag, but I'd prefer something like the tag annotation on the next line)
  • %(objectname:short) turns out to be the tag's SHA for annotated tags, whereas I want to know what they are pointing to.

这最后两个归结为基本上想要git show-refs --tags -d所显示的内容,但是并没有提供--format.

These last two boil down to basically wanting what git show-refs --tags -d shows, but that doesn't offer --format.

推荐答案

在足够现代的Git(您显然在这里拥有)中,git branchgit tag(甚至包括--contains等)的列表品种)只是git for-each-ref的特化,分别在refs/heads/refs/tags/命名空间上运行.

In a sufficiently modern Git (which you clearly have here), the listing varieties of git branch and git tag (even including --contains and the like) are just specializations of git for-each-ref, run over the refs/heads/ and refs/tags/ name spaces respectively.

但是,由于git for-each-ref是管道命令,因此您可以使用它来编写执行所需操作的脚本.我们稍后将需要它.

Since git for-each-ref is a plumbing command, though, you can use it to write a script that does anything you like. We will need this in a moment.

您想要的大多数内容都可以直接在for-each-ref%指令中进行编码.由于git tag具有足够的现代性,因此可以将--format放在首位,因此无论如何,您都可以直接将git tag直接使用.无论如何,值得认真研究

Most of what you want is directly encode-able in for-each-ref's % directives. Since your git tag is modern enough to take --format in the first place, you can just use git tag directly for most of this anyway. In any case, though, it's worth carefully studying the git for-each-ref documentation as the --format directives are surprisingly complex.

您可以使用%(*objectname:short)代替%(objectname:short)来获取标签的目标(*操作仅适用于带注释的标签对象,对其他对象不起作用).

Instead of %(objectname:short), you can use %(*objectname:short) to get the target of the tag (the * action only applies to annotated tag objects, it's a no-op on other objects).

一个特别困难的问题是列对齐.有一个%(align:position,width)指令(自Git 2.8起)可以解决大部分问题. (如果愿意,可以将其拼写为%(align:position=num,width=num).)由于中间列(缩短的OID)是固定宽度,因此我们只需要一个%align:

The one extra-difficult problem is column alignment. There is a %(align:position,width) directive (since Git 2.8) that takes care of most of the issue. (You can spell this as %(align:position=num,width=num) if you prefer.) Since your middle column, the shortened OID, is fixed width, we need only one %align:

git tag --format '%(align:1,20)%(color:green)%(refname:short)%(end)
%(color:white)%(*objectname:short) %(contents:subject)'

(出于显示目的,我将其分为两行).这里的一个obvoius问题是:我们从何处获得了魔法常数20?

(I broke this into two lines for display purposes). The one obvoius issue here is: Where did we get the magic constant 20?

答案是,这只是一个WAG.如果您想计算 正确数字,我们需要进行两次操作:一次计算任何标签的最大宽度,第二次显示标签.我们真正需要git for-each-ref的地方是计算最大宽度",因为我们需要一些shell脚本:

The answer is, it was just a WAG. If you'd like to compute the correct number, we need two passes: one to count the maximum width of any tag, and a second to display the tags. The "count the max width" is where we really need git for-each-ref, as we need a bit of shell scripting:

# Output the length of the longest tag.  If there are no tags,
# print 0 (most logically correct but some callers might want 1;
# consider making a minimum output value an argument, which is
# trivial to do: initialize longest with "${1-0}" instead of just
# "0").
max_tag_len()
{
    local longest=0 name len

    git for-each-ref --format='%(refname:short)' refs/tags | {
        while read name; do
            len=${#name}
            [ $len -gt $longest ] && longest=$len
        done
        echo $longest
    }
}

(请注意,与其他一些情况不同,我们不需要在git for-each-refrefs/tags参数上使用尾部斜杠.并不是真的会伤害到这里,这是没有必要的.)现在我们可以这样做:

(Note that, unlike some other cases, we don't need a trailing slash on the refs/tags argument to git for-each-ref. Not that one actually hurts here, it's just unnecessary.) Now we can do:

width=$(max_tag_len)
git tag --format "%(align:1,$width)%(color:green)..."

在这种情况下,您必须插入一个明确的空格,因为我们至少有一个标签可以完全填满该列.一些Shell算术提供了一种替代方法:

In this case you must insert an explicit space, since we have at least one tag that completely fills the column. A bit of shell arithmetic provides an alternative:

width=$(($(max_tag_len) + 1))

使用您认为最清楚的那个.

Use whichever you think is clearest.

这篇关于如何获得git-branch -avv之类的标签列表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆