Re: Bug: git ls-files and ignored directories

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Junio C Hamano <gitster@xxxxxxxxx> 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);
 }
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]