I type git tag
and it lists my current tags:
1.2.3
1.2.4
How can I determine which of these is annotated, and which is lightweight?
git for-each-ref
tells you what each ref is to by default, its id and its type. To restrict it to just tags, do git for-each-ref refs/tags
.
[T]he output has three fields: The hash of an object, the type of the object, and the name in refs/tags that refers to the object. A so-called "lightweight" tag is a name in refs/tags that refers to a
commit
¹ object. An "annotated" tag is a name in refs/tags that refers to atag
object.- Solomon Slow (in the comments)
Here is an example:
$ 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
with some format:
$ 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
To do this for just one ref, you can use git cat-file
-t
on the local ref, to continue the example:
$ git cat-file -t v1.0-light
commit
$ git cat-file -t v1.1-annot
tag
¹ tags can refer to any Git object, if you want a buddy to fetch just one file and your repo's got a git server, you can git tag forsam :that.file
and Sam can fetch it and show it. Most of the convenience commands don't know what to do with tagged blobs or trees, but the core commands like update-index and such do
commit
or a tag
. I presume those indicate lightweight and annotated tags respectively?
Commented
Apr 17, 2017 at 18:49
commit
object. An "annotated" tag is a name in refs/tags that refers to a tag
object.
Commented
May 30, 2018 at 17:26
The git show-ref -d --tags
command sort of does it, since lightweight tags occur once in the output, and annotated tags occur twice. Also, only annotated tags include the "^{}" dereference operator in the output.
588e9261795ec6dda4bd0a881cf1a86848e3d975 refs/tags/1.2.3
7fe2caaed1b02bb6dae0305c5c0f2592e7080a7a refs/tags/1.2.4
588e9261795ec6dda4bd0a881cf1a86848e3d975 refs/tags/1.2.4^{}
And that output can than be massaged with the unix sort, sed, cut, and uniq commands to make the output more readable:
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 /'
For my original repo (from my question) it outputs this:
lw 1.2.3
a 1.2.4
(e.g., 1.2.3 was "lightweight" and "1.2.4" was annotated).
Get the tag name (say foo
) and then do a git cat-file -t foo
. If it's an an annotated tag, cat-file
will tell you that it's a "tag". If it's a simple tag, cat-file
will tell you that it's a "commit".
Update: As oxymoron said in his comment, git show
works too but it gives you more information than just what kind of tag it is.
git cat-file -p foo
to see the difference and the message + meta
Please try using git describe
https://git-scm.com/docs/git-describe
By default (without --all or --tags) git describe only shows annotated tags.
--first-parent
but anyway: this was not the question to get the latest tag but the question was if a specific one is annotated or not so @Oxymoron your answer doesn't match either, because it only can show you the latest annotated in best case but not lists you which of all tags is annotated or not
Commented
May 12, 2023 at 10:20
git describe
against the output of git tag
to get the information they were looking for. I can't say for certain but I appreciate you pointing this out. I admit I could have done a better job at that. My answer was posted 9 minutes after the question, so I was prob competing
In case someone is interested in checking a single tag, you can just do git show <tag-name>
and if the tag is lightweight, the output will look exactly like for a regular commit:
commit <hash> (<tags>, <branches>)
Author: John Doe <[email protected]>
Date: Wed Apr 12 22:29:20 2023 +0200
The message of the actual commit...
But if it is annotated, the output will start like below, followed by the commit info.
tag <tag-name>
Tagger: John Doe <[email protected]>
Date: Wed Apr 12 22:29:20 2023 +0200
The message of the annotated tag...
git tag -n
do anything for you?