2

As seen in this answer, a git annotated tag has several properties, e.g.

> git cat-file -p v0.1

object 5cf4de319291579d4416da8e0eba8a2973f8b0cf
type commit
tag v0.1
tagger JDB <jd@domain.com> 1521058797 -0400

Version 0.1-beat

The first two properties give the SHA1 and type of the target object that the tag is pointing to. The third property gives the tag's name, v0.1.

But this tag is represented as a file .git/refs/tags/v1.0. So we already have a way to map from the string v0.1 to the tag object and its properties. Why would we need the tag object to also include the tag name in its properties? Branches don't store their names. Commits objects don't store their SHA1's. Is there some situation where you'd have a reference to a tag but not to its name?

LarsH
  • 27,481
  • 8
  • 94
  • 152

2 Answers2

4

Apart from your own answer (tag pointing to tag by object ID), other reasons you might want the tag object to store the tag name:

  • If the ref is "loose", then as you say it is stored as .git/refs/tags/v0.1. But it might be packed instead. So if you want to rely on the refs metadata to map the tag name, it's not that easy. (And anyway, mucking around in the .git directory by hand should always be Plan B at best.)

  • The object hash, and in the case of signed tags the signature, would not cover the tag's filename. If you want an assurance that commit 5cf4de319 is what's meant by "v0.1", then you need the tag object to explicitly store that fact.

UPDATE

I'm again not sure if this translates into a "practically important" reason, but here's one more thing to think about:

What, really, is the difference between an annotated tag vs. a lightweight tag pointing to the tag object from an annotated tag? Best answer I have: name mismatch.

Mark Adelsberger
  • 42,148
  • 4
  • 35
  • 52
  • OK. I wasn't referring to mucking around in the `.git` directory by hand ... rather, referring to what git tools would need. Presumably they can map a tag name to its object efficiently even if it's in packed refs. – LarsH Apr 25 '18 at 16:00
  • Regarding the 2nd point, I can see how it would matter for signed tags, so that the name is part of what is being signed. Are you saying that it also matters for unsigned tags? – LarsH Apr 25 '18 at 16:02
  • 2
    @LarsH - I'd say it's not clear cut whether it matters for unsigned tags. Having it in the object makes it part of the tag identity. So as things are, you could have two tags that are absolutely identical except they have different names, and if the tag object didn't store the tag name you couldn't. Does that "matter"? I wouldn't venture to say one way or the other. – Mark Adelsberger Apr 25 '18 at 16:15
  • 1
    I think in the end we'd have to ask Linus for his reasons, but "the tag name is part of the signed identity" (for signed annotated tags) seems like a good reason. – torek Apr 25 '18 at 16:25
  • Mark, when I asked "are you saying that it also matters for unsigned tags," I was thinking of your sentence, 'If you want an assurance that commit 5cf4de319 is what's meant by "v0.1", then you need the tag object to explicitly store that fact.' When "assurance" refers to something robust like signing, then I can see that the tag name has to be part of the signed data. But in the case of unsigned tags, you already have the information that tag `v0.1` refers to commit 5cf4de3, and adding the tag name into the tag object doesn't seem to add any assurance. Unless I missed something? – LarsH Apr 26 '18 at 00:11
  • @LarsH: What requires clarification here? If you want assurances, you use signed tags. The fact that this sentence was more specific does not change the point that both the signature AND the commit ID would be less informative if the tag object didn't store the name. As of now, counting your own point about tags pointing to tags we've identified five potentially meaningful consequences of including the tag name in the object content. At least 3 of those are practical reasons that would convince me if I were designing the software. If you want more than that, then as torek says, ask Linus. – Mark Adelsberger Apr 26 '18 at 12:36
  • "What requires clarification here?" I was trying to understand how "assurance" applied to both unsigned and signed tags, since your bullet said "and in the case of signed tags". But apparently your sentence about assurance only applied to signed tags. Now I understand what you meant. – LarsH Apr 26 '18 at 14:37
  • I wasn't asking for more reasons; I was trying to understand the reasons that you had given. – LarsH Apr 26 '18 at 14:45
2

OK, the answer I referenced in this question also contains a clue to an answer to this question: A tag that points to a tag uses the target tag's SHA1, not its name, as the reference.

So if tag2 is created pointing to tag1, tag2 points to the tag1 object without actually revealing tag1's name. Therefore if any git command or UI has to dereference tag1, it would have no direct way of knowing that the tag it points to is called tag2, if tag2's object didn't contain that information.

Maybe there are other reasons, but that's the one I could think of. Maybe there are other things (besides a tag) that might reference a tag by its SHA1, and therefore need the name of the referenced tag to be supplied by the referenced tag object.

LarsH
  • 27,481
  • 8
  • 94
  • 152