Re: Bug: git ls-files and ignored directories
- From
Junio C Hamano <gitster@pobox.com>
- Date
- Jun 1, 2012, 19:22 UTC
- Message-ID
- <7vvcja25ye.fsf@alter.siamese.dyndns.org>
- In-Reply-To
- <7vipfa3n0v.fsf@alter.siamese.dyndns.org>
Junio C Hamano <gitster@pobox.com> writes:
Show 8 quoted lines
> 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); }