Re: [PATCH v2 3/3] ref-filter: populate symref from iterator
- From
John Cai <johncai86@gmail.com>
- Date
- Aug 6, 2024, 19:49 UTC
- Message-ID
- <A71B6F98-820D-4692-9712-C6D63F019DCE@gmail.com>
- In-Reply-To
- <xmqqsevouqsj.fsf@gitster.g>
Hi Junio,
On 1 Aug 2024, at 12:54, Junio C Hamano wrote:
Show 36 quoted lines
> Junio C Hamano <gitster@pobox.com> writes:
>
>>> @@ -2852,6 +2852,8 @@ static struct ref_array_item *apply_ref_filter(const char *refname, const struct
>>> ref->commit = commit;
>>> ref->flag = flag;
>>> ref->kind = kind;
>>> + if (flag & REF_ISSYMREF)
>>> + ref->symref = xstrdup_or_null(referent);
>>>
>>> return ref;
>>> }
>>
>> What is curious is that we do not lose any code from
>> populate_value() with this change.
>>
>> Is that because of this piece of code near the beginning of it?
>>
>> CALLOC_ARRAY(ref->value, used_atom_cnt);
>>
>> if (need_symref && (ref->flag & REF_ISSYMREF) && !ref->symref) {
>> ref->symref = refs_resolve_refdup(get_main_ref_store(the_repository),
>> ref->refname,
>> RESOLVE_REF_READING,
>> NULL, NULL);
>> if (!ref->symref)
>> ref->symref = xstrdup("");
>> }
>>
>> That is, if we somehow know the value of ref->symref for a ref that
>> is known to be a symbolic ref (and when we know we need symref
>> information in the output), we do not bother calling refs_resolve
>> here to obtain the value.
>
> I forgot to ask the real question. With your change in place, does
> this "lazily fill ref->symref if it hasn't been discovered yet" code
> still trigger? Under what condition? Or is this now a dead code?Yes that's a good question. I took a look and it seems like in *most* cases by the time populate_value() is called, apply_ref_filter() has already been called that populates the symref member of ref_array_item.
populate_value() gets called by get_ref_atom_value() which gets called by both
1. format_ref_array_item() 2. cmp_ref_sorting()
In the case of [2], the callchain starts with filter_and_format_refs() which calls ref_array_sort() that eventually calls populate_value(). Before ref_array_sort() is called, filter_refs() is called which ends up calling do_filter_refs() with filter_one(), leading to apply_ref_filter().
In the case of [1] however, there are a couple of code paths that call populate_value() without apply_ref_filter() ever being called.
pretty_print_ref() directly calls format_ref_array_item() -> get_ref_atom_value() -> populate_value(). However, apply_ref_filter() is not called which means the symref will not be populated.
Looking through the codebase, this function is only called in builtin/tag.c and bulitin/verify-tag.c in the `git tag -v` codepath. So it seems that if we got rid of this block of code in populate_value(), only in the case where `git tag -v --format='%(symref)'` on a symbolic ref pointing to a tag would the symref be missing.
But I don't even know if this is possible. I tried this locally and got the error:
$ git tag -a -s -m "version 1" v1 refs/heads/master $ git symbolic-ref refs/tags/symbolic-v1 refs/tags/v1 $ git tag -v --format='(%symref)'
error: tag 'refs/tags/symbolic-v1' not found.
So practically speaking, I think we are safe to remove. However, from a future-proof point of view, anyone in the future who calls pretty_print_ref() would also need to be sure to populate the symref member in ref_array_item.
So perhaps from a code durability standpoint we should keep that block?
> > Thanks.