{"thread":{"id":"45882","subject":"[RFC 01/14] dir: stop using the index compatibility macros","startedAt":"2017-05-05T19:53:57Z","lastAt":"2017-05-08T18:01:00Z","messageCount":18,"participants":["Brandon Williams","Junio C Hamano","Jeff Hostetler"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"318881","messageId":"20170505195334.121856-2-bmwill@google.com","threadId":"45882","inReplyTo":"20170505195334.121856-1-bmwill@google.com","subject":"[RFC 01/14] dir: stop using the index compatibility macros","fromName":"Brandon Williams","fromEmail":"bmwill@google.com","sentAt":"2017-05-05T19:53:21Z","receivedAt":"2017-05-05T19:53:57Z","isPatch":false,"sender":{"key":"bwilliams.eng@gmail.com","avatar":null},"body":"In order to make it clearer where the_index is being referenced, stop\nusing the index compatibility macros in dir.c.  This is to make it\neasier to identify the functions which need to be convert to taking in a\n'struct index_state' as a parameter.\n\nThe end goal would be to eliminate the need to reference global index\nstate in dir.c.\n\nSigned-off-by: Brandon Williams <bmwill@google.com>\n---\n dir.c | 41 +++++++++++++++++++++--------------------\n 1 file changed, 21 insertions(+), 20 deletions(-)\n\ndiff --git a/dir.c b/dir.c\nindex f451bfa48..97eadd45e 100644\n--- a/dir.c\n+++ b/dir.c\n@@ -7,6 +7,7 @@\n  * Copyright (C) Linus Torvalds, 2005-2006\n  *\t\t Junio Hamano, 2005-2006\n  */\n+#define NO_THE_INDEX_COMPATIBILITY_MACROS\n #include \"cache.h\"\n #include \"dir.h\"\n #include \"attr.h\"\n@@ -596,12 +597,12 @@ static void *read_skip_worktree_file_from_index(const char *path, size_t *size,\n \tvoid *data;\n \n \tlen = strlen(path);\n-\tpos = cache_name_pos(path, len);\n+\tpos = index_name_pos(&the_index, path, len);\n \tif (pos < 0)\n \t\treturn NULL;\n-\tif (!ce_skip_worktree(active_cache[pos]))\n+\tif (!ce_skip_worktree(the_index.cache[pos]))\n \t\treturn NULL;\n-\tdata = read_sha1_file(active_cache[pos]->oid.hash, &type, &sz);\n+\tdata = read_sha1_file(the_index.cache[pos]->oid.hash, &type, &sz);\n \tif (!data || type != OBJ_BLOB) {\n \t\tfree(data);\n \t\treturn NULL;\n@@ -609,7 +610,7 @@ static void *read_skip_worktree_file_from_index(const char *path, size_t *size,\n \t*size = xsize_t(sz);\n \tif (sha1_stat) {\n \t\tmemset(&sha1_stat->stat, 0, sizeof(sha1_stat->stat));\n-\t\thashcpy(sha1_stat->sha1, active_cache[pos]->oid.hash);\n+\t\thashcpy(sha1_stat->sha1, the_index.cache[pos]->oid.hash);\n \t}\n \treturn data;\n }\n@@ -785,12 +786,12 @@ static int add_excludes(const char *fname, const char *base, int baselen,\n \t\t\t    !match_stat_data_racy(&the_index, &sha1_stat->stat, &st))\n \t\t\t\t; /* no content change, ss->sha1 still good */\n \t\t\telse if (check_index &&\n-\t\t\t\t (pos = cache_name_pos(fname, strlen(fname))) >= 0 &&\n-\t\t\t\t !ce_stage(active_cache[pos]) &&\n-\t\t\t\t ce_uptodate(active_cache[pos]) &&\n+\t\t\t\t (pos = index_name_pos(&the_index, fname, strlen(fname))) >= 0 &&\n+\t\t\t\t !ce_stage(the_index.cache[pos]) &&\n+\t\t\t\t ce_uptodate(the_index.cache[pos]) &&\n \t\t\t\t !would_convert_to_git(fname))\n \t\t\t\thashcpy(sha1_stat->sha1,\n-\t\t\t\t\tactive_cache[pos]->oid.hash);\n+\t\t\t\t\tthe_index.cache[pos]->oid.hash);\n \t\t\telse\n \t\t\t\thash_sha1_file(buf, size, \"blob\", sha1_stat->sha1);\n \t\t\tfill_stat_data(&sha1_stat->stat, &st);\n@@ -1235,7 +1236,7 @@ static struct dir_entry *dir_entry_new(const char *pathname, int len)\n \n static struct dir_entry *dir_add_name(struct dir_struct *dir, const char *pathname, int len)\n {\n-\tif (cache_file_exists(pathname, len, ignore_case))\n+\tif (index_file_exists(&the_index, pathname, len, ignore_case))\n \t\treturn NULL;\n \n \tALLOC_GROW(dir->entries, dir->nr+1, dir->alloc);\n@@ -1244,7 +1245,7 @@ static struct dir_entry *dir_add_name(struct dir_struct *dir, const char *pathna\n \n struct dir_entry *dir_add_ignored(struct dir_struct *dir, const char *pathname, int len)\n {\n-\tif (!cache_name_is_other(pathname, len))\n+\tif (!index_name_is_other(&the_index, pathname, len))\n \t\treturn NULL;\n \n \tALLOC_GROW(dir->ignored, dir->ignored_nr+1, dir->ignored_alloc);\n@@ -1266,10 +1267,10 @@ static enum exist_status directory_exists_in_index_icase(const char *dirname, in\n {\n \tstruct cache_entry *ce;\n \n-\tif (cache_dir_exists(dirname, len))\n+\tif (index_dir_exists(&the_index, dirname, len))\n \t\treturn index_directory;\n \n-\tce = cache_file_exists(dirname, len, ignore_case);\n+\tce = index_file_exists(&the_index, dirname, len, ignore_case);\n \tif (ce && S_ISGITLINK(ce->ce_mode))\n \t\treturn index_gitdir;\n \n@@ -1290,11 +1291,11 @@ static enum exist_status directory_exists_in_index(const char *dirname, int len)\n \tif (ignore_case)\n \t\treturn directory_exists_in_index_icase(dirname, len);\n \n-\tpos = cache_name_pos(dirname, len);\n+\tpos = index_name_pos(&the_index, dirname, len);\n \tif (pos < 0)\n \t\tpos = -pos-1;\n-\twhile (pos < active_nr) {\n-\t\tconst struct cache_entry *ce = active_cache[pos++];\n+\twhile (pos < the_index.cache_nr) {\n+\t\tconst struct cache_entry *ce = the_index.cache[pos++];\n \t\tunsigned char endchar;\n \n \t\tif (strncmp(ce->name, dirname, len))\n@@ -1460,7 +1461,7 @@ static int get_index_dtype(const char *path, int len)\n \tint pos;\n \tconst struct cache_entry *ce;\n \n-\tce = cache_file_exists(path, len, 0);\n+\tce = index_file_exists(&the_index, path, len, 0);\n \tif (ce) {\n \t\tif (!ce_uptodate(ce))\n \t\t\treturn DT_UNKNOWN;\n@@ -1474,12 +1475,12 @@ static int get_index_dtype(const char *path, int len)\n \t}\n \n \t/* Try to look it up as a directory */\n-\tpos = cache_name_pos(path, len);\n+\tpos = index_name_pos(&the_index, path, len);\n \tif (pos >= 0)\n \t\treturn DT_UNKNOWN;\n \tpos = -pos-1;\n-\twhile (pos < active_nr) {\n-\t\tce = active_cache[pos++];\n+\twhile (pos < the_index.cache_nr) {\n+\t\tce = the_index.cache[pos++];\n \t\tif (strncmp(ce->name, path, len))\n \t\t\tbreak;\n \t\tif (ce->name[len] > '/')\n@@ -1522,7 +1523,7 @@ static enum path_treatment treat_one_path(struct dir_struct *dir,\n \t\t\t\t\t  int dtype, struct dirent *de)\n {\n \tint exclude;\n-\tint has_path_in_index = !!cache_file_exists(path->buf, path->len, ignore_case);\n+\tint has_path_in_index = !!index_file_exists(&the_index, path->buf, path->len, ignore_case);\n \n \tif (dtype == DT_UNKNOWN)\n \t\tdtype = get_dtype(de, path->buf, path->len);\n-- \n2.13.0.rc1.294.g07d810a77f-goog\n\n"},{"id":"318882","messageId":"20170505195334.121856-3-bmwill@google.com","threadId":"45882","inReplyTo":"20170505195334.121856-1-bmwill@google.com","subject":"[RFC 02/14] dir: convert read_skip_worktree_file_from_index to take an index","fromName":"Brandon Williams","fromEmail":"bmwill@google.com","sentAt":"2017-05-05T19:53:22Z","receivedAt":"2017-05-05T19:53:59Z","isPatch":false,"sender":{"key":"bwilliams.eng@gmail.com","avatar":null},"body":"Signed-off-by: Brandon Williams <bmwill@google.com>\n---\n dir.c | 13 +++++++------\n 1 file changed, 7 insertions(+), 6 deletions(-)\n\ndiff --git a/dir.c b/dir.c\nindex 97eadd45e..44307b963 100644\n--- a/dir.c\n+++ b/dir.c\n@@ -588,7 +588,8 @@ void add_exclude(const char *string, const char *base,\n \tx->el = el;\n }\n \n-static void *read_skip_worktree_file_from_index(const char *path, size_t *size,\n+static void *read_skip_worktree_file_from_index(const struct index_state *istate,\n+\t\t\t\t\t\tconst char *path, size_t *size,\n \t\t\t\t\t\tstruct sha1_stat *sha1_stat)\n {\n \tint pos, len;\n@@ -597,12 +598,12 @@ static void *read_skip_worktree_file_from_index(const char *path, size_t *size,\n \tvoid *data;\n \n \tlen = strlen(path);\n-\tpos = index_name_pos(&the_index, path, len);\n+\tpos = index_name_pos(istate, path, len);\n \tif (pos < 0)\n \t\treturn NULL;\n-\tif (!ce_skip_worktree(the_index.cache[pos]))\n+\tif (!ce_skip_worktree(istate->cache[pos]))\n \t\treturn NULL;\n-\tdata = read_sha1_file(the_index.cache[pos]->oid.hash, &type, &sz);\n+\tdata = read_sha1_file(istate->cache[pos]->oid.hash, &type, &sz);\n \tif (!data || type != OBJ_BLOB) {\n \t\tfree(data);\n \t\treturn NULL;\n@@ -610,7 +611,7 @@ static void *read_skip_worktree_file_from_index(const char *path, size_t *size,\n \t*size = xsize_t(sz);\n \tif (sha1_stat) {\n \t\tmemset(&sha1_stat->stat, 0, sizeof(sha1_stat->stat));\n-\t\thashcpy(sha1_stat->sha1, the_index.cache[pos]->oid.hash);\n+\t\thashcpy(sha1_stat->sha1, istate->cache[pos]->oid.hash);\n \t}\n \treturn data;\n }\n@@ -751,7 +752,7 @@ static int add_excludes(const char *fname, const char *base, int baselen,\n \t\tif (0 <= fd)\n \t\t\tclose(fd);\n \t\tif (!check_index ||\n-\t\t    (buf = read_skip_worktree_file_from_index(fname, &size, sha1_stat)) == NULL)\n+\t\t    (buf = read_skip_worktree_file_from_index(&the_index, fname, &size, sha1_stat)) == NULL)\n \t\t\treturn -1;\n \t\tif (size == 0) {\n \t\t\tfree(buf);\n-- \n2.13.0.rc1.294.g07d810a77f-goog\n\n"},{"id":"318883","messageId":"20170505195334.121856-5-bmwill@google.com","threadId":"45882","inReplyTo":"20170505195334.121856-1-bmwill@google.com","subject":"[RFC 04/14] dir: convert get_dtype to take index","fromName":"Brandon Williams","fromEmail":"bmwill@google.com","sentAt":"2017-05-05T19:53:24Z","receivedAt":"2017-05-05T19:54:00Z","isPatch":false,"sender":{"key":"bwilliams.eng@gmail.com","avatar":null},"body":"Signed-off-by: Brandon Williams <bmwill@google.com>\n---\n dir.c | 23 +++++++++++++----------\n 1 file changed, 13 insertions(+), 10 deletions(-)\n\ndiff --git a/dir.c b/dir.c\nindex 5c635198d..4515f0083 100644\n--- a/dir.c\n+++ b/dir.c\n@@ -48,7 +48,8 @@ struct cached_dir {\n static enum path_treatment read_directory_recursive(struct dir_struct *dir,\n \tconst char *path, int len, struct untracked_cache_dir *untracked,\n \tint check_only, const struct pathspec *pathspec);\n-static int get_dtype(struct dirent *de, const char *path, int len);\n+static int get_dtype(struct dirent *de, struct index_state *istate,\n+\t\t     const char *path, int len);\n \n int fspathcmp(const char *a, const char *b)\n {\n@@ -975,7 +976,7 @@ static struct exclude *last_exclude_matching_from_list(const char *pathname,\n \n \t\tif (x->flags & EXC_FLAG_MUSTBEDIR) {\n \t\t\tif (*dtype == DT_UNKNOWN)\n-\t\t\t\t*dtype = get_dtype(NULL, pathname, pathlen);\n+\t\t\t\t*dtype = get_dtype(NULL, &the_index, pathname, pathlen);\n \t\t\tif (*dtype != DT_DIR)\n \t\t\t\tcontinue;\n \t\t}\n@@ -1459,12 +1460,13 @@ static int exclude_matches_pathspec(const char *path, int pathlen,\n \treturn 0;\n }\n \n-static int get_index_dtype(const char *path, int len)\n+static int get_index_dtype(struct index_state *istate,\n+\t\t\t   const char *path, int len)\n {\n \tint pos;\n \tconst struct cache_entry *ce;\n \n-\tce = index_file_exists(&the_index, path, len, 0);\n+\tce = index_file_exists(istate, path, len, 0);\n \tif (ce) {\n \t\tif (!ce_uptodate(ce))\n \t\t\treturn DT_UNKNOWN;\n@@ -1478,12 +1480,12 @@ static int get_index_dtype(const char *path, int len)\n \t}\n \n \t/* Try to look it up as a directory */\n-\tpos = index_name_pos(&the_index, path, len);\n+\tpos = index_name_pos(istate, path, len);\n \tif (pos >= 0)\n \t\treturn DT_UNKNOWN;\n \tpos = -pos-1;\n-\twhile (pos < the_index.cache_nr) {\n-\t\tce = the_index.cache[pos++];\n+\twhile (pos < istate->cache_nr) {\n+\t\tce = istate->cache[pos++];\n \t\tif (strncmp(ce->name, path, len))\n \t\t\tbreak;\n \t\tif (ce->name[len] > '/')\n@@ -1497,14 +1499,15 @@ static int get_index_dtype(const char *path, int len)\n \treturn DT_UNKNOWN;\n }\n \n-static int get_dtype(struct dirent *de, const char *path, int len)\n+static int get_dtype(struct dirent *de, struct index_state *istate,\n+\t\t     const char *path, int len)\n {\n \tint dtype = de ? DTYPE(de) : DT_UNKNOWN;\n \tstruct stat st;\n \n \tif (dtype != DT_UNKNOWN)\n \t\treturn dtype;\n-\tdtype = get_index_dtype(path, len);\n+\tdtype = get_index_dtype(istate, path, len);\n \tif (dtype != DT_UNKNOWN)\n \t\treturn dtype;\n \tif (lstat(path, &st))\n@@ -1529,7 +1532,7 @@ static enum path_treatment treat_one_path(struct dir_struct *dir,\n \tint has_path_in_index = !!index_file_exists(&the_index, path->buf, path->len, ignore_case);\n \n \tif (dtype == DT_UNKNOWN)\n-\t\tdtype = get_dtype(de, path->buf, path->len);\n+\t\tdtype = get_dtype(de, &the_index, path->buf, path->len);\n \n \t/* Always exclude indexed files */\n \tif (dtype != DT_DIR && has_path_in_index)\n-- \n2.13.0.rc1.294.g07d810a77f-goog\n\n"},{"id":"318884","messageId":"20170505195334.121856-6-bmwill@google.com","threadId":"45882","inReplyTo":"20170505195334.121856-1-bmwill@google.com","subject":"[RFC 05/14] dir: convert dir_add* to take an index","fromName":"Brandon Williams","fromEmail":"bmwill@google.com","sentAt":"2017-05-05T19:53:25Z","receivedAt":"2017-05-05T19:54:02Z","isPatch":false,"sender":{"key":"bwilliams.eng@gmail.com","avatar":null},"body":"Signed-off-by: Brandon Williams <bmwill@google.com>\n---\n builtin/add.c |  3 ++-\n dir.c         | 18 +++++++++++-------\n dir.h         |  4 +++-\n 3 files changed, 16 insertions(+), 9 deletions(-)\n\ndiff --git a/builtin/add.c b/builtin/add.c\nindex 9f53f020d..bf5e676e4 100644\n--- a/builtin/add.c\n+++ b/builtin/add.c\n@@ -437,7 +437,8 @@ int cmd_add(int argc, const char **argv, const char *prefix)\n \t\t\t\tif (ignore_missing) {\n \t\t\t\t\tint dtype = DT_UNKNOWN;\n \t\t\t\t\tif (is_excluded(&dir, path, &dtype))\n-\t\t\t\t\t\tdir_add_ignored(&dir, path, pathspec.items[i].len);\n+\t\t\t\t\t\tdir_add_ignored(&dir, &the_index,\n+\t\t\t\t\t\t\t\tpath, pathspec.items[i].len);\n \t\t\t\t} else\n \t\t\t\t\tdie(_(\"pathspec '%s' did not match any files\"),\n \t\t\t\t\t    pathspec.items[i].original);\ndiff --git a/dir.c b/dir.c\nindex 4515f0083..a508e8076 100644\n--- a/dir.c\n+++ b/dir.c\n@@ -1236,18 +1236,22 @@ static struct dir_entry *dir_entry_new(const char *pathname, int len)\n \treturn ent;\n }\n \n-static struct dir_entry *dir_add_name(struct dir_struct *dir, const char *pathname, int len)\n+static struct dir_entry *dir_add_name(struct dir_struct *dir,\n+\t\t\t\t      struct index_state *istate,\n+\t\t\t\t      const char *pathname, int len)\n {\n-\tif (index_file_exists(&the_index, pathname, len, ignore_case))\n+\tif (index_file_exists(istate, pathname, len, ignore_case))\n \t\treturn NULL;\n \n \tALLOC_GROW(dir->entries, dir->nr+1, dir->alloc);\n \treturn dir->entries[dir->nr++] = dir_entry_new(pathname, len);\n }\n \n-struct dir_entry *dir_add_ignored(struct dir_struct *dir, const char *pathname, int len)\n+struct dir_entry *dir_add_ignored(struct dir_struct *dir,\n+\t\t\t\t  struct index_state *istate,\n+\t\t\t\t  const char *pathname, int len)\n {\n-\tif (!index_name_is_other(&the_index, pathname, len))\n+\tif (!index_name_is_other(istate, pathname, len))\n \t\treturn NULL;\n \n \tALLOC_GROW(dir->ignored, dir->ignored_nr+1, dir->ignored_alloc);\n@@ -1819,18 +1823,18 @@ static enum path_treatment read_directory_recursive(struct dir_struct *dir,\n \t\tswitch (state) {\n \t\tcase path_excluded:\n \t\t\tif (dir->flags & DIR_SHOW_IGNORED)\n-\t\t\t\tdir_add_name(dir, path.buf, path.len);\n+\t\t\t\tdir_add_name(dir, &the_index, path.buf, path.len);\n \t\t\telse if ((dir->flags & DIR_SHOW_IGNORED_TOO) ||\n \t\t\t\t((dir->flags & DIR_COLLECT_IGNORED) &&\n \t\t\t\texclude_matches_pathspec(path.buf, path.len,\n \t\t\t\t\t\t\t pathspec)))\n-\t\t\t\tdir_add_ignored(dir, path.buf, path.len);\n+\t\t\t\tdir_add_ignored(dir, &the_index, path.buf, path.len);\n \t\t\tbreak;\n \n \t\tcase path_untracked:\n \t\t\tif (dir->flags & DIR_SHOW_IGNORED)\n \t\t\t\tbreak;\n-\t\t\tdir_add_name(dir, path.buf, path.len);\n+\t\t\tdir_add_name(dir, &the_index, path.buf, path.len);\n \t\t\tif (cdir.fdir)\n \t\t\t\tadd_untracked(untracked, path.buf + baselen);\n \t\t\tbreak;\ndiff --git a/dir.h b/dir.h\nindex bf23a470a..a9f809983 100644\n--- a/dir.h\n+++ b/dir.h\n@@ -219,7 +219,9 @@ extern int read_directory(struct dir_struct *, const char *path, int len, const\n \n extern int is_excluded_from_list(const char *pathname, int pathlen, const char *basename,\n \t\t\t\t int *dtype, struct exclude_list *el);\n-struct dir_entry *dir_add_ignored(struct dir_struct *dir, const char *pathname, int len);\n+struct dir_entry *dir_add_ignored(struct dir_struct *dir,\n+\t\t\t\t  struct index_state *istate,\n+\t\t\t\t  const char *pathname, int len);\n \n /*\n  * these implement the matching logic for dir.c:excluded_from_list and\n-- \n2.13.0.rc1.294.g07d810a77f-goog\n\n"},{"id":"318885","messageId":"20170505195334.121856-7-bmwill@google.com","threadId":"45882","inReplyTo":"20170505195334.121856-1-bmwill@google.com","subject":"[RFC 06/14] dir: convert last_exclude_matching_from_list to take an index","fromName":"Brandon Williams","fromEmail":"bmwill@google.com","sentAt":"2017-05-05T19:53:26Z","receivedAt":"2017-05-05T19:54:03Z","isPatch":false,"sender":{"key":"bwilliams.eng@gmail.com","avatar":null},"body":"Signed-off-by: Brandon Williams <bmwill@google.com>\n---\n dir.c | 13 ++++++++-----\n 1 file changed, 8 insertions(+), 5 deletions(-)\n\ndiff --git a/dir.c b/dir.c\nindex a508e8076..077b756c2 100644\n--- a/dir.c\n+++ b/dir.c\n@@ -961,7 +961,8 @@ static struct exclude *last_exclude_matching_from_list(const char *pathname,\n \t\t\t\t\t\t       int pathlen,\n \t\t\t\t\t\t       const char *basename,\n \t\t\t\t\t\t       int *dtype,\n-\t\t\t\t\t\t       struct exclude_list *el)\n+\t\t\t\t\t\t       struct exclude_list *el,\n+\t\t\t\t\t\t       struct index_state *istate)\n {\n \tstruct exclude *exc = NULL; /* undecided */\n \tint i;\n@@ -976,7 +977,7 @@ static struct exclude *last_exclude_matching_from_list(const char *pathname,\n \n \t\tif (x->flags & EXC_FLAG_MUSTBEDIR) {\n \t\t\tif (*dtype == DT_UNKNOWN)\n-\t\t\t\t*dtype = get_dtype(NULL, &the_index, pathname, pathlen);\n+\t\t\t\t*dtype = get_dtype(NULL, istate, pathname, pathlen);\n \t\t\tif (*dtype != DT_DIR)\n \t\t\t\tcontinue;\n \t\t}\n@@ -1012,13 +1013,14 @@ int is_excluded_from_list(const char *pathname,\n \t\t\t  struct exclude_list *el)\n {\n \tstruct exclude *exclude;\n-\texclude = last_exclude_matching_from_list(pathname, pathlen, basename, dtype, el);\n+\texclude = last_exclude_matching_from_list(pathname, pathlen, basename, dtype, el, &the_index);\n \tif (exclude)\n \t\treturn exclude->flags & EXC_FLAG_NEGATIVE ? 0 : 1;\n \treturn -1; /* undecided */\n }\n \n static struct exclude *last_exclude_matching_from_lists(struct dir_struct *dir,\n+\t\t\t\t\t\t\tstruct index_state *istate,\n \t\tconst char *pathname, int pathlen, const char *basename,\n \t\tint *dtype_p)\n {\n@@ -1030,7 +1032,7 @@ static struct exclude *last_exclude_matching_from_lists(struct dir_struct *dir,\n \t\tfor (j = group->nr - 1; j >= 0; j--) {\n \t\t\texclude = last_exclude_matching_from_list(\n \t\t\t\tpathname, pathlen, basename, dtype_p,\n-\t\t\t\t&group->el[j]);\n+\t\t\t\t&group->el[j], istate);\n \t\t\tif (exclude)\n \t\t\t\treturn exclude;\n \t\t}\n@@ -1121,6 +1123,7 @@ static void prep_exclude(struct dir_struct *dir, const char *base, int baselen)\n \t\t\tint dt = DT_DIR;\n \t\t\tdir->basebuf.buf[stk->baselen - 1] = 0;\n \t\t\tdir->exclude = last_exclude_matching_from_lists(dir,\n+\t\t\t\t\t\t\t\t\t&the_index,\n \t\t\t\tdir->basebuf.buf, stk->baselen - 1,\n \t\t\t\tdir->basebuf.buf + current, &dt);\n \t\t\tdir->basebuf.buf[stk->baselen - 1] = '/';\n@@ -1209,7 +1212,7 @@ struct exclude *last_exclude_matching(struct dir_struct *dir,\n \tif (dir->exclude)\n \t\treturn dir->exclude;\n \n-\treturn last_exclude_matching_from_lists(dir, pathname, pathlen,\n+\treturn last_exclude_matching_from_lists(dir, &the_index, pathname, pathlen,\n \t\t\tbasename, dtype_p);\n }\n \n-- \n2.13.0.rc1.294.g07d810a77f-goog\n\n"},{"id":"318886","messageId":"20170505195334.121856-8-bmwill@google.com","threadId":"45882","inReplyTo":"20170505195334.121856-1-bmwill@google.com","subject":"[RFC 07/14] dir: convert is_excluded_from_list to take an index","fromName":"Brandon Williams","fromEmail":"bmwill@google.com","sentAt":"2017-05-05T19:53:27Z","receivedAt":"2017-05-05T19:54:06Z","isPatch":false,"sender":{"key":"bwilliams.eng@gmail.com","avatar":null},"body":"Signed-off-by: Brandon Williams <bmwill@google.com>\n---\n dir.c          | 5 +++--\n dir.h          | 6 ++++--\n unpack-trees.c | 4 ++--\n 3 files changed, 9 insertions(+), 6 deletions(-)\n\ndiff --git a/dir.c b/dir.c\nindex 077b756c2..497a2db85 100644\n--- a/dir.c\n+++ b/dir.c\n@@ -1010,10 +1010,11 @@ static struct exclude *last_exclude_matching_from_list(const char *pathname,\n  */\n int is_excluded_from_list(const char *pathname,\n \t\t\t  int pathlen, const char *basename, int *dtype,\n-\t\t\t  struct exclude_list *el)\n+\t\t\t  struct exclude_list *el, struct index_state *istate)\n {\n \tstruct exclude *exclude;\n-\texclude = last_exclude_matching_from_list(pathname, pathlen, basename, dtype, el, &the_index);\n+\texclude = last_exclude_matching_from_list(pathname, pathlen, basename,\n+\t\t\t\t\t\t  dtype, el, istate);\n \tif (exclude)\n \t\treturn exclude->flags & EXC_FLAG_NEGATIVE ? 0 : 1;\n \treturn -1; /* undecided */\ndiff --git a/dir.h b/dir.h\nindex a9f809983..64254c7e7 100644\n--- a/dir.h\n+++ b/dir.h\n@@ -217,8 +217,10 @@ extern int within_depth(const char *name, int namelen, int depth, int max_depth)\n extern int fill_directory(struct dir_struct *dir, const struct pathspec *pathspec);\n extern int read_directory(struct dir_struct *, const char *path, int len, const struct pathspec *pathspec);\n \n-extern int is_excluded_from_list(const char *pathname, int pathlen, const char *basename,\n-\t\t\t\t int *dtype, struct exclude_list *el);\n+extern int is_excluded_from_list(const char *pathname, int pathlen,\n+\t\t\t\t const char *basename, int *dtype,\n+\t\t\t\t struct exclude_list *el,\n+\t\t\t\t struct index_state *istate);\n struct dir_entry *dir_add_ignored(struct dir_struct *dir,\n \t\t\t\t  struct index_state *istate,\n \t\t\t\t  const char *pathname, int len);\ndiff --git a/unpack-trees.c b/unpack-trees.c\nindex 6b7356dab..9bcb13e4f 100644\n--- a/unpack-trees.c\n+++ b/unpack-trees.c\n@@ -1040,7 +1040,7 @@ static int clear_ce_flags_dir(struct cache_entry **cache, int nr,\n \tstruct cache_entry **cache_end;\n \tint dtype = DT_DIR;\n \tint ret = is_excluded_from_list(prefix->buf, prefix->len,\n-\t\t\t\t\tbasename, &dtype, el);\n+\t\t\t\t\tbasename, &dtype, el, &the_index);\n \tint rc;\n \n \tstrbuf_addch(prefix, '/');\n@@ -1143,7 +1143,7 @@ static int clear_ce_flags_1(struct cache_entry **cache, int nr,\n \t\t/* Non-directory */\n \t\tdtype = ce_to_dtype(ce);\n \t\tret = is_excluded_from_list(ce->name, ce_namelen(ce),\n-\t\t\t\t\t    name, &dtype, el);\n+\t\t\t\t\t    name, &dtype, el, &the_index);\n \t\tif (ret < 0)\n \t\t\tret = defval;\n \t\tif (ret > 0)\n-- \n2.13.0.rc1.294.g07d810a77f-goog\n\n"},{"id":"318887","messageId":"20170505195334.121856-13-bmwill@google.com","threadId":"45882","inReplyTo":"20170505195334.121856-1-bmwill@google.com","subject":"[RFC 12/14] dir: convert read_directory_recursive to take an index","fromName":"Brandon Williams","fromEmail":"bmwill@google.com","sentAt":"2017-05-05T19:53:32Z","receivedAt":"2017-05-05T19:54:11Z","isPatch":false,"sender":{"key":"bwilliams.eng@gmail.com","avatar":null},"body":"Signed-off-by: Brandon Williams <bmwill@google.com>\n---\n dir.c | 52 +++++++++++++++++++++++++++++-----------------------\n 1 file changed, 29 insertions(+), 23 deletions(-)\n\ndiff --git a/dir.c b/dir.c\nindex f08d30ee4..3318ebbcb 100644\n--- a/dir.c\n+++ b/dir.c\n@@ -46,7 +46,8 @@ struct cached_dir {\n };\n \n static enum path_treatment read_directory_recursive(struct dir_struct *dir,\n-\tconst char *path, int len, struct untracked_cache_dir *untracked,\n+\tstruct index_state *istate, const char *path, int len,\n+\tstruct untracked_cache_dir *untracked,\n \tint check_only, const struct pathspec *pathspec);\n static int get_dtype(struct dirent *de, struct index_state *istate,\n \t\t     const char *path, int len);\n@@ -1362,12 +1363,13 @@ static enum exist_status directory_exists_in_index(struct index_state *istate,\n  *  (c) otherwise, we recurse into it.\n  */\n static enum path_treatment treat_directory(struct dir_struct *dir,\n+\tstruct index_state *istate,\n \tstruct untracked_cache_dir *untracked,\n \tconst char *dirname, int len, int baselen, int exclude,\n \tconst struct pathspec *pathspec)\n {\n \t/* The \"len-1\" is to strip the final '/' */\n-\tswitch (directory_exists_in_index(&the_index, dirname, len-1)) {\n+\tswitch (directory_exists_in_index(istate, dirname, len-1)) {\n \tcase index_directory:\n \t\treturn path_recurse;\n \n@@ -1392,7 +1394,7 @@ static enum path_treatment treat_directory(struct dir_struct *dir,\n \n \tuntracked = lookup_untracked(dir->untracked, untracked,\n \t\t\t\t     dirname + baselen, len - baselen);\n-\treturn read_directory_recursive(dir, dirname, len,\n+\treturn read_directory_recursive(dir, istate, dirname, len,\n \t\t\t\t\tuntracked, 1, pathspec);\n }\n \n@@ -1536,16 +1538,17 @@ static int get_dtype(struct dirent *de, struct index_state *istate,\n \n static enum path_treatment treat_one_path(struct dir_struct *dir,\n \t\t\t\t\t  struct untracked_cache_dir *untracked,\n+\t\t\t\t\t  struct index_state *istate,\n \t\t\t\t\t  struct strbuf *path,\n \t\t\t\t\t  int baselen,\n \t\t\t\t\t  const struct pathspec *pathspec,\n \t\t\t\t\t  int dtype, struct dirent *de)\n {\n \tint exclude;\n-\tint has_path_in_index = !!index_file_exists(&the_index, path->buf, path->len, ignore_case);\n+\tint has_path_in_index = !!index_file_exists(istate, path->buf, path->len, ignore_case);\n \n \tif (dtype == DT_UNKNOWN)\n-\t\tdtype = get_dtype(de, &the_index, path->buf, path->len);\n+\t\tdtype = get_dtype(de, istate, path->buf, path->len);\n \n \t/* Always exclude indexed files */\n \tif (dtype != DT_DIR && has_path_in_index)\n@@ -1572,10 +1575,10 @@ static enum path_treatment treat_one_path(struct dir_struct *dir,\n \tif ((dir->flags & DIR_COLLECT_KILLED_ONLY) &&\n \t    (dtype == DT_DIR) &&\n \t    !has_path_in_index &&\n-\t    (directory_exists_in_index(&the_index, path->buf, path->len) == index_nonexistent))\n+\t    (directory_exists_in_index(istate, path->buf, path->len) == index_nonexistent))\n \t\treturn path_none;\n \n-\texclude = is_excluded(dir, &the_index, path->buf, &dtype);\n+\texclude = is_excluded(dir, istate, path->buf, &dtype);\n \n \t/*\n \t * Excluded? If we don't explicitly want to show\n@@ -1589,7 +1592,7 @@ static enum path_treatment treat_one_path(struct dir_struct *dir,\n \t\treturn path_none;\n \tcase DT_DIR:\n \t\tstrbuf_addch(path, '/');\n-\t\treturn treat_directory(dir, untracked, path->buf, path->len,\n+\t\treturn treat_directory(dir, istate, untracked, path->buf, path->len,\n \t\t\t\t       baselen, exclude, pathspec);\n \tcase DT_REG:\n \tcase DT_LNK:\n@@ -1600,6 +1603,7 @@ static enum path_treatment treat_one_path(struct dir_struct *dir,\n static enum path_treatment treat_path_fast(struct dir_struct *dir,\n \t\t\t\t\t   struct untracked_cache_dir *untracked,\n \t\t\t\t\t   struct cached_dir *cdir,\n+\t\t\t\t\t   struct index_state *istate,\n \t\t\t\t\t   struct strbuf *path,\n \t\t\t\t\t   int baselen,\n \t\t\t\t\t   const struct pathspec *pathspec)\n@@ -1618,7 +1622,7 @@ static enum path_treatment treat_path_fast(struct dir_struct *dir,\n \t\t * to its bottom. Verify again the same set of directories\n \t\t * with check_only set.\n \t\t */\n-\t\treturn read_directory_recursive(dir, path->buf, path->len,\n+\t\treturn read_directory_recursive(dir, istate, path->buf, path->len,\n \t\t\t\t\t\tcdir->ucd, 1, pathspec);\n \t/*\n \t * We get path_recurse in the first run when\n@@ -1632,6 +1636,7 @@ static enum path_treatment treat_path_fast(struct dir_struct *dir,\n static enum path_treatment treat_path(struct dir_struct *dir,\n \t\t\t\t      struct untracked_cache_dir *untracked,\n \t\t\t\t      struct cached_dir *cdir,\n+\t\t\t\t      struct index_state *istate,\n \t\t\t\t      struct strbuf *path,\n \t\t\t\t      int baselen,\n \t\t\t\t      const struct pathspec *pathspec)\n@@ -1640,7 +1645,7 @@ static enum path_treatment treat_path(struct dir_struct *dir,\n \tstruct dirent *de = cdir->de;\n \n \tif (!de)\n-\t\treturn treat_path_fast(dir, untracked, cdir, path,\n+\t\treturn treat_path_fast(dir, untracked, cdir, istate, path,\n \t\t\t\t       baselen, pathspec);\n \tif (is_dot_or_dotdot(de->d_name) || !strcmp(de->d_name, \".git\"))\n \t\treturn path_none;\n@@ -1650,7 +1655,7 @@ static enum path_treatment treat_path(struct dir_struct *dir,\n \t\treturn path_none;\n \n \tdtype = DTYPE(de);\n-\treturn treat_one_path(dir, untracked, path, baselen, pathspec, dtype, de);\n+\treturn treat_one_path(dir, untracked, istate, path, baselen, pathspec, dtype, de);\n }\n \n static void add_untracked(struct untracked_cache_dir *dir, const char *name)\n@@ -1781,9 +1786,9 @@ static void close_cached_dir(struct cached_dir *cdir)\n  * Returns the most significant path_treatment value encountered in the scan.\n  */\n static enum path_treatment read_directory_recursive(struct dir_struct *dir,\n-\t\t\t\t    const char *base, int baselen,\n-\t\t\t\t    struct untracked_cache_dir *untracked, int check_only,\n-\t\t\t\t    const struct pathspec *pathspec)\n+\tstruct index_state *istate, const char *base, int baselen,\n+\tstruct untracked_cache_dir *untracked, int check_only,\n+\tconst struct pathspec *pathspec)\n {\n \tstruct cached_dir cdir;\n \tenum path_treatment state, subdir_state, dir_state = path_none;\n@@ -1791,7 +1796,7 @@ static enum path_treatment read_directory_recursive(struct dir_struct *dir,\n \n \tstrbuf_add(&path, base, baselen);\n \n-\tif (open_cached_dir(&cdir, dir, untracked, &the_index, &path, check_only))\n+\tif (open_cached_dir(&cdir, dir, untracked, istate, &path, check_only))\n \t\tgoto out;\n \n \tif (untracked)\n@@ -1799,7 +1804,7 @@ static enum path_treatment read_directory_recursive(struct dir_struct *dir,\n \n \twhile (!read_cached_dir(&cdir)) {\n \t\t/* check how the file or directory should be treated */\n-\t\tstate = treat_path(dir, untracked, &cdir, &path,\n+\t\tstate = treat_path(dir, untracked, &cdir, istate, &path,\n \t\t\t\t   baselen, pathspec);\n \n \t\tif (state > dir_state)\n@@ -1812,7 +1817,7 @@ static enum path_treatment read_directory_recursive(struct dir_struct *dir,\n \t\t\t\t\t      path.buf + baselen,\n \t\t\t\t\t      path.len - baselen);\n \t\t\tsubdir_state =\n-\t\t\t\tread_directory_recursive(dir, path.buf,\n+\t\t\t\tread_directory_recursive(dir, istate, path.buf,\n \t\t\t\t\t\t\t path.len, ud,\n \t\t\t\t\t\t\t check_only, pathspec);\n \t\t\tif (subdir_state > dir_state)\n@@ -1834,18 +1839,18 @@ static enum path_treatment read_directory_recursive(struct dir_struct *dir,\n \t\tswitch (state) {\n \t\tcase path_excluded:\n \t\t\tif (dir->flags & DIR_SHOW_IGNORED)\n-\t\t\t\tdir_add_name(dir, &the_index, path.buf, path.len);\n+\t\t\t\tdir_add_name(dir, istate, path.buf, path.len);\n \t\t\telse if ((dir->flags & DIR_SHOW_IGNORED_TOO) ||\n \t\t\t\t((dir->flags & DIR_COLLECT_IGNORED) &&\n \t\t\t\texclude_matches_pathspec(path.buf, path.len,\n \t\t\t\t\t\t\t pathspec)))\n-\t\t\t\tdir_add_ignored(dir, &the_index, path.buf, path.len);\n+\t\t\t\tdir_add_ignored(dir, istate, path.buf, path.len);\n \t\t\tbreak;\n \n \t\tcase path_untracked:\n \t\t\tif (dir->flags & DIR_SHOW_IGNORED)\n \t\t\t\tbreak;\n-\t\t\tdir_add_name(dir, &the_index, path.buf, path.len);\n+\t\t\tdir_add_name(dir, istate, path.buf, path.len);\n \t\t\tif (cdir.fdir)\n \t\t\t\tadd_untracked(untracked, path.buf + baselen);\n \t\t\tbreak;\n@@ -1870,6 +1875,7 @@ static int cmp_name(const void *p1, const void *p2)\n }\n \n static int treat_leading_path(struct dir_struct *dir,\n+\t\t\t      struct index_state *istate,\n \t\t\t      const char *path, int len,\n \t\t\t      const struct pathspec *pathspec)\n {\n@@ -1897,7 +1903,7 @@ static int treat_leading_path(struct dir_struct *dir,\n \t\t\tbreak;\n \t\tif (simplify_away(sb.buf, sb.len, pathspec))\n \t\t\tbreak;\n-\t\tif (treat_one_path(dir, NULL, &sb, baselen, pathspec,\n+\t\tif (treat_one_path(dir, NULL, istate, &sb, baselen, pathspec,\n \t\t\t\t   DT_DIR, NULL) == path_none)\n \t\t\tbreak; /* do not recurse into it */\n \t\tif (len <= baselen) {\n@@ -2080,8 +2086,8 @@ int read_directory(struct dir_struct *dir, const char *path,\n \t\t * e.g. prep_exclude()\n \t\t */\n \t\tdir->untracked = NULL;\n-\tif (!len || treat_leading_path(dir, path, len, pathspec))\n-\t\tread_directory_recursive(dir, path, len, untracked, 0, pathspec);\n+\tif (!len || treat_leading_path(dir, &the_index, path, len, pathspec))\n+\t\tread_directory_recursive(dir, &the_index, path, len, untracked, 0, pathspec);\n \tQSORT(dir->entries, dir->nr, cmp_name);\n \tQSORT(dir->ignored, dir->ignored_nr, cmp_name);\n \tif (dir->untracked) {\n-- \n2.13.0.rc1.294.g07d810a77f-goog\n\n"},{"id":"318888","messageId":"20170505195334.121856-15-bmwill@google.com","threadId":"45882","inReplyTo":"20170505195334.121856-1-bmwill@google.com","subject":"[RFC 14/14] dir: convert fill_directory to take an index","fromName":"Brandon Williams","fromEmail":"bmwill@google.com","sentAt":"2017-05-05T19:53:34Z","receivedAt":"2017-05-05T19:54:13Z","isPatch":false,"sender":{"key":"bwilliams.eng@gmail.com","avatar":null},"body":"Signed-off-by: Brandon Williams <bmwill@google.com>\n---\n builtin/add.c      | 2 +-\n builtin/clean.c    | 2 +-\n builtin/grep.c     | 2 +-\n builtin/ls-files.c | 2 +-\n dir.c              | 6 ++++--\n dir.h              | 4 +++-\n wt-status.c        | 2 +-\n 7 files changed, 12 insertions(+), 8 deletions(-)\n\ndiff --git a/builtin/add.c b/builtin/add.c\nindex 0b52aeced..36cad00ae 100644\n--- a/builtin/add.c\n+++ b/builtin/add.c\n@@ -400,7 +400,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)\n \t\t}\n \n \t\t/* This picks up the paths that are not tracked */\n-\t\tbaselen = fill_directory(&dir, &pathspec);\n+\t\tbaselen = fill_directory(&dir, &the_index, &pathspec);\n \t\tif (pathspec.nr)\n \t\t\tseen = prune_directory(&dir, &pathspec, baselen);\n \t}\ndiff --git a/builtin/clean.c b/builtin/clean.c\nindex 39866afab..329b68c40 100644\n--- a/builtin/clean.c\n+++ b/builtin/clean.c\n@@ -930,7 +930,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)\n \t\t       PATHSPEC_PREFER_CWD,\n \t\t       prefix, argv);\n \n-\tfill_directory(&dir, &pathspec);\n+\tfill_directory(&dir, &the_index, &pathspec);\n \n \tfor (i = 0; i < dir.nr; i++) {\n \t\tstruct dir_entry *ent = dir.entries[i];\ndiff --git a/builtin/grep.c b/builtin/grep.c\nindex 65070c52f..ca1344133 100644\n--- a/builtin/grep.c\n+++ b/builtin/grep.c\n@@ -866,7 +866,7 @@ static int grep_directory(struct grep_opt *opt, const struct pathspec *pathspec,\n \tif (exc_std)\n \t\tsetup_standard_excludes(&dir);\n \n-\tfill_directory(&dir, pathspec);\n+\tfill_directory(&dir, &the_index, pathspec);\n \tfor (i = 0; i < dir.nr; i++) {\n \t\tif (!dir_path_match(dir.entries[i], pathspec, 0, NULL))\n \t\t\tcontinue;\ndiff --git a/builtin/ls-files.c b/builtin/ls-files.c\nindex ccba227e2..239c18a1f 100644\n--- a/builtin/ls-files.c\n+++ b/builtin/ls-files.c\n@@ -326,7 +326,7 @@ static void show_files(struct dir_struct *dir)\n \tif (show_others || show_killed) {\n \t\tif (!show_others)\n \t\t\tdir->flags |= DIR_COLLECT_KILLED_ONLY;\n-\t\tfill_directory(dir, &pathspec);\n+\t\tfill_directory(dir, &the_index, &pathspec);\n \t\tif (show_others)\n \t\t\tshow_other_files(dir);\n \t\tif (show_killed)\ndiff --git a/dir.c b/dir.c\nindex 4eb8cb6a2..3f3167e55 100644\n--- a/dir.c\n+++ b/dir.c\n@@ -177,7 +177,9 @@ char *common_prefix(const struct pathspec *pathspec)\n \treturn len ? xmemdupz(pathspec->items[0].match, len) : NULL;\n }\n \n-int fill_directory(struct dir_struct *dir, const struct pathspec *pathspec)\n+int fill_directory(struct dir_struct *dir,\n+\t\t   struct index_state *istate,\n+\t\t   const struct pathspec *pathspec)\n {\n \tconst char *prefix;\n \tsize_t prefix_len;\n@@ -190,7 +192,7 @@ int fill_directory(struct dir_struct *dir, const struct pathspec *pathspec)\n \tprefix = prefix_len ? pathspec->items[0].match : \"\";\n \n \t/* Read the directory and prune it */\n-\tread_directory(dir, &the_index, prefix, prefix_len, pathspec);\n+\tread_directory(dir, istate, prefix, prefix_len, pathspec);\n \n \treturn prefix_len;\n }\ndiff --git a/dir.h b/dir.h\nindex a23bcd005..17d110693 100644\n--- a/dir.h\n+++ b/dir.h\n@@ -214,7 +214,9 @@ extern int match_pathspec(const struct pathspec *pathspec,\n extern int report_path_error(const char *ps_matched, const struct pathspec *pathspec, const char *prefix);\n extern int within_depth(const char *name, int namelen, int depth, int max_depth);\n \n-extern int fill_directory(struct dir_struct *dir, const struct pathspec *pathspec);\n+extern int fill_directory(struct dir_struct *dir,\n+\t\t\t  struct index_state *istate,\n+\t\t\t  const struct pathspec *pathspec);\n extern int read_directory(struct dir_struct *, struct index_state *istate,\n \t\t\t  const char *path, int len,\n \t\t\t  const struct pathspec *pathspec);\ndiff --git a/wt-status.c b/wt-status.c\nindex 308cf3779..9e2d03cd9 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -652,7 +652,7 @@ static void wt_status_collect_untracked(struct wt_status *s)\n \t\tdir.untracked = the_index.untracked;\n \tsetup_standard_excludes(&dir);\n \n-\tfill_directory(&dir, &s->pathspec);\n+\tfill_directory(&dir, &the_index, &s->pathspec);\n \n \tfor (i = 0; i < dir.nr; i++) {\n \t\tstruct dir_entry *ent = dir.entries[i];\n-- \n2.13.0.rc1.294.g07d810a77f-goog\n\n"},{"id":"318889","messageId":"20170505195334.121856-14-bmwill@google.com","threadId":"45882","inReplyTo":"20170505195334.121856-1-bmwill@google.com","subject":"[RFC 13/14] dir: convert read_directory to take an index","fromName":"Brandon Williams","fromEmail":"bmwill@google.com","sentAt":"2017-05-05T19:53:33Z","receivedAt":"2017-05-05T19:54:14Z","isPatch":false,"sender":{"key":"bwilliams.eng@gmail.com","avatar":null},"body":"Signed-off-by: Brandon Williams <bmwill@google.com>\n---\n dir.c          | 16 ++++++++--------\n dir.h          |  4 +++-\n unpack-trees.c |  2 +-\n 3 files changed, 12 insertions(+), 10 deletions(-)\n\ndiff --git a/dir.c b/dir.c\nindex 3318ebbcb..4eb8cb6a2 100644\n--- a/dir.c\n+++ b/dir.c\n@@ -190,7 +190,7 @@ int fill_directory(struct dir_struct *dir, const struct pathspec *pathspec)\n \tprefix = prefix_len ? pathspec->items[0].match : \"\";\n \n \t/* Read the directory and prune it */\n-\tread_directory(dir, prefix, prefix_len, pathspec);\n+\tread_directory(dir, &the_index, prefix, prefix_len, pathspec);\n \n \treturn prefix_len;\n }\n@@ -2071,8 +2071,8 @@ static struct untracked_cache_dir *validate_untracked_cache(struct dir_struct *d\n \treturn root;\n }\n \n-int read_directory(struct dir_struct *dir, const char *path,\n-\t\t   int len, const struct pathspec *pathspec)\n+int read_directory(struct dir_struct *dir, struct index_state *istate,\n+\t\t   const char *path, int len, const struct pathspec *pathspec)\n {\n \tstruct untracked_cache_dir *untracked;\n \n@@ -2086,8 +2086,8 @@ int read_directory(struct dir_struct *dir, const char *path,\n \t\t * e.g. prep_exclude()\n \t\t */\n \t\tdir->untracked = NULL;\n-\tif (!len || treat_leading_path(dir, &the_index, path, len, pathspec))\n-\t\tread_directory_recursive(dir, &the_index, path, len, untracked, 0, pathspec);\n+\tif (!len || treat_leading_path(dir, istate, path, len, pathspec))\n+\t\tread_directory_recursive(dir, istate, path, len, untracked, 0, pathspec);\n \tQSORT(dir->entries, dir->nr, cmp_name);\n \tQSORT(dir->ignored, dir->ignored_nr, cmp_name);\n \tif (dir->untracked) {\n@@ -2101,12 +2101,12 @@ int read_directory(struct dir_struct *dir, const char *path,\n \t\t\t\t dir->untracked->gitignore_invalidated,\n \t\t\t\t dir->untracked->dir_invalidated,\n \t\t\t\t dir->untracked->dir_opened);\n-\t\tif (dir->untracked == the_index.untracked &&\n+\t\tif (dir->untracked == istate->untracked &&\n \t\t    (dir->untracked->dir_opened ||\n \t\t     dir->untracked->gitignore_invalidated ||\n \t\t     dir->untracked->dir_invalidated))\n-\t\t\tthe_index.cache_changed |= UNTRACKED_CHANGED;\n-\t\tif (dir->untracked != the_index.untracked) {\n+\t\t\tistate->cache_changed |= UNTRACKED_CHANGED;\n+\t\tif (dir->untracked != istate->untracked) {\n \t\t\tfree(dir->untracked);\n \t\t\tdir->untracked = NULL;\n \t\t}\ndiff --git a/dir.h b/dir.h\nindex b745f1e5d..a23bcd005 100644\n--- a/dir.h\n+++ b/dir.h\n@@ -215,7 +215,9 @@ extern int report_path_error(const char *ps_matched, const struct pathspec *path\n extern int within_depth(const char *name, int namelen, int depth, int max_depth);\n \n extern int fill_directory(struct dir_struct *dir, const struct pathspec *pathspec);\n-extern int read_directory(struct dir_struct *, const char *path, int len, const struct pathspec *pathspec);\n+extern int read_directory(struct dir_struct *, struct index_state *istate,\n+\t\t\t  const char *path, int len,\n+\t\t\t  const struct pathspec *pathspec);\n \n extern int is_excluded_from_list(const char *pathname, int pathlen,\n \t\t\t\t const char *basename, int *dtype,\ndiff --git a/unpack-trees.c b/unpack-trees.c\nindex abdd2922b..48d9cf921 100644\n--- a/unpack-trees.c\n+++ b/unpack-trees.c\n@@ -1564,7 +1564,7 @@ static int verify_clean_subdirectory(const struct cache_entry *ce,\n \tmemset(&d, 0, sizeof(d));\n \tif (o->dir)\n \t\td.exclude_per_dir = o->dir->exclude_per_dir;\n-\ti = read_directory(&d, pathbuf, namelen+1, NULL);\n+\ti = read_directory(&d, &the_index, pathbuf, namelen+1, NULL);\n \tif (i)\n \t\treturn o->gently ? -1 :\n \t\t\tadd_rejected_path(o, ERROR_NOT_UPTODATE_DIR, ce->name);\n-- \n2.13.0.rc1.294.g07d810a77f-goog\n\n"},{"id":"318890","messageId":"20170505195334.121856-11-bmwill@google.com","threadId":"45882","inReplyTo":"20170505195334.121856-1-bmwill@google.com","subject":"[RFC 10/14] dir: convert is_excluded to take an index","fromName":"Brandon Williams","fromEmail":"bmwill@google.com","sentAt":"2017-05-05T19:53:30Z","receivedAt":"2017-05-05T19:54:17Z","isPatch":false,"sender":{"key":"bwilliams.eng@gmail.com","avatar":null},"body":"Signed-off-by: Brandon Williams <bmwill@google.com>\n---\n builtin/add.c          |  2 +-\n builtin/check-ignore.c |  3 ++-\n builtin/clean.c        |  2 +-\n builtin/ls-files.c     |  2 +-\n dir.c                  | 16 +++++++++-------\n dir.h                  |  5 ++++-\n unpack-trees.c         |  2 +-\n 7 files changed, 19 insertions(+), 13 deletions(-)\n\ndiff --git a/builtin/add.c b/builtin/add.c\nindex bf5e676e4..0b52aeced 100644\n--- a/builtin/add.c\n+++ b/builtin/add.c\n@@ -436,7 +436,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)\n \t\t\t     !file_exists(path))) {\n \t\t\t\tif (ignore_missing) {\n \t\t\t\t\tint dtype = DT_UNKNOWN;\n-\t\t\t\t\tif (is_excluded(&dir, path, &dtype))\n+\t\t\t\t\tif (is_excluded(&dir, &the_index, path, &dtype))\n \t\t\t\t\t\tdir_add_ignored(&dir, &the_index,\n \t\t\t\t\t\t\t\tpath, pathspec.items[i].len);\n \t\t\t\t} else\ndiff --git a/builtin/check-ignore.c b/builtin/check-ignore.c\nindex 1d73d3ca3..d2293b22e 100644\n--- a/builtin/check-ignore.c\n+++ b/builtin/check-ignore.c\n@@ -101,7 +101,8 @@ static int check_ignore(struct dir_struct *dir,\n \t\tfull_path = pathspec.items[i].match;\n \t\texclude = NULL;\n \t\tif (!seen[i]) {\n-\t\t\texclude = last_exclude_matching(dir, full_path, &dtype);\n+\t\t\texclude = last_exclude_matching(dir, &the_index,\n+\t\t\t\t\t\t\tfull_path, &dtype);\n \t\t}\n \t\tif (!quiet && (exclude || show_non_matching))\n \t\t\toutput_exclude(pathspec.items[i].original, exclude);\ndiff --git a/builtin/clean.c b/builtin/clean.c\nindex d861f836a..39866afab 100644\n--- a/builtin/clean.c\n+++ b/builtin/clean.c\n@@ -683,7 +683,7 @@ static int filter_by_patterns_cmd(void)\n \t\tfor_each_string_list_item(item, &del_list) {\n \t\t\tint dtype = DT_UNKNOWN;\n \n-\t\t\tif (is_excluded(&dir, item->string, &dtype)) {\n+\t\t\tif (is_excluded(&dir, &the_index, item->string, &dtype)) {\n \t\t\t\t*item->string = '\\0';\n \t\t\t\tchanged++;\n \t\t\t}\ndiff --git a/builtin/ls-files.c b/builtin/ls-files.c\nindex d449e46db..ccba227e2 100644\n--- a/builtin/ls-files.c\n+++ b/builtin/ls-files.c\n@@ -315,7 +315,7 @@ static void show_ru_info(void)\n static int ce_excluded(struct dir_struct *dir, const struct cache_entry *ce)\n {\n \tint dtype = ce_to_dtype(ce);\n-\treturn is_excluded(dir, ce->name, &dtype);\n+\treturn is_excluded(dir, &the_index, ce->name, &dtype);\n }\n \n static void show_files(struct dir_struct *dir)\ndiff --git a/dir.c b/dir.c\nindex 50b5e720e..a15da672c 100644\n--- a/dir.c\n+++ b/dir.c\n@@ -1204,19 +1204,20 @@ static void prep_exclude(struct dir_struct *dir,\n  * undecided.\n  */\n struct exclude *last_exclude_matching(struct dir_struct *dir,\n-\t\t\t\t\t     const char *pathname,\n-\t\t\t\t\t     int *dtype_p)\n+\t\t\t\t      struct index_state *istate,\n+\t\t\t\t      const char *pathname,\n+\t\t\t\t      int *dtype_p)\n {\n \tint pathlen = strlen(pathname);\n \tconst char *basename = strrchr(pathname, '/');\n \tbasename = (basename) ? basename+1 : pathname;\n \n-\tprep_exclude(dir, &the_index, pathname, basename-pathname);\n+\tprep_exclude(dir, istate, pathname, basename-pathname);\n \n \tif (dir->exclude)\n \t\treturn dir->exclude;\n \n-\treturn last_exclude_matching_from_lists(dir, &the_index, pathname, pathlen,\n+\treturn last_exclude_matching_from_lists(dir, istate, pathname, pathlen,\n \t\t\tbasename, dtype_p);\n }\n \n@@ -1225,10 +1226,11 @@ struct exclude *last_exclude_matching(struct dir_struct *dir,\n  * scans all exclude lists to determine whether pathname is excluded.\n  * Returns 1 if true, otherwise 0.\n  */\n-int is_excluded(struct dir_struct *dir, const char *pathname, int *dtype_p)\n+int is_excluded(struct dir_struct *dir, struct index_state *istate,\n+\t\tconst char *pathname, int *dtype_p)\n {\n \tstruct exclude *exclude =\n-\t\tlast_exclude_matching(dir, pathname, dtype_p);\n+\t\tlast_exclude_matching(dir, istate, pathname, dtype_p);\n \tif (exclude)\n \t\treturn exclude->flags & EXC_FLAG_NEGATIVE ? 0 : 1;\n \treturn 0;\n@@ -1573,7 +1575,7 @@ static enum path_treatment treat_one_path(struct dir_struct *dir,\n \t    (directory_exists_in_index(&the_index, path->buf, path->len) == index_nonexistent))\n \t\treturn path_none;\n \n-\texclude = is_excluded(dir, path->buf, &dtype);\n+\texclude = is_excluded(dir, &the_index, path->buf, &dtype);\n \n \t/*\n \t * Excluded? If we don't explicitly want to show\ndiff --git a/dir.h b/dir.h\nindex 1bcda0d23..b745f1e5d 100644\n--- a/dir.h\n+++ b/dir.h\n@@ -236,9 +236,12 @@ extern int match_pathname(const char *, int,\n \t\t\t  const char *, int, int, unsigned);\n \n extern struct exclude *last_exclude_matching(struct dir_struct *dir,\n+\t\t\t\t\t     struct index_state *istate,\n \t\t\t\t\t     const char *name, int *dtype);\n \n-extern int is_excluded(struct dir_struct *dir, const char *name, int *dtype);\n+extern int is_excluded(struct dir_struct *dir,\n+\t\t       struct index_state *istate,\n+\t\t       const char *name, int *dtype);\n \n extern struct exclude_list *add_exclude_list(struct dir_struct *dir,\n \t\t\t\t\t     int group_type, const char *src);\ndiff --git a/unpack-trees.c b/unpack-trees.c\nindex 5b19849e4..abdd2922b 100644\n--- a/unpack-trees.c\n+++ b/unpack-trees.c\n@@ -1606,7 +1606,7 @@ static int check_ok_to_remove(const char *name, int len, int dtype,\n \t\treturn 0;\n \n \tif (o->dir &&\n-\t    is_excluded(o->dir, name, &dtype))\n+\t    is_excluded(o->dir, &the_index, name, &dtype))\n \t\t/*\n \t\t * ce->name is explicitly excluded, so it is Ok to\n \t\t * overwrite it.\n-- \n2.13.0.rc1.294.g07d810a77f-goog\n\n"},{"id":"318891","messageId":"20170505195334.121856-12-bmwill@google.com","threadId":"45882","inReplyTo":"20170505195334.121856-1-bmwill@google.com","subject":"[RFC 11/14] dir: convert open_cached_dir to take an index","fromName":"Brandon Williams","fromEmail":"bmwill@google.com","sentAt":"2017-05-05T19:53:31Z","receivedAt":"2017-05-05T19:54:43Z","isPatch":false,"sender":{"key":"bwilliams.eng@gmail.com","avatar":null},"body":"Signed-off-by: Brandon Williams <bmwill@google.com>\n---\n dir.c | 12 +++++++-----\n 1 file changed, 7 insertions(+), 5 deletions(-)\n\ndiff --git a/dir.c b/dir.c\nindex a15da672c..f08d30ee4 100644\n--- a/dir.c\n+++ b/dir.c\n@@ -1664,6 +1664,7 @@ static void add_untracked(struct untracked_cache_dir *dir, const char *name)\n \n static int valid_cached_dir(struct dir_struct *dir,\n \t\t\t    struct untracked_cache_dir *untracked,\n+\t\t\t    struct index_state *istate,\n \t\t\t    struct strbuf *path,\n \t\t\t    int check_only)\n {\n@@ -1678,7 +1679,7 @@ static int valid_cached_dir(struct dir_struct *dir,\n \t\treturn 0;\n \t}\n \tif (!untracked->valid ||\n-\t    match_stat_data_racy(&the_index, &untracked->stat_data, &st)) {\n+\t    match_stat_data_racy(istate, &untracked->stat_data, &st)) {\n \t\tif (untracked->valid)\n \t\t\tinvalidate_directory(dir->untracked, untracked);\n \t\tfill_stat_data(&untracked->stat_data, &st);\n@@ -1699,10 +1700,10 @@ static int valid_cached_dir(struct dir_struct *dir,\n \t */\n \tif (path->len && path->buf[path->len - 1] != '/') {\n \t\tstrbuf_addch(path, '/');\n-\t\tprep_exclude(dir, &the_index, path->buf, path->len);\n+\t\tprep_exclude(dir, istate, path->buf, path->len);\n \t\tstrbuf_setlen(path, path->len - 1);\n \t} else\n-\t\tprep_exclude(dir, &the_index, path->buf, path->len);\n+\t\tprep_exclude(dir, istate, path->buf, path->len);\n \n \t/* hopefully prep_exclude() haven't invalidated this entry... */\n \treturn untracked->valid;\n@@ -1711,12 +1712,13 @@ static int valid_cached_dir(struct dir_struct *dir,\n static int open_cached_dir(struct cached_dir *cdir,\n \t\t\t   struct dir_struct *dir,\n \t\t\t   struct untracked_cache_dir *untracked,\n+\t\t\t   struct index_state *istate,\n \t\t\t   struct strbuf *path,\n \t\t\t   int check_only)\n {\n \tmemset(cdir, 0, sizeof(*cdir));\n \tcdir->untracked = untracked;\n-\tif (valid_cached_dir(dir, untracked, path, check_only))\n+\tif (valid_cached_dir(dir, untracked, istate, path, check_only))\n \t\treturn 0;\n \tcdir->fdir = opendir(path->len ? path->buf : \".\");\n \tif (dir->untracked)\n@@ -1789,7 +1791,7 @@ static enum path_treatment read_directory_recursive(struct dir_struct *dir,\n \n \tstrbuf_add(&path, base, baselen);\n \n-\tif (open_cached_dir(&cdir, dir, untracked, &path, check_only))\n+\tif (open_cached_dir(&cdir, dir, untracked, &the_index, &path, check_only))\n \t\tgoto out;\n \n \tif (untracked)\n-- \n2.13.0.rc1.294.g07d810a77f-goog\n\n"},{"id":"318892","messageId":"20170505195334.121856-9-bmwill@google.com","threadId":"45882","inReplyTo":"20170505195334.121856-1-bmwill@google.com","subject":"[RFC 08/14] dir: convert add_excludes to take an index","fromName":"Brandon Williams","fromEmail":"bmwill@google.com","sentAt":"2017-05-05T19:53:28Z","receivedAt":"2017-05-05T19:54:51Z","isPatch":false,"sender":{"key":"bwilliams.eng@gmail.com","avatar":null},"body":"Signed-off-by: Brandon Williams <bmwill@google.com>\n---\n dir.c          | 29 +++++++++++++++--------------\n dir.h          |  2 +-\n unpack-trees.c |  2 +-\n 3 files changed, 17 insertions(+), 16 deletions(-)\n\ndiff --git a/dir.c b/dir.c\nindex 497a2db85..b86d02ff9 100644\n--- a/dir.c\n+++ b/dir.c\n@@ -730,7 +730,7 @@ static void invalidate_directory(struct untracked_cache *uc,\n \n /*\n  * Given a file with name \"fname\", read it (either from disk, or from\n- * the index if \"check_index\" is non-zero), parse it and store the\n+ * an index if 'istate' is non-null), parse it and store the\n  * exclude rules in \"el\".\n  *\n  * If \"ss\" is not NULL, compute SHA-1 of the exclude file and fill\n@@ -738,7 +738,8 @@ static void invalidate_directory(struct untracked_cache *uc,\n  * ss_valid is non-zero, \"ss\" must contain good value as input.\n  */\n static int add_excludes(const char *fname, const char *base, int baselen,\n-\t\t\tstruct exclude_list *el, int check_index,\n+\t\t\tstruct exclude_list *el,\n+\t\t\tstruct index_state *istate,\n \t\t\tstruct sha1_stat *sha1_stat)\n {\n \tstruct stat st;\n@@ -752,8 +753,8 @@ static int add_excludes(const char *fname, const char *base, int baselen,\n \t\t\twarn_on_inaccessible(fname);\n \t\tif (0 <= fd)\n \t\t\tclose(fd);\n-\t\tif (!check_index ||\n-\t\t    (buf = read_skip_worktree_file_from_index(&the_index, fname, &size, sha1_stat)) == NULL)\n+\t\tif (!istate ||\n+\t\t    (buf = read_skip_worktree_file_from_index(istate, fname, &size, sha1_stat)) == NULL)\n \t\t\treturn -1;\n \t\tif (size == 0) {\n \t\t\tfree(buf);\n@@ -785,15 +786,15 @@ static int add_excludes(const char *fname, const char *base, int baselen,\n \t\tif (sha1_stat) {\n \t\t\tint pos;\n \t\t\tif (sha1_stat->valid &&\n-\t\t\t    !match_stat_data_racy(&the_index, &sha1_stat->stat, &st))\n+\t\t\t    !match_stat_data_racy(istate, &sha1_stat->stat, &st))\n \t\t\t\t; /* no content change, ss->sha1 still good */\n-\t\t\telse if (check_index &&\n-\t\t\t\t (pos = index_name_pos(&the_index, fname, strlen(fname))) >= 0 &&\n-\t\t\t\t !ce_stage(the_index.cache[pos]) &&\n-\t\t\t\t ce_uptodate(the_index.cache[pos]) &&\n+\t\t\telse if (istate &&\n+\t\t\t\t (pos = index_name_pos(istate, fname, strlen(fname))) >= 0 &&\n+\t\t\t\t !ce_stage(istate->cache[pos]) &&\n+\t\t\t\t ce_uptodate(istate->cache[pos]) &&\n \t\t\t\t !would_convert_to_git(fname))\n \t\t\t\thashcpy(sha1_stat->sha1,\n-\t\t\t\t\tthe_index.cache[pos]->oid.hash);\n+\t\t\t\t\tistate->cache[pos]->oid.hash);\n \t\t\telse\n \t\t\t\thash_sha1_file(buf, size, \"blob\", sha1_stat->sha1);\n \t\t\tfill_stat_data(&sha1_stat->stat, &st);\n@@ -824,9 +825,9 @@ static int add_excludes(const char *fname, const char *base, int baselen,\n \n int add_excludes_from_file_to_list(const char *fname, const char *base,\n \t\t\t\t   int baselen, struct exclude_list *el,\n-\t\t\t\t   int check_index)\n+\t\t\t\t   struct index_state *istate)\n {\n-\treturn add_excludes(fname, base, baselen, el, check_index, NULL);\n+\treturn add_excludes(fname, base, baselen, el, istate, NULL);\n }\n \n struct exclude_list *add_exclude_list(struct dir_struct *dir,\n@@ -858,7 +859,7 @@ static void add_excludes_from_file_1(struct dir_struct *dir, const char *fname,\n \tif (!dir->untracked)\n \t\tdir->unmanaged_exclude_files++;\n \tel = add_exclude_list(dir, EXC_FILE, fname);\n-\tif (add_excludes(fname, \"\", 0, el, 0, sha1_stat) < 0)\n+\tif (add_excludes(fname, \"\", 0, el, NULL, sha1_stat) < 0)\n \t\tdie(\"cannot use %s as an exclude file\", fname);\n }\n \n@@ -1166,7 +1167,7 @@ static void prep_exclude(struct dir_struct *dir, const char *base, int baselen)\n \t\t\tstrbuf_addbuf(&sb, &dir->basebuf);\n \t\t\tstrbuf_addstr(&sb, dir->exclude_per_dir);\n \t\t\tel->src = strbuf_detach(&sb, NULL);\n-\t\t\tadd_excludes(el->src, el->src, stk->baselen, el, 1,\n+\t\t\tadd_excludes(el->src, el->src, stk->baselen, el, &the_index,\n \t\t\t\t     untracked ? &sha1_stat : NULL);\n \t\t}\n \t\t/*\ndiff --git a/dir.h b/dir.h\nindex 64254c7e7..1bcda0d23 100644\n--- a/dir.h\n+++ b/dir.h\n@@ -243,7 +243,7 @@ extern int is_excluded(struct dir_struct *dir, const char *name, int *dtype);\n extern struct exclude_list *add_exclude_list(struct dir_struct *dir,\n \t\t\t\t\t     int group_type, const char *src);\n extern int add_excludes_from_file_to_list(const char *fname, const char *base, int baselen,\n-\t\t\t\t\t  struct exclude_list *el, int check_index);\n+\t\t\t\t\t  struct exclude_list *el, struct  index_state *istate);\n extern void add_excludes_from_file(struct dir_struct *, const char *fname);\n extern void parse_exclude_pattern(const char **string, int *patternlen, unsigned *flags, int *nowildcardlen);\n extern void add_exclude(const char *string, const char *base,\ndiff --git a/unpack-trees.c b/unpack-trees.c\nindex 9bcb13e4f..5b19849e4 100644\n--- a/unpack-trees.c\n+++ b/unpack-trees.c\n@@ -1223,7 +1223,7 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options\n \t\to->skip_sparse_checkout = 1;\n \tif (!o->skip_sparse_checkout) {\n \t\tchar *sparse = git_pathdup(\"info/sparse-checkout\");\n-\t\tif (add_excludes_from_file_to_list(sparse, \"\", 0, &el, 0) < 0)\n+\t\tif (add_excludes_from_file_to_list(sparse, \"\", 0, &el, NULL) < 0)\n \t\t\to->skip_sparse_checkout = 1;\n \t\telse\n \t\t\to->el = &el;\n-- \n2.13.0.rc1.294.g07d810a77f-goog\n\n"},{"id":"318893","messageId":"20170505195334.121856-4-bmwill@google.com","threadId":"45882","inReplyTo":"20170505195334.121856-1-bmwill@google.com","subject":"[RFC 03/14] dir: convert directory_exists_in_index to take index","fromName":"Brandon Williams","fromEmail":"bmwill@google.com","sentAt":"2017-05-05T19:53:23Z","receivedAt":"2017-05-05T19:54:53Z","isPatch":false,"sender":{"key":"bwilliams.eng@gmail.com","avatar":null},"body":"Signed-off-by: Brandon Williams <bmwill@google.com>\n---\n dir.c | 22 ++++++++++++----------\n 1 file changed, 12 insertions(+), 10 deletions(-)\n\ndiff --git a/dir.c b/dir.c\nindex 44307b963..5c635198d 100644\n--- a/dir.c\n+++ b/dir.c\n@@ -1264,14 +1264,15 @@ enum exist_status {\n  * the directory name; instead, use the case insensitive\n  * directory hash.\n  */\n-static enum exist_status directory_exists_in_index_icase(const char *dirname, int len)\n+static enum exist_status directory_exists_in_index_icase(struct index_state *istate,\n+\t\t\t\t\t\t\t const char *dirname, int len)\n {\n \tstruct cache_entry *ce;\n \n-\tif (index_dir_exists(&the_index, dirname, len))\n+\tif (index_dir_exists(istate, dirname, len))\n \t\treturn index_directory;\n \n-\tce = index_file_exists(&the_index, dirname, len, ignore_case);\n+\tce = index_file_exists(istate, dirname, len, ignore_case);\n \tif (ce && S_ISGITLINK(ce->ce_mode))\n \t\treturn index_gitdir;\n \n@@ -1285,18 +1286,19 @@ static enum exist_status directory_exists_in_index_icase(const char *dirname, in\n  * the files it contains) will sort with the '/' at the\n  * end.\n  */\n-static enum exist_status directory_exists_in_index(const char *dirname, int len)\n+static enum exist_status directory_exists_in_index(struct index_state *istate,\n+\t\t\t\t\t\t   const char *dirname, int len)\n {\n \tint pos;\n \n \tif (ignore_case)\n-\t\treturn directory_exists_in_index_icase(dirname, len);\n+\t\treturn directory_exists_in_index_icase(istate, dirname, len);\n \n-\tpos = index_name_pos(&the_index, dirname, len);\n+\tpos = index_name_pos(istate, dirname, len);\n \tif (pos < 0)\n \t\tpos = -pos-1;\n-\twhile (pos < the_index.cache_nr) {\n-\t\tconst struct cache_entry *ce = the_index.cache[pos++];\n+\twhile (pos < istate->cache_nr) {\n+\t\tconst struct cache_entry *ce = istate->cache[pos++];\n \t\tunsigned char endchar;\n \n \t\tif (strncmp(ce->name, dirname, len))\n@@ -1351,7 +1353,7 @@ static enum path_treatment treat_directory(struct dir_struct *dir,\n \tconst struct pathspec *pathspec)\n {\n \t/* The \"len-1\" is to strip the final '/' */\n-\tswitch (directory_exists_in_index(dirname, len-1)) {\n+\tswitch (directory_exists_in_index(&the_index, dirname, len-1)) {\n \tcase index_directory:\n \t\treturn path_recurse;\n \n@@ -1554,7 +1556,7 @@ static enum path_treatment treat_one_path(struct dir_struct *dir,\n \tif ((dir->flags & DIR_COLLECT_KILLED_ONLY) &&\n \t    (dtype == DT_DIR) &&\n \t    !has_path_in_index &&\n-\t    (directory_exists_in_index(path->buf, path->len) == index_nonexistent))\n+\t    (directory_exists_in_index(&the_index, path->buf, path->len) == index_nonexistent))\n \t\treturn path_none;\n \n \texclude = is_excluded(dir, path->buf, &dtype);\n-- \n2.13.0.rc1.294.g07d810a77f-goog\n\n"},{"id":"318894","messageId":"20170505195334.121856-10-bmwill@google.com","threadId":"45882","inReplyTo":"20170505195334.121856-1-bmwill@google.com","subject":"[RFC 09/14] dir: convert prep_exclude to take an index","fromName":"Brandon Williams","fromEmail":"bmwill@google.com","sentAt":"2017-05-05T19:53:29Z","receivedAt":"2017-05-05T19:54:55Z","isPatch":false,"sender":{"key":"bwilliams.eng@gmail.com","avatar":null},"body":"Signed-off-by: Brandon Williams <bmwill@google.com>\n---\n dir.c | 14 ++++++++------\n 1 file changed, 8 insertions(+), 6 deletions(-)\n\ndiff --git a/dir.c b/dir.c\nindex b86d02ff9..50b5e720e 100644\n--- a/dir.c\n+++ b/dir.c\n@@ -1046,7 +1046,9 @@ static struct exclude *last_exclude_matching_from_lists(struct dir_struct *dir,\n  * Loads the per-directory exclude list for the substring of base\n  * which has a char length of baselen.\n  */\n-static void prep_exclude(struct dir_struct *dir, const char *base, int baselen)\n+static void prep_exclude(struct dir_struct *dir,\n+\t\t\t struct index_state *istate,\n+\t\t\t const char *base, int baselen)\n {\n \tstruct exclude_list_group *group;\n \tstruct exclude_list *el;\n@@ -1125,7 +1127,7 @@ static void prep_exclude(struct dir_struct *dir, const char *base, int baselen)\n \t\t\tint dt = DT_DIR;\n \t\t\tdir->basebuf.buf[stk->baselen - 1] = 0;\n \t\t\tdir->exclude = last_exclude_matching_from_lists(dir,\n-\t\t\t\t\t\t\t\t\t&the_index,\n+\t\t\t\t\t\t\t\t\tistate,\n \t\t\t\tdir->basebuf.buf, stk->baselen - 1,\n \t\t\t\tdir->basebuf.buf + current, &dt);\n \t\t\tdir->basebuf.buf[stk->baselen - 1] = '/';\n@@ -1167,7 +1169,7 @@ static void prep_exclude(struct dir_struct *dir, const char *base, int baselen)\n \t\t\tstrbuf_addbuf(&sb, &dir->basebuf);\n \t\t\tstrbuf_addstr(&sb, dir->exclude_per_dir);\n \t\t\tel->src = strbuf_detach(&sb, NULL);\n-\t\t\tadd_excludes(el->src, el->src, stk->baselen, el, &the_index,\n+\t\t\tadd_excludes(el->src, el->src, stk->baselen, el, istate,\n \t\t\t\t     untracked ? &sha1_stat : NULL);\n \t\t}\n \t\t/*\n@@ -1209,7 +1211,7 @@ struct exclude *last_exclude_matching(struct dir_struct *dir,\n \tconst char *basename = strrchr(pathname, '/');\n \tbasename = (basename) ? basename+1 : pathname;\n \n-\tprep_exclude(dir, pathname, basename-pathname);\n+\tprep_exclude(dir, &the_index, pathname, basename-pathname);\n \n \tif (dir->exclude)\n \t\treturn dir->exclude;\n@@ -1695,10 +1697,10 @@ static int valid_cached_dir(struct dir_struct *dir,\n \t */\n \tif (path->len && path->buf[path->len - 1] != '/') {\n \t\tstrbuf_addch(path, '/');\n-\t\tprep_exclude(dir, path->buf, path->len);\n+\t\tprep_exclude(dir, &the_index, path->buf, path->len);\n \t\tstrbuf_setlen(path, path->len - 1);\n \t} else\n-\t\tprep_exclude(dir, path->buf, path->len);\n+\t\tprep_exclude(dir, &the_index, path->buf, path->len);\n \n \t/* hopefully prep_exclude() haven't invalidated this entry... */\n \treturn untracked->valid;\n-- \n2.13.0.rc1.294.g07d810a77f-goog\n\n"},{"id":"318895","messageId":"20170505195334.121856-1-bmwill@google.com","threadId":"45882","inReplyTo":null,"subject":"[RFC 00/14] convert dir.c to take an index parameter","fromName":"Brandon Williams","fromEmail":"bmwill@google.com","sentAt":"2017-05-05T19:53:20Z","receivedAt":"2017-05-05T19:55:09Z","isPatch":false,"sender":{"key":"bwilliams.eng@gmail.com","avatar":null},"body":"One of the things brought up on the list in the past few days has been\nmigrating away from using the index compatibility macros.  One of the issues\nbrought up in that thread was how simply doing that conversion doesn't\neliminate the reliance on global state (specifically the_index).  If one day we\nwant to have a 'repository object' passed around then we first need to convert\ndifferent subsystems to be prepared to handle that.  This series provides a\nfirst step, converting the code in dir.c to take a 'struct index_state' and\nusing that instead of implicitly using 'the_index'.\n\nBrandon Williams (14):\n  dir: stop using the index compatibility macros\n  dir: convert read_skip_worktree_file_from_index to take an index\n  dir: convert directory_exists_in_index to take index\n  dir: convert get_dtype to take index\n  dir: convert dir_add* to take an index\n  dir: convert last_exclude_matching_from_list to take an index\n  dir: convert is_excluded_from_list to take an index\n  dir: convert add_excludes to take an index\n  dir: convert prep_exclude to take an index\n  dir: convert is_excluded to take an index\n  dir: convert open_cached_dir to take an index\n  dir: convert read_directory_recursive to take an index\n  dir: convert read_directory to take an index\n  dir: convert fill_directory to take an index\n\n builtin/add.c          |   7 +-\n builtin/check-ignore.c |   3 +-\n builtin/clean.c        |   4 +-\n builtin/grep.c         |   2 +-\n builtin/ls-files.c     |   4 +-\n dir.c                  | 200 ++++++++++++++++++++++++++++---------------------\n dir.h                  |  27 +++++--\n unpack-trees.c         |  10 +--\n wt-status.c            |   2 +-\n 9 files changed, 151 insertions(+), 108 deletions(-)\n\n-- \n2.13.0.rc1.294.g07d810a77f-goog\n\n"},{"id":"318929","messageId":"xmqqmvaq702u.fsf@gitster.mtv.corp.google.com","threadId":"45882","inReplyTo":"20170505195334.121856-1-bmwill@google.com","subject":"Re: [RFC 00/14] convert dir.c to take an index parameter","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-05-06T10:26:33Z","receivedAt":"2017-05-06T10:26:40Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Brandon Williams <bmwill@google.com> writes:\n\n> One of the things brought up on the list in the past few days has been\n> migrating away from using the index compatibility macros.  One of the issues\n> brought up in that thread was how simply doing that conversion doesn't\n> eliminate the reliance on global state (specifically the_index).  If one day we\n> want to have a 'repository object' passed around then we first need to convert\n> different subsystems to be prepared to handle that.  This series provides a\n> first step, converting the code in dir.c to take a 'struct index_state' and\n> using that instead of implicitly using 'the_index'.\n\nVery nicely done (I only skimmed \"dir.c\" in the end result and didn't\ngo through the changes with fine toothed comb, though).\n\nI would have done this without the first step and then instead had a\nfinal patch that only inserts a single\n\n    #define NO_THE_INDEX_COMPATIBILITY_MACROS\n\nat the beginning of dir.c once everybody in dir.c loses the\nreference to all \"cache\" macros at the end, if I were doing this\nseries, but it is a personal taste.  \n\nThe resulting dir.c does not even refer to the_index, which is very\nnice.\n\nThanks.\n\n> Brandon Williams (14):\n>   dir: stop using the index compatibility macros\n>   dir: convert read_skip_worktree_file_from_index to take an index\n>   dir: convert directory_exists_in_index to take index\n>   dir: convert get_dtype to take index\n>   dir: convert dir_add* to take an index\n>   dir: convert last_exclude_matching_from_list to take an index\n>   dir: convert is_excluded_from_list to take an index\n>   dir: convert add_excludes to take an index\n>   dir: convert prep_exclude to take an index\n>   dir: convert is_excluded to take an index\n>   dir: convert open_cached_dir to take an index\n>   dir: convert read_directory_recursive to take an index\n>   dir: convert read_directory to take an index\n>   dir: convert fill_directory to take an index\n>\n>  builtin/add.c          |   7 +-\n>  builtin/check-ignore.c |   3 +-\n>  builtin/clean.c        |   4 +-\n>  builtin/grep.c         |   2 +-\n>  builtin/ls-files.c     |   4 +-\n>  dir.c                  | 200 ++++++++++++++++++++++++++++---------------------\n>  dir.h                  |  27 +++++--\n>  unpack-trees.c         |  10 +--\n>  wt-status.c            |   2 +-\n>  9 files changed, 151 insertions(+), 108 deletions(-)\n"},{"id":"319102","messageId":"20170508171255.GE179149@google.com","threadId":"45882","inReplyTo":"xmqqmvaq702u.fsf@gitster.mtv.corp.google.com","subject":"Re: [RFC 00/14] convert dir.c to take an index parameter","fromName":"Brandon Williams","fromEmail":"bmwill@google.com","sentAt":"2017-05-08T17:12:55Z","receivedAt":"2017-05-08T17:13:02Z","isPatch":false,"sender":{"key":"bwilliams.eng@gmail.com","avatar":null},"body":"On 05/06, Junio C Hamano wrote:\n> Brandon Williams <bmwill@google.com> writes:\n> \n> > One of the things brought up on the list in the past few days has been\n> > migrating away from using the index compatibility macros.  One of the issues\n> > brought up in that thread was how simply doing that conversion doesn't\n> > eliminate the reliance on global state (specifically the_index).  If one day we\n> > want to have a 'repository object' passed around then we first need to convert\n> > different subsystems to be prepared to handle that.  This series provides a\n> > first step, converting the code in dir.c to take a 'struct index_state' and\n> > using that instead of implicitly using 'the_index'.\n> \n> Very nicely done (I only skimmed \"dir.c\" in the end result and didn't\n> go through the changes with fine toothed comb, though).\n> \n> I would have done this without the first step and then instead had a\n> final patch that only inserts a single\n> \n>     #define NO_THE_INDEX_COMPATIBILITY_MACROS\n> \n> at the beginning of dir.c once everybody in dir.c loses the\n> reference to all \"cache\" macros at the end, if I were doing this\n> series, but it is a personal taste.  \n> \n> The resulting dir.c does not even refer to the_index, which is very\n> nice.\n\nThanks! I'm glad there's a few people who see this as a positive change.\n\n> \n> Thanks.\n> \n> > Brandon Williams (14):\n> >   dir: stop using the index compatibility macros\n> >   dir: convert read_skip_worktree_file_from_index to take an index\n> >   dir: convert directory_exists_in_index to take index\n> >   dir: convert get_dtype to take index\n> >   dir: convert dir_add* to take an index\n> >   dir: convert last_exclude_matching_from_list to take an index\n> >   dir: convert is_excluded_from_list to take an index\n> >   dir: convert add_excludes to take an index\n> >   dir: convert prep_exclude to take an index\n> >   dir: convert is_excluded to take an index\n> >   dir: convert open_cached_dir to take an index\n> >   dir: convert read_directory_recursive to take an index\n> >   dir: convert read_directory to take an index\n> >   dir: convert fill_directory to take an index\n> >\n> >  builtin/add.c          |   7 +-\n> >  builtin/check-ignore.c |   3 +-\n> >  builtin/clean.c        |   4 +-\n> >  builtin/grep.c         |   2 +-\n> >  builtin/ls-files.c     |   4 +-\n> >  dir.c                  | 200 ++++++++++++++++++++++++++++---------------------\n> >  dir.h                  |  27 +++++--\n> >  unpack-trees.c         |  10 +--\n> >  wt-status.c            |   2 +-\n> >  9 files changed, 151 insertions(+), 108 deletions(-)\n\n-- \nBrandon Williams\n"},{"id":"319107","messageId":"bf76dd64-0d4b-cadd-cf34-ec50e9d6e351@jeffhostetler.com","threadId":"45882","inReplyTo":"20170508171255.GE179149@google.com","subject":"Re: [RFC 00/14] convert dir.c to take an index parameter","fromName":"Jeff Hostetler","fromEmail":"git@jeffhostetler.com","sentAt":"2017-05-08T18:00:53Z","receivedAt":"2017-05-08T18:01:00Z","isPatch":false,"sender":{"key":"git@jeffhostetler.com","avatar":null},"body":"\n\nOn 5/8/2017 1:12 PM, Brandon Williams wrote:\n> On 05/06, Junio C Hamano wrote:\n>> Brandon Williams <bmwill@google.com> writes:\n>>\n>>> One of the things brought up on the list in the past few days has been\n>>> migrating away from using the index compatibility macros.  One of the issues\n>>> brought up in that thread was how simply doing that conversion doesn't\n>>> eliminate the reliance on global state (specifically the_index).  If one day we\n>>> want to have a 'repository object' passed around then we first need to convert\n>>> different subsystems to be prepared to handle that.  This series provides a\n>>> first step, converting the code in dir.c to take a 'struct index_state' and\n>>> using that instead of implicitly using 'the_index'.\n>>\n>> Very nicely done (I only skimmed \"dir.c\" in the end result and didn't\n>> go through the changes with fine toothed comb, though).\n>>\n>> I would have done this without the first step and then instead had a\n>> final patch that only inserts a single\n>>\n>>     #define NO_THE_INDEX_COMPATIBILITY_MACROS\n>>\n>> at the beginning of dir.c once everybody in dir.c loses the\n>> reference to all \"cache\" macros at the end, if I were doing this\n>> series, but it is a personal taste.\n>>\n>> The resulting dir.c does not even refer to the_index, which is very\n>> nice.\n>\n> Thanks! I'm glad there's a few people who see this as a positive change.\n\nAgreed.  This looks like a nice start.\nJeff\n\n"}]}