git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jeff King <peff@peff.net>
To: Matthias Andree <matthias.andree@gmx.de>
Cc: Junio C Hamano <gitster@pobox.com>,
	git@vger.kernel.org, Erik Faye-Lund <kusmabite@gmail.com>
Subject: Re: git-tag bug? confusing git fast-export with double tag objects
Date: Thu, 14 May 2009 14:22:49 -0400	[thread overview]
Message-ID: <20090514182249.GA11919@sigill.intra.peff.net> (raw)
In-Reply-To: <op.utwyczlf1e62zd@merlin.emma.line.org>

On Thu, May 14, 2009 at 11:37:37AM +0200, Matthias Andree wrote:

> HOWEVER, I see two problems here (yes, they are corner cases):
>
> #1: git tag -f ("replace tag") fails to "replace" a heaviweight tag if I  
> try to replace a tag by itself (or create a cycle by some other means).
>
> The new "foo" is unique in refs (OK), but it's *not unique* in objects  
> (FAIL), as the old "foo" is referenced by the new "foo" and bears the same 
> tag name.
>
> It screws the repo, breaking the uniqueness of tags. Basically, git tag -f 
> is implementing a half-baked, non-working "rebase tag objects"  
> functionality.

Can you explain how this "screws the repo"? The refs are unique, and in
your examples, a tag object replaced by "git tag -f" no longer has a ref
pointing to it (but in your example of making a tag of a tag, then of
course the original is still reachable indirectly). The "unique in
objects" you refer to is that the tag itself says "here is the name
under which I was tagged". That name is purely informative and has
nothing to do with ref lookup or reachability.

In your examples, I don't see any behavior that is causing actual
problems.

> #2: related: git tag -d cannot reliably delete tag objects
>
> Same here: if another tag object references the tag object I'm deleting,  
> we only delete the ref, but not the tag object. It doesn't (cannot) become 
> dangling.

Deleting the ref makes it dangling, unless something else is referencing
it. In your examples, since you tag the tag, the original tag is still
referenced.

> $ git rev-list --objects --all
> 4481a15d999b1b13066fe932e35ea05b8b1027a6
> 72f3463f5a8089ac91001d458ceffb6d4e1056ee foo
> 2e326d8a210536b7cd1f2bc77e3e29d7231f9ec4 foo
> 995773fc9b649922936e110207e6abb904cc18e8
> 15a9779d8f787428e57830410c7842e5449dfd33 a

The right-hand side of this output is a purely informative "here is a
name that may be useful for packing heuristics". It has nothing to do
with the refs (for blobs, the pathname through which we reached the blob
will be printed -- obviously this is not going to be unique, as you will
have many versions of each file).

> So what we get is (root/parents first, then children):
>
> objects:  4481a1 (commit) <- 2e326d (tag "foo") <- 72f346 (tag "foo")
> refs:     heads/master                             tags/foo
>
> Whoops. "foo" is there twice, and it's referenced from a current ref.
> We have *not* *replaced* it. *If* we did, we should have got:
>
> objects:  4481a1 (commit) <- 72f346 (tag "foo")
> refs:     heads/master       tags/foo
> with a dangling tag 2e326d

Right. Because you didn't ask to replace it. You asked to tag the tag.

> Hu, there's a nice cycle:
>
> 69bf (commit) <- 9756 ('old' tag1) <- 38ae (tag2) <- 8e7a (tag1)

You keep calling these cycles, but they're not (at least in terms of the
git graph). The fact that two distinct objects both contain the string
"tag tag1" is not any more a cycle than two commit objects with the same
commit message. They are both distinct objects with distinct hashes, and
the hashes are how the git graph is built.

> Now, more fun - watch the inconsistency:
>
> $ git tag -d tag1
> Deleted tag 'tag1'
> $ git tag -d tag1
> error: tag 'tag1' not found.

OK, so you deleted the ref tag1.

> Ha! As if... now watch this:
> $ git rev-list --objects  --all | while read a b ; do echo "$a $(git  
> cat-file -t $a) $b" ; done
> 69bf327c5d172fc8e4f63acf4d2e01c474824ce4 commit
> 38aea56fec319d8c259a80157dde2432d2d09b2b tag tag2
> 9756f6fa98a5cce2aab1f6a6e7dd4de515626e19 tag tag1
> d758baa57a7ef20d44df0535bef1a91bb3dc4f62 tree
> d3d8863b140f43f7c07050b9f2e210d41e73edb1 blob otherfile
>
> The tag object "tag1" is still there. WHOOPS!!!

Of course the _old_ tag1 is still there. It is referenced by tag2, which
still has a ref. Again you are confusing the right-hand side of "git
rev-list --objects" with actual ref names.

> I appreciate that this isn't trivial to solve, but I presume anything that 
> walks the object database and uses tags can fail - including, but not  
> limited to, git fast-export.

I am not ruling out the possibility that there is some piece of code
that will be confused by the situation you have created, but it has
nothing to do with graph walking. It would have to be a piece of code
which cares about the uniqueness of informative names inside tag
objects.

-Peff

  parent reply	other threads:[~2009-05-14 18:23 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-05-14  0:53 git-tag bug? confusing git fast-export with double tag objects Matthias Andree
2009-05-14  2:13 ` Matthias Andree
2009-05-14  3:18   ` Junio C Hamano
2009-05-14  9:37     ` Matthias Andree
2009-05-14 12:00       ` Michael J Gruber
2009-05-14 12:16       ` Alex Riesen
2009-05-14 12:51         ` Matthias Andree
2009-05-14 13:16           ` Alex Riesen
2009-05-14 13:39             ` Matthias Andree
2009-05-14 13:42               ` Sverre Rabbelier
2009-05-14 18:02                 ` Matthias Andree
2009-05-14 19:01                   ` Brandon Casey
2009-05-14 18:22       ` Jeff King [this message]
2009-05-14 22:35         ` Matthias Andree
2009-05-15  2:02           ` Jeff King
2009-05-15 12:23             ` Matthias Andree
2009-05-15 13:22               ` Jakub Narebski
2009-05-15 14:54                 ` Johannes Sixt
2009-05-15 15:51                   ` Alex Riesen
2009-05-15 16:14                     ` Matthias Andree
2009-05-15 16:21                     ` Andreas Ericsson
2009-05-15 17:40                       ` Junio C Hamano
2009-05-16  7:14                         ` Andreas Ericsson
2009-05-16  7:56                           ` Jakub Narebski
2009-05-16  8:02                             ` Andreas Ericsson
2009-05-16 17:16                           ` Junio C Hamano
2009-05-19 11:21                             ` Matthias Andree
2009-05-19 11:29                               ` Jeff King
2009-05-16  5:07               ` Jeff King
2009-05-15 16:00       ` Daniel Cheng

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20090514182249.GA11919@sigill.intra.peff.net \
    --to=peff@peff.net \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=kusmabite@gmail.com \
    --cc=matthias.andree@gmx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).