From: Patrick Steinhardt <ps@pks.im>
To: Junio C Hamano <gitster@pobox.com>
Cc: "John Cai via GitGitGadget" <gitgitgadget@gmail.com>,
git@vger.kernel.org, "Phillip Wood" <phillip.wood123@gmail.com>,
"Kristoffer Haugsbakk" <code@khaugsbakk.name>,
"Jeff King" <peff@peff.net>,
"Jean-Noël Avila" <avila.jn@gmail.com>,
"Linus Arver" <linusarver@gmail.com>,
"John Cai" <johncai86@gmail.com>
Subject: Re: [PATCH v2 1/3] refs: keep track of unresolved reference value in iterators
Date: Mon, 5 Aug 2024 12:59:54 +0200 [thread overview]
Message-ID: <ZrCwqqLKcwdOYclN@tanuki> (raw)
In-Reply-To: <xmqqa5hww600.fsf@gitster.g>
[-- Attachment #1: Type: text/plain, Size: 4029 bytes --]
On Thu, Aug 01, 2024 at 09:41:03AM -0700, Junio C Hamano wrote:
> "John Cai via GitGitGadget" <gitgitgadget@gmail.com> writes:
> > @@ -886,6 +889,9 @@ static int files_ref_iterator_advance(struct ref_iterator *ref_iterator)
> > iter->base.refname = iter->iter0->refname;
> > iter->base.oid = iter->iter0->oid;
> > iter->base.flags = iter->iter0->flags;
> > + if (iter->iter0->flags & REF_ISSYMREF)
> > + iter->base.referent = iter->iter0->referent;
>
> Presumably base.referent is initialized to NULL so this "if"
> statement does not need an else clause?
This function typically ends up being called in a loop though. So
without the else clause, wouldn't we potentially leak the value of a
preceding ref into subsequent iterations like this?
> I am primarily wondering why this needs to be conditional. We are
> making verbatim copy of the flags word from *iter->iter0 to
> iter->base; if iter0 is symref we want to mark base also as symref,
> If iter0 is not a symref, then we want to mark base also not a
> symref, presumably. So wouldn't it make sense to just say
>
> iter->base.referent = iter->iter0->referent;
>
> here, regardless of what iter->iter0->flags say about symref-ness of
> the thing? Because ...
> > diff --git a/refs/iterator.c b/refs/iterator.c
> > index d355ebf0d59..26acb6bd640 100644
> > --- a/refs/iterator.c
> > +++ b/refs/iterator.c
> > @@ -7,6 +7,7 @@
> > #include "refs.h"
> > #include "refs/refs-internal.h"
> > #include "iterator.h"
> > +#include "strbuf.h"
> >
> > int ref_iterator_advance(struct ref_iterator *ref_iterator)
> > {
> > @@ -29,6 +30,7 @@ void base_ref_iterator_init(struct ref_iterator *iter,
> > {
> > iter->vtable = vtable;
> > iter->refname = NULL;
> > + iter->referent = NULL;
> > iter->oid = NULL;
> > iter->flags = 0;
> > }
> > @@ -199,6 +201,7 @@ static int merge_ref_iterator_advance(struct ref_iterator *ref_iterator)
> > }
> >
> > if (selection & ITER_YIELD_CURRENT) {
> > + iter->base.referent = (*iter->current)->referent;
> > iter->base.refname = (*iter->current)->refname;
> > iter->base.oid = (*iter->current)->oid;
> > iter->base.flags = (*iter->current)->flags;
>
> ... other parts of the API seem to follow that philosophy.
>
> In other words, the invariant of this code is that .referent is
> non-NULL if and only if the ref is a symref, and that invariant is
> trusted without checking with .flags member. But the earlier hunk
> that copied iter0 to base did not seem to be using that invariant,
> which made it look inconsistent.
Agreed.
> > struct ref_entry *create_ref_entry(const char *refname,
> > + const char *referent,
> > const struct object_id *oid, int flag)
> > {
> > struct ref_entry *ref;
> > @@ -41,6 +43,10 @@ struct ref_entry *create_ref_entry(const char *refname,
> > FLEX_ALLOC_STR(ref, name, refname);
> > oidcpy(&ref->u.value.oid, oid);
> > ref->flag = flag;
> > +
> > + if (flag & REF_ISSYMREF)
> > + ref->u.value.referent = xstrdup_or_null(referent);
>
> OK. ref_value now has referent next to the existing oid, but that
> member only makes sense when flag says it is a symref.
>
> Curiously, that information is missing from ref_value struct, so by
> looking at a ref_value alone, we cannot tell if we should trust the
> value in the .referent member?
>
> Makes me wonder if we should follow the same "ignore what the flag
> says when filling the .referent member; if the ref is not a symref,
> the referent variable is NULL, and if it is, referent is never NULL"
> pattern? Then ref->u.value.referent is _always_ defined---the
> current code says "the u.value.referent member is undefined for ref
> that is not a symref", but with the suggested change, it will be
> "the u.value.referent member is NULL for ref that is not a symref,
> and for a symref, it is the value of the symref".
Yeah, I think that would be preferable indeed.
Patrick
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
next prev parent reply other threads:[~2024-08-05 11:00 UTC|newest]
Thread overview: 44+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-06-06 17:26 [PATCH 0/4] keep track of unresolved value of symbolic-ref in ref iterators John Cai via GitGitGadget
2024-06-06 17:26 ` [PATCH 1/4] refs: add referent parameter to refs_resolve_ref_unsafe John Cai via GitGitGadget
2024-06-06 18:21 ` Junio C Hamano
2024-06-06 18:23 ` Junio C Hamano
2024-06-07 13:43 ` John Cai
2024-06-07 15:21 ` Junio C Hamano
2024-06-10 7:29 ` Patrick Steinhardt
2024-06-10 18:09 ` Junio C Hamano
2024-06-06 21:02 ` John Cai
2024-06-06 22:44 ` Junio C Hamano
2024-06-28 15:30 ` Kristoffer Haugsbakk
2024-06-28 19:47 ` Junio C Hamano
2024-06-30 10:12 ` Linus Arver
2024-06-30 18:19 ` Junio C Hamano
2024-06-11 8:50 ` Jeff King
2024-07-30 14:38 ` John Cai
2024-06-06 17:26 ` [PATCH 2/4] refs: keep track of unresolved reference value in iterators John Cai via GitGitGadget
2024-06-11 9:01 ` Jeff King
2024-06-06 17:26 ` [PATCH 3/4] refs: add referent to each_ref_fn John Cai via GitGitGadget
2024-06-06 17:26 ` [PATCH 4/4] ref-filter: populate symref from iterator John Cai via GitGitGadget
2024-08-01 14:58 ` [PATCH v2 0/3] keep track of unresolved value of symbolic-ref in ref iterators John Cai via GitGitGadget
2024-08-01 14:58 ` [PATCH v2 1/3] refs: keep track of unresolved reference value in iterators John Cai via GitGitGadget
2024-08-01 16:41 ` Junio C Hamano
2024-08-05 10:59 ` Patrick Steinhardt [this message]
2024-08-05 15:40 ` Junio C Hamano
2024-08-01 14:58 ` [PATCH v2 2/3] refs: add referent to each_ref_fn John Cai via GitGitGadget
2024-08-01 14:58 ` [PATCH v2 3/3] ref-filter: populate symref from iterator John Cai via GitGitGadget
2024-08-01 16:43 ` Junio C Hamano
2024-08-01 16:51 ` Junio C Hamano
2024-08-01 16:54 ` Junio C Hamano
2024-08-06 19:49 ` John Cai
2024-08-06 20:17 ` Junio C Hamano
2024-08-07 19:42 ` [PATCH v3 0/3] keep track of unresolved value of symbolic-ref in ref iterators John Cai via GitGitGadget
2024-08-07 19:42 ` [PATCH v3 1/3] refs: keep track of unresolved reference value in iterators John Cai via GitGitGadget
2024-08-07 21:40 ` Junio C Hamano
2024-08-08 18:09 ` John Cai
2024-08-07 19:42 ` [PATCH v3 2/3] refs: add referent to each_ref_fn John Cai via GitGitGadget
2024-08-07 19:42 ` [PATCH v3 3/3] ref-filter: populate symref from iterator John Cai via GitGitGadget
2024-08-09 15:37 ` [PATCH v4 0/3] keep track of unresolved value of symbolic-ref in ref iterators John Cai via GitGitGadget
2024-08-09 15:37 ` [PATCH v4 1/3] refs: keep track of unresolved reference value in iterators John Cai via GitGitGadget
2024-11-23 8:24 ` shejialuo
2024-08-09 15:37 ` [PATCH v4 2/3] refs: add referent to each_ref_fn John Cai via GitGitGadget
2024-08-09 15:37 ` [PATCH v4 3/3] ref-filter: populate symref from iterator John Cai via GitGitGadget
2024-08-09 16:51 ` [PATCH v4 0/3] keep track of unresolved value of symbolic-ref in ref iterators Junio C Hamano
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=ZrCwqqLKcwdOYclN@tanuki \
--to=ps@pks.im \
--cc=avila.jn@gmail.com \
--cc=code@khaugsbakk.name \
--cc=git@vger.kernel.org \
--cc=gitgitgadget@gmail.com \
--cc=gitster@pobox.com \
--cc=johncai86@gmail.com \
--cc=linusarver@gmail.com \
--cc=peff@peff.net \
--cc=phillip.wood123@gmail.com \
/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).