Search code examples
git

show all tags in git log


Why does git log --decorate not display more than one tag per commit?

EDIT: Charles Bailey has come up with the answer (at least in my case)
Essentially, I had one tag that pointed to another tag that pointed to the commit. Because of this extra layer of indirection, the tag wasn't showing up in the log. I'll have to fix this, wither by fixing our tagging script to tag correctly, or by some shell script voodoo to recursively follow tags. Anyway, I'll leave this question up just for reference in case anyone wants it. (I'm new to stack overflow, but I assume that is the correct protocol?)

... Original question follows ...

Backstory: We use GIT at work for source control, and we have a policy of always tagging a commit when we deploy. (It's actually a script that does tags, and then pulls the tag on the server). Since it's a web application with separate staging and production servers, we often tag a release for staging (for testing or whatever), and then later tag the same commit for production.

So it's actually very often that we have multiple tags on the same commit. It would be very nice to be able to see this in the text log, but it doesn't seem to support it. I'm currently working around the issue by manually checking the tag I'm looking for, or by firing up gitk. While both of these solutions work, it seems to me that it's really weird for git log --decorate to only support one tag per commit by default.

I did some googling around, but didn't find much. Am I missing something obvious?

P.S. (I actually use a custom format string with %d, according to the man pages and some quick tests, it's equivalent to --decorate)


Solution

  • Note about tag of tag (tagging a tag), which is at the origin of your issue, as Charles Bailey correctly pointed out in the comment:

    Make sure you study this thread, as overriding a signed tag is not as easy:

    • if you already pushed a tag, the git tag man page seriously advised against a simple git tag -f B to replace a tag name "A"
    • don't try to recreate a signed tag with git tag -f (see the thread extract below)

      (it is about a corner case, but quite instructive about tags in general, and it comes from another SO contributor Jakub Narębski):

    Please note that the name of tag (heavyweight tag, i.e. tag object) is stored in two places:

    • in the tag object itself as a contents of 'tag' header (you can see it in output of "git show <tag>" and also in output of "git cat-file -p <tag>", where <tag> is heavyweight tag, e.g. v1.6.3 in git.git repository),
    • and also is default name of tag reference (reference in "refs/tags/*" namespace) pointing to a tag object.
      Note that the tag reference (appropriate reference in the "refs/tags/*" namespace) is purely local matter; what one repository has in 'refs/tags/v0.1.3', other can have in 'refs/tags/sub/v0.1.3' for example.

    So when you create signed tag 'A', you have the following situation (assuming that it points at some commit)

      35805ce   <--- 5b7b4ead  <=== refs/tags/A
      (commit)       tag A
                     (tag)
    

    Please also note that "git tag -f A A" (notice the absence of options forcing it to be an annotated tag) is a noop - it doesn't change the situation.

    If you do "git tag -f -s A A": note that you force owerwriting a tag (so git assumes that you know what you are doing), and that one of -s / -a / -m options is used to force annotated tag (creation of tag object), you will get the following situation

      35805ce   <--- 5b7b4ea  <--- ada8ddc  <=== refs/tags/A
      (commit)       tag A         tag A
                     (tag)         (tag)
    

    Note also that "git show A" would show the whole chain down to the non-tag object...