git branch -avv
显示所有分支(包括远程分支),使用跟踪分支,短SHA和提交标题进行装饰。是否有一个类似的命令来显示所有标签以及它们指向的提交,可选地包括它是否被推送到上游,另外还有消息,如果标签被注释了吗?
迄今为止我能做的最好的是:
git tag --format '%(color:green)%(refname:short)%09%(color:white)%(objectname:short) %(contents:subject)'
但这有几个问题:
%09
(\t
)对齐失败%(objecttype)
将其显示为commit
或tag
,但我更喜欢下一行标记注释之类的内容)%(objectname:short)
原来是带注释标签的标签的 SHA,而我想知道它们指向的是什么。最后两个归结为基本上想要git show-refs --tags -d
显示的内容,但不提供--format
。
答案 0 :(得分:2)
在一个足够现代的Git(你明显在这里),git branch
和git tag
(甚至包括--contains
等)的列表变体只是{{1的特化},分别遍历git for-each-ref
和refs/heads/
名称空间。
由于refs/tags/
是一个管道命令,因此您可以使用它编写一个可以执行任何操作的脚本。我们马上就会需要这个。
您想要的大部分内容都可以在git for-each-ref
的{{1}}指令中直接编码。由于您的for-each-ref
足够现代,可以首先使用%
,因此无论如何您都可以直接使用git tag
。但无论如何,值得仔细研究the git for-each-ref
documentation,因为--format
指令非常复杂。
而不是git tag
,您可以使用--format
来获取标记的目标(%(objectname:short)
操作仅适用于带注释的标记对象,它是其他对象上的无操作)
一个特别困难的问题是列对齐。有一个%(*objectname:short)
指令(自Git 2.8起)可以处理大部分问题。 (如果您愿意,可以将其拼写为*
。)由于您的中间列(缩短的OID)是固定宽度,因此我们只需要一个%(align:position,width)
:
%(align:position=num,width=num)
(我把它分成两行用于显示目的)。这里的一个obvoius问题是:我们从哪里得到魔法常数20?
答案是,这只是一个WAG。如果你想计算 正确的号码,我们需要两个通道:一个用于计算任何标签的最大宽度,另一个用于显示标签。 “计算最大宽度”是我们真正需要%align
的地方,因为我们需要一些shell脚本:
git tag --format '%(align:1,20)%(color:green)%(refname:short)%(end)
%(color:white)%(*objectname:short) %(contents:subject)'
(注意,与其他一些情况不同,我们不需要git for-each-ref
的{{1}}参数上的尾部斜杠。这不是真的在这里受伤,它只是不必要。)现在我们可以做:
# 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
}
}
在这种情况下,您必须插入一个显式空格,因为我们至少有一个完全填充列的标记。一些shell算术提供了另一种选择:
refs/tags
使用您认为最清楚的。