git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
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 --]

  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).