Git 如何列出所有轻量级标记?

Git 如何列出所有轻量级标记?,git,git-tag,Git,Git Tag,我想列出我的存储库中的所有轻量级标记;我能想到的最好的方法是为每个ref组合git、grep和cut,但这似乎有点复杂 (当我们讨论这个问题时,我们不妨讨论带注释的标记的相同问题:肯定有人会在某个时候对此感到疑惑。) 编辑: 通过lightweight标记,我指的是那些不引用标记对象的标记引用。(换句话说,是未注标记。)所有轻量级标记都位于refs/tags/名称空间中,并且可以使用枚举,例如: git for-each-ref --format '%(refname:short)' refs/

我想列出我的存储库中的所有轻量级标记;我能想到的最好的方法是为每个ref组合
git、
grep
cut
,但这似乎有点复杂

(当我们讨论这个问题时,我们不妨讨论带注释的标记的相同问题:肯定有人会在某个时候对此感到疑惑。)

编辑:


通过
lightweight
标记,我指的是那些不引用标记对象的标记引用。(换句话说,是未注标记。)

所有轻量级标记都位于
refs/tags/
名称空间中,并且可以使用枚举,例如:

git for-each-ref --format '%(refname:short)' refs/tags/
或:

至于带注释的标记,它影响“轻量级”标记部分的诀窍也是,带注释的标记实际上是git存储库中的一个对象,但是,有一个轻量级标记指向该对象,它让您可以通过标记名获取带注释的标记。1所以它实际上是一对东西:轻量级标记,再加上in-repo注释的标记对象,这使得它“不是一个轻量级标记”,除了它同时也是一个轻量级标记这一顽固事实之外

因此,它归结为:找到所有轻量级标记,然后根据您想要的行为选择仅指向提交的标记或指向标记对象的标记,然后继续发出标记名

git的每个ref
文档中都有一个很长的例子,就是用
--format
字符串编写一个完整的脚本,并使用
eval
执行它(或者你可以通过管道到
sh
执行,代价是一个额外的过程)。我通常发现,在读取时将每个ref的
git的输出通过管道传输到
中更简单…
循环:

git for-each-ref refs/tags/ --format '%(objecttype) %(refname:short)' |
    while read ty name; do [ $ty = commit ] && echo $name; done
它只打印所有轻量级标签

与之相比:

git for-each-ref refs/tags/ --format '%(objecttype) %(refname:short)' |
    while read ty name; do [ $ty = tag ] && echo $name; done
它打印所有带注释的标签(或者更准确地说,“带注释的轻量级”标签)

请注意,标记可以(据我所知,目前还没有实际的用例)指向除提交或标记以外的其他对象;由您决定是否使用直接指向
树的标记或
blob


1如果没有轻量级标记,您将无法使用名称
annotag
引用带注释的标记
annotag
——至少要经历
git fsck
用于查找悬挂对象的所有搜索工作。此外,如果删除轻量级标记,带注释的标记对象可能会被垃圾收集。您可以使一个标记对象指向另一个标记对象,以将其保留在repo中(即禁止gc),而无需为第二个标记对象指定外部名称,只要第一个标记对象具有外部名称。但这绝对是件奇怪的事


有趣的是,注释标记的内部格式包含外部名称,因此可以使用此技术来保护“旧”注释标记,通过移除其轻量级标记来隐藏它们,然后恢复原始轻量级标记。不过,是否有人能想出这个用途…:-)

所有轻量级标记都位于
refs/tags/
命名空间中,可以使用枚举,例如:

git for-each-ref --format '%(refname:short)' refs/tags/
或:

至于带注释的标记,它影响“轻量级”标记部分的诀窍也是,带注释的标记实际上是git存储库中的一个对象,但是,有一个轻量级标记指向该对象,它让您可以通过标记名获取带注释的标记。1所以它实际上是一对东西:轻量级标记,再加上in-repo注释的标记对象,这使得它“不是一个轻量级标记”,除了它同时也是一个轻量级标记这一顽固事实之外

因此,它归结为:找到所有轻量级标记,然后根据您想要的行为选择仅指向提交的标记或指向标记对象的标记,然后继续发出标记名

git的每个ref
文档中都有一个很长的例子,就是用
--format
字符串编写一个完整的脚本,并使用
eval
执行它(或者你可以通过管道到
sh
执行,代价是一个额外的过程)。我通常发现,在读取时将每个ref的
git的输出通过管道传输到
中更简单…
循环:

git for-each-ref refs/tags/ --format '%(objecttype) %(refname:short)' |
    while read ty name; do [ $ty = commit ] && echo $name; done
它只打印所有轻量级标签

与之相比:

git for-each-ref refs/tags/ --format '%(objecttype) %(refname:short)' |
    while read ty name; do [ $ty = tag ] && echo $name; done
它打印所有带注释的标签(或者更准确地说,“带注释的轻量级”标签)

请注意,标记可以(据我所知,目前还没有实际的用例)指向除提交或标记以外的其他对象;由您决定是否使用直接指向
树的标记或
blob


1如果没有轻量级标记,您将无法使用名称
annotag
引用带注释的标记
annotag
——至少要经历
git fsck
用于查找悬挂对象的所有搜索工作。此外,如果删除轻量级标记,带注释的标记对象可能会被垃圾收集。您可以使一个标记对象指向另一个标记对象,以将其保留在repo中(即禁止gc),而无需为第二个标记对象指定外部名称,只要第一个标记对象具有外部名称。但这绝对是件奇怪的事


有趣的是,注释标记的内部格式包含外部名称,因此可以使用此技术来保护“旧”注释标记,通过移除其轻量级标记来隐藏它们,然后恢复原始轻量级标记。不过,是否有人能想出这个用途…:-)

如果您使用的是bash,则总结其他答案及其注释:

function git-lightweight-tags() { 
    git for-each-ref refs/tags/ --format '%(objecttype) %(refname:short)' | awk '$1 == "commit" {print $2}' ; 
}

总结另一个答案及其注释(如果您使用的是bash):

function git-lightweight-tags() { 
    git for-each-ref refs/tags/ --format '%(objecttype) %(refname:short)' | awk '$1 == "commit" {print $2}' ; 
}

仅列出lightwei