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
Subject: Re: [PATCH v4 5/5] for-each-ref: add new option to include root refs
Date: Thu, 22 Feb 2024 09:46:06 +0100	[thread overview]
Message-ID: <ZdcJzs2vNkHJsjyN@tanuki> (raw)
In-Reply-To: <20240211183923.131278-6-karthik.188@gmail.com>

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

On Sun, Feb 11, 2024 at 07:39:23PM +0100, Karthik Nayak wrote:
> The git-for-each-ref(1) command doesn't provide a way to print root refs
> i.e pseudorefs and HEAD with the regular "refs/" prefixed refs.
> 
> This commit adds a new option "--include-root-refs" to
> git-for-each-ref(1). When used this would also print pseudorefs and HEAD
> for the current worktree.
> 
> Signed-off-by: Karthik Nayak <karthik.188@gmail.com>
> ---
>  Documentation/git-for-each-ref.txt |  5 ++++-
>  builtin/for-each-ref.c             | 11 ++++++++---
>  ref-filter.c                       | 27 +++++++++++++++++++++++++-
>  ref-filter.h                       |  5 ++++-
>  refs/reftable-backend.c            | 11 +++++++----
>  t/t6302-for-each-ref-filter.sh     | 31 ++++++++++++++++++++++++++++++
>  6 files changed, 80 insertions(+), 10 deletions(-)
> 
> diff --git a/Documentation/git-for-each-ref.txt b/Documentation/git-for-each-ref.txt
> index 3a9ad91b7a..c1dd12b93c 100644
> --- a/Documentation/git-for-each-ref.txt
> +++ b/Documentation/git-for-each-ref.txt
> @@ -10,7 +10,7 @@ SYNOPSIS
>  [verse]
>  'git for-each-ref' [--count=<count>] [--shell|--perl|--python|--tcl]
>  		   [(--sort=<key>)...] [--format=<format>]
> -		   [ --stdin | <pattern>... ]
> +		   [--include-root-refs] [ --stdin | <pattern>... ]
>  		   [--points-at=<object>]
>  		   [--merged[=<object>]] [--no-merged[=<object>]]
>  		   [--contains[=<object>]] [--no-contains[=<object>]]
> @@ -105,6 +105,9 @@ TAB %(refname)`.
>  	any excluded pattern(s) are shown. Matching is done using the
>  	same rules as `<pattern>` above.
>  
> +--include-root-refs::
> +	List root refs (HEAD and pseudorefs) apart from regular refs.
> +
>  FIELD NAMES
>  -----------
>  
> diff --git a/builtin/for-each-ref.c b/builtin/for-each-ref.c
> index 23d352e371..9ed146dad3 100644
> --- a/builtin/for-each-ref.c
> +++ b/builtin/for-each-ref.c
> @@ -20,10 +20,10 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix)
>  {
>  	struct ref_sorting *sorting;
>  	struct string_list sorting_options = STRING_LIST_INIT_DUP;
> -	int icase = 0;
> +	int icase = 0, include_root_refs = 0, from_stdin = 0;
>  	struct ref_filter filter = REF_FILTER_INIT;
>  	struct ref_format format = REF_FORMAT_INIT;
> -	int from_stdin = 0;
> +	unsigned int flags = FILTER_REFS_REGULAR;
>  	struct strvec vec = STRVEC_INIT;
>  
>  	struct option opts[] = {
> @@ -53,6 +53,7 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix)
>  		OPT_NO_CONTAINS(&filter.no_commit, N_("print only refs which don't contain the commit")),
>  		OPT_BOOL(0, "ignore-case", &icase, N_("sorting and filtering are case insensitive")),
>  		OPT_BOOL(0, "stdin", &from_stdin, N_("read reference patterns from stdin")),
> +		OPT_BOOL(0, "include-root-refs", &include_root_refs, N_("also include HEAD ref and pseudorefs")),
>  		OPT_END(),
>  	};
>  
> @@ -96,8 +97,12 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix)
>  		filter.name_patterns = argv;
>  	}
>  
> +	if (include_root_refs) {
> +		flags |= FILTER_REFS_ROOT_REFS;
> +	}

Nit: we don't use braces for single-line blocks.

> +
>  	filter.match_as_path = 1;
> -	filter_and_format_refs(&filter, FILTER_REFS_REGULAR, sorting, &format);
> +	filter_and_format_refs(&filter, flags, sorting, &format);
>  
>  	ref_filter_clear(&filter);
>  	ref_sorting_release(sorting);
> diff --git a/ref-filter.c b/ref-filter.c
> index acb960e35c..0e83e29390 100644
> --- a/ref-filter.c
> +++ b/ref-filter.c
> @@ -2628,6 +2628,12 @@ static int for_each_fullref_in_pattern(struct ref_filter *filter,
>  				       each_ref_fn cb,
>  				       void *cb_data)
>  {
> +	if (filter->kind == FILTER_REFS_KIND_MASK) {
> +		/* in this case, we want to print all refs including root refs. */

Nit: s/in/In, as this is a full sentence.

> +		return refs_for_each_include_root_refs(get_main_ref_store(the_repository),
> +						       cb, cb_data);
> +	}
> +
>  	if (!filter->match_as_path) {
>  		/*
>  		 * in this case, the patterns are applied after
> @@ -2750,6 +2756,9 @@ static int ref_kind_from_refname(const char *refname)
>  			return ref_kind[i].kind;
>  	}
>  
> +	if (is_pseudoref(get_main_ref_store(the_repository), refname))
> +		return FILTER_REFS_PSEUDOREFS;
> +
>  	return FILTER_REFS_OTHERS;
>  }
>  
> @@ -2781,6 +2790,16 @@ static struct ref_array_item *apply_ref_filter(const char *refname, const struct
>  
>  	/* Obtain the current ref kind from filter_ref_kind() and ignore unwanted refs. */
>  	kind = filter_ref_kind(filter, refname);
> +
> +	/*
> +	 * When printing HEAD with all other refs, we want to apply the same formatting
> +	 * rules as the other refs, so we simply ask it to be treated as a pseudoref.
> +	 */
> +	if (filter->kind == FILTER_REFS_KIND_MASK && kind == FILTER_REFS_DETACHED_HEAD)
> +		kind = FILTER_REFS_PSEUDOREFS;

I'm not sure why exactly we need to munge the kind here. Would be great
if the comment explained what the actual difference would be.

> +	else if (!(kind & filter->kind))
> +		return NULL;
> +
>  	if (!(kind & filter->kind))
>  		return NULL;

This condition here is duplicated now, isn't it?

Patrick

> @@ -3049,7 +3068,13 @@ static int do_filter_refs(struct ref_filter *filter, unsigned int type, each_ref
>  			ret = for_each_fullref_in("refs/tags/", fn, cb_data);
>  		else if (filter->kind & FILTER_REFS_REGULAR)
>  			ret = for_each_fullref_in_pattern(filter, fn, cb_data);
> -		if (!ret && (filter->kind & FILTER_REFS_DETACHED_HEAD))
> +
> +		/*
> +		 * When printing all ref types, HEAD is already included,
> +		 * so we don't want to print HEAD again.
> +		 */
> +		if (!ret && (filter->kind != FILTER_REFS_KIND_MASK) &&
> +		    (filter->kind & FILTER_REFS_DETACHED_HEAD))
>  			head_ref(fn, cb_data);
>  	}
>  
> diff --git a/ref-filter.h b/ref-filter.h
> index 5416936800..0ca28d2bba 100644
> --- a/ref-filter.h
> +++ b/ref-filter.h
> @@ -22,7 +22,10 @@
>  #define FILTER_REFS_REGULAR        (FILTER_REFS_TAGS | FILTER_REFS_BRANCHES | \
>  				    FILTER_REFS_REMOTES | FILTER_REFS_OTHERS)
>  #define FILTER_REFS_DETACHED_HEAD  0x0020
> -#define FILTER_REFS_KIND_MASK      (FILTER_REFS_REGULAR | FILTER_REFS_DETACHED_HEAD)
> +#define FILTER_REFS_PSEUDOREFS     0x0040
> +#define FILTER_REFS_ROOT_REFS      (FILTER_REFS_DETACHED_HEAD | FILTER_REFS_PSEUDOREFS)
> +#define FILTER_REFS_KIND_MASK      (FILTER_REFS_REGULAR | FILTER_REFS_DETACHED_HEAD | \
> +				    FILTER_REFS_PSEUDOREFS)
>  
>  struct atom_value;
>  struct ref_sorting;
> diff --git a/refs/reftable-backend.c b/refs/reftable-backend.c
> index a14f2ad7f4..c23a516ac2 100644
> --- a/refs/reftable-backend.c
> +++ b/refs/reftable-backend.c
> @@ -364,12 +364,15 @@ static int reftable_ref_iterator_advance(struct ref_iterator *ref_iterator)
>  			break;
>  
>  		/*
> -		 * The files backend only lists references contained in
> -		 * "refs/". We emulate the same behaviour here and thus skip
> -		 * all references that don't start with this prefix.
> +		 * The files backend only lists references contained in "refs/" unless
> +		 * the root refs are to be included. We emulate the same behaviour here.
>  		 */
> -		if (!starts_with(iter->ref.refname, "refs/"))
> +		if (!starts_with(iter->ref.refname, "refs/") &&
> +		    !(iter->flags & DO_FOR_EACH_INCLUDE_ROOT_REFS &&
> +		     (is_pseudoref(&iter->refs->base, iter->ref.refname) ||
> +		      is_headref(&iter->refs->base, iter->ref.refname)))) {
>  			continue;
> +		}
>  
>  		if (iter->prefix &&
>  		    strncmp(iter->prefix, iter->ref.refname, strlen(iter->prefix))) {
> diff --git a/t/t6302-for-each-ref-filter.sh b/t/t6302-for-each-ref-filter.sh
> index 82f3d1ea0f..948f1bb5f4 100755
> --- a/t/t6302-for-each-ref-filter.sh
> +++ b/t/t6302-for-each-ref-filter.sh
> @@ -31,6 +31,37 @@ test_expect_success 'setup some history and refs' '
>  	git update-ref refs/odd/spot main
>  '
>  
> +test_expect_success '--include-root-refs pattern prints pseudorefs' '
> +	cat >expect <<-\EOF &&
> +	HEAD
> +	ORIG_HEAD
> +	refs/heads/main
> +	refs/heads/side
> +	refs/odd/spot
> +	refs/tags/annotated-tag
> +	refs/tags/doubly-annotated-tag
> +	refs/tags/doubly-signed-tag
> +	refs/tags/four
> +	refs/tags/one
> +	refs/tags/signed-tag
> +	refs/tags/three
> +	refs/tags/two
> +	EOF
> +	git update-ref ORIG_HEAD main &&
> +	git for-each-ref --format="%(refname)" --include-root-refs >actual &&
> +	test_cmp expect actual
> +'
> +
> +test_expect_success '--include-root-refs with other patterns' '
> +	cat >expect <<-\EOF &&
> +	HEAD
> +	ORIG_HEAD
> +	EOF
> +	git update-ref ORIG_HEAD main &&
> +	git for-each-ref --format="%(refname)" --include-root-refs "*HEAD" >actual &&
> +	test_cmp expect actual
> +'
> +
>  test_expect_success 'filtering with --points-at' '
>  	cat >expect <<-\EOF &&
>  	refs/heads/main
> -- 
> 2.43.GIT
> 

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

  reply	other threads:[~2024-02-22  8:46 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
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 [this message]
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=ZdcJzs2vNkHJsjyN@tanuki \
    --to=ps@pks.im \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=karthik.188@gmail.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.
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.