Thread (1 message) 1 message, 1 author, 2016-06-15

Re: Bug: git ls-files and ignored directories

From: Junio C Hamano <hidden>
Date: 2016-06-15 22:53:58
Subsystem: the rest · Maintainer: Linus Torvalds

Possibly related (same subject, not in this thread)

Junio C Hamano [off-list ref] writes:
A naive and unoptimized implementation may look like this patch.

The "path_exclude_check" structure can be enhanced to record the
leading directory it has last checked to be known to be excluded so
that path_excluded() can check if the ce->name[] is still inside
that directory and return true early, but I'll leave it as an
exercise for interested readers while I look at other topics for the
upcoming release.
And an obvious and simple optimization would look like this.

We can keep the shallowest of the excluded directory (i.e. where a
traversing caller would have stopped recursing) in check->path, and
keep returning "Yes, it is excluded" as long as the path is inside
that directory.

 builtin/ls-files.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)
diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index 1385852..5beada0 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -218,11 +218,25 @@ static void path_exclude_check_clear(struct path_exclude_check *check)
 	strbuf_release(&check->path);
 }
 
+/*
+ * Is the ce->name excluded?  This is for a caller like show_files() that
+ * do not honor directory hierarchy and iterate through paths that are
+ * possibly in an ignored directory.
+ *
+ * A path to a directory known to be excluded is left in check->path to
+ * optimize for repeated checks for files in the same excluded directory.
+ */
 static int path_excluded(struct path_exclude_check *check, struct cache_entry *ce)
 {
 	int i, dtype;
 	struct strbuf *path = &check->path;
 
+	if (path->len &&
+	    path->len <= ce_namelen(ce) &&
+	    !memcmp(ce->name, path->buf, path->len) &&
+	    (!ce->name[path->len] || ce->name[path->len] == '/'))
+		return 1;
+
 	strbuf_setlen(path, 0);
 	for (i = 0; ce->name[i]; i++) {
 		int ch = ce->name[i];
@@ -234,6 +248,10 @@ static int path_excluded(struct path_exclude_check *check, struct cache_entry *c
 		}
 		strbuf_addch(path, ch);
 	}
+
+	/* An entry in the index; cannot be a directory with subentries */
+	strbuf_setlen(path, 0);
+
 	dtype = ce_to_dtype(ce);
 	return excluded(check->dir, ce->name, &dtype);
 }
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help