Subject: Re: Strange annotated tag issue

From: Ævar Arnfjörð Bjarmason <[email-masked]>
Date: Mon, 25 Mar 2019 20:19:25 +0100

On Mon, Mar 25 2019, Jeff King wrote:

> On Mon, Mar 25, 2019 at 08:50:14AM -0500, Robert Dailey wrote:
>
>> On Thu, Mar 21, 2019 at 2:29 PM Jeff King <[email-masked]> wrote:
>> > Tags can point to any object, including another tag. It looks like
>> > somebody made an annotated tag of an annotated tag (probably by
>> > mistake, given that they have the same tag-name).
>> [..]
>> Thanks for explaining. This is very helpful. Am I naive to think that
>> this should be an error? I haven't seen a valid _pragmatic_ use for
>> tags pointing to tags. In 100% of cases (including this one), it is
>> done out of error. As per your example, users try to "correct" an
>> annotated tag pointing at a wrong tag or commit. What they expect is
>> the tag to point to the other tag's commit, but that's not what they
>> get.
>
> I don't think I've ever seen a tag-to-a-tag in the wild, but I wouldn't
> be surprised if somebody has found a use for it. For example, because
> tags can be signed, I can make a signature of your signature, showing a
> cryptographic chain of custody.
>
> And at any rate, it has been allowed in the data model for almost 15
> years, so I think disallowing it now would be a bad idea. It might be
> acceptable to introduce a safety valve into the porcelain, though.
>
>> From a high-level, pragmatic perspective, doesn't it make more sense
>> to change the git behavior so that annotated tags may only point to
>> commit objects? And in the `git tag -f -m outer mytag mytag` case in
>> your example, this would automatically perform `mytag^{}` to ensure
>> that the behavior the user expects is the behavior they get?
>
> I think "just commits" is too restrictive. linux.git contains a tag of a
> tree, for example (we also have tags pointing to blobs in git.git, but
> they are not annotated).
>
> However, I could see an argument for the git-tag porcelain to notice a
> tag-of-tag and complain. Probably peeling the tag automatically is a bad
> idea, just because it behaved differently for so long. But something
> like might be OK:

Sounds good!

>   $ git tag -a mytag
>   error: refusing to make a recursive tag
>   hint: The object 'mytag' referred to by your new tag is already a tag.
>   hint:
>   hint: If you meant to create a tag of a tag, use:
>   hint:
>   hint:  git tag -a -f mytag
>   hint:
>   hint: If you meant to tag the object that it points to, use:
>   hint:
>   hint:  git tag -a mytag^{}
>
> It would be a minor annoyance to somebody who frequently makes
> tags-of-tags, but it leaves them with an escape hatch.

Let's call that something like --allow-recursive-tag (inspired by
'merge' --allow-unrelated-histories) so we don't confuse the desire to
create such a tag with clobbering an existing tag (which -f is
documented to do).

I was going to say "let's make the 'error:' part self-explanatory
without the 'hint:'" part, in case the advice was disabled. But looking
we only allow turning advice off on a per-variable basis, so I suspect
if someone bothered to do that they know about this already. Our
--allow-recursive-tag message is also fairly cryptic (and should, but
doesn't have, advice).