All of lore.kernel.org
 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 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.