Git fork

builtin/refs: add 'exists' subcommand

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>
Acked-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>

authored by

Meet Soni and committed by
Junio C Hamano
0f0a8a11 1fa68948

+55
+7
Documentation/git-refs.adoc
··· 18 18 [--contains[=<object>]] [--no-contains[=<object>]] 19 19 [(--exclude=<pattern>)...] [--start-after=<marker>] 20 20 [ --stdin | <pattern>... ] 21 + git refs exists <ref> 21 22 22 23 DESCRIPTION 23 24 ----------- ··· 37 38 List references in the repository with support for filtering, 38 39 formatting, and sorting. This subcommand is an alias for 39 40 linkgit:git-for-each-ref[1] and offers identical functionality. 41 + 42 + exists:: 43 + Check whether the given reference exists. Returns an exit code of 0 if 44 + it does, 2 if it is missing, and 1 in case looking up the reference 45 + failed with an error other than the reference being missing. This does 46 + not verify whether the reference resolves to an actual object. 40 47 41 48 OPTIONS 42 49 -------
+48
builtin/refs.c
··· 7 7 #include "strbuf.h" 8 8 #include "worktree.h" 9 9 #include "for-each-ref.h" 10 + #include "refs/refs-internal.h" 10 11 11 12 #define REFS_MIGRATE_USAGE \ 12 13 N_("git refs migrate --ref-format=<format> [--no-reflog] [--dry-run]") 13 14 14 15 #define REFS_VERIFY_USAGE \ 15 16 N_("git refs verify [--strict] [--verbose]") 17 + 18 + #define REFS_EXISTS_USAGE \ 19 + N_("git refs exists <ref>") 16 20 17 21 static int cmd_refs_migrate(int argc, const char **argv, const char *prefix, 18 22 struct repository *repo UNUSED) ··· 113 117 return for_each_ref_core(argc, argv, prefix, repo, refs_list_usage); 114 118 } 115 119 120 + static int cmd_refs_exists(int argc, const char **argv, const char *prefix, 121 + struct repository *repo UNUSED) 122 + { 123 + struct strbuf unused_referent = STRBUF_INIT; 124 + struct object_id unused_oid; 125 + unsigned int unused_type; 126 + int failure_errno = 0; 127 + const char *ref; 128 + int ret = 0; 129 + const char * const exists_usage[] = { 130 + REFS_EXISTS_USAGE, 131 + NULL, 132 + }; 133 + struct option options[] = { 134 + OPT_END(), 135 + }; 136 + 137 + argc = parse_options(argc, argv, prefix, options, exists_usage, 0); 138 + if (argc != 1) 139 + die(_("'git refs exists' requires a reference")); 140 + 141 + ref = *argv++; 142 + if (refs_read_raw_ref(get_main_ref_store(the_repository), ref, 143 + &unused_oid, &unused_referent, &unused_type, 144 + &failure_errno)) { 145 + if (failure_errno == ENOENT || failure_errno == EISDIR) { 146 + error(_("reference does not exist")); 147 + ret = 2; 148 + } else { 149 + errno = failure_errno; 150 + error_errno(_("failed to look up reference")); 151 + ret = 1; 152 + } 153 + 154 + goto out; 155 + } 156 + 157 + out: 158 + strbuf_release(&unused_referent); 159 + return ret; 160 + } 161 + 116 162 int cmd_refs(int argc, 117 163 const char **argv, 118 164 const char *prefix, ··· 122 168 REFS_MIGRATE_USAGE, 123 169 REFS_VERIFY_USAGE, 124 170 "git refs list " COMMON_USAGE_FOR_EACH_REF, 171 + REFS_EXISTS_USAGE, 125 172 NULL, 126 173 }; 127 174 parse_opt_subcommand_fn *fn = NULL; ··· 129 176 OPT_SUBCOMMAND("migrate", &fn, cmd_refs_migrate), 130 177 OPT_SUBCOMMAND("verify", &fn, cmd_refs_verify), 131 178 OPT_SUBCOMMAND("list", &fn, cmd_refs_list), 179 + OPT_SUBCOMMAND("exists", &fn, cmd_refs_exists), 132 180 OPT_END(), 133 181 }; 134 182