如何列出所有轻量级标签?

时间:2014-01-09 21:10:30

标签: git git-tag

我想在我的存储库中列出所有轻量级标签;我能想到的最好的方法是将git for-each-refgrepcut结合起来,但看起来好像很有点......

(虽然我们在这里,但我们不妨谈论注释标签的相同内容:有人肯定会在某处对此感到疑惑。)

修改

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

3 个答案:

答案 0 :(得分:20)

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

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

或:

git show-ref --tags

对于带注释的标签,嗯,这里的技巧 - 它也会影响“轻量级”标签部分 - 带注释的标签实际上是git存储库中的一个对象,但是,这是一个轻量级的指向该对象的标记,它允许您通过其标记名称获取带注释的标记。 1 所以它实际上是:一个轻量级标签,加上in-repo带注释的标签对象,使它“不是一个轻量级标签”,除了那个顽固的事实,它同时是一个轻量级标签!

因此,它归结为:找到所有轻量级标记,然后可选择只选择指向提交的标记或指向标记对象的标记,具体取决于您想要的行为,然后继续发出标签名称。

git-for-each-ref文档中有一个很长的例子,即在--format字符串中编写完整的脚本并使用eval来执行它(或者你可以管道shgit for-each-ref执行,以一个额外的过程为代价)。我通常发现将while read ...的输出传递到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

可打印所有仅限轻量级标记。

与:比较:

tree

打印所有带注释的标签(或者更准确地说,是“带注释的轻量级”标签)。

请注意,标记可以(可以想象 - 现在没有实际的用例,据我所知)指向除了提交或标记之外的其他内容;您是否要使用直接指向blobannotag的标记执行某些操作。


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

有趣的是,带注释的标签的内部格式包含外部名称,因此可以使用此技术来保护“旧的”带注释的标签,通过删除它们的轻量级标签来隐藏它们,然后再恢复原始的轻量级标签。是否有人可以为此提出使用,但是......: - )

答案 1 :(得分:0)

总结其他答案及其注释(如果您使用的是bash)

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

答案 2 :(得分:0)

仅列出轻量级标签:

git for-each-ref refs/tags | grep commit

要仅列出带注释的标签:

git for-each-ref refs/tags | grep -v commit

说明:

git for-each-ref 列出所有引用:headsremotesstashtags

git for-each-ref refs/tags 仅列出 标签 引用。

| grep commit 只列出那些包含单词 commit 的行。这些是指向提交的标签,因此是轻量级标签。

| grep -v commit 仅列出那些不包含 commit 一词的行。这些是指向标签的标签,因此是带注释的标签。