]> git.ipfire.org Git - thirdparty/git.git/commitdiff
untracked cache: invalidate dirs recursively if .gitignore changes
authorNguyễn Thái Ngọc Duy <pclouds@gmail.com>
Sun, 8 Mar 2015 10:12:27 +0000 (17:12 +0700)
committerJunio C Hamano <gitster@pobox.com>
Thu, 12 Mar 2015 20:45:15 +0000 (13:45 -0700)
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>
dir.c

diff --git a/dir.c b/dir.c
index a0654885b6d04a473c9296277746d5cf9e107e8a..ec7c49643af3573073d22d81b4e24a21c5e97091 100644 (file)
--- 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;