From patchwork Thu Oct 26 09:56:21 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 13437415 Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5859E2B75D for ; Thu, 26 Oct 2023 09:56:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b="b8AkkUeE"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="rjlXycbu" Received: from wout2-smtp.messagingengine.com (wout2-smtp.messagingengine.com [64.147.123.25]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CF8DA1A7 for ; Thu, 26 Oct 2023 02:56:25 -0700 (PDT) Received: from compute1.internal (compute1.nyi.internal [10.202.2.41]) by mailout.west.internal (Postfix) with ESMTP id E5B543200928; Thu, 26 Oct 2023 05:56:24 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute1.internal (MEProxy); Thu, 26 Oct 2023 05:56:25 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pks.im; h=cc:cc :content-type:content-type:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:sender :subject:subject:to:to; s=fm3; t=1698314184; x=1698400584; bh=yL uvweuH0oMfdASyQV703Khqqv4zEuGn5mmt7rB7+Sw=; b=b8AkkUeEmb8q3WRMNE mmDnW3shM2V8W3TW7E/qbZ9qtbmbZ+kgGdjE3q6effgL4p1JHw7DqFsPWJxF0lSD RW96ne2x42+EYF2rKP9XGmh1eTth1jaVZgT03jMmcjqrCura1zD614ohipcuD2gJ NeniwJeK1WkdT7+SUiYwT4TB2YFDgAU21u/rWVoz0HfOQ4gA64V9fW/0WwpEk8WN EqJ3PNY5WKZQqlY7fqOMD6NdFJEbMwje4cmkPIXprzdAYcV67sVZvTvu3F+n740o tKqII9+oJHm+Mw8XZaeoz/fYnz1qvispIUNoCbHjmxYzsCDdXqfZ/4txnZVXfAHP UzeQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:sender:subject :subject:to:to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender :x-sasl-enc; s=fm3; t=1698314184; x=1698400584; bh=yLuvweuH0oMfd ASyQV703Khqqv4zEuGn5mmt7rB7+Sw=; b=rjlXycbuOT1DqGO2MFVK5p46nQ/tw mb7+Q/3BadrYXwW1a5wJIgIPlyHFqYFRtFbI0BlQnkF7nGxMgPP+fCdh96z39Gqv K7WJNHnXH2V3QeiOhXp/UNSU1KDXO78zzcT5Kks7GQWteKtZPJtP/8bdPtgKZufv z05UvKH3cOUDr42aIxK2z1yrZIi7yueGKYTqQkMu6KsU0Sw/NVDWB9UIcQKWoHOf ZFklgGHNBMUsZb/9kZy9HGIyUcufL6a6jXRD7xyG4TRwIFpPHoljRqSgH2/gTb9b OVmknJPQxCFfxegOVq+Rz40oWt2aU9WlRkNKB32tlBiTV446oLClzA0sg== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvkedrledvgddvvdcutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc fjughrpeffhffvvefukfhfgggtuggjsehgtderredttddvnecuhfhrohhmpefrrghtrhhi tghkucfuthgvihhnhhgrrhguthcuoehpshesphhkshdrihhmqeenucggtffrrghtthgvrh hnpeeukedtvedtffevleejtefgheehieegkeeluddvfeefgeehgfeltddtheejleffteen ucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpehpshesph hkshdrihhm X-ME-Proxy: Feedback-ID: i197146af:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Thu, 26 Oct 2023 05:56:23 -0400 (EDT) Received: by vm-mail (OpenSMTPD) with ESMTPSA id 084f9a37 (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Thu, 26 Oct 2023 09:56:14 +0000 (UTC) Date: Thu, 26 Oct 2023 11:56:21 +0200 From: Patrick Steinhardt To: git@vger.kernel.org Cc: Junio C Hamano , Eric Sunshine , Han-Wen Nienhuys Subject: [PATCH v2 01/12] builtin/show-ref: convert pattern to a local variable Message-ID: <78163accbd2c39721249474512dedd8ed2f0fe4e.1698314128.git.ps@pks.im> References: Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: The `pattern` variable is a global variable that tracks either the reference names (not patterns!) for the `--verify` mode or the patterns for the non-verify mode. This is a bit confusing due to the slightly different meanings. Convert the variable to be local. While this does not yet fix the double meaning of the variable, this change allows us to address it in a subsequent patch more easily by explicitly splitting up the different subcommands of git-show-ref(1). Note that we introduce a `struct show_ref_data` to pass the patterns to `show_ref()`. While this is overengineered now, we will extend this structure in a subsequent patch. Signed-off-by: Patrick Steinhardt --- builtin/show-ref.c | 46 ++++++++++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/builtin/show-ref.c b/builtin/show-ref.c index 5110814f796..7efab14b96c 100644 --- a/builtin/show-ref.c +++ b/builtin/show-ref.c @@ -20,7 +20,6 @@ static const char * const show_ref_usage[] = { static int deref_tags, show_head, tags_only, heads_only, found_match, verify, quiet, hash_only, abbrev, exclude_arg; -static const char **pattern; static const char *exclude_existing_arg; static void show_one(const char *refname, const struct object_id *oid) @@ -50,15 +49,21 @@ static void show_one(const char *refname, const struct object_id *oid) } } +struct show_ref_data { + const char **patterns; +}; + static int show_ref(const char *refname, const struct object_id *oid, - int flag UNUSED, void *cbdata UNUSED) + int flag UNUSED, void *cbdata) { + struct show_ref_data *data = cbdata; + if (show_head && !strcmp(refname, "HEAD")) goto match; - if (pattern) { + if (data->patterns) { int reflen = strlen(refname); - const char **p = pattern, *m; + const char **p = data->patterns, *m; while ((m = *p++) != NULL) { int len = strlen(m); if (len > reflen) @@ -180,6 +185,9 @@ static const struct option show_ref_options[] = { int cmd_show_ref(int argc, const char **argv, const char *prefix) { + struct show_ref_data show_ref_data = {0}; + const char **patterns; + git_config(git_default_config, NULL); argc = parse_options(argc, argv, prefix, show_ref_options, @@ -188,38 +196,40 @@ int cmd_show_ref(int argc, const char **argv, const char *prefix) if (exclude_arg) return exclude_existing(exclude_existing_arg); - pattern = argv; - if (!*pattern) - pattern = NULL; + patterns = argv; + if (!*patterns) + patterns = NULL; if (verify) { - if (!pattern) + if (!patterns) die("--verify requires a reference"); - while (*pattern) { + while (*patterns) { struct object_id oid; - if ((starts_with(*pattern, "refs/") || !strcmp(*pattern, "HEAD")) && - !read_ref(*pattern, &oid)) { - show_one(*pattern, &oid); + if ((starts_with(*patterns, "refs/") || !strcmp(*patterns, "HEAD")) && + !read_ref(*patterns, &oid)) { + show_one(*patterns, &oid); } else if (!quiet) - die("'%s' - not a valid ref", *pattern); + die("'%s' - not a valid ref", *patterns); else return 1; - pattern++; + patterns++; } return 0; } + show_ref_data.patterns = patterns; + if (show_head) - head_ref(show_ref, NULL); + head_ref(show_ref, &show_ref_data); if (heads_only || tags_only) { if (heads_only) - for_each_fullref_in("refs/heads/", show_ref, NULL); + for_each_fullref_in("refs/heads/", show_ref, &show_ref_data); if (tags_only) - for_each_fullref_in("refs/tags/", show_ref, NULL); + for_each_fullref_in("refs/tags/", show_ref, &show_ref_data); } else { - for_each_ref(show_ref, NULL); + for_each_ref(show_ref, &show_ref_data); } if (!found_match) { if (verify && !quiet) From patchwork Thu Oct 26 09:56:25 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 13437416 Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C2348AD29 for ; Thu, 26 Oct 2023 09:56:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b="zST6exJK"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="OKc63zdm" Received: from wout2-smtp.messagingengine.com (wout2-smtp.messagingengine.com [64.147.123.25]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0CF3B1A5 for ; Thu, 26 Oct 2023 02:56:29 -0700 (PDT) Received: from compute5.internal (compute5.nyi.internal [10.202.2.45]) by mailout.west.internal (Postfix) with ESMTP id 284B43200928; Thu, 26 Oct 2023 05:56:28 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute5.internal (MEProxy); Thu, 26 Oct 2023 05:56:28 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pks.im; h=cc:cc :content-type:content-type:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:sender :subject:subject:to:to; s=fm3; t=1698314187; x=1698400587; bh=w8 bmCXcQ6tCeqrFz8/9w8fksdWwooBhWSZLNWX3QQcY=; b=zST6exJKglJ1Mlf9vC p7qdA5sLXa0me10vdR5Ziglv/Wd7ICpa2lqhlebbDdyGjIUCLLhRR4p5Nwoq1DQP 70f2drd5XXIms3ghnP66Dfv6qqZXRGT+g+1XO4o+k6qnRRcvnpEPUm9jVmaWuw1D HGL6Gtt237yp4DCubEzhAdzGIrQ2O3WtNYuoEOpB4eVYUZw5QVYZ9tT0y9qLAvvF rgyirOq2ni2zg8kpOuuzxbGcTR/HP4eb7Y1dkxwntp4+hceucUIjVA6c7KgJw7tU VOr54cb/veJ72YVmJ/lVrfHpe1UPwW6EmYVQQqoMZc/gnuLTxTbJBAYr2urshZlx qciw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:sender:subject :subject:to:to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender :x-sasl-enc; s=fm3; t=1698314187; x=1698400587; bh=w8bmCXcQ6tCeq rFz8/9w8fksdWwooBhWSZLNWX3QQcY=; b=OKc63zdmy0Ww0S4n12lQOkFoSQ6XP giAwoj29DN0P2hoaT5QRdVKymD6G3ZV8Dmri1UlkshiRhJY4w5yumTe6SuGLz0To d1vZodUjRUGEGWLwS0cZ5YuDfzwBc3XQLrtHGwll3FVIYNW9DR8UIpRncfxwns4Q JqJd2MloIZKVVvD41laAqrI6CygiVnJUOas8sJMrsYA3llhqHJMtFOhILRLN/xb4 Bhpp/0eQJgPm4W5WbyK7f86nwRt9oE0aQwzFvJ8J3OJYEuK/H3yNT1GaXR8ed7Pf 9lLnvKXvDhgUu73FO+DKsbFNlPR2vWSXjWwL9DpLwmlN1bdl0Ydb/3b1A== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvkedrledvgddvudcutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc fjughrpeffhffvvefukfhfgggtuggjsehgtderredttddvnecuhfhrohhmpefrrghtrhhi tghkucfuthgvihhnhhgrrhguthcuoehpshesphhkshdrihhmqeenucggtffrrghtthgvrh hnpeeukedtvedtffevleejtefgheehieegkeeluddvfeefgeehgfeltddtheejleffteen ucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpehpshesph hkshdrihhm X-ME-Proxy: Feedback-ID: i197146af:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Thu, 26 Oct 2023 05:56:26 -0400 (EDT) Received: by vm-mail (OpenSMTPD) with ESMTPSA id 33aea980 (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Thu, 26 Oct 2023 09:56:18 +0000 (UTC) Date: Thu, 26 Oct 2023 11:56:25 +0200 From: Patrick Steinhardt To: git@vger.kernel.org Cc: Junio C Hamano , Eric Sunshine , Han-Wen Nienhuys Subject: [PATCH v2 02/12] builtin/show-ref: split up different subcommands Message-ID: <9a234622d991186bf7a618bffbf15a936aba34c4.1698314128.git.ps@pks.im> References: Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: While not immediately obvious, git-show-ref(1) actually implements three different subcommands: - `git show-ref ` can be used to list references that match a specific pattern. - `git show-ref --verify ` can be used to list references. These are _not_ patterns. - `git show-ref --exclude-existing` can be used as a filter that reads references from standard input, performing some conversions on each of them. Let's make this more explicit in the code by splitting up the three subcommands into separate functions. This also allows us to address the confusingly named `patterns` variable, which may hold either patterns or reference names. Signed-off-by: Patrick Steinhardt --- builtin/show-ref.c | 101 ++++++++++++++++++++++++--------------------- 1 file changed, 54 insertions(+), 47 deletions(-) diff --git a/builtin/show-ref.c b/builtin/show-ref.c index 7efab14b96c..cad5b8b5066 100644 --- a/builtin/show-ref.c +++ b/builtin/show-ref.c @@ -104,7 +104,7 @@ static int add_existing(const char *refname, * (4) ignore if refname is a ref that exists in the local repository; * (5) otherwise output the line. */ -static int exclude_existing(const char *match) +static int cmd_show_ref__exclude_existing(const char *match) { static struct string_list existing_refs = STRING_LIST_INIT_DUP; char buf[1024]; @@ -142,6 +142,54 @@ static int exclude_existing(const char *match) return 0; } +static int cmd_show_ref__verify(const char **refs) +{ + if (!refs || !*refs) + die("--verify requires a reference"); + + while (*refs) { + struct object_id oid; + + if ((starts_with(*refs, "refs/") || !strcmp(*refs, "HEAD")) && + !read_ref(*refs, &oid)) { + show_one(*refs, &oid); + } + else if (!quiet) + die("'%s' - not a valid ref", *refs); + else + return 1; + refs++; + } + + return 0; +} + +static int cmd_show_ref__patterns(const char **patterns) +{ + struct show_ref_data show_ref_data = {0}; + + if (patterns && *patterns) + show_ref_data.patterns = patterns; + + if (show_head) + head_ref(show_ref, &show_ref_data); + if (heads_only || tags_only) { + if (heads_only) + for_each_fullref_in("refs/heads/", show_ref, &show_ref_data); + if (tags_only) + for_each_fullref_in("refs/tags/", show_ref, &show_ref_data); + } else { + for_each_ref(show_ref, &show_ref_data); + } + if (!found_match) { + if (verify && !quiet) + die("No match"); + return 1; + } + + return 0; +} + static int hash_callback(const struct option *opt, const char *arg, int unset) { hash_only = 1; @@ -185,56 +233,15 @@ static const struct option show_ref_options[] = { int cmd_show_ref(int argc, const char **argv, const char *prefix) { - struct show_ref_data show_ref_data = {0}; - const char **patterns; - git_config(git_default_config, NULL); argc = parse_options(argc, argv, prefix, show_ref_options, show_ref_usage, 0); if (exclude_arg) - return exclude_existing(exclude_existing_arg); - - patterns = argv; - if (!*patterns) - patterns = NULL; - - if (verify) { - if (!patterns) - die("--verify requires a reference"); - while (*patterns) { - struct object_id oid; - - if ((starts_with(*patterns, "refs/") || !strcmp(*patterns, "HEAD")) && - !read_ref(*patterns, &oid)) { - show_one(*patterns, &oid); - } - else if (!quiet) - die("'%s' - not a valid ref", *patterns); - else - return 1; - patterns++; - } - return 0; - } - - show_ref_data.patterns = patterns; - - if (show_head) - head_ref(show_ref, &show_ref_data); - if (heads_only || tags_only) { - if (heads_only) - for_each_fullref_in("refs/heads/", show_ref, &show_ref_data); - if (tags_only) - for_each_fullref_in("refs/tags/", show_ref, &show_ref_data); - } else { - for_each_ref(show_ref, &show_ref_data); - } - if (!found_match) { - if (verify && !quiet) - die("No match"); - return 1; - } - return 0; + return cmd_show_ref__exclude_existing(exclude_existing_arg); + else if (verify) + return cmd_show_ref__verify(argv); + else + return cmd_show_ref__patterns(argv); } From patchwork Thu Oct 26 09:56:29 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 13437417 Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7542EAD29 for ; Thu, 26 Oct 2023 09:56:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b="dpAFb1tw"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="PgyVacrb" Received: from wout2-smtp.messagingengine.com (wout2-smtp.messagingengine.com [64.147.123.25]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3C5D3193 for ; Thu, 26 Oct 2023 02:56:33 -0700 (PDT) Received: from compute6.internal (compute6.nyi.internal [10.202.2.47]) by mailout.west.internal (Postfix) with ESMTP id 6186F32007CF; Thu, 26 Oct 2023 05:56:32 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute6.internal (MEProxy); Thu, 26 Oct 2023 05:56:32 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pks.im; h=cc:cc :content-type:content-type:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:sender :subject:subject:to:to; s=fm3; t=1698314191; x=1698400591; bh=gg nnzXfRmgrGhL78fj84VpDLFaxq6+ybxpC5rh2Q9Qo=; b=dpAFb1twtz/qwMz5i4 gMjNenbipLoozZAhvfMffN1Yp1ASd5L6TRSN240+KJqcpJ/r9uHoDuNoY9OiPvqr F+QRbFRx1kc+JSJQyjYM+G/F4Hqv5v7GiLD+Ad5ZV25ro1n8i5rqXbUKoFDeYcNC pbVxnNyzzGyKZdasdYZyrAalWRa7qeRjm5BiEp3bJ2liWPYI5Ir6S8tEJ8/lXEVW 4b4wgPRxZhMGIoAbCWcolbweN/jVriY5DX5cZ5+35jUSZdlcl+4b+3z7ZM0VZ6h3 1FpYax2/DK/fHziAe+GPmdNPCJ8Zoin+2Xv4amSTEhECN0Q7vd7KCzTuTThA1aKW aatw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:sender:subject :subject:to:to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender :x-sasl-enc; s=fm3; t=1698314191; x=1698400591; bh=ggnnzXfRmgrGh L78fj84VpDLFaxq6+ybxpC5rh2Q9Qo=; b=PgyVacrbhwnvMkRWSVIjrhWQbxwvl v188cMqsHqz7JhPMaAqexxLLo3h1BOMqLYYCXCFqjjWP0e2gERkhCAeP+olCjiNH kIbjyJa3ux3f2FS/O6RYmcxNo4SjaXDH/4t3C6redeMRgqF4ildw+Um8fj6XWV1B hc43Oru8VXptXTpRoSdpFIS16GrWqru2nHTAdj4Em4E+XucdIkQB5k3UMbZqWoY1 dpkvZS13ugenBfKrQMxQQzZI2HyB9QNAP8GAEfjZ7AeRZ71he+4yRnpsGOigdGD6 amI+/wjsNNolnlVhHicGUS63irQVVDmCYlZD9rxKxoE7Fx/opXGNbmNzg== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvkedrledvgddvudcutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc fjughrpeffhffvvefukfhfgggtuggjsehgtderredttddvnecuhfhrohhmpefrrghtrhhi tghkucfuthgvihhnhhgrrhguthcuoehpshesphhkshdrihhmqeenucggtffrrghtthgvrh hnpeeukedtvedtffevleejtefgheehieegkeeluddvfeefgeehgfeltddtheejleffteen ucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpehpshesph hkshdrihhm X-ME-Proxy: Feedback-ID: i197146af:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Thu, 26 Oct 2023 05:56:30 -0400 (EDT) Received: by vm-mail (OpenSMTPD) with ESMTPSA id 56f3f324 (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Thu, 26 Oct 2023 09:56:22 +0000 (UTC) Date: Thu, 26 Oct 2023 11:56:29 +0200 From: Patrick Steinhardt To: git@vger.kernel.org Cc: Junio C Hamano , Eric Sunshine , Han-Wen Nienhuys Subject: [PATCH v2 03/12] builtin/show-ref: fix leaking string buffer Message-ID: References: Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Fix a leaking string buffer in `git show-ref --exclude-existing`. While the buffer is technically not leaking because its variable is declared as static, there is no inherent reason why it should be. Signed-off-by: Patrick Steinhardt --- builtin/show-ref.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/builtin/show-ref.c b/builtin/show-ref.c index cad5b8b5066..e55c38af478 100644 --- a/builtin/show-ref.c +++ b/builtin/show-ref.c @@ -106,7 +106,7 @@ static int add_existing(const char *refname, */ static int cmd_show_ref__exclude_existing(const char *match) { - static struct string_list existing_refs = STRING_LIST_INIT_DUP; + struct string_list existing_refs = STRING_LIST_INIT_DUP; char buf[1024]; int matchlen = match ? strlen(match) : 0; @@ -139,6 +139,8 @@ static int cmd_show_ref__exclude_existing(const char *match) printf("%s\n", buf); } } + + string_list_clear(&existing_refs, 0); return 0; } From patchwork Thu Oct 26 09:56:33 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 13437418 Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C6D612D02C for ; Thu, 26 Oct 2023 09:56:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b="I/C2gXBC"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="S8XKkgDF" Received: from wout2-smtp.messagingengine.com (wout2-smtp.messagingengine.com [64.147.123.25]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 69D7C1AC for ; Thu, 26 Oct 2023 02:56:37 -0700 (PDT) Received: from compute6.internal (compute6.nyi.internal [10.202.2.47]) by mailout.west.internal (Postfix) with ESMTP id 9A34B32007CF; Thu, 26 Oct 2023 05:56:36 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute6.internal (MEProxy); Thu, 26 Oct 2023 05:56:37 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pks.im; h=cc:cc :content-type:content-type:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:sender :subject:subject:to:to; s=fm3; t=1698314196; x=1698400596; bh=jF 7JYayKS5xis4M1MmJCAK+0N/nnCO07b9MkD8cu1x8=; b=I/C2gXBCDLoen+N1Pq QOZfQ0feHyFTHILV6Pok1bsvusQi9vxRFUXKOJEju6H4dhMVr2iQRKjO98pA2VlN hK3gkR3636xvcfGce3uCWYT0UY7jXyQ7qS90hLKvViXIK9VFHRg7dBDkzvolTuI5 mZXlFTyARHu3dzMzUmRauBJtO5BZfUXJ7sSewjssthdY3gViaW15w+0qRzCOg1kb UYcTi1EWjk9xQyDoUX9YSEh/ypRoYzNElBmxOoejJVPjkUCpblEpgJk3RD/e88jd NzrBsoT9XccHiLLWe0MQxFPiBR4jMgVRSisz1y7pgUZWMOMizaqR/hurMaGrfp1k F7NQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:sender:subject :subject:to:to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender :x-sasl-enc; s=fm3; t=1698314196; x=1698400596; bh=jF7JYayKS5xis 4M1MmJCAK+0N/nnCO07b9MkD8cu1x8=; b=S8XKkgDFl9WSfDY+GiKWaIwG3chIZ lnFW0YU6aYTyvS2v+blC8igNwTwkBDhNDsKnTFPEy0zXfsVkmbwX1xd0I6WyJZzs JJgVFiVQC2ZN2LcZJuUJF+5NXh/DrDQv4oLqrpK5GKj+9VqzToC7Y96rh2GOy2PN O/9289gUJA485q3yWjtRDardMm5qciAGpF2LxOnGPZipEJvLlfGnWponqamHkFd2 Vazn60ASTv7lUcXFdpAOuPYfwr+F+I1/SQTZ4Czi1RYl0MVK8N/AaBG5ts4OEoFy F9y4/fkjbs/hqiYwBkAXZ5h/cebsV6cxR03ndMU1t3H/pk0JtaTTT5Rqg== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvkedrledvgddvudcutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc fjughrpeffhffvvefukfhfgggtuggjsehgtderredttddvnecuhfhrohhmpefrrghtrhhi tghkucfuthgvihhnhhgrrhguthcuoehpshesphhkshdrihhmqeenucggtffrrghtthgvrh hnpeeukedtvedtffevleejtefgheehieegkeeluddvfeefgeehgfeltddtheejleffteen ucevlhhushhtvghrufhiiigvpedunecurfgrrhgrmhepmhgrihhlfhhrohhmpehpshesph hkshdrihhm X-ME-Proxy: Feedback-ID: i197146af:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Thu, 26 Oct 2023 05:56:35 -0400 (EDT) Received: by vm-mail (OpenSMTPD) with ESMTPSA id c520dbbb (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Thu, 26 Oct 2023 09:56:26 +0000 (UTC) Date: Thu, 26 Oct 2023 11:56:33 +0200 From: Patrick Steinhardt To: git@vger.kernel.org Cc: Junio C Hamano , Eric Sunshine , Han-Wen Nienhuys Subject: [PATCH v2 04/12] builtin/show-ref: fix dead code when passing patterns Message-ID: <87afcee830caab2782ce693c1f961df6fea6e7b5.1698314128.git.ps@pks.im> References: Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: When passing patterns to `git show-ref` we have some code that will cause us to die if `verify && !quiet` is true. But because `verify` indicates a different subcommand of git-show-ref(1) that causes us to execute `cmd_show_ref__verify()` and not `cmd_show_ref__patterns()`, the condition cannot ever be true. Let's remove this dead code. Signed-off-by: Patrick Steinhardt --- builtin/show-ref.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/builtin/show-ref.c b/builtin/show-ref.c index e55c38af478..f95418d3d16 100644 --- a/builtin/show-ref.c +++ b/builtin/show-ref.c @@ -183,11 +183,8 @@ static int cmd_show_ref__patterns(const char **patterns) } else { for_each_ref(show_ref, &show_ref_data); } - if (!found_match) { - if (verify && !quiet) - die("No match"); + if (!found_match) return 1; - } return 0; } From patchwork Thu Oct 26 09:56:37 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 13437419 Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 95C412D021 for ; Thu, 26 Oct 2023 09:56:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b="n4dcPhDm"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="O6hX/jdD" Received: from wout2-smtp.messagingengine.com (wout2-smtp.messagingengine.com [64.147.123.25]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B0678195 for ; Thu, 26 Oct 2023 02:56:41 -0700 (PDT) Received: from compute5.internal (compute5.nyi.internal [10.202.2.45]) by mailout.west.internal (Postfix) with ESMTP id C3447320098F; Thu, 26 Oct 2023 05:56:40 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute5.internal (MEProxy); Thu, 26 Oct 2023 05:56:41 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pks.im; h=cc:cc :content-type:content-type:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:sender :subject:subject:to:to; s=fm3; t=1698314200; x=1698400600; bh=uj kcj6m7fp9gXatQniAyqp/mjcc/GgjYBPUh5MEmZ34=; b=n4dcPhDmMqoGRRp75u pctDRW34T6s4RWslnlc3/7IOSqFa3lew3jFEDDP1oEs2it7brDsLNX4ElsDfC+xs zaoy2YlOBmOIkTU5xDA65DbvC+e1uia8s6dKtJCCUy1vyiNbQxNy5hDO7l1SF9AE 5S0Oa9XjGUH7nNKBNckMZJcBJr17GYjmMWQPufundZcSDdvehL9Ohu+SkqO0GLWR 7yYJ5MAlABQO5A8eW8NfN2pgticjFLwicMMG1DYZLJk8GAyzQUZyWmnDKy8vw0AX maAmx4HkoQPHM1Ti+zXdvEEIil/F5T/fgHvxDc/UWnJd7NzHq2Nn3ja25ie495hx dsIQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:sender:subject :subject:to:to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender :x-sasl-enc; s=fm3; t=1698314200; x=1698400600; bh=ujkcj6m7fp9gX atQniAyqp/mjcc/GgjYBPUh5MEmZ34=; b=O6hX/jdDOzlDKcgVxidv5e/cYnX1T g38mAH1DJwf0N0AQAHJRdmp947cuPnqmf33AQTzP8F0dkyrq/fANO/mHLc7xTkJW iQe/xXE2VXsjkfc0sNcLTl4Vf6cUyA9mid4rWLzWnfP7HURn2BErsMjQZP3D9i9l GKI/r6J9y+e8uTtly/yceO26ZqdfDWDSOTQ8c4Mw3fA9jaUWLjC7BFX4XStX0EQm 2bVSw7LyVTr7j6Rs5Z3DilJi4B4ZVACGm2yMay2bGxho6fQzKvExU+IEwv1j0y25 OfRmXs49sVtFIjUa8sUJjMBmWllHQO+8HvpitTutfR5SpFV0YcvlKhiDg== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvkedrledvgddvudcutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc fjughrpeffhffvvefukfhfgggtuggjsehgtderredttddvnecuhfhrohhmpefrrghtrhhi tghkucfuthgvihhnhhgrrhguthcuoehpshesphhkshdrihhmqeenucggtffrrghtthgvrh hnpeeukedtvedtffevleejtefgheehieegkeeluddvfeefgeehgfeltddtheejleffteen ucevlhhushhtvghrufhiiigvpedunecurfgrrhgrmhepmhgrihhlfhhrohhmpehpshesph hkshdrihhm X-ME-Proxy: Feedback-ID: i197146af:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Thu, 26 Oct 2023 05:56:39 -0400 (EDT) Received: by vm-mail (OpenSMTPD) with ESMTPSA id 36a09362 (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Thu, 26 Oct 2023 09:56:31 +0000 (UTC) Date: Thu, 26 Oct 2023 11:56:37 +0200 From: Patrick Steinhardt To: git@vger.kernel.org Cc: Junio C Hamano , Eric Sunshine , Han-Wen Nienhuys Subject: [PATCH v2 05/12] builtin/show-ref: refactor `--exclude-existing` options Message-ID: References: Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: It's not immediately obvious options which options are applicable to what subcommand in git-show-ref(1) because all options exist as global state. This can easily cause confusion for the reader. Refactor options for the `--exclude-existing` subcommand to be contained in a separate structure. This structure is stored on the stack and passed down as required. Consequently, it clearly delimits the scope of those options and requires the reader to worry less about global state. Signed-off-by: Patrick Steinhardt --- builtin/show-ref.c | 74 +++++++++++++++++++++++++--------------------- 1 file changed, 40 insertions(+), 34 deletions(-) diff --git a/builtin/show-ref.c b/builtin/show-ref.c index f95418d3d16..90481c58492 100644 --- a/builtin/show-ref.c +++ b/builtin/show-ref.c @@ -19,8 +19,7 @@ static const char * const show_ref_usage[] = { }; static int deref_tags, show_head, tags_only, heads_only, found_match, verify, - quiet, hash_only, abbrev, exclude_arg; -static const char *exclude_existing_arg; + quiet, hash_only, abbrev; static void show_one(const char *refname, const struct object_id *oid) { @@ -95,6 +94,11 @@ static int add_existing(const char *refname, return 0; } +struct exclude_existing_options { + int enabled; + const char *pattern; +}; + /* * read "^(?:\s)?(?:\^\{\})?$" from the standard input, * and @@ -104,11 +108,11 @@ static int add_existing(const char *refname, * (4) ignore if refname is a ref that exists in the local repository; * (5) otherwise output the line. */ -static int cmd_show_ref__exclude_existing(const char *match) +static int cmd_show_ref__exclude_existing(const struct exclude_existing_options *opts) { struct string_list existing_refs = STRING_LIST_INIT_DUP; char buf[1024]; - int matchlen = match ? strlen(match) : 0; + int patternlen = opts->pattern ? strlen(opts->pattern) : 0; for_each_ref(add_existing, &existing_refs); while (fgets(buf, sizeof(buf), stdin)) { @@ -124,11 +128,11 @@ static int cmd_show_ref__exclude_existing(const char *match) for (ref = buf + len; buf < ref; ref--) if (isspace(ref[-1])) break; - if (match) { + if (opts->pattern) { int reflen = buf + len - ref; - if (reflen < matchlen) + if (reflen < patternlen) continue; - if (strncmp(ref, match, matchlen)) + if (strncmp(ref, opts->pattern, patternlen)) continue; } if (check_refname_format(ref, 0)) { @@ -201,44 +205,46 @@ static int hash_callback(const struct option *opt, const char *arg, int unset) static int exclude_existing_callback(const struct option *opt, const char *arg, int unset) { + struct exclude_existing_options *opts = opt->value; BUG_ON_OPT_NEG(unset); - exclude_arg = 1; - *(const char **)opt->value = arg; + opts->enabled = 1; + opts->pattern = arg; return 0; } -static const struct option show_ref_options[] = { - OPT_BOOL(0, "tags", &tags_only, N_("only show tags (can be combined with heads)")), - OPT_BOOL(0, "heads", &heads_only, N_("only show heads (can be combined with tags)")), - OPT_BOOL(0, "verify", &verify, N_("stricter reference checking, " - "requires exact ref path")), - OPT_HIDDEN_BOOL('h', NULL, &show_head, - N_("show the HEAD reference, even if it would be filtered out")), - OPT_BOOL(0, "head", &show_head, - N_("show the HEAD reference, even if it would be filtered out")), - OPT_BOOL('d', "dereference", &deref_tags, - N_("dereference tags into object IDs")), - OPT_CALLBACK_F('s', "hash", &abbrev, N_("n"), - N_("only show SHA1 hash using digits"), - PARSE_OPT_OPTARG, &hash_callback), - OPT__ABBREV(&abbrev), - OPT__QUIET(&quiet, - N_("do not print results to stdout (useful with --verify)")), - OPT_CALLBACK_F(0, "exclude-existing", &exclude_existing_arg, - N_("pattern"), N_("show refs from stdin that aren't in local repository"), - PARSE_OPT_OPTARG | PARSE_OPT_NONEG, exclude_existing_callback), - OPT_END() -}; - int cmd_show_ref(int argc, const char **argv, const char *prefix) { + struct exclude_existing_options exclude_existing_opts = {0}; + const struct option show_ref_options[] = { + OPT_BOOL(0, "tags", &tags_only, N_("only show tags (can be combined with heads)")), + OPT_BOOL(0, "heads", &heads_only, N_("only show heads (can be combined with tags)")), + OPT_BOOL(0, "verify", &verify, N_("stricter reference checking, " + "requires exact ref path")), + OPT_HIDDEN_BOOL('h', NULL, &show_head, + N_("show the HEAD reference, even if it would be filtered out")), + OPT_BOOL(0, "head", &show_head, + N_("show the HEAD reference, even if it would be filtered out")), + OPT_BOOL('d', "dereference", &deref_tags, + N_("dereference tags into object IDs")), + OPT_CALLBACK_F('s', "hash", &abbrev, N_("n"), + N_("only show SHA1 hash using digits"), + PARSE_OPT_OPTARG, &hash_callback), + OPT__ABBREV(&abbrev), + OPT__QUIET(&quiet, + N_("do not print results to stdout (useful with --verify)")), + OPT_CALLBACK_F(0, "exclude-existing", &exclude_existing_opts, + N_("pattern"), N_("show refs from stdin that aren't in local repository"), + PARSE_OPT_OPTARG | PARSE_OPT_NONEG, exclude_existing_callback), + OPT_END() + }; + git_config(git_default_config, NULL); argc = parse_options(argc, argv, prefix, show_ref_options, show_ref_usage, 0); - if (exclude_arg) - return cmd_show_ref__exclude_existing(exclude_existing_arg); + if (exclude_existing_opts.enabled) + return cmd_show_ref__exclude_existing(&exclude_existing_opts); else if (verify) return cmd_show_ref__verify(argv); else From patchwork Thu Oct 26 09:56:42 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 13437420 Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B96DE28E02 for ; Thu, 26 Oct 2023 09:56:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b="ZlSt7Wkp"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="jn/rG4w0" Received: from wout2-smtp.messagingengine.com (wout2-smtp.messagingengine.com [64.147.123.25]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C74AA196 for ; Thu, 26 Oct 2023 02:56:46 -0700 (PDT) Received: from compute1.internal (compute1.nyi.internal [10.202.2.41]) by mailout.west.internal (Postfix) with ESMTP id 03E1C32007CF; Thu, 26 Oct 2023 05:56:45 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute1.internal (MEProxy); Thu, 26 Oct 2023 05:56:46 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pks.im; h=cc:cc :content-type:content-type:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:sender :subject:subject:to:to; s=fm3; t=1698314205; x=1698400605; bh=AX H4vkAgDBd5Zi4eITQJDs0SX1hr46jyNzVXAzoNK3Y=; b=ZlSt7WkpDmvoELwlca pbVlwdUFZ2AGQHhHOSlccIVG37DEBT4nsBJhyw1PWgXYJqasP9MrAgS/+MMF+z/j WK0QWe5AMIbob8uIGESpGwQ6Un9qsm+tVj9XmKYnoJqsPhufPXANAw7sOkZds7OJ nIju/7AfMIcE5ZHk4qSdeG+jyQjKqq2tuK3e9cHp7BbrYTk/nIy0BC2mSSCPLUF4 hymbLbViJPKIIuiivngzezsiQ057QhE1j6XKbaLOFKfhZYSWjtEplj/Jx/OufVrr v88hgxU9GejOMU/3wYRtFJRvx3wkkEhgPXE83PzLpp993zMGH1qU49fF7XXyGj1Y CNFw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:sender:subject :subject:to:to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender :x-sasl-enc; s=fm3; t=1698314205; x=1698400605; bh=AXH4vkAgDBd5Z i4eITQJDs0SX1hr46jyNzVXAzoNK3Y=; b=jn/rG4w0ugns27pgxwEWxkzbMOvQ1 /FcFVtm4q5HkWK0xbY9Rhu5FHbWN7yqX7jF7fa23USAKXN17tcRrL+EOlmMlmggm 4VeF5DH8LuVsPL5R6mAGhd2H2RFP+nfRKy0ucQ5IQEWfpHfB4HJmoL2v+Eo26+kM 5n72XdZSlecTmtyPmS2k18ozl2OokvOFq3X3ML0liRa0YayyChDZG6Pm+l/HOEbz tUl8+2GJmEOrmMx0tg2XZhYmv1PttNQKMkq51uREPyJheMH+4qr7/iUHzQb3gab+ JJmEGxdg9Ep9txKpfijYLr5km9Yj4pnhn4xuQSQBR8/N0WWW3idO8y0Hw== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvkedrledvgddvvdcutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc fjughrpeffhffvvefukfhfgggtuggjsehgtderredttddvnecuhfhrohhmpefrrghtrhhi tghkucfuthgvihhnhhgrrhguthcuoehpshesphhkshdrihhmqeenucggtffrrghtthgvrh hnpeeukedtvedtffevleejtefgheehieegkeeluddvfeefgeehgfeltddtheejleffteen ucevlhhushhtvghrufhiiigvpedunecurfgrrhgrmhepmhgrihhlfhhrohhmpehpshesph hkshdrihhm X-ME-Proxy: Feedback-ID: i197146af:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Thu, 26 Oct 2023 05:56:44 -0400 (EDT) Received: by vm-mail (OpenSMTPD) with ESMTPSA id 08adc2b2 (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Thu, 26 Oct 2023 09:56:35 +0000 (UTC) Date: Thu, 26 Oct 2023 11:56:42 +0200 From: Patrick Steinhardt To: git@vger.kernel.org Cc: Junio C Hamano , Eric Sunshine , Han-Wen Nienhuys Subject: [PATCH v2 06/12] builtin/show-ref: stop using global variable to count matches Message-ID: References: Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: When passing patterns to git-show-ref(1) we're checking whether any reference matches -- if none does, we indicate this condition via an unsuccessful exit code. We're using a global variable to count these matches, which is required because the counter is getting incremented in a callback function. But now that we have the `struct show_ref_data` in place, we can get rid of the global variable and put the counter in there instead. Signed-off-by: Patrick Steinhardt --- builtin/show-ref.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/builtin/show-ref.c b/builtin/show-ref.c index 90481c58492..c30c01785cc 100644 --- a/builtin/show-ref.c +++ b/builtin/show-ref.c @@ -18,7 +18,7 @@ static const char * const show_ref_usage[] = { NULL }; -static int deref_tags, show_head, tags_only, heads_only, found_match, verify, +static int deref_tags, show_head, tags_only, heads_only, verify, quiet, hash_only, abbrev; static void show_one(const char *refname, const struct object_id *oid) @@ -50,6 +50,7 @@ static void show_one(const char *refname, const struct object_id *oid) struct show_ref_data { const char **patterns; + int found_match; }; static int show_ref(const char *refname, const struct object_id *oid, @@ -78,7 +79,7 @@ static int show_ref(const char *refname, const struct object_id *oid, } match: - found_match++; + data->found_match++; show_one(refname, oid); @@ -187,7 +188,7 @@ static int cmd_show_ref__patterns(const char **patterns) } else { for_each_ref(show_ref, &show_ref_data); } - if (!found_match) + if (!show_ref_data.found_match) return 1; return 0; From patchwork Thu Oct 26 09:56:48 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 13437421 Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 472EE2D033 for ; Thu, 26 Oct 2023 09:56:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b="CyBPzH5O"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="RSzC9eya" Received: from wout2-smtp.messagingengine.com (wout2-smtp.messagingengine.com [64.147.123.25]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0ADE118F for ; Thu, 26 Oct 2023 02:56:53 -0700 (PDT) Received: from compute1.internal (compute1.nyi.internal [10.202.2.41]) by mailout.west.internal (Postfix) with ESMTP id 35F9F32009EE; Thu, 26 Oct 2023 05:56:52 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute1.internal (MEProxy); Thu, 26 Oct 2023 05:56:52 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pks.im; h=cc:cc :content-type:content-type:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:sender :subject:subject:to:to; s=fm3; t=1698314211; x=1698400611; bh=fu 2FvTtyzOtBibpJyiVHRxHo+Vd+9SBwQ5fZS+M22yw=; b=CyBPzH5OfpoLTelSFi fHNrlukMOLorIbkUKjyEWLnQiA01YefEPvEcRlpoEI7JCXcNoF6ss7AKkVujYvXz 3C6wNEKyUeEchQFkuru/QPUPWEVB1xVDSiRdmAuvBTcpsImXIDmEVoYD5HsaKukb e8m9x+7CKL2N1I+/MQgupAoj88Ikz34SLJMDHZ5lwV50C8cC/VVNWDK4vDLdGQpw u1VLYCthDGhnUr1u+KwPcneAPgshsldDlHQbWccwRQ4O84gfXWU6aAc/NLr7mdur DhQAQlFnRjOZeQKKkotPWnH1lik6Rhy1snrCp/BnTO8rikhWyoTlKBdyUw3eNQ57 1RGw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:sender:subject :subject:to:to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender :x-sasl-enc; s=fm3; t=1698314211; x=1698400611; bh=fu2FvTtyzOtBi bpJyiVHRxHo+Vd+9SBwQ5fZS+M22yw=; b=RSzC9eya97WATvxe8Ou25jE83/3r7 im3MwQOBnafehOcHvpNCETOSpEN1YOkKe7whtC9y99x0GSqZB0DijNMNToaNj2/T M25zc7RQ841YEAp4eWhEa6uM4AmJns0oYACMpLnvkT7iiLQ43r8chRpVnyQ0MKpr YlevkWTftRckOBTBhB0hOrXRALdVlBq96xiJQUcw66TCH5nOcq8YGTtwk8VbgMNm htwVH45hFZpCRou+WywopxgQ8dxnZMexSU/oYtJBInLi8Ufj8auV0bWD3Tgx2d7e 9KG2VPOewC7H4FTDgHU58IhU5Hi1V2PM4z8sb7dLXywEPiqrHfXS6Mrhw== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvkedrledvgddvvdcutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc fjughrpeffhffvvefukfhfgggtuggjsehgtderredttddvnecuhfhrohhmpefrrghtrhhi tghkucfuthgvihhnhhgrrhguthcuoehpshesphhkshdrihhmqeenucggtffrrghtthgvrh hnpeeukedtvedtffevleejtefgheehieegkeeluddvfeefgeehgfeltddtheejleffteen ucevlhhushhtvghrufhiiigvpedvnecurfgrrhgrmhepmhgrihhlfhhrohhmpehpshesph hkshdrihhm X-ME-Proxy: Feedback-ID: i197146af:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Thu, 26 Oct 2023 05:56:50 -0400 (EDT) Received: by vm-mail (OpenSMTPD) with ESMTPSA id 38bf0267 (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Thu, 26 Oct 2023 09:56:41 +0000 (UTC) Date: Thu, 26 Oct 2023 11:56:48 +0200 From: Patrick Steinhardt To: git@vger.kernel.org Cc: Junio C Hamano , Eric Sunshine , Han-Wen Nienhuys Subject: [PATCH v2 07/12] builtin/show-ref: stop using global vars for `show_one()` Message-ID: <63f1dadf4c2e58439fde6489ee1ae33819f83462.1698314128.git.ps@pks.im> References: Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: The `show_one()` function implicitly receives a bunch of options which are tracked via global variables. This makes it hard to see which subcommands of git-show-ref(1) actually make use of these options. Introduce a `show_one_options` structure that gets passed down to this function. This allows us to get rid of more global state and makes it more explicit which subcommands use those options. Signed-off-by: Patrick Steinhardt --- builtin/show-ref.c | 62 ++++++++++++++++++++++++++++++---------------- 1 file changed, 40 insertions(+), 22 deletions(-) diff --git a/builtin/show-ref.c b/builtin/show-ref.c index c30c01785cc..3e6ad6b6a84 100644 --- a/builtin/show-ref.c +++ b/builtin/show-ref.c @@ -18,10 +18,17 @@ static const char * const show_ref_usage[] = { NULL }; -static int deref_tags, show_head, tags_only, heads_only, verify, - quiet, hash_only, abbrev; +static int show_head, tags_only, heads_only, verify; -static void show_one(const char *refname, const struct object_id *oid) +struct show_one_options { + int quiet; + int hash_only; + int abbrev; + int deref_tags; +}; + +static void show_one(const struct show_one_options *opts, + const char *refname, const struct object_id *oid) { const char *hex; struct object_id peeled; @@ -30,25 +37,26 @@ static void show_one(const char *refname, const struct object_id *oid) die("git show-ref: bad ref %s (%s)", refname, oid_to_hex(oid)); - if (quiet) + if (opts->quiet) return; - hex = repo_find_unique_abbrev(the_repository, oid, abbrev); - if (hash_only) + hex = repo_find_unique_abbrev(the_repository, oid, opts->abbrev); + if (opts->hash_only) printf("%s\n", hex); else printf("%s %s\n", hex, refname); - if (!deref_tags) + if (!opts->deref_tags) return; if (!peel_iterated_oid(oid, &peeled)) { - hex = repo_find_unique_abbrev(the_repository, &peeled, abbrev); + hex = repo_find_unique_abbrev(the_repository, &peeled, opts->abbrev); printf("%s %s^{}\n", hex, refname); } } struct show_ref_data { + const struct show_one_options *show_one_opts; const char **patterns; int found_match; }; @@ -81,7 +89,7 @@ static int show_ref(const char *refname, const struct object_id *oid, match: data->found_match++; - show_one(refname, oid); + show_one(data->show_one_opts, refname, oid); return 0; } @@ -149,7 +157,8 @@ static int cmd_show_ref__exclude_existing(const struct exclude_existing_options return 0; } -static int cmd_show_ref__verify(const char **refs) +static int cmd_show_ref__verify(const struct show_one_options *show_one_opts, + const char **refs) { if (!refs || !*refs) die("--verify requires a reference"); @@ -159,9 +168,9 @@ static int cmd_show_ref__verify(const char **refs) if ((starts_with(*refs, "refs/") || !strcmp(*refs, "HEAD")) && !read_ref(*refs, &oid)) { - show_one(*refs, &oid); + show_one(show_one_opts, *refs, &oid); } - else if (!quiet) + else if (!show_one_opts->quiet) die("'%s' - not a valid ref", *refs); else return 1; @@ -171,9 +180,12 @@ static int cmd_show_ref__verify(const char **refs) return 0; } -static int cmd_show_ref__patterns(const char **patterns) +static int cmd_show_ref__patterns(const struct show_one_options *show_one_opts, + const char **patterns) { - struct show_ref_data show_ref_data = {0}; + struct show_ref_data show_ref_data = { + .show_one_opts = show_one_opts, + }; if (patterns && *patterns) show_ref_data.patterns = patterns; @@ -196,11 +208,16 @@ static int cmd_show_ref__patterns(const char **patterns) static int hash_callback(const struct option *opt, const char *arg, int unset) { - hash_only = 1; + struct show_one_options *opts = opt->value; + struct option abbrev_opt = *opt; + + opts->hash_only = 1; /* Use full length SHA1 if no argument */ if (!arg) return 0; - return parse_opt_abbrev_cb(opt, arg, unset); + + abbrev_opt.value = &opts->abbrev; + return parse_opt_abbrev_cb(&abbrev_opt, arg, unset); } static int exclude_existing_callback(const struct option *opt, const char *arg, @@ -216,6 +233,7 @@ static int exclude_existing_callback(const struct option *opt, const char *arg, int cmd_show_ref(int argc, const char **argv, const char *prefix) { struct exclude_existing_options exclude_existing_opts = {0}; + struct show_one_options show_one_opts = {0}; const struct option show_ref_options[] = { OPT_BOOL(0, "tags", &tags_only, N_("only show tags (can be combined with heads)")), OPT_BOOL(0, "heads", &heads_only, N_("only show heads (can be combined with tags)")), @@ -225,13 +243,13 @@ int cmd_show_ref(int argc, const char **argv, const char *prefix) N_("show the HEAD reference, even if it would be filtered out")), OPT_BOOL(0, "head", &show_head, N_("show the HEAD reference, even if it would be filtered out")), - OPT_BOOL('d', "dereference", &deref_tags, + OPT_BOOL('d', "dereference", &show_one_opts.deref_tags, N_("dereference tags into object IDs")), - OPT_CALLBACK_F('s', "hash", &abbrev, N_("n"), + OPT_CALLBACK_F('s', "hash", &show_one_opts, N_("n"), N_("only show SHA1 hash using digits"), PARSE_OPT_OPTARG, &hash_callback), - OPT__ABBREV(&abbrev), - OPT__QUIET(&quiet, + OPT__ABBREV(&show_one_opts.abbrev), + OPT__QUIET(&show_one_opts.quiet, N_("do not print results to stdout (useful with --verify)")), OPT_CALLBACK_F(0, "exclude-existing", &exclude_existing_opts, N_("pattern"), N_("show refs from stdin that aren't in local repository"), @@ -247,7 +265,7 @@ int cmd_show_ref(int argc, const char **argv, const char *prefix) if (exclude_existing_opts.enabled) return cmd_show_ref__exclude_existing(&exclude_existing_opts); else if (verify) - return cmd_show_ref__verify(argv); + return cmd_show_ref__verify(&show_one_opts, argv); else - return cmd_show_ref__patterns(argv); + return cmd_show_ref__patterns(&show_one_opts, argv); } From patchwork Thu Oct 26 09:56:52 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 13437422 Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9D27D2D03B for ; Thu, 26 Oct 2023 09:56:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b="NLXZJUQg"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="TOzORDTR" Received: from wout2-smtp.messagingengine.com (wout2-smtp.messagingengine.com [64.147.123.25]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 42701193 for ; Thu, 26 Oct 2023 02:56:57 -0700 (PDT) Received: from compute5.internal (compute5.nyi.internal [10.202.2.45]) by mailout.west.internal (Postfix) with ESMTP id 72A2532007CF; Thu, 26 Oct 2023 05:56:56 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute5.internal (MEProxy); Thu, 26 Oct 2023 05:56:56 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pks.im; h=cc:cc :content-type:content-type:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:sender :subject:subject:to:to; s=fm3; t=1698314215; x=1698400615; bh=5l lSNq4xJ/qYO6+GDJxCg7b88d6n/9i2oxG35BMS8S8=; b=NLXZJUQgh8+QH0keI7 OQ4pChWz4/7S5o0yDWREuilYLQJ5wMrYNwlGk6ghwtpy9JDllMz1Q30pvXjT21GU 5HuMDGkQfBiyq0ZD+5WNDjnY+94dBFYpCOUQ8VkcR0a/fTWShJ/DGkKat4pe5CCF 49z9KVciX699H8CbR9pVDvGW3fDb27jgSJ4Kub97xxm3hBSA0eg4dt1kbbb/0hsm H0QahliuYQr/ikFnf+8Qoom6a6e0wMEu3pR5QSAj0EszEa5Yqz9D7/sChqaFDq6i I6K9uHCS6gakxZHSJJg7JeDeMr5po713CaETEY7E10fBnH9iqCm+Q0Ois3S03WXM DNSA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:sender:subject :subject:to:to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender :x-sasl-enc; s=fm3; t=1698314215; x=1698400615; bh=5llSNq4xJ/qYO 6+GDJxCg7b88d6n/9i2oxG35BMS8S8=; b=TOzORDTRXdzi0VqA1aLswgfZzgSzz W3bS08PvxE3zN+AnjET01z5a8QMTCrbjnINb9VF8qStnNsKmyX4qp1Topduz2AAW wsA2nujTkGdqIyLiBbKQeUXizKDydGQZxb//kjZfbNzBHQwGuoi7vS3fJnQNONWe 17MuBhu5LQbsBJpaibDC14yeffjwdWgqiPc0cnF5mzTr28ypjSxWsD9PGmw+Rv7w tmpUSWKG3NwEEbVAf8asjFV9Jp2kNd9UbAXglLxqQwrBFePRd9orLtyra3+QYSFT JGK1q6TB6bsqZYCNTKcZEtktVjZMjqLfgKJ/U3VNoIsLfZPeaCtsjIDXQ== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvkedrledvgddvvdcutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc fjughrpeffhffvvefukfhfgggtuggjsehgtderredttddvnecuhfhrohhmpefrrghtrhhi tghkucfuthgvihhnhhgrrhguthcuoehpshesphhkshdrihhmqeenucggtffrrghtthgvrh hnpeeukedtvedtffevleejtefgheehieegkeeluddvfeefgeehgfeltddtheejleffteen ucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpehpshesph hkshdrihhm X-ME-Proxy: Feedback-ID: i197146af:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Thu, 26 Oct 2023 05:56:54 -0400 (EDT) Received: by vm-mail (OpenSMTPD) with ESMTPSA id 6cfbab53 (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Thu, 26 Oct 2023 09:56:45 +0000 (UTC) Date: Thu, 26 Oct 2023 11:56:52 +0200 From: Patrick Steinhardt To: git@vger.kernel.org Cc: Junio C Hamano , Eric Sunshine , Han-Wen Nienhuys Subject: [PATCH v2 08/12] builtin/show-ref: refactor options for patterns subcommand Message-ID: <88dfeaa4871be057eba2625ee562cdd079e540c8.1698314128.git.ps@pks.im> References: Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: The patterns subcommand is the last command that still uses global variables to track its options. Convert it to use a structure instead with the same motivation as preceding commits. Signed-off-by: Patrick Steinhardt --- builtin/show-ref.c | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/builtin/show-ref.c b/builtin/show-ref.c index 3e6ad6b6a84..87bc45d2d13 100644 --- a/builtin/show-ref.c +++ b/builtin/show-ref.c @@ -18,8 +18,6 @@ static const char * const show_ref_usage[] = { NULL }; -static int show_head, tags_only, heads_only, verify; - struct show_one_options { int quiet; int hash_only; @@ -59,6 +57,7 @@ struct show_ref_data { const struct show_one_options *show_one_opts; const char **patterns; int found_match; + int show_head; }; static int show_ref(const char *refname, const struct object_id *oid, @@ -66,7 +65,7 @@ static int show_ref(const char *refname, const struct object_id *oid, { struct show_ref_data *data = cbdata; - if (show_head && !strcmp(refname, "HEAD")) + if (data->show_head && !strcmp(refname, "HEAD")) goto match; if (data->patterns) { @@ -180,22 +179,30 @@ static int cmd_show_ref__verify(const struct show_one_options *show_one_opts, return 0; } -static int cmd_show_ref__patterns(const struct show_one_options *show_one_opts, +struct patterns_options { + int show_head; + int heads_only; + int tags_only; +}; + +static int cmd_show_ref__patterns(const struct patterns_options *opts, + const struct show_one_options *show_one_opts, const char **patterns) { struct show_ref_data show_ref_data = { .show_one_opts = show_one_opts, + .show_head = opts->show_head, }; if (patterns && *patterns) show_ref_data.patterns = patterns; - if (show_head) + if (opts->show_head) head_ref(show_ref, &show_ref_data); - if (heads_only || tags_only) { - if (heads_only) + if (opts->heads_only || opts->tags_only) { + if (opts->heads_only) for_each_fullref_in("refs/heads/", show_ref, &show_ref_data); - if (tags_only) + if (opts->tags_only) for_each_fullref_in("refs/tags/", show_ref, &show_ref_data); } else { for_each_ref(show_ref, &show_ref_data); @@ -233,15 +240,17 @@ static int exclude_existing_callback(const struct option *opt, const char *arg, int cmd_show_ref(int argc, const char **argv, const char *prefix) { struct exclude_existing_options exclude_existing_opts = {0}; + struct patterns_options patterns_opts = {0}; struct show_one_options show_one_opts = {0}; + int verify = 0; const struct option show_ref_options[] = { - OPT_BOOL(0, "tags", &tags_only, N_("only show tags (can be combined with heads)")), - OPT_BOOL(0, "heads", &heads_only, N_("only show heads (can be combined with tags)")), + OPT_BOOL(0, "tags", &patterns_opts.tags_only, N_("only show tags (can be combined with heads)")), + OPT_BOOL(0, "heads", &patterns_opts.heads_only, N_("only show heads (can be combined with tags)")), OPT_BOOL(0, "verify", &verify, N_("stricter reference checking, " "requires exact ref path")), - OPT_HIDDEN_BOOL('h', NULL, &show_head, + OPT_HIDDEN_BOOL('h', NULL, &patterns_opts.show_head, N_("show the HEAD reference, even if it would be filtered out")), - OPT_BOOL(0, "head", &show_head, + OPT_BOOL(0, "head", &patterns_opts.show_head, N_("show the HEAD reference, even if it would be filtered out")), OPT_BOOL('d', "dereference", &show_one_opts.deref_tags, N_("dereference tags into object IDs")), @@ -267,5 +276,5 @@ int cmd_show_ref(int argc, const char **argv, const char *prefix) else if (verify) return cmd_show_ref__verify(&show_one_opts, argv); else - return cmd_show_ref__patterns(&show_one_opts, argv); + return cmd_show_ref__patterns(&patterns_opts, &show_one_opts, argv); } From patchwork Thu Oct 26 09:56:57 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 13437423 Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3AA4F2D030 for ; Thu, 26 Oct 2023 09:57:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b="KQ1UlfMD"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="RZf/yqox" Received: from wout2-smtp.messagingengine.com (wout2-smtp.messagingengine.com [64.147.123.25]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 726B5196 for ; Thu, 26 Oct 2023 02:57:01 -0700 (PDT) Received: from compute1.internal (compute1.nyi.internal [10.202.2.41]) by mailout.west.internal (Postfix) with ESMTP id A212E320098F; Thu, 26 Oct 2023 05:57:00 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute1.internal (MEProxy); Thu, 26 Oct 2023 05:57:01 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pks.im; h=cc:cc :content-type:content-type:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:sender :subject:subject:to:to; s=fm3; t=1698314220; x=1698400620; bh=yg B7IeWhUT4cltMwwgYeY6qSBMZWncbd6TfzGypuEUs=; b=KQ1UlfMDooA54fk6/n YPwhVxvVe7aq21hSublLxA3LIYdeKRItD3QmrTZRCeEf8HYq9kVGwi48njBMxuUi O2LxqpuQ6b/VIVhV7S7pj6eMXlUGltXMVTNz9ocSqvUsSmqVUL+2tv1gyaBSk8+D FHs2hjmM5AfzNxKBJ6AkePGNI+WaGrO8cGpQZhaCj9R7Vhf/DEiQGaOljZ4g+Pqd lA3F0elhmqde9S+RKB6W4iL6cPRK0XSV/o4oB5G7X6+RZhpxZoQtKaU9anenmiYn kfMzaw1Gsu9oIw1IhhC4vMqjvQ5GcW0maJ4wfsT8wK9Y2YzxqWsawoD6Q0Fe6tvg 2x1Q== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:sender:subject :subject:to:to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender :x-sasl-enc; s=fm3; t=1698314220; x=1698400620; bh=ygB7IeWhUT4cl tMwwgYeY6qSBMZWncbd6TfzGypuEUs=; b=RZf/yqoxhLK5hKMrDXI72Mb5pG2el L9RPnAK6J5kT3G5GH7a1X8HkH6GufsRbWLEQR/UiEBco8R0tbnwC6pEKQ7sjq4fl GVyKIA5EU7jd7Ij3hiWKbauOJy5/qdfjD5MdoWITdNQMVFk1YqKNHG4QnjIQuUv0 w/EQJvYpzYS7FmUxdPMGJtXX2NkxuzjVIcrIG1tZVqJrGNUDkZvNNhtOI8pYVh65 Q8NNepwdMrySk1VOo+zq9pFZ0wU6a1sAZ6JiMWOgcBeXZZjpcPI8llRmifRkT7Jl kDb2KHkNEu7pcgZrQ7qeMcrBRPnXfT7y0r8MSpNWAc26Pr1iqvfUGiD3w== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvkedrledvgddvvdcutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc fjughrpeffhffvvefukfhfgggtuggjsehgtderredttddvnecuhfhrohhmpefrrghtrhhi tghkucfuthgvihhnhhgrrhguthcuoehpshesphhkshdrihhmqeenucggtffrrghtthgvrh hnpeeukedtvedtffevleejtefgheehieegkeeluddvfeefgeehgfeltddtheejleffteen ucevlhhushhtvghrufhiiigvpeefnecurfgrrhgrmhepmhgrihhlfhhrohhmpehpshesph hkshdrihhm X-ME-Proxy: Feedback-ID: i197146af:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Thu, 26 Oct 2023 05:56:59 -0400 (EDT) Received: by vm-mail (OpenSMTPD) with ESMTPSA id 8937df9e (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Thu, 26 Oct 2023 09:56:50 +0000 (UTC) Date: Thu, 26 Oct 2023 11:56:57 +0200 From: Patrick Steinhardt To: git@vger.kernel.org Cc: Junio C Hamano , Eric Sunshine , Han-Wen Nienhuys Subject: [PATCH v2 09/12] builtin/show-ref: ensure mutual exclusiveness of subcommands Message-ID: <5ba566723e8742e6df150b12f1d044089ff62b59.1698314128.git.ps@pks.im> References: Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: The git-show-ref(1) command has three different modes, of which one is implicit and the other two can be chosen explicitly by passing a flag. But while these modes are standalone and cause us to execute completely separate code paths, we gladly accept the case where a user asks for both `--exclude-existing` and `--verify` at the same time even though it is not obvious what will happen. Spoiler: we ignore `--verify` and execute the `--exclude-existing` mode. Let's explicitly detect this invalid usage and die in case both modes were requested. Signed-off-by: Patrick Steinhardt --- builtin/show-ref.c | 4 ++++ t/t1403-show-ref.sh | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/builtin/show-ref.c b/builtin/show-ref.c index 87bc45d2d13..1768aef77b3 100644 --- a/builtin/show-ref.c +++ b/builtin/show-ref.c @@ -271,6 +271,10 @@ int cmd_show_ref(int argc, const char **argv, const char *prefix) argc = parse_options(argc, argv, prefix, show_ref_options, show_ref_usage, 0); + if ((!!exclude_existing_opts.enabled + !!verify) > 1) + die(_("only one of '%s' or '%s' can be given"), + "--exclude-existing", "--verify"); + if (exclude_existing_opts.enabled) return cmd_show_ref__exclude_existing(&exclude_existing_opts); else if (verify) diff --git a/t/t1403-show-ref.sh b/t/t1403-show-ref.sh index 9252a581abf..4a90a88e05d 100755 --- a/t/t1403-show-ref.sh +++ b/t/t1403-show-ref.sh @@ -196,4 +196,9 @@ test_expect_success 'show-ref --verify with dangling ref' ' ) ' +test_expect_success 'show-ref sub-modes are mutually exclusive' ' + test_must_fail git show-ref --verify --exclude-existing 2>err && + grep "only one of ${SQ}--exclude-existing${SQ} or ${SQ}--verify${SQ} can be given" err +' + test_done From patchwork Thu Oct 26 09:57:01 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 13437424 Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 052392AB2C for ; Thu, 26 Oct 2023 09:57:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b="LSu/kLLj"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="d1JEESUT" Received: from wout2-smtp.messagingengine.com (wout2-smtp.messagingengine.com [64.147.123.25]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B13FD9D for ; Thu, 26 Oct 2023 02:57:05 -0700 (PDT) Received: from compute1.internal (compute1.nyi.internal [10.202.2.41]) by mailout.west.internal (Postfix) with ESMTP id DD96132009FB; Thu, 26 Oct 2023 05:57:04 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute1.internal (MEProxy); Thu, 26 Oct 2023 05:57:05 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pks.im; h=cc:cc :content-type:content-type:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:sender :subject:subject:to:to; s=fm3; t=1698314224; x=1698400624; bh=3O 8z3KuuDmwSmlLeG4kB6BOGHumzN+SakJtG5c6mPxw=; b=LSu/kLLjGJTm6ny43k vEcoHYLxKn3li6JyxmKKpinkF4c8s4HAyOeNtIwCDJPerNTsMvkmol8iMwuKlX9b r8svnscJb02mrZFK9wHGIsqmWuj4zokG4oABgFwI1pQKBrJucHx65rFW0SHEXXRc c8s7nnTw8KkYOzZh0MbuljjeGskPCx0LKxOK7VVrWvLkYM7CTUpugkjPh6SQOc0K 9vtTw6Q65zFuigoFaq6cpwRgFM3cnFExBJndRIH/zjwhZzH84dmcHeKnwmq7bQdn TncmbCImlMXqSQJjt/DO8isV9zeEnMykoIXKu32YUpYsDTMpruq+JrYgBkNr+F8C g/bA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:sender:subject :subject:to:to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender :x-sasl-enc; s=fm3; t=1698314224; x=1698400624; bh=3O8z3KuuDmwSm lLeG4kB6BOGHumzN+SakJtG5c6mPxw=; b=d1JEESUTEnucBLVo8LnnMT7ve4fgu FbnvNfzaDMyXjRxy0GezwTWNdml8JsGXDSEe2IkVKV9CgkjNNlMCFGorzaQBCOU3 PpOEPRzvRSXnNQLii/8y/UM+/nXPRTaR2X8F44Z6GR6aEuXD/V0SdRWIJFsYBhJg AszPGixZliO0x2h0evUgnf29/RhdyXkpdJl4hyFccabFp/Y1tWwXw5cSvxGdH21P Y6kN+ULP31PhJ7/uOLWHhxJjV1judeh1Az3nTf/nprOZXLMaWlxryg/V4Eua5U/s ibg3HQSPqzD90BtYmGWKRGja7ZvRrAoZ+zmJfTDaW+8v1aWWThnT7wqBQ== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvkedrledvgddvvdcutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc fjughrpeffhffvvefukfhfgggtuggjsehgtderredttddvnecuhfhrohhmpefrrghtrhhi tghkucfuthgvihhnhhgrrhguthcuoehpshesphhkshdrihhmqeenucggtffrrghtthgvrh hnpeeukedtvedtffevleejtefgheehieegkeeluddvfeefgeehgfeltddtheejleffteen ucevlhhushhtvghrufhiiigvpeegnecurfgrrhgrmhepmhgrihhlfhhrohhmpehpshesph hkshdrihhm X-ME-Proxy: Feedback-ID: i197146af:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Thu, 26 Oct 2023 05:57:03 -0400 (EDT) Received: by vm-mail (OpenSMTPD) with ESMTPSA id 210335e2 (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Thu, 26 Oct 2023 09:56:54 +0000 (UTC) Date: Thu, 26 Oct 2023 11:57:01 +0200 From: Patrick Steinhardt To: git@vger.kernel.org Cc: Junio C Hamano , Eric Sunshine , Han-Wen Nienhuys Subject: [PATCH v2 10/12] builtin/show-ref: explicitly spell out different modes in synopsis Message-ID: References: Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: The synopsis treats the `--verify` and the implicit mode the same. They are slightly different though: - They accept different sets of flags. - The implicit mode accepts patterns while the `--verify` mode accepts references. Split up the synopsis for these two modes such that we can disambiguate those differences. While at it, drop "--quiet" from the pattern mode's synopsis. It does not make a lot of sense to list patterns, but squelch the listing output itself. The description for "--quiet" is adapted accordingly. Signed-off-by: Patrick Steinhardt --- Documentation/git-show-ref.txt | 9 ++++++--- builtin/show-ref.c | 5 ++++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/Documentation/git-show-ref.txt b/Documentation/git-show-ref.txt index 2fe274b8faa..22f5ebc6a92 100644 --- a/Documentation/git-show-ref.txt +++ b/Documentation/git-show-ref.txt @@ -8,9 +8,12 @@ git-show-ref - List references in a local repository SYNOPSIS -------- [verse] -'git show-ref' [-q | --quiet] [--verify] [--head] [-d | --dereference] +'git show-ref' [--head] [-d | --dereference] [-s | --hash[=]] [--abbrev[=]] [--tags] [--heads] [--] [...] +'git show-ref' --verify [-q | --quiet] [-d | --dereference] + [-s | --hash[=]] [--abbrev[=]] + [--] [...] 'git show-ref' --exclude-existing[=] DESCRIPTION @@ -70,8 +73,8 @@ OPTIONS -q:: --quiet:: - Do not print any results to stdout. When combined with `--verify`, this - can be used to silently check if a reference exists. + Do not print any results to stdout. Can be used with `--verify` to + silently check if a reference exists. --exclude-existing[=]:: diff --git a/builtin/show-ref.c b/builtin/show-ref.c index 1768aef77b3..d4561d7ce1f 100644 --- a/builtin/show-ref.c +++ b/builtin/show-ref.c @@ -11,9 +11,12 @@ #include "parse-options.h" static const char * const show_ref_usage[] = { - N_("git show-ref [-q | --quiet] [--verify] [--head] [-d | --dereference]\n" + N_("git show-ref [--head] [-d | --dereference]\n" " [-s | --hash[=]] [--abbrev[=]] [--tags]\n" " [--heads] [--] [...]"), + N_("git show-ref --verify [-q | --quiet] [-d | --dereference]\n" + " [-s | --hash[=]] [--abbrev[=]]\n" + " [--] [...]"), N_("git show-ref --exclude-existing[=]"), NULL }; From patchwork Thu Oct 26 09:57:06 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 13437425 Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 881BD2D02E for ; Thu, 26 Oct 2023 09:57:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b="hR5/B0dc"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="bmpXolXJ" Received: from wout2-smtp.messagingengine.com (wout2-smtp.messagingengine.com [64.147.123.25]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EF64319D for ; Thu, 26 Oct 2023 02:57:09 -0700 (PDT) Received: from compute1.internal (compute1.nyi.internal [10.202.2.41]) by mailout.west.internal (Postfix) with ESMTP id 23FE032009E0; Thu, 26 Oct 2023 05:57:09 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute1.internal (MEProxy); Thu, 26 Oct 2023 05:57:09 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pks.im; h=cc:cc :content-type:content-type:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:sender :subject:subject:to:to; s=fm3; t=1698314228; x=1698400628; bh=9K K9a7oRQWFccu2SHYcosZ2fI/Cx+XYJDPRyBPhiPdQ=; b=hR5/B0dcxZIET9yzR4 9o6BttpCtgo/IBzewq8m49OsO5KW+mH43OLVWkeUXT6Ks8KgZ1nd2a5lxt3s6ucO Gu/KHNP4ODwGsUa73Y5FSmDtZzblyp6+rq8jpx10Xa7xqKSTpJuO+OeP5JikdM/C wXVZE2klvmiaDwARnk8HEPjxA8J8kd6JPBudoBPRHKWimBpshd+3QnyaPbUA8/5K 6kiWcnHr2RH0Rrj2Coez8fChTrUT+pLoeQy801UfppoVIKax+Am3AqG3wT9VUNmP Gw/lWfT+D/dQcgBhnmZVKNVI/zAcMAHYvroN2nbZtp2hZBzYO27912iLWkE13ALx uZhw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:sender:subject :subject:to:to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender :x-sasl-enc; s=fm3; t=1698314228; x=1698400628; bh=9KK9a7oRQWFcc u2SHYcosZ2fI/Cx+XYJDPRyBPhiPdQ=; b=bmpXolXJz1MGW2KMggdiQQfqXOpLG LZQI+p1ZbKcwg3hBWiDeXFw+prcs4n4qMJDGzzaRiGfPJWPCQ5pV08QOKYvxeOdh 8LIgUpZ1dl4gTU2nL7EgD3nO4k6zUDwIcZekWKlwaB7maRRdWVj9ha8hmAInpaV7 xDtzDbT0s+EJARvbMXP2SBiqmb0Xys3O07hgiqqhNY5LY4+SqDE5cPxnE1xNHL2v ls0w4NVxA5mExgWx59H80jdd0ghDkrp1UzIBqaoUA3F1mJ0CfQEzp3F1L/vv2u53 +3xdXuhIssybJyrScDyz8IwCOg6t5sKVxRLIfE/zKIpaO+jRyygD3lMog== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvkedrledvgddvvdcutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc fjughrpeffhffvvefukfhfgggtuggjsehgtderredttddvnecuhfhrohhmpefrrghtrhhi tghkucfuthgvihhnhhgrrhguthcuoehpshesphhkshdrihhmqeenucggtffrrghtthgvrh hnpeeukedtvedtffevleejtefgheehieegkeeluddvfeefgeehgfeltddtheejleffteen ucevlhhushhtvghrufhiiigvpeehnecurfgrrhgrmhepmhgrihhlfhhrohhmpehpshesph hkshdrihhm X-ME-Proxy: Feedback-ID: i197146af:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Thu, 26 Oct 2023 05:57:07 -0400 (EDT) Received: by vm-mail (OpenSMTPD) with ESMTPSA id aef9cf63 (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Thu, 26 Oct 2023 09:56:59 +0000 (UTC) Date: Thu, 26 Oct 2023 11:57:06 +0200 From: Patrick Steinhardt To: git@vger.kernel.org Cc: Junio C Hamano , Eric Sunshine , Han-Wen Nienhuys Subject: [PATCH v2 11/12] builtin/show-ref: add new mode to check for reference existence Message-ID: <327942b116293593deca668842a4f32db7acb0e5.1698314128.git.ps@pks.im> References: Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: While we have multiple ways to show the value of a given reference, we do not have any way to check whether a reference exists at all. While commands like git-rev-parse(1) or git-show-ref(1) can be used to check for reference existence in case the reference resolves to something sane, neither of them can be used to check for existence in some other scenarios where the reference does not resolve cleanly: - References which have an invalid name cannot be resolved. - References to nonexistent objects cannot be resolved. - Dangling symrefs can be resolved via git-symbolic-ref(1), but this requires the caller to special case existence checks depending on whether or not a reference is symbolic or direct. Furthermore, git-rev-list(1) and other commands do not let the caller distinguish easily between an actually missing reference and a generic error. Taken together, this seems like sufficient motivation to introduce a separate plumbing command to explicitly check for the existence of a reference without trying to resolve its contents. This new command comes in the form of `git show-ref --exists`. This new mode will exit successfully when the reference exists, with a specific exit code of 2 when it does not exist, or with 1 when there has been a generic error. Note that the only way to properly implement this command is by using the internal `refs_read_raw_ref()` function. While the public function `refs_resolve_ref_unsafe()` can be made to behave in the same way by passing various flags, it does not provide any way to obtain the errno with which the reference backend failed when reading the reference. As such, it becomes impossible for us to distinguish generic errors from the explicit case where the reference wasn't found. Signed-off-by: Patrick Steinhardt --- Documentation/git-show-ref.txt | 11 ++++++ builtin/show-ref.c | 49 ++++++++++++++++++++++--- t/t1403-show-ref.sh | 67 +++++++++++++++++++++++++++++++++- 3 files changed, 121 insertions(+), 6 deletions(-) diff --git a/Documentation/git-show-ref.txt b/Documentation/git-show-ref.txt index 22f5ebc6a92..8fecc9e80f6 100644 --- a/Documentation/git-show-ref.txt +++ b/Documentation/git-show-ref.txt @@ -15,6 +15,7 @@ SYNOPSIS [-s | --hash[=]] [--abbrev[=]] [--] [...] 'git show-ref' --exclude-existing[=] +'git show-ref' --exists DESCRIPTION ----------- @@ -30,6 +31,10 @@ The `--exclude-existing` form is a filter that does the inverse. It reads refs from stdin, one ref per line, and shows those that don't exist in the local repository. +The `--exists` form can be used to check for the existence of a single +references. This form does not verify whether the reference resolves to an +actual object. + Use of this utility is encouraged in favor of directly accessing files under the `.git` directory. @@ -65,6 +70,12 @@ OPTIONS Aside from returning an error code of 1, it will also print an error message if `--quiet` was not specified. +--exists:: + + Check whether the given reference exists. Returns an exit code of 0 if + it does, 2 if it is missing, and 1 in case looking up the reference + failed with an error other than the reference being missing. + --abbrev[=]:: Abbreviate the object name. When using `--hash`, you do diff --git a/builtin/show-ref.c b/builtin/show-ref.c index d4561d7ce1f..2cbe4e3f721 100644 --- a/builtin/show-ref.c +++ b/builtin/show-ref.c @@ -2,7 +2,7 @@ #include "config.h" #include "gettext.h" #include "hex.h" -#include "refs.h" +#include "refs/refs-internal.h" #include "object-name.h" #include "object-store-ll.h" #include "object.h" @@ -18,6 +18,7 @@ static const char * const show_ref_usage[] = { " [-s | --hash[=]] [--abbrev[=]]\n" " [--] [...]"), N_("git show-ref --exclude-existing[=]"), + N_("git show-ref --exists "), NULL }; @@ -216,6 +217,41 @@ static int cmd_show_ref__patterns(const struct patterns_options *opts, return 0; } +static int cmd_show_ref__exists(const char **refs) +{ + struct strbuf unused_referent = STRBUF_INIT; + struct object_id unused_oid; + unsigned int unused_type; + int failure_errno = 0; + const char *ref; + int ret = 0; + + if (!refs || !*refs) + die("--exists requires a reference"); + ref = *refs++; + if (*refs) + die("--exists requires exactly one reference"); + + if (refs_read_raw_ref(get_main_ref_store(the_repository), ref, + &unused_oid, &unused_referent, &unused_type, + &failure_errno)) { + if (failure_errno == ENOENT) { + error(_("reference does not exist")); + ret = 2; + } else { + errno = failure_errno; + error_errno(_("failed to look up reference")); + ret = 1; + } + + goto out; + } + +out: + strbuf_release(&unused_referent); + return ret; +} + static int hash_callback(const struct option *opt, const char *arg, int unset) { struct show_one_options *opts = opt->value; @@ -245,10 +281,11 @@ int cmd_show_ref(int argc, const char **argv, const char *prefix) struct exclude_existing_options exclude_existing_opts = {0}; struct patterns_options patterns_opts = {0}; struct show_one_options show_one_opts = {0}; - int verify = 0; + int verify = 0, exists = 0; const struct option show_ref_options[] = { OPT_BOOL(0, "tags", &patterns_opts.tags_only, N_("only show tags (can be combined with heads)")), OPT_BOOL(0, "heads", &patterns_opts.heads_only, N_("only show heads (can be combined with tags)")), + OPT_BOOL(0, "exists", &exists, N_("check for reference existence without resolving")), OPT_BOOL(0, "verify", &verify, N_("stricter reference checking, " "requires exact ref path")), OPT_HIDDEN_BOOL('h', NULL, &patterns_opts.show_head, @@ -274,14 +311,16 @@ int cmd_show_ref(int argc, const char **argv, const char *prefix) argc = parse_options(argc, argv, prefix, show_ref_options, show_ref_usage, 0); - if ((!!exclude_existing_opts.enabled + !!verify) > 1) - die(_("only one of '%s' or '%s' can be given"), - "--exclude-existing", "--verify"); + if ((!!exclude_existing_opts.enabled + !!verify + !!exists) > 1) + die(_("only one of '%s', '%s' or '%s' can be given"), + "--exclude-existing", "--verify", "--exists"); if (exclude_existing_opts.enabled) return cmd_show_ref__exclude_existing(&exclude_existing_opts); else if (verify) return cmd_show_ref__verify(&show_one_opts, argv); + else if (exists) + return cmd_show_ref__exists(argv); else return cmd_show_ref__patterns(&patterns_opts, &show_one_opts, argv); } diff --git a/t/t1403-show-ref.sh b/t/t1403-show-ref.sh index 4a90a88e05d..b50ae6fcf11 100755 --- a/t/t1403-show-ref.sh +++ b/t/t1403-show-ref.sh @@ -197,8 +197,73 @@ test_expect_success 'show-ref --verify with dangling ref' ' ' test_expect_success 'show-ref sub-modes are mutually exclusive' ' + cat >expect <<-EOF && + fatal: only one of ${SQ}--exclude-existing${SQ}, ${SQ}--verify${SQ} or ${SQ}--exists${SQ} can be given + EOF + test_must_fail git show-ref --verify --exclude-existing 2>err && - grep "only one of ${SQ}--exclude-existing${SQ} or ${SQ}--verify${SQ} can be given" err + test_cmp expect err && + + test_must_fail git show-ref --verify --exists 2>err && + test_cmp expect err && + + test_must_fail git show-ref --exclude-existing --exists 2>err && + test_cmp expect err +' + +test_expect_success '--exists with existing reference' ' + git show-ref --exists refs/heads/$GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +' + +test_expect_success '--exists with missing reference' ' + test_expect_code 2 git show-ref --exists refs/heads/does-not-exist +' + +test_expect_success '--exists does not use DWIM' ' + test_expect_code 2 git show-ref --exists $GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME 2>err && + grep "reference does not exist" err +' + +test_expect_success '--exists with HEAD' ' + git show-ref --exists HEAD +' + +test_expect_success '--exists with bad reference name' ' + test_when_finished "git update-ref -d refs/heads/bad...name" && + new_oid=$(git rev-parse HEAD) && + test-tool ref-store main update-ref msg refs/heads/bad...name $new_oid $ZERO_OID REF_SKIP_REFNAME_VERIFICATION && + git show-ref --exists refs/heads/bad...name +' + +test_expect_success '--exists with arbitrary symref' ' + test_when_finished "git symbolic-ref -d refs/symref" && + git symbolic-ref refs/symref refs/heads/$GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME && + git show-ref --exists refs/symref +' + +test_expect_success '--exists with dangling symref' ' + test_when_finished "git symbolic-ref -d refs/heads/dangling" && + git symbolic-ref refs/heads/dangling refs/heads/does-not-exist && + git show-ref --exists refs/heads/dangling +' + +test_expect_success '--exists with nonexistent object ID' ' + test-tool ref-store main update-ref msg refs/heads/missing-oid $(test_oid 001) $ZERO_OID REF_SKIP_OID_VERIFICATION && + git show-ref --exists refs/heads/missing-oid +' + +test_expect_success '--exists with non-commit object' ' + tree_oid=$(git rev-parse HEAD^{tree}) && + test-tool ref-store main update-ref msg refs/heads/tree ${tree_oid} $ZERO_OID REF_SKIP_OID_VERIFICATION && + git show-ref --exists refs/heads/tree +' + +test_expect_success '--exists with directory fails with generic error' ' + cat >expect <<-EOF && + error: failed to look up reference: Is a directory + EOF + test_expect_code 1 git show-ref --exists refs/heads 2>err && + test_cmp expect err ' test_done From patchwork Thu Oct 26 09:57:10 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 13437426 Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5BFA82D044 for ; Thu, 26 Oct 2023 09:57:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b="l9vfg1Cr"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="NNCOF3cy" Received: from wout2-smtp.messagingengine.com (wout2-smtp.messagingengine.com [64.147.123.25]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2E2BF1A2 for ; Thu, 26 Oct 2023 02:57:14 -0700 (PDT) Received: from compute5.internal (compute5.nyi.internal [10.202.2.45]) by mailout.west.internal (Postfix) with ESMTP id 5E1EA320098F; Thu, 26 Oct 2023 05:57:13 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute5.internal (MEProxy); Thu, 26 Oct 2023 05:57:13 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pks.im; h=cc:cc :content-type:content-type:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:sender :subject:subject:to:to; s=fm3; t=1698314232; x=1698400632; bh=Uf 1911WsHOmDtsRt3akYNgUmbHiyQeFp6FwE3Yq4SEg=; b=l9vfg1CruotSvATk9/ oIIAT90WLOHDNlQI+r9yVflL+arpNXcq9hHagTzdXuWaYQILI/0ws1eGuqbQbG3C pcKHx0gJv5jfPW5OH4Mz8W4YABf2Cmn+i2FaseMomlUFRP/ScovkLLOIHV4o6K1U 52GOHuJLJHoJwZqCEmUajvFyTTsisswCJgtkthJQepenlUMlR8hFQAF/fLI/Z2Ne fJBKyBxsZuzLqvfbuPGbLDPqRcgPcEjcxgux/WDA6ywVznSxkbEu25dAruyCfPXV LoJA1nheZKzOfwmggl1yFEFovdGCnn0ujfS6gh49sn03Czt4pl6A8GWND45SezZQ k4qg== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:sender:subject :subject:to:to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender :x-sasl-enc; s=fm3; t=1698314232; x=1698400632; bh=Uf1911WsHOmDt sRt3akYNgUmbHiyQeFp6FwE3Yq4SEg=; b=NNCOF3cyISJ+B1muMLii7N5wCkEoz PzoAeSmf9fRAd2nd6Y2Y/37kogImXrR9owzs5XYRh8m0Ha08qZ7JyoWQm2JajUB7 S3Yn+j+I2yGOfTDGSTxVtmePdZqRHwZcbJ/4arsjBpr5FZ2O2q81Di5u2j3HT9/4 RJtY/lE3G+4/otLUgwu+KQCUh4SeRr9y4KoHgK+NE5R2DcBBn99yQG6QGXDFN7sU AC+4oeD0/jiVaG/25H2+85soPfAnBoDW9lznNDFUMkXOwX345wbw7gC3gg/zq9+X vE6plv9ZCGWg6axlQKFjBrQVJX3l6kBAIOBPMkYO9a/JUYeHGSR8XOypQ== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvkedrledvgddvvdcutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc fjughrpeffhffvvefukfhfgggtuggjsehgtderredttddvnecuhfhrohhmpefrrghtrhhi tghkucfuthgvihhnhhgrrhguthcuoehpshesphhkshdrihhmqeenucggtffrrghtthgvrh hnpeeukedtvedtffevleejtefgheehieegkeeluddvfeefgeehgfeltddtheejleffteen ucevlhhushhtvghrufhiiigvpedunecurfgrrhgrmhepmhgrihhlfhhrohhmpehpshesph hkshdrihhm X-ME-Proxy: Feedback-ID: i197146af:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Thu, 26 Oct 2023 05:57:11 -0400 (EDT) Received: by vm-mail (OpenSMTPD) with ESMTPSA id f96a3f05 (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Thu, 26 Oct 2023 09:57:03 +0000 (UTC) Date: Thu, 26 Oct 2023 11:57:10 +0200 From: Patrick Steinhardt To: git@vger.kernel.org Cc: Junio C Hamano , Eric Sunshine , Han-Wen Nienhuys Subject: [PATCH v2 12/12] t: use git-show-ref(1) to check for ref existence Message-ID: <226731c5f18abbbff8fd23cc0f1263b3970ff5eb.1698314128.git.ps@pks.im> References: Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Convert tests that use `test_path_is_file` and `test_path_is_missing` to instead use a set of helpers `test_ref_exists` and `test_ref_missing`. These helpers are implemented via the newly introduced `git show-ref --exists` command. Thus, we can avoid intimate knowledge of how the ref backend stores references on disk. Signed-off-by: Patrick Steinhardt --- t/t1430-bad-ref-name.sh | 27 +++++++++++++------- t/t3200-branch.sh | 33 ++++++++++++++----------- t/t5521-pull-options.sh | 4 +-- t/t5605-clone-local.sh | 2 +- t/test-lib-functions.sh | 55 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 94 insertions(+), 27 deletions(-) diff --git a/t/t1430-bad-ref-name.sh b/t/t1430-bad-ref-name.sh index ff1c967d550..7b7d6953c62 100755 --- a/t/t1430-bad-ref-name.sh +++ b/t/t1430-bad-ref-name.sh @@ -205,8 +205,9 @@ test_expect_success 'update-ref --no-deref -d can delete symref to broken name' test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/broken...ref" && test-tool ref-store main create-symref refs/heads/badname refs/heads/broken...ref msg && test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/badname" && + test_ref_exists refs/heads/badname && git update-ref --no-deref -d refs/heads/badname >output 2>error && - test_path_is_missing .git/refs/heads/badname && + test_ref_missing refs/heads/badname && test_must_be_empty output && test_must_be_empty error ' @@ -216,8 +217,9 @@ test_expect_success 'branch -d can delete symref to broken name' ' test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/broken...ref" && test-tool ref-store main create-symref refs/heads/badname refs/heads/broken...ref msg && test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/badname" && + test_ref_exists refs/heads/badname && git branch -d badname >output 2>error && - test_path_is_missing .git/refs/heads/badname && + test_ref_missing refs/heads/badname && test_i18ngrep "Deleted branch badname (was refs/heads/broken\.\.\.ref)" output && test_must_be_empty error ' @@ -225,8 +227,9 @@ test_expect_success 'branch -d can delete symref to broken name' ' test_expect_success 'update-ref --no-deref -d can delete dangling symref to broken name' ' test-tool ref-store main create-symref refs/heads/badname refs/heads/broken...ref msg && test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/badname" && + test_ref_exists refs/heads/badname && git update-ref --no-deref -d refs/heads/badname >output 2>error && - test_path_is_missing .git/refs/heads/badname && + test_ref_missing refs/heads/badname && test_must_be_empty output && test_must_be_empty error ' @@ -234,8 +237,9 @@ test_expect_success 'update-ref --no-deref -d can delete dangling symref to brok test_expect_success 'branch -d can delete dangling symref to broken name' ' test-tool ref-store main create-symref refs/heads/badname refs/heads/broken...ref msg && test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/badname" && + test_ref_exists refs/heads/badname && git branch -d badname >output 2>error && - test_path_is_missing .git/refs/heads/badname && + test_ref_missing refs/heads/badname && test_i18ngrep "Deleted branch badname (was refs/heads/broken\.\.\.ref)" output && test_must_be_empty error ' @@ -245,8 +249,9 @@ test_expect_success 'update-ref -d can delete broken name through symref' ' test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/broken...ref" && test-tool ref-store main create-symref refs/heads/badname refs/heads/broken...ref msg && test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/badname" && + test_ref_exists refs/heads/broken...ref && git update-ref -d refs/heads/badname >output 2>error && - test_path_is_missing .git/refs/heads/broken...ref && + test_ref_missing refs/heads/broken...ref && test_must_be_empty output && test_must_be_empty error ' @@ -254,8 +259,9 @@ test_expect_success 'update-ref -d can delete broken name through symref' ' test_expect_success 'update-ref --no-deref -d can delete symref with broken name' ' printf "ref: refs/heads/main\n" >.git/refs/heads/broken...symref && test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/broken...symref" && + test_ref_exists refs/heads/broken...symref && git update-ref --no-deref -d refs/heads/broken...symref >output 2>error && - test_path_is_missing .git/refs/heads/broken...symref && + test_ref_missing refs/heads/broken...symref && test_must_be_empty output && test_must_be_empty error ' @@ -263,8 +269,9 @@ test_expect_success 'update-ref --no-deref -d can delete symref with broken name test_expect_success 'branch -d can delete symref with broken name' ' printf "ref: refs/heads/main\n" >.git/refs/heads/broken...symref && test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/broken...symref" && + test_ref_exists refs/heads/broken...symref && git branch -d broken...symref >output 2>error && - test_path_is_missing .git/refs/heads/broken...symref && + test_ref_missing refs/heads/broken...symref && test_i18ngrep "Deleted branch broken...symref (was refs/heads/main)" output && test_must_be_empty error ' @@ -272,8 +279,9 @@ test_expect_success 'branch -d can delete symref with broken name' ' test_expect_success 'update-ref --no-deref -d can delete dangling symref with broken name' ' printf "ref: refs/heads/idonotexist\n" >.git/refs/heads/broken...symref && test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/broken...symref" && + test_ref_exists refs/heads/broken...symref && git update-ref --no-deref -d refs/heads/broken...symref >output 2>error && - test_path_is_missing .git/refs/heads/broken...symref && + test_ref_missing refs/heads/broken...symref && test_must_be_empty output && test_must_be_empty error ' @@ -281,8 +289,9 @@ test_expect_success 'update-ref --no-deref -d can delete dangling symref with br test_expect_success 'branch -d can delete dangling symref with broken name' ' printf "ref: refs/heads/idonotexist\n" >.git/refs/heads/broken...symref && test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/broken...symref" && + test_ref_exists refs/heads/broken...symref && git branch -d broken...symref >output 2>error && - test_path_is_missing .git/refs/heads/broken...symref && + test_ref_missing refs/heads/broken...symref && test_i18ngrep "Deleted branch broken...symref (was refs/heads/idonotexist)" output && test_must_be_empty error ' diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh index 080e4f24a6e..bde4f1485b7 100755 --- a/t/t3200-branch.sh +++ b/t/t3200-branch.sh @@ -25,7 +25,7 @@ test_expect_success 'prepare a trivial repository' ' test_expect_success 'git branch --help should not have created a bogus branch' ' test_might_fail git branch --man --help /dev/null 2>&1 && - test_path_is_missing .git/refs/heads/--help + test_ref_missing refs/heads/--help ' test_expect_success 'branch -h in broken repository' ' @@ -40,7 +40,8 @@ test_expect_success 'branch -h in broken repository' ' ' test_expect_success 'git branch abc should create a branch' ' - git branch abc && test_path_is_file .git/refs/heads/abc + git branch abc && + test_ref_exists refs/heads/abc ' test_expect_success 'git branch abc should fail when abc exists' ' @@ -61,11 +62,13 @@ test_expect_success 'git branch --force abc should succeed when abc exists' ' ' test_expect_success 'git branch a/b/c should create a branch' ' - git branch a/b/c && test_path_is_file .git/refs/heads/a/b/c + git branch a/b/c && + test_ref_exists refs/heads/a/b/c ' test_expect_success 'git branch mb main... should create a branch' ' - git branch mb main... && test_path_is_file .git/refs/heads/mb + git branch mb main... && + test_ref_exists refs/heads/mb ' test_expect_success 'git branch HEAD should fail' ' @@ -78,14 +81,14 @@ EOF test_expect_success 'git branch --create-reflog d/e/f should create a branch and a log' ' GIT_COMMITTER_DATE="2005-05-26 23:30" \ git -c core.logallrefupdates=false branch --create-reflog d/e/f && - test_path_is_file .git/refs/heads/d/e/f && + test_ref_exists refs/heads/d/e/f && test_path_is_file .git/logs/refs/heads/d/e/f && test_cmp expect .git/logs/refs/heads/d/e/f ' test_expect_success 'git branch -d d/e/f should delete a branch and a log' ' git branch -d d/e/f && - test_path_is_missing .git/refs/heads/d/e/f && + test_ref_missing refs/heads/d/e/f && test_must_fail git reflog exists refs/heads/d/e/f ' @@ -213,7 +216,7 @@ test_expect_success 'git branch -M should leave orphaned HEAD alone' ' test_commit initial && git checkout --orphan lonely && grep lonely .git/HEAD && - test_path_is_missing .git/refs/head/lonely && + test_ref_missing refs/head/lonely && git branch -M main mistress && grep lonely .git/HEAD ) @@ -799,8 +802,8 @@ test_expect_success 'deleting a symref' ' git symbolic-ref refs/heads/symref refs/heads/target && echo "Deleted branch symref (was refs/heads/target)." >expect && git branch -d symref >actual && - test_path_is_file .git/refs/heads/target && - test_path_is_missing .git/refs/heads/symref && + test_ref_exists refs/heads/target && + test_ref_missing refs/heads/symref && test_cmp expect actual ' @@ -809,16 +812,16 @@ test_expect_success 'deleting a dangling symref' ' test_path_is_file .git/refs/heads/dangling-symref && echo "Deleted branch dangling-symref (was nowhere)." >expect && git branch -d dangling-symref >actual && - test_path_is_missing .git/refs/heads/dangling-symref && + test_ref_missing refs/heads/dangling-symref && test_cmp expect actual ' test_expect_success 'deleting a self-referential symref' ' git symbolic-ref refs/heads/self-reference refs/heads/self-reference && - test_path_is_file .git/refs/heads/self-reference && + test_ref_exists refs/heads/self-reference && echo "Deleted branch self-reference (was refs/heads/self-reference)." >expect && git branch -d self-reference >actual && - test_path_is_missing .git/refs/heads/self-reference && + test_ref_missing refs/heads/self-reference && test_cmp expect actual ' @@ -826,8 +829,8 @@ test_expect_success 'renaming a symref is not allowed' ' git symbolic-ref refs/heads/topic refs/heads/main && test_must_fail git branch -m topic new-topic && git symbolic-ref refs/heads/topic && - test_path_is_file .git/refs/heads/main && - test_path_is_missing .git/refs/heads/new-topic + test_ref_exists refs/heads/main && + test_ref_missing refs/heads/new-topic ' test_expect_success SYMLINKS 'git branch -m u v should fail when the reflog for u is a symlink' ' @@ -1142,7 +1145,7 @@ EOF test_expect_success 'git checkout -b g/h/i -l should create a branch and a log' ' GIT_COMMITTER_DATE="2005-05-26 23:30" \ git checkout -b g/h/i -l main && - test_path_is_file .git/refs/heads/g/h/i && + test_ref_exists refs/heads/g/h/i && test_path_is_file .git/logs/refs/heads/g/h/i && test_cmp expect .git/logs/refs/heads/g/h/i ' diff --git a/t/t5521-pull-options.sh b/t/t5521-pull-options.sh index 079b2f2536e..3681859f983 100755 --- a/t/t5521-pull-options.sh +++ b/t/t5521-pull-options.sh @@ -143,7 +143,7 @@ test_expect_success 'git pull --dry-run' ' cd clonedry && git pull --dry-run ../parent && test_path_is_missing .git/FETCH_HEAD && - test_path_is_missing .git/refs/heads/main && + test_ref_missing refs/heads/main && test_path_is_missing .git/index && test_path_is_missing file ) @@ -157,7 +157,7 @@ test_expect_success 'git pull --all --dry-run' ' git remote add origin ../parent && git pull --all --dry-run && test_path_is_missing .git/FETCH_HEAD && - test_path_is_missing .git/refs/remotes/origin/main && + test_ref_missing refs/remotes/origin/main && test_path_is_missing .git/index && test_path_is_missing file ) diff --git a/t/t5605-clone-local.sh b/t/t5605-clone-local.sh index 1d7b1abda1a..946c5751885 100755 --- a/t/t5605-clone-local.sh +++ b/t/t5605-clone-local.sh @@ -69,7 +69,7 @@ test_expect_success 'local clone of repo with nonexistent ref in HEAD' ' git clone a d && (cd d && git fetch && - test ! -e .git/refs/remotes/origin/HEAD) + test_ref_missing refs/remotes/origin/HEAD) ' test_expect_success 'bundle clone without .bundle suffix' ' diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh index 2f8868caa17..56b33536ed1 100644 --- a/t/test-lib-functions.sh +++ b/t/test-lib-functions.sh @@ -251,6 +251,61 @@ debug () { done } +# Usage: test_ref_exists [options] +# +# -C : +# Run all git commands in directory +# +# This helper function checks whether a reference exists. Symrefs or object IDs +# will not be resolved. Can be used to check references with bad names. +test_ref_exists () { + local indir= + + while test $# != 0 + do + case "$1" in + -C) + indir="$2" + shift + ;; + *) + break + ;; + esac + shift + done && + + indir=${indir:+"$indir"/} && + + if test "$#" != 1 + then + BUG "expected exactly one reference" + fi && + + git ${indir:+ -C "$indir"} show-ref --exists "$1" +} + +# Behaves the same as test_ref_exists, except that it checks for the absence of +# a reference. This is preferable to `! test_ref_exists` as this function is +# able to distinguish actually-missing references from other, generic errors. +test_ref_missing () { + test_ref_exists "$@" + case "$?" in + 2) + # This is the good case. + return 0 + ;; + 0) + echo >&4 "test_ref_missing: reference exists" + return 1 + ;; + *) + echo >&4 "test_ref_missing: generic error" + return 1 + ;; + esac +} + # Usage: test_commit [options] [ [ []]] # -C : # Run all git commands in directory