untracked cache: don't open non-existent .gitignore

This cuts down a signficant number of open(.gitignore) because most directories usually don't have .gitignore files. 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 27b099ae8742f014700edba92036db288750e44a
1 file changed +25 -1
dir.c
+25 -1
@@ -1020,7 +1020,21 @@ static void prep_exclude(struct dir_struct *dir, const char *base, int baselen)
1020 /* Try to read per-directory file */
1021 hashclr(sha1_stat.sha1);
1022 sha1_stat.valid = 0;
1023 - if (dir->exclude_per_dir) {
1023 + if (dir->exclude_per_dir &&
1024 + /*
1025 + * If we know that no files have been added in
1026 + * this directory (i.e. valid_cached_dir() has
1027 + * been executed and set untracked->valid) ..
1028 + */
1029 + (!untracked || !untracked->valid ||
1030 + /*
1031 + * .. and .gitignore does not exist before
1032 + * (i.e. null exclude_sha1 and skip_worktree is
1033 + * not set). Then we can skip loading .gitignore,
1034 + * which would result in ENOENT anyway.
1035 + * skip_worktree is taken care in read_directory()
1036 + */
1037 + !is_null_sha1(untracked->exclude_sha1))) {
1038 /*
1039 * dir->basebuf gets reused by the traversal, but we
1040 * need fname to remain unchanged to ensure the src
@@ -1783,6 +1797,7 @@ static struct untracked_cache_dir *validate_untracked_cache(struct dir_struct *d
1797 const struct pathspec *pathspec)
1798 {
1799 struct untracked_cache_dir *root;
1800 + int i;
1801
1802 if (!dir->untracked)
1803 return NULL;
@@ -1834,6 +1849,15 @@ static struct untracked_cache_dir *validate_untracked_cache(struct dir_struct *d
1849 if (dir->exclude_list_group[EXC_CMDL].nr)
1850 return NULL;
1851
1852 + /*
1853 + * An optimization in prep_exclude() does not play well with
1854 + * CE_SKIP_WORKTREE. It's a rare case anyway, if a single
1855 + * entry has that bit set, disable the whole untracked cache.
1856 + */
1857 + for (i = 0; i < active_nr; i++)
1858 + if (ce_skip_worktree(active_cache[i]))
1859 + return NULL;
1860 +
1861 if (!dir->untracked->root) {
1862 const int len = sizeof(*dir->untracked->root);
1863 dir->untracked->root = xmalloc(len);