All of lore.kernel.org
 help / color / mirror / Atom feed
From: Patrick Steinhardt <ps@pks.im>
To: Karthik Nayak <karthik.188@gmail.com>
Cc: git@vger.kernel.org, gitster@pobox.com,
	phillip.wood123@gmail.com, Jeff King <peff@peff.net>
Subject: Re: [PATCH v4 1/5] refs: introduce `is_pseudoref()` and `is_headref()`
Date: Mon, 12 Feb 2024 13:47:41 +0100	[thread overview]
Message-ID: <ZcoTbRxIaGmTd4fJ@tanuki> (raw)
In-Reply-To: <20240211183923.131278-2-karthik.188@gmail.com>

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

On Sun, Feb 11, 2024 at 07:39:19PM +0100, Karthik Nayak wrote:
> Introduce two new functions `is_pseudoref()` and `is_headref()`. This
> provides the necessary functionality for us to add pseudorefs and HEAD
> to the loose ref cache in the files backend, allowing us to build
> tooling to print these refs.
> 
> The `is_pseudoref()` function internally calls `is_pseudoref_syntax()`
> but adds onto it by also checking to ensure that the pseudoref either
> ends with a "_HEAD" suffix or matches a list of exceptions. After which
> we also parse the contents of the pseudoref to ensure that it conforms
> to the ref format.
> 
> We cannot directly add the new syntax checks to `is_pseudoref_syntax()`
> because the function is also used by `is_current_worktree_ref()` and
> making it stricter to match only known pseudorefs might have unintended
> consequences due to files like 'BISECT_START' which isn't a pseudoref
> but sometimes contains object ID.
> 
> Keeping this in mind, we leave `is_pseudoref_syntax()` as is and create
> `is_pseudoref()` which is stricter. Ideally we'd want to move the new
> syntax checks to `is_pseudoref_syntax()` but a prerequisite for this
> would be to actually remove the exception list by converting those
> pseudorefs to also contain a '_HEAD' suffix and perhaps move bisect
> related files like 'BISECT_START' to a new directory similar to the
> 'rebase-merge' directory.
> 
> Helped-by: Jeff King <peff@peff.net>
> Signed-off-by: Karthik Nayak <karthik.188@gmail.com>
> ---
>  refs.c | 41 +++++++++++++++++++++++++++++++++++++++++
>  refs.h |  3 +++
>  2 files changed, 44 insertions(+)
> 
> diff --git a/refs.c b/refs.c
> index fff343c256..d8e4cf9a11 100644
> --- a/refs.c
> +++ b/refs.c
> @@ -860,6 +860,47 @@ static int is_pseudoref_syntax(const char *refname)
>  	return 1;
>  }
>  
> +int is_pseudoref(struct ref_store *refs, const char *refname)
> +{
> +	static const char *const irregular_pseudorefs[] = {
> +		"AUTO_MERGE",
> +		"BISECT_EXPECTED_REV",
> +		"NOTES_MERGE_PARTIAL",
> +		"NOTES_MERGE_REF",
> +		"MERGE_AUTOSTASH",
> +	};
> +	struct object_id oid;
> +	size_t i;
> +
> +	if (!is_pseudoref_syntax(refname))
> +		return 0;
> +
> +	if (ends_with(refname, "_HEAD")) {
> +		refs_resolve_ref_unsafe(refs, refname,
> +   					RESOLVE_REF_READING | RESOLVE_REF_NO_RECURSE,
> +   					&oid, NULL);
> +   		return !is_null_oid(&oid);
> +	}

I think it's quite confusing that `is_pseudoref()` not only checks
whether the refname may be a pseudoref, but also whether it actually
exists. Furthermore, why is a pseudoref only considered to exist in case
it's not a symbolic ref? That sounds overly restrictive to me.

So I think this at least needs to be renamed. But I find it really hard
to come up with a proper name here because in my opinion the function
does too much. `is_existing_pseudoref()` feels much too specific to me.
Also, the "reftable" backend wouldn't need to check whether the ref
exists, but only whether a name that it encounters is a pseudoref name
or not.

> +	for (i = 0; i < ARRAY_SIZE(irregular_pseudorefs); i++)
> +		if (!strcmp(refname, irregular_pseudorefs[i])) {
> +			refs_resolve_ref_unsafe(refs, refname,
> +   						RESOLVE_REF_READING | RESOLVE_REF_NO_RECURSE,
> +   						&oid, NULL);
> +			return !is_null_oid(&oid);
> +		}
> +
> +	return 0;
> +}
> +
> +int is_headref(struct ref_store *refs, const char *refname)
> +{
> +	if (!strcmp(refname, "HEAD"))
> +		return refs_ref_exists(refs, refname);
> +
> +	return 0;
> +}

The same comment applies here, as well.

I also worry a bit about the API we have. It becomes really hard to
figure out which function to call now as the API surface seems to
explode. We have:

  - is_pseudoref_syntax
  - is_pseudoref
  - is_headref
  - check_refname_format
  - refname_is_safe

I wonder whether we can maybe consolidate the interface into one or
maybe even two functions where the behaviour can be tweaked with a flag
field. Something like `refname_is_valid()` with a bunch of flags:

  - REFNAME_ACCEPT_HEAD to accept "HEAD"
  - REFNAME_ACCEPT_PSEUDOREF to accept all of the refs ending with
    "_HEAD" or being one of the irregular pseudorefs.
  - REFNAME_ACCEPT_INVALID_BUT_SAFE to accept refnames which aren't
    valid, but which would pass `refname_is_safe()`.

Another alternative could be something like `classify_refname()` that
accepts a refname and returns an enum saying what kind of ref something
is.

Given that this topic won't be included in Git v2.44 anymore, I think
that opening this can of worms would be sensible now.

Patrick

>  static int is_current_worktree_ref(const char *ref) {
>  	return is_pseudoref_syntax(ref) || is_per_worktree_ref(ref);
>  }
> diff --git a/refs.h b/refs.h
> index 303c5fac4d..f66cdd731c 100644
> --- a/refs.h
> +++ b/refs.h
> @@ -1023,4 +1023,7 @@ extern struct ref_namespace_info ref_namespace[NAMESPACE__COUNT];
>   */
>  void update_ref_namespace(enum ref_namespace namespace, char *ref);
>  
> +int is_pseudoref(struct ref_store *refs, const char *refname);
> +int is_headref(struct ref_store *refs, const char *refname);
> +
>  #endif /* REFS_H */
> -- 
> 2.43.GIT
> 

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

  reply	other threads:[~2024-02-12 12:47 UTC|newest]

Thread overview: 94+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-01-19 14:27 [PATCH 0/5] for-each-ref: print all refs on empty string pattern Karthik Nayak
2024-01-19 14:27 ` [PATCH 1/5] refs: expose `is_pseudoref_syntax()` Karthik Nayak
2024-01-19 20:37   ` Junio C Hamano
2024-01-22 15:40     ` Karthik Nayak
2024-01-19 14:27 ` [PATCH 2/5] refs: make `is_pseudoref_syntax()` stricter Karthik Nayak
2024-01-19 20:44   ` Junio C Hamano
2024-01-22 20:13   ` Phillip Wood
2024-01-22 20:22     ` Junio C Hamano
2024-01-23 11:03       ` Phillip Wood
2024-01-23 12:49         ` Karthik Nayak
2024-01-23 16:40           ` phillip.wood123
2024-01-23 17:46           ` Junio C Hamano
2024-01-23 17:38         ` Junio C Hamano
2024-01-23 11:16       ` Patrick Steinhardt
2024-01-23 16:30         ` Phillip Wood
2024-01-23 17:44         ` Junio C Hamano
2024-01-24  8:51           ` Patrick Steinhardt
2024-01-19 14:27 ` [PATCH 3/5] refs: extract out `loose_fill_ref_dir_regular_file()` Karthik Nayak
2024-01-19 14:27 ` [PATCH 4/5] refs: introduce `refs_for_each_all_refs()` Karthik Nayak
2024-01-19 20:57   ` Junio C Hamano
2024-01-22 15:48     ` Karthik Nayak
2024-01-22 17:45       ` Junio C Hamano
2024-01-19 14:27 ` [PATCH 5/5] for-each-ref: avoid filtering on empty pattern Karthik Nayak
2024-01-24 15:27 ` [PATCH v2 0/4] for-each-ref: print all refs on empty string pattern Karthik Nayak
2024-01-24 15:27   ` [PATCH v2 1/4] refs: introduce `is_pseudoref()` and `is_headref()` Karthik Nayak
2024-01-24 19:09     ` Junio C Hamano
2024-01-25 16:20       ` Karthik Nayak
2024-01-25 16:28         ` Junio C Hamano
2024-01-25 21:48           ` Karthik Nayak
2024-01-24 15:27   ` [PATCH v2 2/4] refs: extract out `loose_fill_ref_dir_regular_file()` Karthik Nayak
2024-01-24 15:27   ` [PATCH v2 3/4] refs: introduce `refs_for_each_all_refs()` Karthik Nayak
2024-01-24 15:27   ` [PATCH v2 4/4] for-each-ref: avoid filtering on empty pattern Karthik Nayak
2024-01-29 11:35 ` [PATCH v3 0/4] for-each-ref: print all refs on empty string pattern Karthik Nayak
2024-01-29 11:35   ` [PATCH v3 1/4] refs: introduce `is_pseudoref()` and `is_headref()` Karthik Nayak
2024-02-07  1:48     ` Jeff King
2024-02-07  9:27       ` Karthik Nayak
2024-01-29 11:35   ` [PATCH v3 2/4] refs: extract out `loose_fill_ref_dir_regular_file()` Karthik Nayak
2024-01-29 11:35   ` [PATCH v3 3/4] refs: introduce `refs_for_each_all_refs()` Karthik Nayak
2024-01-29 11:35   ` [PATCH v3 4/4] for-each-ref: avoid filtering on empty pattern Karthik Nayak
2024-02-05 18:48     ` Phillip Wood
2024-02-06  5:33       ` Patrick Steinhardt
2024-02-06 10:49         ` Phillip Wood
2024-02-06  8:52       ` Karthik Nayak
2024-02-06 13:55         ` Phillip Wood
2024-02-06 15:30           ` Karthik Nayak
2024-02-06 17:03           ` Junio C Hamano
2024-02-06 18:47             ` Junio C Hamano
2024-02-06 22:10               ` Karthik Nayak
2024-02-06 22:16                 ` Junio C Hamano
2024-02-07 14:10                   ` Karthik Nayak
2024-02-07 16:00                     ` Junio C Hamano
2024-02-07 16:18                       ` Karthik Nayak
2024-02-07 16:46                         ` Junio C Hamano
2024-02-07 17:02                           ` Karthik Nayak
2024-02-08  8:50                             ` Patrick Steinhardt
2024-02-08 17:04                               ` Junio C Hamano
2024-02-08 17:24                                 ` Patrick Steinhardt
2024-02-08 17:53                                   ` Junio C Hamano
2024-02-09  8:08                                     ` Patrick Steinhardt
2024-02-09 17:15                                       ` Junio C Hamano
2024-02-09 18:27                                         ` Karthik Nayak
2024-02-12  6:51                                           ` Patrick Steinhardt
2024-02-08 10:28                   ` Phillip Wood
2024-02-08 17:07                     ` Junio C Hamano
2024-02-07  7:48                 ` Patrick Steinhardt
2024-02-07 16:01                   ` Junio C Hamano
2024-01-29 20:37   ` [PATCH v3 0/4] for-each-ref: print all refs on empty string pattern Junio C Hamano
2024-02-11 18:39 ` [PATCH v4 0/5] for-each-ref: add '--include-root-refs' option Karthik Nayak
2024-02-11 18:39   ` [PATCH v4 1/5] refs: introduce `is_pseudoref()` and `is_headref()` Karthik Nayak
2024-02-12 12:47     ` Patrick Steinhardt [this message]
2024-02-12 17:01       ` Junio C Hamano
2024-02-13 15:48       ` Karthik Nayak
2024-02-13 19:42       ` Junio C Hamano
2024-02-14 10:28         ` Karthik Nayak
2024-02-14 16:59           ` Junio C Hamano
2024-02-14 18:15             ` Karthik Nayak
2024-02-12 18:05     ` Junio C Hamano
2024-02-11 18:39   ` [PATCH v4 2/5] refs: extract out `loose_fill_ref_dir_regular_file()` Karthik Nayak
2024-02-11 18:39   ` [PATCH v4 3/5] refs: introduce `refs_for_each_include_root_refs()` Karthik Nayak
2024-02-11 18:39   ` [PATCH v4 4/5] ref-filter: rename 'FILTER_REFS_ALL' to 'FILTER_REFS_REGULAR' Karthik Nayak
2024-02-11 18:39   ` [PATCH v4 5/5] for-each-ref: add new option to include root refs Karthik Nayak
2024-02-22  8:46     ` Patrick Steinhardt
2024-02-22 12:57       ` Karthik Nayak
2024-02-22 13:17         ` Patrick Steinhardt
2024-02-23 10:01 ` [PATCH v5 0/5] for-each-ref: add '--include-root-refs' option Karthik Nayak
2024-02-23 10:01   ` [PATCH v5 1/5] refs: introduce `is_pseudoref()` and `is_headref()` Karthik Nayak
2024-02-23 10:01   ` [PATCH v5 2/5] refs: extract out `loose_fill_ref_dir_regular_file()` Karthik Nayak
2024-02-23 10:01   ` [PATCH v5 3/5] refs: introduce `refs_for_each_include_root_refs()` Karthik Nayak
2024-02-23 10:01   ` [PATCH v5 4/5] ref-filter: rename 'FILTER_REFS_ALL' to 'FILTER_REFS_REGULAR' Karthik Nayak
2024-02-23 10:01   ` [PATCH v5 5/5] for-each-ref: add new option to include root refs Karthik Nayak
2024-02-23 18:41   ` [PATCH v5 0/5] for-each-ref: add '--include-root-refs' option Junio C Hamano
2024-02-23 20:13     ` Junio C Hamano
2024-02-27  7:39   ` Patrick Steinhardt
2024-02-27 16:54     ` 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=ZcoTbRxIaGmTd4fJ@tanuki \
    --to=ps@pks.im \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=karthik.188@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.