From patchwork Tue Oct 24 13:10:40 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 13434436 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 6154929404 for ; Tue, 24 Oct 2023 13:10:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b="KejSKgq0"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="Yf5bZ1Ah" Received: from wout4-smtp.messagingengine.com (wout4-smtp.messagingengine.com [64.147.123.20]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0C68510F7 for ; Tue, 24 Oct 2023 06:10:45 -0700 (PDT) Received: from compute6.internal (compute6.nyi.internal [10.202.2.47]) by mailout.west.internal (Postfix) with ESMTP id 3BF4B3200A27; Tue, 24 Oct 2023 09:10:44 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute6.internal (MEProxy); Tue, 24 Oct 2023 09:10:44 -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=1698153043; x=1698239443; bh=4k 7MKiB3q6wYj5DiWFe3VjKUx/nnZuUeoUeNiE2DEms=; b=KejSKgq0uDk3KRR9yL qxdzhq2VJvPXGDY/LI3mU9ToxU6QHCJsSUU4QB2aTyspJLi9dUV0ep2FmO5BuqVA oDIrYzAps6uTw9nPBPHVHOlYptno68ViLxq9iQ586J4zXuvMzVG1bl/FwZQ9wxWN /MIBRJDwqGyJgWNmV6OHh4xar8tqzCr6XuoGlOqPDk6igv5ehaKMsLz7BTNAUa5T a/W6lR8P1OOw50/ZSgDd3/gWZZhaFWgg47n5MIQ+beHcv+iAjkGrLxlV7rJTjtjM x3A7APUU7D+GAVT9pRLpPFcnC5RCnmyZmkZmlm42OJgQhU9l07gCHzUBrTa6L8jC ZpOA== 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=1698153043; x=1698239443; bh=4k7MKiB3q6wYj 5DiWFe3VjKUx/nnZuUeoUeNiE2DEms=; b=Yf5bZ1AhG+pYixPzDKbX7gQiOWidn Udq3QkSbGV0A8CzjhlAo8B3+Qo0q4z6ExQaTdSRiT2ZZTVNAeHQkw+6s3ThnWzUW OQUaAfHVITL71X7zzIZnFG/OmReOOPI/9U2Qau0xZqsSBiEczBFjoWPt7dZgXDhj IcTTPpXDjUqaelFwZQdEUKDp5mMN2ZCO9hT4zk8wl5NchifVIKkMOdeCvRZeVUwD lzwD+THxWgIXjTOzvPoXXpUfYsfzZ8slp3ibuH9u4CglbuFsVRRg7pl5lvn6A9+0 KSNn4sWuKg+qa8PQ4kj6t7mcWUuj7EAUO+LtiKlBfCZfS3yokmyKJpfOg== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvkedrkeekgdeitdcutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc fjughrpeffhffvvefukfhfgggtuggjsehgtderredttddvnecuhfhrohhmpefrrghtrhhi tghkucfuthgvihhnhhgrrhguthcuoehpshesphhkshdrihhmqeenucggtffrrghtthgvrh hnpeeukedtvedtffevleejtefgheehieegkeeluddvfeefgeehgfeltddtheejleffteen ucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpehpshesph hkshdrihhm X-ME-Proxy: Feedback-ID: i197146af:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 24 Oct 2023 09:10:42 -0400 (EDT) Received: by vm-mail (OpenSMTPD) with ESMTPSA id d377ceae (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Tue, 24 Oct 2023 13:10:37 +0000 (UTC) Date: Tue, 24 Oct 2023 15:10:40 +0200 From: Patrick Steinhardt To: git@vger.kernel.org Cc: Junio C Hamano , Eric Sunshine , Han-Wen Nienhuys Subject: [PATCH 01/12] builtin/show-ref: convert pattern to a local variable Message-ID: <78163accbd2c39721249474512dedd8ed2f0fe4e.1698152926.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 Tue Oct 24 13:10:44 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 13434437 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 CADC529416 for ; Tue, 24 Oct 2023 13:10:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b="t1Hbid+I"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="Y+Wq738K" Received: from wout4-smtp.messagingengine.com (wout4-smtp.messagingengine.com [64.147.123.20]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 822581709 for ; Tue, 24 Oct 2023 06:10:48 -0700 (PDT) Received: from compute2.internal (compute2.nyi.internal [10.202.2.46]) by mailout.west.internal (Postfix) with ESMTP id B31BF320014C; Tue, 24 Oct 2023 09:10:47 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute2.internal (MEProxy); Tue, 24 Oct 2023 09:10:48 -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=1698153047; x=1698239447; bh=+u gdG4V/QxZS8eRrEzLxumySsavclQKDyGlTq/LQYsQ=; b=t1Hbid+IqR7VHLsG0G fjLSfGoqgmJrLnMPgrgxAGCw/6xLDQf17pOrOHyT2e48dTKap+bXcvU/+6+KJAQl 1Yiu43kXLsi+l9YT7jwqfAJbKx4BFf6Q69PE42dj+wkxoWd9NomN01j/6vuN40w9 JgcJDzfQlmomfVom99n6DSl8pkjS7pnMUItLfnOIs+icPiAOFbep8Qg2y7iLZydX n9Dpiq96yZeUDLkrJ3X/Ux9o9+qbJYtWGfdRFwtFeP73wocale1yWY1lPNFAWC4e KS3f9sh7DLgo/rQfDbpizjzchDEOBX0sHgvrZHr7IItomZ6Ug/5BSD4nhFqi+YTv ZkjQ== 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=1698153047; x=1698239447; bh=+ugdG4V/QxZS8 eRrEzLxumySsavclQKDyGlTq/LQYsQ=; b=Y+Wq738KEYokIr10SdIID+BKOEZsk Z3973mQu+boGbJKrPH8G8yOnMdyQWknMVvg1SC/J6dqpv4qPJOAwGPja86PSrdy1 nEGBMFUUvTjlSpRwomblusRkE0Jbw8GRjmK9tboJ4H5jkAVEwabrjww3P4YhdyPI B7A4LnkAc2r3wCk/4FS0CnHeRo5GEa6UssYitz5C0RN+tNuI+3AK8rhaMxUmwrKm D9k6OoO977fVb0v/eBZgtPfl/1+jq7vDuF1krBULorH04jWVO7VbVGWtMYxRQGQY LxMHHs/0TNNFSbaHHf1vnC8yZFx/nq4vmyP9S6ZUpuwW3ySiZODAu4ZdQ== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvkedrkeekgdeitdcutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc fjughrpeffhffvvefukfhfgggtuggjsehgtderredttddvnecuhfhrohhmpefrrghtrhhi tghkucfuthgvihhnhhgrrhguthcuoehpshesphhkshdrihhmqeenucggtffrrghtthgvrh hnpeeukedtvedtffevleejtefgheehieegkeeluddvfeefgeehgfeltddtheejleffteen ucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpehpshesph hkshdrihhm X-ME-Proxy: Feedback-ID: i197146af:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 24 Oct 2023 09:10:45 -0400 (EDT) Received: by vm-mail (OpenSMTPD) with ESMTPSA id f12babd4 (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Tue, 24 Oct 2023 13:10:41 +0000 (UTC) Date: Tue, 24 Oct 2023 15:10:44 +0200 From: Patrick Steinhardt To: git@vger.kernel.org Cc: Junio C Hamano , Eric Sunshine , Han-Wen Nienhuys Subject: [PATCH 02/12] builtin/show-ref: split up different subcommands Message-ID: <7e6ab5dee230dcb66cb8adfe4a8114a06c805802.1698152926.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 | 100 ++++++++++++++++++++++++--------------------- 1 file changed, 53 insertions(+), 47 deletions(-) diff --git a/builtin/show-ref.c b/builtin/show-ref.c index 7efab14b96c..56ee3250c5f 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,53 @@ 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 = { + .patterns = (patterns && *patterns) ? patterns : NULL, + }; + + 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 +232,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 Tue Oct 24 13:10: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: 13434438 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 13D4D2AB34 for ; Tue, 24 Oct 2023 13:10:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b="ep0nTznG"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="Hlf1vd0k" Received: from wout4-smtp.messagingengine.com (wout4-smtp.messagingengine.com [64.147.123.20]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D5737CC for ; Tue, 24 Oct 2023 06:10:52 -0700 (PDT) Received: from compute5.internal (compute5.nyi.internal [10.202.2.45]) by mailout.west.internal (Postfix) with ESMTP id 165523200A22; Tue, 24 Oct 2023 09:10:52 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute5.internal (MEProxy); Tue, 24 Oct 2023 09:10: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=1698153051; x=1698239451; bh=VT enEgeHwZu7nfoC1A+Tfn0b5SAeBiTRnXl01bRmPVY=; b=ep0nTznGH5ATQRjTt1 FwwlAS8iTuGmBFk3tXApRiRQhXVPfSnD7ECCGrCGUkTK0ho+R/DNSY6m4qgf9Kr1 Kq9aTCWFbPur7uArxB6/gCe+zk6IpGXIwDt99b7tuZcAREDhZIBS1WqX3S5x6Gmp 79NufUZz2OK7fvXFmuEMim8OXTpLpXcCqKmWnoLUx6+T9bEmF/duexCT9h/gEYdf jzoURZ5W2X+MLCC3GJ+vW6Xc3CrROrKAAMZWak/H1mxYcGuTqc7rvGwnXf5LEw3j VRCAhNZgf6qhc0DDjZ5yN2ABYJ8I9e9dDRFoL+VXqKhuPpJ3+aFid3pbLqwTe08x aroQ== 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=1698153051; x=1698239451; bh=VTenEgeHwZu7n foC1A+Tfn0b5SAeBiTRnXl01bRmPVY=; b=Hlf1vd0kpj298dFcWp1nhkVpaMk6n JfqJtl3Hup142yOF6FP1n6x2tWYX0vPVSuBbP5SQsMuOwwoWHJvHurY0AZKzIEaZ FnDddaoEk00P8fgWVGHeTzNfED7KEhq1uSUJiaf2/lRKfY+Y3daCanbDy45jlJbX sog8GMHW8C3nxEG1DKdGzN6zmV4+tLUMYMvIFYKmDunuuv7bTSVeOdKiSx3GKirs oPUmsZUC/gTIqK5C4hfj/uE94kwPDGkw9gixQI0C9hwq3oJWLZz9kb9IR6/k3wG+ cuOHBowoM8s8DvfOX3j6pk5FPGdqia2Ld6ADpSJhUV321pJMac0onLswA== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvkedrkeekgdeitdcutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc fjughrpeffhffvvefukfhfgggtuggjsehgtderredttddvnecuhfhrohhmpefrrghtrhhi tghkucfuthgvihhnhhgrrhguthcuoehpshesphhkshdrihhmqeenucggtffrrghtthgvrh hnpeeukedtvedtffevleejtefgheehieegkeeluddvfeefgeehgfeltddtheejleffteen ucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpehpshesph hkshdrihhm X-ME-Proxy: Feedback-ID: i197146af:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 24 Oct 2023 09:10:50 -0400 (EDT) Received: by vm-mail (OpenSMTPD) with ESMTPSA id d9ea4d88 (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Tue, 24 Oct 2023 13:10:45 +0000 (UTC) Date: Tue, 24 Oct 2023 15:10:48 +0200 From: Patrick Steinhardt To: git@vger.kernel.org Cc: Junio C Hamano , Eric Sunshine , Han-Wen Nienhuys Subject: [PATCH 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 56ee3250c5f..761669d28de 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 Tue Oct 24 13:10:53 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 13434439 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 4B3442AB42 for ; Tue, 24 Oct 2023 13:10:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b="E8DgpqeP"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="HHQTN/Do" Received: from wout4-smtp.messagingengine.com (wout4-smtp.messagingengine.com [64.147.123.20]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1AFAB1719 for ; Tue, 24 Oct 2023 06:10:57 -0700 (PDT) Received: from compute2.internal (compute2.nyi.internal [10.202.2.46]) by mailout.west.internal (Postfix) with ESMTP id 4D79032009B9; Tue, 24 Oct 2023 09:10:56 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute2.internal (MEProxy); Tue, 24 Oct 2023 09:10: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=1698153055; x=1698239455; bh=Un EnMwirdwxAAIS/g0oVhOAzzsu8M6Daabj+bdockBI=; b=E8DgpqePzvWla5A50s vUGbQlhkbkFW3cBCEXek4I0I3Vu617688Idu6IPKn6MDEezGghOly7dBs8YDccI8 LfMs//MmjYZfBxZ1ST2du5ZM9ILLD+ClYwp4LVKTo+bxnWtV12EZE/8qiBs2pt/N QYCJn5iyhXDaxVUcFZ0opo98+UYJIi8reChOnPSwWtUUVW7uB6qqanPZK0oQFFTp 2JwYW7MZ1f41f/zKKCb8aDPWlNbriZaVBMIC2aleKxVLak4VZgHjEeeWsGKu8Mlz NeQ3Dgo7xcoG5+iFl6ZvgLvuthrzvAOBHmtr5GOdzu3u0gGEwL9t92945ednYgW9 sXlw== 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=1698153055; x=1698239455; bh=UnEnMwirdwxAA IS/g0oVhOAzzsu8M6Daabj+bdockBI=; b=HHQTN/DoOi+6HWgffYqRojuQlBCRi IYwikS3U4a57MIDFVLNj9TimEGBwdQ9STLggSNfrkiBMdb05A6BY/vEx2RyomNPC yUyoB772bajLbwQ2IXIJAxw7wVNSrQxItj5psPciRPdHpBb+PTte3reFIaUQXIht K64D2DkKMTPu/xFeOSjyxVPB9gGY0sjzDSpmGAuh8O79Y38+BgIwgAuPDUUKLFpj PTM8gV7L7PcaTODil3vn4CzgROyHG+5UujJf60WmHXJmYnxVHv2OZS+mIYsnByxS qPgXQhEL+lkJu6EYI4O59wTtG6bH7nxKZwyBFQeafHe92VFlUXfZvYQyQ== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvkedrkeekgdeitdcutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc fjughrpeffhffvvefukfhfgggtuggjsehgtderredttddvnecuhfhrohhmpefrrghtrhhi tghkucfuthgvihhnhhgrrhguthcuoehpshesphhkshdrihhmqeenucggtffrrghtthgvrh hnpeeukedtvedtffevleejtefgheehieegkeeluddvfeefgeehgfeltddtheejleffteen ucevlhhushhtvghrufhiiigvpedunecurfgrrhgrmhepmhgrihhlfhhrohhmpehpshesph hkshdrihhm X-ME-Proxy: Feedback-ID: i197146af:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 24 Oct 2023 09:10:54 -0400 (EDT) Received: by vm-mail (OpenSMTPD) with ESMTPSA id 786e3b97 (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Tue, 24 Oct 2023 13:10:50 +0000 (UTC) Date: Tue, 24 Oct 2023 15:10:53 +0200 From: Patrick Steinhardt To: git@vger.kernel.org Cc: Junio C Hamano , Eric Sunshine , Han-Wen Nienhuys Subject: [PATCH 04/12] builtin/show-ref: fix dead code when passing patterns Message-ID: <29c0c0c6c9728f286efd0b78996f9a1394957862.1698152926.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 of `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 761669d28de..eb60f940a3c 100644 --- a/builtin/show-ref.c +++ b/builtin/show-ref.c @@ -182,11 +182,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 Tue Oct 24 13:10: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: 13434440 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 2BD2029439 for ; Tue, 24 Oct 2023 13:11:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b="gP4YN6eJ"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="DloN5qZ/" Received: from wout4-smtp.messagingengine.com (wout4-smtp.messagingengine.com [64.147.123.20]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5A3AC171B for ; Tue, 24 Oct 2023 06:11:01 -0700 (PDT) Received: from compute6.internal (compute6.nyi.internal [10.202.2.47]) by mailout.west.internal (Postfix) with ESMTP id 8038C32009BC; Tue, 24 Oct 2023 09:11:00 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute6.internal (MEProxy); Tue, 24 Oct 2023 09:11:00 -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=1698153060; x=1698239460; bh=Yn vpPzdGk4bUNY/bhU20UOcJo8wC+m4Qxkd/16716R8=; b=gP4YN6eJClfhNfl3Rv NH2/RzVJjtnC5bJC7v+Ma2/iEn6ik2I5NuUdsO3pLlBxCYYId0fObHETkqVc4jPb Zk3GCA8YwN2OTruBYL87ihhOjHjQTCvJcs4ZNRamMzX+41hAJDwj08fRtln2+Q7O BKIswIYBFLHoO/SuI3Z9VN//tKblFyepUXVLFAu5RPHfAD6RonIyCDwz2CRLjcVQ k9WkGNW8c5vHp458RL0bIveVPT4/OZQW46RuBU3GN5aQ4+IVabXXOWvHPDiPelXy cGWi7ugqK4CHROwZM9tDVLxp0lXfF0tWcfs1jd9Pp9eFSStX3JK9MGfEHkAbkxNV 5WRQ== 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=1698153060; x=1698239460; bh=YnvpPzdGk4bUN Y/bhU20UOcJo8wC+m4Qxkd/16716R8=; b=DloN5qZ/jJRBZQtdPFxdmDdkAF3u2 5A41roaa/FO6PEb8YgzQH7WfEFuTC4Yuw92cZurwapbuCU/Qpy+5353hcdw4yStv UQWyAVH7P9VHZ1HbMLcnIJRjlyM9yy0+TOTc0tlPEjX/qNCW7RXQeqplir+F5iUR d0S4wKNseukThavu3Wl/8uqgsEX4/BmtJTCZ4zdFAvKnf8UxLwXgOB8T2+w+1nNn hvIaV7OZbcqhATJ6d8rBUFubOsyz7V5gGtZpuq8wl8W5b6iRbnn14/h2wgrhhBTT /sMQw7E0LtPSk5yknvx81Zi0TZs1bIYXmHn2baIgrU4cr/o+kphEcl1+w== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvkedrkeekgdeitdcutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc fjughrpeffhffvvefukfhfgggtuggjsehgtderredttddvnecuhfhrohhmpefrrghtrhhi tghkucfuthgvihhnhhgrrhguthcuoehpshesphhkshdrihhmqeenucggtffrrghtthgvrh hnpeeukedtvedtffevleejtefgheehieegkeeluddvfeefgeehgfeltddtheejleffteen ucevlhhushhtvghrufhiiigvpedunecurfgrrhgrmhepmhgrihhlfhhrohhmpehpshesph hkshdrihhm X-ME-Proxy: Feedback-ID: i197146af:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 24 Oct 2023 09:10:58 -0400 (EDT) Received: by vm-mail (OpenSMTPD) with ESMTPSA id ed772654 (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Tue, 24 Oct 2023 13:10:54 +0000 (UTC) Date: Tue, 24 Oct 2023 15:10:57 +0200 From: Patrick Steinhardt To: git@vger.kernel.org Cc: Junio C Hamano , Eric Sunshine , Han-Wen Nienhuys Subject: [PATCH 05/12] builtin/show-ref: refactor `--exclude-existing` options Message-ID: <8d0b0b5700c7ffed6b3a74760d0d9155b404bb4f.1698152926.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: It's not immediately obvious options which options are applicable to what subcommand ni 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. Consequentially, 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 | 72 +++++++++++++++++++++++++--------------------- 1 file changed, 39 insertions(+), 33 deletions(-) diff --git a/builtin/show-ref.c b/builtin/show-ref.c index eb60f940a3c..e130b999c0b 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 matchlen = 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) continue; - if (strncmp(ref, match, matchlen)) + if (strncmp(ref, opts->pattern, matchlen)) continue; } if (check_refname_format(ref, 0)) { @@ -200,44 +204,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 Tue Oct 24 13:11: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: 13434441 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 B4542219ED for ; Tue, 24 Oct 2023 13:11:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b="Mqvpdfhc"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="p73LA1JR" Received: from wout4-smtp.messagingengine.com (wout4-smtp.messagingengine.com [64.147.123.20]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9427210C3 for ; Tue, 24 Oct 2023 06:11:05 -0700 (PDT) Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailout.west.internal (Postfix) with ESMTP id C6A0C32009F6; Tue, 24 Oct 2023 09:11:04 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute4.internal (MEProxy); Tue, 24 Oct 2023 09:11: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=1698153064; x=1698239464; bh=hu yu/lIuKKxw+SdqzTc16OrSRgOkAN80be/vtGSWqVk=; b=MqvpdfhcClnUoxIkEm FSgh1p9tRmM3e2/rjPbcQWBgPEB3lu+sK/X2Hdph10f6NpEQaNPLn5XxFqwd09ld ZlO7L1mAWCjpdpL47nZrFobSacPMY1sBJ/JbEcaYiaz+82j4IRU0Pg5lqt96s0yL ZUm5tr9s6NEneuPB017zokurio+UKf2S9A+O4jcWUc1enn+LO2lA8RXVi1Ab6HBd mluX2kUTUy+CF9aKea/SZcW1fKzeKp9n9MZhMnJFZaGoVwCzOYA3ELHHD5Kx3P+C 7UP+up5+nkl6YbHsW0PPEknaOb5dvxgdymcH/P9WTf3V7PKXCruot0LVHS1lDmBt KD3A== 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=1698153064; x=1698239464; bh=huyu/lIuKKxw+ SdqzTc16OrSRgOkAN80be/vtGSWqVk=; b=p73LA1JRmIAkD+x1NksZFnJgh1i41 tca0X/iYqRtRhT9GQi79vivrEi3MpymXkBZEHkpNDop020P+u7l62b3JReWhxTPX o6zwl+Fx0M+SBwKS2cxizRsNyEOkl8f/r1bslqBwIKHu/49ADWgichFXLNOivF8l Blp2mFYWZ024guRVj/iPXk6wMnqZ6hyR6Lw94Mp1V9HAySd9mZ2BtT7VBscwPnjL sNWMcWl1TwTlfN4G31k6bgoTGhibzP5m0gPsBj1/f/SrnOCdQOvEErxae54qy3tw lQBEJBYLAUmCi0560ogzwCQqxkWtt3HfNWZ1zwJlWrrcyYcfDRhy2FOJQ== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvkedrkeekgdeitdcutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc fjughrpeffhffvvefukfhfgggtuggjsehgtderredttddvnecuhfhrohhmpefrrghtrhhi tghkucfuthgvihhnhhgrrhguthcuoehpshesphhkshdrihhmqeenucggtffrrghtthgvrh hnpeeukedtvedtffevleejtefgheehieegkeeluddvfeefgeehgfeltddtheejleffteen ucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpehpshesph hkshdrihhm X-ME-Proxy: Feedback-ID: i197146af:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 24 Oct 2023 09:11:03 -0400 (EDT) Received: by vm-mail (OpenSMTPD) with ESMTPSA id 7d66287f (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Tue, 24 Oct 2023 13:10:58 +0000 (UTC) Date: Tue, 24 Oct 2023 15:11:01 +0200 From: Patrick Steinhardt To: git@vger.kernel.org Cc: Junio C Hamano , Eric Sunshine , Han-Wen Nienhuys Subject: [PATCH 06/12] builtin/show-ref: stop using global variable to count matches Message-ID: <6e0f3d4e104372157da1ebd4509a5a7b0ac47636.1698152926.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(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 e130b999c0b..4c039007dd1 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); @@ -186,7 +187,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 Tue Oct 24 13:11:05 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 13434442 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 5D7A62AB29 for ; Tue, 24 Oct 2023 13:11:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b="GhbiEa4C"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="BUau//e8" Received: from wout4-smtp.messagingengine.com (wout4-smtp.messagingengine.com [64.147.123.20]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2599D12C for ; Tue, 24 Oct 2023 06:11:10 -0700 (PDT) Received: from compute6.internal (compute6.nyi.internal [10.202.2.47]) by mailout.west.internal (Postfix) with ESMTP id 0D01832009A2; Tue, 24 Oct 2023 09:11:08 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute6.internal (MEProxy); Tue, 24 Oct 2023 09:11: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=1698153068; x=1698239468; bh=4O +QhhRPzjMcG4fhQuEBHVoFnp353aobwTW7NxcHFzw=; b=GhbiEa4CGL6eNTaqj7 mjmaEMU70wW3DqMyrOfwDO3j4O3rx/n9nqeL85+2MYKiapzIAQwU5OuWFV/BFTJO MIFBm4DClW+c1NJLLVlpg3YYeMLRdrO8JAvgPm0/M5NoucfHBcrproh3gk8jo8+I 3mBYFLCh5pyFSl37RJitdpn9heHrieFaiypx7wF2bASuuZrkuYBMQD1SBFh1dumj yum28QlojPE6PGvefqgv8ZiyIGhU9WBuNtjYwbNy3gYkFrOQik5Zqk7I8A9a1Uld yQ3zREISr4K69Mux0D3wZ8+cKA+Br+86uJMszz/M1ZPthJxRFquPrExY6dCYOGas Iy3Q== 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=1698153068; x=1698239468; bh=4O+QhhRPzjMcG 4fhQuEBHVoFnp353aobwTW7NxcHFzw=; b=BUau//e8uSWPf+YoF2aPWNFEHH4t9 uFhBIkb5I7k0nJbc6a5plyGepoamNyIVBHk+VjUJ8kF7PEfu2mpnAZ+37qL034Fi RJj2GU0XZ04ZUbittJG3P6JagljGGgBFzbLrLJ4jdrEw+6+FDTX77p93784/sc2m nN+M1/LIszgOPssXYcAjSdaZXvwIgqUQ2wMvo4R8WiOXic2h/QqzN5cQO1dDzTE/ GzQsET4xhjCB6Hayd5ggHg/ttjkX0WjeN7iZza5SGKHAx9jjeIKhAjTHvA+GTSvw HjpPGUuUpzM/3h8r/0kYGx/bf+8GfKo2ywn05vvAT9VpiYH+vR7a+hntw== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvkedrkeekgdeitdcutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc fjughrpeffhffvvefukfhfgggtuggjsehgtderredttddvnecuhfhrohhmpefrrghtrhhi tghkucfuthgvihhnhhgrrhguthcuoehpshesphhkshdrihhmqeenucggtffrrghtthgvrh hnpeeukedtvedtffevleejtefgheehieegkeeluddvfeefgeehgfeltddtheejleffteen ucevlhhushhtvghrufhiiigvpedvnecurfgrrhgrmhepmhgrihhlfhhrohhmpehpshesph hkshdrihhm X-ME-Proxy: Feedback-ID: i197146af:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 24 Oct 2023 09:11:07 -0400 (EDT) Received: by vm-mail (OpenSMTPD) with ESMTPSA id bbf255d3 (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Tue, 24 Oct 2023 13:11:02 +0000 (UTC) Date: Tue, 24 Oct 2023 15:11:05 +0200 From: Patrick Steinhardt To: git@vger.kernel.org Cc: Junio C Hamano , Eric Sunshine , Han-Wen Nienhuys Subject: [PATCH 07/12] builtin/show-ref: stop using global vars for `show_one()` Message-ID: <2da1e65dd8f92b3b6955321abf6b497cca75ce0d.1698152926.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 | 59 +++++++++++++++++++++++++++++----------------- 1 file changed, 38 insertions(+), 21 deletions(-) diff --git a/builtin/show-ref.c b/builtin/show-ref.c index 4c039007dd1..589a91f15b9 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,11 @@ 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 = { + .show_one_opts = show_one_opts, .patterns = (patterns && *patterns) ? patterns : NULL, }; @@ -195,11 +206,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, @@ -215,6 +231,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)")), @@ -224,13 +241,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"), @@ -246,7 +263,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 Tue Oct 24 13:11: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: 13434443 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 B1BB32941D for ; Tue, 24 Oct 2023 13:11:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b="Bg/Jdkot"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="WfZ8m+5t" Received: from wout4-smtp.messagingengine.com (wout4-smtp.messagingengine.com [64.147.123.20]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 101DB10D0 for ; Tue, 24 Oct 2023 06:11:14 -0700 (PDT) Received: from compute3.internal (compute3.nyi.internal [10.202.2.43]) by mailout.west.internal (Postfix) with ESMTP id 41C3532009F6; Tue, 24 Oct 2023 09:11:13 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute3.internal (MEProxy); Tue, 24 Oct 2023 09:11: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=1698153072; x=1698239472; bh=hx qvT3H5tPvDkXCFWLFIGM5ut63nYUI8vmf59Cq2ywQ=; b=Bg/JdkotBpF0DAkOtp 2OkO2rzeaBat6o18NOr+Yo0BnVBX+WfTIc25n1HUVvDkJYC1/sSM77XxpZ7XU4rl xSM4CM6pKPuFCFgfpX9cE56Abs4cOYS3G1GhH2znH3JIEvs/Q/32c+jY4ITQVu0V 1sAtdKWlgm0moLc3QMTYH3QjCTXNEwMNy1Jgrsr+S3cnyduZfK5xENDdvxp7ECCx rXs9d09h0RYQVlqKdyVvGMy7PDx0fvvibzSZMAwEY7akSwPzpnNSVwWHwlRulwIi sANPsAhnWlarFE1BkRf645A2q9kk4OCRXjFh0XdGYx3QJoZ1bWxo0RmvEu55pj0s XWCA== 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=1698153072; x=1698239472; bh=hxqvT3H5tPvDk XCFWLFIGM5ut63nYUI8vmf59Cq2ywQ=; b=WfZ8m+5txr3j8L3SzMA9J9h9SFtjS vpaRTQT8iuVJioi/gZg1lWQLN56Gbw7gEEGbOzhXlp4eZIOM2aKeDgmf5nn3fSCP rVk6aR7PHLWd6rllA0MsqXcfxYAi8otUW/0R10RZBqcrQSysd4W3pW5YpUo1VrT2 Uv43naAi5D12mBxMeTeRMxi9hd/0LrOB6zH9mZTaI89MdZ5lLINqHljWdlsw110M MrgAI0vbbwIb3/+qyJ6I7jPDnytbZsJVWMfpqwx2APjNZTOyEC+ROZluNyFEYUts raNFDqbiPtF9Ge4yiEvh2/xjFm2fNF93RUZpG5pJW+ariYN3B2EkCt21g== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvkedrkeekgdeitdcutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc fjughrpeffhffvvefukfhfgggtuggjsehgtderredttddvnecuhfhrohhmpefrrghtrhhi tghkucfuthgvihhnhhgrrhguthcuoehpshesphhkshdrihhmqeenucggtffrrghtthgvrh hnpeeukedtvedtffevleejtefgheehieegkeeluddvfeefgeehgfeltddtheejleffteen ucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpehpshesph hkshdrihhm X-ME-Proxy: Feedback-ID: i197146af:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 24 Oct 2023 09:11:11 -0400 (EDT) Received: by vm-mail (OpenSMTPD) with ESMTPSA id 295b1b49 (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Tue, 24 Oct 2023 13:11:07 +0000 (UTC) Date: Tue, 24 Oct 2023 15:11:10 +0200 From: Patrick Steinhardt To: git@vger.kernel.org Cc: Junio C Hamano , Eric Sunshine , Han-Wen Nienhuys Subject: [PATCH 08/12] builtin/show-ref: refactor options for patterns subcommand Message-ID: <805889eda4cf89e6aebf8a408ceb2a5c60551526.1698152926.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 589a91f15b9..5d5d7d22ed1 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,20 +179,28 @@ 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, .patterns = (patterns && *patterns) ? patterns : NULL, }; - 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); @@ -231,15 +238,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")), @@ -265,5 +274,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 Tue Oct 24 13:11:14 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 13434444 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 188092942B for ; Tue, 24 Oct 2023 13:11:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b="Gcwuo7p1"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="pGzJ94ZU" Received: from wout4-smtp.messagingengine.com (wout4-smtp.messagingengine.com [64.147.123.20]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5B54D10E5 for ; Tue, 24 Oct 2023 06:11:18 -0700 (PDT) Received: from compute6.internal (compute6.nyi.internal [10.202.2.47]) by mailout.west.internal (Postfix) with ESMTP id 8B6FE32009BC; Tue, 24 Oct 2023 09:11:17 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute6.internal (MEProxy); Tue, 24 Oct 2023 09:11:17 -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=1698153077; x=1698239477; bh=ZI ulf8p5P1sFr8OpHPLfmknQk3p2DIrP9qjZXRmkxNk=; b=Gcwuo7p1ZVZQfanT3W U9d6ZE8EufYpjRXCuBaoJKby6Vt0Q0VDRb+SrRXci+XYYdLucOjT7mABfou5VII3 h/YN+v03vcGDfPIVdhK1hpwcUKMkkgIdz3iuwn6Wf/ts/7tqLbTI76LuBGWfdPcg lXAJ2sUlaaR7l/hqCPbtoGtUBtCNmyYQmq41+phBrt77vxtB9AqZJs0qACyCj5HR MQhvExMW6n8fyEgB2dENIGEXeDcTSxPRdyXHRxklKjn2u0R62RgTyCPJqYbFZrBy kfT1XpGt07mcWSuYMwYQksI95eBcvfw/3Zj/Jx9YkBcSsLC7nFLXnJ/0zxJD/4Wt bhZQ== 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=1698153077; x=1698239477; bh=ZIulf8p5P1sFr 8OpHPLfmknQk3p2DIrP9qjZXRmkxNk=; b=pGzJ94ZUwm/9DQl2sVcZLf/XTlbpM Gbzq3hy3MoqOEqY7pwWRPhzsNgoyIcf7MlLfQEjKNsJxaRB9+v/tGXeiBFPtgLsf FkMY0e4rUab27tuh0JlQZ7FI8xE5zx5BQr0aDrW7/w5FYAX4dxFeKiaVxEJpL+gg AKdStW7UqsPkfjNGtZfQ/ewzOHthj8TNtN21h88tn7MFjD6eDhb/eQDKzRhweOc5 VFY3f7ltz6y+HALCEzwDc4BukrYhFMVXKmD6TN75aHBs+ymOT0WF53NneVBS3jjx OYK5EoRhB2ubINuuprvHrpy1dAJ/pC3LbwUMMMiUI6NXSKSrk+aAM8mmQ== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvkedrkeekgdeitdcutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc fjughrpeffhffvvefukfhfgggtuggjsehgtderredttddvnecuhfhrohhmpefrrghtrhhi tghkucfuthgvihhnhhgrrhguthcuoehpshesphhkshdrihhmqeenucggtffrrghtthgvrh hnpeeukedtvedtffevleejtefgheehieegkeeluddvfeefgeehgfeltddtheejleffteen ucevlhhushhtvghrufhiiigvpeefnecurfgrrhgrmhepmhgrihhlfhhrohhmpehpshesph hkshdrihhm X-ME-Proxy: Feedback-ID: i197146af:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 24 Oct 2023 09:11:15 -0400 (EDT) Received: by vm-mail (OpenSMTPD) with ESMTPSA id b36975e6 (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Tue, 24 Oct 2023 13:11:11 +0000 (UTC) Date: Tue, 24 Oct 2023 15:11:14 +0200 From: Patrick Steinhardt To: git@vger.kernel.org Cc: Junio C Hamano , Eric Sunshine , Han-Wen Nienhuys Subject: [PATCH 09/12] builtin/show-ref: ensure mutual exclusiveness of subcommands 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 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 | 3 +++ t/t1403-show-ref.sh | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/builtin/show-ref.c b/builtin/show-ref.c index 5d5d7d22ed1..10d0213e687 100644 --- a/builtin/show-ref.c +++ b/builtin/show-ref.c @@ -269,6 +269,9 @@ 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 --exclude-existing or --verify can be given")); + 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..3a312c8b27c 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 --exclude-existing or --verify can be given" err +' + test_done From patchwork Tue Oct 24 13:11:20 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 13434445 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 2AB372AB35 for ; Tue, 24 Oct 2023 13:11:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b="FvHxRJcd"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="Zv1Otd3p" Received: from wout4-smtp.messagingengine.com (wout4-smtp.messagingengine.com [64.147.123.20]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B67DED7D for ; Tue, 24 Oct 2023 06:11:24 -0700 (PDT) Received: from compute3.internal (compute3.nyi.internal [10.202.2.43]) by mailout.west.internal (Postfix) with ESMTP id D43D032009F6; Tue, 24 Oct 2023 09:11:23 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute3.internal (MEProxy); Tue, 24 Oct 2023 09:11:24 -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=1698153083; x=1698239483; bh=3a PQPejqIhi+4oQbY3rbLJ+Z4+YNu+SSxjN3/d6f7/4=; b=FvHxRJcdBpiRh9rl8z QSiteKZa/jxaktxBxGQKOzQ5ov50ehkhmQRmEyCnr1v7u2ICgwqSAPB8CNEFhcfe bsOmdikjbQ5o0Ru5Hr4jC59Rk4gJ7chr3ZSao8Ol4D3PjG+3W7Dv01It4NiiTI7H kuEiLYsj3M3jGf32RyPByl0nWVHLgbDeaX4LK1BW44EYbCFeKqGyETl5nbC/UNKT V2wyzdHRWZ/T4R/SVJmExZAcV0KDfm2j0MM+cjDCCGAHlY8yrgmod8xU/Jf0A3Uo MWiH6Je2L5eD0lIQLnlFNHU7VcpFP+nRTig2V9O7eI2CeTKp8NOFYIPco9qLeMna OIqw== 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=1698153083; x=1698239483; bh=3aPQPejqIhi+4 oQbY3rbLJ+Z4+YNu+SSxjN3/d6f7/4=; b=Zv1Otd3pnoF9Mmz+ZdgsG2ja7PuJ/ 3PqRo3Hn1wEdye8Z6esKoPUiR1rDmJQK2TFnI6WE73XciQCAsypaJgXJJYBKec/q aUB6W/nWQex6ORMDe4PpAujkdNuPbEHXlTXcrWH9XUtYkrHFvNvDY0jBLwbPLlJ9 Tb7drJUBvOttkfwbuRlkWebWlTCdYUwGrlAA3mmcZ7EUT52KQWSswx8OyaoPg5Dc rxXCbyUwiG74ghTMBD51KK/u+DkMVDWAJ0JoIhP7Tmr3rM/HQH2XsT7FovYZsguf 6Qx0ZidF3skHMZHKcycySR2bJj3d5BwZDr13vvp2tBZZDNOwg2taR/IIA== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvkedrkeekgdeitdcutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc fjughrpeffhffvvefukfhfgggtuggjsehgtderredttddvnecuhfhrohhmpefrrghtrhhi tghkucfuthgvihhnhhgrrhguthcuoehpshesphhkshdrihhmqeenucggtffrrghtthgvrh hnpeeukedtvedtffevleejtefgheehieegkeeluddvfeefgeehgfeltddtheejleffteen ucevlhhushhtvghrufhiiigvpedunecurfgrrhgrmhepmhgrihhlfhhrohhmpehpshesph hkshdrihhm X-ME-Proxy: Feedback-ID: i197146af:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 24 Oct 2023 09:11:22 -0400 (EDT) Received: by vm-mail (OpenSMTPD) with ESMTPSA id 232ddd98 (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Tue, 24 Oct 2023 13:11:17 +0000 (UTC) Date: Tue, 24 Oct 2023 15:11:20 +0200 From: Patrick Steinhardt To: git@vger.kernel.org Cc: Junio C Hamano , Eric Sunshine , Han-Wen Nienhuys Subject: [PATCH 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. Signed-off-by: Patrick Steinhardt --- Documentation/git-show-ref.txt | 5 ++++- builtin/show-ref.c | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Documentation/git-show-ref.txt b/Documentation/git-show-ref.txt index 2fe274b8faa..ab23e0b62e1 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' [-q | --quiet] [--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 diff --git a/builtin/show-ref.c b/builtin/show-ref.c index 10d0213e687..d0a32d07404 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 [-q | --quiet] [--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 Tue Oct 24 13:11:24 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 13434446 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 0A4882AB57 for ; Tue, 24 Oct 2023 13:11:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b="n1Q5CbBI"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="rMEO6iZP" Received: from wout4-smtp.messagingengine.com (wout4-smtp.messagingengine.com [64.147.123.20]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 172D9C1 for ; Tue, 24 Oct 2023 06:11:29 -0700 (PDT) Received: from compute3.internal (compute3.nyi.internal [10.202.2.43]) by mailout.west.internal (Postfix) with ESMTP id 482243200998; Tue, 24 Oct 2023 09:11:28 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute3.internal (MEProxy); Tue, 24 Oct 2023 09:11: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=1698153087; x=1698239487; bh=bc k707V/CsZyXnCQfr89GqMdUZnpBV6/h5yw4vkUKOM=; b=n1Q5CbBIGHcRwr7MCD yn43gtPhZwxX3WQJVtv+NjUd+toAvO76ykSTaDuE/lX75KCHa4vUzuzxCIzfLLLk uzLjcY3KNq0b5tL0rDCd3iBPneuPSFX3ltzrMGZ5gCo+3wJhLBwIGM0Il5vsuIG2 Uws1cy9Tc84QF9Xr6efU8lLRworikNSduhM6M5dfR6r8iDFU+um0UKYSClocPBLR U5ySJHKRDQn8KP7JSmOxbV7mLUKS6IrikwDK6od3IavPA0+lieFXh1mbMGliBiO0 QF5hIFgyCeWEyAhhCAEQbDt/Ib16UgGoEW5SCyJhhJi5Iqi2KwE4LVviYTzzaRxl Y4VQ== 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=1698153087; x=1698239487; bh=bck707V/CsZyX nCQfr89GqMdUZnpBV6/h5yw4vkUKOM=; b=rMEO6iZPJlz7dae+9SkQ1NhLNSoP/ aN2XVhxlKlXOKAbmrjyRs1AOrxLZh6rJLVKPTssKLaTKc8b7ZJo4GIXlDUynwo6j /g5OukptVBcO80/kdCTEGHzBG2+zjrMFXJqRzumRz+VX//BRFRxBzJ6o7c9FGpae rS0cdw/363CYEeydBTvdp2jxw5DnTgPNhanDayBS393Su4WP3o4cYnJnauS6meQk stJt7AAl/rRffnMxu42fGvGb2kg2YwtVfoSPtWNIk8ynEwN5JNPdlCT5qCeC98I/ tIPkKAac+GWk8XpZRkkA+D+q8jKnMjxeq4SoT9aSvZglTpz09s6NgTyPw== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvkedrkeekgdeitdcutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc fjughrpeffhffvvefukfhfgggtuggjsehgtderredttddvnecuhfhrohhmpefrrghtrhhi tghkucfuthgvihhnhhgrrhguthcuoehpshesphhkshdrihhmqeenucggtffrrghtthgvrh hnpeeukedtvedtffevleejtefgheehieegkeeluddvfeefgeehgfeltddtheejleffteen ucevlhhushhtvghrufhiiigvpedvnecurfgrrhgrmhepmhgrihhlfhhrohhmpehpshesph hkshdrihhm X-ME-Proxy: Feedback-ID: i197146af:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 24 Oct 2023 09:11:26 -0400 (EDT) Received: by vm-mail (OpenSMTPD) with ESMTPSA id 1f441da7 (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Tue, 24 Oct 2023 13:11:21 +0000 (UTC) Date: Tue, 24 Oct 2023 15:11:24 +0200 From: Patrick Steinhardt To: git@vger.kernel.org Cc: Junio C Hamano , Eric Sunshine , Han-Wen Nienhuys Subject: [PATCH 11/12] builtin/show-ref: add new mode to check for reference existence Message-ID: <2f876e61dd36a8887a1286bb8db9fb6577c55c9b.1698152926.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 whteher 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 gseems 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 error 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 | 47 ++++++++++++++++++++++-- t/t1403-show-ref.sh | 67 +++++++++++++++++++++++++++++++++- 3 files changed, 120 insertions(+), 5 deletions(-) diff --git a/Documentation/git-show-ref.txt b/Documentation/git-show-ref.txt index ab23e0b62e1..a7e9374bc2b 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 error code of 0 if + it does, 2 if it is missing, and 128 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 d0a32d07404..617e754bbed 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 }; @@ -214,6 +215,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 = 1; + + 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 { + error(_("failed to look up reference: %s"), strerror(failure_errno)); + } + + goto out; + } + + ret = 0; + +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; @@ -243,10 +279,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, @@ -272,13 +309,15 @@ 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 --exclude-existing or --verify can be given")); + if ((!!exclude_existing_opts.enabled + !!verify + !!exists) > 1) + die(_("only one of --exclude-existing, --exists or --verify can be given")); 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 3a312c8b27c..17eba350ce5 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 --exclude-existing, --exists or --verify can be given + EOF + test_must_fail git show-ref --verify --exclude-existing 2>err && - grep "only one of --exclude-existing or --verify 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 Tue Oct 24 13:11: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: 13434447 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 74E3B2941C for ; Tue, 24 Oct 2023 13:11:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b="TlP+T933"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="sXm2i5Qe" Received: from wout4-smtp.messagingengine.com (wout4-smtp.messagingengine.com [64.147.123.20]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7B513129 for ; Tue, 24 Oct 2023 06:11:33 -0700 (PDT) Received: from compute3.internal (compute3.nyi.internal [10.202.2.43]) by mailout.west.internal (Postfix) with ESMTP id B02863200946; Tue, 24 Oct 2023 09:11:32 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute3.internal (MEProxy); Tue, 24 Oct 2023 09:11:33 -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=1698153092; x=1698239492; bh=zz OH5ueITiZTBr1TZ6jNHry3ZIaZVc9wnVkZyZ5d64g=; b=TlP+T933/ltJdnPX4S mrJ/az6XF0kIwXRAML0pkLRs6zNK8B4n8OHOE2OWjK0CdIwy0ceUZEstFsf5JS4r CGXqsMfSF0ho91VPYXBvuXaNAgZ0DMQIKAOsFCcbKns9cxrfFqnA0ikZH8BevmPR SAy5c5uCSDwWNDiIkE5+X3T8CVbCuatyNdbXZu4ku3LDo2+LW6QP2MiMKTSO3/i/ D3IqozCHHCn+c0FDDV8yz1WV7U3NP8sILIyU1OGBJDJwFKFbPcK1STRRnDXNLGva Esr6s0vsEhtFxcy1xnO3WaS50GVi3pE0GxPr+79WjH/eHOfjRPjREoAvqesBPai1 qoMQ== 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=1698153092; x=1698239492; bh=zzOH5ueITiZTB r1TZ6jNHry3ZIaZVc9wnVkZyZ5d64g=; b=sXm2i5Qe551annuRcKZJ6wY/cleSI BPLH6TQltcv/b09mMgT1voznxorMtpgE+x34UqsffKlYUAiE3fygwxPIUQ0LUATJ Wq1BiFYcFGOqlv+3XKgvHOIEC4fD1GNJbS+niS0ekg1qZD3uI5u7RR9QibT5FL22 4VHx1R04pOSbtmu5a09Ubj0+LwPMy7jo3ORycpPaIfqZAILygXFKDY4+/+qh3Q5N AUyt2cUqnApDoMHkErSORmJxgqoDlndgMEuP94T0GAo46M7bkz02YOjviTYMD4pI ZaeuONOyDuy6lufas9NFN2iEFkh2903NOmRF6obgbdDi9M94oRmQh37vA== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvkedrkeekgdeitdcutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc fjughrpeffhffvvefukfhfgggtuggjsehgtderredttddvnecuhfhrohhmpefrrghtrhhi tghkucfuthgvihhnhhgrrhguthcuoehpshesphhkshdrihhmqeenucggtffrrghtthgvrh hnpeeukedtvedtffevleejtefgheehieegkeeluddvfeefgeehgfeltddtheejleffteen ucevlhhushhtvghrufhiiigvpeefnecurfgrrhgrmhepmhgrihhlfhhrohhmpehpshesph hkshdrihhm X-ME-Proxy: Feedback-ID: i197146af:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 24 Oct 2023 09:11:30 -0400 (EDT) Received: by vm-mail (OpenSMTPD) with ESMTPSA id 4041d07e (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Tue, 24 Oct 2023 13:11:26 +0000 (UTC) Date: Tue, 24 Oct 2023 15:11:29 +0200 From: Patrick Steinhardt To: git@vger.kernel.org Cc: Junio C Hamano , Eric Sunshine , Han-Wen Nienhuys Subject: [PATCH 12/12] t: use git-show-ref(1) to check for ref existence 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: 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