Search code examples
gitgit-tag

How can I tell if a given git tag is annotated or lightweight?


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?


Solution

  • 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 a tag 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