我输入 git tag
命令,它会列出当前的标签:
1.2.3
1.2.4
我如何确定这些中哪一个是已注释的,哪一个是轻量级的?
git for-each-ref
默认情况下会告诉你每个引用的名称,ID和类型。如果只想限制在标签上,可以使用 git for-each-ref refs/tags
。
输出有三个字段:对象的哈希值,对象的类型以及引用该对象的 refs/tags 中的名称。所谓的“轻量级”标签是指引用了一个
commit
¹ 对象的 refs/tags 中的名称。而“注释型”标签是指引用了一个tag
对象的 refs/tags 中的名称。- Solomon Slow(评论中的内容)
以下是一个示例:
$ git for-each-ref refs/tags
902fa933e4a9d018574cbb7b5783a130338b47b8 commit refs/tags/v1.0-light
1f486472ccac3250c19235d843d196a3a7fbd78b tag refs/tags/v1.1-annot
fd3cf147ac6b0bb9da13ae2fb2b73122b919a036 commit refs/tags/v1.2-light
带有一些格式:
$ git for-each-ref \
--format="%(if:equals=tag)%(objecttype)%(then)a %(else)%(if:equals=blob)%(objecttype)%(then)b %(else) %(end)%(end)%(align:20,right)%(refname:short)%09%(objectname:short)%(end)%09%(if:equals=tag)%(objecttype)%(then)@%(object) %(contents:subject)%(else)%(end)" \
--sort=taggerdate \
refs/tags
v1.2-light fd3cf14
b forsam 633de05
a v1.1-annot 1f48647 @1e25186bcf26d260754b6ebf6b236e92eeadc69b annotation comment
v1.0-light 902fa93
如果只针对一个引用进行操作,您可以在本地引用上使用git cat-file
-t
命令来执行,例如:
$ git cat-file -t v1.0-light
commit
$ git cat-file -t v1.1-annot
tag
¹ 标签可以引用 Git 中的任何对象,如果你想让你的朋友只获取一个文件而你的仓库有一个 Git 服务器,你可以使用 git tag forsam :that.file
命令,然后 Sam 就可以获取并显示它了。大多数方便的命令不知道如何处理标记的 blob 或 tree,但是像 update-index 等核心命令则可以。
commit
对象的refs/tags中的名称。而“附注型”标签是指指向tag
对象的refs/tags中的名称。 - Solomon Slowgit show-ref -d --tags
命令可以实现这一点,因为轻量级标签在输出中只出现一次,而带注释的标签会出现两次。此外,只有带注释的标签在输出中包含 "^{}" 解引用运算符。
588e9261795ec6dda4bd0a881cf1a86848e3d975 refs/tags/1.2.3
7fe2caaed1b02bb6dae0305c5c0f2592e7080a7a refs/tags/1.2.4
588e9261795ec6dda4bd0a881cf1a86848e3d975 refs/tags/1.2.4^{}
然后可以使用unix的sort、sed、cut和uniq命令来处理输出,使输出更易读:
git show-ref -d --tags |
cut -b 42- | # to remove the commit-id
sort |
sed 's/\^{}//' | # remove ^{} markings
uniq -c | # count identical lines
sed 's/2\ refs\/tags\// a /' | # 2 identicals = annotated
sed 's/1\ refs\/tags\//lw /'
对于我的原始仓库(来自我的问题),它输出:
lw 1.2.3
a 1.2.4
(例如,1.2.3版本是“轻量级”的,“1.2.4”版本被注释了)。
获取标签名称(例如foo
),然后执行git cat-file -t foo
命令。如果它是一个带注释的标签,cat-file
会告诉你这是一个“tag”。如果它是一个简单标签,cat-file
会告诉您这是一个“commit”。
更新:正如oxymoron在他的评论中所说,git show
也可以使用,但它会提供比只是标签类型更多的信息。
git cat-file -p foo
命令查看差异和消息+元数据。 - kxrgit describe
命令。git describe
只显示带有注释的标签。--first-parent
时才是这样。无论如何,问题不是获取最新标签,而是特定标签是否被注释所以 @Oxymoron 的回答也不对,因为它只能在最好的情况下显示最新的注释,而不能列出所有标签是否被注释 - childno͡.degit describe
与 git tag
的输出进行比较,以获取他们正在寻找的信息。我不能确定,但我感谢你指出这一点。我承认我本可以做得更好。我的答案是在问题发布后9分钟发布的,所以我可能在竞争中。 - Oxymorongit show <tag-name>
即可。如果该标签是轻量级的,则输出将与常规提交完全相同。commit <hash> (<tags>, <branches>)
Author: John Doe <john@doe.com>
Date: Wed Apr 12 22:29:20 2023 +0200
The message of the actual commit...
但如果它被注释了,输出将会以以下方式开始,然后是提交信息。
tag <tag-name>
Tagger: John Doe <john@doe.com>
Date: Wed Apr 12 22:29:20 2023 +0200
The message of the annotated tag...
git tag -n
命令对你有什么作用吗? - Oxymoron