{"thread":{"id":"64005","subject":"[GSoC][PATCH 0/2] Add refs exists subcommand","startedAt":"2025-08-21T08:52:53Z","lastAt":"2025-09-02T16:57:51Z","messageCount":23,"participants":["Meet Soni","Patrick Steinhardt","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":2},"messages":[{"id":"524632","messageId":"20250821085246.929307-1-meetsoni3017@gmail.com","threadId":"64005","inReplyTo":null,"subject":"[GSoC][PATCH 0/2] Add refs exists subcommand","fromName":"Meet Soni","fromEmail":"meetsoni3017@gmail.com","sentAt":"2025-08-21T08:52:44Z","receivedAt":"2025-08-21T08:52:53Z","isPatch":true,"sender":{"key":"meetsoni3017@gmail.com","avatar":"https://avatars.githubusercontent.com/u/92802561?v=4"},"body":"This series introduces `git refs exists` as a modern replacement for\n`git show-ref --exists`, continuing the effort to consolidate commands\nunder the `git refs` namespace.\n\nThe two patches are as follows:\n\n1. The first implements the `exists` subcommand. The small amount of\n   logic is duplicated from `show-ref` to avoid unnecessary abstraction.\n\n2. The second adds tests by refactoring the `show-ref --exists` tests\n   into a shareable helper, ensuring both commands are tested for\n   identical behavior.\n\nMeet Soni (2):\n  builtin/refs: add 'exists' subcommand\n  t: add test for git refs exists subcommand\n\n Documentation/git-refs.adoc |  7 ++++\n builtin/refs.c              | 48 +++++++++++++++++++++++++++\n t/meson.build               |  3 +-\n t/show-ref-exists-tests.sh  | 66 +++++++++++++++++++++++++++++++++++++\n t/t1403-show-ref.sh         | 66 +------------------------------------\n t/t1462-refs-exists.sh      | 22 +++++++++++++\n 6 files changed, 146 insertions(+), 66 deletions(-)\n create mode 100644 t/show-ref-exists-tests.sh\n create mode 100755 t/t1462-refs-exists.sh\n\n\nbase-commit: c44beea485f0f2feaf460e2ac87fdd5608d63cf0\nprerequisite-patch-id: 235cc677f372e9571dade4313f8cfed4eab65f7f\nprerequisite-patch-id: d0cb9932dcf233b3a26e413514375191ede93c73\nprerequisite-patch-id: 9cb324ad34a786af110e9d3d47e4ca8aec240971\nprerequisite-patch-id: 0d74ac673c285c334adcc19b9ca2d4919563e804\nprerequisite-patch-id: 04c6d989f4130a063bc80f7dc9ce9a16d3459665\nprerequisite-patch-id: 95dafb2692da02d79c59cc2742258a915da25e88\nprerequisite-patch-id: f14c9a47038305eb3cfe8e9b649fa64065ada9cd\nprerequisite-patch-id: 6923112c5bbec8f7f89d4a978cd2dd8e3eb55630\nprerequisite-patch-id: 68baea3d311384cf9b8685ad874bb1b103a81f7d\nprerequisite-patch-id: 2378c874394d7805730a46879d03da0bef244adb\nprerequisite-patch-id: d329083ff7ea2fb57c984c4c4718bbb793fea13d\nprerequisite-patch-id: 9b34591269ae3de243da1ae750878b7f6b29da07\nprerequisite-patch-id: e3fa9191e8bc9e281adaf7c056644073e0b99dc9\nprerequisite-patch-id: d3ecaf8354dc1d58dc70a9d9ea51508ceff2b2e1\nprerequisite-patch-id: 90cd997029c15397eceb219d0d22989d9e874a92\nprerequisite-patch-id: 37e3430d0a76fcdd8f6853c311f76aa18ba4f430\nprerequisite-patch-id: 358ee0b96796c09458b03c35739268866a2c36df\nprerequisite-patch-id: 50119e8583f0bcf8c275758d1955682643974687\nprerequisite-patch-id: d85f18fb917f1affeefd4f807c7a8114fa6adb16\nprerequisite-patch-id: 84e6b5171ddd6f5736196cbe79549f4186b85981\nprerequisite-patch-id: d4b4473d029ea8df05668f9bfd767a9272255e3f\nprerequisite-patch-id: 8cb9a456888b52813ef095b7f997dab5f390df0a\nprerequisite-patch-id: 4e16bf58775a0dbbf58302f21d11864b96f321eb\nprerequisite-patch-id: eabfc6cb85b47f04d78c2634dbaa6fddf87a60f9\nprerequisite-patch-id: 15aad03c722b62d6fa22bdc3a44f862ebc2b1c88\nprerequisite-patch-id: 9361523cda8f829d5fb7cef7d234f3fda99ebb9b\nprerequisite-patch-id: 66abfbef34f4f7bc408324c5f327b767ef36a679\nprerequisite-patch-id: 449ca227be630deeced22f191344becc63cdf9d1\nprerequisite-patch-id: 5226b03a040940b4fe1bf0af254a77d67f5a177e\nprerequisite-patch-id: e7c24bcc4a5ed5367e90bb23db0e28d0ccbdad2a\nprerequisite-patch-id: abfc3c9c3ea59b7495e229e9ad433f60dc0ff8f7\nprerequisite-patch-id: 7fe80bfc019f63df308391e1127a25e59103abc2\nprerequisite-patch-id: a84ad0fb4b321a8d6c58d942a716b8e3748156ba\nprerequisite-patch-id: 900b6cbe5278bc6beeadc102509f1385ce7d637e\nprerequisite-patch-id: c7ad0ca2ff0e22d174da1047c6eb30b1dcd8da84\nprerequisite-patch-id: 118017529d699ca93d9ee86196eac8557f5c36a1\nprerequisite-patch-id: 49b0a7b7e607adb614e7b46d2778ac46d3b3c7ce\nprerequisite-patch-id: 823f58165b365d7368faa82d905fe0d0c2136357\nprerequisite-patch-id: 665b97ae5be824000628b34bdbb2b73b68b5c292\nprerequisite-patch-id: e3c140859b3637d5a13c020ef041ad25a4a6bc42\nprerequisite-patch-id: 41cb62f978e5dbf3a658ffffe99b8c1b479938a1\nprerequisite-patch-id: 1929619486cdee7517c3f2b0af67e96c69c89764\nprerequisite-patch-id: 5035d6f130dfc22b4fe9ea79b7a436fd54070a81\nprerequisite-patch-id: 53dd4f1d4455d8cdf2e2a2fcb082be00ad8c0914\nprerequisite-patch-id: 2efcbefc0f0395e8178e656c3c79cea2acf54377\nprerequisite-patch-id: 447c1cb43a64eb6c95d98e115fcbf424492a3ab5\nprerequisite-patch-id: f929f5f303123f8b937cb94c200ba93b139b9dfb\nprerequisite-patch-id: 373824b744f085cd7bfd97f1568c6f2d56ea8ca2\nprerequisite-patch-id: e4dfe5bca99ff093f0c8aff1a085010c0f0d3c6f\nprerequisite-patch-id: ca8fe616ea1ac4d575747f9224222bd65f514705\nprerequisite-patch-id: d34e569010a2beb0d5ddfe7e3dedf3abb77c5604\nprerequisite-patch-id: 250bae2541030fcdfc5b35ede44c23e1138c7a3c\nprerequisite-patch-id: 476284f1a96b09b8853052c9ba8f32acb2834c17\nprerequisite-patch-id: 9cd780236535e9e84eae38f2a19c5e010f6c1288\nprerequisite-patch-id: 7e3ba2fb3d0dd0760a3e3a5b336927b04999b28a\nprerequisite-patch-id: 0a500a41e9feeca41e81bb0e1bfcf3ddfbe4cb82\nprerequisite-patch-id: a11fa19efa109c1394e0c6ab781720c61ce13c41\nprerequisite-patch-id: b365ab543df9d138b41c1a8d40a754b84b965e99\nprerequisite-patch-id: 6f248fa00c78e2171a52f4c038d4bd7f339840b2\nprerequisite-patch-id: fb1e7d4305f77c598936f4b638fa7803965c9e78\nprerequisite-patch-id: 5b1b57b2c3fb387b3fbd7a9c6f0b57c80199a94d\nprerequisite-patch-id: 9d70dcb2e265c49f9b84afafa56c857567943a04\nprerequisite-patch-id: cf13b44e4629fbf488603defcbc8acdc0217b4be\nprerequisite-patch-id: c90829faf86b799652917ef99206e7b1cead2c54\nprerequisite-patch-id: b076beae979d5ac7fedcc13b5d26e77d5cbe6663\nprerequisite-patch-id: 5f39ac2a8c07870f69770baa0109793ff7022076\nprerequisite-patch-id: cafedb553cd007249c5bfcac36242438656ca170\nprerequisite-patch-id: 197d745dfcefbd8751e0c90aac632331826752a1\nprerequisite-patch-id: 0d1d1a35ed44cf830442f3e74c65cdcdf9b91566\nprerequisite-patch-id: 4cc86520dd4d680ee3ca856d176f324e683eca41\nprerequisite-patch-id: 95a6721029877cf75106b96a6bcc707aa17e1b9c\nprerequisite-patch-id: 5b7734071f21d853533a6ee09383690fafb5fead\nprerequisite-patch-id: 7e1d3e7927abac3b453fd0e79b634c7365ed955a\nprerequisite-patch-id: 7daea73cac876045f587001cf94b7f83ee9e12c4\nprerequisite-patch-id: a765074cb9084aa5da8e72b2690c323c3ec83231\nprerequisite-patch-id: 4e277720b943d0a26cc85adda11eb568e442f77b\nprerequisite-patch-id: 28f977860324220a487487be0704519f90a02306\nprerequisite-patch-id: 08e65a7035bac5c4232ea4e39c54eecc49408f19\nprerequisite-patch-id: 63c3e610f0e56eabc039483636e292d05bbc63b9\nprerequisite-patch-id: bedd7161331cb4fbf30debff40d33a8a0c14023f\nprerequisite-patch-id: bf6dd38daaf71b4599833e4c8cbf64698e9c1a36\nprerequisite-patch-id: c611631180a541b1787c12bcbe64bb9ae3454244\nprerequisite-patch-id: f3368c4816df6c93c1ec1b35c1c405657f1a7387\nprerequisite-patch-id: 29c35a90c70a4f37baf96b4f592e197c5621666a\nprerequisite-patch-id: 6a612f309924935068f6a57f8d181d842a274ea5\nprerequisite-patch-id: 76634063b4f24689276d6099bade4330c3fa8bde\nprerequisite-patch-id: e217cab3cdd411bad09c252de5fb4206be77d637\nprerequisite-patch-id: bb3fbaa2b7bd78e3e60f7a434146005c04161509\nprerequisite-patch-id: 24edfd0bf766d61c182de3aa86377ae90db4f7ef\nprerequisite-patch-id: bcc3a15b67760ab9433363223c506cd09f03747e\nprerequisite-patch-id: e7bd2d09677a0bb1019e3c3790417498ba2dc7f2\nprerequisite-patch-id: c79540346ad559338d46454486dcc1be25e9c5a1\nprerequisite-patch-id: 8803357fd1432a264d60c9e1a688dc85d7935b3e\nprerequisite-patch-id: c099a26d62f63b535199c6f52271bb63e88df69c\nprerequisite-patch-id: d1825e57939cbd15928498352e1a7f00c673c12d\nprerequisite-patch-id: 3ebef3d7a7a7b224eb0a68ec8edfa0358a2c5a7b\nprerequisite-patch-id: 69f3f6729c7c473374a9f21ec2875b8e42ea5cd9\nprerequisite-patch-id: 2c5dc68c7b4811b6710cf1516cbd3608cc761bbc\nprerequisite-patch-id: 0803b4f82635672ea9b6b9a546d9a9577884c5ad\nprerequisite-patch-id: 553adfe23223a427db3f93e23dfb603c55cc5aae\n-- \n2.34.1\n\n"},{"id":"524633","messageId":"20250821085246.929307-2-meetsoni3017@gmail.com","threadId":"64005","inReplyTo":"20250821085246.929307-1-meetsoni3017@gmail.com","subject":"[GSoC][PATCH 1/2] builtin/refs: add 'exists' subcommand","fromName":"Meet Soni","fromEmail":"meetsoni3017@gmail.com","sentAt":"2025-08-21T08:52:45Z","receivedAt":"2025-08-21T08:52:55Z","isPatch":true,"sender":{"key":"meetsoni3017@gmail.com","avatar":"https://avatars.githubusercontent.com/u/92802561?v=4"},"body":"As part of the ongoing effort to consolidate reference handling,\nintroduce a new `exists` subcommand. This command provides the same\nfunctionality and exit-code behavior as `git show-ref --exists`, serving\nas its modern replacement.\n\nThe logic for `show-ref --exists` is minimal. Rather than creating a\nshared helper function which would be overkill for ~20 lines of code,\nits implementation is intentionally duplicated here. This contrasts with\n`git refs list`, where sharing the larger implementation of\n`for-each-ref` was necessary.\n\nDocumentation for the new subcommand is also added to the `git-refs(1)`\nman page.\n\nMentored-by: Patrick Steinhardt <ps@pks.im>\nMentored-by: shejialuo <shejialuo@gmail.com>\nSigned-off-by: Meet Soni <meetsoni3017@gmail.com>\n---\n Documentation/git-refs.adoc |  7 ++++++\n builtin/refs.c              | 48 +++++++++++++++++++++++++++++++++++++\n 2 files changed, 55 insertions(+)\n\ndiff --git a/Documentation/git-refs.adoc b/Documentation/git-refs.adoc\nindex d462953fb5..bfa9b3ea2d 100644\n--- a/Documentation/git-refs.adoc\n+++ b/Documentation/git-refs.adoc\n@@ -18,6 +18,7 @@ git refs list [--count=<count>] [--shell|--perl|--python|--tcl]\n \t\t   [--contains[=<object>]] [--no-contains[=<object>]]\n \t\t   [(--exclude=<pattern>)...] [--start-after=<marker>]\n \t\t   [ --stdin | (<pattern>...)]\n+git refs exists <ref>\n \n DESCRIPTION\n -----------\n@@ -38,6 +39,12 @@ list::\n \tformatting, and sorting. This subcommand is an alias for\n \tlinkgit:git-for-each-ref[1] and offers identical functionality.\n \n+exists::\n+\tCheck whether the given reference exists. Returns an exit code of 0 if\n+\tit does, 2 if it is missing, and 1 in case looking up the reference\n+\tfailed with an error other than the reference being missing. This does\n+\tnot verify whether the reference resolves to an actual object.\n+\n OPTIONS\n -------\n \ndiff --git a/builtin/refs.c b/builtin/refs.c\nindex 76224feba4..617d8ab138 100644\n--- a/builtin/refs.c\n+++ b/builtin/refs.c\n@@ -7,6 +7,7 @@\n #include \"strbuf.h\"\n #include \"worktree.h\"\n #include \"for-each-ref.h\"\n+#include \"refs/refs-internal.h\"\n \n #define REFS_MIGRATE_USAGE \\\n \tN_(\"git refs migrate --ref-format=<format> [--no-reflog] [--dry-run]\")\n@@ -14,6 +15,9 @@\n #define REFS_VERIFY_USAGE \\\n \tN_(\"git refs verify [--strict] [--verbose]\")\n \n+#define REFS_EXISTS_USAGE \\\n+\tN_(\"git refs exists <ref>\")\n+\n static int cmd_refs_migrate(int argc, const char **argv, const char *prefix,\n \t\t\t    struct repository *repo UNUSED)\n {\n@@ -113,6 +117,48 @@ static int cmd_refs_list(int argc, const char **argv, const char *prefix,\n \treturn for_each_ref_core(argc, argv, prefix, repo, refs_list_usage);\n }\n \n+static int cmd_refs_exists(int argc, const char **argv, const char *prefix,\n+\t\t\t   struct repository *repo UNUSED)\n+{\n+\tstruct strbuf unused_referent = STRBUF_INIT;\n+\tstruct object_id unused_oid;\n+\tunsigned int unused_type;\n+\tint failure_errno = 0;\n+\tconst char *ref;\n+\n+\tconst char * const exists_usage[] = {\n+\t\tREFS_EXISTS_USAGE,\n+\t\tNULL,\n+\t};\n+\tstruct option options[] = {\n+\t\tOPT_END(),\n+\t};\n+\n+\targc = parse_options(argc, argv, prefix, options, exists_usage, 0);\n+\tif (!argc)\n+\t\tdie(\"'git refs exists' requires a reference\");\n+\n+\tref = *argv++;\n+\tif (*argv)\n+\t\tdie(\"'git refs exists' requires exactly one reference\");\n+\n+\tif (refs_read_raw_ref(get_main_ref_store(the_repository), ref,\n+\t\t\t      &unused_oid, &unused_referent, &unused_type,\n+\t\t\t      &failure_errno)) {\n+\t\tif (failure_errno == ENOENT || failure_errno == EISDIR) {\n+\t\t\terror(_(\"reference does not exist\"));\n+\t\t\treturn 2;\n+\t\t} else {\n+\t\t\terrno = failure_errno;\n+\t\t\terror_errno(_(\"failed to look up reference\"));\n+\t\t\treturn 1;\n+\t\t}\n+\t}\n+\n+\tstrbuf_release(&unused_referent);\n+\treturn 0;\n+}\n+\n int cmd_refs(int argc,\n \t     const char **argv,\n \t     const char *prefix,\n@@ -122,6 +168,7 @@ int cmd_refs(int argc,\n \t\tREFS_MIGRATE_USAGE,\n \t\tREFS_VERIFY_USAGE,\n \t\t\"git refs list \" COMMON_USAGE_FOR_EACH_REF,\n+\t\tREFS_EXISTS_USAGE,\n \t\tNULL,\n \t};\n \tparse_opt_subcommand_fn *fn = NULL;\n@@ -129,6 +176,7 @@ int cmd_refs(int argc,\n \t\tOPT_SUBCOMMAND(\"migrate\", &fn, cmd_refs_migrate),\n \t\tOPT_SUBCOMMAND(\"verify\", &fn, cmd_refs_verify),\n \t\tOPT_SUBCOMMAND(\"list\", &fn, cmd_refs_list),\n+\t\tOPT_SUBCOMMAND(\"exists\", &fn, cmd_refs_exists),\n \t\tOPT_END(),\n \t};\n \n-- \n2.34.1\n\n"},{"id":"524634","messageId":"20250821085246.929307-3-meetsoni3017@gmail.com","threadId":"64005","inReplyTo":"20250821085246.929307-1-meetsoni3017@gmail.com","subject":"[GSoC][PATCH 2/2] t: add test for git refs exists subcommand","fromName":"Meet Soni","fromEmail":"meetsoni3017@gmail.com","sentAt":"2025-08-21T08:52:46Z","receivedAt":"2025-08-21T08:52:58Z","isPatch":true,"sender":{"key":"meetsoni3017@gmail.com","avatar":"https://avatars.githubusercontent.com/u/92802561?v=4"},"body":"The new `git refs exists` subcommand must have identical behavior to its\npredecessor, `git show-ref --exists`. To avoid duplicating the entire\ntest suite, refactor the existing tests into a shareable helper script.\n\nExtract the tests for the `--exists` flag from `t1403-show-ref.sh` into\na new `show-ref-exists-tests.sh` helper. The command under test is\nparameterized using the `$git_show_ref_exists` variable.\n\nSource new helper to both `t1403-show-ref.sh` and the new test file,\n`t1462-refs-exists.sh`, ensuring both commands are verified against the\nsame comprehensive test suite.\n\nMentored-by: Patrick Steinhardt <ps@pks.im>\nMentored-by: shejialuo <shejialuo@gmail.com>\nSigned-off-by: Meet Soni <meetsoni3017@gmail.com>\n---\n t/meson.build              |  3 +-\n t/show-ref-exists-tests.sh | 66 ++++++++++++++++++++++++++++++++++++++\n t/t1403-show-ref.sh        | 66 +-------------------------------------\n t/t1462-refs-exists.sh     | 22 +++++++++++++\n 4 files changed, 91 insertions(+), 66 deletions(-)\n create mode 100644 t/show-ref-exists-tests.sh\n create mode 100755 t/t1462-refs-exists.sh\n\ndiff --git a/t/meson.build b/t/meson.build\nindex baeeba2ce6..eed812a9b9 100644\n--- a/t/meson.build\n+++ b/t/meson.build\n@@ -211,6 +211,7 @@ integration_tests = [\n   't1451-fsck-buffer.sh',\n   't1460-refs-migrate.sh',\n   't1461-refs-list.sh',\n+  't1462-refs-exists.sh',\n   't1500-rev-parse.sh',\n   't1501-work-tree.sh',\n   't1502-rev-parse-parseopt.sh',\n@@ -1219,4 +1220,4 @@ if perl.found() and time.found()\n       timeout: 0,\n     )\n   endforeach\n-endif\n\\ No newline at end of file\n+endif\ndiff --git a/t/show-ref-exists-tests.sh b/t/show-ref-exists-tests.sh\nnew file mode 100644\nindex 0000000000..23b941d386\n--- /dev/null\n+++ b/t/show-ref-exists-tests.sh\n@@ -0,0 +1,66 @@\n+git_show_ref_exists=${git_show_ref_exists:-git show-ref --exists}\n+\n+test_expect_success '--exists with existing reference' '\n+\t${git_show_ref_exists} refs/heads/$GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n+'\n+\n+test_expect_success '--exists with missing reference' '\n+\ttest_expect_code 2 ${git_show_ref_exists} refs/heads/does-not-exist\n+'\n+\n+test_expect_success '--exists does not use DWIM' '\n+\ttest_expect_code 2 ${git_show_ref_exists} $GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME 2>err &&\n+\tgrep \"reference does not exist\" err\n+'\n+\n+test_expect_success '--exists with HEAD' '\n+\t${git_show_ref_exists} HEAD\n+'\n+\n+test_expect_success '--exists with bad reference name' '\n+\ttest_when_finished \"git update-ref -d refs/heads/bad...name\" &&\n+\tnew_oid=$(git rev-parse HEAD) &&\n+\ttest-tool ref-store main update-ref msg refs/heads/bad...name $new_oid $ZERO_OID REF_SKIP_REFNAME_VERIFICATION &&\n+\t${git_show_ref_exists} refs/heads/bad...name\n+'\n+\n+test_expect_success '--exists with arbitrary symref' '\n+\ttest_when_finished \"git symbolic-ref -d refs/symref\" &&\n+\tgit symbolic-ref refs/symref refs/heads/$GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME &&\n+\t${git_show_ref_exists} refs/symref\n+'\n+\n+test_expect_success '--exists with dangling symref' '\n+\ttest_when_finished \"git symbolic-ref -d refs/heads/dangling\" &&\n+\tgit symbolic-ref refs/heads/dangling refs/heads/does-not-exist &&\n+\t${git_show_ref_exists} refs/heads/dangling\n+'\n+\n+test_expect_success '--exists with nonexistent object ID' '\n+\ttest-tool ref-store main update-ref msg refs/heads/missing-oid $(test_oid 001) $ZERO_OID REF_SKIP_OID_VERIFICATION &&\n+\t${git_show_ref_exists} refs/heads/missing-oid\n+'\n+\n+test_expect_success '--exists with non-commit object' '\n+\ttree_oid=$(git rev-parse HEAD^{tree}) &&\n+\ttest-tool ref-store main update-ref msg refs/heads/tree ${tree_oid} $ZERO_OID REF_SKIP_OID_VERIFICATION &&\n+\t${git_show_ref_exists} refs/heads/tree\n+'\n+\n+test_expect_success '--exists with directory fails with generic error' '\n+\tcat >expect <<-EOF &&\n+\terror: reference does not exist\n+\tEOF\n+\ttest_expect_code 2 ${git_show_ref_exists} refs/heads 2>err &&\n+\ttest_cmp expect err\n+'\n+\n+test_expect_success '--exists with non-existent special ref' '\n+\ttest_expect_code 2 ${git_show_ref_exists} FETCH_HEAD\n+'\n+\n+test_expect_success '--exists with existing special ref' '\n+\ttest_when_finished \"rm .git/FETCH_HEAD\" &&\n+\tgit rev-parse HEAD >.git/FETCH_HEAD &&\n+\t${git_show_ref_exists} FETCH_HEAD\n+'\ndiff --git a/t/t1403-show-ref.sh b/t/t1403-show-ref.sh\nindex 9da3650e91..dbae82384b 100755\n--- a/t/t1403-show-ref.sh\n+++ b/t/t1403-show-ref.sh\n@@ -228,69 +228,5 @@ test_expect_success 'show-ref sub-modes are mutually exclusive' '\n \tgrep \"cannot be used together\" err\n '\n \n-test_expect_success '--exists with existing reference' '\n-\tgit show-ref --exists refs/heads/$GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n-'\n-\n-test_expect_success '--exists with missing reference' '\n-\ttest_expect_code 2 git show-ref --exists refs/heads/does-not-exist\n-'\n-\n-test_expect_success '--exists does not use DWIM' '\n-\ttest_expect_code 2 git show-ref --exists $GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME 2>err &&\n-\tgrep \"reference does not exist\" err\n-'\n-\n-test_expect_success '--exists with HEAD' '\n-\tgit show-ref --exists HEAD\n-'\n-\n-test_expect_success '--exists with bad reference name' '\n-\ttest_when_finished \"git update-ref -d refs/heads/bad...name\" &&\n-\tnew_oid=$(git rev-parse HEAD) &&\n-\ttest-tool ref-store main update-ref msg refs/heads/bad...name $new_oid $ZERO_OID REF_SKIP_REFNAME_VERIFICATION &&\n-\tgit show-ref --exists refs/heads/bad...name\n-'\n-\n-test_expect_success '--exists with arbitrary symref' '\n-\ttest_when_finished \"git symbolic-ref -d refs/symref\" &&\n-\tgit symbolic-ref refs/symref refs/heads/$GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME &&\n-\tgit show-ref --exists refs/symref\n-'\n-\n-test_expect_success '--exists with dangling symref' '\n-\ttest_when_finished \"git symbolic-ref -d refs/heads/dangling\" &&\n-\tgit symbolic-ref refs/heads/dangling refs/heads/does-not-exist &&\n-\tgit show-ref --exists refs/heads/dangling\n-'\n-\n-test_expect_success '--exists with nonexistent object ID' '\n-\ttest-tool ref-store main update-ref msg refs/heads/missing-oid $(test_oid 001) $ZERO_OID REF_SKIP_OID_VERIFICATION &&\n-\tgit show-ref --exists refs/heads/missing-oid\n-'\n-\n-test_expect_success '--exists with non-commit object' '\n-\ttree_oid=$(git rev-parse HEAD^{tree}) &&\n-\ttest-tool ref-store main update-ref msg refs/heads/tree ${tree_oid} $ZERO_OID REF_SKIP_OID_VERIFICATION &&\n-\tgit show-ref --exists refs/heads/tree\n-'\n-\n-test_expect_success '--exists with directory fails with generic error' '\n-\tcat >expect <<-EOF &&\n-\terror: reference does not exist\n-\tEOF\n-\ttest_expect_code 2 git show-ref --exists refs/heads 2>err &&\n-\ttest_cmp expect err\n-'\n-\n-test_expect_success '--exists with non-existent special ref' '\n-\ttest_expect_code 2 git show-ref --exists FETCH_HEAD\n-'\n-\n-test_expect_success '--exists with existing special ref' '\n-\ttest_when_finished \"rm .git/FETCH_HEAD\" &&\n-\tgit rev-parse HEAD >.git/FETCH_HEAD &&\n-\tgit show-ref --exists FETCH_HEAD\n-'\n-\n+. \"$TEST_DIRECTORY\"/show-ref-exists-tests.sh\n test_done\ndiff --git a/t/t1462-refs-exists.sh b/t/t1462-refs-exists.sh\nnew file mode 100755\nindex 0000000000..c00d76cc9e\n--- /dev/null\n+++ b/t/t1462-refs-exists.sh\n@@ -0,0 +1,22 @@\n+#!/bin/sh\n+\n+test_description='refs exists'\n+GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n+export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n+\n+. ./test-lib.sh\n+\n+git_show_ref_exists='git refs exists'\n+\n+test_expect_success setup '\n+\ttest_commit --annotate A &&\n+\tgit checkout -b side &&\n+\ttest_commit --annotate B &&\n+\tgit checkout main &&\n+\ttest_commit C &&\n+\tgit branch B A^0\n+'\n+\n+. \"$TEST_DIRECTORY\"/show-ref-exists-tests.sh\n+\n+test_done\n-- \n2.34.1\n\n"},{"id":"524638","messageId":"aKbzLhqryk5d-zgh@pks.im","threadId":"64005","inReplyTo":"20250821085246.929307-2-meetsoni3017@gmail.com","subject":"Re: [GSoC][PATCH 1/2] builtin/refs: add 'exists' subcommand","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2025-08-21T10:21:34Z","receivedAt":"2025-08-21T10:21:41Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Thu, Aug 21, 2025 at 02:22:45PM +0530, Meet Soni wrote:\n> As part of the ongoing effort to consolidate reference handling,\n> introduce a new `exists` subcommand. This command provides the same\n> functionality and exit-code behavior as `git show-ref --exists`, serving\n> as its modern replacement.\n> \n> The logic for `show-ref --exists` is minimal. Rather than creating a\n> shared helper function which would be overkill for ~20 lines of code,\n> its implementation is intentionally duplicated here. This contrasts with\n> `git refs list`, where sharing the larger implementation of\n> `for-each-ref` was necessary.\n\nI agree with this decision. It doesn't really feel worth it to share\ncode for such trivial functionality.\n\n> diff --git a/builtin/refs.c b/builtin/refs.c\n> index 76224feba4..617d8ab138 100644\n> --- a/builtin/refs.c\n> +++ b/builtin/refs.c\n> @@ -113,6 +117,48 @@ static int cmd_refs_list(int argc, const char **argv, const char *prefix,\n>  \treturn for_each_ref_core(argc, argv, prefix, repo, refs_list_usage);\n>  }\n>  \n> +static int cmd_refs_exists(int argc, const char **argv, const char *prefix,\n> +\t\t\t   struct repository *repo UNUSED)\n> +{\n> +\tstruct strbuf unused_referent = STRBUF_INIT;\n> +\tstruct object_id unused_oid;\n> +\tunsigned int unused_type;\n> +\tint failure_errno = 0;\n> +\tconst char *ref;\n> +\n\nLet's drop this empty newline.\n\n> +\tconst char * const exists_usage[] = {\n> +\t\tREFS_EXISTS_USAGE,\n> +\t\tNULL,\n> +\t};\n> +\tstruct option options[] = {\n> +\t\tOPT_END(),\n> +\t};\n> +\n> +\targc = parse_options(argc, argv, prefix, options, exists_usage, 0);\n> +\tif (!argc)\n> +\t\tdie(\"'git refs exists' requires a reference\");\n> +\n> +\tref = *argv++;\n> +\tif (*argv)\n> +\t\tdie(\"'git refs exists' requires exactly one reference\");\n\nWe can combine these two error messages to just say `if (argc != 1)`.\nAlso, the strings should be marked for translation.\n\n> +\tif (refs_read_raw_ref(get_main_ref_store(the_repository), ref,\n> +\t\t\t      &unused_oid, &unused_referent, &unused_type,\n> +\t\t\t      &failure_errno)) {\n> +\t\tif (failure_errno == ENOENT || failure_errno == EISDIR) {\n> +\t\t\terror(_(\"reference does not exist\"));\n> +\t\t\treturn 2;\n> +\t\t} else {\n> +\t\t\terrno = failure_errno;\n> +\t\t\terror_errno(_(\"failed to look up reference\"));\n> +\t\t\treturn 1;\n\nI'd personally prefer to se a common exit path and use `goto` so that\none doesn't have to worry about whether or not the `struct strbuf` needs\nto be free'd in error cases. But I'll leave it up to you to decide\nwhether you want to do this change.\n\nPatrick\n"},{"id":"524639","messageId":"aKbzNNcZZ-E0FVeI@pks.im","threadId":"64005","inReplyTo":"20250821085246.929307-3-meetsoni3017@gmail.com","subject":"Re: [GSoC][PATCH 2/2] t: add test for git refs exists subcommand","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2025-08-21T10:21:40Z","receivedAt":"2025-08-21T10:21:45Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Thu, Aug 21, 2025 at 02:22:46PM +0530, Meet Soni wrote:\n> The new `git refs exists` subcommand must have identical behavior to its\n> predecessor, `git show-ref --exists`. To avoid duplicating the entire\n> test suite, refactor the existing tests into a shareable helper script.\n> \n> Extract the tests for the `--exists` flag from `t1403-show-ref.sh` into\n> a new `show-ref-exists-tests.sh` helper. The command under test is\n> parameterized using the `$git_show_ref_exists` variable.\n> \n> Source new helper to both `t1403-show-ref.sh` and the new test file,\n\ns/new/this/, otherwise this reads grammatically wrong to me.\n\n>  test_done\n> diff --git a/t/t1462-refs-exists.sh b/t/t1462-refs-exists.sh\n> new file mode 100755\n> index 0000000000..c00d76cc9e\n> --- /dev/null\n> +++ b/t/t1462-refs-exists.sh\n> @@ -0,0 +1,22 @@\n> +#!/bin/sh\n> +\n> +test_description='refs exists'\n> +GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n> +export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n> +\n> +. ./test-lib.sh\n> +\n> +git_show_ref_exists='git refs exists'\n> +\n> +test_expect_success setup '\n> +\ttest_commit --annotate A &&\n> +\tgit checkout -b side &&\n> +\ttest_commit --annotate B &&\n> +\tgit checkout main &&\n> +\ttest_commit C &&\n> +\tgit branch B A^0\n> +'\n\nIt's a bit weird that this setup needs to be replicated. I guess it\ncomes from the fact that t1403 also has a bunch of other tests for\ngit-show-ref(1) that are irrelevant to existence checks.\n\nHow about we instead split out the existence-checks in t1403 into a\nseparate test suite first and then pull out the whole logic from it in a\nsubsequent commit so that we can also share the setup?\n\nPatrick\n"},{"id":"524640","messageId":"aKbzOuB0wL17Jhxb@pks.im","threadId":"64005","inReplyTo":"20250821085246.929307-1-meetsoni3017@gmail.com","subject":"Re: [GSoC][PATCH 0/2] Add refs exists subcommand","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2025-08-21T10:21:46Z","receivedAt":"2025-08-21T10:21:51Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Thu, Aug 21, 2025 at 02:22:44PM +0530, Meet Soni wrote:\n> This series introduces `git refs exists` as a modern replacement for\n> `git show-ref --exists`, continuing the effort to consolidate commands\n> under the `git refs` namespace.\n> \n> The two patches are as follows:\n> \n> 1. The first implements the `exists` subcommand. The small amount of\n>    logic is duplicated from `show-ref` to avoid unnecessary abstraction.\n> \n> 2. The second adds tests by refactoring the `show-ref --exists` tests\n>    into a shareable helper, ensuring both commands are tested for\n>    identical behavior.\n> \n> Meet Soni (2):\n>   builtin/refs: add 'exists' subcommand\n>   t: add test for git refs exists subcommand\n> \n>  Documentation/git-refs.adoc |  7 ++++\n>  builtin/refs.c              | 48 +++++++++++++++++++++++++++\n>  t/meson.build               |  3 +-\n>  t/show-ref-exists-tests.sh  | 66 +++++++++++++++++++++++++++++++++++++\n>  t/t1403-show-ref.sh         | 66 +------------------------------------\n>  t/t1462-refs-exists.sh      | 22 +++++++++++++\n>  6 files changed, 146 insertions(+), 66 deletions(-)\n>  create mode 100644 t/show-ref-exists-tests.sh\n>  create mode 100755 t/t1462-refs-exists.sh\n> \n> \n> base-commit: c44beea485f0f2feaf460e2ac87fdd5608d63cf0\n> prerequisite-patch-id: 235cc677f372e9571dade4313f8cfed4eab65f7f\n> prerequisite-patch-id: d0cb9932dcf233b3a26e413514375191ede93c73\n> prerequisite-patch-id: 9cb324ad34a786af110e9d3d47e4ca8aec240971\n> prerequisite-patch-id: 0d74ac673c285c334adcc19b9ca2d4919563e804\n> prerequisite-patch-id: 04c6d989f4130a063bc80f7dc9ce9a16d3459665\n> prerequisite-patch-id: 95dafb2692da02d79c59cc2742258a915da25e88\n> prerequisite-patch-id: f14c9a47038305eb3cfe8e9b649fa64065ada9cd\n...\n\nFeels like something went wrong here :)\n\nWhat the cover letter doesn't mention explicitly is what the base of\nthis topic is. I assume it's probably v2.51.0 with ms/refs-list merged\ninto it?\n\nPatrick\n"},{"id":"524663","messageId":"xmqq7byw4qbl.fsf@gitster.g","threadId":"64005","inReplyTo":"20250821085246.929307-1-meetsoni3017@gmail.com","subject":"Re: [GSoC][PATCH 0/2] Add refs exists subcommand","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-08-21T16:01:02Z","receivedAt":"2025-08-21T16:01:04Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Meet Soni <meetsoni3017@gmail.com> writes:\n\n> base-commit: c44beea485f0f2feaf460e2ac87fdd5608d63cf0\n> prerequisite-patch-id: 235cc677f372e9571dade4313f8cfed4eab65f7f\n> ... (~100 lines of crap omitted)\n> prerequisite-patch-id: 553adfe23223a427db3f93e23dfb603c55cc5aae\n\nPlease don't force others to go hunt to find so many patches before\nbeing able to even recreate what you based your changes on.\n\nLearn the way how it is usually done by looking at:\n\nhttps://lore.kernel.org/git/20250106-b4-pks-object-file-racy-collision-check-v2-0-8b3984ecbb18@pks.im/\n\nBasically you would want to say\n\n    This is built on top of <commit> with <topic*> merged into it.\n\nwhere <commit> is a commit on 'master' (or 'maint' or an even older\nmaintenance track, if the topic is about fixing a bug in a released\nversion of Git), and <topic*> are topic branches in flight that can\nbe merged to the same integration target ('master', or an older\nmaintenance tracks you chose <commit> from).  And keep the number of\n<topic*> to an absolute minimum in order for your changes to work.\n\nThanks.\n"},{"id":"524698","messageId":"CAPhwyn2jW4p+_004OHYjtcScGFBEx3zXi50F2TYTDBjsUHFxgw@mail.gmail.com","threadId":"64005","inReplyTo":"xmqq7byw4qbl.fsf@gitster.g","subject":"Re: [GSoC][PATCH 0/2] Add refs exists subcommand","fromName":"Meet Soni","fromEmail":"meetsoni3017@gmail.com","sentAt":"2025-08-22T04:27:13Z","receivedAt":"2025-08-22T04:27:25Z","isPatch":true,"sender":{"key":"meetsoni3017@gmail.com","avatar":"https://avatars.githubusercontent.com/u/92802561?v=4"},"body":"On Thu, 21 Aug 2025 at 21:31, Junio C Hamano <gitster@pobox.com> wrote:\n>\n> Meet Soni <meetsoni3017@gmail.com> writes:\n>\n> > base-commit: c44beea485f0f2feaf460e2ac87fdd5608d63cf0\n> > prerequisite-patch-id: 235cc677f372e9571dade4313f8cfed4eab65f7f\n> > ... (~100 lines of crap omitted)\n> > prerequisite-patch-id: 553adfe23223a427db3f93e23dfb603c55cc5aae\n>\n> Please don't force others to go hunt to find so many patches before\n> being able to even recreate what you based your changes on.\n>\nI was a bit confused between cherry-picking and basing my series on next, and I\nended up doing the latter. I’ll fix it.\n\n> Learn the way how it is usually done by looking at:\n>\n> https://lore.kernel.org/git/20250106-b4-pks-object-file-racy-collision-check-v2-0-8b3984ecbb18@pks.im/\n>\n> Basically you would want to say\n>\n>     This is built on top of <commit> with <topic*> merged into it.\n>\n> where <commit> is a commit on 'master' (or 'maint' or an even older\n> maintenance track, if the topic is about fixing a bug in a released\n> version of Git), and <topic*> are topic branches in flight that can\n> be merged to the same integration target ('master', or an older\n> maintenance tracks you chose <commit> from).  And keep the number of\n> <topic*> to an absolute minimum in order for your changes to work.\n>\n> Thanks.\n\nThanks.\n"},{"id":"524699","messageId":"CAPhwyn0PAX12E_dmwE9UftcotKT5fyJq4xz5MTWkc7rz-qS-4g@mail.gmail.com","threadId":"64005","inReplyTo":"aKbzNNcZZ-E0FVeI@pks.im","subject":"Re: [GSoC][PATCH 2/2] t: add test for git refs exists subcommand","fromName":"Meet Soni","fromEmail":"meetsoni3017@gmail.com","sentAt":"2025-08-22T04:59:45Z","receivedAt":"2025-08-22T04:59:57Z","isPatch":true,"sender":{"key":"meetsoni3017@gmail.com","avatar":"https://avatars.githubusercontent.com/u/92802561?v=4"},"body":"On Thu, 21 Aug 2025 at 15:51, Patrick Steinhardt <ps@pks.im> wrote:\n>\n> On Thu, Aug 21, 2025 at 02:22:46PM +0530, Meet Soni wrote:\n> > The new `git refs exists` subcommand must have identical behavior to its\n> > predecessor, `git show-ref --exists`. To avoid duplicating the entire\n> > test suite, refactor the existing tests into a shareable helper script.\n> >\n> > Extract the tests for the `--exists` flag from `t1403-show-ref.sh` into\n> > a new `show-ref-exists-tests.sh` helper. The command under test is\n> > parameterized using the `$git_show_ref_exists` variable.\n> >\n> > Source new helper to both `t1403-show-ref.sh` and the new test file,\n>\n> s/new/this/, otherwise this reads grammatically wrong to me.\n>\n> >  test_done\n> > diff --git a/t/t1462-refs-exists.sh b/t/t1462-refs-exists.sh\n> > new file mode 100755\n> > index 0000000000..c00d76cc9e\n> > --- /dev/null\n> > +++ b/t/t1462-refs-exists.sh\n> > @@ -0,0 +1,22 @@\n> > +#!/bin/sh\n> > +\n> > +test_description='refs exists'\n> > +GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n> > +export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n> > +\n> > +. ./test-lib.sh\n> > +\n> > +git_show_ref_exists='git refs exists'\n> > +\n> > +test_expect_success setup '\n> > +     test_commit --annotate A &&\n> > +     git checkout -b side &&\n> > +     test_commit --annotate B &&\n> > +     git checkout main &&\n> > +     test_commit C &&\n> > +     git branch B A^0\n> > +'\n>\n> It's a bit weird that this setup needs to be replicated. I guess it\n> comes from the fact that t1403 also has a bunch of other tests for\n> git-show-ref(1) that are irrelevant to existence checks.\n>\n> How about we instead split out the existence-checks in t1403 into a\n> separate test suite first and then pull out the whole logic from it in a\n> subsequent commit so that we can also share the setup?\n>\nThanks for the review. You're right, splitting the test commit into two is\ncleaner. I'll make that change and send out a v2 shortly.\n\n> Patrick\n\nThanks,\nMeet.\n"},{"id":"524765","messageId":"20250823060012.540433-1-meetsoni3017@gmail.com","threadId":"64005","inReplyTo":"20250821085246.929307-1-meetsoni3017@gmail.com","subject":"[GSoC][PATCH v2 0/4] Add refs exists subcommand","fromName":"Meet Soni","fromEmail":"meetsoni3017@gmail.com","sentAt":"2025-08-23T06:00:08Z","receivedAt":"2025-08-23T06:00:19Z","isPatch":true,"sender":{"key":"meetsoni3017@gmail.com","avatar":"https://avatars.githubusercontent.com/u/92802561?v=4"},"body":"This series introduces `git refs exists` as a modern replacement for\n`git show-ref --exists`, continuing the effort to consolidate commands\nunder the `git refs` namespace.\n\nChanges in v2:\n  - v1 was based on the \"next\" branch as this series required a couple\n    of commits merged in it, but as those commits are now completely\n    merged into the master branch, I've rebased the v2 onto master\n    branch.\n\n  - split the test commit to make the setup shareable.\n\nMeet Soni (4):\n  builtin/refs: add 'exists' subcommand\n  t1403: split 'show-ref --exists' tests into a separate file\n  t1422: refactor tests to be shareable\n  t: add test for git refs exists subcommand\n\n Documentation/git-refs.adoc |  7 ++++\n builtin/refs.c              | 48 +++++++++++++++++++++++\n t/meson.build               |  4 +-\n t/show-ref-exists-tests.sh  | 76 +++++++++++++++++++++++++++++++++++++\n t/t1403-show-ref.sh         | 65 -------------------------------\n t/t1422-show-ref-exists.sh  |  9 +++++\n t/t1462-refs-exists.sh      | 10 +++++\n 7 files changed, 153 insertions(+), 66 deletions(-)\n create mode 100644 t/show-ref-exists-tests.sh\n create mode 100755 t/t1422-show-ref-exists.sh\n create mode 100755 t/t1462-refs-exists.sh\n\nRange-diff against v1:\n 1:  3fe68ee250 <  -:  ---------- bloom: optimize multiple pathspec items in revision\n 2:  36554bf51a <  -:  ---------- commit: convert pop_most_recent_commit() to prio_queue\n 3:  304f06e0c0 <  -:  ---------- commit: use prio_queue_replace() in pop_most_recent_commit(),MIME-Version: 1.0\n 4:  e436bc94f3 <  -:  ---------- prio-queue: add prio_queue_replace()\n 5:  c7a5d9a13c <  -:  ---------- Revert \"Merge branch 'rs/pop-recent-commit-with-prio-queue' into next\"\n 6:  d66d5bfc41 <  -:  ---------- archive: flush deflate stream until Z_STREAM_END\n 7:  5297b08916 <  -:  ---------- Revert \"Merge branch 'jt/archive-zip-deflate-fix' into next\"\n 8:  19623eb97e <  -:  ---------- doc: factor out common option\n 9:  69c207dc45 <  -:  ---------- builtin/for-each-ref: align usage string with the man page\n10:  6eeb1c070a <  -:  ---------- builtin/for-each-ref: factor out core logic into a helper\n11:  eecccfe98b <  -:  ---------- builtin/refs: add list subcommand\n12:  aa91c5c570 <  -:  ---------- t6300: refactor tests to be shareable\n13:  fed66d91c0 <  -:  ---------- t: add test for git refs list subcommand\n14:  9bb4abe6cd <  -:  ---------- combine-diff: zero memory used for callback filepairs\n15:  2a43e0e550 <  -:  ---------- within_depth: fix return for empty path\n16:  a1dfa5448d <  -:  ---------- diff: teach tree-diff a max-depth parameter\n17:  b55e6d36eb <  -:  ---------- diff: ensure consistent diff behavior with ignore options\n18:  fe54b9ef02 <  -:  ---------- parse-options: refactor flags for usage_with_options_internal\n19:  129b3632f3 <  -:  ---------- builtin: also setup gently for --help-all\n20:  e1d3d61a45 <  -:  ---------- diff: --no-index should ignore the worktree\n21:  621ce9c1c6 <  -:  ---------- git-jump: make `diff` work with filenames containing spaces\n22:  9a49aef8dc <  -:  ---------- environment: remove the global variable 'merge_log_config'\n23:  22d421fed9 <  -:  ---------- builtin/fmt-merge-msg: stop depending on 'the_repository'\n24:  f81a574f59 <  -:  ---------- doc: test linkgit macros for well-formedness\n25:  63d33eb7f6 <  -:  ---------- doc: check well-formedness of delimited sections\n26:  ed26022094 <  -:  ---------- doc: check for absence of multiple terms in each entry of desc list\n27:  03a353bb97 <  -:  ---------- doc: check for absence of the form --[no-]parameter\n28:  93203872d7 <  -:  ---------- doc:git-for-each-ref: fix styling and typos\n29:  84f3d6e11e <  -:  ---------- doc lint: check that synopsis manpages have synopsis inlines\n30:  741f36c7d9 <  -:  ---------- docs: remove stray bracket from git-clone synopsis\n31:  83d64df8d5 <  -:  ---------- t7005: use modern test style\n32:  a9c4141abb <  -:  ---------- t7005: stop abusing --exec-path\n33:  a60203a015 <  -:  ---------- t7005: sanitize test environment for subsequent tests\n34:  7d4a5fef7d <  -:  ---------- count-objects: document count-objects pack\n35:  3481cb7dfd <  -:  ---------- commit-graph: stop using `the_hash_algo` via macros\n36:  e45402bb19 <  -:  ---------- commit-graph: store the hash algorithm instead of its length\n37:  f1141b4391 <  -:  ---------- commit-graph: refactor `parse_commit_graph()` to take a repository\n38:  89cc9b9adf <  -:  ---------- commit-graph: stop using `the_hash_algo`\n39:  ddacfc7466 <  -:  ---------- commit-graph: stop using `the_repository`\n40:  7be9e410b2 <  -:  ---------- commit-graph: stop passing in redundant repository\n41:  cab69db9c3 <  -:  ---------- t/t1517: mark tests that fail with GIT_TEST_INSTALLED\n42:  ab94bb8000 <  -:  ---------- repo: declare the repo command\n43:  9adb8a7fd1 <  -:  ---------- repo: add the field references.format\n44:  acf2669b54 <  -:  ---------- repo: add the field layout.bare\n45:  e52cd654c9 <  -:  ---------- repo: add the field layout.shallow\n46:  a81224d128 <  -:  ---------- repo: add the --format flag\n47:  d59b2a3793 <  -:  ---------- Revert \"Merge branch 'ad/t1517-short-help-tests-fix' into next\"\n48:  5643b59dea !  1:  d1fa4e927e builtin/refs: add 'exists' subcommand\n    @@ Commit message\n         builtin/refs: add 'exists' subcommand\n     \n         As part of the ongoing effort to consolidate reference handling,\n    -    introduce a new `exists` subcommand. This command provides the same\n    +    introduce `exists` subcommand. This command provides the same\n         functionality and exit-code behavior as `git show-ref --exists`, serving\n         as its modern replacement.\n     \n    @@ Commit message\n         `git refs list`, where sharing the larger implementation of\n         `for-each-ref` was necessary.\n     \n    -    Documentation for the new subcommand is also added to the `git-refs(1)`\n    +    Documentation for this subcommand is also added to the `git-refs(1)`\n         man page.\n     \n         Mentored-by: Patrick Steinhardt <ps@pks.im>\n    @@ Documentation/git-refs.adoc\n     @@ Documentation/git-refs.adoc: git refs list [--count=<count>] [--shell|--perl|--python|--tcl]\n      \t\t   [--contains[=<object>]] [--no-contains[=<object>]]\n      \t\t   [(--exclude=<pattern>)...] [--start-after=<marker>]\n    - \t\t   [ --stdin | (<pattern>...)]\n    + \t\t   [ --stdin | <pattern>... ]\n     +git refs exists <ref>\n      \n      DESCRIPTION\n    @@ builtin/refs.c: static int cmd_refs_list(int argc, const char **argv, const char\n     +\tunsigned int unused_type;\n     +\tint failure_errno = 0;\n     +\tconst char *ref;\n    -+\n    ++\tint ret = 0;\n     +\tconst char * const exists_usage[] = {\n     +\t\tREFS_EXISTS_USAGE,\n     +\t\tNULL,\n    @@ builtin/refs.c: static int cmd_refs_list(int argc, const char **argv, const char\n     +\t};\n     +\n     +\targc = parse_options(argc, argv, prefix, options, exists_usage, 0);\n    -+\tif (!argc)\n    -+\t\tdie(\"'git refs exists' requires a reference\");\n    ++\tif (argc != 1)\n    ++\t\tdie(_(\"'git refs exists' requires a reference\"));\n     +\n     +\tref = *argv++;\n    -+\tif (*argv)\n    -+\t\tdie(\"'git refs exists' requires exactly one reference\");\n    -+\n     +\tif (refs_read_raw_ref(get_main_ref_store(the_repository), ref,\n     +\t\t\t      &unused_oid, &unused_referent, &unused_type,\n     +\t\t\t      &failure_errno)) {\n     +\t\tif (failure_errno == ENOENT || failure_errno == EISDIR) {\n     +\t\t\terror(_(\"reference does not exist\"));\n    -+\t\t\treturn 2;\n    ++\t\t\tret = 2;\n     +\t\t} else {\n     +\t\t\terrno = failure_errno;\n     +\t\t\terror_errno(_(\"failed to look up reference\"));\n    -+\t\t\treturn 1;\n    ++\t\t\tret = 1;\n     +\t\t}\n    ++\n    ++\t\tgoto out;\n     +\t}\n     +\n    ++out:\n     +\tstrbuf_release(&unused_referent);\n    -+\treturn 0;\n    ++\treturn ret;\n     +}\n     +\n      int cmd_refs(int argc,\n -:  ---------- >  2:  f1dfafe6c9 t1403: split 'show-ref --exists' tests into a separate file\n49:  e14bd088bd !  3:  a2a65c428c t: add test for git refs exists subcommand\n    @@ Metadata\n     Author: Meet Soni <meetsoni3017@gmail.com>\n     \n      ## Commit message ##\n    -    t: add test for git refs exists subcommand\n    +    t1422: refactor tests to be shareable\n     \n    -    The new `git refs exists` subcommand must have identical behavior to its\n    -    predecessor, `git show-ref --exists`. To avoid duplicating the entire\n    -    test suite, refactor the existing tests into a shareable helper script.\n    +    In preparation for adding tests for the `git refs exists` command,\n    +    refactor the existing t1422 test suite to make its logic shareable.\n     \n    -    Extract the tests for the `--exists` flag from `t1403-show-ref.sh` into\n    -    a new `show-ref-exists-tests.sh` helper. The command under test is\n    -    parameterized using the `$git_show_ref_exists` variable.\n    +    Move the core test logic from `t1422-show-ref-exists.sh` to\n    +    `show-ref-exists-tests.sh` file. Inside this script, replace hardcoded\n    +    calls to \"git show-ref --exists\" with the `$git_show_ref_exists`\n    +    variable.\n     \n    -    Source new helper to both `t1403-show-ref.sh` and the new test file,\n    -    `t1462-refs-exists.sh`, ensuring both commands are verified against the\n    -    same comprehensive test suite.\n    +    The original `t1422-show-ref-exists.sh` script now becomes a simple\n    +    \"driver\". It is responsible for setting the default value of the\n    +    variable and then sourcing the test library.\n    +\n    +    This structure follows an established pattern for sharing tests and\n    +    prepares the test suite for the `refs exists` tests to be added in a\n    +    subsequent commit.\n     \n         Mentored-by: Patrick Steinhardt <ps@pks.im>\n         Mentored-by: shejialuo <shejialuo@gmail.com>\n         Signed-off-by: Meet Soni <meetsoni3017@gmail.com>\n     \n    - ## t/meson.build ##\n    -@@ t/meson.build: integration_tests = [\n    -   't1451-fsck-buffer.sh',\n    -   't1460-refs-migrate.sh',\n    -   't1461-refs-list.sh',\n    -+  't1462-refs-exists.sh',\n    -   't1500-rev-parse.sh',\n    -   't1501-work-tree.sh',\n    -   't1502-rev-parse-parseopt.sh',\n    -@@ t/meson.build: if perl.found() and time.found()\n    -       timeout: 0,\n    -     )\n    -   endforeach\n    --endif\n    - \\ No newline at end of file\n    -+endif\n    -\n      ## t/show-ref-exists-tests.sh (new) ##\n     @@\n     +git_show_ref_exists=${git_show_ref_exists:-git show-ref --exists}\n    ++test_expect_success setup '\n    ++\ttest_commit --annotate A &&\n    ++\tgit checkout -b side &&\n    ++\ttest_commit --annotate B &&\n    ++\tgit checkout main &&\n    ++\ttest_commit C &&\n    ++\tgit branch B A^0\n    ++'\n     +\n     +test_expect_success '--exists with existing reference' '\n     +\t${git_show_ref_exists} refs/heads/$GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n    @@ t/show-ref-exists-tests.sh (new)\n     +\tgit rev-parse HEAD >.git/FETCH_HEAD &&\n     +\t${git_show_ref_exists} FETCH_HEAD\n     +'\n    ++\n    ++test_done\n     \n    - ## t/t1403-show-ref.sh ##\n    -@@ t/t1403-show-ref.sh: test_expect_success 'show-ref sub-modes are mutually exclusive' '\n    - \tgrep \"cannot be used together\" err\n    - '\n    + ## t/t1422-show-ref-exists.sh (mode change 100644 => 100755) ##\n    +@@ t/t1422-show-ref-exists.sh: export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n    + \n    + . ./test-lib.sh\n      \n    +-test_expect_success setup '\n    +-\ttest_commit --annotate A &&\n    +-\tgit checkout -b side &&\n    +-\ttest_commit --annotate B &&\n    +-\tgit checkout main &&\n    +-\ttest_commit C &&\n    +-\tgit branch B A^0\n    +-'\n    +-\n     -test_expect_success '--exists with existing reference' '\n     -\tgit show-ref --exists refs/heads/$GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n     -'\n    @@ t/t1403-show-ref.sh: test_expect_success 'show-ref sub-modes are mutually exclus\n     -\tgit show-ref --exists FETCH_HEAD\n     -'\n     -\n    +-test_done\n     +. \"$TEST_DIRECTORY\"/show-ref-exists-tests.sh\n    - test_done\n    -\n    - ## t/t1462-refs-exists.sh (new) ##\n    -@@\n    -+#!/bin/sh\n    -+\n    -+test_description='refs exists'\n    -+GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n    -+export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n    -+\n    -+. ./test-lib.sh\n    -+\n    -+git_show_ref_exists='git refs exists'\n    -+\n    -+test_expect_success setup '\n    -+\ttest_commit --annotate A &&\n    -+\tgit checkout -b side &&\n    -+\ttest_commit --annotate B &&\n    -+\tgit checkout main &&\n    -+\ttest_commit C &&\n    -+\tgit branch B A^0\n    -+'\n    -+\n    -+. \"$TEST_DIRECTORY\"/show-ref-exists-tests.sh\n    -+\n    -+test_done\n -:  ---------- >  4:  e92da499b5 t: add test for git refs exists subcommand\n-- \n2.34.1\n\n"},{"id":"524766","messageId":"20250823060012.540433-2-meetsoni3017@gmail.com","threadId":"64005","inReplyTo":"20250823060012.540433-1-meetsoni3017@gmail.com","subject":"[GSoC][PATCH v2 1/4] builtin/refs: add 'exists' subcommand","fromName":"Meet Soni","fromEmail":"meetsoni3017@gmail.com","sentAt":"2025-08-23T06:00:09Z","receivedAt":"2025-08-23T06:00:22Z","isPatch":true,"sender":{"key":"meetsoni3017@gmail.com","avatar":"https://avatars.githubusercontent.com/u/92802561?v=4"},"body":"As part of the ongoing effort to consolidate reference handling,\nintroduce `exists` subcommand. This command provides the same\nfunctionality and exit-code behavior as `git show-ref --exists`, serving\nas its modern replacement.\n\nThe logic for `show-ref --exists` is minimal. Rather than creating a\nshared helper function which would be overkill for ~20 lines of code,\nits implementation is intentionally duplicated here. This contrasts with\n`git refs list`, where sharing the larger implementation of\n`for-each-ref` was necessary.\n\nDocumentation for this subcommand is also added to the `git-refs(1)`\nman page.\n\nMentored-by: Patrick Steinhardt <ps@pks.im>\nMentored-by: shejialuo <shejialuo@gmail.com>\nSigned-off-by: Meet Soni <meetsoni3017@gmail.com>\n---\n Documentation/git-refs.adoc |  7 ++++++\n builtin/refs.c              | 48 +++++++++++++++++++++++++++++++++++++\n 2 files changed, 55 insertions(+)\n\ndiff --git a/Documentation/git-refs.adoc b/Documentation/git-refs.adoc\nindex e608980711..5d2032b318 100644\n--- a/Documentation/git-refs.adoc\n+++ b/Documentation/git-refs.adoc\n@@ -18,6 +18,7 @@ git refs list [--count=<count>] [--shell|--perl|--python|--tcl]\n \t\t   [--contains[=<object>]] [--no-contains[=<object>]]\n \t\t   [(--exclude=<pattern>)...] [--start-after=<marker>]\n \t\t   [ --stdin | <pattern>... ]\n+git refs exists <ref>\n \n DESCRIPTION\n -----------\n@@ -38,6 +39,12 @@ list::\n \tformatting, and sorting. This subcommand is an alias for\n \tlinkgit:git-for-each-ref[1] and offers identical functionality.\n \n+exists::\n+\tCheck whether the given reference exists. Returns an exit code of 0 if\n+\tit does, 2 if it is missing, and 1 in case looking up the reference\n+\tfailed with an error other than the reference being missing. This does\n+\tnot verify whether the reference resolves to an actual object.\n+\n OPTIONS\n -------\n \ndiff --git a/builtin/refs.c b/builtin/refs.c\nindex 76224feba4..91548783b7 100644\n--- a/builtin/refs.c\n+++ b/builtin/refs.c\n@@ -7,6 +7,7 @@\n #include \"strbuf.h\"\n #include \"worktree.h\"\n #include \"for-each-ref.h\"\n+#include \"refs/refs-internal.h\"\n \n #define REFS_MIGRATE_USAGE \\\n \tN_(\"git refs migrate --ref-format=<format> [--no-reflog] [--dry-run]\")\n@@ -14,6 +15,9 @@\n #define REFS_VERIFY_USAGE \\\n \tN_(\"git refs verify [--strict] [--verbose]\")\n \n+#define REFS_EXISTS_USAGE \\\n+\tN_(\"git refs exists <ref>\")\n+\n static int cmd_refs_migrate(int argc, const char **argv, const char *prefix,\n \t\t\t    struct repository *repo UNUSED)\n {\n@@ -113,6 +117,48 @@ static int cmd_refs_list(int argc, const char **argv, const char *prefix,\n \treturn for_each_ref_core(argc, argv, prefix, repo, refs_list_usage);\n }\n \n+static int cmd_refs_exists(int argc, const char **argv, const char *prefix,\n+\t\t\t   struct repository *repo UNUSED)\n+{\n+\tstruct strbuf unused_referent = STRBUF_INIT;\n+\tstruct object_id unused_oid;\n+\tunsigned int unused_type;\n+\tint failure_errno = 0;\n+\tconst char *ref;\n+\tint ret = 0;\n+\tconst char * const exists_usage[] = {\n+\t\tREFS_EXISTS_USAGE,\n+\t\tNULL,\n+\t};\n+\tstruct option options[] = {\n+\t\tOPT_END(),\n+\t};\n+\n+\targc = parse_options(argc, argv, prefix, options, exists_usage, 0);\n+\tif (argc != 1)\n+\t\tdie(_(\"'git refs exists' requires a reference\"));\n+\n+\tref = *argv++;\n+\tif (refs_read_raw_ref(get_main_ref_store(the_repository), ref,\n+\t\t\t      &unused_oid, &unused_referent, &unused_type,\n+\t\t\t      &failure_errno)) {\n+\t\tif (failure_errno == ENOENT || failure_errno == EISDIR) {\n+\t\t\terror(_(\"reference does not exist\"));\n+\t\t\tret = 2;\n+\t\t} else {\n+\t\t\terrno = failure_errno;\n+\t\t\terror_errno(_(\"failed to look up reference\"));\n+\t\t\tret = 1;\n+\t\t}\n+\n+\t\tgoto out;\n+\t}\n+\n+out:\n+\tstrbuf_release(&unused_referent);\n+\treturn ret;\n+}\n+\n int cmd_refs(int argc,\n \t     const char **argv,\n \t     const char *prefix,\n@@ -122,6 +168,7 @@ int cmd_refs(int argc,\n \t\tREFS_MIGRATE_USAGE,\n \t\tREFS_VERIFY_USAGE,\n \t\t\"git refs list \" COMMON_USAGE_FOR_EACH_REF,\n+\t\tREFS_EXISTS_USAGE,\n \t\tNULL,\n \t};\n \tparse_opt_subcommand_fn *fn = NULL;\n@@ -129,6 +176,7 @@ int cmd_refs(int argc,\n \t\tOPT_SUBCOMMAND(\"migrate\", &fn, cmd_refs_migrate),\n \t\tOPT_SUBCOMMAND(\"verify\", &fn, cmd_refs_verify),\n \t\tOPT_SUBCOMMAND(\"list\", &fn, cmd_refs_list),\n+\t\tOPT_SUBCOMMAND(\"exists\", &fn, cmd_refs_exists),\n \t\tOPT_END(),\n \t};\n \n-- \n2.34.1\n\n"},{"id":"524767","messageId":"20250823060012.540433-3-meetsoni3017@gmail.com","threadId":"64005","inReplyTo":"20250823060012.540433-1-meetsoni3017@gmail.com","subject":"[GSoC][PATCH v2 2/4] t1403: split 'show-ref --exists' tests into a separate file","fromName":"Meet Soni","fromEmail":"meetsoni3017@gmail.com","sentAt":"2025-08-23T06:00:10Z","receivedAt":"2025-08-23T06:00:24Z","isPatch":true,"sender":{"key":"meetsoni3017@gmail.com","avatar":"https://avatars.githubusercontent.com/u/92802561?v=4"},"body":"The test file for git-show-ref(1), `t1403-show-ref.sh`, contains a group\nof tests for the '--exists' flag. To improve organization and to prepare\nfor refactoring these tests to be shareable, move the '--exists' tests\nand their corresponding setup logic into a self-contained test suite,\n`t1422-show-ref-exists.sh`.\n\nThis is a pure code-movement refactoring with no change in test coverage\nor behavior.\n\nMentored-by: Patrick Steinhardt <ps@pks.im>\nMentored-by: shejialuo <shejialuo@gmail.com>\nSigned-off-by: Meet Soni <meetsoni3017@gmail.com>\n---\n t/meson.build              |  3 +-\n t/t1403-show-ref.sh        | 65 -----------------------------\n t/t1422-show-ref-exists.sh | 83 ++++++++++++++++++++++++++++++++++++++\n 3 files changed, 85 insertions(+), 66 deletions(-)\n create mode 100644 t/t1422-show-ref-exists.sh\n\ndiff --git a/t/meson.build b/t/meson.build\nindex daf01fb5d0..4d6bc3d38e 100644\n--- a/t/meson.build\n+++ b/t/meson.build\n@@ -205,6 +205,7 @@ integration_tests = [\n   't1419-exclude-refs.sh',\n   't1420-lost-found.sh',\n   't1421-reflog-write.sh',\n+  't1422-show-ref-exists.sh',\n   't1430-bad-ref-name.sh',\n   't1450-fsck.sh',\n   't1451-fsck-buffer.sh',\n@@ -1216,4 +1217,4 @@ if perl.found() and time.found()\n       timeout: 0,\n     )\n   endforeach\n-endif\n\\ No newline at end of file\n+endif\ndiff --git a/t/t1403-show-ref.sh b/t/t1403-show-ref.sh\nindex 9da3650e91..36c903ca19 100755\n--- a/t/t1403-show-ref.sh\n+++ b/t/t1403-show-ref.sh\n@@ -228,69 +228,4 @@ test_expect_success 'show-ref sub-modes are mutually exclusive' '\n \tgrep \"cannot be used together\" err\n '\n \n-test_expect_success '--exists with existing reference' '\n-\tgit show-ref --exists refs/heads/$GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n-'\n-\n-test_expect_success '--exists with missing reference' '\n-\ttest_expect_code 2 git show-ref --exists refs/heads/does-not-exist\n-'\n-\n-test_expect_success '--exists does not use DWIM' '\n-\ttest_expect_code 2 git show-ref --exists $GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME 2>err &&\n-\tgrep \"reference does not exist\" err\n-'\n-\n-test_expect_success '--exists with HEAD' '\n-\tgit show-ref --exists HEAD\n-'\n-\n-test_expect_success '--exists with bad reference name' '\n-\ttest_when_finished \"git update-ref -d refs/heads/bad...name\" &&\n-\tnew_oid=$(git rev-parse HEAD) &&\n-\ttest-tool ref-store main update-ref msg refs/heads/bad...name $new_oid $ZERO_OID REF_SKIP_REFNAME_VERIFICATION &&\n-\tgit show-ref --exists refs/heads/bad...name\n-'\n-\n-test_expect_success '--exists with arbitrary symref' '\n-\ttest_when_finished \"git symbolic-ref -d refs/symref\" &&\n-\tgit symbolic-ref refs/symref refs/heads/$GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME &&\n-\tgit show-ref --exists refs/symref\n-'\n-\n-test_expect_success '--exists with dangling symref' '\n-\ttest_when_finished \"git symbolic-ref -d refs/heads/dangling\" &&\n-\tgit symbolic-ref refs/heads/dangling refs/heads/does-not-exist &&\n-\tgit show-ref --exists refs/heads/dangling\n-'\n-\n-test_expect_success '--exists with nonexistent object ID' '\n-\ttest-tool ref-store main update-ref msg refs/heads/missing-oid $(test_oid 001) $ZERO_OID REF_SKIP_OID_VERIFICATION &&\n-\tgit show-ref --exists refs/heads/missing-oid\n-'\n-\n-test_expect_success '--exists with non-commit object' '\n-\ttree_oid=$(git rev-parse HEAD^{tree}) &&\n-\ttest-tool ref-store main update-ref msg refs/heads/tree ${tree_oid} $ZERO_OID REF_SKIP_OID_VERIFICATION &&\n-\tgit show-ref --exists refs/heads/tree\n-'\n-\n-test_expect_success '--exists with directory fails with generic error' '\n-\tcat >expect <<-EOF &&\n-\terror: reference does not exist\n-\tEOF\n-\ttest_expect_code 2 git show-ref --exists refs/heads 2>err &&\n-\ttest_cmp expect err\n-'\n-\n-test_expect_success '--exists with non-existent special ref' '\n-\ttest_expect_code 2 git show-ref --exists FETCH_HEAD\n-'\n-\n-test_expect_success '--exists with existing special ref' '\n-\ttest_when_finished \"rm .git/FETCH_HEAD\" &&\n-\tgit rev-parse HEAD >.git/FETCH_HEAD &&\n-\tgit show-ref --exists FETCH_HEAD\n-'\n-\n test_done\ndiff --git a/t/t1422-show-ref-exists.sh b/t/t1422-show-ref-exists.sh\nnew file mode 100644\nindex 0000000000..0eccb2dce1\n--- /dev/null\n+++ b/t/t1422-show-ref-exists.sh\n@@ -0,0 +1,83 @@\n+#!/bin/sh\n+\n+test_description='show-ref --exists'\n+GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n+export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n+\n+. ./test-lib.sh\n+\n+test_expect_success setup '\n+\ttest_commit --annotate A &&\n+\tgit checkout -b side &&\n+\ttest_commit --annotate B &&\n+\tgit checkout main &&\n+\ttest_commit C &&\n+\tgit branch B A^0\n+'\n+\n+test_expect_success '--exists with existing reference' '\n+\tgit show-ref --exists refs/heads/$GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n+'\n+\n+test_expect_success '--exists with missing reference' '\n+\ttest_expect_code 2 git show-ref --exists refs/heads/does-not-exist\n+'\n+\n+test_expect_success '--exists does not use DWIM' '\n+\ttest_expect_code 2 git show-ref --exists $GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME 2>err &&\n+\tgrep \"reference does not exist\" err\n+'\n+\n+test_expect_success '--exists with HEAD' '\n+\tgit show-ref --exists HEAD\n+'\n+\n+test_expect_success '--exists with bad reference name' '\n+\ttest_when_finished \"git update-ref -d refs/heads/bad...name\" &&\n+\tnew_oid=$(git rev-parse HEAD) &&\n+\ttest-tool ref-store main update-ref msg refs/heads/bad...name $new_oid $ZERO_OID REF_SKIP_REFNAME_VERIFICATION &&\n+\tgit show-ref --exists refs/heads/bad...name\n+'\n+\n+test_expect_success '--exists with arbitrary symref' '\n+\ttest_when_finished \"git symbolic-ref -d refs/symref\" &&\n+\tgit symbolic-ref refs/symref refs/heads/$GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME &&\n+\tgit show-ref --exists refs/symref\n+'\n+\n+test_expect_success '--exists with dangling symref' '\n+\ttest_when_finished \"git symbolic-ref -d refs/heads/dangling\" &&\n+\tgit symbolic-ref refs/heads/dangling refs/heads/does-not-exist &&\n+\tgit show-ref --exists refs/heads/dangling\n+'\n+\n+test_expect_success '--exists with nonexistent object ID' '\n+\ttest-tool ref-store main update-ref msg refs/heads/missing-oid $(test_oid 001) $ZERO_OID REF_SKIP_OID_VERIFICATION &&\n+\tgit show-ref --exists refs/heads/missing-oid\n+'\n+\n+test_expect_success '--exists with non-commit object' '\n+\ttree_oid=$(git rev-parse HEAD^{tree}) &&\n+\ttest-tool ref-store main update-ref msg refs/heads/tree ${tree_oid} $ZERO_OID REF_SKIP_OID_VERIFICATION &&\n+\tgit show-ref --exists refs/heads/tree\n+'\n+\n+test_expect_success '--exists with directory fails with generic error' '\n+\tcat >expect <<-EOF &&\n+\terror: reference does not exist\n+\tEOF\n+\ttest_expect_code 2 git show-ref --exists refs/heads 2>err &&\n+\ttest_cmp expect err\n+'\n+\n+test_expect_success '--exists with non-existent special ref' '\n+\ttest_expect_code 2 git show-ref --exists FETCH_HEAD\n+'\n+\n+test_expect_success '--exists with existing special ref' '\n+\ttest_when_finished \"rm .git/FETCH_HEAD\" &&\n+\tgit rev-parse HEAD >.git/FETCH_HEAD &&\n+\tgit show-ref --exists FETCH_HEAD\n+'\n+\n+test_done\n-- \n2.34.1\n\n"},{"id":"524768","messageId":"20250823060012.540433-4-meetsoni3017@gmail.com","threadId":"64005","inReplyTo":"20250823060012.540433-1-meetsoni3017@gmail.com","subject":"[GSoC][PATCH v2 3/4] t1422: refactor tests to be shareable","fromName":"Meet Soni","fromEmail":"meetsoni3017@gmail.com","sentAt":"2025-08-23T06:00:11Z","receivedAt":"2025-08-23T06:00:27Z","isPatch":true,"sender":{"key":"meetsoni3017@gmail.com","avatar":"https://avatars.githubusercontent.com/u/92802561?v=4"},"body":"In preparation for adding tests for the `git refs exists` command,\nrefactor the existing t1422 test suite to make its logic shareable.\n\nMove the core test logic from `t1422-show-ref-exists.sh` to\n`show-ref-exists-tests.sh` file. Inside this script, replace hardcoded\ncalls to \"git show-ref --exists\" with the `$git_show_ref_exists`\nvariable.\n\nThe original `t1422-show-ref-exists.sh` script now becomes a simple\n\"driver\". It is responsible for setting the default value of the\nvariable and then sourcing the test library.\n\nThis structure follows an established pattern for sharing tests and\nprepares the test suite for the `refs exists` tests to be added in a\nsubsequent commit.\n\nMentored-by: Patrick Steinhardt <ps@pks.im>\nMentored-by: shejialuo <shejialuo@gmail.com>\nSigned-off-by: Meet Soni <meetsoni3017@gmail.com>\n---\n t/show-ref-exists-tests.sh | 76 ++++++++++++++++++++++++++++++++++++++\n t/t1422-show-ref-exists.sh | 76 +-------------------------------------\n 2 files changed, 77 insertions(+), 75 deletions(-)\n create mode 100644 t/show-ref-exists-tests.sh\n mode change 100644 => 100755 t/t1422-show-ref-exists.sh\n\ndiff --git a/t/show-ref-exists-tests.sh b/t/show-ref-exists-tests.sh\nnew file mode 100644\nindex 0000000000..2c29643573\n--- /dev/null\n+++ b/t/show-ref-exists-tests.sh\n@@ -0,0 +1,76 @@\n+git_show_ref_exists=${git_show_ref_exists:-git show-ref --exists}\n+test_expect_success setup '\n+\ttest_commit --annotate A &&\n+\tgit checkout -b side &&\n+\ttest_commit --annotate B &&\n+\tgit checkout main &&\n+\ttest_commit C &&\n+\tgit branch B A^0\n+'\n+\n+test_expect_success '--exists with existing reference' '\n+\t${git_show_ref_exists} refs/heads/$GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n+'\n+\n+test_expect_success '--exists with missing reference' '\n+\ttest_expect_code 2 ${git_show_ref_exists} refs/heads/does-not-exist\n+'\n+\n+test_expect_success '--exists does not use DWIM' '\n+\ttest_expect_code 2 ${git_show_ref_exists} $GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME 2>err &&\n+\tgrep \"reference does not exist\" err\n+'\n+\n+test_expect_success '--exists with HEAD' '\n+\t${git_show_ref_exists} HEAD\n+'\n+\n+test_expect_success '--exists with bad reference name' '\n+\ttest_when_finished \"git update-ref -d refs/heads/bad...name\" &&\n+\tnew_oid=$(git rev-parse HEAD) &&\n+\ttest-tool ref-store main update-ref msg refs/heads/bad...name $new_oid $ZERO_OID REF_SKIP_REFNAME_VERIFICATION &&\n+\t${git_show_ref_exists} refs/heads/bad...name\n+'\n+\n+test_expect_success '--exists with arbitrary symref' '\n+\ttest_when_finished \"git symbolic-ref -d refs/symref\" &&\n+\tgit symbolic-ref refs/symref refs/heads/$GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME &&\n+\t${git_show_ref_exists} refs/symref\n+'\n+\n+test_expect_success '--exists with dangling symref' '\n+\ttest_when_finished \"git symbolic-ref -d refs/heads/dangling\" &&\n+\tgit symbolic-ref refs/heads/dangling refs/heads/does-not-exist &&\n+\t${git_show_ref_exists} refs/heads/dangling\n+'\n+\n+test_expect_success '--exists with nonexistent object ID' '\n+\ttest-tool ref-store main update-ref msg refs/heads/missing-oid $(test_oid 001) $ZERO_OID REF_SKIP_OID_VERIFICATION &&\n+\t${git_show_ref_exists} refs/heads/missing-oid\n+'\n+\n+test_expect_success '--exists with non-commit object' '\n+\ttree_oid=$(git rev-parse HEAD^{tree}) &&\n+\ttest-tool ref-store main update-ref msg refs/heads/tree ${tree_oid} $ZERO_OID REF_SKIP_OID_VERIFICATION &&\n+\t${git_show_ref_exists} refs/heads/tree\n+'\n+\n+test_expect_success '--exists with directory fails with generic error' '\n+\tcat >expect <<-EOF &&\n+\terror: reference does not exist\n+\tEOF\n+\ttest_expect_code 2 ${git_show_ref_exists} refs/heads 2>err &&\n+\ttest_cmp expect err\n+'\n+\n+test_expect_success '--exists with non-existent special ref' '\n+\ttest_expect_code 2 ${git_show_ref_exists} FETCH_HEAD\n+'\n+\n+test_expect_success '--exists with existing special ref' '\n+\ttest_when_finished \"rm .git/FETCH_HEAD\" &&\n+\tgit rev-parse HEAD >.git/FETCH_HEAD &&\n+\t${git_show_ref_exists} FETCH_HEAD\n+'\n+\n+test_done\ndiff --git a/t/t1422-show-ref-exists.sh b/t/t1422-show-ref-exists.sh\nold mode 100644\nnew mode 100755\nindex 0eccb2dce1..fdca3f16c8\n--- a/t/t1422-show-ref-exists.sh\n+++ b/t/t1422-show-ref-exists.sh\n@@ -6,78 +6,4 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n . ./test-lib.sh\n \n-test_expect_success setup '\n-\ttest_commit --annotate A &&\n-\tgit checkout -b side &&\n-\ttest_commit --annotate B &&\n-\tgit checkout main &&\n-\ttest_commit C &&\n-\tgit branch B A^0\n-'\n-\n-test_expect_success '--exists with existing reference' '\n-\tgit show-ref --exists refs/heads/$GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n-'\n-\n-test_expect_success '--exists with missing reference' '\n-\ttest_expect_code 2 git show-ref --exists refs/heads/does-not-exist\n-'\n-\n-test_expect_success '--exists does not use DWIM' '\n-\ttest_expect_code 2 git show-ref --exists $GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME 2>err &&\n-\tgrep \"reference does not exist\" err\n-'\n-\n-test_expect_success '--exists with HEAD' '\n-\tgit show-ref --exists HEAD\n-'\n-\n-test_expect_success '--exists with bad reference name' '\n-\ttest_when_finished \"git update-ref -d refs/heads/bad...name\" &&\n-\tnew_oid=$(git rev-parse HEAD) &&\n-\ttest-tool ref-store main update-ref msg refs/heads/bad...name $new_oid $ZERO_OID REF_SKIP_REFNAME_VERIFICATION &&\n-\tgit show-ref --exists refs/heads/bad...name\n-'\n-\n-test_expect_success '--exists with arbitrary symref' '\n-\ttest_when_finished \"git symbolic-ref -d refs/symref\" &&\n-\tgit symbolic-ref refs/symref refs/heads/$GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME &&\n-\tgit show-ref --exists refs/symref\n-'\n-\n-test_expect_success '--exists with dangling symref' '\n-\ttest_when_finished \"git symbolic-ref -d refs/heads/dangling\" &&\n-\tgit symbolic-ref refs/heads/dangling refs/heads/does-not-exist &&\n-\tgit show-ref --exists refs/heads/dangling\n-'\n-\n-test_expect_success '--exists with nonexistent object ID' '\n-\ttest-tool ref-store main update-ref msg refs/heads/missing-oid $(test_oid 001) $ZERO_OID REF_SKIP_OID_VERIFICATION &&\n-\tgit show-ref --exists refs/heads/missing-oid\n-'\n-\n-test_expect_success '--exists with non-commit object' '\n-\ttree_oid=$(git rev-parse HEAD^{tree}) &&\n-\ttest-tool ref-store main update-ref msg refs/heads/tree ${tree_oid} $ZERO_OID REF_SKIP_OID_VERIFICATION &&\n-\tgit show-ref --exists refs/heads/tree\n-'\n-\n-test_expect_success '--exists with directory fails with generic error' '\n-\tcat >expect <<-EOF &&\n-\terror: reference does not exist\n-\tEOF\n-\ttest_expect_code 2 git show-ref --exists refs/heads 2>err &&\n-\ttest_cmp expect err\n-'\n-\n-test_expect_success '--exists with non-existent special ref' '\n-\ttest_expect_code 2 git show-ref --exists FETCH_HEAD\n-'\n-\n-test_expect_success '--exists with existing special ref' '\n-\ttest_when_finished \"rm .git/FETCH_HEAD\" &&\n-\tgit rev-parse HEAD >.git/FETCH_HEAD &&\n-\tgit show-ref --exists FETCH_HEAD\n-'\n-\n-test_done\n+. \"$TEST_DIRECTORY\"/show-ref-exists-tests.sh\n-- \n2.34.1\n\n"},{"id":"524769","messageId":"20250823060012.540433-5-meetsoni3017@gmail.com","threadId":"64005","inReplyTo":"20250823060012.540433-1-meetsoni3017@gmail.com","subject":"[GSoC][PATCH v2 4/4] t: add test for git refs exists subcommand","fromName":"Meet Soni","fromEmail":"meetsoni3017@gmail.com","sentAt":"2025-08-23T06:00:12Z","receivedAt":"2025-08-23T06:00:30Z","isPatch":true,"sender":{"key":"meetsoni3017@gmail.com","avatar":"https://avatars.githubusercontent.com/u/92802561?v=4"},"body":"Add a test script, `t/t1462-refs-exists.sh`, for the `git refs exists`\ncommand.\n\nThis script acts as a simple driver, leveraging the shared test library\ncreated in the preceding commit. It works by overriding the\n`$git_show_ref_exists` variable to \"git refs exists\" and then sourcing the\nshared library (`t/show-ref-exists-tests.sh`).\n\nThis approach ensures that `git refs exists` is tested against the\nentire comprehensive test suite of `git show-ref --exists`, verifying\nthat it acts as a compatible drop-in replacement.\n\nMentored-by: Patrick Steinhardt <ps@pks.im>\nMentored-by: shejialuo <shejialuo@gmail.com>\nSigned-off-by: Meet Soni <meetsoni3017@gmail.com>\n---\n t/meson.build          |  1 +\n t/t1462-refs-exists.sh | 10 ++++++++++\n 2 files changed, 11 insertions(+)\n create mode 100755 t/t1462-refs-exists.sh\n\ndiff --git a/t/meson.build b/t/meson.build\nindex 4d6bc3d38e..93e9773ec8 100644\n--- a/t/meson.build\n+++ b/t/meson.build\n@@ -211,6 +211,7 @@ integration_tests = [\n   't1451-fsck-buffer.sh',\n   't1460-refs-migrate.sh',\n   't1461-refs-list.sh',\n+  't1462-refs-exists.sh',\n   't1500-rev-parse.sh',\n   't1501-work-tree.sh',\n   't1502-rev-parse-parseopt.sh',\ndiff --git a/t/t1462-refs-exists.sh b/t/t1462-refs-exists.sh\nnew file mode 100755\nindex 0000000000..349453c4ca\n--- /dev/null\n+++ b/t/t1462-refs-exists.sh\n@@ -0,0 +1,10 @@\n+#!/bin/sh\n+\n+test_description='refs exists'\n+GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n+export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n+\n+. ./test-lib.sh\n+\n+git_show_ref_exists='git refs exists'\n+. \"$TEST_DIRECTORY\"/show-ref-exists-tests.sh\n-- \n2.34.1\n\n"},{"id":"524816","messageId":"aKtEp7OyTXFdDPH0@pks.im","threadId":"64005","inReplyTo":"20250823060012.540433-1-meetsoni3017@gmail.com","subject":"Re: [GSoC][PATCH v2 0/4] Add refs exists subcommand","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2025-08-24T16:58:15Z","receivedAt":"2025-08-24T16:58:23Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Sat, Aug 23, 2025 at 11:30:08AM +0530, Meet Soni wrote:\n> This series introduces `git refs exists` as a modern replacement for\n> `git show-ref --exists`, continuing the effort to consolidate commands\n> under the `git refs` namespace.\n> \n> Changes in v2:\n>   - v1 was based on the \"next\" branch as this series required a couple\n>     of commits merged in it, but as those commits are now completely\n>     merged into the master branch, I've rebased the v2 onto master\n>     branch.\n\nGood.\n\n>   - split the test commit to make the setup shareable.\n\nGood, as well.\n\n>     @@ Commit message\n>          builtin/refs: add 'exists' subcommand\n>      \n>          As part of the ongoing effort to consolidate reference handling,\n>     -    introduce a new `exists` subcommand. This command provides the same\n>     +    introduce `exists` subcommand. This command provides the same\n>          functionality and exit-code behavior as `git show-ref --exists`, serving\n>          as its modern replacement.\n\nThis reads a bit funny now -- I think the previous version was\npreferable.\n\nPatrick\n"},{"id":"524817","messageId":"aKtEr0wwNHfiF4dN@pks.im","threadId":"64005","inReplyTo":"20250823060012.540433-4-meetsoni3017@gmail.com","subject":"Re: [GSoC][PATCH v2 3/4] t1422: refactor tests to be shareable","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2025-08-24T16:58:23Z","receivedAt":"2025-08-24T16:58:31Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Sat, Aug 23, 2025 at 11:30:11AM +0530, Meet Soni wrote:\n> diff --git a/t/show-ref-exists-tests.sh b/t/show-ref-exists-tests.sh\n> new file mode 100644\n> index 0000000000..2c29643573\n> --- /dev/null\n> +++ b/t/show-ref-exists-tests.sh\n> @@ -0,0 +1,76 @@\n> +git_show_ref_exists=${git_show_ref_exists:-git show-ref --exists}\n> +test_expect_success setup '\n\nTiny nit: let's add an empty line between these two lines.\n\nPatrick\n"},{"id":"524921","messageId":"20250826064110.10540-1-meetsoni3017@gmail.com","threadId":"64005","inReplyTo":"20250823060012.540433-1-meetsoni3017@gmail.com","subject":"[GSoC][PATCH v3 0/4] Add refs exists subcommand","fromName":"Meet Soni","fromEmail":"meetsoni3017@gmail.com","sentAt":"2025-08-26T06:41:06Z","receivedAt":"2025-08-26T06:41:17Z","isPatch":true,"sender":{"key":"meetsoni3017@gmail.com","avatar":"https://avatars.githubusercontent.com/u/92802561?v=4"},"body":"This series introduces `git refs exists` as a modern replacement for\n`git show-ref --exists`, continuing the effort to consolidate commands\nunder the `git refs` namespace.\n\nchanges in v3:\n - Reverted commit message.\n - nit: added empty line.\n\nMeet Soni (4):\n  builtin/refs: add 'exists' subcommand\n  t1403: split 'show-ref --exists' tests into a separate file\n  t1422: refactor tests to be shareable\n  t: add test for git refs exists subcommand\n\n Documentation/git-refs.adoc |  7 ++++\n builtin/refs.c              | 48 +++++++++++++++++++++++\n t/meson.build               |  4 +-\n t/show-ref-exists-tests.sh  | 77 +++++++++++++++++++++++++++++++++++++\n t/t1403-show-ref.sh         | 65 -------------------------------\n t/t1422-show-ref-exists.sh  |  9 +++++\n t/t1462-refs-exists.sh      | 10 +++++\n 7 files changed, 154 insertions(+), 66 deletions(-)\n create mode 100644 t/show-ref-exists-tests.sh\n create mode 100755 t/t1422-show-ref-exists.sh\n create mode 100755 t/t1462-refs-exists.sh\n\nRange-diff against v2:\n 1:  19623eb97e <  -:  ---------- doc: factor out common option\n 2:  69c207dc45 <  -:  ---------- builtin/for-each-ref: align usage string with the man page\n 3:  6eeb1c070a <  -:  ---------- builtin/for-each-ref: factor out core logic into a helper\n 4:  eecccfe98b <  -:  ---------- builtin/refs: add list subcommand\n 5:  aa91c5c570 <  -:  ---------- t6300: refactor tests to be shareable\n 6:  fed66d91c0 <  -:  ---------- t: add test for git refs list subcommand\n 7:  b55e6d36eb <  -:  ---------- diff: ensure consistent diff behavior with ignore options\n 8:  e1d3d61a45 <  -:  ---------- diff: --no-index should ignore the worktree\n 9:  621ce9c1c6 <  -:  ---------- git-jump: make `diff` work with filenames containing spaces\n10:  9a49aef8dc <  -:  ---------- environment: remove the global variable 'merge_log_config'\n11:  22d421fed9 <  -:  ---------- builtin/fmt-merge-msg: stop depending on 'the_repository'\n12:  741f36c7d9 <  -:  ---------- docs: remove stray bracket from git-clone synopsis\n13:  1fa68948c3 <  -:  ---------- The second batch\n14:  d1fa4e927e !  1:  0c9349fa74 builtin/refs: add 'exists' subcommand\n    @@ Commit message\n         builtin/refs: add 'exists' subcommand\n     \n         As part of the ongoing effort to consolidate reference handling,\n    -    introduce `exists` subcommand. This command provides the same\n    +    introduce a new `exists` subcommand. This command provides the same\n         functionality and exit-code behavior as `git show-ref --exists`, serving\n         as its modern replacement.\n     \n    @@ Commit message\n         `git refs list`, where sharing the larger implementation of\n         `for-each-ref` was necessary.\n     \n    -    Documentation for this subcommand is also added to the `git-refs(1)`\n    +    Documentation for the new subcommand is also added to the `git-refs(1)`\n         man page.\n     \n         Mentored-by: Patrick Steinhardt <ps@pks.im>\n15:  f1dfafe6c9 =  2:  d32067af55 t1403: split 'show-ref --exists' tests into a separate file\n16:  a2a65c428c !  3:  fb7223ad07 t1422: refactor tests to be shareable\n    @@ Commit message\n      ## t/show-ref-exists-tests.sh (new) ##\n     @@\n     +git_show_ref_exists=${git_show_ref_exists:-git show-ref --exists}\n    ++\n     +test_expect_success setup '\n     +\ttest_commit --annotate A &&\n     +\tgit checkout -b side &&\n17:  e92da499b5 =  4:  75b5ee4ede t: add test for git refs exists subcommand\n-- \n2.34.1\n\n"},{"id":"524922","messageId":"20250826064110.10540-2-meetsoni3017@gmail.com","threadId":"64005","inReplyTo":"20250826064110.10540-1-meetsoni3017@gmail.com","subject":"[GSoC][PATCH v3 1/4] builtin/refs: add 'exists' subcommand","fromName":"Meet Soni","fromEmail":"meetsoni3017@gmail.com","sentAt":"2025-08-26T06:41:07Z","receivedAt":"2025-08-26T06:41:19Z","isPatch":true,"sender":{"key":"meetsoni3017@gmail.com","avatar":"https://avatars.githubusercontent.com/u/92802561?v=4"},"body":"As part of the ongoing effort to consolidate reference handling,\nintroduce a new `exists` subcommand. This command provides the same\nfunctionality and exit-code behavior as `git show-ref --exists`, serving\nas its modern replacement.\n\nThe logic for `show-ref --exists` is minimal. Rather than creating a\nshared helper function which would be overkill for ~20 lines of code,\nits implementation is intentionally duplicated here. This contrasts with\n`git refs list`, where sharing the larger implementation of\n`for-each-ref` was necessary.\n\nDocumentation for the new subcommand is also added to the `git-refs(1)`\nman page.\n\nMentored-by: Patrick Steinhardt <ps@pks.im>\nMentored-by: shejialuo <shejialuo@gmail.com>\nSigned-off-by: Meet Soni <meetsoni3017@gmail.com>\n---\n Documentation/git-refs.adoc |  7 ++++++\n builtin/refs.c              | 48 +++++++++++++++++++++++++++++++++++++\n 2 files changed, 55 insertions(+)\n\ndiff --git a/Documentation/git-refs.adoc b/Documentation/git-refs.adoc\nindex e608980711..5d2032b318 100644\n--- a/Documentation/git-refs.adoc\n+++ b/Documentation/git-refs.adoc\n@@ -18,6 +18,7 @@ git refs list [--count=<count>] [--shell|--perl|--python|--tcl]\n \t\t   [--contains[=<object>]] [--no-contains[=<object>]]\n \t\t   [(--exclude=<pattern>)...] [--start-after=<marker>]\n \t\t   [ --stdin | <pattern>... ]\n+git refs exists <ref>\n \n DESCRIPTION\n -----------\n@@ -38,6 +39,12 @@ list::\n \tformatting, and sorting. This subcommand is an alias for\n \tlinkgit:git-for-each-ref[1] and offers identical functionality.\n \n+exists::\n+\tCheck whether the given reference exists. Returns an exit code of 0 if\n+\tit does, 2 if it is missing, and 1 in case looking up the reference\n+\tfailed with an error other than the reference being missing. This does\n+\tnot verify whether the reference resolves to an actual object.\n+\n OPTIONS\n -------\n \ndiff --git a/builtin/refs.c b/builtin/refs.c\nindex 76224feba4..91548783b7 100644\n--- a/builtin/refs.c\n+++ b/builtin/refs.c\n@@ -7,6 +7,7 @@\n #include \"strbuf.h\"\n #include \"worktree.h\"\n #include \"for-each-ref.h\"\n+#include \"refs/refs-internal.h\"\n \n #define REFS_MIGRATE_USAGE \\\n \tN_(\"git refs migrate --ref-format=<format> [--no-reflog] [--dry-run]\")\n@@ -14,6 +15,9 @@\n #define REFS_VERIFY_USAGE \\\n \tN_(\"git refs verify [--strict] [--verbose]\")\n \n+#define REFS_EXISTS_USAGE \\\n+\tN_(\"git refs exists <ref>\")\n+\n static int cmd_refs_migrate(int argc, const char **argv, const char *prefix,\n \t\t\t    struct repository *repo UNUSED)\n {\n@@ -113,6 +117,48 @@ static int cmd_refs_list(int argc, const char **argv, const char *prefix,\n \treturn for_each_ref_core(argc, argv, prefix, repo, refs_list_usage);\n }\n \n+static int cmd_refs_exists(int argc, const char **argv, const char *prefix,\n+\t\t\t   struct repository *repo UNUSED)\n+{\n+\tstruct strbuf unused_referent = STRBUF_INIT;\n+\tstruct object_id unused_oid;\n+\tunsigned int unused_type;\n+\tint failure_errno = 0;\n+\tconst char *ref;\n+\tint ret = 0;\n+\tconst char * const exists_usage[] = {\n+\t\tREFS_EXISTS_USAGE,\n+\t\tNULL,\n+\t};\n+\tstruct option options[] = {\n+\t\tOPT_END(),\n+\t};\n+\n+\targc = parse_options(argc, argv, prefix, options, exists_usage, 0);\n+\tif (argc != 1)\n+\t\tdie(_(\"'git refs exists' requires a reference\"));\n+\n+\tref = *argv++;\n+\tif (refs_read_raw_ref(get_main_ref_store(the_repository), ref,\n+\t\t\t      &unused_oid, &unused_referent, &unused_type,\n+\t\t\t      &failure_errno)) {\n+\t\tif (failure_errno == ENOENT || failure_errno == EISDIR) {\n+\t\t\terror(_(\"reference does not exist\"));\n+\t\t\tret = 2;\n+\t\t} else {\n+\t\t\terrno = failure_errno;\n+\t\t\terror_errno(_(\"failed to look up reference\"));\n+\t\t\tret = 1;\n+\t\t}\n+\n+\t\tgoto out;\n+\t}\n+\n+out:\n+\tstrbuf_release(&unused_referent);\n+\treturn ret;\n+}\n+\n int cmd_refs(int argc,\n \t     const char **argv,\n \t     const char *prefix,\n@@ -122,6 +168,7 @@ int cmd_refs(int argc,\n \t\tREFS_MIGRATE_USAGE,\n \t\tREFS_VERIFY_USAGE,\n \t\t\"git refs list \" COMMON_USAGE_FOR_EACH_REF,\n+\t\tREFS_EXISTS_USAGE,\n \t\tNULL,\n \t};\n \tparse_opt_subcommand_fn *fn = NULL;\n@@ -129,6 +176,7 @@ int cmd_refs(int argc,\n \t\tOPT_SUBCOMMAND(\"migrate\", &fn, cmd_refs_migrate),\n \t\tOPT_SUBCOMMAND(\"verify\", &fn, cmd_refs_verify),\n \t\tOPT_SUBCOMMAND(\"list\", &fn, cmd_refs_list),\n+\t\tOPT_SUBCOMMAND(\"exists\", &fn, cmd_refs_exists),\n \t\tOPT_END(),\n \t};\n \n-- \n2.34.1\n\n"},{"id":"524924","messageId":"20250826064110.10540-3-meetsoni3017@gmail.com","threadId":"64005","inReplyTo":"20250826064110.10540-1-meetsoni3017@gmail.com","subject":"[GSoC][PATCH v3 2/4] t1403: split 'show-ref --exists' tests into a separate file","fromName":"Meet Soni","fromEmail":"meetsoni3017@gmail.com","sentAt":"2025-08-26T06:41:08Z","receivedAt":"2025-08-26T06:41:22Z","isPatch":true,"sender":{"key":"meetsoni3017@gmail.com","avatar":"https://avatars.githubusercontent.com/u/92802561?v=4"},"body":"The test file for git-show-ref(1), `t1403-show-ref.sh`, contains a group\nof tests for the '--exists' flag. To improve organization and to prepare\nfor refactoring these tests to be shareable, move the '--exists' tests\nand their corresponding setup logic into a self-contained test suite,\n`t1422-show-ref-exists.sh`.\n\nThis is a pure code-movement refactoring with no change in test coverage\nor behavior.\n\nMentored-by: Patrick Steinhardt <ps@pks.im>\nMentored-by: shejialuo <shejialuo@gmail.com>\nSigned-off-by: Meet Soni <meetsoni3017@gmail.com>\n---\n t/meson.build              |  3 +-\n t/t1403-show-ref.sh        | 65 -----------------------------\n t/t1422-show-ref-exists.sh | 83 ++++++++++++++++++++++++++++++++++++++\n 3 files changed, 85 insertions(+), 66 deletions(-)\n create mode 100644 t/t1422-show-ref-exists.sh\n\ndiff --git a/t/meson.build b/t/meson.build\nindex daf01fb5d0..4d6bc3d38e 100644\n--- a/t/meson.build\n+++ b/t/meson.build\n@@ -205,6 +205,7 @@ integration_tests = [\n   't1419-exclude-refs.sh',\n   't1420-lost-found.sh',\n   't1421-reflog-write.sh',\n+  't1422-show-ref-exists.sh',\n   't1430-bad-ref-name.sh',\n   't1450-fsck.sh',\n   't1451-fsck-buffer.sh',\n@@ -1216,4 +1217,4 @@ if perl.found() and time.found()\n       timeout: 0,\n     )\n   endforeach\n-endif\n\\ No newline at end of file\n+endif\ndiff --git a/t/t1403-show-ref.sh b/t/t1403-show-ref.sh\nindex 9da3650e91..36c903ca19 100755\n--- a/t/t1403-show-ref.sh\n+++ b/t/t1403-show-ref.sh\n@@ -228,69 +228,4 @@ test_expect_success 'show-ref sub-modes are mutually exclusive' '\n \tgrep \"cannot be used together\" err\n '\n \n-test_expect_success '--exists with existing reference' '\n-\tgit show-ref --exists refs/heads/$GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n-'\n-\n-test_expect_success '--exists with missing reference' '\n-\ttest_expect_code 2 git show-ref --exists refs/heads/does-not-exist\n-'\n-\n-test_expect_success '--exists does not use DWIM' '\n-\ttest_expect_code 2 git show-ref --exists $GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME 2>err &&\n-\tgrep \"reference does not exist\" err\n-'\n-\n-test_expect_success '--exists with HEAD' '\n-\tgit show-ref --exists HEAD\n-'\n-\n-test_expect_success '--exists with bad reference name' '\n-\ttest_when_finished \"git update-ref -d refs/heads/bad...name\" &&\n-\tnew_oid=$(git rev-parse HEAD) &&\n-\ttest-tool ref-store main update-ref msg refs/heads/bad...name $new_oid $ZERO_OID REF_SKIP_REFNAME_VERIFICATION &&\n-\tgit show-ref --exists refs/heads/bad...name\n-'\n-\n-test_expect_success '--exists with arbitrary symref' '\n-\ttest_when_finished \"git symbolic-ref -d refs/symref\" &&\n-\tgit symbolic-ref refs/symref refs/heads/$GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME &&\n-\tgit show-ref --exists refs/symref\n-'\n-\n-test_expect_success '--exists with dangling symref' '\n-\ttest_when_finished \"git symbolic-ref -d refs/heads/dangling\" &&\n-\tgit symbolic-ref refs/heads/dangling refs/heads/does-not-exist &&\n-\tgit show-ref --exists refs/heads/dangling\n-'\n-\n-test_expect_success '--exists with nonexistent object ID' '\n-\ttest-tool ref-store main update-ref msg refs/heads/missing-oid $(test_oid 001) $ZERO_OID REF_SKIP_OID_VERIFICATION &&\n-\tgit show-ref --exists refs/heads/missing-oid\n-'\n-\n-test_expect_success '--exists with non-commit object' '\n-\ttree_oid=$(git rev-parse HEAD^{tree}) &&\n-\ttest-tool ref-store main update-ref msg refs/heads/tree ${tree_oid} $ZERO_OID REF_SKIP_OID_VERIFICATION &&\n-\tgit show-ref --exists refs/heads/tree\n-'\n-\n-test_expect_success '--exists with directory fails with generic error' '\n-\tcat >expect <<-EOF &&\n-\terror: reference does not exist\n-\tEOF\n-\ttest_expect_code 2 git show-ref --exists refs/heads 2>err &&\n-\ttest_cmp expect err\n-'\n-\n-test_expect_success '--exists with non-existent special ref' '\n-\ttest_expect_code 2 git show-ref --exists FETCH_HEAD\n-'\n-\n-test_expect_success '--exists with existing special ref' '\n-\ttest_when_finished \"rm .git/FETCH_HEAD\" &&\n-\tgit rev-parse HEAD >.git/FETCH_HEAD &&\n-\tgit show-ref --exists FETCH_HEAD\n-'\n-\n test_done\ndiff --git a/t/t1422-show-ref-exists.sh b/t/t1422-show-ref-exists.sh\nnew file mode 100644\nindex 0000000000..0eccb2dce1\n--- /dev/null\n+++ b/t/t1422-show-ref-exists.sh\n@@ -0,0 +1,83 @@\n+#!/bin/sh\n+\n+test_description='show-ref --exists'\n+GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n+export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n+\n+. ./test-lib.sh\n+\n+test_expect_success setup '\n+\ttest_commit --annotate A &&\n+\tgit checkout -b side &&\n+\ttest_commit --annotate B &&\n+\tgit checkout main &&\n+\ttest_commit C &&\n+\tgit branch B A^0\n+'\n+\n+test_expect_success '--exists with existing reference' '\n+\tgit show-ref --exists refs/heads/$GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n+'\n+\n+test_expect_success '--exists with missing reference' '\n+\ttest_expect_code 2 git show-ref --exists refs/heads/does-not-exist\n+'\n+\n+test_expect_success '--exists does not use DWIM' '\n+\ttest_expect_code 2 git show-ref --exists $GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME 2>err &&\n+\tgrep \"reference does not exist\" err\n+'\n+\n+test_expect_success '--exists with HEAD' '\n+\tgit show-ref --exists HEAD\n+'\n+\n+test_expect_success '--exists with bad reference name' '\n+\ttest_when_finished \"git update-ref -d refs/heads/bad...name\" &&\n+\tnew_oid=$(git rev-parse HEAD) &&\n+\ttest-tool ref-store main update-ref msg refs/heads/bad...name $new_oid $ZERO_OID REF_SKIP_REFNAME_VERIFICATION &&\n+\tgit show-ref --exists refs/heads/bad...name\n+'\n+\n+test_expect_success '--exists with arbitrary symref' '\n+\ttest_when_finished \"git symbolic-ref -d refs/symref\" &&\n+\tgit symbolic-ref refs/symref refs/heads/$GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME &&\n+\tgit show-ref --exists refs/symref\n+'\n+\n+test_expect_success '--exists with dangling symref' '\n+\ttest_when_finished \"git symbolic-ref -d refs/heads/dangling\" &&\n+\tgit symbolic-ref refs/heads/dangling refs/heads/does-not-exist &&\n+\tgit show-ref --exists refs/heads/dangling\n+'\n+\n+test_expect_success '--exists with nonexistent object ID' '\n+\ttest-tool ref-store main update-ref msg refs/heads/missing-oid $(test_oid 001) $ZERO_OID REF_SKIP_OID_VERIFICATION &&\n+\tgit show-ref --exists refs/heads/missing-oid\n+'\n+\n+test_expect_success '--exists with non-commit object' '\n+\ttree_oid=$(git rev-parse HEAD^{tree}) &&\n+\ttest-tool ref-store main update-ref msg refs/heads/tree ${tree_oid} $ZERO_OID REF_SKIP_OID_VERIFICATION &&\n+\tgit show-ref --exists refs/heads/tree\n+'\n+\n+test_expect_success '--exists with directory fails with generic error' '\n+\tcat >expect <<-EOF &&\n+\terror: reference does not exist\n+\tEOF\n+\ttest_expect_code 2 git show-ref --exists refs/heads 2>err &&\n+\ttest_cmp expect err\n+'\n+\n+test_expect_success '--exists with non-existent special ref' '\n+\ttest_expect_code 2 git show-ref --exists FETCH_HEAD\n+'\n+\n+test_expect_success '--exists with existing special ref' '\n+\ttest_when_finished \"rm .git/FETCH_HEAD\" &&\n+\tgit rev-parse HEAD >.git/FETCH_HEAD &&\n+\tgit show-ref --exists FETCH_HEAD\n+'\n+\n+test_done\n-- \n2.34.1\n\n"},{"id":"524923","messageId":"20250826064110.10540-4-meetsoni3017@gmail.com","threadId":"64005","inReplyTo":"20250826064110.10540-1-meetsoni3017@gmail.com","subject":"[GSoC][PATCH v3 3/4] t1422: refactor tests to be shareable","fromName":"Meet Soni","fromEmail":"meetsoni3017@gmail.com","sentAt":"2025-08-26T06:41:09Z","receivedAt":"2025-08-26T06:41:24Z","isPatch":true,"sender":{"key":"meetsoni3017@gmail.com","avatar":"https://avatars.githubusercontent.com/u/92802561?v=4"},"body":"In preparation for adding tests for the `git refs exists` command,\nrefactor the existing t1422 test suite to make its logic shareable.\n\nMove the core test logic from `t1422-show-ref-exists.sh` to\n`show-ref-exists-tests.sh` file. Inside this script, replace hardcoded\ncalls to \"git show-ref --exists\" with the `$git_show_ref_exists`\nvariable.\n\nThe original `t1422-show-ref-exists.sh` script now becomes a simple\n\"driver\". It is responsible for setting the default value of the\nvariable and then sourcing the test library.\n\nThis structure follows an established pattern for sharing tests and\nprepares the test suite for the `refs exists` tests to be added in a\nsubsequent commit.\n\nMentored-by: Patrick Steinhardt <ps@pks.im>\nMentored-by: shejialuo <shejialuo@gmail.com>\nSigned-off-by: Meet Soni <meetsoni3017@gmail.com>\n---\n t/show-ref-exists-tests.sh | 77 ++++++++++++++++++++++++++++++++++++++\n t/t1422-show-ref-exists.sh | 76 +------------------------------------\n 2 files changed, 78 insertions(+), 75 deletions(-)\n create mode 100644 t/show-ref-exists-tests.sh\n mode change 100644 => 100755 t/t1422-show-ref-exists.sh\n\ndiff --git a/t/show-ref-exists-tests.sh b/t/show-ref-exists-tests.sh\nnew file mode 100644\nindex 0000000000..36e8e9df33\n--- /dev/null\n+++ b/t/show-ref-exists-tests.sh\n@@ -0,0 +1,77 @@\n+git_show_ref_exists=${git_show_ref_exists:-git show-ref --exists}\n+\n+test_expect_success setup '\n+\ttest_commit --annotate A &&\n+\tgit checkout -b side &&\n+\ttest_commit --annotate B &&\n+\tgit checkout main &&\n+\ttest_commit C &&\n+\tgit branch B A^0\n+'\n+\n+test_expect_success '--exists with existing reference' '\n+\t${git_show_ref_exists} refs/heads/$GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n+'\n+\n+test_expect_success '--exists with missing reference' '\n+\ttest_expect_code 2 ${git_show_ref_exists} refs/heads/does-not-exist\n+'\n+\n+test_expect_success '--exists does not use DWIM' '\n+\ttest_expect_code 2 ${git_show_ref_exists} $GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME 2>err &&\n+\tgrep \"reference does not exist\" err\n+'\n+\n+test_expect_success '--exists with HEAD' '\n+\t${git_show_ref_exists} HEAD\n+'\n+\n+test_expect_success '--exists with bad reference name' '\n+\ttest_when_finished \"git update-ref -d refs/heads/bad...name\" &&\n+\tnew_oid=$(git rev-parse HEAD) &&\n+\ttest-tool ref-store main update-ref msg refs/heads/bad...name $new_oid $ZERO_OID REF_SKIP_REFNAME_VERIFICATION &&\n+\t${git_show_ref_exists} refs/heads/bad...name\n+'\n+\n+test_expect_success '--exists with arbitrary symref' '\n+\ttest_when_finished \"git symbolic-ref -d refs/symref\" &&\n+\tgit symbolic-ref refs/symref refs/heads/$GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME &&\n+\t${git_show_ref_exists} refs/symref\n+'\n+\n+test_expect_success '--exists with dangling symref' '\n+\ttest_when_finished \"git symbolic-ref -d refs/heads/dangling\" &&\n+\tgit symbolic-ref refs/heads/dangling refs/heads/does-not-exist &&\n+\t${git_show_ref_exists} refs/heads/dangling\n+'\n+\n+test_expect_success '--exists with nonexistent object ID' '\n+\ttest-tool ref-store main update-ref msg refs/heads/missing-oid $(test_oid 001) $ZERO_OID REF_SKIP_OID_VERIFICATION &&\n+\t${git_show_ref_exists} refs/heads/missing-oid\n+'\n+\n+test_expect_success '--exists with non-commit object' '\n+\ttree_oid=$(git rev-parse HEAD^{tree}) &&\n+\ttest-tool ref-store main update-ref msg refs/heads/tree ${tree_oid} $ZERO_OID REF_SKIP_OID_VERIFICATION &&\n+\t${git_show_ref_exists} refs/heads/tree\n+'\n+\n+test_expect_success '--exists with directory fails with generic error' '\n+\tcat >expect <<-EOF &&\n+\terror: reference does not exist\n+\tEOF\n+\ttest_expect_code 2 ${git_show_ref_exists} refs/heads 2>err &&\n+\ttest_cmp expect err\n+'\n+\n+test_expect_success '--exists with non-existent special ref' '\n+\ttest_expect_code 2 ${git_show_ref_exists} FETCH_HEAD\n+'\n+\n+test_expect_success '--exists with existing special ref' '\n+\ttest_when_finished \"rm .git/FETCH_HEAD\" &&\n+\tgit rev-parse HEAD >.git/FETCH_HEAD &&\n+\t${git_show_ref_exists} FETCH_HEAD\n+'\n+\n+test_done\ndiff --git a/t/t1422-show-ref-exists.sh b/t/t1422-show-ref-exists.sh\nold mode 100644\nnew mode 100755\nindex 0eccb2dce1..fdca3f16c8\n--- a/t/t1422-show-ref-exists.sh\n+++ b/t/t1422-show-ref-exists.sh\n@@ -6,78 +6,4 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n \n . ./test-lib.sh\n \n-test_expect_success setup '\n-\ttest_commit --annotate A &&\n-\tgit checkout -b side &&\n-\ttest_commit --annotate B &&\n-\tgit checkout main &&\n-\ttest_commit C &&\n-\tgit branch B A^0\n-'\n-\n-test_expect_success '--exists with existing reference' '\n-\tgit show-ref --exists refs/heads/$GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n-'\n-\n-test_expect_success '--exists with missing reference' '\n-\ttest_expect_code 2 git show-ref --exists refs/heads/does-not-exist\n-'\n-\n-test_expect_success '--exists does not use DWIM' '\n-\ttest_expect_code 2 git show-ref --exists $GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME 2>err &&\n-\tgrep \"reference does not exist\" err\n-'\n-\n-test_expect_success '--exists with HEAD' '\n-\tgit show-ref --exists HEAD\n-'\n-\n-test_expect_success '--exists with bad reference name' '\n-\ttest_when_finished \"git update-ref -d refs/heads/bad...name\" &&\n-\tnew_oid=$(git rev-parse HEAD) &&\n-\ttest-tool ref-store main update-ref msg refs/heads/bad...name $new_oid $ZERO_OID REF_SKIP_REFNAME_VERIFICATION &&\n-\tgit show-ref --exists refs/heads/bad...name\n-'\n-\n-test_expect_success '--exists with arbitrary symref' '\n-\ttest_when_finished \"git symbolic-ref -d refs/symref\" &&\n-\tgit symbolic-ref refs/symref refs/heads/$GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME &&\n-\tgit show-ref --exists refs/symref\n-'\n-\n-test_expect_success '--exists with dangling symref' '\n-\ttest_when_finished \"git symbolic-ref -d refs/heads/dangling\" &&\n-\tgit symbolic-ref refs/heads/dangling refs/heads/does-not-exist &&\n-\tgit show-ref --exists refs/heads/dangling\n-'\n-\n-test_expect_success '--exists with nonexistent object ID' '\n-\ttest-tool ref-store main update-ref msg refs/heads/missing-oid $(test_oid 001) $ZERO_OID REF_SKIP_OID_VERIFICATION &&\n-\tgit show-ref --exists refs/heads/missing-oid\n-'\n-\n-test_expect_success '--exists with non-commit object' '\n-\ttree_oid=$(git rev-parse HEAD^{tree}) &&\n-\ttest-tool ref-store main update-ref msg refs/heads/tree ${tree_oid} $ZERO_OID REF_SKIP_OID_VERIFICATION &&\n-\tgit show-ref --exists refs/heads/tree\n-'\n-\n-test_expect_success '--exists with directory fails with generic error' '\n-\tcat >expect <<-EOF &&\n-\terror: reference does not exist\n-\tEOF\n-\ttest_expect_code 2 git show-ref --exists refs/heads 2>err &&\n-\ttest_cmp expect err\n-'\n-\n-test_expect_success '--exists with non-existent special ref' '\n-\ttest_expect_code 2 git show-ref --exists FETCH_HEAD\n-'\n-\n-test_expect_success '--exists with existing special ref' '\n-\ttest_when_finished \"rm .git/FETCH_HEAD\" &&\n-\tgit rev-parse HEAD >.git/FETCH_HEAD &&\n-\tgit show-ref --exists FETCH_HEAD\n-'\n-\n-test_done\n+. \"$TEST_DIRECTORY\"/show-ref-exists-tests.sh\n-- \n2.34.1\n\n"},{"id":"524925","messageId":"20250826064110.10540-5-meetsoni3017@gmail.com","threadId":"64005","inReplyTo":"20250826064110.10540-1-meetsoni3017@gmail.com","subject":"[GSoC][PATCH v3 4/4] t: add test for git refs exists subcommand","fromName":"Meet Soni","fromEmail":"meetsoni3017@gmail.com","sentAt":"2025-08-26T06:41:10Z","receivedAt":"2025-08-26T06:41:27Z","isPatch":true,"sender":{"key":"meetsoni3017@gmail.com","avatar":"https://avatars.githubusercontent.com/u/92802561?v=4"},"body":"Add a test script, `t/t1462-refs-exists.sh`, for the `git refs exists`\ncommand.\n\nThis script acts as a simple driver, leveraging the shared test library\ncreated in the preceding commit. It works by overriding the\n`$git_show_ref_exists` variable to \"git refs exists\" and then sourcing the\nshared library (`t/show-ref-exists-tests.sh`).\n\nThis approach ensures that `git refs exists` is tested against the\nentire comprehensive test suite of `git show-ref --exists`, verifying\nthat it acts as a compatible drop-in replacement.\n\nMentored-by: Patrick Steinhardt <ps@pks.im>\nMentored-by: shejialuo <shejialuo@gmail.com>\nSigned-off-by: Meet Soni <meetsoni3017@gmail.com>\n---\n t/meson.build          |  1 +\n t/t1462-refs-exists.sh | 10 ++++++++++\n 2 files changed, 11 insertions(+)\n create mode 100755 t/t1462-refs-exists.sh\n\ndiff --git a/t/meson.build b/t/meson.build\nindex 4d6bc3d38e..93e9773ec8 100644\n--- a/t/meson.build\n+++ b/t/meson.build\n@@ -211,6 +211,7 @@ integration_tests = [\n   't1451-fsck-buffer.sh',\n   't1460-refs-migrate.sh',\n   't1461-refs-list.sh',\n+  't1462-refs-exists.sh',\n   't1500-rev-parse.sh',\n   't1501-work-tree.sh',\n   't1502-rev-parse-parseopt.sh',\ndiff --git a/t/t1462-refs-exists.sh b/t/t1462-refs-exists.sh\nnew file mode 100755\nindex 0000000000..349453c4ca\n--- /dev/null\n+++ b/t/t1462-refs-exists.sh\n@@ -0,0 +1,10 @@\n+#!/bin/sh\n+\n+test_description='refs exists'\n+GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main\n+export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\n+\n+. ./test-lib.sh\n+\n+git_show_ref_exists='git refs exists'\n+. \"$TEST_DIRECTORY\"/show-ref-exists-tests.sh\n-- \n2.34.1\n\n"},{"id":"525336","messageId":"aLbahNFrs9jchnXZ@pks.im","threadId":"64005","inReplyTo":"20250826064110.10540-1-meetsoni3017@gmail.com","subject":"Re: [GSoC][PATCH v3 0/4] Add refs exists subcommand","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2025-09-02T11:52:36Z","receivedAt":"2025-09-02T11:52:43Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Tue, Aug 26, 2025 at 12:11:06PM +0530, Meet Soni wrote:\n> This series introduces `git refs exists` as a modern replacement for\n> `git show-ref --exists`, continuing the effort to consolidate commands\n> under the `git refs` namespace.\n> \n> changes in v3:\n>  - Reverted commit message.\n>  - nit: added empty line.\n\nThanks, this version looks good to me.\n\nPatrick\n"},{"id":"525355","messageId":"xmqqtt1kkd0y.fsf@gitster.g","threadId":"64005","inReplyTo":"20250826064110.10540-1-meetsoni3017@gmail.com","subject":"Re: [GSoC][PATCH v3 0/4] Add refs exists subcommand","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-09-02T16:57:49Z","receivedAt":"2025-09-02T16:57:51Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Meet Soni <meetsoni3017@gmail.com> writes:\n\n> This series introduces `git refs exists` as a modern replacement for\n> `git show-ref --exists`, continuing the effort to consolidate commands\n> under the `git refs` namespace.\n>\n> changes in v3:\n>  - Reverted commit message.\n>  - nit: added empty line.\n>\n> Meet Soni (4):\n>   builtin/refs: add 'exists' subcommand\n>   t1403: split 'show-ref --exists' tests into a separate file\n>   t1422: refactor tests to be shareable\n>   t: add test for git refs exists subcommand\n>\n>  Documentation/git-refs.adoc |  7 ++++\n>  builtin/refs.c              | 48 +++++++++++++++++++++++\n>  t/meson.build               |  4 +-\n>  t/show-ref-exists-tests.sh  | 77 +++++++++++++++++++++++++++++++++++++\n>  t/t1403-show-ref.sh         | 65 -------------------------------\n>  t/t1422-show-ref-exists.sh  |  9 +++++\n>  t/t1462-refs-exists.sh      | 10 +++++\n>  7 files changed, 154 insertions(+), 66 deletions(-)\n>  create mode 100644 t/show-ref-exists-tests.sh\n>  create mode 100755 t/t1422-show-ref-exists.sh\n>  create mode 100755 t/t1462-refs-exists.sh\n>\n> Range-diff against v2:\n>  1:  19623eb97e <  -:  ---------- doc: factor out common option\n>  2:  69c207dc45 <  -:  ---------- builtin/for-each-ref: align usage string with the man page\n>  3:  6eeb1c070a <  -:  ---------- builtin/for-each-ref: factor out core logic into a helper\n>  4:  eecccfe98b <  -:  ---------- builtin/refs: add list subcommand\n>  5:  aa91c5c570 <  -:  ---------- t6300: refactor tests to be shareable\n>  6:  fed66d91c0 <  -:  ---------- t: add test for git refs list subcommand\n>  7:  b55e6d36eb <  -:  ---------- diff: ensure consistent diff behavior with ignore options\n>  8:  e1d3d61a45 <  -:  ---------- diff: --no-index should ignore the worktree\n>  9:  621ce9c1c6 <  -:  ---------- git-jump: make `diff` work with filenames containing spaces\n> 10:  9a49aef8dc <  -:  ---------- environment: remove the global variable 'merge_log_config'\n> 11:  22d421fed9 <  -:  ---------- builtin/fmt-merge-msg: stop depending on 'the_repository'\n> 12:  741f36c7d9 <  -:  ---------- docs: remove stray bracket from git-clone synopsis\n> 13:  1fa68948c3 <  -:  ---------- The second batch\n\nGitGitGadget and/or range-diff somehow went berserk?\n\nBut thanks to it, I now know that the series is built on top of the\nsecond batch ;-)  I was wondering why the patches did not apply\ncleanly to a more recent tip of 'master'.\n\nWill queue.  Thanks.\n"}]}