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>
Nguyễn Thái Ngọc Duy committed
Mar 8, 2015 at 17:12 UTC
5ebf79ad4b308c678bd9623dd906c01bb0ab7e0f
1 file changed
+17
-1
dir.c
+17
-1
@@ -1011,7 +1011,23 @@ static void prep_exclude(struct dir_struct *dir, const char *base, int baselen)
1011
add_excludes(el->src, el->src, stk->baselen, el, 1,
1012
untracked ? &sha1_stat : NULL);
1013
}
1014
- if (untracked) {
1014
+ /*
1015
+ * NEEDSWORK: when untracked cache is enabled, prep_exclude()
1016
+ * will first be called in valid_cached_dir() then maybe many
1017
+ * times more in last_exclude_matching(). When the cache is
1018
+ * used, last_exclude_matching() will not be called and
1019
+ * reading .gitignore content will be a waste.
1020
+ *
1021
+ * So when it's called by valid_cached_dir() and we can get
1022
+ * .gitignore SHA-1 from the index (i.e. .gitignore is not
1023
+ * modified on work tree), we could delay reading the
1024
+ * .gitignore content until we absolutely need it in
1025
+ * last_exclude_matching(). Be careful about ignore rule
1026
+ * order, though, if you do that.
1027
+ */
1028
+ if (untracked &&
1029
+ hashcmp(sha1_stat.sha1, untracked->exclude_sha1)) {
1030
+ invalidate_gitignore(dir->untracked, untracked);
1031
hashcpy(untracked->exclude_sha1, sha1_stat.sha1);
1032
}
1033
dir->exclude_stack = stk;