git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Patrick Steinhardt <ps@pks.im>
To: Junio C Hamano <gitster@pobox.com>
Cc: git@vger.kernel.org, Taylor Blau <me@ttaylorr.com>,
	Phillip Wood <phillip.wood123@gmail.com>
Subject: Re: [PATCH v2 1/4] wt-status: read HEAD and ORIG_HEAD via the refdb
Date: Thu, 14 Dec 2023 14:21:35 +0100	[thread overview]
Message-ID: <ZXsBX-PW5J_5nTPT@tanuki> (raw)
In-Reply-To: <xmqqle9zqidj.fsf@gitster.g>

[-- Attachment #1: Type: text/plain, Size: 3621 bytes --]

On Tue, Dec 12, 2023 at 12:24:24PM -0800, Junio C Hamano wrote:
> Patrick Steinhardt <ps@pks.im> writes:
[snip]
> > diff --git a/wt-status.c b/wt-status.c
> > index 9f45bf6949..fe9e590b80 100644
> > --- a/wt-status.c
> > +++ b/wt-status.c
> > @@ -1295,26 +1295,27 @@ static char *read_line_from_git_path(const char *filename)
> >  static int split_commit_in_progress(struct wt_status *s)
> >  {
> >  	int split_in_progress = 0;
> > -	char *head, *orig_head, *rebase_amend, *rebase_orig_head;
> > +	struct object_id head_oid, orig_head_oid;
> > +	char *rebase_amend, *rebase_orig_head;
> >  
> >  	if ((!s->amend && !s->nowarn && !s->workdir_dirty) ||
> >  	    !s->branch || strcmp(s->branch, "HEAD"))
> >  		return 0;
> >  
> > -	head = read_line_from_git_path("HEAD");
> > -	orig_head = read_line_from_git_path("ORIG_HEAD");
> > +	if (read_ref_full("HEAD", RESOLVE_REF_NO_RECURSE, &head_oid, NULL) ||
> > +	    read_ref_full("ORIG_HEAD", RESOLVE_REF_NO_RECURSE, &orig_head_oid, NULL))
> > +		return 0;
> > +
> 
> This made me wonder if we have changed behaviour when on an unborn
> branch.  In such a case, the original most likely would have read
> "ref: blah" in "head" and compared it with "rebase_amend", which
> would be a good way to ensure they would not match.  I would not
> know offhand what the updated code would do, but head_oid would be
> uninitialized in such a case, so ...?

The code flow goes as following:

  1. We call `read_ref_full()`, which itself calls
     `refs_resolve_ref_unsafe()`.

  2. It calls `refs_read_raw_ref()`, which succeeds and finds the
     symref.

  3. We notice that this is a symref and that `RESOLVE_REF_NO_RECURSE`
     is set. We thus clear the object ID and return the name of the
     symref target.

  4. Back in `read_ref_full()` we see that `refs_resolve_ref_unsafe()`
     returns the symref target, which we interpret as successful lookup.
     We thus return `0`.

  5. Now we look up "rebase-merge/{amend,orig-head}" and end up
     comparing whatever they contain with the cleared OID resolved from
     HEAD/ORIG_HEAD.

So the OID would not be uninitialized but the zero OID. Now:

  - "rebase-merge/amend" always contains the result of `repo_get_oid()`
    and never contains the zero OID.

  - "rebase-merge/orig-head" may contain the zero OID when there was no
    ORIG_HEAD at the time of starting a rebase or in case it did not
    resolve

So... if ORIG_HEAD was rewritten to be a symref pointing into nirvana
between starting the rebase and calling into "wt-status.c", and when
ORIG_HEAD didn't exist at the time of starting the rebase, then we might
now wrongly report that splitting was in progress.

In other cases the old code was actually doing the wrong thing. Suppose
that ORIG_HEAD was a dangling symref, then we'd have written the zero
OID into "rebase-merge/orig-head". But when calling into "wt-status.c"
now we read the still-dangling symref value and notice that the zero OID
is different than "ref: refs/heads/dangling".

I dunno. It feels like this is one of many cases where as you start to
think deeply about how things behave you realize that it's been broken
all along. On the other hand, I doubt there was even a single user who
ever experienced this issue. It often just needs to be correct enough.

I think the best way to go about this is to check for `REF_ISSSYMREF`
and exit early in that case. We only want to compare direct refs, so
this is closer to the old behaviour and should even fix edge cases like
the above.

Will update.

Patrick

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

  parent reply	other threads:[~2023-12-14 13:22 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-11-29  8:14 [PATCH 0/4] refs: improve handling of special refs Patrick Steinhardt
2023-11-29  8:14 ` [PATCH 1/4] wt-status: read HEAD and ORIG_HEAD via the refdb Patrick Steinhardt
2023-11-29 21:45   ` Taylor Blau
2023-11-30  7:42     ` Patrick Steinhardt
2023-11-30 17:36       ` Taylor Blau
2023-11-29  8:14 ` [PATCH 2/4] refs: propagate errno when reading special refs fails Patrick Steinhardt
2023-11-29 21:51   ` Taylor Blau
2023-11-30  7:43     ` Patrick Steinhardt
2023-11-29  8:14 ` [PATCH 3/4] refs: complete list of special refs Patrick Steinhardt
2023-11-29 21:59   ` Taylor Blau
2023-11-30  7:44     ` Patrick Steinhardt
2023-11-30 15:42   ` Phillip Wood
2023-12-01  6:43     ` Patrick Steinhardt
2023-12-04 14:18       ` Phillip Wood
2023-11-29  8:14 ` [PATCH 4/4] bisect: consistently write BISECT_EXPECTED_REV via the refdb Patrick Steinhardt
2023-11-29 22:13   ` Taylor Blau
2023-11-29 22:14 ` [PATCH 0/4] refs: improve handling of special refs Taylor Blau
2023-11-30  7:46   ` Patrick Steinhardt
2023-11-30 17:35     ` Taylor Blau
2023-12-12  7:18 ` [PATCH v2 " Patrick Steinhardt
2023-12-12  7:18   ` [PATCH v2 1/4] wt-status: read HEAD and ORIG_HEAD via the refdb Patrick Steinhardt
2023-12-12 20:24     ` Junio C Hamano
2023-12-12 23:32       ` Ramsay Jones
2023-12-13  0:36         ` Junio C Hamano
2023-12-13  7:38           ` Patrick Steinhardt
2023-12-13 15:15             ` Junio C Hamano
2023-12-14  9:04               ` Patrick Steinhardt
2023-12-14 16:41                 ` Junio C Hamano
2023-12-14 13:21       ` Patrick Steinhardt [this message]
2023-12-12  7:18   ` [PATCH v2 2/4] refs: propagate errno when reading special refs fails Patrick Steinhardt
2023-12-12 20:28     ` Junio C Hamano
2023-12-13  7:28       ` Patrick Steinhardt
2023-12-12  7:18   ` [PATCH v2 3/4] refs: complete list of special refs Patrick Steinhardt
2023-12-12  7:19   ` [PATCH v2 4/4] bisect: consistently write BISECT_EXPECTED_REV via the refdb Patrick Steinhardt
2023-12-14 13:36 ` [PATCH v3 0/4] refs: improve handling of special refs Patrick Steinhardt
2023-12-14 13:36   ` [PATCH v3 1/4] wt-status: read HEAD and ORIG_HEAD via the refdb Patrick Steinhardt
2023-12-14 13:37   ` [PATCH v3 2/4] refs: propagate errno when reading special refs fails Patrick Steinhardt
2023-12-14 13:37   ` [PATCH v3 3/4] refs: complete list of special refs Patrick Steinhardt
2023-12-14 13:37   ` [PATCH v3 4/4] bisect: consistently write BISECT_EXPECTED_REV via the refdb Patrick Steinhardt
2023-12-20 19:28   ` [PATCH v3 0/4] refs: improve handling of special refs Junio C Hamano
2023-12-21 10:08     ` Patrick Steinhardt

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

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ZXsBX-PW5J_5nTPT@tanuki \
    --to=ps@pks.im \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=me@ttaylorr.com \
    --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.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

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 read-only IMAP folder(s) and NNTP newsgroup(s).