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

Sam*_*amB 16 git git-tag

我想在我的存储库中列出所有轻量级标签; 我能想到的最好的东西包括结合git for-each-ref,grepcut,但似乎它会有点狡猾......

(虽然我们正在谈论它,但我们不妨谈论注释标签的相同事情:有人肯定会在某处对此感到疑惑.)

编辑:

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

tor*_*rek 21

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

git for-each-ref --format '%(refname:short)' refs/tags/
Run Code Online (Sandbox Code Playgroud)

要么:

git show-ref --tags
Run Code Online (Sandbox Code Playgroud)

至于带注释的标签,诀窍就在这里 - 它影响"轻量级"标签部分 - 是一个带注释的标签实际上是git存储库中的一个对象,但是,有一个指向该对象的轻量级标签,它可以让你通过其标记名称获取带注释的标记.1 所以它实际上是对东西:一个轻量级标签,加上内部回复注释标签对象,使它"不是一个轻量级标签",除了那个顽固的事实,它同时一个轻量级标签!

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

git-for-each-ref文档中编写一个完整的脚本--format并使用eval它来执行它(或者你可以管道sh执行,以一个额外的进程为代价)有一个很长的例子.我通常发现将输出传递git for-each-refwhile read ...循环中更简单:

git for-each-ref refs/tags/ --format '%(objecttype) %(refname:short)' |
    while read ty name; do [ $ty = commit ] && echo $name; done
Run Code Online (Sandbox Code Playgroud)

它会打印所有仅限轻量级的标签.

与之比较:

git for-each-ref refs/tags/ --format '%(objecttype) %(refname:short)' |
    while read ty name; do [ $ty = tag ] && echo $name; done
Run Code Online (Sandbox Code Playgroud)

它打印所有带注释的标签(或更确切地说,"轻量级注释"标签).

请注意,标记可以(可以想象 - 现在没有实际的用例,据我所知)指向除了提交或标记之外的其他内容; 取决于你是否用直接指向tree或的标签做某事blob.


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

有趣的是,带注释的标签的内部格式包含外部名称,因此可以使用此技术来保护"旧的"带注释的标签,通过删除它们的轻量级标签来隐藏它们,然后再恢复原始的轻量级标签.无论任何人都可以想出利用这一点,虽然... :-)

  • 我只需将这些 while 循环替换为 `awk`: `git for-each-ref refs/tags/ --format '%(objecttype) %(refname:short)' | awk '$1 == "标签" {print $2}'` (2认同)

lea*_*ode 13

仅列出轻量级标签:

git for-each-ref refs/tags | grep commit
Run Code Online (Sandbox Code Playgroud)

仅列出带注释的标签:

git for-each-ref refs/tags | grep -v commit
Run Code Online (Sandbox Code Playgroud)

解释:

git for-each-ref列出所有参考:HeadsRemotesStashTags

git for-each-ref refs/tags仅列出标签参考。

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

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