git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH 3/4] refs: complete list of special refs

From
Patrick Steinhardt <ps@pks.im>
Date
Nov 30, 2023, 07:44 UTC
Message-ID
<ZWg9RW4L8nBhYmaB@tanuki>
In-Reply-To
<ZWe0RzOoHI9QZMox@nand.local>
On Wed, Nov 29, 2023 at 04:59:35PM -0500, Taylor Blau wrote:
Show 85 quoted lines
> On Wed, Nov 29, 2023 at 09:14:20AM +0100, Patrick Steinhardt wrote:
> > We have some references that are more special than others. The reason
> > for them being special is that they either do not follow the usual
> > format of references, or that they are written to the filesystem
> > directly by the respective owning subsystem and thus circumvent the
> > reference backend.
> >
> > This works perfectly fine right now because the reffiles backend will
> > know how to read those refs just fine. But with the prospect of gaining
> > a new reference backend implementation we need to be a lot more careful
> > here:
> >
> >   - We need to make sure that we are consistent about how those refs are
> >     written. They must either always be written via the filesystem, or
> >     they must always be written via the reference backend. Any mixture
> >     will lead to inconsistent state.
> >
> >   - We need to make sure that such special refs are always handled
> >     specially when reading them.
> >
> > We're already mostly good with regard to the first item, except for
> > `BISECT_EXPECTED_REV` which will be addressed in a subsequent commit.
> > But the current list of special refs is missing a lot of refs that
> > really should be treated specially. Right now, we only treat
> > `FETCH_HEAD` and `MERGE_HEAD` specially here.
> >
> > Introduce a new function `is_special_ref()` that contains all current
> > instances of special refs to fix the reading path.
> >
> > Based-on-patch-by: Han-Wen Nienhuys <hanwenn@gmail.com>
> > Signed-off-by: Patrick Steinhardt <ps@pks.im>
> > ---
> >  refs.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
> >  1 file changed, 56 insertions(+), 2 deletions(-)
> >
> > diff --git a/refs.c b/refs.c
> > index 7d4a057f36..2d39d3fe80 100644
> > --- a/refs.c
> > +++ b/refs.c
> > @@ -1822,15 +1822,69 @@ static int refs_read_special_head(struct ref_store *ref_store,
> >  	return result;
> >  }
> >
> > +static int is_special_ref(const char *refname)
> > +{
> > +	/*
> > +	 * Special references get written and read directly via the filesystem
> > +	 * by the subsystems that create them. Thus, they must not go through
> > +	 * the reference backend but must instead be read directly. It is
> > +	 * arguable whether this behaviour is sensible, or whether it's simply
> > +	 * a leaky abstraction enabled by us only having a single reference
> > +	 * backend implementation. But at least for a subset of references it
> > +	 * indeed does make sense to treat them specially:
> > +	 *
> > +	 * - FETCH_HEAD may contain multiple object IDs, and each one of them
> > +	 *   carries additional metadata like where it came from.
> > +	 *
> > +	 * - MERGE_HEAD may contain multiple object IDs when merging multiple
> > +	 *   heads.
> > +	 *
> > +	 * - "rebase-apply/" and "rebase-merge/" contain all of the state for
> > +	 *   rebases, where keeping it closely together feels sensible.
> > +	 *
> > +	 * There are some exceptions that you might expect to see on this list
> > +	 * but which are handled exclusively via the reference backend:
> > +	 *
> > +	 * - CHERRY_PICK_HEAD
> > +	 * - HEAD
> > +	 * - ORIG_HEAD
> > +	 *
> > +	 * Writing or deleting references must consistently go either through
> > +	 * the filesystem (special refs) or through the reference backend
> > +	 * (normal ones).
> > +	 */
> > +	const char * const special_refs[] = {
> > +		"AUTO_MERGE",
> > +		"BISECT_EXPECTED_REV",
> > +		"FETCH_HEAD",
> > +		"MERGE_AUTOSTASH",
> > +		"MERGE_HEAD",
> > +	};
> 
> Is there a reason that we don't want to declare this statically? If we
> did, I think we could drop one const, since the strings would instead
> reside in the .rodata section.
Not really, no.
Show 5 quoted lines
> > +	int i;
> 
> Not that it matters for this case, but it may be worth declaring i to be
> an unsigned type, since it's used as an index into an array. size_t
> seems like an appropriate choice there.

Hm. We do use `int` almost everywhere when iterating through an array via `ARRAY_SIZE`, but ultimately I don't mind whether it's `int`, `unsigned` or `size_t`.

Show 23 quoted lines
> > +	for (i = 0; i < ARRAY_SIZE(special_refs); i++)
> > +		if (!strcmp(refname, special_refs[i]))
> > +			return 1;
> > +
> > +	/*
> > +	 * git-rebase(1) stores its state in `rebase-apply/` or
> > +	 * `rebase-merge/`, including various reference-like bits.
> > +	 */
> > +	if (starts_with(refname, "rebase-apply/") ||
> > +	    starts_with(refname, "rebase-merge/"))
> 
> Do we care about case sensitivity here? Definitely not on case-sensitive
> filesystems, but I'm not sure about case-insensitive ones. For instance,
> on macOS, I can do:
> 
>     $ git rev-parse hEAd
> 
> and get the same value as "git rev-parse HEAD" (on my Linux workstation,
> this fails as expected).
> 
> I doubt that there are many users in the wild asking to resolve
> reBASe-APPLY/xyz, but I think that after this patch that would no longer
> work as-is, so we may want to replace this with istarts_with() instead.

In practice I'd argue that nobody is ever going to ask for something in `rebase-apply/` outside of Git internals or scripts, and I'd expect these to always use proper casing. So I rather lean towards a "no, we don't care about case sensitivity".

Patrick
Previous: Taylor BlauNext: Phillip Wood
Message 11 of 41 in “refs: improve handling of special refs”
  1. 0/4 refs: improve handling of special refsPatrick Steinhardt, Nov 29, 2023
  2. 1/4 wt-status: read HEAD and ORIG_HEAD via the refdbPatrick Steinhardt, Nov 29, 2023
  3. Taylor BlauNov 29, 2023
  4. Patrick SteinhardtNov 30, 2023
  5. Taylor BlauNov 30, 2023
  6. 2/4 refs: propagate errno when reading special refs failsPatrick Steinhardt, Nov 29, 2023
  7. Taylor BlauNov 29, 2023
  8. Patrick SteinhardtNov 30, 2023
  9. 3/4 refs: complete list of special refsPatrick Steinhardt, Nov 29, 2023
  10. Taylor BlauNov 29, 2023
  11. Patrick SteinhardtNov 30, 2023
  12. Phillip WoodNov 30, 2023
  13. Patrick SteinhardtDec 1, 2023
  14. Phillip WoodDec 4, 2023
  15. 4/4 bisect: consistently write BISECT_EXPECTED_REV via the refdbPatrick Steinhardt, Nov 29, 2023
  16. Taylor BlauNov 29, 2023
  17. Taylor BlauNov 29, 2023
  18. Patrick SteinhardtNov 30, 2023
  19. Taylor BlauNov 30, 2023
  20. 0/4 refs: improve handling of special refsPatrick Steinhardt, Dec 12, 2023
  21. 1/4 wt-status: read HEAD and ORIG_HEAD via the refdbPatrick Steinhardt, Dec 12, 2023
  22. Junio C HamanoDec 12, 2023
  23. Ramsay JonesDec 12, 2023
  24. Junio C HamanoDec 13, 2023
  25. Patrick SteinhardtDec 13, 2023
  26. Junio C HamanoDec 13, 2023
  27. Patrick SteinhardtDec 14, 2023
  28. Junio C HamanoDec 14, 2023
  29. Patrick SteinhardtDec 14, 2023
  30. 2/4 refs: propagate errno when reading special refs failsPatrick Steinhardt, Dec 12, 2023
  31. Junio C HamanoDec 12, 2023
  32. Patrick SteinhardtDec 13, 2023
  33. 3/4 refs: complete list of special refsPatrick Steinhardt, Dec 12, 2023
  34. 4/4 bisect: consistently write BISECT_EXPECTED_REV via the refdbPatrick Steinhardt, Dec 12, 2023
  35. 0/4 refs: improve handling of special refsPatrick Steinhardt, Dec 14, 2023
  36. 1/4 wt-status: read HEAD and ORIG_HEAD via the refdbPatrick Steinhardt, Dec 14, 2023
  37. 2/4 refs: propagate errno when reading special refs failsPatrick Steinhardt, Dec 14, 2023
  38. 3/4 refs: complete list of special refsPatrick Steinhardt, Dec 14, 2023
  39. 4/4 bisect: consistently write BISECT_EXPECTED_REV via the refdbPatrick Steinhardt, Dec 14, 2023
  40. Junio C HamanoDec 20, 2023
  41. Patrick SteinhardtDec 21, 2023

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.