summaryrefslogtreecommitdiff
path: root/dir.c
diff options
context:
space:
mode:
authorNguyễn Thái Ngọc Duy <pclouds@gmail.com>2015-03-08 10:12:27 (GMT)
committerJunio C Hamano <gitster@pobox.com>2015-03-12 20:45:15 (GMT)
commit5ebf79ad4b308c678bd9623dd906c01bb0ab7e0f (patch)
tree89402f5f857bf8b3a04d06f2b5bd76ed412584ef /dir.c
parentccad261f07900b55029f3fd42a9ec8f17229808f (diff)
downloadgit-5ebf79ad4b308c678bd9623dd906c01bb0ab7e0f.zip
git-5ebf79ad4b308c678bd9623dd906c01bb0ab7e0f.tar.gz
git-5ebf79ad4b308c678bd9623dd906c01bb0ab7e0f.tar.bz2
untracked cache: invalidate dirs recursively if .gitignore changes
It's easy to see that if an existing .gitignore changes, its SHA-1 would be different and invalidate_gitignore() is called. If .gitignore is removed, add_excludes() will treat it like an empty .gitignore, which again should invalidate the cached directory data. if .gitignore is added, lookup_untracked() already fills initial .gitignore SHA-1 as "empty file", so again invalidate_gitignore() is called. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'dir.c')
-rw-r--r--dir.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/dir.c b/dir.c
index a065488..ec7c496 100644
--- a/dir.c
+++ b/dir.c
@@ -1011,7 +1011,23 @@ static void prep_exclude(struct dir_struct *dir, const char *base, int baselen)
add_excludes(el->src, el->src, stk->baselen, el, 1,
untracked ? &sha1_stat : NULL);
}
- if (untracked) {
+ /*
+ * NEEDSWORK: when untracked cache is enabled, prep_exclude()
+ * will first be called in valid_cached_dir() then maybe many
+ * times more in last_exclude_matching(). When the cache is
+ * used, last_exclude_matching() will not be called and
+ * reading .gitignore content will be a waste.
+ *
+ * So when it's called by valid_cached_dir() and we can get
+ * .gitignore SHA-1 from the index (i.e. .gitignore is not
+ * modified on work tree), we could delay reading the
+ * .gitignore content until we absolutely need it in
+ * last_exclude_matching(). Be careful about ignore rule
+ * order, though, if you do that.
+ */
+ if (untracked &&
+ hashcmp(sha1_stat.sha1, untracked->exclude_sha1)) {
+ invalidate_gitignore(dir->untracked, untracked);
hashcpy(untracked->exclude_sha1, sha1_stat.sha1);
}
dir->exclude_stack = stk;