From: Meet Soni <meetsoni3017@gmail.com>
To: git@vger.kernel.org
Cc: Meet Soni <meetsoni3017@gmail.com>,
Patrick Steinhardt <ps@pks.im>, shejialuo <shejialuo@gmail.com>,
Karthik Nayak <karthik.188@gmail.com>,
Junio C Hamano <gitster@pobox.com>,
John Cai <johncai86@gmail.com>
Subject: [GSoC][RFC PATCH 1/2] builtin/refs: add list subcommand
Date: Sat, 14 Jun 2025 12:35:35 +0530 [thread overview]
Message-ID: <20250614070536.17320-2-meetsoni3017@gmail.com> (raw)
In-Reply-To: <20250614070536.17320-1-meetsoni3017@gmail.com>
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
next prev parent reply other threads:[~2025-06-14 7:06 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-06-14 7:05 [GSoC][RFC PATCH 0/2] Add refs list subcommand Meet Soni
2025-06-14 7:05 ` Meet Soni [this message]
2025-06-14 7:05 ` [GSoC][RFC PATCH 2/2] t: add tests for " 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 7:49 ` [GSoC][RFC PATCH 1/2] builtin/refs: add " Meet Soni
2025-06-27 16:27 ` Jean-Noël Avila
2025-06-27 18:13 ` Junio C Hamano
2025-06-30 4:28 ` Meet Soni
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=20250614070536.17320-2-meetsoni3017@gmail.com \
--to=meetsoni3017@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=johncai86@gmail.com \
--cc=karthik.188@gmail.com \
--cc=ps@pks.im \
--cc=shejialuo@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 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).