{"thread":{"id":"49115","subject":"[PATCH 00/24] Kill the_index part3","startedAt":"2018-08-13T16:15:22Z","lastAt":"2018-08-15T19:48:14Z","messageCount":38,"participants":["Nguyễn Thái Ngọc Duy","Brandon Williams","Duy Nguyen","Junio C Hamano","Stefan Beller"],"isPatch":true,"patchVersion":1,"patchTotal":24},"messages":[{"id":"355369","messageId":"20180813161441.16824-1-pclouds@gmail.com","threadId":"49115","inReplyTo":null,"subject":"[PATCH 00/24] Kill the_index part3","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-08-13T16:14:17Z","receivedAt":"2018-08-13T16:15:22Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"This is the third part of killing the_index (at least outside\nbuiltin/). Part 1 [1] is dropped. Part 2 is nd/no-extern on 'pu'. This\npart is built on top of nd/no-extern.\n\nThis series would actually break 'pu' because builtin/stash.c uses\nthree functions that are updated here. So we would need something like\nthe following patch to make it build again.\n\nI don't know if that adds too much work on Junio. If it does, I guess\nI'll hold this off for a while until builtin/stash.c gets merged\nbecause reordering these patches, pushing the patches that break\nstash.c away, really takes a lot of work.\n\n[1] https://public-inbox.org/git/20180616054157.32433-1-pclouds@gmail.com/\n\ndiff --git a/builtin/stash.c b/builtin/stash.c\nindex 74eda822ce..f34edba21f 100644\n--- a/builtin/stash.c\n+++ b/builtin/stash.c\n@@ -294,7 +294,7 @@ static int apply_patch_from_buf(struct strbuf *patch, int cached, int reverse,\n \tconst char *patch_path = \".git/stash_patch.patch\";\n \tFILE *patch_file;\n \n-\tif (init_apply_state(&state, NULL))\n+\tif (init_apply_state(&state, the_repository, NULL))\n \t\treturn -1;\n \n \tstate.cached = cached;\n@@ -873,7 +873,7 @@ static int get_untracked_files(const char **argv, const char *prefix,\n \tmax_len = fill_directory(&dir, the_repository->index, &pathspec);\n \tfor (i = 0; i < dir.nr; i++) {\n \t\tstruct dir_entry *ent = dir.entries[i];\n-\t\tif (!dir_path_match(ent, &pathspec, max_len, seen)) {\n+\t\tif (!dir_path_match(the_repository->index, ent, &pathspec, max_len, seen)) {\n \t\t\tfree(ent);\n \t\t\tcontinue;\n \t\t}\n@@ -1299,7 +1299,7 @@ static int do_push_stash(int argc, const char **argv, const char *prefix,\n \n \t\tfor (i = 0; i < active_nr; ++i) {\n \t\t\tconst struct cache_entry *ce = active_cache[i];\n-\t\t\tif (!ce_path_match(ce, &ps, ps_matched))\n+\t\t\tif (!ce_path_match(&the_index, ce, &ps, ps_matched))\n \t\t\t\tcontinue;\n \t\t}\n \nNguyễn Thái Ngọc Duy (24):\n  diff.c: move read_index() code back to the caller\n  cache-tree: wrap the_index based wrappers with #ifdef\n  attr: remove an implicit dependency on the_index\n  convert.c: remove an implicit dependency on the_index\n  dir.c: remove an implicit dependency on the_index in pathspec code\n  preload-index.c: use the right index instead of the_index\n  ls-files: correct index argument to get_convert_attr_ascii()\n  unpack-trees: remove 'extern' on function declaration\n  unpack-trees: add a note about path invalidation\n  unpack-trees: don't shadow global var the_index\n  unpack-trees: convert clear_ce_flags* to avoid the_index\n  unpack-trees: avoid the_index in verify_absent()\n  pathspec.c: use the right index instead of the_index\n  submodule.c: use the right index instead of the_index\n  entry.c: use the right index instead of the_index\n  attr: remove index from git_attr_set_direction()\n  grep: use the right index instead of the_index\n  archive.c: avoid access to the_index\n  archive-*.c: use the right repository\n  resolve-undo.c: use the right index instead of the_index\n  apply.c: pass struct apply_state to more functions\n  apply.c: make init_apply_state() take a struct repository\n  apply.c: remove implicit dependency on the_index\n  blame.c: remove implicit dependency on the_index\n\n apply.c                     | 66 +++++++++++++++++++++----------------\n apply.h                     |  4 +++\n archive-tar.c               |  2 +-\n archive-zip.c               |  2 +-\n archive.c                   | 47 ++++++++++++++++----------\n archive.h                   | 16 +++++++--\n attr.c                      | 52 +++++++++++++++++------------\n attr.h                      | 11 ++++---\n blame.c                     | 52 +++++++++++++++++------------\n blame.h                     |  1 +\n builtin/add.c               |  6 ++--\n builtin/am.c                |  2 +-\n builtin/apply.c             |  2 +-\n builtin/archive.c           |  2 +-\n builtin/blame.c             |  1 +\n builtin/cat-file.c          |  2 +-\n builtin/check-attr.c        |  6 ++--\n builtin/checkout-index.c    |  1 +\n builtin/checkout.c          |  2 +-\n builtin/clean.c             |  2 +-\n builtin/commit.c            |  2 +-\n builtin/diff-tree.c         |  8 +++--\n builtin/grep.c              |  6 ++--\n builtin/ls-files.c          | 17 +++++-----\n builtin/pack-objects.c      |  2 +-\n builtin/rm.c                |  2 +-\n builtin/submodule--helper.c |  2 +-\n builtin/update-index.c      |  2 +-\n builtin/upload-archive.c    |  3 +-\n cache-tree.c                | 12 -------\n cache-tree.h                | 17 ++++++++--\n convert.c                   | 41 +++++++++++++----------\n convert.h                   | 15 ++++++---\n diff-lib.c                  |  4 +--\n diff.c                      | 12 +------\n diff.h                      |  1 -\n dir.c                       | 27 ++++++++-------\n dir.h                       | 16 +++++----\n entry.c                     |  9 ++---\n ll-merge.c                  |  4 +--\n merge-recursive.c           |  2 +-\n pathspec.c                  |  2 +-\n preload-index.c             |  2 +-\n read-cache.c                |  2 +-\n rerere.c                    |  2 +-\n resolve-undo.c              |  2 +-\n revision.c                  |  2 +-\n sequencer.c                 |  4 +--\n sha1-file.c                 |  4 +--\n submodule.c                 |  8 ++---\n unpack-trees.c              | 57 ++++++++++++++++++++------------\n unpack-trees.h              |  4 +--\n userdiff.c                  |  2 +-\n ws.c                        |  2 +-\n wt-status.c                 |  6 ++--\n 55 files changed, 337 insertions(+), 245 deletions(-)\n\n-- \n2.18.0.1004.g6639190530\n\n"},{"id":"355370","messageId":"20180813161441.16824-2-pclouds@gmail.com","threadId":"49115","inReplyTo":"20180813161441.16824-1-pclouds@gmail.com","subject":"[PATCH 01/24] diff.c: move read_index() code back to the caller","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-08-13T16:14:18Z","receivedAt":"2018-08-13T16:15:23Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"This code is only needed for diff-tree (since f0c6b2a2fd ([PATCH]\nOptimize diff-tree -[CM] --stdin - 2005-05-27)). Let the caller do the\npreparation instead and avoid read_index() in diff.c code.\n\nread_index() should be avoided (in addition to the_index) because it\nuses get_index_file() underneath to get the path $GIT_DIR/index. This\neffectively pulls the_repository in and may become the only reason to\npull a 'struct repository *' in diff.c. Let's keep the dependencies as\nfew as possible and kick it back to diff-tree.c\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/diff-tree.c |  8 +++++---\n diff.c              | 10 ----------\n diff.h              |  1 -\n 3 files changed, 5 insertions(+), 14 deletions(-)\n\ndiff --git a/builtin/diff-tree.c b/builtin/diff-tree.c\nindex 91ba67070e..d07bf2e4c4 100644\n--- a/builtin/diff-tree.c\n+++ b/builtin/diff-tree.c\n@@ -163,9 +163,11 @@ int cmd_diff_tree(int argc, const char **argv, const char *prefix)\n \t\tint saved_nrl = 0;\n \t\tint saved_dcctc = 0;\n \n-\t\tif (opt->diffopt.detect_rename)\n-\t\t\topt->diffopt.setup |= (DIFF_SETUP_USE_SIZE_CACHE |\n-\t\t\t\t\t       DIFF_SETUP_USE_CACHE);\n+\t\tif (opt->diffopt.detect_rename) {\n+\t\t\tif (!the_index.cache)\n+\t\t\t\tread_index(&the_index);\n+\t\t\topt->diffopt.setup |= DIFF_SETUP_USE_SIZE_CACHE;\n+\t\t}\n \t\twhile (fgets(line, sizeof(line), stdin)) {\n \t\t\tstruct object_id oid;\n \ndiff --git a/diff.c b/diff.c\nindex 04d044bbb6..72ce8007fd 100644\n--- a/diff.c\n+++ b/diff.c\n@@ -4414,16 +4414,6 @@ void diff_setup_done(struct diff_options *options)\n \n \tif (options->detect_rename && options->rename_limit < 0)\n \t\toptions->rename_limit = diff_rename_limit_default;\n-\tif (options->setup & DIFF_SETUP_USE_CACHE) {\n-\t\tif (!active_cache)\n-\t\t\t/* read-cache does not die even when it fails\n-\t\t\t * so it is safe for us to do this here.  Also\n-\t\t\t * it does not smudge active_cache or active_nr\n-\t\t\t * when it fails, so we do not have to worry about\n-\t\t\t * cleaning it up ourselves either.\n-\t\t\t */\n-\t\t\tread_cache();\n-\t}\n \tif (hexsz < options->abbrev)\n \t\toptions->abbrev = hexsz; /* full */\n \ndiff --git a/diff.h b/diff.h\nindex 20c697dbfe..3ada6ad33c 100644\n--- a/diff.h\n+++ b/diff.h\n@@ -312,7 +312,6 @@ void diff_change(struct diff_options *,\n struct diff_filepair *diff_unmerge(struct diff_options *, const char *path);\n \n #define DIFF_SETUP_REVERSE      \t1\n-#define DIFF_SETUP_USE_CACHE\t\t2\n #define DIFF_SETUP_USE_SIZE_CACHE\t4\n \n /*\n-- \n2.18.0.1004.g6639190530\n\n"},{"id":"355371","messageId":"20180813161441.16824-3-pclouds@gmail.com","threadId":"49115","inReplyTo":"20180813161441.16824-1-pclouds@gmail.com","subject":"[PATCH 02/24] cache-tree: wrap the_index based wrappers with #ifdef","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-08-13T16:14:19Z","receivedAt":"2018-08-13T16:15:25Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"This puts update_main_cache_tree() and write_cache_as_tree() in the\nsame group of \"index compat\" functions that assume the_index\nimplicitly, which should only be used within builtin/ or t/helper.\n\nsequencer.c is also updated to not use these functions. As of now, no\nfiles outside builtin/ use these functions anymore.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n cache-tree.c | 12 ------------\n cache-tree.h | 17 ++++++++++++++---\n sequencer.c  |  4 ++--\n 3 files changed, 16 insertions(+), 17 deletions(-)\n\ndiff --git a/cache-tree.c b/cache-tree.c\nindex 181d5919f0..16ea022c46 100644\n--- a/cache-tree.c\n+++ b/cache-tree.c\n@@ -652,11 +652,6 @@ int write_index_as_tree(struct object_id *oid, struct index_state *index_state,\n \treturn ret;\n }\n \n-int write_cache_as_tree(struct object_id *oid, int flags, const char *prefix)\n-{\n-\treturn write_index_as_tree(oid, &the_index, get_index_file(), flags, prefix);\n-}\n-\n static void prime_cache_tree_rec(struct cache_tree *it, struct tree *tree)\n {\n \tstruct tree_desc desc;\n@@ -723,10 +718,3 @@ int cache_tree_matches_traversal(struct cache_tree *root,\n \t\treturn it->entry_count;\n \treturn 0;\n }\n-\n-int update_main_cache_tree(int flags)\n-{\n-\tif (!the_index.cache_tree)\n-\t\tthe_index.cache_tree = cache_tree();\n-\treturn cache_tree_update(&the_index, flags);\n-}\ndiff --git a/cache-tree.h b/cache-tree.h\nindex 9799e894f7..fc0c842e77 100644\n--- a/cache-tree.h\n+++ b/cache-tree.h\n@@ -33,8 +33,6 @@ struct cache_tree *cache_tree_read(const char *buffer, unsigned long size);\n int cache_tree_fully_valid(struct cache_tree *);\n int cache_tree_update(struct index_state *, int);\n \n-int update_main_cache_tree(int);\n-\n /* bitmasks to write_cache_as_tree flags */\n #define WRITE_TREE_MISSING_OK 1\n #define WRITE_TREE_IGNORE_CACHE_TREE 2\n@@ -48,9 +46,22 @@ int update_main_cache_tree(int);\n #define WRITE_TREE_PREFIX_ERROR (-3)\n \n int write_index_as_tree(struct object_id *oid, struct index_state *index_state, const char *index_path, int flags, const char *prefix);\n-int write_cache_as_tree(struct object_id *oid, int flags, const char *prefix);\n void prime_cache_tree(struct index_state *, struct tree *);\n \n int cache_tree_matches_traversal(struct cache_tree *, struct name_entry *ent, struct traverse_info *info);\n \n+#ifndef NO_THE_INDEX_COMPATIBILITY_MACROS\n+static inline int write_cache_as_tree(struct object_id *oid, int flags, const char *prefix)\n+{\n+\treturn write_index_as_tree(oid, &the_index, get_index_file(), flags, prefix);\n+}\n+\n+static inline int update_main_cache_tree(int flags)\n+{\n+\tif (!the_index.cache_tree)\n+\t\tthe_index.cache_tree = cache_tree();\n+\treturn cache_tree_update(&the_index, flags);\n+}\n+#endif\n+\n #endif\ndiff --git a/sequencer.c b/sequencer.c\nindex 31038472fd..4d40f50c1c 100644\n--- a/sequencer.c\n+++ b/sequencer.c\n@@ -1244,7 +1244,7 @@ static int try_to_commit(struct strbuf *msg, const char *author,\n \t\tcommit_list_insert(current_head, &parents);\n \t}\n \n-\tif (write_cache_as_tree(&tree, 0, NULL)) {\n+\tif (write_index_as_tree(&tree, &the_index, get_index_file(), 0, NULL)) {\n \t\tres = error(_(\"git write-tree failed to write a tree\"));\n \t\tgoto out;\n \t}\n@@ -1630,7 +1630,7 @@ static int do_pick_commit(enum todo_command command, struct commit *commit,\n \t\t * that represents the \"current\" state for merge-recursive\n \t\t * to work on.\n \t\t */\n-\t\tif (write_cache_as_tree(&head, 0, NULL))\n+\t\tif (write_index_as_tree(&head, &the_index, get_index_file(), 0, NULL))\n \t\t\treturn error(_(\"your index file is unmerged.\"));\n \t} else {\n \t\tunborn = get_oid(\"HEAD\", &head);\n-- \n2.18.0.1004.g6639190530\n\n"},{"id":"355372","messageId":"20180813161441.16824-4-pclouds@gmail.com","threadId":"49115","inReplyTo":"20180813161441.16824-1-pclouds@gmail.com","subject":"[PATCH 03/24] attr: remove an implicit dependency on the_index","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-08-13T16:14:20Z","receivedAt":"2018-08-13T16:15:26Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Make the attr API take an index_state instead of assuming the_index in\nattr code. All call sites are converted blindly to keep the patch\nsimple and retain current behavior. Individual call sites may receive\nfurther updates to use the right index instead of the_index.\n\nThere is one ugly temporary workaround added in attr.c that needs some\nmore explanation.\n\nCommit c24f3abace (apply: file commited with CRLF should roundtrip\ndiff and apply - 2017-08-19) forces one convert_to_git() call to NOT\nread the index at all. But what do you know, we read it anyway by\nfalling back to the_index. When \"istate\" from convert_to_git is now\npropagated down to read_attr_from_array() we will hit segfault\nsomewhere inside read_blob_data_from_index.\n\nThe right way of dealing with this is to kill \"use_index\" variable and\nonly follow \"istate\" but at this stage we are not ready for that:\nwhile most git_attr_set_direction() calls just passes the_index to be\nassigned to use_index, unpack-trees passes a different one which is\nused by entry.c code, which has no way to know what index to use if we\ndelete use_index. So this has to be done later.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n archive.c              |  2 +-\n attr.c                 | 57 ++++++++++++++++++++++++++++--------------\n attr.h                 | 10 +++++---\n builtin/check-attr.c   |  4 +--\n builtin/pack-objects.c |  2 +-\n convert.c              |  2 +-\n dir.c                  |  2 +-\n ll-merge.c             |  4 +--\n userdiff.c             |  2 +-\n ws.c                   |  2 +-\n 10 files changed, 55 insertions(+), 32 deletions(-)\n\ndiff --git a/archive.c b/archive.c\nindex 78b0a398a0..a8397e6173 100644\n--- a/archive.c\n+++ b/archive.c\n@@ -109,7 +109,7 @@ static const struct attr_check *get_archive_attrs(const char *path)\n \tstatic struct attr_check *check;\n \tif (!check)\n \t\tcheck = attr_check_initl(\"export-ignore\", \"export-subst\", NULL);\n-\treturn git_check_attr(path, check) ? NULL : check;\n+\treturn git_check_attr(&the_index, path, check) ? NULL : check;\n }\n \n static int check_attr_export_ignore(const struct attr_check *check)\ndiff --git a/attr.c b/attr.c\nindex 067fb9e0c0..863fad3bd1 100644\n--- a/attr.c\n+++ b/attr.c\n@@ -708,10 +708,10 @@ static struct attr_stack *read_attr_from_array(const char **list)\n  * another thread could potentially be calling into the attribute system.\n  */\n static enum git_attr_direction direction;\n-static struct index_state *use_index;\n+static const struct index_state *use_index;\n \n void git_attr_set_direction(enum git_attr_direction new_direction,\n-\t\t\t    struct index_state *istate)\n+\t\t\t    const struct index_state *istate)\n {\n \tif (is_bare_repository() && new_direction != GIT_ATTR_INDEX)\n \t\tBUG(\"non-INDEX attr direction in a bare repo\");\n@@ -743,13 +743,24 @@ static struct attr_stack *read_attr_from_file(const char *path, int macro_ok)\n \treturn res;\n }\n \n-static struct attr_stack *read_attr_from_index(const char *path, int macro_ok)\n+static struct attr_stack *read_attr_from_index(const struct index_state *istate,\n+\t\t\t\t\t       const char *path,\n+\t\t\t\t\t       int macro_ok)\n {\n \tstruct attr_stack *res;\n \tchar *buf, *sp;\n \tint lineno = 0;\n+\tconst struct index_state *to_read_from;\n \n-\tbuf = read_blob_data_from_index(use_index ? use_index : &the_index, path, NULL);\n+\t/*\n+\t * Temporary workaround for c24f3abace (apply: file commited\n+\t * with CRLF should roundtrip diff and apply - 2017-08-19)\n+\t */\n+\tto_read_from = use_index ? use_index : istate;\n+\tif (!to_read_from)\n+\t\treturn NULL;\n+\n+\tbuf = read_blob_data_from_index(to_read_from, path, NULL);\n \tif (!buf)\n \t\treturn NULL;\n \n@@ -768,15 +779,16 @@ static struct attr_stack *read_attr_from_index(const char *path, int macro_ok)\n \treturn res;\n }\n \n-static struct attr_stack *read_attr(const char *path, int macro_ok)\n+static struct attr_stack *read_attr(const struct index_state *istate,\n+\t\t\t\t    const char *path, int macro_ok)\n {\n \tstruct attr_stack *res = NULL;\n \n \tif (direction == GIT_ATTR_INDEX) {\n-\t\tres = read_attr_from_index(path, macro_ok);\n+\t\tres = read_attr_from_index(istate, path, macro_ok);\n \t} else if (!is_bare_repository()) {\n \t\tif (direction == GIT_ATTR_CHECKOUT) {\n-\t\t\tres = read_attr_from_index(path, macro_ok);\n+\t\t\tres = read_attr_from_index(istate, path, macro_ok);\n \t\t\tif (!res)\n \t\t\t\tres = read_attr_from_file(path, macro_ok);\n \t\t} else if (direction == GIT_ATTR_CHECKIN) {\n@@ -788,7 +800,7 @@ static struct attr_stack *read_attr(const char *path, int macro_ok)\n \t\t\t\t * We allow operation in a sparsely checked out\n \t\t\t\t * work tree, so read from it.\n \t\t\t\t */\n-\t\t\t\tres = read_attr_from_index(path, macro_ok);\n+\t\t\t\tres = read_attr_from_index(istate, path, macro_ok);\n \t\t}\n \t}\n \n@@ -859,7 +871,8 @@ static void push_stack(struct attr_stack **attr_stack_p,\n \t}\n }\n \n-static void bootstrap_attr_stack(struct attr_stack **stack)\n+static void bootstrap_attr_stack(const struct index_state *istate,\n+\t\t\t\t struct attr_stack **stack)\n {\n \tstruct attr_stack *e;\n \n@@ -883,7 +896,7 @@ static void bootstrap_attr_stack(struct attr_stack **stack)\n \t}\n \n \t/* root directory */\n-\te = read_attr(GITATTRIBUTES_FILE, 1);\n+\te = read_attr(istate, GITATTRIBUTES_FILE, 1);\n \tpush_stack(stack, e, xstrdup(\"\"), 0);\n \n \t/* info frame */\n@@ -896,7 +909,8 @@ static void bootstrap_attr_stack(struct attr_stack **stack)\n \tpush_stack(stack, e, NULL, 0);\n }\n \n-static void prepare_attr_stack(const char *path, int dirlen,\n+static void prepare_attr_stack(const struct index_state *istate,\n+\t\t\t       const char *path, int dirlen,\n \t\t\t       struct attr_stack **stack)\n {\n \tstruct attr_stack *info;\n@@ -917,7 +931,7 @@ static void prepare_attr_stack(const char *path, int dirlen,\n \t * .gitattributes in deeper directories to shallower ones,\n \t * and finally use the built-in set as the default.\n \t */\n-\tbootstrap_attr_stack(stack);\n+\tbootstrap_attr_stack(istate, stack);\n \n \t/*\n \t * Pop the \"info\" one that is always at the top of the stack.\n@@ -973,7 +987,7 @@ static void prepare_attr_stack(const char *path, int dirlen,\n \t\tstrbuf_add(&pathbuf, path + pathbuf.len, (len - pathbuf.len));\n \t\tstrbuf_addf(&pathbuf, \"/%s\", GITATTRIBUTES_FILE);\n \n-\t\tnext = read_attr(pathbuf.buf, 0);\n+\t\tnext = read_attr(istate, pathbuf.buf, 0);\n \n \t\t/* reset the pathbuf to not include \"/.gitattributes\" */\n \t\tstrbuf_setlen(&pathbuf, len);\n@@ -1095,7 +1109,9 @@ static void determine_macros(struct all_attrs_item *all_attrs,\n  * If check->check_nr is non-zero, only attributes in check[] are collected.\n  * Otherwise all attributes are collected.\n  */\n-static void collect_some_attrs(const char *path, struct attr_check *check)\n+static void collect_some_attrs(const struct index_state *istate,\n+\t\t\t       const char *path,\n+\t\t\t       struct attr_check *check)\n {\n \tint i, pathlen, rem, dirlen;\n \tconst char *cp, *last_slash = NULL;\n@@ -1114,7 +1130,7 @@ static void collect_some_attrs(const char *path, struct attr_check *check)\n \t\tdirlen = 0;\n \t}\n \n-\tprepare_attr_stack(path, dirlen, &check->stack);\n+\tprepare_attr_stack(istate, path, dirlen, &check->stack);\n \tall_attrs_init(&g_attr_hashmap, check);\n \tdetermine_macros(check->all_attrs, check->stack);\n \n@@ -1136,11 +1152,13 @@ static void collect_some_attrs(const char *path, struct attr_check *check)\n \tfill(path, pathlen, basename_offset, check->stack, check->all_attrs, rem);\n }\n \n-int git_check_attr(const char *path, struct attr_check *check)\n+int git_check_attr(const struct index_state *istate,\n+\t\t   const char *path,\n+\t\t   struct attr_check *check)\n {\n \tint i;\n \n-\tcollect_some_attrs(path, check);\n+\tcollect_some_attrs(istate, path, check);\n \n \tfor (i = 0; i < check->nr; i++) {\n \t\tsize_t n = check->items[i].attr->attr_nr;\n@@ -1153,12 +1171,13 @@ int git_check_attr(const char *path, struct attr_check *check)\n \treturn 0;\n }\n \n-void git_all_attrs(const char *path, struct attr_check *check)\n+void git_all_attrs(const struct index_state *istate,\n+\t\t   const char *path, struct attr_check *check)\n {\n \tint i;\n \n \tattr_check_reset(check);\n-\tcollect_some_attrs(path, check);\n+\tcollect_some_attrs(istate, path, check);\n \n \tfor (i = 0; i < check->all_attrs_nr; i++) {\n \t\tconst char *name = check->all_attrs[i].attr->name;\ndiff --git a/attr.h b/attr.h\nindex 46340010bb..3daca3c0cb 100644\n--- a/attr.h\n+++ b/attr.h\n@@ -1,6 +1,8 @@\n #ifndef ATTR_H\n #define ATTR_H\n \n+struct index_state;\n+\n /* An attribute is a pointer to this opaque structure */\n struct git_attr;\n \n@@ -60,13 +62,15 @@ void attr_check_free(struct attr_check *check);\n  */\n const char *git_attr_name(const struct git_attr *);\n \n-int git_check_attr(const char *path, struct attr_check *check);\n+int git_check_attr(const struct index_state *istate,\n+\t\t   const char *path, struct attr_check *check);\n \n /*\n  * Retrieve all attributes that apply to the specified path.\n  * check holds the attributes and their values.\n  */\n-void git_all_attrs(const char *path, struct attr_check *check);\n+void git_all_attrs(const struct index_state *istate,\n+\t\t   const char *path, struct attr_check *check);\n \n enum git_attr_direction {\n \tGIT_ATTR_CHECKIN,\n@@ -74,7 +78,7 @@ enum git_attr_direction {\n \tGIT_ATTR_INDEX\n };\n void git_attr_set_direction(enum git_attr_direction new_direction,\n-\t\t\t    struct index_state *istate);\n+\t\t\t    const struct index_state *istate);\n \n void attr_start(void);\n \ndiff --git a/builtin/check-attr.c b/builtin/check-attr.c\nindex 91444dc044..f7b59993d3 100644\n--- a/builtin/check-attr.c\n+++ b/builtin/check-attr.c\n@@ -63,9 +63,9 @@ static void check_attr(const char *prefix,\n \t\tprefix_path(prefix, prefix ? strlen(prefix) : 0, file);\n \n \tif (collect_all) {\n-\t\tgit_all_attrs(full_path, check);\n+\t\tgit_all_attrs(&the_index, full_path, check);\n \t} else {\n-\t\tif (git_check_attr(full_path, check))\n+\t\tif (git_check_attr(&the_index, full_path, check))\n \t\t\tdie(\"git_check_attr died\");\n \t}\n \toutput_attr(check, file);\ndiff --git a/builtin/pack-objects.c b/builtin/pack-objects.c\nindex 4391504a91..3ff6da441f 100644\n--- a/builtin/pack-objects.c\n+++ b/builtin/pack-objects.c\n@@ -945,7 +945,7 @@ static int no_try_delta(const char *path)\n \n \tif (!check)\n \t\tcheck = attr_check_initl(\"delta\", NULL);\n-\tif (git_check_attr(path, check))\n+\tif (git_check_attr(&the_index, path, check))\n \t\treturn 0;\n \tif (ATTR_FALSE(check->items[0].value))\n \t\treturn 1;\ndiff --git a/convert.c b/convert.c\nindex 7907efd16f..1935bde929 100644\n--- a/convert.c\n+++ b/convert.c\n@@ -1303,7 +1303,7 @@ static void convert_attrs(struct conv_attrs *ca, const char *path)\n \t\tgit_config(read_convert_config, NULL);\n \t}\n \n-\tif (!git_check_attr(path, check)) {\n+\tif (!git_check_attr(&the_index, path, check)) {\n \t\tstruct attr_check_item *ccheck = check->items;\n \t\tca->crlf_action = git_path_check_crlf(ccheck + 4);\n \t\tif (ca->crlf_action == CRLF_UNDEFINED)\ndiff --git a/dir.c b/dir.c\nindex 21e6f2520a..29fbbd48c8 100644\n--- a/dir.c\n+++ b/dir.c\n@@ -281,7 +281,7 @@ static int match_attrs(const char *name, int namelen,\n {\n \tint i;\n \n-\tgit_check_attr(name, item->attr_check);\n+\tgit_check_attr(&the_index, name, item->attr_check);\n \tfor (i = 0; i < item->attr_match_nr; i++) {\n \t\tconst char *value;\n \t\tint matched;\ndiff --git a/ll-merge.c b/ll-merge.c\nindex a6ad2ec12d..0e2800f7bb 100644\n--- a/ll-merge.c\n+++ b/ll-merge.c\n@@ -371,7 +371,7 @@ int ll_merge(mmbuffer_t *result_buf,\n \tif (!check)\n \t\tcheck = attr_check_initl(\"merge\", \"conflict-marker-size\", NULL);\n \n-\tif (!git_check_attr(path, check)) {\n+\tif (!git_check_attr(&the_index, path, check)) {\n \t\tll_driver_name = check->items[0].value;\n \t\tif (check->items[1].value) {\n \t\t\tmarker_size = atoi(check->items[1].value);\n@@ -398,7 +398,7 @@ int ll_merge_marker_size(const char *path)\n \n \tif (!check)\n \t\tcheck = attr_check_initl(\"conflict-marker-size\", NULL);\n-\tif (!git_check_attr(path, check) && check->items[0].value) {\n+\tif (!git_check_attr(&the_index, path, check) && check->items[0].value) {\n \t\tmarker_size = atoi(check->items[0].value);\n \t\tif (marker_size <= 0)\n \t\t\tmarker_size = DEFAULT_CONFLICT_MARKER_SIZE;\ndiff --git a/userdiff.c b/userdiff.c\nindex 36af25e7f9..f3f4be579c 100644\n--- a/userdiff.c\n+++ b/userdiff.c\n@@ -278,7 +278,7 @@ struct userdiff_driver *userdiff_find_by_path(const char *path)\n \t\tcheck = attr_check_initl(\"diff\", NULL);\n \tif (!path)\n \t\treturn NULL;\n-\tif (git_check_attr(path, check))\n+\tif (git_check_attr(&the_index, path, check))\n \t\treturn NULL;\n \n \tif (ATTR_TRUE(check->items[0].value))\ndiff --git a/ws.c b/ws.c\nindex a07caedd5a..5b67b426e7 100644\n--- a/ws.c\n+++ b/ws.c\n@@ -78,7 +78,7 @@ unsigned whitespace_rule(const char *pathname)\n \tif (!attr_whitespace_rule)\n \t\tattr_whitespace_rule = attr_check_initl(\"whitespace\", NULL);\n \n-\tif (!git_check_attr(pathname, attr_whitespace_rule)) {\n+\tif (!git_check_attr(&the_index, pathname, attr_whitespace_rule)) {\n \t\tconst char *value;\n \n \t\tvalue = attr_whitespace_rule->items[0].value;\n-- \n2.18.0.1004.g6639190530\n\n"},{"id":"355373","messageId":"20180813161441.16824-5-pclouds@gmail.com","threadId":"49115","inReplyTo":"20180813161441.16824-1-pclouds@gmail.com","subject":"[PATCH 04/24] convert.c: remove an implicit dependency on the_index","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-08-13T16:14:21Z","receivedAt":"2018-08-13T16:15:28Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Make the convert API take an index_state instead of assuming the_index\nin convert.c. All external call sites are converted blindly to keep\nthe patch simple and retain current behavior. Individual call sites\nmay receive further updates to use the right index instead of\nthe_index.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n apply.c            |  2 +-\n archive.c          |  2 +-\n builtin/cat-file.c |  2 +-\n builtin/ls-files.c |  2 +-\n convert.c          | 41 ++++++++++++++++++++++++-----------------\n convert.h          | 15 ++++++++++-----\n diff.c             |  2 +-\n entry.c            |  6 +++---\n merge-recursive.c  |  2 +-\n sha1-file.c        |  4 ++--\n 10 files changed, 45 insertions(+), 33 deletions(-)\n\ndiff --git a/apply.c b/apply.c\nindex 2594927248..2476f06ebd 100644\n--- a/apply.c\n+++ b/apply.c\n@@ -4335,7 +4335,7 @@ static int try_create_file(const char *path, unsigned int mode, const char *buf,\n \tif (fd < 0)\n \t\treturn 1;\n \n-\tif (convert_to_working_tree(path, buf, size, &nbuf)) {\n+\tif (convert_to_working_tree(&the_index, path, buf, size, &nbuf)) {\n \t\tsize = nbuf.len;\n \t\tbuf  = nbuf.buf;\n \t}\ndiff --git a/archive.c b/archive.c\nindex a8397e6173..31de1bba52 100644\n--- a/archive.c\n+++ b/archive.c\n@@ -79,7 +79,7 @@ void *object_file_to_archive(const struct archiver_args *args,\n \t\tsize_t size = 0;\n \n \t\tstrbuf_attach(&buf, buffer, *sizep, *sizep + 1);\n-\t\tconvert_to_working_tree(path, buf.buf, buf.len, &buf);\n+\t\tconvert_to_working_tree(&the_index, path, buf.buf, buf.len, &buf);\n \t\tif (commit)\n \t\t\tformat_subst(commit, buf.buf, buf.len, &buf);\n \t\tbuffer = strbuf_detach(&buf, &size);\ndiff --git a/builtin/cat-file.c b/builtin/cat-file.c\nindex 4a44b2404f..c726ee1092 100644\n--- a/builtin/cat-file.c\n+++ b/builtin/cat-file.c\n@@ -39,7 +39,7 @@ static int filter_object(const char *path, unsigned mode,\n \t\t\t     oid_to_hex(oid), path);\n \tif ((type == OBJ_BLOB) && S_ISREG(mode)) {\n \t\tstruct strbuf strbuf = STRBUF_INIT;\n-\t\tif (convert_to_working_tree(path, *buf, *size, &strbuf)) {\n+\t\tif (convert_to_working_tree(&the_index, path, *buf, *size, &strbuf)) {\n \t\t\tfree(*buf);\n \t\t\t*size = strbuf.len;\n \t\t\t*buf = strbuf_detach(&strbuf, NULL);\ndiff --git a/builtin/ls-files.c b/builtin/ls-files.c\nindex 88bb2019ad..d996734b45 100644\n--- a/builtin/ls-files.c\n+++ b/builtin/ls-files.c\n@@ -63,7 +63,7 @@ static void write_eolinfo(const struct index_state *istate,\n \t\tstruct stat st;\n \t\tconst char *i_txt = \"\";\n \t\tconst char *w_txt = \"\";\n-\t\tconst char *a_txt = get_convert_attr_ascii(path);\n+\t\tconst char *a_txt = get_convert_attr_ascii(&the_index, path);\n \t\tif (ce && S_ISREG(ce->ce_mode))\n \t\t\ti_txt = get_cached_convert_stats_ascii(istate,\n \t\t\t\t\t\t\t       ce->name);\ndiff --git a/convert.c b/convert.c\nindex 1935bde929..8acfe8ae45 100644\n--- a/convert.c\n+++ b/convert.c\n@@ -1291,7 +1291,8 @@ struct conv_attrs {\n \tconst char *working_tree_encoding; /* Supported encoding or default encoding if NULL */\n };\n \n-static void convert_attrs(struct conv_attrs *ca, const char *path)\n+static void convert_attrs(const struct index_state *istate,\n+\t\t\t  struct conv_attrs *ca, const char *path)\n {\n \tstatic struct attr_check *check;\n \n@@ -1303,7 +1304,7 @@ static void convert_attrs(struct conv_attrs *ca, const char *path)\n \t\tgit_config(read_convert_config, NULL);\n \t}\n \n-\tif (!git_check_attr(&the_index, path, check)) {\n+\tif (!git_check_attr(istate, path, check)) {\n \t\tstruct attr_check_item *ccheck = check->items;\n \t\tca->crlf_action = git_path_check_crlf(ccheck + 4);\n \t\tif (ca->crlf_action == CRLF_UNDEFINED)\n@@ -1340,11 +1341,11 @@ static void convert_attrs(struct conv_attrs *ca, const char *path)\n \t\tca->crlf_action = CRLF_AUTO_INPUT;\n }\n \n-int would_convert_to_git_filter_fd(const char *path)\n+int would_convert_to_git_filter_fd(const struct index_state *istate, const char *path)\n {\n \tstruct conv_attrs ca;\n \n-\tconvert_attrs(&ca, path);\n+\tconvert_attrs(istate, &ca, path);\n \tif (!ca.drv)\n \t\treturn 0;\n \n@@ -1359,11 +1360,11 @@ int would_convert_to_git_filter_fd(const char *path)\n \treturn apply_filter(path, NULL, 0, -1, NULL, ca.drv, CAP_CLEAN, NULL);\n }\n \n-const char *get_convert_attr_ascii(const char *path)\n+const char *get_convert_attr_ascii(const struct index_state *istate, const char *path)\n {\n \tstruct conv_attrs ca;\n \n-\tconvert_attrs(&ca, path);\n+\tconvert_attrs(istate, &ca, path);\n \tswitch (ca.attr_action) {\n \tcase CRLF_UNDEFINED:\n \t\treturn \"\";\n@@ -1392,7 +1393,7 @@ int convert_to_git(const struct index_state *istate,\n \tint ret = 0;\n \tstruct conv_attrs ca;\n \n-\tconvert_attrs(&ca, path);\n+\tconvert_attrs(istate, &ca, path);\n \n \tret |= apply_filter(path, src, len, -1, dst, ca.drv, CAP_CLEAN, NULL);\n \tif (!ret && ca.drv && ca.drv->required)\n@@ -1424,7 +1425,7 @@ void convert_to_git_filter_fd(const struct index_state *istate,\n \t\t\t      int conv_flags)\n {\n \tstruct conv_attrs ca;\n-\tconvert_attrs(&ca, path);\n+\tconvert_attrs(istate, &ca, path);\n \n \tassert(ca.drv);\n \tassert(ca.drv->clean || ca.drv->process);\n@@ -1437,14 +1438,15 @@ void convert_to_git_filter_fd(const struct index_state *istate,\n \tident_to_git(path, dst->buf, dst->len, dst, ca.ident);\n }\n \n-static int convert_to_working_tree_internal(const char *path, const char *src,\n+static int convert_to_working_tree_internal(const struct index_state *istate,\n+\t\t\t\t\t    const char *path, const char *src,\n \t\t\t\t\t    size_t len, struct strbuf *dst,\n \t\t\t\t\t    int normalizing, struct delayed_checkout *dco)\n {\n \tint ret = 0, ret_filter = 0;\n \tstruct conv_attrs ca;\n \n-\tconvert_attrs(&ca, path);\n+\tconvert_attrs(istate, &ca, path);\n \n \tret |= ident_to_worktree(path, src, len, dst, ca.ident);\n \tif (ret) {\n@@ -1478,22 +1480,25 @@ static int convert_to_working_tree_internal(const char *path, const char *src,\n \treturn ret | ret_filter;\n }\n \n-int async_convert_to_working_tree(const char *path, const char *src,\n+int async_convert_to_working_tree(const struct index_state *istate,\n+\t\t\t\t  const char *path, const char *src,\n \t\t\t\t  size_t len, struct strbuf *dst,\n \t\t\t\t  void *dco)\n {\n-\treturn convert_to_working_tree_internal(path, src, len, dst, 0, dco);\n+\treturn convert_to_working_tree_internal(istate, path, src, len, dst, 0, dco);\n }\n \n-int convert_to_working_tree(const char *path, const char *src, size_t len, struct strbuf *dst)\n+int convert_to_working_tree(const struct index_state *istate,\n+\t\t\t    const char *path, const char *src,\n+\t\t\t    size_t len, struct strbuf *dst)\n {\n-\treturn convert_to_working_tree_internal(path, src, len, dst, 0, NULL);\n+\treturn convert_to_working_tree_internal(istate, path, src, len, dst, 0, NULL);\n }\n \n int renormalize_buffer(const struct index_state *istate, const char *path,\n \t\t       const char *src, size_t len, struct strbuf *dst)\n {\n-\tint ret = convert_to_working_tree_internal(path, src, len, dst, 1, NULL);\n+\tint ret = convert_to_working_tree_internal(istate, path, src, len, dst, 1, NULL);\n \tif (ret) {\n \t\tsrc = dst->buf;\n \t\tlen = dst->len;\n@@ -1927,12 +1932,14 @@ static struct stream_filter *ident_filter(const struct object_id *oid)\n  * Note that you would be crazy to set CRLF, smuge/clean or ident to a\n  * large binary blob you would want us not to slurp into the memory!\n  */\n-struct stream_filter *get_stream_filter(const char *path, const struct object_id *oid)\n+struct stream_filter *get_stream_filter(const struct index_state *istate,\n+\t\t\t\t\tconst char *path,\n+\t\t\t\t\tconst struct object_id *oid)\n {\n \tstruct conv_attrs ca;\n \tstruct stream_filter *filter = NULL;\n \n-\tconvert_attrs(&ca, path);\n+\tconvert_attrs(istate, &ca, path);\n \tif (ca.drv && (ca.drv->process || ca.drv->smudge || ca.drv->clean))\n \t\treturn NULL;\n \ndiff --git a/convert.h b/convert.h\nindex 0a0fa15b58..6d0ee887ed 100644\n--- a/convert.h\n+++ b/convert.h\n@@ -60,15 +60,18 @@ extern char *check_roundtrip_encoding;\n const char *get_cached_convert_stats_ascii(const struct index_state *istate,\n \t\t\t\t\t   const char *path);\n const char *get_wt_convert_stats_ascii(const char *path);\n-const char *get_convert_attr_ascii(const char *path);\n+const char *get_convert_attr_ascii(const struct index_state *istate,\n+\t\t\t\t   const char *path);\n \n /* returns 1 if *dst was used */\n int convert_to_git(const struct index_state *istate,\n \t\t   const char *path, const char *src, size_t len,\n \t\t   struct strbuf *dst, int conv_flags);\n-int convert_to_working_tree(const char *path, const char *src,\n+int convert_to_working_tree(const struct index_state *istate,\n+\t\t\t    const char *path, const char *src,\n \t\t\t    size_t len, struct strbuf *dst);\n-int async_convert_to_working_tree(const char *path, const char *src,\n+int async_convert_to_working_tree(const struct index_state *istate,\n+\t\t\t\t  const char *path, const char *src,\n \t\t\t\t  size_t len, struct strbuf *dst,\n \t\t\t\t  void *dco);\n int async_query_available_blobs(const char *cmd,\n@@ -86,7 +89,8 @@ void convert_to_git_filter_fd(const struct index_state *istate,\n \t\t\t      const char *path, int fd,\n \t\t\t      struct strbuf *dst,\n \t\t\t      int conv_flags);\n-int would_convert_to_git_filter_fd(const char *path);\n+int would_convert_to_git_filter_fd(const struct index_state *istate,\n+\t\t\t\t   const char *path);\n \n /*****************************************************************\n  *\n@@ -96,7 +100,8 @@ int would_convert_to_git_filter_fd(const char *path);\n \n struct stream_filter; /* opaque */\n \n-struct stream_filter *get_stream_filter(const char *path,\n+struct stream_filter *get_stream_filter(const struct index_state *istate,\n+\t\t\t\t\tconst char *path,\n \t\t\t\t\tconst struct object_id *);\n void free_stream_filter(struct stream_filter *);\n int is_null_stream_filter(struct stream_filter *);\ndiff --git a/diff.c b/diff.c\nindex 72ce8007fd..3670206d23 100644\n--- a/diff.c\n+++ b/diff.c\n@@ -3893,7 +3893,7 @@ static void prep_temp_blob(const char *path, struct diff_tempfile *temp,\n \ttemp->tempfile = mks_tempfile_ts(tempfile.buf, strlen(base) + 1);\n \tif (!temp->tempfile)\n \t\tdie_errno(\"unable to create temp-file\");\n-\tif (convert_to_working_tree(path,\n+\tif (convert_to_working_tree(&the_index, path,\n \t\t\t(const char *)blob, (size_t)size, &buf)) {\n \t\tblob = buf.buf;\n \t\tsize = buf.len;\ndiff --git a/entry.c b/entry.c\nindex b5d1d3cf23..b2381fd9f6 100644\n--- a/entry.c\n+++ b/entry.c\n@@ -266,7 +266,7 @@ static int write_entry(struct cache_entry *ce,\n \tconst struct submodule *sub;\n \n \tif (ce_mode_s_ifmt == S_IFREG) {\n-\t\tstruct stream_filter *filter = get_stream_filter(ce->name,\n+\t\tstruct stream_filter *filter = get_stream_filter(&the_index, ce->name,\n \t\t\t\t\t\t\t\t &ce->oid);\n \t\tif (filter &&\n \t\t    !streaming_write_entry(ce, path, filter,\n@@ -314,14 +314,14 @@ static int write_entry(struct cache_entry *ce,\n \t\t * Convert from git internal format to working tree format\n \t\t */\n \t\tif (dco && dco->state != CE_NO_DELAY) {\n-\t\t\tret = async_convert_to_working_tree(ce->name, new_blob,\n+\t\t\tret = async_convert_to_working_tree(&the_index, ce->name, new_blob,\n \t\t\t\t\t\t\t    size, &buf, dco);\n \t\t\tif (ret && string_list_has_string(&dco->paths, ce->name)) {\n \t\t\t\tfree(new_blob);\n \t\t\t\tgoto delayed;\n \t\t\t}\n \t\t} else\n-\t\t\tret = convert_to_working_tree(ce->name, new_blob, size, &buf);\n+\t\t\tret = convert_to_working_tree(&the_index, ce->name, new_blob, size, &buf);\n \n \t\tif (ret) {\n \t\t\tfree(new_blob);\ndiff --git a/merge-recursive.c b/merge-recursive.c\nindex 1446e92bea..defcbff93b 100644\n--- a/merge-recursive.c\n+++ b/merge-recursive.c\n@@ -966,7 +966,7 @@ static int update_file_flags(struct merge_options *o,\n \t\t}\n \t\tif (S_ISREG(mode)) {\n \t\t\tstruct strbuf strbuf = STRBUF_INIT;\n-\t\t\tif (convert_to_working_tree(path, buf, size, &strbuf)) {\n+\t\t\tif (convert_to_working_tree(&the_index, path, buf, size, &strbuf)) {\n \t\t\t\tfree(buf);\n \t\t\t\tsize = strbuf.len;\n \t\t\t\tbuf = strbuf_detach(&strbuf, NULL);\ndiff --git a/sha1-file.c b/sha1-file.c\nindex dfa8a35d68..0016d46052 100644\n--- a/sha1-file.c\n+++ b/sha1-file.c\n@@ -1860,7 +1860,7 @@ static int index_stream_convert_blob(struct object_id *oid, int fd,\n \tstruct strbuf sbuf = STRBUF_INIT;\n \n \tassert(path);\n-\tassert(would_convert_to_git_filter_fd(path));\n+\tassert(would_convert_to_git_filter_fd(&the_index, path));\n \n \tconvert_to_git_filter_fd(&the_index, path, fd, &sbuf,\n \t\t\t\t get_conv_flags(flags));\n@@ -1950,7 +1950,7 @@ int index_fd(struct object_id *oid, int fd, struct stat *st,\n \t * Call xsize_t() only when needed to avoid potentially unnecessary\n \t * die() for large files.\n \t */\n-\tif (type == OBJ_BLOB && path && would_convert_to_git_filter_fd(path))\n+\tif (type == OBJ_BLOB && path && would_convert_to_git_filter_fd(&the_index, path))\n \t\tret = index_stream_convert_blob(oid, fd, path, flags);\n \telse if (!S_ISREG(st->st_mode))\n \t\tret = index_pipe(oid, fd, type, path, flags);\n-- \n2.18.0.1004.g6639190530\n\n"},{"id":"355374","messageId":"20180813161441.16824-7-pclouds@gmail.com","threadId":"49115","inReplyTo":"20180813161441.16824-1-pclouds@gmail.com","subject":"[PATCH 06/24] preload-index.c: use the right index instead of the_index","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-08-13T16:14:23Z","receivedAt":"2018-08-13T16:15:30Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n preload-index.c | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/preload-index.c b/preload-index.c\nindex d61d7662d5..71cd2437a3 100644\n--- a/preload-index.c\n+++ b/preload-index.c\n@@ -58,7 +58,7 @@ static void *preload_thread(void *_data)\n \t\t\tcontinue;\n \t\tif (ce->ce_flags & CE_FSMONITOR_VALID)\n \t\t\tcontinue;\n-\t\tif (!ce_path_match(&the_index, ce, &p->pathspec, NULL))\n+\t\tif (!ce_path_match(index, ce, &p->pathspec, NULL))\n \t\t\tcontinue;\n \t\tif (threaded_has_symlink_leading_path(&cache, ce->name, ce_namelen(ce)))\n \t\t\tcontinue;\n-- \n2.18.0.1004.g6639190530\n\n"},{"id":"355375","messageId":"20180813161441.16824-6-pclouds@gmail.com","threadId":"49115","inReplyTo":"20180813161441.16824-1-pclouds@gmail.com","subject":"[PATCH 05/24] dir.c: remove an implicit dependency on the_index in pathspec code","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-08-13T16:14:22Z","receivedAt":"2018-08-13T16:15:31Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Make the match_patchspec API and friends take an index_state instead\nof assuming the_index in dir.c. All external call sites are converted\nblindly to keep the patch simple and retain current behavior.\nIndividual call sites may receive further updates to use the right\nindex instead of the_index.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n archive.c                   |  2 +-\n builtin/add.c               |  6 +++---\n builtin/checkout.c          |  2 +-\n builtin/clean.c             |  2 +-\n builtin/commit.c            |  2 +-\n builtin/grep.c              |  6 +++---\n builtin/ls-files.c          |  6 +++---\n builtin/rm.c                |  2 +-\n builtin/submodule--helper.c |  2 +-\n builtin/update-index.c      |  2 +-\n diff-lib.c                  |  4 ++--\n dir.c                       | 27 ++++++++++++++++-----------\n dir.h                       | 16 ++++++++++------\n pathspec.c                  |  2 +-\n preload-index.c             |  2 +-\n read-cache.c                |  2 +-\n rerere.c                    |  2 +-\n resolve-undo.c              |  2 +-\n revision.c                  |  2 +-\n submodule.c                 |  2 +-\n wt-status.c                 |  6 +++---\n 21 files changed, 54 insertions(+), 45 deletions(-)\n\ndiff --git a/archive.c b/archive.c\nindex 31de1bba52..c81e35bf23 100644\n--- a/archive.c\n+++ b/archive.c\n@@ -313,7 +313,7 @@ static int reject_entry(const struct object_id *oid, struct strbuf *base,\n \t\tstruct strbuf sb = STRBUF_INIT;\n \t\tstrbuf_addbuf(&sb, base);\n \t\tstrbuf_addstr(&sb, filename);\n-\t\tif (!match_pathspec(context, sb.buf, sb.len, 0, NULL, 1))\n+\t\tif (!match_pathspec(&the_index, context, sb.buf, sb.len, 0, NULL, 1))\n \t\t\tret = READ_TREE_RECURSIVE;\n \t\tstrbuf_release(&sb);\n \t}\ndiff --git a/builtin/add.c b/builtin/add.c\nindex 8a155dd41e..066623a195 100644\n--- a/builtin/add.c\n+++ b/builtin/add.c\n@@ -40,7 +40,7 @@ static void chmod_pathspec(struct pathspec *pathspec, char flip)\n \tfor (i = 0; i < active_nr; i++) {\n \t\tstruct cache_entry *ce = active_cache[i];\n \n-\t\tif (pathspec && !ce_path_match(ce, pathspec, NULL))\n+\t\tif (pathspec && !ce_path_match(&the_index, ce, pathspec, NULL))\n \t\t\tcontinue;\n \n \t\tif (chmod_cache_entry(ce, flip) < 0)\n@@ -135,7 +135,7 @@ static int renormalize_tracked_files(const struct pathspec *pathspec, int flags)\n \t\t\tcontinue; /* do not touch unmerged paths */\n \t\tif (!S_ISREG(ce->ce_mode) && !S_ISLNK(ce->ce_mode))\n \t\t\tcontinue; /* do not touch non blobs */\n-\t\tif (pathspec && !ce_path_match(ce, pathspec, NULL))\n+\t\tif (pathspec && !ce_path_match(&the_index, ce, pathspec, NULL))\n \t\t\tcontinue;\n \t\tretval |= add_file_to_cache(ce->name, flags | HASH_RENORMALIZE);\n \t}\n@@ -155,7 +155,7 @@ static char *prune_directory(struct dir_struct *dir, struct pathspec *pathspec,\n \ti = dir->nr;\n \twhile (--i >= 0) {\n \t\tstruct dir_entry *entry = *src++;\n-\t\tif (dir_path_match(entry, pathspec, prefix, seen))\n+\t\tif (dir_path_match(&the_index, entry, pathspec, prefix, seen))\n \t\t\t*dst++ = entry;\n \t}\n \tdir->nr = dst - dir->entries;\ndiff --git a/builtin/checkout.c b/builtin/checkout.c\nindex 516136a23a..54acb8d268 100644\n--- a/builtin/checkout.c\n+++ b/builtin/checkout.c\n@@ -318,7 +318,7 @@ static int checkout_paths(const struct checkout_opts *opts,\n \t\t * match_pathspec() for _all_ entries when\n \t\t * opts->source_tree != NULL.\n \t\t */\n-\t\tif (ce_path_match(ce, &opts->pathspec, ps_matched))\n+\t\tif (ce_path_match(&the_index, ce, &opts->pathspec, ps_matched))\n \t\t\tce->ce_flags |= CE_MATCHED;\n \t}\n \ndiff --git a/builtin/clean.c b/builtin/clean.c\nindex ab402c204c..8d9a7dc206 100644\n--- a/builtin/clean.c\n+++ b/builtin/clean.c\n@@ -976,7 +976,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)\n \t\t\tcontinue;\n \n \t\tif (pathspec.nr)\n-\t\t\tmatches = dir_path_match(ent, &pathspec, 0, NULL);\n+\t\t\tmatches = dir_path_match(&the_index, ent, &pathspec, 0, NULL);\n \n \t\tif (pathspec.nr && !matches)\n \t\t\tcontinue;\ndiff --git a/builtin/commit.c b/builtin/commit.c\nindex 158e3f843a..21277dd42e 100644\n--- a/builtin/commit.c\n+++ b/builtin/commit.c\n@@ -251,7 +251,7 @@ static int list_paths(struct string_list *list, const char *with_tree,\n \n \t\tif (ce->ce_flags & CE_UPDATE)\n \t\t\tcontinue;\n-\t\tif (!ce_path_match(ce, pattern, m))\n+\t\tif (!ce_path_match(&the_index, ce, pattern, m))\n \t\t\tcontinue;\n \t\titem = string_list_insert(list, ce->name);\n \t\tif (ce_skip_worktree(ce))\ndiff --git a/builtin/grep.c b/builtin/grep.c\nindex 056161f0f8..9d7ba87f9b 100644\n--- a/builtin/grep.c\n+++ b/builtin/grep.c\n@@ -497,7 +497,7 @@ static int grep_cache(struct grep_opt *opt, struct repository *repo,\n \t\tstrbuf_addstr(&name, ce->name);\n \n \t\tif (S_ISREG(ce->ce_mode) &&\n-\t\t    match_pathspec(pathspec, name.buf, name.len, 0, NULL,\n+\t\t    match_pathspec(&the_index, pathspec, name.buf, name.len, 0, NULL,\n \t\t\t\t   S_ISDIR(ce->ce_mode) ||\n \t\t\t\t   S_ISGITLINK(ce->ce_mode))) {\n \t\t\t/*\n@@ -515,7 +515,7 @@ static int grep_cache(struct grep_opt *opt, struct repository *repo,\n \t\t\t\thit |= grep_file(opt, name.buf);\n \t\t\t}\n \t\t} else if (recurse_submodules && S_ISGITLINK(ce->ce_mode) &&\n-\t\t\t   submodule_path_match(pathspec, name.buf, NULL)) {\n+\t\t\t   submodule_path_match(&the_index, pathspec, name.buf, NULL)) {\n \t\t\thit |= grep_submodule(opt, repo, pathspec, NULL, ce->name, ce->name);\n \t\t} else {\n \t\t\tcontinue;\n@@ -679,7 +679,7 @@ static int grep_directory(struct grep_opt *opt, const struct pathspec *pathspec,\n \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\tif (!dir_path_match(&the_index, dir.entries[i], pathspec, 0, NULL))\n \t\t\tcontinue;\n \t\thit |= grep_file(opt, dir.entries[i]->name);\n \t\tif (hit && opt->status_only)\ndiff --git a/builtin/ls-files.c b/builtin/ls-files.c\nindex d996734b45..7233b92794 100644\n--- a/builtin/ls-files.c\n+++ b/builtin/ls-files.c\n@@ -128,7 +128,7 @@ static void show_dir_entry(const char *tag, struct dir_entry *ent)\n \tif (len > ent->len)\n \t\tdie(\"git ls-files: internal error - directory entry not superset of prefix\");\n \n-\tif (!dir_path_match(ent, &pathspec, len, ps_matched))\n+\tif (!dir_path_match(&the_index, ent, &pathspec, len, ps_matched))\n \t\treturn;\n \n \tfputs(tag, stdout);\n@@ -228,7 +228,7 @@ static void show_ce(struct repository *repo, struct dir_struct *dir,\n \tif (recurse_submodules && S_ISGITLINK(ce->ce_mode) &&\n \t    is_submodule_active(repo, ce->name)) {\n \t\tshow_submodule(repo, dir, ce->name);\n-\t} else if (match_pathspec(&pathspec, fullname, strlen(fullname),\n+\t} else if (match_pathspec(&the_index, &pathspec, fullname, strlen(fullname),\n \t\t\t\t  max_prefix_len, ps_matched,\n \t\t\t\t  S_ISDIR(ce->ce_mode) ||\n \t\t\t\t  S_ISGITLINK(ce->ce_mode))) {\n@@ -264,7 +264,7 @@ static void show_ru_info(const struct index_state *istate)\n \t\tlen = strlen(path);\n \t\tif (len < max_prefix_len)\n \t\t\tcontinue; /* outside of the prefix */\n-\t\tif (!match_pathspec(&pathspec, path, len,\n+\t\tif (!match_pathspec(&the_index, &pathspec, path, len,\n \t\t\t\t    max_prefix_len, ps_matched, 0))\n \t\t\tcontinue; /* uninterested */\n \t\tfor (i = 0; i < 3; i++) {\ndiff --git a/builtin/rm.c b/builtin/rm.c\nindex 65b448ef8e..eebdc4aab1 100644\n--- a/builtin/rm.c\n+++ b/builtin/rm.c\n@@ -278,7 +278,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix)\n \n \tfor (i = 0; i < active_nr; i++) {\n \t\tconst struct cache_entry *ce = active_cache[i];\n-\t\tif (!ce_path_match(ce, &pathspec, seen))\n+\t\tif (!ce_path_match(&the_index, ce, &pathspec, seen))\n \t\t\tcontinue;\n \t\tALLOC_GROW(list.entry, list.nr + 1, list.alloc);\n \t\tlist.entry[list.nr].name = xstrdup(ce->name);\ndiff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c\nindex a3c4564c6c..a4440a3109 100644\n--- a/builtin/submodule--helper.c\n+++ b/builtin/submodule--helper.c\n@@ -331,7 +331,7 @@ static int module_list_compute(int argc, const char **argv,\n \tfor (i = 0; i < active_nr; i++) {\n \t\tconst struct cache_entry *ce = active_cache[i];\n \n-\t\tif (!match_pathspec(pathspec, ce->name, ce_namelen(ce),\n+\t\tif (!match_pathspec(&the_index, pathspec, ce->name, ce_namelen(ce),\n \t\t\t\t    0, ps_matched, 1) ||\n \t\t    !S_ISGITLINK(ce->ce_mode))\n \t\t\tcontinue;\ndiff --git a/builtin/update-index.c b/builtin/update-index.c\nindex f5c0b6a1d2..f75fd24083 100644\n--- a/builtin/update-index.c\n+++ b/builtin/update-index.c\n@@ -748,7 +748,7 @@ static int do_reupdate(int ac, const char **av,\n \t\tint save_nr;\n \t\tchar *path;\n \n-\t\tif (ce_stage(ce) || !ce_path_match(ce, &pathspec, NULL))\n+\t\tif (ce_stage(ce) || !ce_path_match(&the_index, ce, &pathspec, NULL))\n \t\t\tcontinue;\n \t\tif (has_head)\n \t\t\told = read_one_ent(NULL, &head_oid,\ndiff --git a/diff-lib.c b/diff-lib.c\nindex 732f684a49..88a98b1c06 100644\n--- a/diff-lib.c\n+++ b/diff-lib.c\n@@ -109,7 +109,7 @@ int run_diff_files(struct rev_info *revs, unsigned int option)\n \t\tif (diff_can_quit_early(&revs->diffopt))\n \t\t\tbreak;\n \n-\t\tif (!ce_path_match(ce, &revs->prune_data, NULL))\n+\t\tif (!ce_path_match(&the_index, ce, &revs->prune_data, NULL))\n \t\t\tcontinue;\n \n \t\tif (ce_stage(ce)) {\n@@ -474,7 +474,7 @@ static int oneway_diff(const struct cache_entry * const *src,\n \tif (tree == o->df_conflict_entry)\n \t\ttree = NULL;\n \n-\tif (ce_path_match(idx ? idx : tree, &revs->prune_data, NULL)) {\n+\tif (ce_path_match(&the_index, idx ? idx : tree, &revs->prune_data, NULL)) {\n \t\tdo_oneway_diff(o, idx, tree);\n \t\tif (diff_can_quit_early(&revs->diffopt)) {\n \t\t\to->exiting_early = 1;\ndiff --git a/dir.c b/dir.c\nindex 29fbbd48c8..e25aed013b 100644\n--- a/dir.c\n+++ b/dir.c\n@@ -276,12 +276,13 @@ static int do_read_blob(const struct object_id *oid, struct oid_stat *oid_stat,\n #define DO_MATCH_DIRECTORY (1<<1)\n #define DO_MATCH_SUBMODULE (1<<2)\n \n-static int match_attrs(const char *name, int namelen,\n+static int match_attrs(const struct index_state *istate,\n+\t\t       const char *name, int namelen,\n \t\t       const struct pathspec_item *item)\n {\n \tint i;\n \n-\tgit_check_attr(&the_index, name, item->attr_check);\n+\tgit_check_attr(istate, name, item->attr_check);\n \tfor (i = 0; i < item->attr_match_nr; i++) {\n \t\tconst char *value;\n \t\tint matched;\n@@ -318,7 +319,8 @@ static int match_attrs(const char *name, int namelen,\n  *\n  * It returns 0 when there is no match.\n  */\n-static int match_pathspec_item(const struct pathspec_item *item, int prefix,\n+static int match_pathspec_item(const struct index_state *istate,\n+\t\t\t       const struct pathspec_item *item, int prefix,\n \t\t\t       const char *name, int namelen, unsigned flags)\n {\n \t/* name/namelen has prefix cut off by caller */\n@@ -358,7 +360,7 @@ static int match_pathspec_item(const struct pathspec_item *item, int prefix,\n \t    strncmp(item->match, name - prefix, item->prefix))\n \t\treturn 0;\n \n-\tif (item->attr_match_nr && !match_attrs(name, namelen, item))\n+\tif (item->attr_match_nr && !match_attrs(istate, name, namelen, item))\n \t\treturn 0;\n \n \t/* If the match was just the prefix, we matched */\n@@ -426,7 +428,8 @@ static int match_pathspec_item(const struct pathspec_item *item, int prefix,\n  * pathspec did not match any names, which could indicate that the\n  * user mistyped the nth pathspec.\n  */\n-static int do_match_pathspec(const struct pathspec *ps,\n+static int do_match_pathspec(const struct index_state *istate,\n+\t\t\t     const struct pathspec *ps,\n \t\t\t     const char *name, int namelen,\n \t\t\t     int prefix, char *seen,\n \t\t\t     unsigned flags)\n@@ -472,7 +475,7 @@ static int do_match_pathspec(const struct pathspec *ps,\n \t\t */\n \t\tif (seen && ps->items[i].magic & PATHSPEC_EXCLUDE)\n \t\t\tseen[i] = MATCHED_FNMATCH;\n-\t\thow = match_pathspec_item(ps->items+i, prefix, name,\n+\t\thow = match_pathspec_item(istate, ps->items+i, prefix, name,\n \t\t\t\t\t  namelen, flags);\n \t\tif (ps->recursive &&\n \t\t    (ps->magic & PATHSPEC_MAXDEPTH) &&\n@@ -496,17 +499,18 @@ static int do_match_pathspec(const struct pathspec *ps,\n \treturn retval;\n }\n \n-int match_pathspec(const struct pathspec *ps,\n+int match_pathspec(const struct index_state *istate,\n+\t\t   const struct pathspec *ps,\n \t\t   const char *name, int namelen,\n \t\t   int prefix, char *seen, int is_dir)\n {\n \tint positive, negative;\n \tunsigned flags = is_dir ? DO_MATCH_DIRECTORY : 0;\n-\tpositive = do_match_pathspec(ps, name, namelen,\n+\tpositive = do_match_pathspec(istate, ps, name, namelen,\n \t\t\t\t     prefix, seen, flags);\n \tif (!(ps->magic & PATHSPEC_EXCLUDE) || !positive)\n \t\treturn positive;\n-\tnegative = do_match_pathspec(ps, name, namelen,\n+\tnegative = do_match_pathspec(istate, ps, name, namelen,\n \t\t\t\t     prefix, seen,\n \t\t\t\t     flags | DO_MATCH_EXCLUDE);\n \treturn negative ? 0 : positive;\n@@ -515,11 +519,12 @@ int match_pathspec(const struct pathspec *ps,\n /**\n  * Check if a submodule is a superset of the pathspec\n  */\n-int submodule_path_match(const struct pathspec *ps,\n+int submodule_path_match(const struct index_state *istate,\n+\t\t\t const struct pathspec *ps,\n \t\t\t const char *submodule_name,\n \t\t\t char *seen)\n {\n-\tint matched = do_match_pathspec(ps, submodule_name,\n+\tint matched = do_match_pathspec(istate, ps, submodule_name,\n \t\t\t\t\tstrlen(submodule_name),\n \t\t\t\t\t0, seen,\n \t\t\t\t\tDO_MATCH_DIRECTORY |\ndiff --git a/dir.h b/dir.h\nindex f5fdedbab2..e3ec26143d 100644\n--- a/dir.h\n+++ b/dir.h\n@@ -216,7 +216,8 @@ extern int count_slashes(const char *s);\n extern int simple_length(const char *match);\n extern int no_wildcard(const char *string);\n extern char *common_prefix(const struct pathspec *pathspec);\n-extern int match_pathspec(const struct pathspec *pathspec,\n+extern int match_pathspec(const struct index_state *istate,\n+\t\t\t  const struct pathspec *pathspec,\n \t\t\t  const char *name, int namelen,\n \t\t\t  int prefix, char *seen, int is_dir);\n extern int report_path_error(const char *ps_matched, const struct pathspec *pathspec, const char *prefix);\n@@ -326,25 +327,28 @@ extern int git_fnmatch(const struct pathspec_item *item,\n \t\t       const char *pattern, const char *string,\n \t\t       int prefix);\n \n-extern int submodule_path_match(const struct pathspec *ps,\n+extern int submodule_path_match(const struct index_state *istate,\n+\t\t\t\tconst struct pathspec *ps,\n \t\t\t\tconst char *submodule_name,\n \t\t\t\tchar *seen);\n \n-static inline int ce_path_match(const struct cache_entry *ce,\n+static inline int ce_path_match(const struct index_state *istate,\n+\t\t\t\tconst struct cache_entry *ce,\n \t\t\t\tconst struct pathspec *pathspec,\n \t\t\t\tchar *seen)\n {\n-\treturn match_pathspec(pathspec, ce->name, ce_namelen(ce), 0, seen,\n+\treturn match_pathspec(istate, pathspec, ce->name, ce_namelen(ce), 0, seen,\n \t\t\t      S_ISDIR(ce->ce_mode) || S_ISGITLINK(ce->ce_mode));\n }\n \n-static inline int dir_path_match(const struct dir_entry *ent,\n+static inline int dir_path_match(const struct index_state *istate,\n+\t\t\t\t const struct dir_entry *ent,\n \t\t\t\t const struct pathspec *pathspec,\n \t\t\t\t int prefix, char *seen)\n {\n \tint has_trailing_dir = ent->len && ent->name[ent->len - 1] == '/';\n \tint len = has_trailing_dir ? ent->len - 1 : ent->len;\n-\treturn match_pathspec(pathspec, ent->name, len, prefix, seen,\n+\treturn match_pathspec(istate, pathspec, ent->name, len, prefix, seen,\n \t\t\t      has_trailing_dir);\n }\n \ndiff --git a/pathspec.c b/pathspec.c\nindex 27cd606786..897cb9cbbe 100644\n--- a/pathspec.c\n+++ b/pathspec.c\n@@ -37,7 +37,7 @@ void add_pathspec_matches_against_index(const struct pathspec *pathspec,\n \t\treturn;\n \tfor (i = 0; i < istate->cache_nr; i++) {\n \t\tconst struct cache_entry *ce = istate->cache[i];\n-\t\tce_path_match(ce, pathspec, seen);\n+\t\tce_path_match(&the_index, ce, pathspec, seen);\n \t}\n }\n \ndiff --git a/preload-index.c b/preload-index.c\nindex 4d08d44874..d61d7662d5 100644\n--- a/preload-index.c\n+++ b/preload-index.c\n@@ -58,7 +58,7 @@ static void *preload_thread(void *_data)\n \t\t\tcontinue;\n \t\tif (ce->ce_flags & CE_FSMONITOR_VALID)\n \t\t\tcontinue;\n-\t\tif (!ce_path_match(ce, &p->pathspec, NULL))\n+\t\tif (!ce_path_match(&the_index, ce, &p->pathspec, NULL))\n \t\t\tcontinue;\n \t\tif (threaded_has_symlink_leading_path(&cache, ce->name, ce_namelen(ce)))\n \t\t\tcontinue;\ndiff --git a/read-cache.c b/read-cache.c\nindex 880849fc8a..3a930bbcc1 100644\n--- a/read-cache.c\n+++ b/read-cache.c\n@@ -1493,7 +1493,7 @@ int refresh_index(struct index_state *istate, unsigned int flags,\n \t\tif (ignore_submodules && S_ISGITLINK(ce->ce_mode))\n \t\t\tcontinue;\n \n-\t\tif (pathspec && !ce_path_match(ce, pathspec, seen))\n+\t\tif (pathspec && !ce_path_match(&the_index, ce, pathspec, seen))\n \t\t\tfiltered = 1;\n \n \t\tif (ce_stage(ce)) {\ndiff --git a/rerere.c b/rerere.c\nindex 16c8aac621..c7787aa07f 100644\n--- a/rerere.c\n+++ b/rerere.c\n@@ -1120,7 +1120,7 @@ int rerere_forget(struct pathspec *pathspec)\n \tfind_conflict(&conflict);\n \tfor (i = 0; i < conflict.nr; i++) {\n \t\tstruct string_list_item *it = &conflict.items[i];\n-\t\tif (!match_pathspec(pathspec, it->string,\n+\t\tif (!match_pathspec(&the_index, pathspec, it->string,\n \t\t\t\t    strlen(it->string), 0, NULL, 0))\n \t\t\tcontinue;\n \t\trerere_forget_one_path(it->string, &merge_rr);\ndiff --git a/resolve-undo.c b/resolve-undo.c\nindex c30ae5cf49..d2e2d22b7f 100644\n--- a/resolve-undo.c\n+++ b/resolve-undo.c\n@@ -188,7 +188,7 @@ void unmerge_index(struct index_state *istate, const struct pathspec *pathspec)\n \n \tfor (i = 0; i < istate->cache_nr; i++) {\n \t\tconst struct cache_entry *ce = istate->cache[i];\n-\t\tif (!ce_path_match(ce, pathspec, NULL))\n+\t\tif (!ce_path_match(&the_index, ce, pathspec, NULL))\n \t\t\tcontinue;\n \t\ti = unmerge_index_entry_at(istate, i);\n \t}\ndiff --git a/revision.c b/revision.c\nindex 0627494378..de4dce600d 100644\n--- a/revision.c\n+++ b/revision.c\n@@ -1517,7 +1517,7 @@ static void prepare_show_merge(struct rev_info *revs)\n \t\tconst struct cache_entry *ce = active_cache[i];\n \t\tif (!ce_stage(ce))\n \t\t\tcontinue;\n-\t\tif (ce_path_match(ce, &revs->prune_data, NULL)) {\n+\t\tif (ce_path_match(&the_index, ce, &revs->prune_data, NULL)) {\n \t\t\tprune_num++;\n \t\t\tREALLOC_ARRAY(prune, prune_num);\n \t\t\tprune[prune_num-2] = ce->name;\ndiff --git a/submodule.c b/submodule.c\nindex 6e14547e9e..293efc2a2f 100644\n--- a/submodule.c\n+++ b/submodule.c\n@@ -258,7 +258,7 @@ int is_submodule_active(struct repository *repo, const char *path)\n \t\t}\n \n \t\tparse_pathspec(&ps, 0, 0, NULL, args.argv);\n-\t\tret = match_pathspec(&ps, path, strlen(path), 0, NULL, 1);\n+\t\tret = match_pathspec(&the_index, &ps, path, strlen(path), 0, NULL, 1);\n \n \t\targv_array_clear(&args);\n \t\tclear_pathspec(&ps);\ndiff --git a/wt-status.c b/wt-status.c\nindex 6bf2fdbab6..5ffab61015 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -647,7 +647,7 @@ static void wt_status_collect_changes_initial(struct wt_status *s)\n \t\tstruct wt_status_change_data *d;\n \t\tconst struct cache_entry *ce = active_cache[i];\n \n-\t\tif (!ce_path_match(ce, &s->pathspec, NULL))\n+\t\tif (!ce_path_match(&the_index, ce, &s->pathspec, NULL))\n \t\t\tcontinue;\n \t\tif (ce_intent_to_add(ce))\n \t\t\tcontinue;\n@@ -703,7 +703,7 @@ static void wt_status_collect_untracked(struct wt_status *s)\n \tfor (i = 0; i < dir.nr; i++) {\n \t\tstruct dir_entry *ent = dir.entries[i];\n \t\tif (cache_name_is_other(ent->name, ent->len) &&\n-\t\t    dir_path_match(ent, &s->pathspec, 0, NULL))\n+\t\t    dir_path_match(&the_index, ent, &s->pathspec, 0, NULL))\n \t\t\tstring_list_insert(&s->untracked, ent->name);\n \t\tfree(ent);\n \t}\n@@ -711,7 +711,7 @@ static void wt_status_collect_untracked(struct wt_status *s)\n \tfor (i = 0; i < dir.ignored_nr; i++) {\n \t\tstruct dir_entry *ent = dir.ignored[i];\n \t\tif (cache_name_is_other(ent->name, ent->len) &&\n-\t\t    dir_path_match(ent, &s->pathspec, 0, NULL))\n+\t\t    dir_path_match(&the_index, ent, &s->pathspec, 0, NULL))\n \t\t\tstring_list_insert(&s->ignored, ent->name);\n \t\tfree(ent);\n \t}\n-- \n2.18.0.1004.g6639190530\n\n"},{"id":"355376","messageId":"20180813161441.16824-8-pclouds@gmail.com","threadId":"49115","inReplyTo":"20180813161441.16824-1-pclouds@gmail.com","subject":"[PATCH 07/24] ls-files: correct index argument to get_convert_attr_ascii()","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-08-13T16:14:24Z","receivedAt":"2018-08-13T16:15:31Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"write_eolinfo() does take an istate as function argument and it should\nbe used instead of the_index.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/ls-files.c | 17 +++++++++--------\n 1 file changed, 9 insertions(+), 8 deletions(-)\n\ndiff --git a/builtin/ls-files.c b/builtin/ls-files.c\nindex 7233b92794..7f9919a362 100644\n--- a/builtin/ls-files.c\n+++ b/builtin/ls-files.c\n@@ -63,7 +63,7 @@ static void write_eolinfo(const struct index_state *istate,\n \t\tstruct stat st;\n \t\tconst char *i_txt = \"\";\n \t\tconst char *w_txt = \"\";\n-\t\tconst char *a_txt = get_convert_attr_ascii(&the_index, path);\n+\t\tconst char *a_txt = get_convert_attr_ascii(istate, path);\n \t\tif (ce && S_ISREG(ce->ce_mode))\n \t\t\ti_txt = get_cached_convert_stats_ascii(istate,\n \t\t\t\t\t\t\t       ce->name);\n@@ -121,18 +121,19 @@ static void print_debug(const struct cache_entry *ce)\n \t}\n }\n \n-static void show_dir_entry(const char *tag, struct dir_entry *ent)\n+static void show_dir_entry(const struct index_state *istate,\n+\t\t\t   const char *tag, struct dir_entry *ent)\n {\n \tint len = max_prefix_len;\n \n \tif (len > ent->len)\n \t\tdie(\"git ls-files: internal error - directory entry not superset of prefix\");\n \n-\tif (!dir_path_match(&the_index, ent, &pathspec, len, ps_matched))\n+\tif (!dir_path_match(istate, ent, &pathspec, len, ps_matched))\n \t\treturn;\n \n \tfputs(tag, stdout);\n-\twrite_eolinfo(NULL, NULL, ent->name);\n+\twrite_eolinfo(istate, NULL, ent->name);\n \twrite_name(ent->name);\n }\n \n@@ -145,7 +146,7 @@ static void show_other_files(const struct index_state *istate,\n \t\tstruct dir_entry *ent = dir->entries[i];\n \t\tif (!index_name_is_other(istate, ent->name, ent->len))\n \t\t\tcontinue;\n-\t\tshow_dir_entry(tag_other, ent);\n+\t\tshow_dir_entry(istate, tag_other, ent);\n \t}\n }\n \n@@ -196,7 +197,7 @@ static void show_killed_files(const struct index_state *istate,\n \t\t\t}\n \t\t}\n \t\tif (killed)\n-\t\t\tshow_dir_entry(tag_killed, dir->entries[i]);\n+\t\t\tshow_dir_entry(istate, tag_killed, dir->entries[i]);\n \t}\n }\n \n@@ -228,7 +229,7 @@ static void show_ce(struct repository *repo, struct dir_struct *dir,\n \tif (recurse_submodules && S_ISGITLINK(ce->ce_mode) &&\n \t    is_submodule_active(repo, ce->name)) {\n \t\tshow_submodule(repo, dir, ce->name);\n-\t} else if (match_pathspec(&the_index, &pathspec, fullname, strlen(fullname),\n+\t} else if (match_pathspec(repo->index, &pathspec, fullname, strlen(fullname),\n \t\t\t\t  max_prefix_len, ps_matched,\n \t\t\t\t  S_ISDIR(ce->ce_mode) ||\n \t\t\t\t  S_ISGITLINK(ce->ce_mode))) {\n@@ -264,7 +265,7 @@ static void show_ru_info(const struct index_state *istate)\n \t\tlen = strlen(path);\n \t\tif (len < max_prefix_len)\n \t\t\tcontinue; /* outside of the prefix */\n-\t\tif (!match_pathspec(&the_index, &pathspec, path, len,\n+\t\tif (!match_pathspec(istate, &pathspec, path, len,\n \t\t\t\t    max_prefix_len, ps_matched, 0))\n \t\t\tcontinue; /* uninterested */\n \t\tfor (i = 0; i < 3; i++) {\n-- \n2.18.0.1004.g6639190530\n\n"},{"id":"355377","messageId":"20180813161441.16824-9-pclouds@gmail.com","threadId":"49115","inReplyTo":"20180813161441.16824-1-pclouds@gmail.com","subject":"[PATCH 08/24] unpack-trees: remove 'extern' on function declaration","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-08-13T16:14:25Z","receivedAt":"2018-08-13T16:15:33Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n unpack-trees.h | 4 ++--\n 1 file changed, 2 insertions(+), 2 deletions(-)\n\ndiff --git a/unpack-trees.h b/unpack-trees.h\nindex c2b434c606..534358fcc5 100644\n--- a/unpack-trees.h\n+++ b/unpack-trees.h\n@@ -82,8 +82,8 @@ struct unpack_trees_options {\n \tstruct exclude_list *el; /* for internal use */\n };\n \n-extern int unpack_trees(unsigned n, struct tree_desc *t,\n-\t\tstruct unpack_trees_options *options);\n+int unpack_trees(unsigned n, struct tree_desc *t,\n+\t\t struct unpack_trees_options *options);\n \n int verify_uptodate(const struct cache_entry *ce,\n \t\t    struct unpack_trees_options *o);\n-- \n2.18.0.1004.g6639190530\n\n"},{"id":"355378","messageId":"20180813161441.16824-10-pclouds@gmail.com","threadId":"49115","inReplyTo":"20180813161441.16824-1-pclouds@gmail.com","subject":"[PATCH 09/24] unpack-trees: add a note about path invalidation","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-08-13T16:14:26Z","receivedAt":"2018-08-13T16:15:35Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n unpack-trees.c | 11 +++++++++++\n 1 file changed, 11 insertions(+)\n\ndiff --git a/unpack-trees.c b/unpack-trees.c\nindex f9efee0836..c07a6cd646 100644\n--- a/unpack-trees.c\n+++ b/unpack-trees.c\n@@ -1552,6 +1552,17 @@ static int verify_uptodate_sparse(const struct cache_entry *ce,\n \treturn verify_uptodate_1(ce, o, ERROR_SPARSE_NOT_UPTODATE_FILE);\n }\n \n+/*\n+ * TODO: We should actually invalidate o->result, not src_index [1].\n+ * But since cache tree and untracked cache both are not copied to\n+ * o->result until unpacking is complete, we invalidate them on\n+ * src_index instead with the assumption that they will be copied to\n+ * dst_index at the end.\n+ *\n+ * [1] src_index->cache_tree is also used in unpack_callback() so if\n+ * we invalidate o->result, we need to update it to use\n+ * o->result.cache_tree as well.\n+ */\n static void invalidate_ce_path(const struct cache_entry *ce,\n \t\t\t       struct unpack_trees_options *o)\n {\n-- \n2.18.0.1004.g6639190530\n\n"},{"id":"355379","messageId":"20180813161441.16824-11-pclouds@gmail.com","threadId":"49115","inReplyTo":"20180813161441.16824-1-pclouds@gmail.com","subject":"[PATCH 10/24] unpack-trees: don't shadow global var the_index","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-08-13T16:14:27Z","receivedAt":"2018-08-13T16:15:36Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"This function mark_new_skip_worktree() has an argument named the_index\nwhich is also the name of a global variable. While they have different\ntypes (the global the_index is not a pointer) mistakes can easily\nhappen and it's also confusing for readers. Rename the function\nargument to something other than the_index.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n unpack-trees.c | 9 ++++-----\n 1 file changed, 4 insertions(+), 5 deletions(-)\n\ndiff --git a/unpack-trees.c b/unpack-trees.c\nindex c07a6cd646..f50b463f65 100644\n--- a/unpack-trees.c\n+++ b/unpack-trees.c\n@@ -1238,7 +1238,7 @@ static int clear_ce_flags(struct cache_entry **cache, int nr,\n  * Set/Clear CE_NEW_SKIP_WORKTREE according to $GIT_DIR/info/sparse-checkout\n  */\n static void mark_new_skip_worktree(struct exclude_list *el,\n-\t\t\t\t   struct index_state *the_index,\n+\t\t\t\t   struct index_state *istate,\n \t\t\t\t   int select_flag, int skip_wt_flag)\n {\n \tint i;\n@@ -1247,8 +1247,8 @@ static void mark_new_skip_worktree(struct exclude_list *el,\n \t * 1. Pretend the narrowest worktree: only unmerged entries\n \t * are checked out\n \t */\n-\tfor (i = 0; i < the_index->cache_nr; i++) {\n-\t\tstruct cache_entry *ce = the_index->cache[i];\n+\tfor (i = 0; i < istate->cache_nr; i++) {\n+\t\tstruct cache_entry *ce = istate->cache[i];\n \n \t\tif (select_flag && !(ce->ce_flags & select_flag))\n \t\t\tcontinue;\n@@ -1263,8 +1263,7 @@ static void mark_new_skip_worktree(struct exclude_list *el,\n \t * 2. Widen worktree according to sparse-checkout file.\n \t * Matched entries will have skip_wt_flag cleared (i.e. \"in\")\n \t */\n-\tclear_ce_flags(the_index->cache, the_index->cache_nr,\n-\t\t       select_flag, skip_wt_flag, el);\n+\tclear_ce_flags(istate->cache, istate->cache_nr, select_flag, skip_wt_flag, el);\n }\n \n static int verify_absent(const struct cache_entry *,\n-- \n2.18.0.1004.g6639190530\n\n"},{"id":"355380","messageId":"20180813161441.16824-12-pclouds@gmail.com","threadId":"49115","inReplyTo":"20180813161441.16824-1-pclouds@gmail.com","subject":"[PATCH 11/24] unpack-trees: convert clear_ce_flags* to avoid the_index","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-08-13T16:14:28Z","receivedAt":"2018-08-13T16:15:36Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Prior to fba92be8f7, this code implicitly (and incorrectly) assumes\nthe_index when running the exclude machinery. fba92be8f7 helps show\nthis problem clearer because unpack-trees operation is supposed to\nwork on whatever index the caller specifies... not specifically\nthe_index.\n\nUpdate the code to use \"istate\" argument that's originally from\nmark_new_skip_worktree(). From the call sites, both in unpack_trees(),\nyou can see that this function works on two separate indexes:\no->src_index and o->result. The second mark_new_skip_worktree() so far\nhas incorecctly applied exclude rules on o->src_index instead of\no->result. It's unclear what is the consequences of this, but it's\ndefinitely wrong.\n\n[1] fba92be8f7 (dir: convert is_excluded_from_list to take an index -\n    2017-05-05)\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n unpack-trees.c | 31 ++++++++++++++++++-------------\n 1 file changed, 18 insertions(+), 13 deletions(-)\n\ndiff --git a/unpack-trees.c b/unpack-trees.c\nindex f50b463f65..5d11f10e66 100644\n--- a/unpack-trees.c\n+++ b/unpack-trees.c\n@@ -1092,13 +1092,15 @@ static int unpack_callback(int n, unsigned long mask, unsigned long dirmask, str\n \treturn mask;\n }\n \n-static int clear_ce_flags_1(struct cache_entry **cache, int nr,\n+static int clear_ce_flags_1(struct index_state *istate,\n+\t\t\t    struct cache_entry **cache, int nr,\n \t\t\t    struct strbuf *prefix,\n \t\t\t    int select_mask, int clear_mask,\n \t\t\t    struct exclude_list *el, int defval);\n \n /* Whole directory matching */\n-static int clear_ce_flags_dir(struct cache_entry **cache, int nr,\n+static int clear_ce_flags_dir(struct index_state *istate,\n+\t\t\t      struct cache_entry **cache, int nr,\n \t\t\t      struct strbuf *prefix,\n \t\t\t      char *basename,\n \t\t\t      int select_mask, int clear_mask,\n@@ -1107,7 +1109,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, &the_index);\n+\t\t\t\t\tbasename, &dtype, el, istate);\n \tint rc;\n \n \tstrbuf_addch(prefix, '/');\n@@ -1129,7 +1131,7 @@ static int clear_ce_flags_dir(struct cache_entry **cache, int nr,\n \t * calling clear_ce_flags_1(). That function will call\n \t * the expensive is_excluded_from_list() on every entry.\n \t */\n-\trc = clear_ce_flags_1(cache, cache_end - cache,\n+\trc = clear_ce_flags_1(istate, cache, cache_end - cache,\n \t\t\t      prefix,\n \t\t\t      select_mask, clear_mask,\n \t\t\t      el, ret);\n@@ -1152,7 +1154,8 @@ static int clear_ce_flags_dir(struct cache_entry **cache, int nr,\n  *   cache[0]->name[0..(prefix_len-1)]\n  * Top level path has prefix_len zero.\n  */\n-static int clear_ce_flags_1(struct cache_entry **cache, int nr,\n+static int clear_ce_flags_1(struct index_state *istate,\n+\t\t\t    struct cache_entry **cache, int nr,\n \t\t\t    struct strbuf *prefix,\n \t\t\t    int select_mask, int clear_mask,\n \t\t\t    struct exclude_list *el, int defval)\n@@ -1186,7 +1189,7 @@ static int clear_ce_flags_1(struct cache_entry **cache, int nr,\n \t\t\tlen = slash - name;\n \t\t\tstrbuf_add(prefix, name, len);\n \n-\t\t\tprocessed = clear_ce_flags_dir(cache, cache_end - cache,\n+\t\t\tprocessed = clear_ce_flags_dir(istate, cache, cache_end - cache,\n \t\t\t\t\t\t       prefix,\n \t\t\t\t\t\t       prefix->buf + prefix->len - len,\n \t\t\t\t\t\t       select_mask, clear_mask,\n@@ -1200,7 +1203,7 @@ static int clear_ce_flags_1(struct cache_entry **cache, int nr,\n \t\t\t}\n \n \t\t\tstrbuf_addch(prefix, '/');\n-\t\t\tcache += clear_ce_flags_1(cache, cache_end - cache,\n+\t\t\tcache += clear_ce_flags_1(istate, cache, cache_end - cache,\n \t\t\t\t\t\t  prefix,\n \t\t\t\t\t\t  select_mask, clear_mask, el, defval);\n \t\t\tstrbuf_setlen(prefix, prefix->len - len - 1);\n@@ -1210,7 +1213,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, &the_index);\n+\t\t\t\t\t    name, &dtype, el, istate);\n \t\tif (ret < 0)\n \t\t\tret = defval;\n \t\tif (ret > 0)\n@@ -1220,15 +1223,17 @@ static int clear_ce_flags_1(struct cache_entry **cache, int nr,\n \treturn nr - (cache_end - cache);\n }\n \n-static int clear_ce_flags(struct cache_entry **cache, int nr,\n-\t\t\t    int select_mask, int clear_mask,\n-\t\t\t    struct exclude_list *el)\n+static int clear_ce_flags(struct index_state *istate,\n+\t\t\t  int select_mask, int clear_mask,\n+\t\t\t  struct exclude_list *el)\n {\n \tstatic struct strbuf prefix = STRBUF_INIT;\n \n \tstrbuf_reset(&prefix);\n \n-\treturn clear_ce_flags_1(cache, nr,\n+\treturn clear_ce_flags_1(istate,\n+\t\t\t\tistate->cache,\n+\t\t\t\tistate->cache_nr,\n \t\t\t\t&prefix,\n \t\t\t\tselect_mask, clear_mask,\n \t\t\t\tel, 0);\n@@ -1263,7 +1268,7 @@ static void mark_new_skip_worktree(struct exclude_list *el,\n \t * 2. Widen worktree according to sparse-checkout file.\n \t * Matched entries will have skip_wt_flag cleared (i.e. \"in\")\n \t */\n-\tclear_ce_flags(istate->cache, istate->cache_nr, select_flag, skip_wt_flag, el);\n+\tclear_ce_flags(istate, select_flag, skip_wt_flag, el);\n }\n \n static int verify_absent(const struct cache_entry *,\n-- \n2.18.0.1004.g6639190530\n\n"},{"id":"355381","messageId":"20180813161441.16824-14-pclouds@gmail.com","threadId":"49115","inReplyTo":"20180813161441.16824-1-pclouds@gmail.com","subject":"[PATCH 13/24] pathspec.c: use the right index instead of the_index","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-08-13T16:14:30Z","receivedAt":"2018-08-13T16:15:38Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n pathspec.c | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/pathspec.c b/pathspec.c\nindex 897cb9cbbe..6f005996fd 100644\n--- a/pathspec.c\n+++ b/pathspec.c\n@@ -37,7 +37,7 @@ void add_pathspec_matches_against_index(const struct pathspec *pathspec,\n \t\treturn;\n \tfor (i = 0; i < istate->cache_nr; i++) {\n \t\tconst struct cache_entry *ce = istate->cache[i];\n-\t\tce_path_match(&the_index, ce, pathspec, seen);\n+\t\tce_path_match(istate, ce, pathspec, seen);\n \t}\n }\n \n-- \n2.18.0.1004.g6639190530\n\n"},{"id":"355382","messageId":"20180813161441.16824-13-pclouds@gmail.com","threadId":"49115","inReplyTo":"20180813161441.16824-1-pclouds@gmail.com","subject":"[PATCH 12/24] unpack-trees: avoid the_index in verify_absent()","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-08-13T16:14:29Z","receivedAt":"2018-08-13T16:15:39Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Both functions that are updated in this commit are called by\nverify_absent(), which is part of the \"unpack-trees\" operation that is\nsupposed to work on any index file specified by the caller. Thanks to\nBrandon [1] [2], an implicit dependency on the_index is exposed. This\ncommit fixes it.\n\nIn both functions, it makes sense to use src_index to check for\nexclusion because it's almost unchanged and should give us the same\noutcome as if running the exclude check before the unpack.\n\nIt's \"almost unchanged\" because we do invalidate cache-tree and\nuntracked cache in the source index. But this should not affect how\nexclude machinery uses the index: to see if a file is tracked, and to\nread a blob from the index instead of worktree if it's marked\nskip-worktree (i.e. it's not available in worktree)\n\n[1] a0bba65b10 (dir: convert is_excluded to take an index - 2017-05-05\n[2] 2c1eb10454 (dir: convert read_directory to take an index - 2017-05-05)\n\nHelped-by: Elijah Newren <newren@gmail.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n unpack-trees.c | 4 ++--\n 1 file changed, 2 insertions(+), 2 deletions(-)\n\ndiff --git a/unpack-trees.c b/unpack-trees.c\nindex 5d11f10e66..14e9043f9d 100644\n--- a/unpack-trees.c\n+++ b/unpack-trees.c\n@@ -1658,7 +1658,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, &the_index, pathbuf, namelen+1, NULL);\n+\ti = read_directory(&d, o->src_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@@ -1700,7 +1700,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, &the_index, name, &dtype))\n+\t    is_excluded(o->dir, o->src_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.18.0.1004.g6639190530\n\n"},{"id":"355383","messageId":"20180813161441.16824-15-pclouds@gmail.com","threadId":"49115","inReplyTo":"20180813161441.16824-1-pclouds@gmail.com","subject":"[PATCH 14/24] submodule.c: use the right index instead of the_index","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-08-13T16:14:31Z","receivedAt":"2018-08-13T16:15:40Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n submodule.c | 8 ++++----\n 1 file changed, 4 insertions(+), 4 deletions(-)\n\ndiff --git a/submodule.c b/submodule.c\nindex 293efc2a2f..50cbf5f13e 100644\n--- a/submodule.c\n+++ b/submodule.c\n@@ -93,7 +93,7 @@ int update_path_in_gitmodules(const char *oldpath, const char *newpath)\n \tif (!file_exists(GITMODULES_FILE)) /* Do nothing without .gitmodules */\n \t\treturn -1;\n \n-\tif (is_gitmodules_unmerged(&the_index))\n+\tif (is_gitmodules_unmerged(the_repository->index))\n \t\tdie(_(\"Cannot change unmerged .gitmodules, resolve merge conflicts first\"));\n \n \tsubmodule = submodule_from_path(the_repository, &null_oid, oldpath);\n@@ -127,7 +127,7 @@ int remove_path_from_gitmodules(const char *path)\n \tif (!file_exists(GITMODULES_FILE)) /* Do nothing without .gitmodules */\n \t\treturn -1;\n \n-\tif (is_gitmodules_unmerged(&the_index))\n+\tif (is_gitmodules_unmerged(the_repository->index))\n \t\tdie(_(\"Cannot change unmerged .gitmodules, resolve merge conflicts first\"));\n \n \tsubmodule = submodule_from_path(the_repository, &null_oid, path);\n@@ -188,7 +188,7 @@ void set_diffopt_flags_from_submodule_config(struct diff_options *diffopt,\n \n \t\tif (ignore)\n \t\t\thandle_ignore_submodules_arg(diffopt, ignore);\n-\t\telse if (is_gitmodules_unmerged(&the_index))\n+\t\telse if (is_gitmodules_unmerged(the_repository->index))\n \t\t\tdiffopt->flags.ignore_submodules = 1;\n \t}\n }\n@@ -258,7 +258,7 @@ int is_submodule_active(struct repository *repo, const char *path)\n \t\t}\n \n \t\tparse_pathspec(&ps, 0, 0, NULL, args.argv);\n-\t\tret = match_pathspec(&the_index, &ps, path, strlen(path), 0, NULL, 1);\n+\t\tret = match_pathspec(repo->index, &ps, path, strlen(path), 0, NULL, 1);\n \n \t\targv_array_clear(&args);\n \t\tclear_pathspec(&ps);\n-- \n2.18.0.1004.g6639190530\n\n"},{"id":"355384","messageId":"20180813161441.16824-17-pclouds@gmail.com","threadId":"49115","inReplyTo":"20180813161441.16824-1-pclouds@gmail.com","subject":"[PATCH 16/24] attr: remove index from git_attr_set_direction()","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-08-13T16:14:33Z","receivedAt":"2018-08-13T16:15:41Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Since attr checking API now take the index, there's no need to set an\nindex in advance with this call. Most call sites are straightforward\nbecause they either pass the_index or NULL (which defaults back to\nthe_index previously). There's only one suspicious call site in\nunpack-trees.c where it sets a different index.\n\nThis code in unpack-trees is about to check out entries from the\nnew/temporary index after merging is done in it. The attributes will\nbe used by entry.c code to do crlf conversion if needed. entry.c now\nrespects struct checkout's istate field, and this field is correctly\nset in unpack-trees.c, there should be no regression from this change.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n archive.c            |  2 +-\n attr.c               | 15 +++------------\n attr.h               |  3 +--\n builtin/check-attr.c |  2 +-\n unpack-trees.c       |  4 ++--\n 5 files changed, 8 insertions(+), 18 deletions(-)\n\ndiff --git a/archive.c b/archive.c\nindex c81e35bf23..aca9179d03 100644\n--- a/archive.c\n+++ b/archive.c\n@@ -274,7 +274,7 @@ int write_archive_entries(struct archiver_args *args,\n \t\tinit_tree_desc(&t, args->tree->buffer, args->tree->size);\n \t\tif (unpack_trees(1, &t, &opts))\n \t\t\treturn -1;\n-\t\tgit_attr_set_direction(GIT_ATTR_INDEX, &the_index);\n+\t\tgit_attr_set_direction(GIT_ATTR_INDEX);\n \t}\n \n \terr = read_tree_recursive(args->tree, \"\", 0, 0, &args->pathspec,\ndiff --git a/attr.c b/attr.c\nindex 863fad3bd1..98e4953f6e 100644\n--- a/attr.c\n+++ b/attr.c\n@@ -708,10 +708,8 @@ static struct attr_stack *read_attr_from_array(const char **list)\n  * another thread could potentially be calling into the attribute system.\n  */\n static enum git_attr_direction direction;\n-static const struct index_state *use_index;\n \n-void git_attr_set_direction(enum git_attr_direction new_direction,\n-\t\t\t    const struct index_state *istate)\n+void git_attr_set_direction(enum git_attr_direction new_direction)\n {\n \tif (is_bare_repository() && new_direction != GIT_ATTR_INDEX)\n \t\tBUG(\"non-INDEX attr direction in a bare repo\");\n@@ -720,7 +718,6 @@ void git_attr_set_direction(enum git_attr_direction new_direction,\n \t\tdrop_all_attr_stacks();\n \n \tdirection = new_direction;\n-\tuse_index = istate;\n }\n \n static struct attr_stack *read_attr_from_file(const char *path, int macro_ok)\n@@ -750,17 +747,11 @@ static struct attr_stack *read_attr_from_index(const struct index_state *istate,\n \tstruct attr_stack *res;\n \tchar *buf, *sp;\n \tint lineno = 0;\n-\tconst struct index_state *to_read_from;\n \n-\t/*\n-\t * Temporary workaround for c24f3abace (apply: file commited\n-\t * with CRLF should roundtrip diff and apply - 2017-08-19)\n-\t */\n-\tto_read_from = use_index ? use_index : istate;\n-\tif (!to_read_from)\n+\tif (!istate)\n \t\treturn NULL;\n \n-\tbuf = read_blob_data_from_index(to_read_from, path, NULL);\n+\tbuf = read_blob_data_from_index(istate, path, NULL);\n \tif (!buf)\n \t\treturn NULL;\n \ndiff --git a/attr.h b/attr.h\nindex 3daca3c0cb..01dab4a126 100644\n--- a/attr.h\n+++ b/attr.h\n@@ -77,8 +77,7 @@ enum git_attr_direction {\n \tGIT_ATTR_CHECKOUT,\n \tGIT_ATTR_INDEX\n };\n-void git_attr_set_direction(enum git_attr_direction new_direction,\n-\t\t\t    const struct index_state *istate);\n+void git_attr_set_direction(enum git_attr_direction new_direction);\n \n void attr_start(void);\n \ndiff --git a/builtin/check-attr.c b/builtin/check-attr.c\nindex f7b59993d3..c05573ff9c 100644\n--- a/builtin/check-attr.c\n+++ b/builtin/check-attr.c\n@@ -120,7 +120,7 @@ int cmd_check_attr(int argc, const char **argv, const char *prefix)\n \t}\n \n \tif (cached_attrs)\n-\t\tgit_attr_set_direction(GIT_ATTR_INDEX, NULL);\n+\t\tgit_attr_set_direction(GIT_ATTR_INDEX);\n \n \tdoubledash = -1;\n \tfor (i = 0; doubledash < 0 && i < argc; i++) {\ndiff --git a/unpack-trees.c b/unpack-trees.c\nindex 14e9043f9d..f25089b878 100644\n--- a/unpack-trees.c\n+++ b/unpack-trees.c\n@@ -353,7 +353,7 @@ static int check_updates(struct unpack_trees_options *o)\n \tprogress = get_progress(o);\n \n \tif (o->update)\n-\t\tgit_attr_set_direction(GIT_ATTR_CHECKOUT, index);\n+\t\tgit_attr_set_direction(GIT_ATTR_CHECKOUT);\n \n \tif (should_update_submodules() && o->update && !o->dry_run)\n \t\tload_gitmodules_file(index, NULL);\n@@ -413,7 +413,7 @@ static int check_updates(struct unpack_trees_options *o)\n \tstop_progress(&progress);\n \terrs |= finish_delayed_checkout(&state);\n \tif (o->update)\n-\t\tgit_attr_set_direction(GIT_ATTR_CHECKIN, NULL);\n+\t\tgit_attr_set_direction(GIT_ATTR_CHECKIN);\n \treturn errs != 0;\n }\n \n-- \n2.18.0.1004.g6639190530\n\n"},{"id":"355385","messageId":"20180813161441.16824-16-pclouds@gmail.com","threadId":"49115","inReplyTo":"20180813161441.16824-1-pclouds@gmail.com","subject":"[PATCH 15/24] entry.c: use the right index instead of the_index","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-08-13T16:14:32Z","receivedAt":"2018-08-13T16:15:41Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"checkout-index.c needs update because if checkout->istate is NULL,\nie_match_stat() will crash. Previously this is ie_match_stat(&the_index, ..)\nso it will not crash, but it is not technically correct either.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/checkout-index.c | 1 +\n entry.c                  | 9 +++++----\n 2 files changed, 6 insertions(+), 4 deletions(-)\n\ndiff --git a/builtin/checkout-index.c b/builtin/checkout-index.c\nindex a730f6a1aa..d92db62fbd 100644\n--- a/builtin/checkout-index.c\n+++ b/builtin/checkout-index.c\n@@ -190,6 +190,7 @@ int cmd_checkout_index(int argc, const char **argv, const char *prefix)\n \n \targc = parse_options(argc, argv, prefix, builtin_checkout_index_options,\n \t\t\tbuiltin_checkout_index_usage, 0);\n+\tstate.istate = &the_index;\n \tstate.force = force;\n \tstate.quiet = quiet;\n \tstate.not_new = not_new;\ndiff --git a/entry.c b/entry.c\nindex b2381fd9f6..2a2ab6c839 100644\n--- a/entry.c\n+++ b/entry.c\n@@ -266,7 +266,7 @@ static int write_entry(struct cache_entry *ce,\n \tconst struct submodule *sub;\n \n \tif (ce_mode_s_ifmt == S_IFREG) {\n-\t\tstruct stream_filter *filter = get_stream_filter(&the_index, ce->name,\n+\t\tstruct stream_filter *filter = get_stream_filter(state->istate, ce->name,\n \t\t\t\t\t\t\t\t &ce->oid);\n \t\tif (filter &&\n \t\t    !streaming_write_entry(ce, path, filter,\n@@ -314,14 +314,14 @@ static int write_entry(struct cache_entry *ce,\n \t\t * Convert from git internal format to working tree format\n \t\t */\n \t\tif (dco && dco->state != CE_NO_DELAY) {\n-\t\t\tret = async_convert_to_working_tree(&the_index, ce->name, new_blob,\n+\t\t\tret = async_convert_to_working_tree(state->istate, ce->name, new_blob,\n \t\t\t\t\t\t\t    size, &buf, dco);\n \t\t\tif (ret && string_list_has_string(&dco->paths, ce->name)) {\n \t\t\t\tfree(new_blob);\n \t\t\t\tgoto delayed;\n \t\t\t}\n \t\t} else\n-\t\t\tret = convert_to_working_tree(&the_index, ce->name, new_blob, size, &buf);\n+\t\t\tret = convert_to_working_tree(state->istate, ce->name, new_blob, size, &buf);\n \n \t\tif (ret) {\n \t\t\tfree(new_blob);\n@@ -422,7 +422,8 @@ int checkout_entry(struct cache_entry *ce,\n \n \tif (!check_path(path.buf, path.len, &st, state->base_dir_len)) {\n \t\tconst struct submodule *sub;\n-\t\tunsigned changed = ce_match_stat(ce, &st, CE_MATCH_IGNORE_VALID|CE_MATCH_IGNORE_SKIP_WORKTREE);\n+\t\tunsigned changed = ie_match_stat(state->istate, ce, &st,\n+\t\t\t\t\t\t CE_MATCH_IGNORE_VALID | CE_MATCH_IGNORE_SKIP_WORKTREE);\n \t\t/*\n \t\t * Needs to be checked before !changed returns early,\n \t\t * as the possibly empty directory was not changed\n-- \n2.18.0.1004.g6639190530\n\n"},{"id":"355386","messageId":"20180813161441.16824-18-pclouds@gmail.com","threadId":"49115","inReplyTo":"20180813161441.16824-1-pclouds@gmail.com","subject":"[PATCH 17/24] grep: use the right index instead of the_index","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-08-13T16:14:34Z","receivedAt":"2018-08-13T16:15:42Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/grep.c | 4 ++--\n 1 file changed, 2 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin/grep.c b/builtin/grep.c\nindex 9d7ba87f9b..b7033954ac 100644\n--- a/builtin/grep.c\n+++ b/builtin/grep.c\n@@ -497,7 +497,7 @@ static int grep_cache(struct grep_opt *opt, struct repository *repo,\n \t\tstrbuf_addstr(&name, ce->name);\n \n \t\tif (S_ISREG(ce->ce_mode) &&\n-\t\t    match_pathspec(&the_index, pathspec, name.buf, name.len, 0, NULL,\n+\t\t    match_pathspec(repo->index, pathspec, name.buf, name.len, 0, NULL,\n \t\t\t\t   S_ISDIR(ce->ce_mode) ||\n \t\t\t\t   S_ISGITLINK(ce->ce_mode))) {\n \t\t\t/*\n@@ -515,7 +515,7 @@ static int grep_cache(struct grep_opt *opt, struct repository *repo,\n \t\t\t\thit |= grep_file(opt, name.buf);\n \t\t\t}\n \t\t} else if (recurse_submodules && S_ISGITLINK(ce->ce_mode) &&\n-\t\t\t   submodule_path_match(&the_index, pathspec, name.buf, NULL)) {\n+\t\t\t   submodule_path_match(repo->index, pathspec, name.buf, NULL)) {\n \t\t\thit |= grep_submodule(opt, repo, pathspec, NULL, ce->name, ce->name);\n \t\t} else {\n \t\t\tcontinue;\n-- \n2.18.0.1004.g6639190530\n\n"},{"id":"355388","messageId":"20180813161441.16824-20-pclouds@gmail.com","threadId":"49115","inReplyTo":"20180813161441.16824-1-pclouds@gmail.com","subject":"[PATCH 19/24] archive-*.c: use the right repository","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-08-13T16:14:36Z","receivedAt":"2018-08-13T16:15:45Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"With 'struct archive_args' gaining new repository pointer, we don't\nhave to assume the_repository in the archive backends anymore.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n archive-tar.c | 2 +-\n archive-zip.c | 2 +-\n 2 files changed, 2 insertions(+), 2 deletions(-)\n\ndiff --git a/archive-tar.c b/archive-tar.c\nindex 7df8565246..69ff23dfb0 100644\n--- a/archive-tar.c\n+++ b/archive-tar.c\n@@ -277,7 +277,7 @@ static int write_tar_entry(struct archiver_args *args,\n \t\tmemcpy(header.name, path, pathlen);\n \n \tif (S_ISREG(mode) && !args->convert &&\n-\t    oid_object_info(the_repository, oid, &size) == OBJ_BLOB &&\n+\t    oid_object_info(args->repo, oid, &size) == OBJ_BLOB &&\n \t    size > big_file_threshold)\n \t\tbuffer = NULL;\n \telse if (S_ISLNK(mode) || S_ISREG(mode)) {\ndiff --git a/archive-zip.c b/archive-zip.c\nindex abc556e5a7..107da5f97e 100644\n--- a/archive-zip.c\n+++ b/archive-zip.c\n@@ -326,7 +326,7 @@ static int write_zip_entry(struct archiver_args *args,\n \t\tcompressed_size = 0;\n \t\tbuffer = NULL;\n \t} else if (S_ISREG(mode) || S_ISLNK(mode)) {\n-\t\tenum object_type type = oid_object_info(the_repository, oid,\n+\t\tenum object_type type = oid_object_info(args->repo, oid,\n \t\t\t\t\t\t\t&size);\n \n \t\tmethod = 0;\n-- \n2.18.0.1004.g6639190530\n\n"},{"id":"355387","messageId":"20180813161441.16824-21-pclouds@gmail.com","threadId":"49115","inReplyTo":"20180813161441.16824-1-pclouds@gmail.com","subject":"[PATCH 20/24] resolve-undo.c: use the right index instead of the_index","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-08-13T16:14:37Z","receivedAt":"2018-08-13T16:15:46Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n resolve-undo.c | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/resolve-undo.c b/resolve-undo.c\nindex d2e2d22b7f..236320f179 100644\n--- a/resolve-undo.c\n+++ b/resolve-undo.c\n@@ -188,7 +188,7 @@ void unmerge_index(struct index_state *istate, const struct pathspec *pathspec)\n \n \tfor (i = 0; i < istate->cache_nr; i++) {\n \t\tconst struct cache_entry *ce = istate->cache[i];\n-\t\tif (!ce_path_match(&the_index, ce, pathspec, NULL))\n+\t\tif (!ce_path_match(istate, ce, pathspec, NULL))\n \t\t\tcontinue;\n \t\ti = unmerge_index_entry_at(istate, i);\n \t}\n-- \n2.18.0.1004.g6639190530\n\n"},{"id":"355389","messageId":"20180813161441.16824-22-pclouds@gmail.com","threadId":"49115","inReplyTo":"20180813161441.16824-1-pclouds@gmail.com","subject":"[PATCH 21/24] apply.c: pass struct apply_state to more functions","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-08-13T16:14:38Z","receivedAt":"2018-08-13T16:15:46Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"we're going to remove the dependency on the_index by moving 'struct\nindex_state *' to somewhere inside struct apply_state. Let's make sure\nrelevant functions have access to this struct now and reduce the diff\nnoise when the actual conversion happens.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n apply.c | 18 +++++++++++-------\n 1 file changed, 11 insertions(+), 7 deletions(-)\n\ndiff --git a/apply.c b/apply.c\nindex 2476f06ebd..572cd639a6 100644\n--- a/apply.c\n+++ b/apply.c\n@@ -3374,7 +3374,9 @@ static struct patch *previous_patch(struct apply_state *state,\n \treturn previous;\n }\n \n-static int verify_index_match(const struct cache_entry *ce, struct stat *st)\n+static int verify_index_match(struct apply_state *state,\n+\t\t\t      const struct cache_entry *ce,\n+\t\t\t      struct stat *st)\n {\n \tif (S_ISGITLINK(ce->ce_mode)) {\n \t\tif (!S_ISDIR(st->st_mode))\n@@ -3524,7 +3526,7 @@ static int load_current(struct apply_state *state,\n \t\tif (checkout_target(&the_index, ce, &st))\n \t\t\treturn -1;\n \t}\n-\tif (verify_index_match(ce, &st))\n+\tif (verify_index_match(state, ce, &st))\n \t\treturn error(_(\"%s: does not match index\"), name);\n \n \tstatus = load_patch_target(state, &buf, ce, &st, patch, name, mode);\n@@ -3694,7 +3696,7 @@ static int check_preimage(struct apply_state *state,\n \t\t\tif (checkout_target(&the_index, *ce, st))\n \t\t\t\treturn -1;\n \t\t}\n-\t\tif (!state->cached && verify_index_match(*ce, st))\n+\t\tif (!state->cached && verify_index_match(state, *ce, st))\n \t\t\treturn error(_(\"%s: does not match index\"), old_name);\n \t\tif (state->cached)\n \t\t\tst_mode = (*ce)->ce_mode;\n@@ -4313,7 +4315,9 @@ static int add_index_file(struct apply_state *state,\n  *   0 if everything went well\n  *   1 if a recoverable error happened\n  */\n-static int try_create_file(const char *path, unsigned int mode, const char *buf, unsigned long size)\n+static int try_create_file(struct apply_state *state, const char *path,\n+\t\t\t   unsigned int mode, const char *buf,\n+\t\t\t   unsigned long size)\n {\n \tint fd, res;\n \tstruct strbuf nbuf = STRBUF_INIT;\n@@ -4371,7 +4375,7 @@ static int create_one_file(struct apply_state *state,\n \tif (state->cached)\n \t\treturn 0;\n \n-\tres = try_create_file(path, mode, buf, size);\n+\tres = try_create_file(state, path, mode, buf, size);\n \tif (res < 0)\n \t\treturn -1;\n \tif (!res)\n@@ -4380,7 +4384,7 @@ static int create_one_file(struct apply_state *state,\n \tif (errno == ENOENT) {\n \t\tif (safe_create_leading_directories(path))\n \t\t\treturn 0;\n-\t\tres = try_create_file(path, mode, buf, size);\n+\t\tres = try_create_file(state, path, mode, buf, size);\n \t\tif (res < 0)\n \t\t\treturn -1;\n \t\tif (!res)\n@@ -4402,7 +4406,7 @@ static int create_one_file(struct apply_state *state,\n \t\tfor (;;) {\n \t\t\tchar newpath[PATH_MAX];\n \t\t\tmksnpath(newpath, sizeof(newpath), \"%s~%u\", path, nr);\n-\t\t\tres = try_create_file(newpath, mode, buf, size);\n+\t\t\tres = try_create_file(state, newpath, mode, buf, size);\n \t\t\tif (res < 0)\n \t\t\t\treturn -1;\n \t\t\tif (!res) {\n-- \n2.18.0.1004.g6639190530\n\n"},{"id":"355390","messageId":"20180813161441.16824-23-pclouds@gmail.com","threadId":"49115","inReplyTo":"20180813161441.16824-1-pclouds@gmail.com","subject":"[PATCH 22/24] apply.c: make init_apply_state() take a struct repository","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-08-13T16:14:39Z","receivedAt":"2018-08-13T16:15:48Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"We're moving away from the_index in this code. \"struct index_state *\"\ncould be added to struct apply_state. But let's aim long term and put\nstruct repository here instead so that we could even avoid more global\nstates in the future. The index will be available via\napply_state->repo->index.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n apply.c         | 2 ++\n apply.h         | 4 ++++\n builtin/am.c    | 2 +-\n builtin/apply.c | 2 +-\n 4 files changed, 8 insertions(+), 2 deletions(-)\n\ndiff --git a/apply.c b/apply.c\nindex 572cd639a6..3704850ef2 100644\n--- a/apply.c\n+++ b/apply.c\n@@ -76,10 +76,12 @@ static int parse_ignorewhitespace_option(struct apply_state *state,\n }\n \n int init_apply_state(struct apply_state *state,\n+\t\t     struct repository *repo,\n \t\t     const char *prefix)\n {\n \tmemset(state, 0, sizeof(*state));\n \tstate->prefix = prefix;\n+\tstate->repo = repo;\n \tstate->apply = 1;\n \tstate->line_termination = '\\n';\n \tstate->p_value = 1;\ndiff --git a/apply.h b/apply.h\nindex 01963b5ec4..78c8bcfc3c 100644\n--- a/apply.h\n+++ b/apply.h\n@@ -1,6 +1,8 @@\n #ifndef APPLY_H\n #define APPLY_H\n \n+struct repository;\n+\n enum apply_ws_error_action {\n \tnowarn_ws_error,\n \twarn_on_ws_error,\n@@ -62,6 +64,7 @@ struct apply_state {\n \tint unsafe_paths;\n \n \t/* Other non boolean parameters */\n+\tstruct repository *repo;\n \tconst char *index_file;\n \tenum apply_verbosity apply_verbosity;\n \tconst char *fake_ancestor;\n@@ -116,6 +119,7 @@ int apply_parse_options(int argc, const char **argv,\n \t\t\tint *force_apply, int *options,\n \t\t\tconst char * const *apply_usage);\n int init_apply_state(struct apply_state *state,\n+\t\t     struct repository *repo,\n \t\t     const char *prefix);\n void clear_apply_state(struct apply_state *state);\n int check_apply_state(struct apply_state *state, int force_apply);\ndiff --git a/builtin/am.c b/builtin/am.c\nindex 2c19e69f58..9f7ecf6ecb 100644\n--- a/builtin/am.c\n+++ b/builtin/am.c\n@@ -1464,7 +1464,7 @@ static int run_apply(const struct am_state *state, const char *index_file)\n \tint force_apply = 0;\n \tint options = 0;\n \n-\tif (init_apply_state(&apply_state, NULL))\n+\tif (init_apply_state(&apply_state, the_repository, NULL))\n \t\tBUG(\"init_apply_state() failed\");\n \n \targv_array_push(&apply_opts, \"apply\");\ndiff --git a/builtin/apply.c b/builtin/apply.c\nindex 48d3989331..3f099b9605 100644\n--- a/builtin/apply.c\n+++ b/builtin/apply.c\n@@ -16,7 +16,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix)\n \tint ret;\n \tstruct apply_state state;\n \n-\tif (init_apply_state(&state, prefix))\n+\tif (init_apply_state(&state, the_repository, prefix))\n \t\texit(128);\n \n \targc = apply_parse_options(argc, argv,\n-- \n2.18.0.1004.g6639190530\n\n"},{"id":"355391","messageId":"20180813161441.16824-19-pclouds@gmail.com","threadId":"49115","inReplyTo":"20180813161441.16824-1-pclouds@gmail.com","subject":"[PATCH 18/24] archive.c: avoid access to the_index","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-08-13T16:14:35Z","receivedAt":"2018-08-13T16:15:49Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n archive.c                | 45 ++++++++++++++++++++++++++--------------\n archive.h                | 16 +++++++++++---\n builtin/archive.c        |  2 +-\n builtin/upload-archive.c |  3 ++-\n 4 files changed, 45 insertions(+), 21 deletions(-)\n\ndiff --git a/archive.c b/archive.c\nindex aca9179d03..0a07b140fe 100644\n--- a/archive.c\n+++ b/archive.c\n@@ -79,7 +79,7 @@ void *object_file_to_archive(const struct archiver_args *args,\n \t\tsize_t size = 0;\n \n \t\tstrbuf_attach(&buf, buffer, *sizep, *sizep + 1);\n-\t\tconvert_to_working_tree(&the_index, path, buf.buf, buf.len, &buf);\n+\t\tconvert_to_working_tree(args->repo->index, path, buf.buf, buf.len, &buf);\n \t\tif (commit)\n \t\t\tformat_subst(commit, buf.buf, buf.len, &buf);\n \t\tbuffer = strbuf_detach(&buf, &size);\n@@ -104,12 +104,13 @@ struct archiver_context {\n \tstruct directory *bottom;\n };\n \n-static const struct attr_check *get_archive_attrs(const char *path)\n+static const struct attr_check *get_archive_attrs(struct index_state *istate,\n+\t\t\t\t\t\t  const char *path)\n {\n \tstatic struct attr_check *check;\n \tif (!check)\n \t\tcheck = attr_check_initl(\"export-ignore\", \"export-subst\", NULL);\n-\treturn git_check_attr(&the_index, path, check) ? NULL : check;\n+\treturn git_check_attr(istate, path, check) ? NULL : check;\n }\n \n static int check_attr_export_ignore(const struct attr_check *check)\n@@ -145,7 +146,7 @@ static int write_archive_entry(const struct object_id *oid, const char *base,\n \n \tif (!S_ISDIR(mode)) {\n \t\tconst struct attr_check *check;\n-\t\tcheck = get_archive_attrs(path_without_prefix);\n+\t\tcheck = get_archive_attrs(args->repo->index, path_without_prefix);\n \t\tif (check_attr_export_ignore(check))\n \t\t\treturn 0;\n \t\targs->convert = check_attr_export_subst(check);\n@@ -220,7 +221,7 @@ static int queue_or_write_archive_entry(const struct object_id *oid,\n \t\t/* Borrow base, but restore its original value when done. */\n \t\tstrbuf_addstr(base, filename);\n \t\tstrbuf_addch(base, '/');\n-\t\tcheck = get_archive_attrs(base->buf);\n+\t\tcheck = get_archive_attrs(c->args->repo->index, base->buf);\n \t\tstrbuf_setlen(base, baselen);\n \n \t\tif (check_attr_export_ignore(check))\n@@ -268,8 +269,8 @@ int write_archive_entries(struct archiver_args *args,\n \t\tmemset(&opts, 0, sizeof(opts));\n \t\topts.index_only = 1;\n \t\topts.head_idx = -1;\n-\t\topts.src_index = &the_index;\n-\t\topts.dst_index = &the_index;\n+\t\topts.src_index = args->repo->index;\n+\t\topts.dst_index = args->repo->index;\n \t\topts.fn = oneway_merge;\n \t\tinit_tree_desc(&t, args->tree->buffer, args->tree->size);\n \t\tif (unpack_trees(1, &t, &opts))\n@@ -304,33 +305,43 @@ static const struct archiver *lookup_archiver(const char *name)\n \treturn NULL;\n }\n \n+struct path_exists_context {\n+\tstruct pathspec pathspec;\n+\tstruct archiver_args *args;\n+};\n+\n static int reject_entry(const struct object_id *oid, struct strbuf *base,\n \t\t\tconst char *filename, unsigned mode,\n \t\t\tint stage, void *context)\n {\n \tint ret = -1;\n+\tstruct path_exists_context *ctx = context;\n+\n \tif (S_ISDIR(mode)) {\n \t\tstruct strbuf sb = STRBUF_INIT;\n \t\tstrbuf_addbuf(&sb, base);\n \t\tstrbuf_addstr(&sb, filename);\n-\t\tif (!match_pathspec(&the_index, context, sb.buf, sb.len, 0, NULL, 1))\n+\t\tif (!match_pathspec(ctx->args->repo->index,\n+\t\t\t\t    &ctx->pathspec,\n+\t\t\t\t    sb.buf, sb.len, 0, NULL, 1))\n \t\t\tret = READ_TREE_RECURSIVE;\n \t\tstrbuf_release(&sb);\n \t}\n \treturn ret;\n }\n \n-static int path_exists(struct tree *tree, const char *path)\n+static int path_exists(struct archiver_args *args, const char *path)\n {\n \tconst char *paths[] = { path, NULL };\n-\tstruct pathspec pathspec;\n+\tstruct path_exists_context ctx;\n \tint ret;\n \n-\tparse_pathspec(&pathspec, 0, 0, \"\", paths);\n-\tpathspec.recursive = 1;\n-\tret = read_tree_recursive(tree, \"\", 0, 0, &pathspec,\n-\t\t\t\t  reject_entry, &pathspec);\n-\tclear_pathspec(&pathspec);\n+\tctx.args = args;\n+\tparse_pathspec(&ctx.pathspec, 0, 0, \"\", paths);\n+\tctx.pathspec.recursive = 1;\n+\tret = read_tree_recursive(args->tree, \"\", 0, 0, &ctx.pathspec,\n+\t\t\t\t  reject_entry, &ctx);\n+\tclear_pathspec(&ctx.pathspec);\n \treturn ret != 0;\n }\n \n@@ -348,7 +359,7 @@ static void parse_pathspec_arg(const char **pathspec,\n \tar_args->pathspec.recursive = 1;\n \tif (pathspec) {\n \t\twhile (*pathspec) {\n-\t\t\tif (**pathspec && !path_exists(ar_args->tree, *pathspec))\n+\t\t\tif (**pathspec && !path_exists(ar_args, *pathspec))\n \t\t\t\tdie(_(\"pathspec '%s' did not match any files\"), *pathspec);\n \t\t\tpathspec++;\n \t\t}\n@@ -510,6 +521,7 @@ static int parse_archive_args(int argc, const char **argv,\n }\n \n int write_archive(int argc, const char **argv, const char *prefix,\n+\t\t  struct repository *repo,\n \t\t  const char *name_hint, int remote)\n {\n \tconst struct archiver *ar = NULL;\n@@ -521,6 +533,7 @@ int write_archive(int argc, const char **argv, const char *prefix,\n \tinit_tar_archiver();\n \tinit_zip_archiver();\n \n+\targs.repo = repo;\n \targc = parse_archive_args(argc, argv, &ar, &args, name_hint, remote);\n \tif (!startup_info->have_repository) {\n \t\t/*\ndiff --git a/archive.h b/archive.h\nindex 1f9954f7cd..75b9a86066 100644\n--- a/archive.h\n+++ b/archive.h\n@@ -3,7 +3,10 @@\n \n #include \"pathspec.h\"\n \n+struct repository;\n+\n struct archiver_args {\n+\tstruct repository *repo;\n \tconst char *base;\n \tsize_t baselen;\n \tstruct tree *tree;\n@@ -17,6 +20,16 @@ struct archiver_args {\n \tint compression_level;\n };\n \n+/* main api */\n+\n+extern int write_archive(int argc, const char **argv, const char *prefix,\n+\t\t\t struct repository *repo,\n+\t\t\t const char *name_hint, int remote);\n+\n+const char *archive_format_from_filename(const char *filename);\n+\n+/* archive backend stuff */\n+\n #define ARCHIVER_WANT_COMPRESSION_LEVELS 1\n #define ARCHIVER_REMOTE 2\n struct archiver {\n@@ -36,9 +49,6 @@ typedef int (*write_archive_entry_fn_t)(struct archiver_args *args,\n \t\t\t\t\tunsigned int mode);\n \n extern int write_archive_entries(struct archiver_args *args, write_archive_entry_fn_t write_entry);\n-extern int write_archive(int argc, const char **argv, const char *prefix, const char *name_hint, int remote);\n-\n-const char *archive_format_from_filename(const char *filename);\n extern void *object_file_to_archive(const struct archiver_args *args,\n \t\t\t\t    const char *path, const struct object_id *oid,\n \t\t\t\t    unsigned int mode, enum object_type *type,\ndiff --git a/builtin/archive.c b/builtin/archive.c\nindex 73971d0dd2..e74f675390 100644\n--- a/builtin/archive.c\n+++ b/builtin/archive.c\n@@ -105,5 +105,5 @@ int cmd_archive(int argc, const char **argv, const char *prefix)\n \n \tsetvbuf(stderr, NULL, _IOLBF, BUFSIZ);\n \n-\treturn write_archive(argc, argv, prefix, output, 0);\n+\treturn write_archive(argc, argv, prefix, the_repository, output, 0);\n }\ndiff --git a/builtin/upload-archive.c b/builtin/upload-archive.c\nindex 84532ae9a9..25d9116356 100644\n--- a/builtin/upload-archive.c\n+++ b/builtin/upload-archive.c\n@@ -43,7 +43,8 @@ int cmd_upload_archive_writer(int argc, const char **argv, const char *prefix)\n \t}\n \n \t/* parse all options sent by the client */\n-\treturn write_archive(sent_argv.argc, sent_argv.argv, prefix, NULL, 1);\n+\treturn write_archive(sent_argv.argc, sent_argv.argv, prefix,\n+\t\t\t     the_repository, NULL, 1);\n }\n \n __attribute__((format (printf, 1, 2)))\n-- \n2.18.0.1004.g6639190530\n\n"},{"id":"355392","messageId":"20180813161441.16824-24-pclouds@gmail.com","threadId":"49115","inReplyTo":"20180813161441.16824-1-pclouds@gmail.com","subject":"[PATCH 23/24] apply.c: remove implicit dependency on the_index","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-08-13T16:14:40Z","receivedAt":"2018-08-13T16:15:50Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Use apply_state->repo->index instead of the_index (in most cases,\nunless we need to use a temporary index in some functions). Let the\ncallers (am and apply) tell us what to use, instead of always assuming\nto operate on the_index.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n apply.c | 46 +++++++++++++++++++++++++---------------------\n 1 file changed, 25 insertions(+), 21 deletions(-)\n\ndiff --git a/apply.c b/apply.c\nindex 3704850ef2..e485fbc6bc 100644\n--- a/apply.c\n+++ b/apply.c\n@@ -3385,7 +3385,8 @@ static int verify_index_match(struct apply_state *state,\n \t\t\treturn -1;\n \t\treturn 0;\n \t}\n-\treturn ce_match_stat(ce, st, CE_MATCH_IGNORE_VALID|CE_MATCH_IGNORE_SKIP_WORKTREE);\n+\treturn ie_match_stat(state->repo->index, ce, st,\n+\t\t\t     CE_MATCH_IGNORE_VALID | CE_MATCH_IGNORE_SKIP_WORKTREE);\n }\n \n #define SUBMODULE_PATCH_WITHOUT_INDEX 1\n@@ -3518,14 +3519,14 @@ static int load_current(struct apply_state *state,\n \tif (!patch->is_new)\n \t\tBUG(\"patch to %s is not a creation\", patch->old_name);\n \n-\tpos = cache_name_pos(name, strlen(name));\n+\tpos = index_name_pos(state->repo->index, name, strlen(name));\n \tif (pos < 0)\n \t\treturn error(_(\"%s: does not exist in index\"), name);\n-\tce = active_cache[pos];\n+\tce = state->repo->index->cache[pos];\n \tif (lstat(name, &st)) {\n \t\tif (errno != ENOENT)\n \t\t\treturn error_errno(\"%s\", name);\n-\t\tif (checkout_target(&the_index, ce, &st))\n+\t\tif (checkout_target(state->repo->index, ce, &st))\n \t\t\treturn -1;\n \t}\n \tif (verify_index_match(state, ce, &st))\n@@ -3687,15 +3688,16 @@ static int check_preimage(struct apply_state *state,\n \t}\n \n \tif (state->check_index && !previous) {\n-\t\tint pos = cache_name_pos(old_name, strlen(old_name));\n+\t\tint pos = index_name_pos(state->repo->index, old_name,\n+\t\t\t\t\t strlen(old_name));\n \t\tif (pos < 0) {\n \t\t\tif (patch->is_new < 0)\n \t\t\t\tgoto is_new;\n \t\t\treturn error(_(\"%s: does not exist in index\"), old_name);\n \t\t}\n-\t\t*ce = active_cache[pos];\n+\t\t*ce = state->repo->index->cache[pos];\n \t\tif (stat_ret < 0) {\n-\t\t\tif (checkout_target(&the_index, *ce, st))\n+\t\t\tif (checkout_target(state->repo->index, *ce, st))\n \t\t\t\treturn -1;\n \t\t}\n \t\tif (!state->cached && verify_index_match(state, *ce, st))\n@@ -3742,7 +3744,7 @@ static int check_to_create(struct apply_state *state,\n \tstruct stat nst;\n \n \tif (state->check_index &&\n-\t    cache_name_pos(new_name, strlen(new_name)) >= 0 &&\n+\t    index_name_pos(state->repo->index, new_name, strlen(new_name)) >= 0 &&\n \t    !ok_if_exists)\n \t\treturn EXISTS_IN_INDEX;\n \tif (state->cached)\n@@ -3831,7 +3833,8 @@ static int path_is_beyond_symlink_1(struct apply_state *state, struct strbuf *na\n \t\tif (state->check_index) {\n \t\t\tstruct cache_entry *ce;\n \n-\t\t\tce = cache_file_exists(name->buf, name->len, ignore_case);\n+\t\t\tce = index_file_exists(state->repo->index, name->buf,\n+\t\t\t\t\t       name->len, ignore_case);\n \t\t\tif (ce && S_ISLNK(ce->ce_mode))\n \t\t\t\treturn 1;\n \t\t} else {\n@@ -4006,9 +4009,10 @@ static int check_patch_list(struct apply_state *state, struct patch *patch)\n static int read_apply_cache(struct apply_state *state)\n {\n \tif (state->index_file)\n-\t\treturn read_cache_from(state->index_file);\n+\t\treturn read_index_from(state->repo->index, state->index_file,\n+\t\t\t\t       get_git_dir());\n \telse\n-\t\treturn read_cache();\n+\t\treturn read_index(state->repo->index);\n }\n \n /* This function tries to read the object name from the current index */\n@@ -4019,10 +4023,10 @@ static int get_current_oid(struct apply_state *state, const char *path,\n \n \tif (read_apply_cache(state) < 0)\n \t\treturn -1;\n-\tpos = cache_name_pos(path, strlen(path));\n+\tpos = index_name_pos(state->repo->index, path, strlen(path));\n \tif (pos < 0)\n \t\treturn -1;\n-\toidcpy(oid, &active_cache[pos]->oid);\n+\toidcpy(oid, &state->repo->index->cache[pos]->oid);\n \treturn 0;\n }\n \n@@ -4250,7 +4254,7 @@ static void patch_stats(struct apply_state *state, struct patch *patch)\n static int remove_file(struct apply_state *state, struct patch *patch, int rmdir_empty)\n {\n \tif (state->update_index && !state->ita_only) {\n-\t\tif (remove_file_from_cache(patch->old_name) < 0)\n+\t\tif (remove_file_from_index(state->repo->index, patch->old_name) < 0)\n \t\t\treturn error(_(\"unable to remove %s from index\"), patch->old_name);\n \t}\n \tif (!state->cached) {\n@@ -4271,7 +4275,7 @@ static int add_index_file(struct apply_state *state,\n \tstruct cache_entry *ce;\n \tint namelen = strlen(path);\n \n-\tce = make_empty_cache_entry(&the_index, namelen);\n+\tce = make_empty_cache_entry(state->repo->index, namelen);\n \tmemcpy(ce->name, path, namelen);\n \tce->ce_mode = create_ce_mode(mode);\n \tce->ce_flags = create_ce_flags(0);\n@@ -4303,7 +4307,7 @@ static int add_index_file(struct apply_state *state,\n \t\t\t\t       \"for newly created file %s\"), path);\n \t\t}\n \t}\n-\tif (add_cache_entry(ce, ADD_CACHE_OK_TO_ADD) < 0) {\n+\tif (add_index_entry(state->repo->index, ce, ADD_CACHE_OK_TO_ADD) < 0) {\n \t\tdiscard_cache_entry(ce);\n \t\treturn error(_(\"unable to add cache entry for %s\"), path);\n \t}\n@@ -4341,7 +4345,7 @@ static int try_create_file(struct apply_state *state, const char *path,\n \tif (fd < 0)\n \t\treturn 1;\n \n-\tif (convert_to_working_tree(&the_index, path, buf, size, &nbuf)) {\n+\tif (convert_to_working_tree(state->repo->index, path, buf, size, &nbuf)) {\n \t\tsize = nbuf.len;\n \t\tbuf  = nbuf.buf;\n \t}\n@@ -4438,17 +4442,17 @@ static int add_conflicted_stages_file(struct apply_state *state,\n \tnamelen = strlen(patch->new_name);\n \tmode = patch->new_mode ? patch->new_mode : (S_IFREG | 0644);\n \n-\tremove_file_from_cache(patch->new_name);\n+\tremove_file_from_index(state->repo->index, patch->new_name);\n \tfor (stage = 1; stage < 4; stage++) {\n \t\tif (is_null_oid(&patch->threeway_stage[stage - 1]))\n \t\t\tcontinue;\n-\t\tce = make_empty_cache_entry(&the_index, namelen);\n+\t\tce = make_empty_cache_entry(state->repo->index, namelen);\n \t\tmemcpy(ce->name, patch->new_name, namelen);\n \t\tce->ce_mode = create_ce_mode(mode);\n \t\tce->ce_flags = create_ce_flags(stage);\n \t\tce->ce_namelen = namelen;\n \t\toidcpy(&ce->oid, &patch->threeway_stage[stage - 1]);\n-\t\tif (add_cache_entry(ce, ADD_CACHE_OK_TO_ADD) < 0) {\n+\t\tif (add_index_entry(state->repo->index, ce, ADD_CACHE_OK_TO_ADD) < 0) {\n \t\t\tdiscard_cache_entry(ce);\n \t\t\treturn error(_(\"unable to add cache entry for %s\"),\n \t\t\t\t     patch->new_name);\n@@ -4897,7 +4901,7 @@ int apply_all_patches(struct apply_state *state,\n \t}\n \n \tif (state->update_index) {\n-\t\tres = write_locked_index(&the_index, &state->lock_file, COMMIT_LOCK);\n+\t\tres = write_locked_index(state->repo->index, &state->lock_file, COMMIT_LOCK);\n \t\tif (res) {\n \t\t\terror(_(\"Unable to write new index file\"));\n \t\t\tres = -128;\n-- \n2.18.0.1004.g6639190530\n\n"},{"id":"355393","messageId":"20180813161441.16824-25-pclouds@gmail.com","threadId":"49115","inReplyTo":"20180813161441.16824-1-pclouds@gmail.com","subject":"[PATCH 24/24] blame.c: remove implicit dependency on the_index","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2018-08-13T16:14:41Z","receivedAt":"2018-08-13T16:15:52Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Side note, since we gain access to the right repository, we can stop\nrely on the_repository in this code as well.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n blame.c         | 52 +++++++++++++++++++++++++++++--------------------\n blame.h         |  1 +\n builtin/blame.c |  1 +\n 3 files changed, 33 insertions(+), 21 deletions(-)\n\ndiff --git a/blame.c b/blame.c\nindex 58a7036847..08c0c6cf73 100644\n--- a/blame.c\n+++ b/blame.c\n@@ -90,7 +90,8 @@ static struct blame_origin *get_origin(struct commit *commit, const char *path)\n \n \n \n-static void verify_working_tree_path(struct commit *work_tree, const char *path)\n+static void verify_working_tree_path(struct repository *repo,\n+\t\t\t\t     struct commit *work_tree, const char *path)\n {\n \tstruct commit_list *parents;\n \tint pos;\n@@ -101,15 +102,15 @@ static void verify_working_tree_path(struct commit *work_tree, const char *path)\n \t\tunsigned mode;\n \n \t\tif (!get_tree_entry(commit_oid, path, &blob_oid, &mode) &&\n-\t\t    oid_object_info(the_repository, &blob_oid, NULL) == OBJ_BLOB)\n+\t\t    oid_object_info(repo, &blob_oid, NULL) == OBJ_BLOB)\n \t\t\treturn;\n \t}\n \n-\tpos = cache_name_pos(path, strlen(path));\n+\tpos = index_name_pos(repo->index, path, strlen(path));\n \tif (pos >= 0)\n \t\t; /* path is in the index */\n-\telse if (-1 - pos < active_nr &&\n-\t\t !strcmp(active_cache[-1 - pos]->name, path))\n+\telse if (-1 - pos < repo->index->cache_nr &&\n+\t\t !strcmp(repo->index->cache[-1 - pos]->name, path))\n \t\t; /* path is in the index, unmerged */\n \telse\n \t\tdie(\"no such path '%s' in HEAD\", path);\n@@ -165,7 +166,8 @@ static void set_commit_buffer_from_strbuf(struct commit *c, struct strbuf *sb)\n  * Prepare a dummy commit that represents the work tree (or staged) item.\n  * Note that annotating work tree item never works in the reverse.\n  */\n-static struct commit *fake_working_tree_commit(struct diff_options *opt,\n+static struct commit *fake_working_tree_commit(struct repository *repo,\n+\t\t\t\t\t       struct diff_options *opt,\n \t\t\t\t\t       const char *path,\n \t\t\t\t\t       const char *contents_from)\n {\n@@ -181,7 +183,7 @@ static struct commit *fake_working_tree_commit(struct diff_options *opt,\n \tunsigned mode;\n \tstruct strbuf msg = STRBUF_INIT;\n \n-\tread_cache();\n+\tread_index(repo->index);\n \ttime(&now);\n \tcommit = alloc_commit_node(the_repository);\n \tcommit->object.parsed = 1;\n@@ -193,7 +195,7 @@ static struct commit *fake_working_tree_commit(struct diff_options *opt,\n \n \tparent_tail = append_parent(parent_tail, &head_oid);\n \tappend_merge_parents(parent_tail);\n-\tverify_working_tree_path(commit, path);\n+\tverify_working_tree_path(repo, commit, path);\n \n \torigin = make_origin(commit, path);\n \n@@ -251,7 +253,7 @@ static struct commit *fake_working_tree_commit(struct diff_options *opt,\n \t\tif (strbuf_read(&buf, 0, 0) < 0)\n \t\t\tdie_errno(\"failed to read from stdin\");\n \t}\n-\tconvert_to_git(&the_index, path, buf.buf, buf.len, &buf, 0);\n+\tconvert_to_git(repo->index, path, buf.buf, buf.len, &buf, 0);\n \torigin->file.ptr = buf.buf;\n \torigin->file.size = buf.len;\n \tpretend_object_file(buf.buf, buf.len, OBJ_BLOB, &origin->blob_oid);\n@@ -262,27 +264,28 @@ static struct commit *fake_working_tree_commit(struct diff_options *opt,\n \t * bits; we are not going to write this index out -- we just\n \t * want to run \"diff-index --cached\".\n \t */\n-\tdiscard_cache();\n-\tread_cache();\n+\tdiscard_index(repo->index);\n+\tread_index(repo->index);\n \n \tlen = strlen(path);\n \tif (!mode) {\n-\t\tint pos = cache_name_pos(path, len);\n+\t\tint pos = index_name_pos(repo->index, path, len);\n \t\tif (0 <= pos)\n-\t\t\tmode = active_cache[pos]->ce_mode;\n+\t\t\tmode = repo->index->cache[pos]->ce_mode;\n \t\telse\n \t\t\t/* Let's not bother reading from HEAD tree */\n \t\t\tmode = S_IFREG | 0644;\n \t}\n-\tce = make_empty_cache_entry(&the_index, len);\n+\tce = make_empty_cache_entry(repo->index, len);\n \toidcpy(&ce->oid, &origin->blob_oid);\n \tmemcpy(ce->name, path, len);\n \tce->ce_flags = create_ce_flags(0);\n \tce->ce_namelen = len;\n \tce->ce_mode = create_ce_mode(mode);\n-\tadd_cache_entry(ce, ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE);\n+\tadd_index_entry(repo->index, ce,\n+\t\t\tADD_CACHE_OK_TO_ADD | ADD_CACHE_OK_TO_REPLACE);\n \n-\tcache_tree_invalidate_path(&the_index, path);\n+\tcache_tree_invalidate_path(repo->index, path);\n \n \treturn commit;\n }\n@@ -519,13 +522,14 @@ static void queue_blames(struct blame_scoreboard *sb, struct blame_origin *porig\n  *\n  * This also fills origin->mode for corresponding tree path.\n  */\n-static int fill_blob_sha1_and_mode(struct blame_origin *origin)\n+static int fill_blob_sha1_and_mode(struct repository *repo,\n+\t\t\t\t   struct blame_origin *origin)\n {\n \tif (!is_null_oid(&origin->blob_oid))\n \t\treturn 0;\n \tif (get_tree_entry(&origin->commit->object.oid, origin->path, &origin->blob_oid, &origin->mode))\n \t\tgoto error_out;\n-\tif (oid_object_info(the_repository, &origin->blob_oid, NULL) != OBJ_BLOB)\n+\tif (oid_object_info(repo, &origin->blob_oid, NULL) != OBJ_BLOB)\n \t\tgoto error_out;\n \treturn 0;\n  error_out:\n@@ -1767,7 +1771,9 @@ void init_scoreboard(struct blame_scoreboard *sb)\n \tsb->copy_score = BLAME_DEFAULT_COPY_SCORE;\n }\n \n-void setup_scoreboard(struct blame_scoreboard *sb, const char *path, struct blame_origin **orig)\n+void setup_scoreboard(struct blame_scoreboard *sb,\n+\t\t      const char *path,\n+\t\t      struct blame_origin **orig)\n {\n \tconst char *final_commit_name = NULL;\n \tstruct blame_origin *o;\n@@ -1779,6 +1785,9 @@ void setup_scoreboard(struct blame_scoreboard *sb, const char *path, struct blam\n \tif (sb->reverse && sb->contents_from)\n \t\tdie(_(\"--contents and --reverse do not blend well.\"));\n \n+\tif (!sb->repo)\n+\t\tBUG(\"repo is NULL\");\n+\n \tif (!sb->reverse) {\n \t\tsb->final = find_single_final(sb->revs, &final_commit_name);\n \t\tsb->commits.compare = compare_commits_by_commit_date;\n@@ -1800,7 +1809,8 @@ void setup_scoreboard(struct blame_scoreboard *sb, const char *path, struct blam\n \t\t * or \"--contents\".\n \t\t */\n \t\tsetup_work_tree();\n-\t\tsb->final = fake_working_tree_commit(&sb->revs->diffopt,\n+\t\tsb->final = fake_working_tree_commit(sb->repo,\n+\t\t\t\t\t\t     &sb->revs->diffopt,\n \t\t\t\t\t\t     path, sb->contents_from);\n \t\tadd_pending_object(sb->revs, &(sb->final->object), \":\");\n \t}\n@@ -1845,7 +1855,7 @@ void setup_scoreboard(struct blame_scoreboard *sb, const char *path, struct blam\n \t}\n \telse {\n \t\to = get_origin(sb->final, path);\n-\t\tif (fill_blob_sha1_and_mode(o))\n+\t\tif (fill_blob_sha1_and_mode(sb->repo, o))\n \t\t\tdie(_(\"no such path %s in %s\"), path, final_commit_name);\n \n \t\tif (sb->revs->diffopt.flags.allow_textconv &&\ndiff --git a/blame.h b/blame.h\nindex 9b5240fb6d..be3a895043 100644\n--- a/blame.h\n+++ b/blame.h\n@@ -102,6 +102,7 @@ struct blame_scoreboard {\n \tstruct commit *final;\n \t/* Priority queue for commits with unassigned blame records */\n \tstruct prio_queue commits;\n+\tstruct repository *repo;\n \tstruct rev_info *revs;\n \tconst char *path;\n \ndiff --git a/builtin/blame.c b/builtin/blame.c\nindex 5c93d169dd..cbbcb26f89 100644\n--- a/builtin/blame.c\n+++ b/builtin/blame.c\n@@ -988,6 +988,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)\n \tsb.revs = &revs;\n \tsb.contents_from = contents_from;\n \tsb.reverse = reverse;\n+\tsb.repo = the_repository;\n \tsetup_scoreboard(&sb, path, &o);\n \tlno = sb.num_lines;\n \n-- \n2.18.0.1004.g6639190530\n\n"},{"id":"355401","messageId":"20180813171202.GA240194@google.com","threadId":"49115","inReplyTo":"20180813161441.16824-4-pclouds@gmail.com","subject":"Re: [PATCH 03/24] attr: remove an implicit dependency on the_index","fromName":"Brandon Williams","fromEmail":"bmwill@google.com","sentAt":"2018-08-13T17:12:02Z","receivedAt":"2018-08-13T17:12:07Z","isPatch":true,"sender":{"key":"bwilliams.eng@gmail.com","avatar":null},"body":"On 08/13, Nguyễn Thái Ngọc Duy wrote:\n> Make the attr API take an index_state instead of assuming the_index in\n> attr code. All call sites are converted blindly to keep the patch\n> simple and retain current behavior. Individual call sites may receive\n> further updates to use the right index instead of the_index.\n> \n> There is one ugly temporary workaround added in attr.c that needs some\n> more explanation.\n> \n> Commit c24f3abace (apply: file commited with CRLF should roundtrip\n> diff and apply - 2017-08-19) forces one convert_to_git() call to NOT\n> read the index at all. But what do you know, we read it anyway by\n> falling back to the_index. When \"istate\" from convert_to_git is now\n> propagated down to read_attr_from_array() we will hit segfault\n> somewhere inside read_blob_data_from_index.\n> \n> The right way of dealing with this is to kill \"use_index\" variable and\n> only follow \"istate\" but at this stage we are not ready for that:\n> while most git_attr_set_direction() calls just passes the_index to be\n> assigned to use_index, unpack-trees passes a different one which is\n> used by entry.c code, which has no way to know what index to use if we\n> delete use_index. So this has to be done later.\n\nYep, I remember back when I was doing some refactorings on the attr\nsystem trying to get rid of the whole \"use_index\" thing.  At that point\nin time it wasn't feasible to do so, so i'm excited that it should be\ndone soon! :D\n\n> \n> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n> ---\n>  archive.c              |  2 +-\n>  attr.c                 | 57 ++++++++++++++++++++++++++++--------------\n>  attr.h                 | 10 +++++---\n>  builtin/check-attr.c   |  4 +--\n>  builtin/pack-objects.c |  2 +-\n>  convert.c              |  2 +-\n>  dir.c                  |  2 +-\n>  ll-merge.c             |  4 +--\n>  userdiff.c             |  2 +-\n>  ws.c                   |  2 +-\n>  10 files changed, 55 insertions(+), 32 deletions(-)\n> \n> diff --git a/archive.c b/archive.c\n> index 78b0a398a0..a8397e6173 100644\n> --- a/archive.c\n> +++ b/archive.c\n> @@ -109,7 +109,7 @@ static const struct attr_check *get_archive_attrs(const char *path)\n>  \tstatic struct attr_check *check;\n>  \tif (!check)\n>  \t\tcheck = attr_check_initl(\"export-ignore\", \"export-subst\", NULL);\n> -\treturn git_check_attr(path, check) ? NULL : check;\n> +\treturn git_check_attr(&the_index, path, check) ? NULL : check;\n>  }\n>  \n>  static int check_attr_export_ignore(const struct attr_check *check)\n> diff --git a/attr.c b/attr.c\n> index 067fb9e0c0..863fad3bd1 100644\n> --- a/attr.c\n> +++ b/attr.c\n> @@ -708,10 +708,10 @@ static struct attr_stack *read_attr_from_array(const char **list)\n>   * another thread could potentially be calling into the attribute system.\n>   */\n>  static enum git_attr_direction direction;\n> -static struct index_state *use_index;\n> +static const struct index_state *use_index;\n>  \n>  void git_attr_set_direction(enum git_attr_direction new_direction,\n> -\t\t\t    struct index_state *istate)\n> +\t\t\t    const struct index_state *istate)\n>  {\n>  \tif (is_bare_repository() && new_direction != GIT_ATTR_INDEX)\n>  \t\tBUG(\"non-INDEX attr direction in a bare repo\");\n> @@ -743,13 +743,24 @@ static struct attr_stack *read_attr_from_file(const char *path, int macro_ok)\n>  \treturn res;\n>  }\n>  \n> -static struct attr_stack *read_attr_from_index(const char *path, int macro_ok)\n> +static struct attr_stack *read_attr_from_index(const struct index_state *istate,\n> +\t\t\t\t\t       const char *path,\n> +\t\t\t\t\t       int macro_ok)\n>  {\n>  \tstruct attr_stack *res;\n>  \tchar *buf, *sp;\n>  \tint lineno = 0;\n> +\tconst struct index_state *to_read_from;\n>  \n> -\tbuf = read_blob_data_from_index(use_index ? use_index : &the_index, path, NULL);\n> +\t/*\n> +\t * Temporary workaround for c24f3abace (apply: file commited\n> +\t * with CRLF should roundtrip diff and apply - 2017-08-19)\n> +\t */\n> +\tto_read_from = use_index ? use_index : istate;\n> +\tif (!to_read_from)\n> +\t\treturn NULL;\n> +\n> +\tbuf = read_blob_data_from_index(to_read_from, path, NULL);\n>  \tif (!buf)\n>  \t\treturn NULL;\n>  \n> @@ -768,15 +779,16 @@ static struct attr_stack *read_attr_from_index(const char *path, int macro_ok)\n>  \treturn res;\n>  }\n>  \n> -static struct attr_stack *read_attr(const char *path, int macro_ok)\n> +static struct attr_stack *read_attr(const struct index_state *istate,\n> +\t\t\t\t    const char *path, int macro_ok)\n>  {\n>  \tstruct attr_stack *res = NULL;\n>  \n>  \tif (direction == GIT_ATTR_INDEX) {\n> -\t\tres = read_attr_from_index(path, macro_ok);\n> +\t\tres = read_attr_from_index(istate, path, macro_ok);\n>  \t} else if (!is_bare_repository()) {\n>  \t\tif (direction == GIT_ATTR_CHECKOUT) {\n> -\t\t\tres = read_attr_from_index(path, macro_ok);\n> +\t\t\tres = read_attr_from_index(istate, path, macro_ok);\n>  \t\t\tif (!res)\n>  \t\t\t\tres = read_attr_from_file(path, macro_ok);\n>  \t\t} else if (direction == GIT_ATTR_CHECKIN) {\n> @@ -788,7 +800,7 @@ static struct attr_stack *read_attr(const char *path, int macro_ok)\n>  \t\t\t\t * We allow operation in a sparsely checked out\n>  \t\t\t\t * work tree, so read from it.\n>  \t\t\t\t */\n> -\t\t\t\tres = read_attr_from_index(path, macro_ok);\n> +\t\t\t\tres = read_attr_from_index(istate, path, macro_ok);\n>  \t\t}\n>  \t}\n>  \n> @@ -859,7 +871,8 @@ static void push_stack(struct attr_stack **attr_stack_p,\n>  \t}\n>  }\n>  \n> -static void bootstrap_attr_stack(struct attr_stack **stack)\n> +static void bootstrap_attr_stack(const struct index_state *istate,\n> +\t\t\t\t struct attr_stack **stack)\n>  {\n>  \tstruct attr_stack *e;\n>  \n> @@ -883,7 +896,7 @@ static void bootstrap_attr_stack(struct attr_stack **stack)\n>  \t}\n>  \n>  \t/* root directory */\n> -\te = read_attr(GITATTRIBUTES_FILE, 1);\n> +\te = read_attr(istate, GITATTRIBUTES_FILE, 1);\n>  \tpush_stack(stack, e, xstrdup(\"\"), 0);\n>  \n>  \t/* info frame */\n> @@ -896,7 +909,8 @@ static void bootstrap_attr_stack(struct attr_stack **stack)\n>  \tpush_stack(stack, e, NULL, 0);\n>  }\n>  \n> -static void prepare_attr_stack(const char *path, int dirlen,\n> +static void prepare_attr_stack(const struct index_state *istate,\n> +\t\t\t       const char *path, int dirlen,\n>  \t\t\t       struct attr_stack **stack)\n>  {\n>  \tstruct attr_stack *info;\n> @@ -917,7 +931,7 @@ static void prepare_attr_stack(const char *path, int dirlen,\n>  \t * .gitattributes in deeper directories to shallower ones,\n>  \t * and finally use the built-in set as the default.\n>  \t */\n> -\tbootstrap_attr_stack(stack);\n> +\tbootstrap_attr_stack(istate, stack);\n>  \n>  \t/*\n>  \t * Pop the \"info\" one that is always at the top of the stack.\n> @@ -973,7 +987,7 @@ static void prepare_attr_stack(const char *path, int dirlen,\n>  \t\tstrbuf_add(&pathbuf, path + pathbuf.len, (len - pathbuf.len));\n>  \t\tstrbuf_addf(&pathbuf, \"/%s\", GITATTRIBUTES_FILE);\n>  \n> -\t\tnext = read_attr(pathbuf.buf, 0);\n> +\t\tnext = read_attr(istate, pathbuf.buf, 0);\n>  \n>  \t\t/* reset the pathbuf to not include \"/.gitattributes\" */\n>  \t\tstrbuf_setlen(&pathbuf, len);\n> @@ -1095,7 +1109,9 @@ static void determine_macros(struct all_attrs_item *all_attrs,\n>   * If check->check_nr is non-zero, only attributes in check[] are collected.\n>   * Otherwise all attributes are collected.\n>   */\n> -static void collect_some_attrs(const char *path, struct attr_check *check)\n> +static void collect_some_attrs(const struct index_state *istate,\n> +\t\t\t       const char *path,\n> +\t\t\t       struct attr_check *check)\n>  {\n>  \tint i, pathlen, rem, dirlen;\n>  \tconst char *cp, *last_slash = NULL;\n> @@ -1114,7 +1130,7 @@ static void collect_some_attrs(const char *path, struct attr_check *check)\n>  \t\tdirlen = 0;\n>  \t}\n>  \n> -\tprepare_attr_stack(path, dirlen, &check->stack);\n> +\tprepare_attr_stack(istate, path, dirlen, &check->stack);\n>  \tall_attrs_init(&g_attr_hashmap, check);\n>  \tdetermine_macros(check->all_attrs, check->stack);\n>  \n> @@ -1136,11 +1152,13 @@ static void collect_some_attrs(const char *path, struct attr_check *check)\n>  \tfill(path, pathlen, basename_offset, check->stack, check->all_attrs, rem);\n>  }\n>  \n> -int git_check_attr(const char *path, struct attr_check *check)\n> +int git_check_attr(const struct index_state *istate,\n> +\t\t   const char *path,\n> +\t\t   struct attr_check *check)\n>  {\n>  \tint i;\n>  \n> -\tcollect_some_attrs(path, check);\n> +\tcollect_some_attrs(istate, path, check);\n>  \n>  \tfor (i = 0; i < check->nr; i++) {\n>  \t\tsize_t n = check->items[i].attr->attr_nr;\n> @@ -1153,12 +1171,13 @@ int git_check_attr(const char *path, struct attr_check *check)\n>  \treturn 0;\n>  }\n>  \n> -void git_all_attrs(const char *path, struct attr_check *check)\n> +void git_all_attrs(const struct index_state *istate,\n> +\t\t   const char *path, struct attr_check *check)\n>  {\n>  \tint i;\n>  \n>  \tattr_check_reset(check);\n> -\tcollect_some_attrs(path, check);\n> +\tcollect_some_attrs(istate, path, check);\n>  \n>  \tfor (i = 0; i < check->all_attrs_nr; i++) {\n>  \t\tconst char *name = check->all_attrs[i].attr->name;\n> diff --git a/attr.h b/attr.h\n> index 46340010bb..3daca3c0cb 100644\n> --- a/attr.h\n> +++ b/attr.h\n> @@ -1,6 +1,8 @@\n>  #ifndef ATTR_H\n>  #define ATTR_H\n>  \n> +struct index_state;\n> +\n>  /* An attribute is a pointer to this opaque structure */\n>  struct git_attr;\n>  \n> @@ -60,13 +62,15 @@ void attr_check_free(struct attr_check *check);\n>   */\n>  const char *git_attr_name(const struct git_attr *);\n>  \n> -int git_check_attr(const char *path, struct attr_check *check);\n> +int git_check_attr(const struct index_state *istate,\n> +\t\t   const char *path, struct attr_check *check);\n>  \n>  /*\n>   * Retrieve all attributes that apply to the specified path.\n>   * check holds the attributes and their values.\n>   */\n> -void git_all_attrs(const char *path, struct attr_check *check);\n> +void git_all_attrs(const struct index_state *istate,\n> +\t\t   const char *path, struct attr_check *check);\n>  \n>  enum git_attr_direction {\n>  \tGIT_ATTR_CHECKIN,\n> @@ -74,7 +78,7 @@ enum git_attr_direction {\n>  \tGIT_ATTR_INDEX\n>  };\n>  void git_attr_set_direction(enum git_attr_direction new_direction,\n> -\t\t\t    struct index_state *istate);\n> +\t\t\t    const struct index_state *istate);\n>  \n>  void attr_start(void);\n>  \n> diff --git a/builtin/check-attr.c b/builtin/check-attr.c\n> index 91444dc044..f7b59993d3 100644\n> --- a/builtin/check-attr.c\n> +++ b/builtin/check-attr.c\n> @@ -63,9 +63,9 @@ static void check_attr(const char *prefix,\n>  \t\tprefix_path(prefix, prefix ? strlen(prefix) : 0, file);\n>  \n>  \tif (collect_all) {\n> -\t\tgit_all_attrs(full_path, check);\n> +\t\tgit_all_attrs(&the_index, full_path, check);\n>  \t} else {\n> -\t\tif (git_check_attr(full_path, check))\n> +\t\tif (git_check_attr(&the_index, full_path, check))\n>  \t\t\tdie(\"git_check_attr died\");\n>  \t}\n>  \toutput_attr(check, file);\n> diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c\n> index 4391504a91..3ff6da441f 100644\n> --- a/builtin/pack-objects.c\n> +++ b/builtin/pack-objects.c\n> @@ -945,7 +945,7 @@ static int no_try_delta(const char *path)\n>  \n>  \tif (!check)\n>  \t\tcheck = attr_check_initl(\"delta\", NULL);\n> -\tif (git_check_attr(path, check))\n> +\tif (git_check_attr(&the_index, path, check))\n>  \t\treturn 0;\n>  \tif (ATTR_FALSE(check->items[0].value))\n>  \t\treturn 1;\n> diff --git a/convert.c b/convert.c\n> index 7907efd16f..1935bde929 100644\n> --- a/convert.c\n> +++ b/convert.c\n> @@ -1303,7 +1303,7 @@ static void convert_attrs(struct conv_attrs *ca, const char *path)\n>  \t\tgit_config(read_convert_config, NULL);\n>  \t}\n>  \n> -\tif (!git_check_attr(path, check)) {\n> +\tif (!git_check_attr(&the_index, path, check)) {\n>  \t\tstruct attr_check_item *ccheck = check->items;\n>  \t\tca->crlf_action = git_path_check_crlf(ccheck + 4);\n>  \t\tif (ca->crlf_action == CRLF_UNDEFINED)\n> diff --git a/dir.c b/dir.c\n> index 21e6f2520a..29fbbd48c8 100644\n> --- a/dir.c\n> +++ b/dir.c\n> @@ -281,7 +281,7 @@ static int match_attrs(const char *name, int namelen,\n>  {\n>  \tint i;\n>  \n> -\tgit_check_attr(name, item->attr_check);\n> +\tgit_check_attr(&the_index, name, item->attr_check);\n>  \tfor (i = 0; i < item->attr_match_nr; i++) {\n>  \t\tconst char *value;\n>  \t\tint matched;\n> diff --git a/ll-merge.c b/ll-merge.c\n> index a6ad2ec12d..0e2800f7bb 100644\n> --- a/ll-merge.c\n> +++ b/ll-merge.c\n> @@ -371,7 +371,7 @@ int ll_merge(mmbuffer_t *result_buf,\n>  \tif (!check)\n>  \t\tcheck = attr_check_initl(\"merge\", \"conflict-marker-size\", NULL);\n>  \n> -\tif (!git_check_attr(path, check)) {\n> +\tif (!git_check_attr(&the_index, path, check)) {\n>  \t\tll_driver_name = check->items[0].value;\n>  \t\tif (check->items[1].value) {\n>  \t\t\tmarker_size = atoi(check->items[1].value);\n> @@ -398,7 +398,7 @@ int ll_merge_marker_size(const char *path)\n>  \n>  \tif (!check)\n>  \t\tcheck = attr_check_initl(\"conflict-marker-size\", NULL);\n> -\tif (!git_check_attr(path, check) && check->items[0].value) {\n> +\tif (!git_check_attr(&the_index, path, check) && check->items[0].value) {\n>  \t\tmarker_size = atoi(check->items[0].value);\n>  \t\tif (marker_size <= 0)\n>  \t\t\tmarker_size = DEFAULT_CONFLICT_MARKER_SIZE;\n> diff --git a/userdiff.c b/userdiff.c\n> index 36af25e7f9..f3f4be579c 100644\n> --- a/userdiff.c\n> +++ b/userdiff.c\n> @@ -278,7 +278,7 @@ struct userdiff_driver *userdiff_find_by_path(const char *path)\n>  \t\tcheck = attr_check_initl(\"diff\", NULL);\n>  \tif (!path)\n>  \t\treturn NULL;\n> -\tif (git_check_attr(path, check))\n> +\tif (git_check_attr(&the_index, path, check))\n>  \t\treturn NULL;\n>  \n>  \tif (ATTR_TRUE(check->items[0].value))\n> diff --git a/ws.c b/ws.c\n> index a07caedd5a..5b67b426e7 100644\n> --- a/ws.c\n> +++ b/ws.c\n> @@ -78,7 +78,7 @@ unsigned whitespace_rule(const char *pathname)\n>  \tif (!attr_whitespace_rule)\n>  \t\tattr_whitespace_rule = attr_check_initl(\"whitespace\", NULL);\n>  \n> -\tif (!git_check_attr(pathname, attr_whitespace_rule)) {\n> +\tif (!git_check_attr(&the_index, pathname, attr_whitespace_rule)) {\n>  \t\tconst char *value;\n>  \n>  \t\tvalue = attr_whitespace_rule->items[0].value;\n> -- \n> 2.18.0.1004.g6639190530\n> \n\n-- \nBrandon Williams\n"},{"id":"355407","messageId":"20180813171718.GB240194@google.com","threadId":"49115","inReplyTo":"20180813161441.16824-6-pclouds@gmail.com","subject":"Re: [PATCH 05/24] dir.c: remove an implicit dependency on the_index in pathspec code","fromName":"Brandon Williams","fromEmail":"bmwill@google.com","sentAt":"2018-08-13T17:17:18Z","receivedAt":"2018-08-13T17:17:24Z","isPatch":true,"sender":{"key":"bwilliams.eng@gmail.com","avatar":null},"body":"On 08/13, Nguyễn Thái Ngọc Duy wrote:\n> diff --git a/dir.c b/dir.c\n> index 29fbbd48c8..e25aed013b 100644\n> --- a/dir.c\n> +++ b/dir.c\n> @@ -276,12 +276,13 @@ static int do_read_blob(const struct object_id *oid, struct oid_stat *oid_stat,\n>  #define DO_MATCH_DIRECTORY (1<<1)\n>  #define DO_MATCH_SUBMODULE (1<<2)\n>  \n> -static int match_attrs(const char *name, int namelen,\n> +static int match_attrs(const struct index_state *istate,\n> +\t\t       const char *name, int namelen,\n>  \t\t       const struct pathspec_item *item)\n>  {\n>  \tint i;\n>  \n> -\tgit_check_attr(&the_index, name, item->attr_check);\n> +\tgit_check_attr(istate, name, item->attr_check);\n>  \tfor (i = 0; i < item->attr_match_nr; i++) {\n>  \t\tconst char *value;\n>  \t\tint matched;\n> @@ -318,7 +319,8 @@ static int match_attrs(const char *name, int namelen,\n>   *\n>   * It returns 0 when there is no match.\n>   */\n> -static int match_pathspec_item(const struct pathspec_item *item, int prefix,\n> +static int match_pathspec_item(const struct index_state *istate,\n> +\t\t\t       const struct pathspec_item *item, int prefix,\n>  \t\t\t       const char *name, int namelen, unsigned flags)\n>  {\n>  \t/* name/namelen has prefix cut off by caller */\n> @@ -358,7 +360,7 @@ static int match_pathspec_item(const struct pathspec_item *item, int prefix,\n>  \t    strncmp(item->match, name - prefix, item->prefix))\n>  \t\treturn 0;\n>  \n> -\tif (item->attr_match_nr && !match_attrs(name, namelen, item))\n> +\tif (item->attr_match_nr && !match_attrs(istate, name, namelen, item))\n>  \t\treturn 0;\n\nYuck, all of this just because I added the ability to match against\nattrs with pathspecs.  Part of me wonders if it would be better to put a\npointer to the needed istate in the pathspec struct...but then I can\nthink of a ton of reasons why that wouldn't be good either.\n\nSo yes I think this is probably the right approach, I'm just sorry I\nmade it this messy :/\n\n\n-- \nBrandon Williams\n"},{"id":"355416","messageId":"20180813172253.GC240194@google.com","threadId":"49115","inReplyTo":"20180813161441.16824-17-pclouds@gmail.com","subject":"Re: [PATCH 16/24] attr: remove index from git_attr_set_direction()","fromName":"Brandon Williams","fromEmail":"bmwill@google.com","sentAt":"2018-08-13T17:22:53Z","receivedAt":"2018-08-13T17:22:58Z","isPatch":true,"sender":{"key":"bwilliams.eng@gmail.com","avatar":null},"body":"On 08/13, Nguyễn Thái Ngọc Duy wrote:\n> Since attr checking API now take the index, there's no need to set an\n> index in advance with this call. Most call sites are straightforward\n> because they either pass the_index or NULL (which defaults back to\n> the_index previously). There's only one suspicious call site in\n> unpack-trees.c where it sets a different index.\n> \n> This code in unpack-trees is about to check out entries from the\n> new/temporary index after merging is done in it. The attributes will\n> be used by entry.c code to do crlf conversion if needed. entry.c now\n> respects struct checkout's istate field, and this field is correctly\n> set in unpack-trees.c, there should be no regression from this change.\n\nThanks for fixing this! The API is now that much cleaner :)\n\n> \n> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n> ---\n>  archive.c            |  2 +-\n>  attr.c               | 15 +++------------\n>  attr.h               |  3 +--\n>  builtin/check-attr.c |  2 +-\n>  unpack-trees.c       |  4 ++--\n>  5 files changed, 8 insertions(+), 18 deletions(-)\n> \n> diff --git a/archive.c b/archive.c\n> index c81e35bf23..aca9179d03 100644\n> --- a/archive.c\n> +++ b/archive.c\n> @@ -274,7 +274,7 @@ int write_archive_entries(struct archiver_args *args,\n>  \t\tinit_tree_desc(&t, args->tree->buffer, args->tree->size);\n>  \t\tif (unpack_trees(1, &t, &opts))\n>  \t\t\treturn -1;\n> -\t\tgit_attr_set_direction(GIT_ATTR_INDEX, &the_index);\n> +\t\tgit_attr_set_direction(GIT_ATTR_INDEX);\n>  \t}\n>  \n>  \terr = read_tree_recursive(args->tree, \"\", 0, 0, &args->pathspec,\n> diff --git a/attr.c b/attr.c\n> index 863fad3bd1..98e4953f6e 100644\n> --- a/attr.c\n> +++ b/attr.c\n> @@ -708,10 +708,8 @@ static struct attr_stack *read_attr_from_array(const char **list)\n>   * another thread could potentially be calling into the attribute system.\n>   */\n>  static enum git_attr_direction direction;\n> -static const struct index_state *use_index;\n>  \n> -void git_attr_set_direction(enum git_attr_direction new_direction,\n> -\t\t\t    const struct index_state *istate)\n> +void git_attr_set_direction(enum git_attr_direction new_direction)\n>  {\n>  \tif (is_bare_repository() && new_direction != GIT_ATTR_INDEX)\n>  \t\tBUG(\"non-INDEX attr direction in a bare repo\");\n> @@ -720,7 +718,6 @@ void git_attr_set_direction(enum git_attr_direction new_direction,\n>  \t\tdrop_all_attr_stacks();\n>  \n>  \tdirection = new_direction;\n> -\tuse_index = istate;\n>  }\n>  \n>  static struct attr_stack *read_attr_from_file(const char *path, int macro_ok)\n> @@ -750,17 +747,11 @@ static struct attr_stack *read_attr_from_index(const struct index_state *istate,\n>  \tstruct attr_stack *res;\n>  \tchar *buf, *sp;\n>  \tint lineno = 0;\n> -\tconst struct index_state *to_read_from;\n>  \n> -\t/*\n> -\t * Temporary workaround for c24f3abace (apply: file commited\n> -\t * with CRLF should roundtrip diff and apply - 2017-08-19)\n> -\t */\n> -\tto_read_from = use_index ? use_index : istate;\n> -\tif (!to_read_from)\n> +\tif (!istate)\n>  \t\treturn NULL;\n>  \n> -\tbuf = read_blob_data_from_index(to_read_from, path, NULL);\n> +\tbuf = read_blob_data_from_index(istate, path, NULL);\n>  \tif (!buf)\n>  \t\treturn NULL;\n>  \n> diff --git a/attr.h b/attr.h\n> index 3daca3c0cb..01dab4a126 100644\n> --- a/attr.h\n> +++ b/attr.h\n> @@ -77,8 +77,7 @@ enum git_attr_direction {\n>  \tGIT_ATTR_CHECKOUT,\n>  \tGIT_ATTR_INDEX\n>  };\n> -void git_attr_set_direction(enum git_attr_direction new_direction,\n> -\t\t\t    const struct index_state *istate);\n> +void git_attr_set_direction(enum git_attr_direction new_direction);\n>  \n>  void attr_start(void);\n>  \n> diff --git a/builtin/check-attr.c b/builtin/check-attr.c\n> index f7b59993d3..c05573ff9c 100644\n> --- a/builtin/check-attr.c\n> +++ b/builtin/check-attr.c\n> @@ -120,7 +120,7 @@ int cmd_check_attr(int argc, const char **argv, const char *prefix)\n>  \t}\n>  \n>  \tif (cached_attrs)\n> -\t\tgit_attr_set_direction(GIT_ATTR_INDEX, NULL);\n> +\t\tgit_attr_set_direction(GIT_ATTR_INDEX);\n>  \n>  \tdoubledash = -1;\n>  \tfor (i = 0; doubledash < 0 && i < argc; i++) {\n> diff --git a/unpack-trees.c b/unpack-trees.c\n> index 14e9043f9d..f25089b878 100644\n> --- a/unpack-trees.c\n> +++ b/unpack-trees.c\n> @@ -353,7 +353,7 @@ static int check_updates(struct unpack_trees_options *o)\n>  \tprogress = get_progress(o);\n>  \n>  \tif (o->update)\n> -\t\tgit_attr_set_direction(GIT_ATTR_CHECKOUT, index);\n> +\t\tgit_attr_set_direction(GIT_ATTR_CHECKOUT);\n>  \n>  \tif (should_update_submodules() && o->update && !o->dry_run)\n>  \t\tload_gitmodules_file(index, NULL);\n> @@ -413,7 +413,7 @@ static int check_updates(struct unpack_trees_options *o)\n>  \tstop_progress(&progress);\n>  \terrs |= finish_delayed_checkout(&state);\n>  \tif (o->update)\n> -\t\tgit_attr_set_direction(GIT_ATTR_CHECKIN, NULL);\n> +\t\tgit_attr_set_direction(GIT_ATTR_CHECKIN);\n>  \treturn errs != 0;\n>  }\n>  \n> -- \n> 2.18.0.1004.g6639190530\n> \n\n-- \nBrandon Williams\n"},{"id":"355417","messageId":"20180813172857.GD240194@google.com","threadId":"49115","inReplyTo":"20180813161441.16824-1-pclouds@gmail.com","subject":"Re: [PATCH 00/24] Kill the_index part3","fromName":"Brandon Williams","fromEmail":"bmwill@google.com","sentAt":"2018-08-13T17:28:57Z","receivedAt":"2018-08-13T17:29:02Z","isPatch":true,"sender":{"key":"bwilliams.eng@gmail.com","avatar":null},"body":"On 08/13, Nguyễn Thái Ngọc Duy wrote:\n> This is the third part of killing the_index (at least outside\n> builtin/). Part 1 [1] is dropped. Part 2 is nd/no-extern on 'pu'. This\n> part is built on top of nd/no-extern.\n> \n> This series would actually break 'pu' because builtin/stash.c uses\n> three functions that are updated here. So we would need something like\n> the following patch to make it build again.\n> \n> I don't know if that adds too much work on Junio. If it does, I guess\n> I'll hold this off for a while until builtin/stash.c gets merged\n> because reordering these patches, pushing the patches that break\n> stash.c away, really takes a lot of work.\n> \n> [1] https://public-inbox.org/git/20180616054157.32433-1-pclouds@gmail.com/\n\nI went through and found this to be a pleasant read and hopefully others\nagree with the approach this series took vs what your part 1 did so that\nwe can get this change in.\n\n\n-- \nBrandon Williams\n"},{"id":"355440","messageId":"CACsJy8BCb2fbUwOzifd-01ak3vNFKdBavWcmp4da9A_RR1xCMA@mail.gmail.com","threadId":"49115","inReplyTo":"20180813171718.GB240194@google.com","subject":"Re: [PATCH 05/24] dir.c: remove an implicit dependency on the_index in pathspec code","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2018-08-13T18:40:56Z","receivedAt":"2018-08-13T18:41:24Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Mon, Aug 13, 2018 at 7:17 PM Brandon Williams <bmwill@google.com> wrote:\n> I'm just sorry I made it this messy :/\n\nTake it with pride! I think all core devs can say \"oh yes I've made\nbig contributions. See there? I made that mess!\" :D\n-- \nDuy\n"},{"id":"355482","messageId":"xmqq8t5a3qzr.fsf@gitster-ct.c.googlers.com","threadId":"49115","inReplyTo":"20180813161441.16824-3-pclouds@gmail.com","subject":"Re: [PATCH 02/24] cache-tree: wrap the_index based wrappers with #ifdef","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2018-08-13T21:18:16Z","receivedAt":"2018-08-13T21:18:22Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nguyễn Thái Ngọc Duy  <pclouds@gmail.com> writes:\n\n> This puts update_main_cache_tree() and write_cache_as_tree() in the\n> same group of \"index compat\" functions that assume the_index\n> implicitly, which should only be used within builtin/ or t/helper.\n>\n> sequencer.c is also updated to not use these functions. As of now, no\n> files outside builtin/ use these functions anymore.\n\nMakes sense.\n"},{"id":"355485","messageId":"xmqq4lfy3que.fsf@gitster-ct.c.googlers.com","threadId":"49115","inReplyTo":"20180813161441.16824-5-pclouds@gmail.com","subject":"Re: [PATCH 04/24] convert.c: remove an implicit dependency on the_index","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2018-08-13T21:21:29Z","receivedAt":"2018-08-13T21:21:33Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nguyễn Thái Ngọc Duy  <pclouds@gmail.com> writes:\n\n> Make the convert API take an index_state instead of assuming the_index\n> in convert.c. All external call sites are converted blindly to keep\n> the patch simple and retain current behavior. Individual call sites\n> may receive further updates to use the right index instead of\n> the_index.\n>\n> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n> ---\n\nNice progression from inside to outside, a bit by bit.  Quite a\npleasant read so far ;-)\n"},{"id":"355487","messageId":"xmqqzhxq2c4v.fsf@gitster-ct.c.googlers.com","threadId":"49115","inReplyTo":"20180813172857.GD240194@google.com","subject":"Re: [PATCH 00/24] Kill the_index part3","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2018-08-13T21:24:32Z","receivedAt":"2018-08-13T21:24:37Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Brandon Williams <bmwill@google.com> writes:\n\n> On 08/13, Nguyễn Thái Ngọc Duy wrote:\n>> This is the third part of killing the_index (at least outside\n>> builtin/). Part 1 [1] is dropped. Part 2 is nd/no-extern on 'pu'. This\n>> part is built on top of nd/no-extern.\n>> \n>> This series would actually break 'pu' because builtin/stash.c uses\n>> three functions that are updated here. So we would need something like\n>> the following patch to make it build again.\n>> \n>> I don't know if that adds too much work on Junio. If it does, I guess\n>> I'll hold this off for a while until builtin/stash.c gets merged\n>> because reordering these patches, pushing the patches that break\n>> stash.c away, really takes a lot of work.\n>> \n>> [1] https://public-inbox.org/git/20180616054157.32433-1-pclouds@gmail.com/\n>\n> I went through and found this to be a pleasant read and hopefully others\n> agree with the approach this series took vs what your part 1 did so that\n> we can get this change in.\n\nYeah, I've only finished my first pass (read: I didn't go through\nthe patches with fine toothed comb, nor thought about interactions\nwith other topics), but this round was quite a pleasnt read so far.\n\n\n\n"},{"id":"355742","messageId":"CAGZ79kZTqcCzRLVTWVzjttU7dd98H2vm3WA9AceXypE-XwM4LA@mail.gmail.com","threadId":"49115","inReplyTo":"20180813161441.16824-8-pclouds@gmail.com","subject":"Re: [PATCH 07/24] ls-files: correct index argument to get_convert_attr_ascii()","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2018-08-15T18:56:43Z","receivedAt":"2018-08-15T18:56:57Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"On Mon, Aug 13, 2018 at 9:15 AM Nguyễn Thái Ngọc Duy <pclouds@gmail.com> wrote:\n>\n> write_eolinfo() does take an istate as function argument and it should\n> be used instead of the_index.\n>\n> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n> ---\n>  builtin/ls-files.c | 17 +++++++++--------\n>  1 file changed, 9 insertions(+), 8 deletions(-)\n>\n> diff --git a/builtin/ls-files.c b/builtin/ls-files.c\n> index 7233b92794..7f9919a362 100644\n> --- a/builtin/ls-files.c\n> +++ b/builtin/ls-files.c\n> @@ -63,7 +63,7 @@ static void write_eolinfo(const struct index_state *istate,\n>                 struct stat st;\n>                 const char *i_txt = \"\";\n>                 const char *w_txt = \"\";\n> -               const char *a_txt = get_convert_attr_ascii(&the_index, path);\n> +               const char *a_txt = get_convert_attr_ascii(istate, path);\n\nGoing by the commit message this patch should end here?\n\n> -static void show_dir_entry(const char *tag, struct dir_entry *ent)\n> +static void show_dir_entry(const struct index_state *istate,\n> +                          const char *tag, struct dir_entry *ent)\n[...]\n> -       if (!dir_path_match(&the_index, ent, &pathspec, len, ps_matched))\n> +       if (!dir_path_match(istate, ent, &pathspec, len, ps_matched))\n[...]\n> -       write_eolinfo(NULL, NULL, ent->name);\n> +       write_eolinfo(istate, NULL, ent->name);\n\nbut here we need to pass through the istate, which is why we adjust the\ndir_path_match while we're here\n\n> -               show_dir_entry(tag_other, ent);\n> +               show_dir_entry(istate, tag_other, ent);\n[...]\n> -                       show_dir_entry(tag_killed, dir->entries[i]);\n> +                       show_dir_entry(istate, tag_killed, dir->entries[i]);\n\nand having to adjust more callers here\n\n> @@ -228,7 +229,7 @@ static void show_ce(struct repository *repo, struct dir_struct *dir,\n\n> -       } else if (match_pathspec(&the_index, &pathspec, fullname, strlen(fullname),\n> +       } else if (match_pathspec(repo->index, &pathspec, fullname, strlen(fullname),\n\n> @@ -264,7 +265,7 @@ static void show_ru_info(const struct index_state *istate)\n\n> -               if (!match_pathspec(&the_index, &pathspec, path, len,\n> +               if (!match_pathspec(istate, &pathspec, path, len,\n\nThese seem more or less unrelated to the commit message\nor the code changes above. Maybe mention these as a\n\"while at it\" or separate them out in their own commit?\n\nthanks,\nStefan\n"},{"id":"355744","messageId":"CAGZ79kbs+4_D95+F5km0ODPb1_7tPXMivet35Pq+4vut1ZS9dw@mail.gmail.com","threadId":"49115","inReplyTo":"20180813161441.16824-9-pclouds@gmail.com","subject":"Re: [PATCH 08/24] unpack-trees: remove 'extern' on function declaration","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2018-08-15T19:10:22Z","receivedAt":"2018-08-15T19:10:36Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"On Mon, Aug 13, 2018 at 9:15 AM Nguyễn Thái Ngọc Duy <pclouds@gmail.com> wrote:\n>\n> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n\nThis removes the only existing extern keyword, which was added by\nLinus in  933bf40a5c6 (Start moving unpack-trees to \"struct tree_desc\",\n2007-08-09). All other callers do not have this noise word as it was\nsimply never\npresent there despite the old age of unpack-trees.h. Interesting history.\n\nThanks!\nStefan\n"},{"id":"355746","messageId":"CACsJy8AJh16X5HPf6GqfBn-6JwiDn=3505d0+e38bNOxOTg76Q@mail.gmail.com","threadId":"49115","inReplyTo":"CAGZ79kbs+4_D95+F5km0ODPb1_7tPXMivet35Pq+4vut1ZS9dw@mail.gmail.com","subject":"Re: [PATCH 08/24] unpack-trees: remove 'extern' on function declaration","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2018-08-15T19:21:21Z","receivedAt":"2018-08-15T19:21:49Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Wed, Aug 15, 2018 at 9:10 PM Stefan Beller <sbeller@google.com> wrote:\n>\n> On Mon, Aug 13, 2018 at 9:15 AM Nguyễn Thái Ngọc Duy <pclouds@gmail.com> wrote:\n> >\n> > Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n>\n> This removes the only existing extern keyword, which was added by\n> Linus in  933bf40a5c6 (Start moving unpack-trees to \"struct tree_desc\",\n> 2007-08-09). All other callers do not have this noise word as it was\n> simply never\n> present there despite the old age of unpack-trees.h. Interesting history.\n\nLinus did not add 'extern' though. It was Johannes a year ago in\n16da134b1f (read-trees: refactor the unpack_trees() part -\n2006-07-30). Man this function is _old_.\n-- \nDuy\n"},{"id":"355747","messageId":"CAGZ79ka=G6918mECGWUm5vYs-r-SAKLGuBirahKCTv9waQ2xgw@mail.gmail.com","threadId":"49115","inReplyTo":"CACsJy8AJh16X5HPf6GqfBn-6JwiDn=3505d0+e38bNOxOTg76Q@mail.gmail.com","subject":"Re: [PATCH 08/24] unpack-trees: remove 'extern' on function declaration","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2018-08-15T19:25:05Z","receivedAt":"2018-08-15T19:25:20Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"On Wed, Aug 15, 2018 at 12:21 PM Duy Nguyen <pclouds@gmail.com> wrote:\n>\n> On Wed, Aug 15, 2018 at 9:10 PM Stefan Beller <sbeller@google.com> wrote:\n> >\n> > On Mon, Aug 13, 2018 at 9:15 AM Nguyễn Thái Ngọc Duy <pclouds@gmail.com> wrote:\n> > >\n> > > Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n> >\n> > This removes the only existing extern keyword, which was added by\n> > Linus in  933bf40a5c6 (Start moving unpack-trees to \"struct tree_desc\",\n> > 2007-08-09). All other callers do not have this noise word as it was\n> > simply never\n> > present there despite the old age of unpack-trees.h. Interesting history.\n>\n> Linus did not add 'extern' though. It was Johannes a year ago in\n> 16da134b1f (read-trees: refactor the unpack_trees() part -\n> 2006-07-30). Man this function is _old_.\n\nAh, yes. I stopped at the first blame here but dug down on other functions\nas I expected some of the recent \"remove externs here\" and magically\noverlook this function.\n"},{"id":"355752","messageId":"CAGZ79kYm17PFwd+j+sY_oZHNNrdL335rKgBDBvDiq+qPGXvgEw@mail.gmail.com","threadId":"49115","inReplyTo":"xmqqzhxq2c4v.fsf@gitster-ct.c.googlers.com","subject":"Re: [PATCH 00/24] Kill the_index part3","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2018-08-15T19:48:00Z","receivedAt":"2018-08-15T19:48:14Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"On Mon, Aug 13, 2018 at 2:24 PM Junio C Hamano <gitster@pobox.com> wrote:\n>\n> Brandon Williams <bmwill@google.com> writes:\n>\n> > On 08/13, Nguyễn Thái Ngọc Duy wrote:\n> >> This is the third part of killing the_index (at least outside\n> >> builtin/). Part 1 [1] is dropped. Part 2 is nd/no-extern on 'pu'. This\n> >> part is built on top of nd/no-extern.\n> >>\n> >> This series would actually break 'pu' because builtin/stash.c uses\n> >> three functions that are updated here. So we would need something like\n> >> the following patch to make it build again.\n> >>\n> >> I don't know if that adds too much work on Junio. If it does, I guess\n> >> I'll hold this off for a while until builtin/stash.c gets merged\n> >> because reordering these patches, pushing the patches that break\n> >> stash.c away, really takes a lot of work.\n> >>\n> >> [1] https://public-inbox.org/git/20180616054157.32433-1-pclouds@gmail.com/\n> >\n> > I went through and found this to be a pleasant read and hopefully others\n> > agree with the approach this series took vs what your part 1 did so that\n> > we can get this change in.\n>\n> Yeah, I've only finished my first pass (read: I didn't go through\n> the patches with fine toothed comb, nor thought about interactions\n> with other topics), but this round was quite a pleasnt read so far.\n>\n\nI went through this topic with a finer comb and just found nits,\nnone of which I would deem a complete show stopper.\n"}]}