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);