* [GSoC][RFC PATCH 0/2] Add refs list subcommand
@ 2025-06-14 7:05 Meet Soni
2025-06-14 7:05 ` [GSoC][RFC PATCH 1/2] builtin/refs: add " Meet Soni
` (2 more replies)
0 siblings, 3 replies; 13+ messages in thread
From: Meet Soni @ 2025-06-14 7:05 UTC (permalink / raw)
To: git; +Cc: Meet Soni
This patch series introduces the git refs list subcommand, as part of a
longer-term goal to consolidate and modernize ref listing functionality
currently split between git-show-ref(1) and git-for-each-ref(1).
The initial implementation focuses on mirroring the behavior of
git-show-ref, providing support for filtering by --branches, --tags, and
--head, and implementing pattern matching similar to the legacy command.
This ensures backward compatibility.
That said, git-for-each-ref(1) offers more flexible pattern matching and
we acknowledge that its style may be a better fit in the long run. As
such, this RFC deliberately starts with the show-ref matching semantics
to solicit feedback on whether to switch to for-each-ref style matching
as the default, with a compatibility flag to preserve legacy behavior.
It's also worth highlighting that several options from git-show-ref are
intended to be supported in the git refs list subcommand. These include
flags such as '--abbrev', '--quiet', '--dereference', '--hash', and
'--exclude-existing'. While this series focuses on core functionality
and pattern matching, these additional options are within scope for
future patches.
Additionally, the git-for-each-ref(1) command offers a rich set of
features that would be valuable to incorporate into git refs list. At
this point, all of its existing options appear to provide meaningful
functionality, and my current thinking is to support them incrementally
as part of expanding this subcommand. I'd appreciate feedback on whether
there are any options that should be reconsidered or excluded in this
consolidation effort.
This RFC is meant to start a broader discussion on:
- The desired default behavior of pattern matching in git refs list
- Which features from both git-show-ref and git-for-each-ref should be
preserved, rethought, or dropped
- How much backward compatibility we want to offer, and through what
interface (e.g., compatibility flags)
Feedback and thoughts on these topics would be very welcome.
Meet Soni (2):
builtin/refs: add list subcommand
t: add tests for refs list subcommand
Documentation/git-refs.adoc | 25 ++++++++
builtin/refs.c | 110 ++++++++++++++++++++++++++++++++++++
t/meson.build | 1 +
t/t1461-refs-list.sh | 95 +++++++++++++++++++++++++++++++
4 files changed, 231 insertions(+)
create mode 100755 t/t1461-refs-list.sh
--
2.34.1
^ permalink raw reply [flat|nested] 13+ messages in thread* [GSoC][RFC PATCH 1/2] builtin/refs: add list subcommand 2025-06-14 7:05 [GSoC][RFC PATCH 0/2] Add refs list subcommand Meet Soni @ 2025-06-14 7:05 ` Meet Soni 2025-06-14 7:05 ` [GSoC][RFC PATCH 2/2] t: add tests for refs " Meet Soni 2025-06-14 23:45 ` [GSoC][RFC PATCH 0/2] Add " Junio C Hamano 2 siblings, 0 replies; 13+ messages in thread From: Meet Soni @ 2025-06-14 7:05 UTC (permalink / raw) To: git Cc: Meet Soni, Patrick Steinhardt, shejialuo, Karthik Nayak, Junio C Hamano, John Cai Git's reference management is distributed across multiple commands and as part of an ongoing effort to streamline and modernize reference handling, we are beginning to consolidate these operations into a cohesive `git refs` command. Add a `list` subcommand to `git refs` as a modern replacement for `git show-ref`, consolidating ref listing functionality under the unified `git refs` command. The initial implementation supports the following options from `git show-ref`: - --head - --tags - --branches - patterns argument For large changes, this patch limits itself to the basic ref listing and commonly used flags. Remaining options will be added incrementally in follow-up patches, guided by feedback from the mailing list. Mentored-by: Patrick Steinhardt <ps@pks.im> Mentored-by: shejialuo <shejialuo@gmail.com> Mentored-by: Karthik Nayak <karthik.188@gmail.com> Signed-off-by: Meet Soni <meetsoni3017@gmail.com> --- Documentation/git-refs.adoc | 25 ++++++++ builtin/refs.c | 110 ++++++++++++++++++++++++++++++++++++ 2 files changed, 135 insertions(+) diff --git a/Documentation/git-refs.adoc b/Documentation/git-refs.adoc index 4d6dc994f9..397c3ceb01 100644 --- a/Documentation/git-refs.adoc +++ b/Documentation/git-refs.adoc @@ -11,6 +11,7 @@ SYNOPSIS [synopsis] git refs migrate --ref-format=<format> [--no-reflog] [--dry-run] git refs verify [--strict] [--verbose] +git refs list [--head] [--branches] [--tag] [--] [<pattern>...] DESCRIPTION ----------- @@ -26,6 +27,12 @@ migrate:: verify:: Verify reference database consistency. +list:: + Displays references available in a local repository along with the associated + commit IDs. Results can be filtered using a pattern. + + By default, shows the tags, heads, and remote refs. + OPTIONS ------- @@ -57,6 +64,24 @@ The following options are specific to 'git refs verify': --verbose:: When verifying the reference database consistency, be chatty. +The following options are specific to 'git refs list': + +--head:: + Show the HEAD reference, even if it would normally be filtered out. + +--branches:: +--tags:: + Limit to local branches and local tags, respectively. These options + are not mutually exclusive; when given both, references stored in + "refs/heads" and "refs/tags" are displayed. + +<pattern>...:: + Show references matching one or more patterns. Patterns are matched from + the end of the full name, and only complete parts are matched, e.g. + 'master' matches 'refs/heads/master', 'refs/remotes/origin/master', + 'refs/tags/jedi/master' but not 'refs/heads/mymaster' or + 'refs/remotes/master/jedi'. + KNOWN LIMITATIONS ----------------- diff --git a/builtin/refs.c b/builtin/refs.c index 998d2a2c1c..c098132191 100644 --- a/builtin/refs.c +++ b/builtin/refs.c @@ -2,6 +2,9 @@ #include "builtin.h" #include "config.h" #include "fsck.h" +#include "hex.h" +#include "object-name.h" +#include "object-store.h" #include "parse-options.h" #include "refs.h" #include "strbuf.h" @@ -13,6 +16,9 @@ #define REFS_VERIFY_USAGE \ N_("git refs verify [--strict] [--verbose]") +#define REFS_LIST_USAGE \ + N_("git refs list [--head] [--branches] [--tag] [--] [<pattern>...]") + static int cmd_refs_migrate(int argc, const char **argv, const char *prefix, struct repository *repo UNUSED) { @@ -101,6 +107,108 @@ static int cmd_refs_verify(int argc, const char **argv, const char *prefix, return ret; } +struct list_options { + unsigned int show_head; + unsigned int filter_branches; + unsigned int filter_tags; + unsigned int found_match; + const char **patterns; +}; + +static void print_ref(const char *refname, const struct object_id *oid) +{ + const char *hex; + + hex = oid_to_hex(oid); + if (!has_object(the_repository, oid, + HAS_OBJECT_RECHECK_PACKED | HAS_OBJECT_FETCH_PROMISOR)) + die("git refs list: bad ref %s (%s)", refname, + hex); + + printf("%s %s\n", hex, refname); +} + +static int list_ref(const char *refname, const char *referent UNUSED, + const struct object_id *oid, int flag UNUSED, void *cbdata) +{ + struct list_options *data = cbdata; + + if (data->show_head && !strcmp(refname, "HEAD")) + goto match; + + if (data->patterns) { + int reflen = strlen(refname); + const char **pattern_ptr = data->patterns, *pattern; + while ((pattern = *pattern_ptr++) != NULL) { + int pattern_len = strlen(pattern); + if (pattern_len > reflen) + continue; + if (memcmp(pattern, refname + reflen - pattern_len, pattern_len)) + continue; + if (pattern_len == reflen) + goto match; + if (refname[reflen - pattern_len - 1] == '/') + goto match; + } + return 0; + } + +match: + data->found_match++; + + print_ref(refname, oid); + + return 0; +} + +static int cmd_refs_list(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) +{ + struct list_options list_opts = {0}; + const char * const list_usage[] = { + REFS_LIST_USAGE, + NULL, + }; + struct option options[] = { + OPT_BOOL(0, "head", &list_opts.show_head, + N_("show the HEAD reference, even if it would be filtered out")), + OPT_BOOL(0, "tags", &list_opts.filter_tags, + N_("only show tags (can be combined with --branches)")), + OPT_BOOL(0, "branches", &list_opts.filter_branches, + N_("only show branches (can be combined with --tags)")), + OPT_END(), + }; + + argc = parse_options(argc, argv, prefix, options, list_usage, 0); + + if (argv && *argv) + list_opts.patterns = argv; + + if (list_opts.show_head) + refs_head_ref(get_main_ref_store(the_repository), list_ref, + &list_opts); + + if (list_opts.filter_tags || list_opts.filter_branches) { + if (list_opts.filter_branches) + refs_for_each_fullref_in(get_main_ref_store(the_repository), + "refs/heads/", NULL, + list_ref, &list_opts); + + if (list_opts.filter_tags) + refs_for_each_fullref_in(get_main_ref_store(the_repository), + "refs/tags/", NULL, + list_ref, &list_opts); + } else { + refs_for_each_ref(get_main_ref_store(the_repository), + list_ref, &list_opts); + } + + if (!list_opts.found_match) + return 1; + + return 0; +} + int cmd_refs(int argc, const char **argv, const char *prefix, @@ -109,12 +217,14 @@ int cmd_refs(int argc, const char * const refs_usage[] = { REFS_MIGRATE_USAGE, REFS_VERIFY_USAGE, + REFS_LIST_USAGE, NULL, }; parse_opt_subcommand_fn *fn = NULL; struct option opts[] = { OPT_SUBCOMMAND("migrate", &fn, cmd_refs_migrate), OPT_SUBCOMMAND("verify", &fn, cmd_refs_verify), + OPT_SUBCOMMAND("list", &fn, cmd_refs_list), OPT_END(), }; -- 2.34.1 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* [GSoC][RFC PATCH 2/2] t: add tests for refs list subcommand 2025-06-14 7:05 [GSoC][RFC PATCH 0/2] Add refs list subcommand Meet Soni 2025-06-14 7:05 ` [GSoC][RFC PATCH 1/2] builtin/refs: add " Meet Soni @ 2025-06-14 7:05 ` Meet Soni 2025-06-14 23:45 ` [GSoC][RFC PATCH 0/2] Add " Junio C Hamano 2 siblings, 0 replies; 13+ messages in thread From: Meet Soni @ 2025-06-14 7:05 UTC (permalink / raw) To: git; +Cc: Meet Soni, Patrick Steinhardt, shejialuo, Karthik Nayak, Junio C Hamano Test the implemented functionality of `git refs list` and verify backward compatibility with `git show-ref` for the supported flags and patterns. Mentored-by: Patrick Steinhardt <ps@pks.im> Mentored-by: shejialuo <shejialuo@gmail.com> Mentored-by: Karthik Nayak <karthik.188@gmail.com> Signed-off-by: Meet Soni <meetsoni3017@gmail.com> --- t/meson.build | 1 + t/t1461-refs-list.sh | 95 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100755 t/t1461-refs-list.sh diff --git a/t/meson.build b/t/meson.build index d052fc3e23..c9d0863490 100644 --- a/t/meson.build +++ b/t/meson.build @@ -224,6 +224,7 @@ integration_tests = [ 't1450-fsck.sh', 't1451-fsck-buffer.sh', 't1460-refs-migrate.sh', + 't1461-refs-list.sh', 't1500-rev-parse.sh', 't1501-work-tree.sh', 't1502-rev-parse-parseopt.sh', diff --git a/t/t1461-refs-list.sh b/t/t1461-refs-list.sh new file mode 100755 index 0000000000..d628a193fc --- /dev/null +++ b/t/t1461-refs-list.sh @@ -0,0 +1,95 @@ +#!/bin/sh + +test_description='Verify git refs list functionality and compatibility with git show-ref' +GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main +export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME + +. ./test-lib.sh + +test_expect_success setup ' + test_commit --annotate A && + git checkout -b side && + test_commit --annotate B && + git checkout main && + test_commit C && + git branch B A^0 +' + +test_expect_success 'refs list --branches, --tags, --head, pattern' ' + for branch in B main side + do + echo $(git rev-parse refs/heads/$branch) refs/heads/$branch || return 1 + done >expect.branches && + git refs list --branches >actual && + test_cmp expect.branches actual && + + for tag in A B C + do + echo $(git rev-parse refs/tags/$tag) refs/tags/$tag || return 1 + done >expect.tags && + git refs list --tags >actual && + test_cmp expect.tags actual && + + cat expect.branches expect.tags >expect && + git refs list --branches --tags >actual && + test_cmp expect actual && + + { + echo $(git rev-parse HEAD) HEAD && + cat expect.branches expect.tags + } >expect && + git refs list --branches --tags --head >actual && + test_cmp expect actual && + + { + echo $(git rev-parse HEAD) HEAD && + echo $(git rev-parse refs/heads/B) refs/heads/B && + echo $(git rev-parse refs/tags/B) refs/tags/B + } >expect && + git refs list --head B >actual && + test_cmp expect actual && + + { + echo $(git rev-parse refs/heads/B) refs/heads/B && + echo $(git rev-parse refs/tags/A) refs/tags/A && + echo $(git rev-parse refs/tags/B) refs/tags/B + } >expect && + git refs list A B >actual && + test_cmp expect actual +' + +test_expect_success 'Backward compatibility with show-ref' ' + git show-ref >expect&& + git refs list >actual&& + test_cmp expect actual && + + git show-ref --branches >expect && + git refs list --branches >actual && + test_cmp expect actual && + + git show-ref --tags >expect && + git refs list --tags >actual && + test_cmp expect actual && + + git show-ref --head >expect && + git refs list --head >actual && + test_cmp expect actual && + + git show-ref --branches --tags --head >expect && + git refs list --branches --tags --head >actual && + test_cmp expect actual && + + git show-ref B >expect && + git refs list B >actual && + test_cmp expect actual && + + git show-ref --head B >expect && + git refs list --head B >actual && + test_cmp expect actual && + + git show-ref A B >expect && + git refs list A B >actual && + test_cmp expect actual +' + +test_done -- 2.34.1 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [GSoC][RFC PATCH 0/2] Add refs list subcommand 2025-06-14 7:05 [GSoC][RFC PATCH 0/2] Add refs list subcommand Meet Soni 2025-06-14 7:05 ` [GSoC][RFC PATCH 1/2] builtin/refs: add " Meet Soni 2025-06-14 7:05 ` [GSoC][RFC PATCH 2/2] t: add tests for refs " Meet Soni @ 2025-06-14 23:45 ` Junio C Hamano 2025-06-17 11:51 ` Meet Soni 2 siblings, 1 reply; 13+ messages in thread From: Junio C Hamano @ 2025-06-14 23:45 UTC (permalink / raw) To: Meet Soni; +Cc: git Meet Soni <meetsoni3017@gmail.com> writes: > This RFC is meant to start a broader discussion on: > > - The desired default behavior of pattern matching in git refs list > > - Which features from both git-show-ref and git-for-each-ref should be > preserved, rethought, or dropped > > - How much backward compatibility we want to offer, and through what > interface (e.g., compatibility flags) > > Feedback and thoughts on these topics would be very welcome. In addition to these three points, 0th point perhaps is "Is it desirable to unify these two commands in the first place?" I only use "show-ref" when I care about a single ref in a script, expecting to be able to switch on its exit status. Everything else I'd use for-each-ref. But then that particular unique advantage of show-ref over for-each-ref can be done with "rev-parse --verify". So, I'd rather not to see yet another command to do the same thing. Rather, is it insufficient to just use for-each-ref or rev-parse, let the sleeping show-ref alone, and be happy? > Meet Soni (2): > builtin/refs: add list subcommand > t: add tests for refs list subcommand > > Documentation/git-refs.adoc | 25 ++++++++ > builtin/refs.c | 110 ++++++++++++++++++++++++++++++++++++ > t/meson.build | 1 + > t/t1461-refs-list.sh | 95 +++++++++++++++++++++++++++++++ > 4 files changed, 231 insertions(+) > create mode 100755 t/t1461-refs-list.sh ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [GSoC][RFC PATCH 0/2] Add refs list subcommand 2025-06-14 23:45 ` [GSoC][RFC PATCH 0/2] Add " Junio C Hamano @ 2025-06-17 11:51 ` Meet Soni 0 siblings, 0 replies; 13+ messages in thread From: Meet Soni @ 2025-06-17 11:51 UTC (permalink / raw) To: Junio C Hamano; +Cc: git On Sun, 15 Jun 2025 at 05:15, Junio C Hamano <gitster@pobox.com> wrote: > > Meet Soni <meetsoni3017@gmail.com> writes: > > > This RFC is meant to start a broader discussion on: > > > > - The desired default behavior of pattern matching in git refs list > > > > - Which features from both git-show-ref and git-for-each-ref should be > > preserved, rethought, or dropped > > > > - How much backward compatibility we want to offer, and through what > > interface (e.g., compatibility flags) > > > > Feedback and thoughts on these topics would be very welcome. > > In addition to these three points, 0th point perhaps is "Is it > desirable to unify these two commands in the first place?" > > I only use "show-ref" when I care about a single ref in a script, > expecting to be able to switch on its exit status. Everything else > I'd use for-each-ref. > > But then that particular unique advantage of show-ref over for-each-ref > can be done with "rev-parse --verify". > > So, I'd rather not to see yet another command to do the same thing. > Rather, is it insufficient to just use for-each-ref or rev-parse, > let the sleeping show-ref alone, and be happy? The broader motivation behind this effort (and the overarching GSoC project) has been to reduce fragmentation in ref-related functionality by gradually consolidating it under the git refs umbrella, aiming for consistency and discoverability. Your point about rev-parse --verify covering show-ref's main utility is well taken. If that truly makes show-ref redundant, then perhaps it makes more sense to focus consolidation efforts around for-each-ref instead. One concern I have is that if we simply replicate for-each-ref under a new name, we may still face the same question: what does this new command add that the old one doesn't already handle? I'd love to hear thoughts on what a modernized or simplified ref-listing interface could look like. Are there features or changes worth exploring that could justify the consolidation? Thanks, Meet ^ permalink raw reply [flat|nested] 13+ messages in thread
* [GSoC][RFC PATCH 0/2] Add refs list subcommand
@ 2025-06-27 7:49 Meet Soni
2025-06-27 18:03 ` Junio C Hamano
0 siblings, 1 reply; 13+ messages in thread
From: Meet Soni @ 2025-06-27 7:49 UTC (permalink / raw)
To: git; +Cc: ps, shejialuo, karthik.188, Meet Soni
This patch series introduces `git refs list` as a modern replacement for
`git for-each-ref`, as part of an effort to consolidate ref-related
functionality under a unified `git refs` command.
Git's ref-related operations are currently handled by several distinct
commands, such as `git show-ref`, `git for-each-ref`, `git update-ref`,
`git pack-refs`, etc. This distribution has a few practical drawbacks:
- Users need to rely on multiple commands for related tasks involving
refs.
- The commands may differ slightly in behavior and option syntax,
leading to inconsistency.
We propose a long-term consolidation effort to bring ref-related
subcommands under the umbrella of a single command: `git refs`.
The implementation of `git refs list` is functionally identical to `git
for-each-ref`. It reuses the same internal logic (cmd_for_each_ref) to
ensure complete backward compatibility. The purpose of this patch is not
to introduce new behavior but to provide an alternate entry point under
the consolidated `git refs` namespace.
The motivation behind this change is twofold:
- Consolidation: Centralizing ref-related operations makes them easier
to discover, use, and maintain.
- Evolution: While the initial goal is parity with existing commands,
this consolidation allows for careful reconsideration of which
features are essential. Over time, we can:
- Remove legacy or obscure options that are no longer needed.
- Add improvements that wouldn't make sense to bolt onto legacy
commands.
- Offering a more consistent and user-friendly surface.
To verify backward compatibility, this patch also includes a test
`t/t1461-refs-list.sh`, which runs the full `t6300-for-each-ref.sh` test
using `git refs list`. The test uses ${GIT_REFS_LIST_CMD:-for-each-ref}
to allow substitution without duplicating tests.
This patch is deliberately conservative: it introduces no behavioral
changes and leaves `for-each-ref` untouched. The goal is to lay
groundwork and demonstrate viability of ref consolidation within `git
refs`.
Going forward, I'd like to initiate a discussion on what the ideal
surface of `git refs list` should look like. Which options and features
from `for-each-ref` should be carried over? Are there any that are
obsolete or overly niche? What improvements might be worth considering
now that we have a new, consolidated interface?
Feedback on this, especially from those who rely on `for-each-ref` in
scripts or tooling would be very helpful.
Meet Soni (2):
builtin/refs: add list subcommand
t: add test for git refs list subcommand
Documentation/git-refs.adoc | 95 ++++++++++
builtin/refs.c | 110 ++++++++++++
t/meson.build | 1 +
t/t1461-refs-list.sh | 8 +
t/t6300-for-each-ref.sh | 333 ++++++++++++++++++------------------
5 files changed, 384 insertions(+), 163 deletions(-)
create mode 100755 t/t1461-refs-list.sh
base-commit: cb3b40381e1d5ee32dde96521ad7cfd68eb308a6
--
2.34.1
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [GSoC][RFC PATCH 0/2] Add refs list subcommand 2025-06-27 7:49 Meet Soni @ 2025-06-27 18:03 ` Junio C Hamano 2025-06-28 8:05 ` shejialuo 2025-06-30 3:53 ` Meet Soni 0 siblings, 2 replies; 13+ messages in thread From: Junio C Hamano @ 2025-06-27 18:03 UTC (permalink / raw) To: Meet Soni; +Cc: git, ps, shejialuo, karthik.188 Meet Soni <meetsoni3017@gmail.com> writes: > - Remove legacy or obscure options that are no longer needed. Such as? > - Add improvements that wouldn't make sense to bolt onto legacy > commands. Such as? While I agree that there may be cases that the above goals in general would bring us improvements, I think neither of these two applies to for-each-ref. People are using for-each-ref to iterate over and enumerate refs already, and if you are to add some new features to "git refs list", they certainly will demand these new goodies to be added to for-each-ref as well. So, I dunno. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [GSoC][RFC PATCH 0/2] Add refs list subcommand 2025-06-27 18:03 ` Junio C Hamano @ 2025-06-28 8:05 ` shejialuo 2025-06-30 14:05 ` Junio C Hamano 2025-06-30 3:53 ` Meet Soni 1 sibling, 1 reply; 13+ messages in thread From: shejialuo @ 2025-06-28 8:05 UTC (permalink / raw) To: Junio C Hamano; +Cc: Meet Soni, git, ps, karthik.188 On Fri, Jun 27, 2025 at 11:03:13AM -0700, Junio C Hamano wrote: > Meet Soni <meetsoni3017@gmail.com> writes: > > > - Remove legacy or obscure options that are no longer needed. > > Such as? > > > - Add improvements that wouldn't make sense to bolt onto legacy > > commands. > > Such as? > > While I agree that there may be cases that the above goals in > general would bring us improvements, I think neither of these two > applies to for-each-ref. People are using for-each-ref to iterate > over and enumerate refs already, and if you are to add some new > features to "git refs list", they certainly will demand these new > goodies to be added to for-each-ref as well. > If so, we would make "git refs list" to place "git for-each-ref" at all. However, in the current implementation, we indeed introduce duplicate code path if we decide to do above. Thanks, Jialuo ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [GSoC][RFC PATCH 0/2] Add refs list subcommand 2025-06-28 8:05 ` shejialuo @ 2025-06-30 14:05 ` Junio C Hamano 2025-07-06 12:58 ` shejialuo 0 siblings, 1 reply; 13+ messages in thread From: Junio C Hamano @ 2025-06-30 14:05 UTC (permalink / raw) To: shejialuo; +Cc: Meet Soni, git, ps, karthik.188 shejialuo <shejialuo@gmail.com> writes: > If so, we would make "git refs list" to place "git for-each-ref" at > all. However, in the current implementation, we indeed introduce > duplicate code path if we decide to do above. I do not know what you meant by your first sentence. If you make "git refs list <anything>" a thin wrapper for "git for-each-ref <anthing>", you can satisfy "I want to teach any and all features related to references to the 'git refs' command" while not penalizing existing users. After all, that is essentially what "git branch" and "git tag" do as their listing mode and supports the featurs from for-each-ref, isn't it? ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [GSoC][RFC PATCH 0/2] Add refs list subcommand 2025-06-30 14:05 ` Junio C Hamano @ 2025-07-06 12:58 ` shejialuo 0 siblings, 0 replies; 13+ messages in thread From: shejialuo @ 2025-07-06 12:58 UTC (permalink / raw) To: Junio C Hamano; +Cc: Meet Soni, git, ps, karthik.188 On Mon, Jun 30, 2025 at 07:05:43AM -0700, Junio C Hamano wrote: > shejialuo <shejialuo@gmail.com> writes: > > > If so, we would make "git refs list" to place "git for-each-ref" at > > all. However, in the current implementation, we indeed introduce > > duplicate code path if we decide to do above. > > I do not know what you meant by your first sentence. > Sorry, I think I made you confused here. My meaning is exactly below what you have said. > If you make "git refs list <anything>" a thin wrapper for "git > for-each-ref <anthing>", you can satisfy "I want to teach any and > all features related to references to the 'git refs' command" while > not penalizing existing users. After all, that is essentially what > "git branch" and "git tag" do as their listing mode and supports the > featurs from for-each-ref, isn't it? That's right. I just want to let Meet know, if we decide to make "git refs list" a wrapper for "git for-each-ref", we need to change the current code design as we introduced repeated code path. --- Sorry for the late reply, as I am extremely busy with my own business. Thanks, Jialuo ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [GSoC][RFC PATCH 0/2] Add refs list subcommand 2025-06-27 18:03 ` Junio C Hamano 2025-06-28 8:05 ` shejialuo @ 2025-06-30 3:53 ` Meet Soni 2025-06-30 20:10 ` Junio C Hamano 1 sibling, 1 reply; 13+ messages in thread From: Meet Soni @ 2025-06-30 3:53 UTC (permalink / raw) To: Junio C Hamano; +Cc: git, ps, shejialuo, karthik.188 On Fri, 27 Jun 2025 at 23:33, Junio C Hamano <gitster@pobox.com> wrote: > > Meet Soni <meetsoni3017@gmail.com> writes: > > > - Remove legacy or obscure options that are no longer needed. > > Such as? > > > - Add improvements that wouldn't make sense to bolt onto legacy > > commands. > > Such as? > > While I agree that there may be cases that the above goals in > general would bring us improvements, I think neither of these two > applies to for-each-ref. People are using for-each-ref to iterate > over and enumerate refs already, and if you are to add some new > features to "git refs list", they certainly will demand these new > goodies to be added to for-each-ref as well. > > So, I dunno. To clarify, I don't have specific options or improvements in mind right now. The idea behind mentioning them was to acknowledge that having a consolidated interface like git refs might open the door to such discussions. The primary motivation here is to make ref-related commands discoverable at a single entry point - git refs, rather than scattered across several top-level commands. The aim is to improve disoverability and set the stage for potential future cleanup or enhancements, should the community find value in doing so. Per mentor suggestion, this RFC was meant to invite broader input on whether the community sees value in such a consolidation, and if so, what shape future refinements (if any) might take. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [GSoC][RFC PATCH 0/2] Add refs list subcommand 2025-06-30 3:53 ` Meet Soni @ 2025-06-30 20:10 ` Junio C Hamano 2025-07-09 13:36 ` Patrick Steinhardt 0 siblings, 1 reply; 13+ messages in thread From: Junio C Hamano @ 2025-06-30 20:10 UTC (permalink / raw) To: Meet Soni; +Cc: git, ps, shejialuo, karthik.188 Meet Soni <meetsoni3017@gmail.com> writes: > To clarify, I don't have specific options or improvements in mind right now. > The idea behind mentioning them was to acknowledge that having a consolidated > interface like git refs might open the door to such discussions. One complaint we heard a lot about Git in the past (I do not know if people got used to and learned to live with, or they are still complaining about the same these days) was that there were always multiple ways to do related things slightly differently. The machinery of for-each-ref is shared by branch and tag to give them feature-parity. Adding yet another command that behaves slightly differently, with the intention to make it diverge even more in the future, feels going backwards. > The primary motivation here is to make ref-related commands discoverable at a > single entry point - git refs, rather than scattered across several top-level > commands. The aim is to improve disoverability and set the stage for > potential future > cleanup or enhancements, should the community find value in doing so. We need to be a bit careful. There was a case that went in a totally opposite direction. Even though a single command was there in the beginning that can be used to pick a specific thing out of the histories stored in a repository to externalize it in the file system to be worked on, it was later split into two commands as folks thought it would make it more discoverable. Even though branches, tags, and symbolic refs like HEAD are all refs, from the point of view of end-users, they are different things built on top of the same underlying mechanism. The fact that they share the underlying mechanism does not necessarily mean that a single same command is easier to discover and work on them to the users. It may not hurt too much to have "enumerate all refs, and for each ref, allowing to limit them or to sort them with some criteria, and show them in a customizable format" as "git refs list", but we do need to keep the feature parity with "git for-each-ref". Adding unnecessary subtle differences would only confuse users. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [GSoC][RFC PATCH 0/2] Add refs list subcommand 2025-06-30 20:10 ` Junio C Hamano @ 2025-07-09 13:36 ` Patrick Steinhardt 0 siblings, 0 replies; 13+ messages in thread From: Patrick Steinhardt @ 2025-07-09 13:36 UTC (permalink / raw) To: Junio C Hamano; +Cc: Meet Soni, git, shejialuo, karthik.188 On Mon, Jun 30, 2025 at 01:10:36PM -0700, Junio C Hamano wrote: > Meet Soni <meetsoni3017@gmail.com> writes: > > > To clarify, I don't have specific options or improvements in mind right now. > > The idea behind mentioning them was to acknowledge that having a consolidated > > interface like git refs might open the door to such discussions. > > One complaint we heard a lot about Git in the past (I do not know if > people got used to and learned to live with, or they are still > complaining about the same these days) was that there were always > multiple ways to do related things slightly differently. > > The machinery of for-each-ref is shared by branch and tag to give > them feature-parity. Adding yet another command that behaves > slightly differently, with the intention to make it diverge even > more in the future, feels going backwards. That's fair. I do think that the common infrastructure should be shared indeed, and that includes the options. So the most important benefit of the new subcommand would be an improvement to discoverability. But there is one default in git-for-each-ref(1) that has been biting us multiple times at GitLab already, namely the default format. In git-for-each-ref(1) it is: %(objectname) %(objecttype)\t%(refname) The problem with this format is `%(objecttype)` -- it requires us to not only read refs from the reference database, but also resolve the object via the ODB so that we can figure out its type. And that can be a huge slowdown in large repositories. Take e.g. the Chromium repository: Benchmark 1: git for-each-ref Time (mean ± σ): 148.9 ms ± 1.0 ms [User: 80.7 ms, System: 67.2 ms] Range (min … max): 147.2 ms … 154.2 ms 100 runs Benchmark 2: git for-each-ref --format="%(objectname) %(refname)" Time (mean ± σ): 22.4 ms ± 0.3 ms [User: 21.4 ms, System: 1.0 ms] Range (min … max): 22.0 ms … 24.0 ms 100 runs Summary git for-each-ref --format="%(objectname) %(refname)" ran 6.65 ± 0.09 times faster than git for-each-ref So from my point of view, this is a thing we should consider changing in the new subcommand. For all the other options I agree, we should have common infra and thus common options. Patrick ^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2025-07-09 13:36 UTC | newest] Thread overview: 13+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-06-14 7:05 [GSoC][RFC PATCH 0/2] Add refs list subcommand Meet Soni 2025-06-14 7:05 ` [GSoC][RFC PATCH 1/2] builtin/refs: add " Meet Soni 2025-06-14 7:05 ` [GSoC][RFC PATCH 2/2] t: add tests for refs " Meet Soni 2025-06-14 23:45 ` [GSoC][RFC PATCH 0/2] Add " Junio C Hamano 2025-06-17 11:51 ` Meet Soni -- strict thread matches above, loose matches on Subject: below -- 2025-06-27 7:49 Meet Soni 2025-06-27 18:03 ` Junio C Hamano 2025-06-28 8:05 ` shejialuo 2025-06-30 14:05 ` Junio C Hamano 2025-07-06 12:58 ` shejialuo 2025-06-30 3:53 ` Meet Soni 2025-06-30 20:10 ` Junio C Hamano 2025-07-09 13:36 ` Patrick Steinhardt
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 NNTP newsgroup(s).