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

[PATCH 6/8] pathspec: turn on tries when appropriate

From
Toon Claes <toon@iotcl.com>
Date
Mar 26, 2025, 20:18 UTC
Message-ID
<20250326-toon-blame-tree-v1-6-4173133f3786@iotcl.com>
In-Reply-To
<20250326-toon-blame-tree-v1-0-4173133f3786@iotcl.com>
From: Jeff King <peff@peff.net>

An earlier commit introduced pathspec_tries, but we did not actually generate them by default. This patch causes us to do so when it is possible (i.e., when no wildcards or other pathspec magic are in use). This doesn't actually do anything yet, though, as none of the pathspec users have learned to make use of the tries.

We embed the pathspec_trie directly inside the "struct pathspec". This is not strictly necessary, as once created, the trie does not depend on the original pathspec. However, since the intended use is to optimize existing pathspec callers, passing the trie around as part of the pathspec will minimize disruption to the call chain.

Signed-off-by: Jeff King <peff@peff.net>
---
 pathspec.c               | 19 +++++++++++++++++++
 pathspec.h               |  1 +
 t/helper/test-pathspec.c |  6 ++----
 3 files changed, 22 insertions(+), 4 deletions(-)
diff --git a/pathspec.c b/pathspec.c
index 0e381fd748..c174edef32 100644
--- a/pathspec.c
+++ b/pathspec.c
@@ -117,6 +117,19 @@ struct pathspec_trie *pathspec_trie_build(const struct pathspec *pathspec)
 	return ret;
 }
 
+static void pathspec_trie_clear(struct pathspec_trie *t)
+{
+	if (t) {
+		for (size_t i = 0; i < t->nr; i++) {
+			pathspec_trie_clear(t->entries[i]);
+			FREE_AND_NULL(t->entries[i]);
+		}
+
+		t->nr = 0;
+		FREE_AND_NULL(t->entries);
+	}
+}
+
 int pathspec_trie_lookup(const struct pathspec_trie *parent,
 			 const char *path, size_t len)
 {
@@ -799,6 +812,8 @@ void parse_pathspec(struct pathspec *pathspec,
 			BUG("PATHSPEC_MAXDEPTH_VALID and PATHSPEC_KEEP_ORDER are incompatible");
 		QSORT(pathspec->items, pathspec->nr, pathspec_item_cmp);
 	}
+
+	pathspec->trie = pathspec_trie_build(pathspec);
 }
 
 void parse_pathspec_file(struct pathspec *pathspec, unsigned magic_mask,
@@ -859,6 +874,8 @@ void copy_pathspec(struct pathspec *dst, const struct pathspec *src)
 
 		d->attr_check = attr_check_dup(s->attr_check);
 	}
+
+	dst->trie = pathspec_trie_build(dst);
 }
 
 void clear_pathspec(struct pathspec *pathspec)
@@ -877,6 +894,8 @@ void clear_pathspec(struct pathspec *pathspec)
 			attr_check_free(pathspec->items[i].attr_check);
 	}
 
+	pathspec_trie_clear(pathspec->trie);
+	FREE_AND_NULL(pathspec->trie);
 	FREE_AND_NULL(pathspec->items);
 	pathspec->nr = 0;
 }
diff --git a/pathspec.h b/pathspec.h
index 71bafb78a9..ff11599d25 100644
--- a/pathspec.h
+++ b/pathspec.h
@@ -76,6 +76,7 @@ struct pathspec {
 		} *attr_match;
 		struct attr_check *attr_check;
 	} *items;
+	struct pathspec_trie *trie;
 };
 
 #define GUARD_PATHSPEC(ps, mask) \
diff --git a/t/helper/test-pathspec.c b/t/helper/test-pathspec.c
index c04417681f..72e335abc1 100644
--- a/t/helper/test-pathspec.c
+++ b/t/helper/test-pathspec.c
@@ -63,7 +63,6 @@ static int cmd_trie(const char **argv)
 {
 	const char **specs, **paths;
 	struct pathspec pathspec;
-	struct pathspec_trie *trie;
 
 	paths = specs = argv;
 	while (*paths && strcmp(*paths, "--"))
@@ -72,12 +71,11 @@ static int cmd_trie(const char **argv)
 		*paths++ = NULL;
 
 	parse_pathspec(&pathspec, 0, 0, "", specs);
-	trie = pathspec_trie_build(&pathspec);
-	if (!trie)
+	if (!pathspec.trie)
 		die("unable to make trie from pathspec");
 
 	for (; *paths; paths++) {
-		if (trie_match(trie, *paths))
+		if (trie_match(pathspec.trie, *paths))
 			printf("yes\n");
 		else
 			printf("no\n");
-- 
2.49.0.rc2
Previous: Toon ClaesNext: Toon Claes
Message 7 of 15 in “Introduce git-blame-tree(1) command”
  1. 0/8 Introduce git-blame-tree(1) commandToon Claes, Mar 26, 2025
  2. 1/8 combine-diff: zero memory used for callback filepairsToon Claes, Mar 26, 2025
  3. 2/8 within_depth: fix return for empty pathToon Claes, Mar 26, 2025
  4. 3/8 diff: teach tree-diff a max-depth parameterToon Claes, Mar 26, 2025
  5. 4/8 blame-tree: introduce new subcommand to blame filesToon Claes, Mar 26, 2025
  6. 5/8 pathspec: add optional trie indexToon Claes, Mar 26, 2025
  7. 6/8 pathspec: turn on tries when appropriateToon Claes, Mar 26, 2025
  8. 7/8 tree-diff: use pathspec triesToon Claes, Mar 26, 2025
  9. 8/8 blame-tree: narrow pathspec as we traverseToon Claes, Mar 26, 2025
  10. Taylor BlauMar 26, 2025
  11. Jeff KingMar 27, 2025
  12. Taylor BlauMar 27, 2025
  13. Toon ClaesMar 28, 2025
  14. Jeff KingApr 1, 2025
  15. Derrick StoleeMar 27, 2025

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.