Volume XXII, number 280Wednesday, October 7, 2026Latest message 51 minutes ago

The Git List

News and archive of git@vger.kernel.org, since April 2005

v2describe: fix --exclude, --match with --contains and --all

1 messages between Jun 1, 2026 and Jun 1, 2026, from Jacob Keller.

Plain Markdown or JSON for tools and agents. Diffs are folded; open one to read it.

Jacob KellerJun 1, 2026, 23:36 UTC on lore
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>
---
Changes in v2:
* Use check_describe for tests.
* Fix test which could return multiple answers by adding an additional
  exclude.
* Add a few additional tests around origin remote.
 builtin/describe.c  | 18 +++++++++++++++---
 t/t6120-describe.sh | 22 ++++++++++++++++++++++
 2 files changed, 37 insertions(+), 3 deletions(-)
Show changes to 2 files +37 −3

builtin/describe.c, t/t6120-describe.sh

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..4d72033e391d 100755
--- a/t/t6120-describe.sh
+++ b/t/t6120-describe.sh
@@ -359,6 +359,28 @@ test_expect_success 'describe --contains and --no-match' '
 	test_cmp expect actual
 '
 
+test_expect_success 'describe --contains --all --match no matching commit' '
+	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
+'
+
+check_describe "tags/A^0" --contains --all --match="A" $(git rev-parse "refs/tags/A^0")
+
+check_describe "branch_A" --contains --all --match="branch*" $(git rev-parse "refs/tags/A^0")
+
+check_describe "branch_C~1" --contains --all --match="branch*" --exclude="branch_A" $(git rev-parse "refs/tags/A^0")
+
+check_describe "branch_A" --contains --all \
+	--exclude="A" --exclude="c" --exclude="test*" --exclude="origin/remote_branch_A" \
+	$(git rev-parse "refs/tags/A^0")
+
+check_describe "remotes/origin/remote_branch_A" --contains --all --match="origin/remote*" $(git rev-parse "refs/tags/A^0")
+
+check_describe "remotes/origin/remote_branch_C~1" --contains --all \
+	--match="origin/remote*" --exclude="origin/remote_branch_A" \
+	$(git rev-parse "refs/tags/A^0")
+
 test_expect_success 'setup and absorb a submodule' '
 	test_create_repo sub1 &&
 	test_commit -C sub1 initial &&
-- 
2.54.0.633.g0ded84c31b89

Back to recent threads