From: Jacob Keller <jacob.e.keller@intel.com>
To: <git@vger.kernel.org>
Cc: Junio C Hamano <gitster@pobox.com>,
Jacob Keller <jacob.keller@gmail.com>,
Tuomas Ahola <taahol@utu.fi>
Subject: [PATCH] describe: fix --exclude, --match with --contains and --all
Date: Thu, 28 May 2026 16:29:51 -0700 [thread overview]
Message-ID: <20260528232950.187002-2-jacob.e.keller@intel.com> (raw)
From: Jacob Keller <jacob.keller@gmail.com>
git describe --contains acts as a wrapper around git name-rev. When
operating with --contains and --all, the --match and --exclude patterns
are not properly forwarded to name-rev as --exclude and --refs options.
This results in the command silently discarding match and exclude
requests from the user when operating in --all mode.
We could check and die() if the user provides --contains, --all, and
--match/--exclude. However, its also straight forward to just pass the
filters down to git name-rev.
Notice that the documentation for --match and --exclude mention the
--all mode. It explains that they operate on refs with the prefix
refs/tags, and additionally refs/heads and refs/remotes when using
--all.
Fix the describe logic to pass the patterns down with the appropriate
prefixes when --all is provided. This fixes the support to match the
documented behavior.
Add tests to check that this works as expected.
Reported-by: Tuomas Ahola <taahol@utu.fi>
Signed-off-by: Jacob Keller <jacob.keller@gmail.com>
---
I was looking into reviving the patch that just added a simple die() and
realized that its actually pretty straight forward to just fix the support
instead. I'm open to either route, if we think this support isn't
necessary... I'm not sure if there are any gotchas or other issues with how
I implemented this.
builtin/describe.c | 18 +++++++++++++++---
t/t6120-describe.sh | 29 +++++++++++++++++++++++++++++
2 files changed, 44 insertions(+), 3 deletions(-)
diff --git a/builtin/describe.c b/builtin/describe.c
index 1c47d7c0b7c3..faaf44cec573 100644
--- a/builtin/describe.c
+++ b/builtin/describe.c
@@ -712,13 +712,25 @@ int cmd_describe(int argc,
NULL);
if (always)
strvec_push(&args, "--always");
- if (!all) {
+ if (!all)
strvec_push(&args, "--tags");
+
+ for_each_string_list_item(item, &patterns)
+ strvec_pushf(&args, "--refs=refs/tags/%s", item->string);
+ for_each_string_list_item(item, &exclude_patterns)
+ strvec_pushf(&args, "--exclude=refs/tags/%s", item->string);
+
+ if (all) {
for_each_string_list_item(item, &patterns)
- strvec_pushf(&args, "--refs=refs/tags/%s", item->string);
+ strvec_pushf(&args, "--refs=refs/heads/%s", item->string);
for_each_string_list_item(item, &exclude_patterns)
- strvec_pushf(&args, "--exclude=refs/tags/%s", item->string);
+ strvec_pushf(&args, "--exclude=refs/heads/%s", item->string);
+ for_each_string_list_item(item, &patterns)
+ strvec_pushf(&args, "--refs=refs/remotes/%s", item->string);
+ for_each_string_list_item(item, &exclude_patterns)
+ strvec_pushf(&args, "--exclude=refs/remotes/%s", item->string);
}
+
if (argc)
strvec_pushv(&args, argv);
else
diff --git a/t/t6120-describe.sh b/t/t6120-describe.sh
index 8ee3d2c37d02..f46e628d6a1a 100755
--- a/t/t6120-describe.sh
+++ b/t/t6120-describe.sh
@@ -359,6 +359,35 @@ test_expect_success 'describe --contains and --no-match' '
test_cmp expect actual
'
+test_expect_success 'describe --contains --all --match' '
+ echo "tags/A^0" >expect &&
+ tagged_commit=$(git rev-parse "refs/tags/A^0") &&
+ test_must_fail git describe --contains --all --match="B" $tagged_commit >actual &&
+ git describe --contains --all --match="A" $tagged_commit >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'describe --contains --all --match branch' '
+ echo "branch_A" >expect &&
+ tagged_commit=$(git rev-parse "refs/tags/A^0") &&
+ git describe --contains --all --match="branch*" $tagged_commit >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'describe --contains --all --match and --exclude' '
+ echo "branch_C~1" >expect &&
+ tagged_commit=$(git rev-parse "refs/tags/A^0") &&
+ git describe --contains --all --match="branch*" --exclude="branch_A" $tagged_commit >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'describe --contains --all --exclude' '
+ echo "branch_A" >expect &&
+ tagged_commit=$(git rev-parse "refs/tags/A^0") &&
+ git describe --contains --all --exclude="A" --exclude="c" --exclude="test*" $tagged_commit >actual &&
+ test_cmp expect actual
+'
+
test_expect_success 'setup and absorb a submodule' '
test_create_repo sub1 &&
test_commit -C sub1 initial &&
--
2.54.0.633.g0ded84c31b89
next reply other threads:[~2026-05-28 23:31 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-28 23:29 Jacob Keller [this message]
2026-05-30 23:47 ` [PATCH] describe: fix --exclude, --match with --contains and --all Junio C Hamano
2026-05-31 23:46 ` Tuomas Ahola
2026-06-01 0:40 ` Junio C Hamano
2026-06-01 22:35 ` Jacob Keller
2026-06-02 0:10 ` Junio C Hamano
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260528232950.187002-2-jacob.e.keller@intel.com \
--to=jacob.e.keller@intel.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=jacob.keller@gmail.com \
--cc=taahol@utu.fi \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox