在有足够的Git现代(你清楚这里)的git branch
和git tag
上市品种(甚至包括--contains
等)都只是git for-each-ref
专业化,分别运行在refs/heads/
和refs/tags/
名字空间。
既然git for-each-ref
是一个管道命令,但是,您可以使用它来编写一个脚本来执行任何您喜欢的操作。我们需要一点时间。
大多数你想要的是直接编码在for-each-ref
的%
指令。由于您的git tag
已经足够现代,可以首先使用--format
,您可以直接使用git tag
直接用于大多数情况。无论如何,值得仔细研究the git for-each-ref
documentation,因为--format
指令非常复杂。
代替%(objectname:short)
,您可以使用%(*objectname:short)
来获取标签的目标(*
操作仅适用于带注释的标签对象,对其他对象不可操作)。
一个非常困难的问题是列对齐。有一个%(align:position,width)
指令(从Git 2.8开始)负责处理大部分问题。 (如果你愿意的话,可以拼出以此为%(align:position=num,width=num)
。)由于您的中间列,缩短的OID,是固定宽度,我们只需要一个%align
:
git tag --format '%(align:1,20)%(color:green)%(refname:short)%(end)
%(color:white)%(*objectname:short) %(contents:subject)'
(我打破了这成两行显示的目的)。这里的一个obvoius问题是:我们从哪里得到魔法常数20?
答案是,它只是一个WAG。如果您想计算正确的数字,我们需要两次传递:一个用于计算任何标签的最大宽度,另一个用于显示标签。 “计数的最大宽度”是我们真正需要的git for-each-ref
,因为我们需要一点shell脚本:
# 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
}
}
(需要注意的是,不像其他一些情况下,我们并不需要对refs/tags
结尾的斜线。参数git for-each-ref
不是一个真正疼在这里,它只是不必要的)现在我们可以这样做:
width=$(max_tag_len)
git tag --format "%(align:1,$width)%(color:green)..."
在这种情况下,你必须插入一个明确的空间,因为我们至少有一个标记,完全填充柱。一点壳算术提供了一个替代方案:
width=$(($(max_tag_len) + 1))
使用无论你认为最清楚。
谢谢,这就是我担心的事情;)您可以使用独特的分隔符(例如'|')跳过'max_tag_len',然后管道到'column -ts'|''。虽然使用颜色似乎弄得有点... –
我注意到的一个问题是同时使用'{un,}带注释的标签,在这种情况下事情变得非常混乱。特别是,如果只是为了好玩,你会对注释标签进行注释... –