All of lore.kernel.org
 help / color / mirror / Atom feed
From: Meet Soni <meetsoni3017@gmail.com>
To: git@vger.kernel.org
Cc: ps@pks.im, shejialuo@gmail.com, Meet Soni <meetsoni3017@gmail.com>
Subject: [GSoC][PATCH 1/2] builtin/refs: add 'exists' subcommand
Date: Thu, 21 Aug 2025 14:22:45 +0530	[thread overview]
Message-ID: <20250821085246.929307-2-meetsoni3017@gmail.com> (raw)
In-Reply-To: <20250821085246.929307-1-meetsoni3017@gmail.com>

As part of the ongoing effort to consolidate reference handling,
introduce a new `exists` subcommand. This command provides the same
functionality and exit-code behavior as `git show-ref --exists`, serving
as its modern replacement.

The logic for `show-ref --exists` is minimal. Rather than creating a
shared helper function which would be overkill for ~20 lines of code,
its implementation is intentionally duplicated here. This contrasts with
`git refs list`, where sharing the larger implementation of
`for-each-ref` was necessary.

Documentation for the new subcommand is also added to the `git-refs(1)`
man page.

Mentored-by: Patrick Steinhardt <ps@pks.im>
Mentored-by: shejialuo <shejialuo@gmail.com>
Signed-off-by: Meet Soni <meetsoni3017@gmail.com>
---
 Documentation/git-refs.adoc |  7 ++++++
 builtin/refs.c              | 48 +++++++++++++++++++++++++++++++++++++
 2 files changed, 55 insertions(+)

diff --git a/Documentation/git-refs.adoc b/Documentation/git-refs.adoc
index d462953fb5..bfa9b3ea2d 100644
--- a/Documentation/git-refs.adoc
+++ b/Documentation/git-refs.adoc
@@ -18,6 +18,7 @@ git refs list [--count=<count>] [--shell|--perl|--python|--tcl]
 		   [--contains[=<object>]] [--no-contains[=<object>]]
 		   [(--exclude=<pattern>)...] [--start-after=<marker>]
 		   [ --stdin | (<pattern>...)]
+git refs exists <ref>
 
 DESCRIPTION
 -----------
@@ -38,6 +39,12 @@ list::
 	formatting, and sorting. This subcommand is an alias for
 	linkgit:git-for-each-ref[1] and offers identical functionality.
 
+exists::
+	Check whether the given reference exists. Returns an exit code of 0 if
+	it does, 2 if it is missing, and 1 in case looking up the reference
+	failed with an error other than the reference being missing. This does
+	not verify whether the reference resolves to an actual object.
+
 OPTIONS
 -------
 
diff --git a/builtin/refs.c b/builtin/refs.c
index 76224feba4..617d8ab138 100644
--- a/builtin/refs.c
+++ b/builtin/refs.c
@@ -7,6 +7,7 @@
 #include "strbuf.h"
 #include "worktree.h"
 #include "for-each-ref.h"
+#include "refs/refs-internal.h"
 
 #define REFS_MIGRATE_USAGE \
 	N_("git refs migrate --ref-format=<format> [--no-reflog] [--dry-run]")
@@ -14,6 +15,9 @@
 #define REFS_VERIFY_USAGE \
 	N_("git refs verify [--strict] [--verbose]")
 
+#define REFS_EXISTS_USAGE \
+	N_("git refs exists <ref>")
+
 static int cmd_refs_migrate(int argc, const char **argv, const char *prefix,
 			    struct repository *repo UNUSED)
 {
@@ -113,6 +117,48 @@ static int cmd_refs_list(int argc, const char **argv, const char *prefix,
 	return for_each_ref_core(argc, argv, prefix, repo, refs_list_usage);
 }
 
+static int cmd_refs_exists(int argc, const char **argv, const char *prefix,
+			   struct repository *repo UNUSED)
+{
+	struct strbuf unused_referent = STRBUF_INIT;
+	struct object_id unused_oid;
+	unsigned int unused_type;
+	int failure_errno = 0;
+	const char *ref;
+
+	const char * const exists_usage[] = {
+		REFS_EXISTS_USAGE,
+		NULL,
+	};
+	struct option options[] = {
+		OPT_END(),
+	};
+
+	argc = parse_options(argc, argv, prefix, options, exists_usage, 0);
+	if (!argc)
+		die("'git refs exists' requires a reference");
+
+	ref = *argv++;
+	if (*argv)
+		die("'git refs exists' requires exactly one reference");
+
+	if (refs_read_raw_ref(get_main_ref_store(the_repository), ref,
+			      &unused_oid, &unused_referent, &unused_type,
+			      &failure_errno)) {
+		if (failure_errno == ENOENT || failure_errno == EISDIR) {
+			error(_("reference does not exist"));
+			return 2;
+		} else {
+			errno = failure_errno;
+			error_errno(_("failed to look up reference"));
+			return 1;
+		}
+	}
+
+	strbuf_release(&unused_referent);
+	return 0;
+}
+
 int cmd_refs(int argc,
 	     const char **argv,
 	     const char *prefix,
@@ -122,6 +168,7 @@ int cmd_refs(int argc,
 		REFS_MIGRATE_USAGE,
 		REFS_VERIFY_USAGE,
 		"git refs list " COMMON_USAGE_FOR_EACH_REF,
+		REFS_EXISTS_USAGE,
 		NULL,
 	};
 	parse_opt_subcommand_fn *fn = NULL;
@@ -129,6 +176,7 @@ int cmd_refs(int argc,
 		OPT_SUBCOMMAND("migrate", &fn, cmd_refs_migrate),
 		OPT_SUBCOMMAND("verify", &fn, cmd_refs_verify),
 		OPT_SUBCOMMAND("list", &fn, cmd_refs_list),
+		OPT_SUBCOMMAND("exists", &fn, cmd_refs_exists),
 		OPT_END(),
 	};
 
-- 
2.34.1


  reply	other threads:[~2025-08-21  8:52 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-08-21  8:52 [GSoC][PATCH 0/2] Add refs exists subcommand Meet Soni
2025-08-21  8:52 ` Meet Soni [this message]
2025-08-21 10:21   ` [GSoC][PATCH 1/2] builtin/refs: add 'exists' subcommand Patrick Steinhardt
2025-08-21  8:52 ` [GSoC][PATCH 2/2] t: add test for git refs exists subcommand Meet Soni
2025-08-21 10:21   ` Patrick Steinhardt
2025-08-22  4:59     ` Meet Soni
2025-08-21 10:21 ` [GSoC][PATCH 0/2] Add " Patrick Steinhardt
2025-08-21 16:01 ` Junio C Hamano
2025-08-22  4:27   ` Meet Soni
2025-08-23  6:00 ` [GSoC][PATCH v2 0/4] " Meet Soni
2025-08-23  6:00   ` [GSoC][PATCH v2 1/4] builtin/refs: add 'exists' subcommand Meet Soni
2025-08-23  6:00   ` [GSoC][PATCH v2 2/4] t1403: split 'show-ref --exists' tests into a separate file Meet Soni
2025-08-23  6:00   ` [GSoC][PATCH v2 3/4] t1422: refactor tests to be shareable Meet Soni
2025-08-24 16:58     ` Patrick Steinhardt
2025-08-23  6:00   ` [GSoC][PATCH v2 4/4] t: add test for git refs exists subcommand Meet Soni
2025-08-24 16:58   ` [GSoC][PATCH v2 0/4] Add " Patrick Steinhardt
2025-08-26  6:41   ` [GSoC][PATCH v3 " Meet Soni
2025-08-26  6:41     ` [GSoC][PATCH v3 1/4] builtin/refs: add 'exists' subcommand Meet Soni
2025-08-26  6:41     ` [GSoC][PATCH v3 2/4] t1403: split 'show-ref --exists' tests into a separate file Meet Soni
2025-08-26  6:41     ` [GSoC][PATCH v3 3/4] t1422: refactor tests to be shareable Meet Soni
2025-08-26  6:41     ` [GSoC][PATCH v3 4/4] t: add test for git refs exists subcommand Meet Soni
2025-09-02 11:52     ` [GSoC][PATCH v3 0/4] Add " Patrick Steinhardt
2025-09-02 16:57     ` 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=20250821085246.929307-2-meetsoni3017@gmail.com \
    --to=meetsoni3017@gmail.com \
    --cc=git@vger.kernel.org \
    --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 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.