git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 5/5] describe: teach describe negative pattern matches

From
Jacob Keller <jacob.e.keller@intel.com>
Date
Jan 12, 2017, 00:17 UTC
Message-ID
<20170112001721.2534-6-jacob.e.keller@intel.com>
In-Reply-To
<20170112001721.2534-1-jacob.e.keller@intel.com>
From: Jacob Keller <jacob.keller@gmail.com>

Teach git-describe the `--discard` option which will allow specifying a glob pattern of tags to ignore. This can be combined with the `--match` patterns to enable more flexibility in determining which tags to consider.

For example, suppose you wish to find the first official release tag that contains a certain commit. If we assume that official release tags are of the form "v*" and pre-release candidates include "*rc*" in their name, we can now find the first tag that introduces commit abcdef via:

  git describe --contains --match="v*" --discard="*rc*"
Add documentation and tests for this change.
Signed-off-by: Jacob Keller <jacob.keller@gmail.com>
---
 Documentation/git-describe.txt |  8 ++++++++
 builtin/describe.c             | 21 +++++++++++++++++++++
 t/t6120-describe.sh            |  8 ++++++++
 3 files changed, 37 insertions(+)
diff --git a/Documentation/git-describe.txt b/Documentation/git-describe.txt
index 7ad41e2f6ade..a89bbde207b2 100644
--- a/Documentation/git-describe.txt
+++ b/Documentation/git-describe.txt
@@ -88,6 +88,14 @@ OPTIONS
 	patterns will be considered. Use `--no-match` to clear and reset the
 	list of patterns.
 
+--discard <pattern>::
+	Do not consider tags matching the given `glob(7)` pattern, excluding
+	the "refs/tags/" prefix. This can be used to narrow the tag space and
+	find only tags matching some meaningful criteria. If given multiple
+	times, a list of patterns will be accumulated and tags matching any
+	of the patterns will be discarded. Use `--no-discard` to clear and
+	reset the list of patterns.
+
 --always::
 	Show uniquely abbreviated commit object as fallback.
 
diff --git a/builtin/describe.c b/builtin/describe.c
index 5cc9e9abe798..c09288ee6321 100644
--- a/builtin/describe.c
+++ b/builtin/describe.c
@@ -29,6 +29,7 @@ static int max_candidates = 10;
 static struct hashmap names;
 static int have_util;
 static struct string_list patterns = STRING_LIST_INIT_NODUP;
+static struct string_list discard_patterns = STRING_LIST_INIT_NODUP;
 static int always;
 static const char *dirty;
 
@@ -130,6 +131,22 @@ static int get_name(const char *path, const struct object_id *oid, int flag, voi
 		return 0;
 
 	/*
+	 * If we're given discard patterns, first discard any tag which match
+	 * any of the discard pattern.
+	 */
+	if (discard_patterns.nr) {
+		struct string_list_item *item;
+
+		if (!is_tag)
+			return 0;
+
+		for_each_string_list_item(item, &discard_patterns) {
+			if (!wildmatch(item->string, path + 10, 0, NULL))
+				return 0;
+		}
+	}
+
+	/*
 	 * If we're given patterns, accept only tags which match at least one
 	 * pattern.
 	 */
@@ -421,6 +438,8 @@ int cmd_describe(int argc, const char **argv, const char *prefix)
 			    N_("consider <n> most recent tags (default: 10)")),
 		OPT_STRING_LIST(0, "match", &patterns, N_("pattern"),
 			   N_("only consider tags matching <pattern>")),
+		OPT_STRING_LIST(0, "discard", &discard_patterns, N_("pattern"),
+			   N_("do not consider tags matching <pattern>")),
 		OPT_BOOL(0, "always",        &always,
 			N_("show abbreviated commit object as fallback")),
 		{OPTION_STRING, 0, "dirty",  &dirty, N_("mark"),
@@ -458,6 +477,8 @@ int cmd_describe(int argc, const char **argv, const char *prefix)
 			argv_array_push(&args, "--tags");
 			for_each_string_list_item(item, &patterns)
 				argv_array_pushf(&args, "--refs=refs/tags/%s", item->string);
+			for_each_string_list_item(item, &discard_patterns)
+				argv_array_pushf(&args, "--discard=refs/tags/%s", item->string);
 		}
 		if (argc)
 			argv_array_pushv(&args, argv);
diff --git a/t/t6120-describe.sh b/t/t6120-describe.sh
index 9e5db9b87a1f..4e4a9f2e5305 100755
--- a/t/t6120-describe.sh
+++ b/t/t6120-describe.sh
@@ -218,6 +218,14 @@ test_expect_success 'describe --contains and --match' '
 	test_cmp expect actual
 '
 
+test_expect_success 'describe --discard' '
+	echo "c~1" >expect &&
+	tagged_commit=$(git rev-parse "refs/tags/A^0") &&
+	test_must_fail git describe --contains --match="B" $tagged_commit &&
+	git describe --contains --match="?" --discard="A" $tagged_commit >actual &&
+	test_cmp expect actual
+'
+
 test_expect_success 'describe --contains and --no-match' '
 	echo "A^0" >expect &&
 	tagged_commit=$(git rev-parse "refs/tags/A^0") &&
-- 
2.11.0.403.g196674b8396b
Previous: Jacob KellerNext: Johannes Schindelin
Message 2 of 25 in “extend git-describe pattern matching”
  1. 0/5 extend git-describe pattern matchingJacob Keller, Jan 12, 2017
  2. 5/5 describe: teach describe negative pattern matchesJacob Keller, Jan 12, 2017
  3. Johannes SchindelinJan 12, 2017
  4. Junio C HamanoJan 12, 2017
  5. Johannes SixtJan 12, 2017
  6. Jacob KellerJan 13, 2017
  7. Johannes SixtJan 13, 2017
  8. Jacob KellerJan 13, 2017
  9. Johannes SixtJan 13, 2017
  10. Jacob KellerJan 17, 2017
  11. Johannes SchindelinJan 18, 2017
  12. Jacob KellerJan 18, 2017
  13. 4/5 describe: teach --match to accept multiple patternsJacob Keller, Jan 12, 2017
  14. 2/5 name-rev: extend --refs to accept multiple patternsJacob Keller, Jan 12, 2017
  15. Johannes SchindelinJan 12, 2017
  16. Jacob KellerJan 13, 2017
  17. 3/5 name-rev: add support to discard refs by pattern matchJacob Keller, Jan 12, 2017
  18. Johannes SchindelinJan 12, 2017
  19. Jacob KellerJan 13, 2017
  20. 1/5 doc: add documentation for OPT_STRING_LISTJacob Keller, Jan 12, 2017
  21. Johannes SchindelinJan 12, 2017
  22. Jacob KellerJan 13, 2017
  23. Johannes SchindelinJan 12, 2017
  24. Junio C HamanoJan 13, 2017
  25. Jacob KellerJan 13, 2017

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.