From: Michael J Gruber <git@drmicha.warpmail.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:00:25 +0200 [thread overview]
Message-ID: <4A0C07D9.8030401@drmicha.warpmail.net> (raw)
In-Reply-To: <op.utwyczlf1e62zd@merlin.emma.line.org>
Matthias Andree venit, vidit, dixit 14.05.2009 11:37:
> Am 14.05.2009, 05:18 Uhr, schrieb Junio C Hamano <gitster@pobox.com>:
>
>> "Matthias Andree" <matthias.andree@gmx.de> writes:
>>
>>> Am 14.05.2009, 02:53 Uhr, schrieb Matthias Andree
>>> <matthias.andree@gmx.de>:
>>>
>>>> 2. how do I trash the accidentally created 2nd "baz" tag object,
>>>> i. e. remove it from the (packed) object database? Of course, I can
>>>> hack some script (or use a text editor) to grind this
>>>> git-fast-export into shape and re-importing it...
>>>
>>> OK, that worked: I traced (with git cat-file) the tree through all
>>> tagged tag until the first tagged commit, and hack packed-refs (or
>>> refs/tags/foo) to point to the commit object, and afterwards prune
>>> the dangling tag.
>>>
>>> However, the other questions remain. I'd think git tag should
>>> dereference its 2nd non-option argument to a commit before laying
>>> down the tag...
>>
>> No. You can tag any object, and a tag is an object. You can point a
>> signed tag with your own signed tag to attest your own belief on that
>> other guy's tag, be it "it's genuine", "the tagged commit suits my need",
>> etc.
>
> OK, so I can tag/sign any object, fine.
>
> 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.
>
>
>
> #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.
>
>
>
> Watch:
>
> $ cd $(mktemp -d)
> $ git init
> Initialized empty Git repository in /tmp/tmp.GBjHED4Xj8/.git/
> $ date >a
> $ git add a
> $ git commit -m "new file a" -a
> [master (root-commit) 4481a15] new file a
> 1 files changed, 1 insertions(+), 0 deletions(-)
> create mode 100644 a
> $ LANG=C git tag foo -m "add tag foo" -s
> [GPG passphrase query]
> $ LANG=C git tag foo foo -m "add tag foo" -s
> fatal: tag 'foo' already exists
>
> -> this is ok, now let's break uniqueness:
>
> $ LANG=C git tag foo foo -m "add tag foo" -s -f
> [GPG passphrase query]
> $ git rev-list --objects --all
> 4481a15d999b1b13066fe932e35ea05b8b1027a6
> 72f3463f5a8089ac91001d458ceffb6d4e1056ee foo
> 2e326d8a210536b7cd1f2bc77e3e29d7231f9ec4 foo
> 995773fc9b649922936e110207e6abb904cc18e8
> 15a9779d8f787428e57830410c7842e5449dfd33 a
> $ git show-ref
> 4481a15d999b1b13066fe932e35ea05b8b1027a6 refs/heads/master
> 72f3463f5a8089ac91001d458ceffb6d4e1056ee refs/tags/foo
> $ git cat-file tag 72f346
> object 2e326d8a210536b7cd1f2bc77e3e29d7231f9ec4
> type tag
> tag foo
> tagger Matthias Andree <matthias.andree@gmx.de> 1242289836 +0200
>
> add tag foo
> -----BEGIN PGP SIGNATURE-----
> ...
> $
> $ git cat-file tag 2e326d
> object 4481a15d999b1b13066fe932e35ea05b8b1027a6
> type commit
> tag foo
> tagger Matthias Andree <matthias.andree@gmx.de> 1242289732 +0200
>
> add tag foo
> -----BEGIN PGP SIGNATURE-----
> ...
>
>
> 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
>
>> I thought there was a breakage report followed by a fix to the
>> fast-export that mishandled a tag that points at another tag not too
>> long ago. Do you have 1982467 (builtin-fast-export.c: handle nested
>> tags, 2009-03-23)?
>
> I have that beast (how do I QUICKLY check if that is reachable from
> refs/master? git log | grep isn't exactly quick),
"git branch --contains 1982467" gives you all branches which have that.
"git rev-list -1 "master..1982467|wc -l" checks whether 1982467 is
contained in master.
but I think that's
> unrelated. The real problem is the tag name is no longer unique, and we
> must prevent that.
>
> Let's screw with the tag objects even more (fresh repo, some "otherfile"):
>
> $ git tag -m "old tag1" -a tag1
> $ git tag -m "tag2" -a tag2 tag1
> $ git tag -m "new tag1" tag1 tag2
> fatal: tag 'tag1' already exists
> $ git tag -f -m "new tag1" tag1 tag2
> $ git rev-list --objects tag1
> 69bf327c5d172fc8e4f63acf4d2e01c474824ce4
> 8e7a1997726fc5158954569134d2cafad710f6fe tag1
> 38aea56fec319d8c259a80157dde2432d2d09b2b tag2
> 9756f6fa98a5cce2aab1f6a6e7dd4de515626e19 tag1
> d758baa57a7ef20d44df0535bef1a91bb3dc4f62
> d3d8863b140f43f7c07050b9f2e210d41e73edb1 otherfile
> $ git show-ref
> 69bf327c5d172fc8e4f63acf4d2e01c474824ce4 refs/heads/master
> 8e7a1997726fc5158954569134d2cafad710f6fe refs/tags/tag1
> 38aea56fec319d8c259a80157dde2432d2d09b2b refs/tags/tag2
> $ gitk
> $ git cat-file tag 8e7a
> object 38aea56fec319d8c259a80157dde2432d2d09b2b
> type tag
> tag tag1
> tagger Matthias Andree <matthias.andree@gmx.de> 1242292320 +0200
>
> new tag1
> $ git cat-file tag 38ae
> object 9756f6fa98a5cce2aab1f6a6e7dd4de515626e19
> type tag
> tag tag2
> tagger Matthias Andree <matthias.andree@gmx.de> 1242292301 +0200
>
> tag2
> $ git cat-file tag 9756
> object 69bf327c5d172fc8e4f63acf4d2e01c474824ce4
> type commit
> tag tag1
> tagger Matthias Andree <matthias.andree@gmx.de> 1242292293 +0200
>
> old tag1
>
> Hu, there's a nice cycle:
>
> 69bf (commit) <- 9756 ('old' tag1) <- 38ae (tag2) <- 8e7a (tag1)
>
> Now, more fun - watch the inconsistency:
>
> $ git tag -d tag1
> Deleted tag 'tag1'
> $ git tag -d tag1
> error: tag 'tag1' not found.
>
> 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!!!
>
> 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.
>
> Either git tag -f/-d should complain and refuse if it cannot
> replace/remove the tag because it wouldn't become dangling (other
> dependencies on it, best to list them), or it would have to recursively
> trash all its children, too - and perhaps require -f -f be specified for
> this recursive replacing/removal.
>
next prev parent reply other threads:[~2009-05-14 12:00 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 [this message]
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
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=4A0C07D9.8030401@drmicha.warpmail.net \
--to=git@drmicha.warpmail.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.