git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH v2] load_ref_decorations(): fix decoration with tags

From
Jeff King <peff@peff.net>
Date
Jul 13, 2021, 21:27 UTC
Message-ID
<YO4FObgRvpt1nVr0@coredump.intra.peff.net>
In-Reply-To
<xmqqpmvl29ry.fsf@gitster.g>
On Tue, Jul 13, 2021 at 02:17:53PM -0700, Junio C Hamano wrote:
Show 20 quoted lines
> >> Note how this commit could have been done as an optimization before
> >> 88473c8bae: When our peeling hits a non-tag, we won't parse that tagged
> >> object only to immediately end the loop.
> >
> > Yep, thanks for mentioning this, as it's somewhat subtle.
> 
> It is too subtle that I am not sure what the paragraph wants to say.
> 
> Before 88473c8b, we had a fully parsed object in obj and entered the
> while() loop iff the outermost object is a tag, then we find the
> underlying object via obj->tagged.  We parse that underlying object
> to find if it is a tag, and break out if it is not.
> 
> By "this commit", I assume that the above mean the change in this
> fix, i.e. parse 'obj' if it has not been parsed before looking at
> its tagged field.  But I am not sure how that would have been an
> optimization before 88473c8b that gave a parsed tag object 'obj'
> upon entry to the loop.
> 
> Puzzled.

The optimization is that we are parsing tags before looking at their structs, instead of always parsing the thing that the tag points to.

So in the old loop (pseudo-code for clarity):
  parse_object(obj);
  while (obj->type == OBJ_TAG) {
          obj = obj->tagged;
	  parse_object(obj);
  }

if we had a tag pointing to a commit, we'd parse the commit. But we don't need to. We just need to know that it exists and is a commit.

In the new code, we parse only when we need to look at obj->tagged:
  while (obj->type == OBJ_TAG) {
          parse_object(obj);
	  obj = obj->tagged;
  }

So we must "somehow" know the type of "obj" in the first place, as well as the type of every obj->tagged we look at. And that leads into your question here:

Show 33 quoted lines
> In any case, let's talk about this patch in the context to which it
> is designed to be applied, i.e. post 88473c8b3c8b.
> 
> When we come here, we have done oid_object_info() plus
> lookup_object_by_type() to obtain 'obj' and we know its type.
> Then we enter the loop.
> 
>  	while (obj->type == OBJ_TAG) {
> +		if (!obj->parsed)
> +			parse_object(the_repository, &obj->oid);
> 
> And we parse if it hasn't been parsed.  THat is why we can ...
> 
>  		obj = ((struct tag *)obj)->tagged;
>  		if (!obj)
>  			break;
> 
> ... look at its tagged member.
> 
> -		if (!obj->parsed)
> -			parse_object(the_repository, &obj->oid);
>  		add_name_decoration(DECORATION_REF_TAG, refname, obj);
> 
> And the updated 'obj' (i.e. direct referent of the tag object) is
> fed to add_name_decoration().  And then we move to the next
> iteration.
> 
> Now, do we know what type of object 'obj' is at this point?  We
> did parse the outermost tag upon entry to this loop, we replaced
> 'obj' variable with the referent by following the .tagged member,
> but we haven't parsed that object or ran oid_object_info() on it.
> 
> Puzzled.

...and the answer is that we don't need to parse it. The tag object mentions the type of what it points to, and we use lookup_commit(), etc, to create the object pointed to by its "tagged" field. If we can't do that (say, because the tag is missing the type field, or we previously saw the object as a different type, etc), then obj->tagged would be NULL and we'd break out of the loop.

-Peff
Previous: Junio C HamanoNext: Junio C Hamano
Message 7 of 12 in “load_ref_decorations(): fix decoration with tags”
  1. load_ref_decorations(): fix decoration with tagsMartin Ågren, Jul 12, 2021
  2. Jeff KingJul 13, 2021
  3. load_ref_decorations(): fix decoration with tagsMartin Ågren, Jul 13, 2021
  4. Jeff KingJul 13, 2021
  5. Martin ÅgrenJul 13, 2021
  6. Junio C HamanoJul 13, 2021
  7. Jeff KingJul 13, 2021
  8. Junio C HamanoJul 13, 2021
  9. Martin ÅgrenJul 13, 2021
  10. Jeff KingJul 13, 2021
  11. Martin ÅgrenJul 14, 2021
  12. load_ref_decorations(): fix decoration with tagsJeff King, Jul 14, 2021

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.