git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Patrick Steinhardt <ps@pks.im>
To: git@vger.kernel.org
Cc: hanwenn@gmail.com
Subject: [PATCH 3/4] refs: complete list of special refs
Date: Wed, 29 Nov 2023 09:14:20 +0100	[thread overview]
Message-ID: <0e38103114a206bedbbbd7ea97cb77fa05fd3c29.1701243201.git.ps@pks.im> (raw)
In-Reply-To: <cover.1701243201.git.ps@pks.im>

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

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",
+	};
+	int i;
+
+	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/"))
+		return 1;
+
+	return 0;
+}
+
 int refs_read_raw_ref(struct ref_store *ref_store, const char *refname,
 		      struct object_id *oid, struct strbuf *referent,
 		      unsigned int *type, int *failure_errno)
 {
 	assert(failure_errno);
-	if (!strcmp(refname, "FETCH_HEAD") || !strcmp(refname, "MERGE_HEAD")) {
+	if (is_special_ref(refname))
 		return refs_read_special_head(ref_store, refname, oid, referent,
 					      type, failure_errno);
-	}
 
 	return ref_store->be->read_raw_ref(ref_store, refname, oid, referent,
 					   type, failure_errno);
-- 
2.43.0


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

  parent reply	other threads:[~2023-11-29  8:14 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 ` Patrick Steinhardt [this message]
2023-11-29 21:59   ` [PATCH 3/4] refs: complete list of special refs 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
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=0e38103114a206bedbbbd7ea97cb77fa05fd3c29.1701243201.git.ps@pks.im \
    --to=ps@pks.im \
    --cc=git@vger.kernel.org \
    --cc=hanwenn@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).