{"thread":{"id":"54916","subject":"[PATCH 00/12] Remove more index compatibility macros","startedAt":"2021-01-01T13:08:10Z","lastAt":"2021-01-26T20:54:08Z","messageCount":65,"participants":["Derrick Stolee via GitGitGadget","Elijah Newren","Eric Sunshine","Alban Gruin","Derrick Stolee","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":12},"messages":[{"id":"413290","messageId":"pull.830.git.1609506428.gitgitgadget@gmail.com","threadId":"54916","inReplyTo":null,"subject":"[PATCH 00/12] Remove more index compatibility macros","fromName":"Derrick Stolee via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-01-01T13:06:56Z","receivedAt":"2021-01-01T13:08:10Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"I noticed that Duy's project around USE_THE_INDEX_COMPATIBILITY_MACROS has\nbeen on pause for a while. Here is my attempt to continue that project a\nlittle.\n\nI started going through the builtins that still use cache_name_pos() and the\nfirst few were easy: merge-inex, mv, rm.\n\nThen I hit update-index and it was a bit bigger. It's included here as well.\n\nMy strategy for update-index was to create static globals \"repo\" and\n\"istate\" that point to the_repository and the_index, respectively. Then, I\nwas able to remove macros one-by-one without changing method prototypes\nwithin the file.\n\nI had started trying to keep everything local to the method signatures, but\nI hit a snag when reaching the command-line parsing callbacks, which I could\nnot modify their call signature. At that point, I had something that was\nalready much more complicated than what I present now. Outside of the first\nupdate-index commit, everything was a mechanical find/replace.\n\nIn total, this allows us to remove four of the compatibility macros because\nthey are no longer used.\n\nThanks, -Stolee\n\nDerrick Stolee (12):\n  merge-index: drop index compatibility macros\n  mv: remove index compatibility macros\n  rm: remove compatilibity macros\n  update-index: drop the_index, the_repository\n  update-index: use istate->cache over active_cache\n  update-index: use index->cache_nr over active_nr\n  update-index: use istate->cache_changed\n  update-index: use index_name_pos() over cache_name_pos()\n  update-index: use remove_file_from_index()\n  update-index: use add_index_entry()\n  update-index: replace several compatibility macros\n  update-index: remove ce_match_stat(), all macros\n\n Documentation/technical/racy-git.txt |   6 +-\n builtin/merge-index.c                |  33 +++---\n builtin/mv.c                         |  42 ++++----\n builtin/rm.c                         |  56 ++++++-----\n builtin/update-index.c               | 145 ++++++++++++++-------------\n cache.h                              |   4 -\n 6 files changed, 149 insertions(+), 137 deletions(-)\n\n\nbase-commit: 71ca53e8125e36efbda17293c50027d31681a41f\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-830%2Fderrickstolee%2Findex-compatibility-1-v1\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-830/derrickstolee/index-compatibility-1-v1\nPull-Request: https://github.com/gitgitgadget/git/pull/830\n-- \ngitgitgadget\n"},{"id":"413291","messageId":"68d88b651c74659eb171e88d701b89d11e7f5f24.1609506428.git.gitgitgadget@gmail.com","threadId":"54916","inReplyTo":"pull.830.git.1609506428.gitgitgadget@gmail.com","subject":"[PATCH 01/12] merge-index: drop index compatibility macros","fromName":"Derrick Stolee via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-01-01T13:06:57Z","receivedAt":"2021-01-01T13:08:10Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"From: Derrick Stolee <dstolee@microsoft.com>\n\nReplace uses of the old macros for the_index and instead pass around a\n'struct index_state' pointer. This allows dropping the compatibility\nflag.\n\nSigned-off-by: Derrick Stolee <dstolee@microsoft.com>\n---\n builtin/merge-index.c | 33 ++++++++++++++++++---------------\n 1 file changed, 18 insertions(+), 15 deletions(-)\n\ndiff --git a/builtin/merge-index.c b/builtin/merge-index.c\nindex 38ea6ad6ca2..8c7e6b0e6a2 100644\n--- a/builtin/merge-index.c\n+++ b/builtin/merge-index.c\n@@ -1,4 +1,3 @@\n-#define USE_THE_INDEX_COMPATIBILITY_MACROS\n #include \"builtin.h\"\n #include \"run-command.h\"\n \n@@ -6,18 +5,19 @@ static const char *pgm;\n static int one_shot, quiet;\n static int err;\n \n-static int merge_entry(int pos, const char *path)\n+static int merge_entry(struct index_state *istate,\n+\t\t       int pos, const char *path)\n {\n \tint found;\n \tconst char *arguments[] = { pgm, \"\", \"\", \"\", path, \"\", \"\", \"\", NULL };\n \tchar hexbuf[4][GIT_MAX_HEXSZ + 1];\n \tchar ownbuf[4][60];\n \n-\tif (pos >= active_nr)\n+\tif (pos >= istate->cache_nr)\n \t\tdie(\"git merge-index: %s not in the cache\", path);\n \tfound = 0;\n \tdo {\n-\t\tconst struct cache_entry *ce = active_cache[pos];\n+\t\tconst struct cache_entry *ce = istate->cache[pos];\n \t\tint stage = ce_stage(ce);\n \n \t\tif (strcmp(ce->name, path))\n@@ -27,7 +27,7 @@ static int merge_entry(int pos, const char *path)\n \t\txsnprintf(ownbuf[stage], sizeof(ownbuf[stage]), \"%o\", ce->ce_mode);\n \t\targuments[stage] = hexbuf[stage];\n \t\targuments[stage + 4] = ownbuf[stage];\n-\t} while (++pos < active_nr);\n+\t} while (++pos < istate->cache_nr);\n \tif (!found)\n \t\tdie(\"git merge-index: %s not in the cache\", path);\n \n@@ -43,32 +43,34 @@ static int merge_entry(int pos, const char *path)\n \treturn found;\n }\n \n-static void merge_one_path(const char *path)\n+static void merge_one_path(struct index_state *istate,\n+\t\t\t   const char *path)\n {\n-\tint pos = cache_name_pos(path, strlen(path));\n+\tint pos = index_name_pos(istate, path, strlen(path));\n \n \t/*\n \t * If it already exists in the cache as stage0, it's\n \t * already merged and there is nothing to do.\n \t */\n \tif (pos < 0)\n-\t\tmerge_entry(-pos-1, path);\n+\t\tmerge_entry(istate, -pos - 1, path);\n }\n \n-static void merge_all(void)\n+static void merge_all(struct index_state *istate)\n {\n \tint i;\n-\tfor (i = 0; i < active_nr; i++) {\n-\t\tconst struct cache_entry *ce = active_cache[i];\n+\tfor (i = 0; i < istate->cache_nr; i++) {\n+\t\tconst struct cache_entry *ce = istate->cache[i];\n \t\tif (!ce_stage(ce))\n \t\t\tcontinue;\n-\t\ti += merge_entry(i, ce->name)-1;\n+\t\ti += merge_entry(istate, i, ce->name)-1;\n \t}\n }\n \n int cmd_merge_index(int argc, const char **argv, const char *prefix)\n {\n \tint i, force_file = 0;\n+\tstruct index_state *istate;\n \n \t/* Without this we cannot rely on waitpid() to tell\n \t * what happened to our children.\n@@ -78,7 +80,8 @@ int cmd_merge_index(int argc, const char **argv, const char *prefix)\n \tif (argc < 3)\n \t\tusage(\"git merge-index [-o] [-q] <merge-program> (-a | [--] [<filename>...])\");\n \n-\tread_cache();\n+\trepo_read_index(the_repository);\n+\tistate = the_repository->index;\n \n \ti = 1;\n \tif (!strcmp(argv[i], \"-o\")) {\n@@ -98,12 +101,12 @@ int cmd_merge_index(int argc, const char **argv, const char *prefix)\n \t\t\t\tcontinue;\n \t\t\t}\n \t\t\tif (!strcmp(arg, \"-a\")) {\n-\t\t\t\tmerge_all();\n+\t\t\t\tmerge_all(istate);\n \t\t\t\tcontinue;\n \t\t\t}\n \t\t\tdie(\"git merge-index: unknown option %s\", arg);\n \t\t}\n-\t\tmerge_one_path(arg);\n+\t\tmerge_one_path(istate, arg);\n \t}\n \tif (err && !quiet)\n \t\tdie(\"merge program failed\");\n-- \ngitgitgadget\n\n"},{"id":"413294","messageId":"84330533d4f4e203cd5d8a61495adaafd3881a4a.1609506428.git.gitgitgadget@gmail.com","threadId":"54916","inReplyTo":"pull.830.git.1609506428.gitgitgadget@gmail.com","subject":"[PATCH 02/12] mv: remove index compatibility macros","fromName":"Derrick Stolee via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-01-01T13:06:58Z","receivedAt":"2021-01-01T13:08:10Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"From: Derrick Stolee <dstolee@microsoft.com>\n\nThe mv builtin uses the compatibility macros to interact with the index.\nUpdate these to use modern methods referring to a 'struct index_state'\npointer. Several helper methods need to be updated to consider such a\npointer, but the modifications are rudimentary.\n\nTwo macros can be deleted from cache.h because these are the last uses.\n\nSigned-off-by: Derrick Stolee <dstolee@microsoft.com>\n---\n builtin/mv.c | 42 +++++++++++++++++++++++-------------------\n cache.h      |  2 --\n 2 files changed, 23 insertions(+), 21 deletions(-)\n\ndiff --git a/builtin/mv.c b/builtin/mv.c\nindex 7dac714af90..0055d49a8a7 100644\n--- a/builtin/mv.c\n+++ b/builtin/mv.c\n@@ -3,7 +3,6 @@\n  *\n  * Copyright (C) 2006 Johannes Schindelin\n  */\n-#define USE_THE_INDEX_COMPATIBILITY_MACROS\n #include \"builtin.h\"\n #include \"config.h\"\n #include \"pathspec.h\"\n@@ -75,13 +74,14 @@ static const char *add_slash(const char *path)\n \n #define SUBMODULE_WITH_GITDIR ((const char *)1)\n \n-static void prepare_move_submodule(const char *src, int first,\n+static void prepare_move_submodule(struct index_state *istate,\n+\t\t\t\t   const char *src, int first,\n \t\t\t\t   const char **submodule_gitfile)\n {\n \tstruct strbuf submodule_dotgit = STRBUF_INIT;\n-\tif (!S_ISGITLINK(active_cache[first]->ce_mode))\n+\tif (!S_ISGITLINK(istate->cache[first]->ce_mode))\n \t\tdie(_(\"Directory %s is in index and no submodule?\"), src);\n-\tif (!is_staging_gitmodules_ok(&the_index))\n+\tif (!is_staging_gitmodules_ok(istate))\n \t\tdie(_(\"Please stage your changes to .gitmodules or stash them to proceed\"));\n \tstrbuf_addf(&submodule_dotgit, \"%s/.git\", src);\n \t*submodule_gitfile = read_gitfile(submodule_dotgit.buf);\n@@ -92,19 +92,20 @@ static void prepare_move_submodule(const char *src, int first,\n \tstrbuf_release(&submodule_dotgit);\n }\n \n-static int index_range_of_same_dir(const char *src, int length,\n+static int index_range_of_same_dir(struct index_state *istate,\n+\t\t\t\t   const char *src, int length,\n \t\t\t\t   int *first_p, int *last_p)\n {\n \tconst char *src_w_slash = add_slash(src);\n \tint first, last, len_w_slash = length + 1;\n \n-\tfirst = cache_name_pos(src_w_slash, len_w_slash);\n+\tfirst = index_name_pos(istate, src_w_slash, len_w_slash);\n \tif (first >= 0)\n \t\tdie(_(\"%.*s is in index\"), len_w_slash, src_w_slash);\n \n \tfirst = -1 - first;\n-\tfor (last = first; last < active_nr; last++) {\n-\t\tconst char *path = active_cache[last]->name;\n+\tfor (last = first; last < istate->cache_nr; last++) {\n+\t\tconst char *path = istate->cache[last]->name;\n \t\tif (strncmp(path, src_w_slash, len_w_slash))\n \t\t\tbreak;\n \t}\n@@ -133,6 +134,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix)\n \tstruct string_list src_for_dst = STRING_LIST_INIT_NODUP;\n \tstruct lock_file lock_file = LOCK_INIT;\n \tstruct cache_entry *ce;\n+\tstruct index_state *istate;\n \n \tgit_config(git_default_config, NULL);\n \n@@ -141,9 +143,10 @@ int cmd_mv(int argc, const char **argv, const char *prefix)\n \tif (--argc < 1)\n \t\tusage_with_options(builtin_mv_usage, builtin_mv_options);\n \n-\thold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);\n-\tif (read_cache() < 0)\n+\trepo_hold_locked_index(the_repository, &lock_file, LOCK_DIE_ON_ERROR);\n+\tif (repo_read_index(the_repository) < 0)\n \t\tdie(_(\"index file corrupt\"));\n+\tistate = the_repository->index;\n \n \tsource = internal_prefix_pathspec(prefix, argv, argc, 0);\n \tmodes = xcalloc(argc, sizeof(enum update_mode));\n@@ -190,12 +193,13 @@ int cmd_mv(int argc, const char **argv, const char *prefix)\n \t\t\t\t&& lstat(dst, &st) == 0)\n \t\t\tbad = _(\"cannot move directory over file\");\n \t\telse if (src_is_dir) {\n-\t\t\tint first = cache_name_pos(src, length), last;\n+\t\t\tint first = index_name_pos(istate, src, length);\n+\t\t\tint last;\n \n \t\t\tif (first >= 0)\n-\t\t\t\tprepare_move_submodule(src, first,\n+\t\t\t\tprepare_move_submodule(istate, src, first,\n \t\t\t\t\t\t       submodule_gitfile + i);\n-\t\t\telse if (index_range_of_same_dir(src, length,\n+\t\t\telse if (index_range_of_same_dir(istate, src, length,\n \t\t\t\t\t\t\t &first, &last) < 1)\n \t\t\t\tbad = _(\"source directory is empty\");\n \t\t\telse { /* last - first >= 1 */\n@@ -212,7 +216,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix)\n \t\t\t\tdst_len = strlen(dst);\n \n \t\t\t\tfor (j = 0; j < last - first; j++) {\n-\t\t\t\t\tconst char *path = active_cache[first + j]->name;\n+\t\t\t\t\tconst char *path = istate->cache[first + j]->name;\n \t\t\t\t\tsource[argc + j] = path;\n \t\t\t\t\tdestination[argc + j] =\n \t\t\t\t\t\tprefix_path(dst, dst_len, path + length + 1);\n@@ -221,7 +225,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix)\n \t\t\t\t}\n \t\t\t\targc += last - first;\n \t\t\t}\n-\t\t} else if (!(ce = cache_file_exists(src, length, ignore_case))) {\n+\t\t} else if (!(ce = index_file_exists(istate, src, length, ignore_case))) {\n \t\t\tbad = _(\"not under version control\");\n \t\t} else if (ce_stage(ce)) {\n \t\t\tbad = _(\"conflicted\");\n@@ -291,15 +295,15 @@ int cmd_mv(int argc, const char **argv, const char *prefix)\n \t\tif (mode == WORKING_DIRECTORY)\n \t\t\tcontinue;\n \n-\t\tpos = cache_name_pos(src, strlen(src));\n+\t\tpos = index_name_pos(istate, src, strlen(src));\n \t\tassert(pos >= 0);\n-\t\trename_cache_entry_at(pos, dst);\n+\t\trename_index_entry_at(istate, pos, dst);\n \t}\n \n \tif (gitmodules_modified)\n-\t\tstage_updated_gitmodules(&the_index);\n+\t\tstage_updated_gitmodules(istate);\n \n-\tif (write_locked_index(&the_index, &lock_file,\n+\tif (write_locked_index(istate, &lock_file,\n \t\t\t       COMMIT_LOCK | SKIP_IF_UNCHANGED))\n \t\tdie(_(\"Unable to write new index file\"));\n \ndiff --git a/cache.h b/cache.h\nindex 71097657489..7bfb8195d97 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -409,7 +409,6 @@ extern struct index_state the_index;\n #define unmerged_cache() unmerged_index(&the_index)\n #define cache_name_pos(name, namelen) index_name_pos(&the_index,(name),(namelen))\n #define add_cache_entry(ce, option) add_index_entry(&the_index, (ce), (option))\n-#define rename_cache_entry_at(pos, new_name) rename_index_entry_at(&the_index, (pos), (new_name))\n #define remove_cache_entry_at(pos) remove_index_entry_at(&the_index, (pos))\n #define remove_file_from_cache(path) remove_file_from_index(&the_index, (path))\n #define add_to_cache(path, st, flags) add_to_index(&the_index, (path), (st), (flags))\n@@ -420,7 +419,6 @@ extern struct index_state the_index;\n #define ce_match_stat(ce, st, options) ie_match_stat(&the_index, (ce), (st), (options))\n #define ce_modified(ce, st, options) ie_modified(&the_index, (ce), (st), (options))\n #define cache_dir_exists(name, namelen) index_dir_exists(&the_index, (name), (namelen))\n-#define cache_file_exists(name, namelen, igncase) index_file_exists(&the_index, (name), (namelen), (igncase))\n #define cache_name_is_other(name, namelen) index_name_is_other(&the_index, (name), (namelen))\n #define resolve_undo_clear() resolve_undo_clear_index(&the_index)\n #define unmerge_cache_entry_at(at) unmerge_index_entry_at(&the_index, at)\n-- \ngitgitgadget\n\n"},{"id":"413292","messageId":"54e167d587260f79d3ce532e26de27ca5a440fd1.1609506428.git.gitgitgadget@gmail.com","threadId":"54916","inReplyTo":"pull.830.git.1609506428.gitgitgadget@gmail.com","subject":"[PATCH 03/12] rm: remove compatilibity macros","fromName":"Derrick Stolee via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-01-01T13:06:59Z","receivedAt":"2021-01-01T13:08:11Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"From: Derrick Stolee <dstolee@microsoft.com>\n\nThe rm builtin still uses the antiquated compatibility macros for\ninteracting with the index. Update these to the more modern uses by\npassing around a 'struct index_state' pointer.\n\nSigned-off-by: Derrick Stolee <dstolee@microsoft.com>\n---\n builtin/rm.c | 56 ++++++++++++++++++++++++++++------------------------\n 1 file changed, 30 insertions(+), 26 deletions(-)\n\ndiff --git a/builtin/rm.c b/builtin/rm.c\nindex 4858631e0f0..767df8d6b25 100644\n--- a/builtin/rm.c\n+++ b/builtin/rm.c\n@@ -3,7 +3,6 @@\n  *\n  * Copyright (C) Linus Torvalds 2006\n  */\n-#define USE_THE_INDEX_COMPATIBILITY_MACROS\n #include \"builtin.h\"\n #include \"config.h\"\n #include \"lockfile.h\"\n@@ -28,12 +27,14 @@ static struct {\n \t} *entry;\n } list;\n \n-static int get_ours_cache_pos(const char *path, int pos)\n+static int get_ours_cache_pos(struct index_state *istate,\n+\t\t\t      const char *path, int pos)\n {\n \tint i = -pos - 1;\n \n-\twhile ((i < active_nr) && !strcmp(active_cache[i]->name, path)) {\n-\t\tif (ce_stage(active_cache[i]) == 2)\n+\twhile ((i < istate->cache_nr) &&\n+\t       !strcmp(istate->cache[i]->name, path)) {\n+\t\tif (ce_stage(istate->cache[i]) == 2)\n \t\t\treturn i;\n \t\ti++;\n \t}\n@@ -61,7 +62,7 @@ static void print_error_files(struct string_list *files_list,\n \t}\n }\n \n-static void submodules_absorb_gitdir_if_needed(void)\n+static void submodules_absorb_gitdir_if_needed(struct index_state *istate)\n {\n \tint i;\n \tfor (i = 0; i < list.nr; i++) {\n@@ -69,13 +70,13 @@ static void submodules_absorb_gitdir_if_needed(void)\n \t\tint pos;\n \t\tconst struct cache_entry *ce;\n \n-\t\tpos = cache_name_pos(name, strlen(name));\n+\t\tpos = index_name_pos(istate, name, strlen(name));\n \t\tif (pos < 0) {\n-\t\t\tpos = get_ours_cache_pos(name, pos);\n+\t\t\tpos = get_ours_cache_pos(istate, name, pos);\n \t\t\tif (pos < 0)\n \t\t\t\tcontinue;\n \t\t}\n-\t\tce = active_cache[pos];\n+\t\tce = istate->cache[pos];\n \n \t\tif (!S_ISGITLINK(ce->ce_mode) ||\n \t\t    !file_exists(ce->name) ||\n@@ -88,7 +89,8 @@ static void submodules_absorb_gitdir_if_needed(void)\n \t}\n }\n \n-static int check_local_mod(struct object_id *head, int index_only)\n+static int check_local_mod(struct index_state *istate,\n+\t\t\t   struct object_id *head, int index_only)\n {\n \t/*\n \t * Items in list are already sorted in the cache order,\n@@ -114,21 +116,21 @@ static int check_local_mod(struct object_id *head, int index_only)\n \t\tint local_changes = 0;\n \t\tint staged_changes = 0;\n \n-\t\tpos = cache_name_pos(name, strlen(name));\n+\t\tpos = index_name_pos(istate, name, strlen(name));\n \t\tif (pos < 0) {\n \t\t\t/*\n \t\t\t * Skip unmerged entries except for populated submodules\n \t\t\t * that could lose history when removed.\n \t\t\t */\n-\t\t\tpos = get_ours_cache_pos(name, pos);\n+\t\t\tpos = get_ours_cache_pos(istate, name, pos);\n \t\t\tif (pos < 0)\n \t\t\t\tcontinue;\n \n-\t\t\tif (!S_ISGITLINK(active_cache[pos]->ce_mode) ||\n+\t\t\tif (!S_ISGITLINK(istate->cache[pos]->ce_mode) ||\n \t\t\t    is_empty_dir(name))\n \t\t\t\tcontinue;\n \t\t}\n-\t\tce = active_cache[pos];\n+\t\tce = istate->cache[pos];\n \n \t\tif (lstat(ce->name, &st) < 0) {\n \t\t\tif (!is_missing_file_error(errno))\n@@ -165,7 +167,7 @@ static int check_local_mod(struct object_id *head, int index_only)\n \t\t * Is the index different from the file in the work tree?\n \t\t * If it's a submodule, is its work tree modified?\n \t\t */\n-\t\tif (ce_match_stat(ce, &st, 0) ||\n+\t\tif (ie_match_stat(istate, ce, &st, 0) ||\n \t\t    (S_ISGITLINK(ce->ce_mode) &&\n \t\t     bad_to_remove_submodule(ce->name,\n \t\t\t\tSUBMODULE_REMOVAL_DIE_ON_ERROR |\n@@ -257,6 +259,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix)\n \tint i;\n \tstruct pathspec pathspec;\n \tchar *seen;\n+\tstruct index_state *istate;\n \n \tgit_config(git_default_config, NULL);\n \n@@ -284,24 +287,25 @@ int cmd_rm(int argc, const char **argv, const char *prefix)\n \tif (!index_only)\n \t\tsetup_work_tree();\n \n-\thold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);\n+\trepo_hold_locked_index(the_repository, &lock_file, LOCK_DIE_ON_ERROR);\n \n-\tif (read_cache() < 0)\n+\tif (repo_read_index(the_repository) < 0)\n \t\tdie(_(\"index file corrupt\"));\n \n-\trefresh_index(&the_index, REFRESH_QUIET|REFRESH_UNMERGED, &pathspec, NULL, NULL);\n+\tistate = the_repository->index;\n+\trefresh_index(istate, REFRESH_QUIET|REFRESH_UNMERGED, &pathspec, NULL, NULL);\n \n \tseen = xcalloc(pathspec.nr, 1);\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(&the_index, ce, &pathspec, seen))\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(istate, 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);\n \t\tlist.entry[list.nr].is_submodule = S_ISGITLINK(ce->ce_mode);\n \t\tif (list.entry[list.nr++].is_submodule &&\n-\t\t    !is_staging_gitmodules_ok(&the_index))\n+\t\t    !is_staging_gitmodules_ok(istate))\n \t\t\tdie(_(\"please stage your changes to .gitmodules or stash them to proceed\"));\n \t}\n \n@@ -329,7 +333,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix)\n \t}\n \n \tif (!index_only)\n-\t\tsubmodules_absorb_gitdir_if_needed();\n+\t\tsubmodules_absorb_gitdir_if_needed(istate);\n \n \t/*\n \t * If not forced, the file, the index and the HEAD (if exists)\n@@ -345,7 +349,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix)\n \t\tstruct object_id oid;\n \t\tif (get_oid(\"HEAD\", &oid))\n \t\t\toidclr(&oid);\n-\t\tif (check_local_mod(&oid, index_only))\n+\t\tif (check_local_mod(istate, &oid, index_only))\n \t\t\texit(1);\n \t}\n \n@@ -358,7 +362,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix)\n \t\tif (!quiet)\n \t\t\tprintf(\"rm '%s'\\n\", path);\n \n-\t\tif (remove_file_from_cache(path))\n+\t\tif (remove_file_from_index(istate, path))\n \t\t\tdie(_(\"git rm: unable to remove %s\"), path);\n \t}\n \n@@ -398,10 +402,10 @@ int cmd_rm(int argc, const char **argv, const char *prefix)\n \t\t}\n \t\tstrbuf_release(&buf);\n \t\tif (gitmodules_modified)\n-\t\t\tstage_updated_gitmodules(&the_index);\n+\t\t\tstage_updated_gitmodules(istate);\n \t}\n \n-\tif (write_locked_index(&the_index, &lock_file,\n+\tif (write_locked_index(istate, &lock_file,\n \t\t\t       COMMIT_LOCK | SKIP_IF_UNCHANGED))\n \t\tdie(_(\"Unable to write new index file\"));\n \n-- \ngitgitgadget\n\n"},{"id":"413293","messageId":"77f6510bb680aaf119526f75daadf8c40d22793e.1609506428.git.gitgitgadget@gmail.com","threadId":"54916","inReplyTo":"pull.830.git.1609506428.gitgitgadget@gmail.com","subject":"[PATCH 04/12] update-index: drop the_index, the_repository","fromName":"Derrick Stolee via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-01-01T13:07:00Z","receivedAt":"2021-01-01T13:08:11Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"From: Derrick Stolee <dstolee@microsoft.com>\n\nTo reduce the need for the index compatibility macros, we will replace\ntheir uses in update-index mechanically. This is the most interesting\nchange, which creates global \"repo\" and \"istate\" pointers. The macros\ncan then be mechanically replaced by instances that use the istate\npointer instead of the version that autocompletes to use the_index.\n\nSigned-off-by: Derrick Stolee <dstolee@microsoft.com>\n---\n builtin/update-index.c | 59 +++++++++++++++++++++++-------------------\n 1 file changed, 32 insertions(+), 27 deletions(-)\n\ndiff --git a/builtin/update-index.c b/builtin/update-index.c\nindex 79087bccea4..c9a6cde97da 100644\n--- a/builtin/update-index.c\n+++ b/builtin/update-index.c\n@@ -40,6 +40,9 @@ static int ignore_skip_worktree_entries;\n #define UNMARK_FLAG 2\n static struct strbuf mtime_dir = STRBUF_INIT;\n \n+static struct repository *repo;\n+static struct index_state *istate;\n+\n /* Untracked cache mode */\n enum uc_mode {\n \tUC_UNSPECIFIED = -1,\n@@ -232,13 +235,13 @@ static int mark_ce_flags(const char *path, int flag, int mark)\n \tint namelen = strlen(path);\n \tint pos = cache_name_pos(path, namelen);\n \tif (0 <= pos) {\n-\t\tmark_fsmonitor_invalid(&the_index, active_cache[pos]);\n+\t\tmark_fsmonitor_invalid(istate, active_cache[pos]);\n \t\tif (mark)\n \t\t\tactive_cache[pos]->ce_flags |= flag;\n \t\telse\n \t\t\tactive_cache[pos]->ce_flags &= ~flag;\n \t\tactive_cache[pos]->ce_flags |= CE_UPDATE_IN_BASE;\n-\t\tcache_tree_invalidate_path(&the_index, path);\n+\t\tcache_tree_invalidate_path(istate, path);\n \t\tactive_cache_changed |= CE_ENTRY_CHANGED;\n \t\treturn 0;\n \t}\n@@ -277,14 +280,14 @@ static int add_one_path(const struct cache_entry *old, const char *path, int len\n \tif (old && !ce_stage(old) && !ce_match_stat(old, st, 0))\n \t\treturn 0;\n \n-\tce = make_empty_cache_entry(&the_index, len);\n+\tce = make_empty_cache_entry(istate, len);\n \tmemcpy(ce->name, path, len);\n \tce->ce_flags = create_ce_flags(0);\n \tce->ce_namelen = len;\n-\tfill_stat_cache_info(&the_index, ce, st);\n+\tfill_stat_cache_info(istate, ce, st);\n \tce->ce_mode = ce_mode_from_stat(old, st->st_mode);\n \n-\tif (index_path(&the_index, &ce->oid, path, st,\n+\tif (index_path(istate, &ce->oid, path, st,\n \t\t       info_only ? 0 : HASH_WRITE_OBJECT)) {\n \t\tdiscard_cache_entry(ce);\n \t\treturn -1;\n@@ -411,7 +414,7 @@ static int add_cacheinfo(unsigned int mode, const struct object_id *oid,\n \t\treturn error(\"Invalid path '%s'\", path);\n \n \tlen = strlen(path);\n-\tce = make_empty_cache_entry(&the_index, len);\n+\tce = make_empty_cache_entry(istate, len);\n \n \toidcpy(&ce->oid, oid);\n \tmemcpy(ce->name, path, len);\n@@ -603,7 +606,7 @@ static struct cache_entry *read_one_ent(const char *which,\n \tstruct object_id oid;\n \tstruct cache_entry *ce;\n \n-\tif (get_tree_entry(the_repository, ent, path, &oid, &mode)) {\n+\tif (get_tree_entry(repo, ent, path, &oid, &mode)) {\n \t\tif (which)\n \t\t\terror(\"%s: not in %s branch.\", path, which);\n \t\treturn NULL;\n@@ -613,7 +616,7 @@ static struct cache_entry *read_one_ent(const char *which,\n \t\t\terror(\"%s: not a blob in %s branch.\", path, which);\n \t\treturn NULL;\n \t}\n-\tce = make_empty_cache_entry(&the_index, namelen);\n+\tce = make_empty_cache_entry(istate, namelen);\n \n \toidcpy(&ce->oid, &oid);\n \tmemcpy(ce->name, path, namelen);\n@@ -751,7 +754,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(&the_index, ce, &pathspec, NULL))\n+\t\tif (ce_stage(ce) || !ce_path_match(istate, ce, &pathspec, NULL))\n \t\t\tcontinue;\n \t\tif (has_head)\n \t\t\told = read_one_ent(NULL, &head_oid,\n@@ -968,7 +971,6 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \tstruct parse_opt_ctx_t ctx;\n \tstrbuf_getline_fn getline_fn;\n \tint parseopt_state = PARSE_OPT_UNKNOWN;\n-\tstruct repository *r = the_repository;\n \tstruct option options[] = {\n \t\tOPT_BIT('q', NULL, &refresh_args.flags,\n \t\t\tN_(\"continue refresh even when index needs update\"),\n@@ -1077,16 +1079,19 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \n \tgit_config(git_default_config, NULL);\n \n+\trepo = the_repository;\n+\n \t/* we will diagnose later if it turns out that we need to update it */\n-\tnewfd = hold_locked_index(&lock_file, 0);\n+\tnewfd = repo_hold_locked_index(repo, &lock_file, 0);\n \tif (newfd < 0)\n \t\tlock_error = errno;\n \n-\tentries = read_cache();\n+\tentries = repo_read_index(repo);\n \tif (entries < 0)\n \t\tdie(\"cache corrupted\");\n \n-\tthe_index.updated_skipworktree = 1;\n+\tistate = repo->index;\n+\tistate->updated_skipworktree = 1;\n \n \t/*\n \t * Custom copy of parse_options() because we want to handle\n@@ -1140,9 +1145,9 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \t\t\t    preferred_index_format,\n \t\t\t    INDEX_FORMAT_LB, INDEX_FORMAT_UB);\n \n-\t\tif (the_index.version != preferred_index_format)\n+\t\tif (istate->version != preferred_index_format)\n \t\t\tactive_cache_changed |= SOMETHING_CHANGED;\n-\t\tthe_index.version = preferred_index_format;\n+\t\tistate->version = preferred_index_format;\n \t}\n \n \tif (read_from_stdin) {\n@@ -1173,28 +1178,28 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \t\t\twarning(_(\"core.splitIndex is set to false; \"\n \t\t\t\t  \"remove or change it, if you really want to \"\n \t\t\t\t  \"enable split index\"));\n-\t\tif (the_index.split_index)\n-\t\t\tthe_index.cache_changed |= SPLIT_INDEX_ORDERED;\n+\t\tif (istate->split_index)\n+\t\t\tistate->cache_changed |= SPLIT_INDEX_ORDERED;\n \t\telse\n-\t\t\tadd_split_index(&the_index);\n+\t\t\tadd_split_index(istate);\n \t} else if (!split_index) {\n \t\tif (git_config_get_split_index() == 1)\n \t\t\twarning(_(\"core.splitIndex is set to true; \"\n \t\t\t\t  \"remove or change it, if you really want to \"\n \t\t\t\t  \"disable split index\"));\n-\t\tremove_split_index(&the_index);\n+\t\tremove_split_index(istate);\n \t}\n \n-\tprepare_repo_settings(r);\n+\tprepare_repo_settings(repo);\n \tswitch (untracked_cache) {\n \tcase UC_UNSPECIFIED:\n \t\tbreak;\n \tcase UC_DISABLE:\n-\t\tif (r->settings.core_untracked_cache == UNTRACKED_CACHE_WRITE)\n+\t\tif (repo->settings.core_untracked_cache == UNTRACKED_CACHE_WRITE)\n \t\t\twarning(_(\"core.untrackedCache is set to true; \"\n \t\t\t\t  \"remove or change it, if you really want to \"\n \t\t\t\t  \"disable the untracked cache\"));\n-\t\tremove_untracked_cache(&the_index);\n+\t\tremove_untracked_cache(istate);\n \t\treport(_(\"Untracked cache disabled\"));\n \t\tbreak;\n \tcase UC_TEST:\n@@ -1202,11 +1207,11 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \t\treturn !test_if_untracked_cache_is_supported();\n \tcase UC_ENABLE:\n \tcase UC_FORCE:\n-\t\tif (r->settings.core_untracked_cache == UNTRACKED_CACHE_REMOVE)\n+\t\tif (repo->settings.core_untracked_cache == UNTRACKED_CACHE_REMOVE)\n \t\t\twarning(_(\"core.untrackedCache is set to false; \"\n \t\t\t\t  \"remove or change it, if you really want to \"\n \t\t\t\t  \"enable the untracked cache\"));\n-\t\tadd_untracked_cache(&the_index);\n+\t\tadd_untracked_cache(istate);\n \t\treport(_(\"Untracked cache enabled for '%s'\"), get_git_work_tree());\n \t\tbreak;\n \tdefault:\n@@ -1218,14 +1223,14 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \t\t\twarning(_(\"core.fsmonitor is unset; \"\n \t\t\t\t\"set it if you really want to \"\n \t\t\t\t\"enable fsmonitor\"));\n-\t\tadd_fsmonitor(&the_index);\n+\t\tadd_fsmonitor(istate);\n \t\treport(_(\"fsmonitor enabled\"));\n \t} else if (!fsmonitor) {\n \t\tif (git_config_get_fsmonitor() == 1)\n \t\t\twarning(_(\"core.fsmonitor is set; \"\n \t\t\t\t\"remove it if you really want to \"\n \t\t\t\t\"disable fsmonitor\"));\n-\t\tremove_fsmonitor(&the_index);\n+\t\tremove_fsmonitor(istate);\n \t\treport(_(\"fsmonitor disabled\"));\n \t}\n \n@@ -1235,7 +1240,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \t\t\t\texit(128);\n \t\t\tunable_to_lock_die(get_index_file(), lock_error);\n \t\t}\n-\t\tif (write_locked_index(&the_index, &lock_file, COMMIT_LOCK))\n+\t\tif (write_locked_index(istate, &lock_file, COMMIT_LOCK))\n \t\t\tdie(\"Unable to write new index file\");\n \t}\n \n-- \ngitgitgadget\n\n"},{"id":"413295","messageId":"f841500c66310179d47478bb928eb35a4427fe5f.1609506428.git.gitgitgadget@gmail.com","threadId":"54916","inReplyTo":"pull.830.git.1609506428.gitgitgadget@gmail.com","subject":"[PATCH 07/12] update-index: use istate->cache_changed","fromName":"Derrick Stolee via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-01-01T13:07:03Z","receivedAt":"2021-01-01T13:08:51Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"From: Derrick Stolee <dstolee@microsoft.com>\n\nThis is a mechanical replacement of active_cache_changed.\n\nSigned-off-by: Derrick Stolee <dstolee@microsoft.com>\n---\n builtin/update-index.c | 10 +++++-----\n 1 file changed, 5 insertions(+), 5 deletions(-)\n\ndiff --git a/builtin/update-index.c b/builtin/update-index.c\nindex f1657a66496..a64f2f5a8f4 100644\n--- a/builtin/update-index.c\n+++ b/builtin/update-index.c\n@@ -242,7 +242,7 @@ static int mark_ce_flags(const char *path, int flag, int mark)\n \t\t\tistate->cache[pos]->ce_flags &= ~flag;\n \t\tistate->cache[pos]->ce_flags |= CE_UPDATE_IN_BASE;\n \t\tcache_tree_invalidate_path(istate, path);\n-\t\tactive_cache_changed |= CE_ENTRY_CHANGED;\n+\t\tistate->cache_changed |= CE_ENTRY_CHANGED;\n \t\treturn 0;\n \t}\n \treturn -1;\n@@ -926,7 +926,7 @@ static enum parse_opt_result unresolve_callback(\n \t*has_errors = do_unresolve(ctx->argc, ctx->argv,\n \t\t\t\tprefix, prefix ? strlen(prefix) : 0);\n \tif (*has_errors)\n-\t\tactive_cache_changed = 0;\n+\t\tistate->cache_changed = 0;\n \n \tctx->argv += ctx->argc - 1;\n \tctx->argc = 1;\n@@ -947,7 +947,7 @@ static enum parse_opt_result reupdate_callback(\n \tsetup_work_tree();\n \t*has_errors = do_reupdate(ctx->argc, ctx->argv, prefix);\n \tif (*has_errors)\n-\t\tactive_cache_changed = 0;\n+\t\tistate->cache_changed = 0;\n \n \tctx->argv += ctx->argc - 1;\n \tctx->argc = 1;\n@@ -1146,7 +1146,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \t\t\t    INDEX_FORMAT_LB, INDEX_FORMAT_UB);\n \n \t\tif (istate->version != preferred_index_format)\n-\t\t\tactive_cache_changed |= SOMETHING_CHANGED;\n+\t\t\tistate->cache_changed |= SOMETHING_CHANGED;\n \t\tistate->version = preferred_index_format;\n \t}\n \n@@ -1234,7 +1234,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \t\treport(_(\"fsmonitor disabled\"));\n \t}\n \n-\tif (active_cache_changed || force_write) {\n+\tif (istate->cache_changed || force_write) {\n \t\tif (newfd < 0) {\n \t\t\tif (refresh_args.flags & REFRESH_QUIET)\n \t\t\t\texit(128);\n-- \ngitgitgadget\n\n"},{"id":"413296","messageId":"e99b8bddb3ab30e3db3e1738cf9ef23787394512.1609506428.git.gitgitgadget@gmail.com","threadId":"54916","inReplyTo":"pull.830.git.1609506428.gitgitgadget@gmail.com","subject":"[PATCH 06/12] update-index: use index->cache_nr over active_nr","fromName":"Derrick Stolee via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-01-01T13:07:02Z","receivedAt":"2021-01-01T13:08:51Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"From: Derrick Stolee <dstolee@microsoft.com>\n\nSigned-off-by: Derrick Stolee <dstolee@microsoft.com>\n---\n builtin/update-index.c | 14 +++++++-------\n 1 file changed, 7 insertions(+), 7 deletions(-)\n\ndiff --git a/builtin/update-index.c b/builtin/update-index.c\nindex 0616c786410..f1657a66496 100644\n--- a/builtin/update-index.c\n+++ b/builtin/update-index.c\n@@ -346,7 +346,7 @@ static int process_directory(const char *path, int len, struct stat *st)\n \n \t/* Inexact match: is there perhaps a subdirectory match? */\n \tpos = -pos-1;\n-\twhile (pos < active_nr) {\n+\twhile (pos < istate->cache_nr) {\n \t\tconst struct cache_entry *ce = istate->cache[pos++];\n \n \t\tif (strncmp(ce->name, path, len))\n@@ -638,7 +638,7 @@ static int unresolve_one(const char *path)\n \tif (0 <= pos) {\n \t\t/* already merged */\n \t\tpos = unmerge_cache_entry_at(pos);\n-\t\tif (pos < active_nr) {\n+\t\tif (pos < istate->cache_nr) {\n \t\t\tconst struct cache_entry *ce = istate->cache[pos];\n \t\t\tif (ce_stage(ce) &&\n \t\t\t    ce_namelen(ce) == namelen &&\n@@ -652,7 +652,7 @@ static int unresolve_one(const char *path)\n \t\t * want to do anything in the former case.\n \t\t */\n \t\tpos = -pos-1;\n-\t\tif (pos < active_nr) {\n+\t\tif (pos < istate->cache_nr) {\n \t\t\tconst struct cache_entry *ce = istate->cache[pos];\n \t\t\tif (ce_namelen(ce) == namelen &&\n \t\t\t    !memcmp(ce->name, path, namelen)) {\n@@ -748,7 +748,7 @@ static int do_reupdate(int ac, const char **av,\n \t\t */\n \t\thas_head = 0;\n  redo:\n-\tfor (pos = 0; pos < active_nr; pos++) {\n+\tfor (pos = 0; pos < istate->cache_nr; pos++) {\n \t\tconst struct cache_entry *ce = istate->cache[pos];\n \t\tstruct cache_entry *old = NULL;\n \t\tint save_nr;\n@@ -766,14 +766,14 @@ static int do_reupdate(int ac, const char **av,\n \t\t}\n \t\t/* Be careful.  The working tree may not have the\n \t\t * path anymore, in which case, under 'allow_remove',\n-\t\t * or worse yet 'allow_replace', active_nr may decrease.\n+\t\t * or worse yet 'allow_replace', istate->cache_nr may decrease.\n \t\t */\n-\t\tsave_nr = active_nr;\n+\t\tsave_nr = istate->cache_nr;\n \t\tpath = xstrdup(ce->name);\n \t\tupdate_one(path);\n \t\tfree(path);\n \t\tdiscard_cache_entry(old);\n-\t\tif (save_nr != active_nr)\n+\t\tif (save_nr != istate->cache_nr)\n \t\t\tgoto redo;\n \t}\n \tclear_pathspec(&pathspec);\n-- \ngitgitgadget\n\n"},{"id":"413297","messageId":"cf091799cae2a999b0c1dabd40159ad1f76d2bbc.1609506428.git.gitgitgadget@gmail.com","threadId":"54916","inReplyTo":"pull.830.git.1609506428.gitgitgadget@gmail.com","subject":"[PATCH 10/12] update-index: use add_index_entry()","fromName":"Derrick Stolee via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-01-01T13:07:06Z","receivedAt":"2021-01-01T13:08:51Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"From: Derrick Stolee <dstolee@microsoft.com>\n\nThis is a mechanical replacement of add_cache_entry().\n\nSigned-off-by: Derrick Stolee <dstolee@microsoft.com>\n---\n builtin/update-index.c | 8 ++++----\n 1 file changed, 4 insertions(+), 4 deletions(-)\n\ndiff --git a/builtin/update-index.c b/builtin/update-index.c\nindex 6f51fb4a14e..577ae2391b7 100644\n--- a/builtin/update-index.c\n+++ b/builtin/update-index.c\n@@ -294,7 +294,7 @@ static int add_one_path(const struct cache_entry *old, const char *path, int len\n \t}\n \toption = allow_add ? ADD_CACHE_OK_TO_ADD : 0;\n \toption |= allow_replace ? ADD_CACHE_OK_TO_REPLACE : 0;\n-\tif (add_cache_entry(ce, option)) {\n+\tif (add_index_entry(istate, ce, option)) {\n \t\tdiscard_cache_entry(ce);\n \t\treturn error(\"%s: cannot add to the index - missing --add option?\", path);\n \t}\n@@ -425,7 +425,7 @@ static int add_cacheinfo(unsigned int mode, const struct object_id *oid,\n \t\tce->ce_flags |= CE_VALID;\n \toption = allow_add ? ADD_CACHE_OK_TO_ADD : 0;\n \toption |= allow_replace ? ADD_CACHE_OK_TO_REPLACE : 0;\n-\tif (add_cache_entry(ce, option))\n+\tif (add_index_entry(istate, ce, option))\n \t\treturn error(\"%s: cannot add to the index - missing --add option?\",\n \t\t\t     path);\n \treport(\"add '%s'\", path);\n@@ -683,12 +683,12 @@ static int unresolve_one(const char *path)\n \t}\n \n \tremove_file_from_index(istate, path);\n-\tif (add_cache_entry(ce_2, ADD_CACHE_OK_TO_ADD)) {\n+\tif (add_index_entry(istate, ce_2, ADD_CACHE_OK_TO_ADD)) {\n \t\terror(\"%s: cannot add our version to the index.\", path);\n \t\tret = -1;\n \t\tgoto free_return;\n \t}\n-\tif (!add_cache_entry(ce_3, ADD_CACHE_OK_TO_ADD))\n+\tif (!add_index_entry(istate, ce_3, ADD_CACHE_OK_TO_ADD))\n \t\treturn 0;\n \terror(\"%s: cannot add their version to the index.\", path);\n \tret = -1;\n-- \ngitgitgadget\n\n"},{"id":"413298","messageId":"d7856e2e772afdd07ba9531377a528099b46b8c2.1609506428.git.gitgitgadget@gmail.com","threadId":"54916","inReplyTo":"pull.830.git.1609506428.gitgitgadget@gmail.com","subject":"[PATCH 11/12] update-index: replace several compatibility macros","fromName":"Derrick Stolee via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-01-01T13:07:07Z","receivedAt":"2021-01-01T13:08:51Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"From: Derrick Stolee <dstolee@microsoft.com>\n\nThis is also the last usage of unmerge_cache_entry_at(), so it can be\nremoved from cache.h.\n\nSigned-off-by: Derrick Stolee <dstolee@microsoft.com>\n---\n builtin/update-index.c | 11 ++++++-----\n cache.h                |  1 -\n 2 files changed, 6 insertions(+), 6 deletions(-)\n\ndiff --git a/builtin/update-index.c b/builtin/update-index.c\nindex 577ae2391b7..4da0c169dc7 100644\n--- a/builtin/update-index.c\n+++ b/builtin/update-index.c\n@@ -441,7 +441,7 @@ static void chmod_path(char flip, const char *path)\n \tif (pos < 0)\n \t\tgoto fail;\n \tce = istate->cache[pos];\n-\tif (chmod_cache_entry(ce, flip) < 0)\n+\tif (chmod_index_entry(istate, ce, flip) < 0)\n \t\tgoto fail;\n \n \treport(\"chmod %cx '%s'\", flip, path);\n@@ -637,7 +637,7 @@ static int unresolve_one(const char *path)\n \tpos = index_name_pos(istate, path, namelen);\n \tif (0 <= pos) {\n \t\t/* already merged */\n-\t\tpos = unmerge_cache_entry_at(pos);\n+\t\tpos = unmerge_index_entry_at(istate, pos);\n \t\tif (pos < istate->cache_nr) {\n \t\t\tconst struct cache_entry *ce = istate->cache[pos];\n \t\t\tif (ce_stage(ce) &&\n@@ -788,8 +788,9 @@ struct refresh_params {\n static int refresh(struct refresh_params *o, unsigned int flag)\n {\n \tsetup_work_tree();\n-\tread_cache();\n-\t*o->has_errors |= refresh_cache(o->flags | flag);\n+\trepo_read_index(repo);\n+\t*o->has_errors |= refresh_index(istate, o->flags | flag,\n+\t\t\t\t\tNULL, NULL, NULL);\n \treturn 0;\n }\n \n@@ -825,7 +826,7 @@ static int resolve_undo_clear_callback(const struct option *opt,\n {\n \tBUG_ON_OPT_NEG(unset);\n \tBUG_ON_OPT_ARG(arg);\n-\tresolve_undo_clear();\n+\tresolve_undo_clear_index(istate);\n \treturn 0;\n }\n \ndiff --git a/cache.h b/cache.h\nindex 7bfb8195d97..dfcbc4923e2 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -421,7 +421,6 @@ extern struct index_state the_index;\n #define cache_dir_exists(name, namelen) index_dir_exists(&the_index, (name), (namelen))\n #define cache_name_is_other(name, namelen) index_name_is_other(&the_index, (name), (namelen))\n #define resolve_undo_clear() resolve_undo_clear_index(&the_index)\n-#define unmerge_cache_entry_at(at) unmerge_index_entry_at(&the_index, at)\n #define unmerge_cache(pathspec) unmerge_index(&the_index, pathspec)\n #define read_blob_data_from_cache(path, sz) read_blob_data_from_index(&the_index, (path), (sz))\n #define hold_locked_index(lock_file, flags) repo_hold_locked_index(the_repository, (lock_file), (flags))\n-- \ngitgitgadget\n\n"},{"id":"413299","messageId":"c576e2d96762eefd714def45b49fb5742cee28f6.1609506428.git.gitgitgadget@gmail.com","threadId":"54916","inReplyTo":"pull.830.git.1609506428.gitgitgadget@gmail.com","subject":"[PATCH 09/12] update-index: use remove_file_from_index()","fromName":"Derrick Stolee via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-01-01T13:07:05Z","receivedAt":"2021-01-01T13:08:51Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"From: Derrick Stolee <dstolee@microsoft.com>\n\nThis is a mechanical replacement of remove_file_from_cache().\n\nSigned-off-by: Derrick Stolee <dstolee@microsoft.com>\n---\n builtin/update-index.c | 10 +++++-----\n 1 file changed, 5 insertions(+), 5 deletions(-)\n\ndiff --git a/builtin/update-index.c b/builtin/update-index.c\nindex 9e57779731f..6f51fb4a14e 100644\n--- a/builtin/update-index.c\n+++ b/builtin/update-index.c\n@@ -252,7 +252,7 @@ static int remove_one_path(const char *path)\n {\n \tif (!allow_remove)\n \t\treturn error(\"%s: does not exist and --remove not passed\", path);\n-\tif (remove_file_from_cache(path))\n+\tif (remove_file_from_index(istate, path))\n \t\treturn error(\"%s: cannot remove from the index\", path);\n \treturn 0;\n }\n@@ -386,7 +386,7 @@ static int process_path(const char *path, struct stat *st, int stat_errno)\n \t\t * On the other hand, removing it from index should work\n \t\t */\n \t\tif (!ignore_skip_worktree_entries && allow_remove &&\n-\t\t    remove_file_from_cache(path))\n+\t\t    remove_file_from_index(istate, path))\n \t\t\treturn error(\"%s: cannot remove from the index\", path);\n \t\treturn 0;\n \t}\n@@ -484,7 +484,7 @@ static void update_one(const char *path)\n \t}\n \n \tif (force_remove) {\n-\t\tif (remove_file_from_cache(path))\n+\t\tif (remove_file_from_index(istate, path))\n \t\t\tdie(\"git update-index: unable to remove %s\", path);\n \t\treport(\"remove '%s'\", path);\n \t\treturn;\n@@ -567,7 +567,7 @@ static void read_index_info(int nul_term_line)\n \n \t\tif (!mode) {\n \t\t\t/* mode == 0 means there is no such path -- remove */\n-\t\t\tif (remove_file_from_cache(path_name))\n+\t\t\tif (remove_file_from_index(istate, path_name))\n \t\t\t\tdie(\"git update-index: unable to remove %s\",\n \t\t\t\t    ptr);\n \t\t}\n@@ -682,7 +682,7 @@ static int unresolve_one(const char *path)\n \t\tgoto free_return;\n \t}\n \n-\tremove_file_from_cache(path);\n+\tremove_file_from_index(istate, path);\n \tif (add_cache_entry(ce_2, ADD_CACHE_OK_TO_ADD)) {\n \t\terror(\"%s: cannot add our version to the index.\", path);\n \t\tret = -1;\n-- \ngitgitgadget\n\n"},{"id":"413300","messageId":"d2af7e21ca13c4c1b19ab363246cee5a395430de.1609506428.git.gitgitgadget@gmail.com","threadId":"54916","inReplyTo":"pull.830.git.1609506428.gitgitgadget@gmail.com","subject":"[PATCH 08/12] update-index: use index_name_pos() over cache_name_pos()","fromName":"Derrick Stolee via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-01-01T13:07:04Z","receivedAt":"2021-01-01T13:08:51Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"From: Derrick Stolee <dstolee@microsoft.com>\n\nSigned-off-by: Derrick Stolee <dstolee@microsoft.com>\n---\n builtin/update-index.c | 10 +++++-----\n 1 file changed, 5 insertions(+), 5 deletions(-)\n\ndiff --git a/builtin/update-index.c b/builtin/update-index.c\nindex a64f2f5a8f4..9e57779731f 100644\n--- a/builtin/update-index.c\n+++ b/builtin/update-index.c\n@@ -233,7 +233,7 @@ static int test_if_untracked_cache_is_supported(void)\n static int mark_ce_flags(const char *path, int flag, int mark)\n {\n \tint namelen = strlen(path);\n-\tint pos = cache_name_pos(path, namelen);\n+\tint pos = index_name_pos(istate, path, namelen);\n \tif (0 <= pos) {\n \t\tmark_fsmonitor_invalid(istate, istate->cache[pos]);\n \t\tif (mark)\n@@ -327,7 +327,7 @@ static int add_one_path(const struct cache_entry *old, const char *path, int len\n static int process_directory(const char *path, int len, struct stat *st)\n {\n \tstruct object_id oid;\n-\tint pos = cache_name_pos(path, len);\n+\tint pos = index_name_pos(istate, path, len);\n \n \t/* Exact match: file or existing gitlink */\n \tif (pos >= 0) {\n@@ -377,7 +377,7 @@ static int process_path(const char *path, struct stat *st, int stat_errno)\n \tif (has_symlink_leading_path(path, len))\n \t\treturn error(\"'%s' is beyond a symbolic link\", path);\n \n-\tpos = cache_name_pos(path, len);\n+\tpos = index_name_pos(istate, path, len);\n \tce = pos < 0 ? NULL : istate->cache[pos];\n \tif (ce && ce_skip_worktree(ce)) {\n \t\t/*\n@@ -437,7 +437,7 @@ static void chmod_path(char flip, const char *path)\n \tint pos;\n \tstruct cache_entry *ce;\n \n-\tpos = cache_name_pos(path, strlen(path));\n+\tpos = index_name_pos(istate, path, strlen(path));\n \tif (pos < 0)\n \t\tgoto fail;\n \tce = istate->cache[pos];\n@@ -634,7 +634,7 @@ static int unresolve_one(const char *path)\n \tstruct cache_entry *ce_2 = NULL, *ce_3 = NULL;\n \n \t/* See if there is such entry in the index. */\n-\tpos = cache_name_pos(path, namelen);\n+\tpos = index_name_pos(istate, path, namelen);\n \tif (0 <= pos) {\n \t\t/* already merged */\n \t\tpos = unmerge_cache_entry_at(pos);\n-- \ngitgitgadget\n\n"},{"id":"413301","messageId":"cc5df3566dfa015b57582fe76f3f6e940d549017.1609506428.git.gitgitgadget@gmail.com","threadId":"54916","inReplyTo":"pull.830.git.1609506428.gitgitgadget@gmail.com","subject":"[PATCH 05/12] update-index: use istate->cache over active_cache","fromName":"Derrick Stolee via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-01-01T13:07:01Z","receivedAt":"2021-01-01T13:08:51Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"From: Derrick Stolee <dstolee@microsoft.com>\n\nSigned-off-by: Derrick Stolee <dstolee@microsoft.com>\n---\n builtin/update-index.c | 22 +++++++++++-----------\n 1 file changed, 11 insertions(+), 11 deletions(-)\n\ndiff --git a/builtin/update-index.c b/builtin/update-index.c\nindex c9a6cde97da..0616c786410 100644\n--- a/builtin/update-index.c\n+++ b/builtin/update-index.c\n@@ -235,12 +235,12 @@ static int mark_ce_flags(const char *path, int flag, int mark)\n \tint namelen = strlen(path);\n \tint pos = cache_name_pos(path, namelen);\n \tif (0 <= pos) {\n-\t\tmark_fsmonitor_invalid(istate, active_cache[pos]);\n+\t\tmark_fsmonitor_invalid(istate, istate->cache[pos]);\n \t\tif (mark)\n-\t\t\tactive_cache[pos]->ce_flags |= flag;\n+\t\t\tistate->cache[pos]->ce_flags |= flag;\n \t\telse\n-\t\t\tactive_cache[pos]->ce_flags &= ~flag;\n-\t\tactive_cache[pos]->ce_flags |= CE_UPDATE_IN_BASE;\n+\t\t\tistate->cache[pos]->ce_flags &= ~flag;\n+\t\tistate->cache[pos]->ce_flags |= CE_UPDATE_IN_BASE;\n \t\tcache_tree_invalidate_path(istate, path);\n \t\tactive_cache_changed |= CE_ENTRY_CHANGED;\n \t\treturn 0;\n@@ -331,7 +331,7 @@ static int process_directory(const char *path, int len, struct stat *st)\n \n \t/* Exact match: file or existing gitlink */\n \tif (pos >= 0) {\n-\t\tconst struct cache_entry *ce = active_cache[pos];\n+\t\tconst struct cache_entry *ce = istate->cache[pos];\n \t\tif (S_ISGITLINK(ce->ce_mode)) {\n \n \t\t\t/* Do nothing to the index if there is no HEAD! */\n@@ -347,7 +347,7 @@ static int process_directory(const char *path, int len, struct stat *st)\n \t/* Inexact match: is there perhaps a subdirectory match? */\n \tpos = -pos-1;\n \twhile (pos < active_nr) {\n-\t\tconst struct cache_entry *ce = active_cache[pos++];\n+\t\tconst struct cache_entry *ce = istate->cache[pos++];\n \n \t\tif (strncmp(ce->name, path, len))\n \t\t\tbreak;\n@@ -378,7 +378,7 @@ static int process_path(const char *path, struct stat *st, int stat_errno)\n \t\treturn error(\"'%s' is beyond a symbolic link\", path);\n \n \tpos = cache_name_pos(path, len);\n-\tce = pos < 0 ? NULL : active_cache[pos];\n+\tce = pos < 0 ? NULL : istate->cache[pos];\n \tif (ce && ce_skip_worktree(ce)) {\n \t\t/*\n \t\t * working directory version is assumed \"good\"\n@@ -440,7 +440,7 @@ static void chmod_path(char flip, const char *path)\n \tpos = cache_name_pos(path, strlen(path));\n \tif (pos < 0)\n \t\tgoto fail;\n-\tce = active_cache[pos];\n+\tce = istate->cache[pos];\n \tif (chmod_cache_entry(ce, flip) < 0)\n \t\tgoto fail;\n \n@@ -639,7 +639,7 @@ static int unresolve_one(const char *path)\n \t\t/* already merged */\n \t\tpos = unmerge_cache_entry_at(pos);\n \t\tif (pos < active_nr) {\n-\t\t\tconst struct cache_entry *ce = active_cache[pos];\n+\t\t\tconst struct cache_entry *ce = istate->cache[pos];\n \t\t\tif (ce_stage(ce) &&\n \t\t\t    ce_namelen(ce) == namelen &&\n \t\t\t    !memcmp(ce->name, path, namelen))\n@@ -653,7 +653,7 @@ static int unresolve_one(const char *path)\n \t\t */\n \t\tpos = -pos-1;\n \t\tif (pos < active_nr) {\n-\t\t\tconst struct cache_entry *ce = active_cache[pos];\n+\t\t\tconst struct cache_entry *ce = istate->cache[pos];\n \t\t\tif (ce_namelen(ce) == namelen &&\n \t\t\t    !memcmp(ce->name, path, namelen)) {\n \t\t\t\tfprintf(stderr,\n@@ -749,7 +749,7 @@ static int do_reupdate(int ac, const char **av,\n \t\thas_head = 0;\n  redo:\n \tfor (pos = 0; pos < active_nr; pos++) {\n-\t\tconst struct cache_entry *ce = active_cache[pos];\n+\t\tconst struct cache_entry *ce = istate->cache[pos];\n \t\tstruct cache_entry *old = NULL;\n \t\tint save_nr;\n \t\tchar *path;\n-- \ngitgitgadget\n\n"},{"id":"413302","messageId":"8fb307c3bee9a33ad408bba6c422e992fb1e2656.1609506428.git.gitgitgadget@gmail.com","threadId":"54916","inReplyTo":"pull.830.git.1609506428.gitgitgadget@gmail.com","subject":"[PATCH 12/12] update-index: remove ce_match_stat(), all macros","fromName":"Derrick Stolee via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-01-01T13:07:08Z","receivedAt":"2021-01-01T13:08:51Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"From: Derrick Stolee <dstolee@microsoft.com>\n\nThe final index compatibility macro to remove from the update-index\nbuiltin is ce_match_state(). Further, this is the last use of that macro\nanywhere, so it should be removed.\n\nThere are some remaining references in the racy-git.txt technical\ndocument that are updated to ie_match_stat().\n\nSigned-off-by: Derrick Stolee <dstolee@microsoft.com>\n---\n Documentation/technical/racy-git.txt | 6 +++---\n builtin/update-index.c               | 3 +--\n cache.h                              | 1 -\n 3 files changed, 4 insertions(+), 6 deletions(-)\n\ndiff --git a/Documentation/technical/racy-git.txt b/Documentation/technical/racy-git.txt\nindex ceda4bbfda4..65188e04559 100644\n--- a/Documentation/technical/racy-git.txt\n+++ b/Documentation/technical/racy-git.txt\n@@ -26,7 +26,7 @@ information obtained from the filesystem via `lstat(2)` system\n call when they were last updated.  When checking if they differ,\n Git first runs `lstat(2)` on the files and compares the result\n with this information (this is what was originally done by the\n-`ce_match_stat()` function, but the current code does it in\n+`ie_match_stat()` function, but the current code does it in\n `ce_match_stat_basic()` function).  If some of these \"cached\n stat information\" fields do not match, Git can tell that the\n files are modified without even looking at their contents.\n@@ -102,7 +102,7 @@ timestamp as the index file itself.\n \n The callers that want to check if an index entry matches the\n corresponding file in the working tree continue to call\n-`ce_match_stat()`, but with this change, `ce_match_stat()` uses\n+`ie_match_stat()`, but with this change, `ie_match_stat()` uses\n `ce_modified_check_fs()` to see if racily clean ones are\n actually clean after comparing the cached stat information using\n `ce_match_stat_basic()`.\n@@ -128,7 +128,7 @@ Runtime penalty\n ---------------\n \n The runtime penalty of falling back to `ce_modified_check_fs()`\n-from `ce_match_stat()` can be very expensive when there are many\n+from `ie_match_stat()` can be very expensive when there are many\n racily clean entries.  An obvious way to artificially create\n this situation is to give the same timestamp to all the files in\n the working tree in a large project, run `git update-index` on\ndiff --git a/builtin/update-index.c b/builtin/update-index.c\nindex 4da0c169dc7..256df43ecbd 100644\n--- a/builtin/update-index.c\n+++ b/builtin/update-index.c\n@@ -3,7 +3,6 @@\n  *\n  * Copyright (C) Linus Torvalds, 2005\n  */\n-#define USE_THE_INDEX_COMPATIBILITY_MACROS\n #include \"cache.h\"\n #include \"config.h\"\n #include \"lockfile.h\"\n@@ -277,7 +276,7 @@ static int add_one_path(const struct cache_entry *old, const char *path, int len\n \tstruct cache_entry *ce;\n \n \t/* Was the old index entry already up-to-date? */\n-\tif (old && !ce_stage(old) && !ce_match_stat(old, st, 0))\n+\tif (old && !ce_stage(old) && !ie_match_stat(istate, old, st, 0))\n \t\treturn 0;\n \n \tce = make_empty_cache_entry(istate, len);\ndiff --git a/cache.h b/cache.h\nindex dfcbc4923e2..2925bf050b8 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -416,7 +416,6 @@ extern struct index_state the_index;\n #define chmod_cache_entry(ce, flip) chmod_index_entry(&the_index, (ce), (flip))\n #define refresh_cache(flags) refresh_index(&the_index, (flags), NULL, NULL, NULL)\n #define refresh_and_write_cache(refresh_flags, write_flags, gentle) repo_refresh_and_write_index(the_repository, (refresh_flags), (write_flags), (gentle), NULL, NULL, NULL)\n-#define ce_match_stat(ce, st, options) ie_match_stat(&the_index, (ce), (st), (options))\n #define ce_modified(ce, st, options) ie_modified(&the_index, (ce), (st), (options))\n #define cache_dir_exists(name, namelen) index_dir_exists(&the_index, (name), (namelen))\n #define cache_name_is_other(name, namelen) index_name_is_other(&the_index, (name), (namelen))\n-- \ngitgitgadget\n"},{"id":"413305","messageId":"CABPp-BEboS3OG0dMi6kzaXkJ3vELKgpV1Km0m3ZjACA2nGa5QA@mail.gmail.com","threadId":"54916","inReplyTo":"77f6510bb680aaf119526f75daadf8c40d22793e.1609506428.git.gitgitgadget@gmail.com","subject":"Re: [PATCH 04/12] update-index: drop the_index, the_repository","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2021-01-01T21:05:16Z","receivedAt":"2021-01-01T21:06:26Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Fri, Jan 1, 2021 at 5:10 AM Derrick Stolee via GitGitGadget\n<gitgitgadget@gmail.com> wrote:\n>\n> From: Derrick Stolee <dstolee@microsoft.com>\n>\n> To reduce the need for the index compatibility macros, we will replace\n> their uses in update-index mechanically. This is the most interesting\n> change, which creates global \"repo\" and \"istate\" pointers. The macros\n> can then be mechanically replaced by instances that use the istate\n> pointer instead of the version that autocompletes to use the_index.\n\nautocompletes seems a bit weird to me here.  Perhaps s/autocompletes\nto use/implicitly uses/ ?\n\nAlso, it seems like in the last few patches you just used\nthe_repository whereas here you're trying to avoid it.  Is that\nbecause there are more uses here and only one in the other patches?\n\nOtherwise, all the changes in this patch (and the other ones I've read\nso far; going through them in order) seem like the obvious mechanical\nchanges necessary to update to avoid the index compatibility macros.\nSo, looking good so far.\n\n>\n> Signed-off-by: Derrick Stolee <dstolee@microsoft.com>\n> ---\n>  builtin/update-index.c | 59 +++++++++++++++++++++++-------------------\n>  1 file changed, 32 insertions(+), 27 deletions(-)\n>\n> diff --git a/builtin/update-index.c b/builtin/update-index.c\n> index 79087bccea4..c9a6cde97da 100644\n> --- a/builtin/update-index.c\n> +++ b/builtin/update-index.c\n> @@ -40,6 +40,9 @@ static int ignore_skip_worktree_entries;\n>  #define UNMARK_FLAG 2\n>  static struct strbuf mtime_dir = STRBUF_INIT;\n>\n> +static struct repository *repo;\n> +static struct index_state *istate;\n> +\n>  /* Untracked cache mode */\n>  enum uc_mode {\n>         UC_UNSPECIFIED = -1,\n> @@ -232,13 +235,13 @@ static int mark_ce_flags(const char *path, int flag, int mark)\n>         int namelen = strlen(path);\n>         int pos = cache_name_pos(path, namelen);\n>         if (0 <= pos) {\n> -               mark_fsmonitor_invalid(&the_index, active_cache[pos]);\n> +               mark_fsmonitor_invalid(istate, active_cache[pos]);\n>                 if (mark)\n>                         active_cache[pos]->ce_flags |= flag;\n>                 else\n>                         active_cache[pos]->ce_flags &= ~flag;\n>                 active_cache[pos]->ce_flags |= CE_UPDATE_IN_BASE;\n> -               cache_tree_invalidate_path(&the_index, path);\n> +               cache_tree_invalidate_path(istate, path);\n>                 active_cache_changed |= CE_ENTRY_CHANGED;\n>                 return 0;\n>         }\n> @@ -277,14 +280,14 @@ static int add_one_path(const struct cache_entry *old, const char *path, int len\n>         if (old && !ce_stage(old) && !ce_match_stat(old, st, 0))\n>                 return 0;\n>\n> -       ce = make_empty_cache_entry(&the_index, len);\n> +       ce = make_empty_cache_entry(istate, len);\n>         memcpy(ce->name, path, len);\n>         ce->ce_flags = create_ce_flags(0);\n>         ce->ce_namelen = len;\n> -       fill_stat_cache_info(&the_index, ce, st);\n> +       fill_stat_cache_info(istate, ce, st);\n>         ce->ce_mode = ce_mode_from_stat(old, st->st_mode);\n>\n> -       if (index_path(&the_index, &ce->oid, path, st,\n> +       if (index_path(istate, &ce->oid, path, st,\n>                        info_only ? 0 : HASH_WRITE_OBJECT)) {\n>                 discard_cache_entry(ce);\n>                 return -1;\n> @@ -411,7 +414,7 @@ static int add_cacheinfo(unsigned int mode, const struct object_id *oid,\n>                 return error(\"Invalid path '%s'\", path);\n>\n>         len = strlen(path);\n> -       ce = make_empty_cache_entry(&the_index, len);\n> +       ce = make_empty_cache_entry(istate, len);\n>\n>         oidcpy(&ce->oid, oid);\n>         memcpy(ce->name, path, len);\n> @@ -603,7 +606,7 @@ static struct cache_entry *read_one_ent(const char *which,\n>         struct object_id oid;\n>         struct cache_entry *ce;\n>\n> -       if (get_tree_entry(the_repository, ent, path, &oid, &mode)) {\n> +       if (get_tree_entry(repo, ent, path, &oid, &mode)) {\n>                 if (which)\n>                         error(\"%s: not in %s branch.\", path, which);\n>                 return NULL;\n> @@ -613,7 +616,7 @@ static struct cache_entry *read_one_ent(const char *which,\n>                         error(\"%s: not a blob in %s branch.\", path, which);\n>                 return NULL;\n>         }\n> -       ce = make_empty_cache_entry(&the_index, namelen);\n> +       ce = make_empty_cache_entry(istate, namelen);\n>\n>         oidcpy(&ce->oid, &oid);\n>         memcpy(ce->name, path, namelen);\n> @@ -751,7 +754,7 @@ static int do_reupdate(int ac, const char **av,\n>                 int save_nr;\n>                 char *path;\n>\n> -               if (ce_stage(ce) || !ce_path_match(&the_index, ce, &pathspec, NULL))\n> +               if (ce_stage(ce) || !ce_path_match(istate, ce, &pathspec, NULL))\n>                         continue;\n>                 if (has_head)\n>                         old = read_one_ent(NULL, &head_oid,\n> @@ -968,7 +971,6 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n>         struct parse_opt_ctx_t ctx;\n>         strbuf_getline_fn getline_fn;\n>         int parseopt_state = PARSE_OPT_UNKNOWN;\n> -       struct repository *r = the_repository;\n>         struct option options[] = {\n>                 OPT_BIT('q', NULL, &refresh_args.flags,\n>                         N_(\"continue refresh even when index needs update\"),\n> @@ -1077,16 +1079,19 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n>\n>         git_config(git_default_config, NULL);\n>\n> +       repo = the_repository;\n> +\n>         /* we will diagnose later if it turns out that we need to update it */\n> -       newfd = hold_locked_index(&lock_file, 0);\n> +       newfd = repo_hold_locked_index(repo, &lock_file, 0);\n>         if (newfd < 0)\n>                 lock_error = errno;\n>\n> -       entries = read_cache();\n> +       entries = repo_read_index(repo);\n>         if (entries < 0)\n>                 die(\"cache corrupted\");\n>\n> -       the_index.updated_skipworktree = 1;\n> +       istate = repo->index;\n> +       istate->updated_skipworktree = 1;\n>\n>         /*\n>          * Custom copy of parse_options() because we want to handle\n> @@ -1140,9 +1145,9 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n>                             preferred_index_format,\n>                             INDEX_FORMAT_LB, INDEX_FORMAT_UB);\n>\n> -               if (the_index.version != preferred_index_format)\n> +               if (istate->version != preferred_index_format)\n>                         active_cache_changed |= SOMETHING_CHANGED;\n> -               the_index.version = preferred_index_format;\n> +               istate->version = preferred_index_format;\n>         }\n>\n>         if (read_from_stdin) {\n> @@ -1173,28 +1178,28 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n>                         warning(_(\"core.splitIndex is set to false; \"\n>                                   \"remove or change it, if you really want to \"\n>                                   \"enable split index\"));\n> -               if (the_index.split_index)\n> -                       the_index.cache_changed |= SPLIT_INDEX_ORDERED;\n> +               if (istate->split_index)\n> +                       istate->cache_changed |= SPLIT_INDEX_ORDERED;\n>                 else\n> -                       add_split_index(&the_index);\n> +                       add_split_index(istate);\n>         } else if (!split_index) {\n>                 if (git_config_get_split_index() == 1)\n>                         warning(_(\"core.splitIndex is set to true; \"\n>                                   \"remove or change it, if you really want to \"\n>                                   \"disable split index\"));\n> -               remove_split_index(&the_index);\n> +               remove_split_index(istate);\n>         }\n>\n> -       prepare_repo_settings(r);\n> +       prepare_repo_settings(repo);\n>         switch (untracked_cache) {\n>         case UC_UNSPECIFIED:\n>                 break;\n>         case UC_DISABLE:\n> -               if (r->settings.core_untracked_cache == UNTRACKED_CACHE_WRITE)\n> +               if (repo->settings.core_untracked_cache == UNTRACKED_CACHE_WRITE)\n>                         warning(_(\"core.untrackedCache is set to true; \"\n>                                   \"remove or change it, if you really want to \"\n>                                   \"disable the untracked cache\"));\n> -               remove_untracked_cache(&the_index);\n> +               remove_untracked_cache(istate);\n>                 report(_(\"Untracked cache disabled\"));\n>                 break;\n>         case UC_TEST:\n> @@ -1202,11 +1207,11 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n>                 return !test_if_untracked_cache_is_supported();\n>         case UC_ENABLE:\n>         case UC_FORCE:\n> -               if (r->settings.core_untracked_cache == UNTRACKED_CACHE_REMOVE)\n> +               if (repo->settings.core_untracked_cache == UNTRACKED_CACHE_REMOVE)\n>                         warning(_(\"core.untrackedCache is set to false; \"\n>                                   \"remove or change it, if you really want to \"\n>                                   \"enable the untracked cache\"));\n> -               add_untracked_cache(&the_index);\n> +               add_untracked_cache(istate);\n>                 report(_(\"Untracked cache enabled for '%s'\"), get_git_work_tree());\n>                 break;\n>         default:\n> @@ -1218,14 +1223,14 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n>                         warning(_(\"core.fsmonitor is unset; \"\n>                                 \"set it if you really want to \"\n>                                 \"enable fsmonitor\"));\n> -               add_fsmonitor(&the_index);\n> +               add_fsmonitor(istate);\n>                 report(_(\"fsmonitor enabled\"));\n>         } else if (!fsmonitor) {\n>                 if (git_config_get_fsmonitor() == 1)\n>                         warning(_(\"core.fsmonitor is set; \"\n>                                 \"remove it if you really want to \"\n>                                 \"disable fsmonitor\"));\n> -               remove_fsmonitor(&the_index);\n> +               remove_fsmonitor(istate);\n>                 report(_(\"fsmonitor disabled\"));\n>         }\n>\n> @@ -1235,7 +1240,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n>                                 exit(128);\n>                         unable_to_lock_die(get_index_file(), lock_error);\n>                 }\n> -               if (write_locked_index(&the_index, &lock_file, COMMIT_LOCK))\n> +               if (write_locked_index(istate, &lock_file, COMMIT_LOCK))\n>                         die(\"Unable to write new index file\");\n>         }\n>\n> --\n> gitgitgadget\n>\n"},{"id":"413306","messageId":"CABPp-BEPDpagENsmx=8gJ9SqUFrD+mh87WbLnV1mpgtFz56qVg@mail.gmail.com","threadId":"54916","inReplyTo":"8fb307c3bee9a33ad408bba6c422e992fb1e2656.1609506428.git.gitgitgadget@gmail.com","subject":"Re: [PATCH 12/12] update-index: remove ce_match_stat(), all macros","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2021-01-01T21:12:25Z","receivedAt":"2021-01-01T21:16:47Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Fri, Jan 1, 2021 at 5:12 AM Derrick Stolee via GitGitGadget\n<gitgitgadget@gmail.com> wrote:\n>\n> From: Derrick Stolee <dstolee@microsoft.com>\n>\n> The final index compatibility macro to remove from the update-index\n> builtin is ce_match_state(). Further, this is the last use of that macro\n\nI think you mean ce_match_stat(); no trailing 'e'.\n\n> anywhere, so it should be removed.\n>\n> There are some remaining references in the racy-git.txt technical\n> document that are updated to ie_match_stat().\n>\n> Signed-off-by: Derrick Stolee <dstolee@microsoft.com>\n> ---\n>  Documentation/technical/racy-git.txt | 6 +++---\n>  builtin/update-index.c               | 3 +--\n>  cache.h                              | 1 -\n>  3 files changed, 4 insertions(+), 6 deletions(-)\n>\n> diff --git a/Documentation/technical/racy-git.txt b/Documentation/technical/racy-git.txt\n> index ceda4bbfda4..65188e04559 100644\n> --- a/Documentation/technical/racy-git.txt\n> +++ b/Documentation/technical/racy-git.txt\n> @@ -26,7 +26,7 @@ information obtained from the filesystem via `lstat(2)` system\n>  call when they were last updated.  When checking if they differ,\n>  Git first runs `lstat(2)` on the files and compares the result\n>  with this information (this is what was originally done by the\n> -`ce_match_stat()` function, but the current code does it in\n> +`ie_match_stat()` function, but the current code does it in\n\nEven updating the documentation... :-)\n\nArguably, this change should have been done years ago when\nce_match_stat was turned into a macro, but certainly becomes more\nimportant with your patch that removes the macro.\n\n>  `ce_match_stat_basic()` function).  If some of these \"cached\n>  stat information\" fields do not match, Git can tell that the\n>  files are modified without even looking at their contents.\n> @@ -102,7 +102,7 @@ timestamp as the index file itself.\n>\n>  The callers that want to check if an index entry matches the\n>  corresponding file in the working tree continue to call\n> -`ce_match_stat()`, but with this change, `ce_match_stat()` uses\n> +`ie_match_stat()`, but with this change, `ie_match_stat()` uses\n>  `ce_modified_check_fs()` to see if racily clean ones are\n>  actually clean after comparing the cached stat information using\n>  `ce_match_stat_basic()`.\n> @@ -128,7 +128,7 @@ Runtime penalty\n>  ---------------\n>\n>  The runtime penalty of falling back to `ce_modified_check_fs()`\n> -from `ce_match_stat()` can be very expensive when there are many\n> +from `ie_match_stat()` can be very expensive when there are many\n>  racily clean entries.  An obvious way to artificially create\n>  this situation is to give the same timestamp to all the files in\n>  the working tree in a large project, run `git update-index` on\n> diff --git a/builtin/update-index.c b/builtin/update-index.c\n> index 4da0c169dc7..256df43ecbd 100644\n> --- a/builtin/update-index.c\n> +++ b/builtin/update-index.c\n> @@ -3,7 +3,6 @@\n>   *\n>   * Copyright (C) Linus Torvalds, 2005\n>   */\n> -#define USE_THE_INDEX_COMPATIBILITY_MACROS\n>  #include \"cache.h\"\n>  #include \"config.h\"\n>  #include \"lockfile.h\"\n> @@ -277,7 +276,7 @@ static int add_one_path(const struct cache_entry *old, const char *path, int len\n>         struct cache_entry *ce;\n>\n>         /* Was the old index entry already up-to-date? */\n> -       if (old && !ce_stage(old) && !ce_match_stat(old, st, 0))\n> +       if (old && !ce_stage(old) && !ie_match_stat(istate, old, st, 0))\n>                 return 0;\n>\n>         ce = make_empty_cache_entry(istate, len);\n> diff --git a/cache.h b/cache.h\n> index dfcbc4923e2..2925bf050b8 100644\n> --- a/cache.h\n> +++ b/cache.h\n> @@ -416,7 +416,6 @@ extern struct index_state the_index;\n>  #define chmod_cache_entry(ce, flip) chmod_index_entry(&the_index, (ce), (flip))\n>  #define refresh_cache(flags) refresh_index(&the_index, (flags), NULL, NULL, NULL)\n>  #define refresh_and_write_cache(refresh_flags, write_flags, gentle) repo_refresh_and_write_index(the_repository, (refresh_flags), (write_flags), (gentle), NULL, NULL, NULL)\n> -#define ce_match_stat(ce, st, options) ie_match_stat(&the_index, (ce), (st), (options))\n>  #define ce_modified(ce, st, options) ie_modified(&the_index, (ce), (st), (options))\n>  #define cache_dir_exists(name, namelen) index_dir_exists(&the_index, (name), (namelen))\n>  #define cache_name_is_other(name, namelen) index_name_is_other(&the_index, (name), (namelen))\n\nThe rest looks good.\n"},{"id":"413307","messageId":"CABPp-BHKeKegCRNVJLvgPMk8F60NgpVxjU0jiPYtzGpK-2xRBw@mail.gmail.com","threadId":"54916","inReplyTo":"pull.830.git.1609506428.gitgitgadget@gmail.com","subject":"Re: [PATCH 00/12] Remove more index compatibility macros","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2021-01-01T21:16:41Z","receivedAt":"2021-01-01T21:18:47Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Fri, Jan 1, 2021 at 5:10 AM Derrick Stolee via GitGitGadget\n<gitgitgadget@gmail.com> wrote:\n>\n> I noticed that Duy's project around USE_THE_INDEX_COMPATIBILITY_MACROS has\n> been on pause for a while. Here is my attempt to continue that project a\n> little.\n>\n> I started going through the builtins that still use cache_name_pos() and the\n> first few were easy: merge-inex, mv, rm.\n>\n> Then I hit update-index and it was a bit bigger. It's included here as well.\n>\n> My strategy for update-index was to create static globals \"repo\" and\n> \"istate\" that point to the_repository and the_index, respectively. Then, I\n> was able to remove macros one-by-one without changing method prototypes\n> within the file.\n>\n> I had started trying to keep everything local to the method signatures, but\n> I hit a snag when reaching the command-line parsing callbacks, which I could\n> not modify their call signature. At that point, I had something that was\n> already much more complicated than what I present now. Outside of the first\n> update-index commit, everything was a mechanical find/replace.\n>\n> In total, this allows us to remove four of the compatibility macros because\n> they are no longer used.\n\nThis series is divided nicely in a way that makes review easy.  I've\nmade some of these same types of changes elsewhere, and the whole\nseries is really just a long sequence of mechanical changes (plus a\ncase or two of fixing formatting on a line you were changing anyway,\nsuch as adding spaces around an operator).  I think the work to\ncontinue dropping the implicit dependency on the_index is helpful.\n\nI only found two minor suggestions for improving the commit messages;\nthe patches all look good to me.\n"},{"id":"413309","messageId":"CAPig+cS-oDfCX-LaDEW2U+9Aa9VNZUPs54isODoHCv6HxAdZeQ@mail.gmail.com","threadId":"54916","inReplyTo":"pull.830.git.1609506428.gitgitgadget@gmail.com","subject":"Re: [PATCH 00/12] Remove more index compatibility macros","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2021-01-02T06:12:10Z","receivedAt":"2021-01-02T06:13:19Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Fri, Jan 1, 2021 at 8:09 AM Derrick Stolee via GitGitGadget\n<gitgitgadget@gmail.com> wrote:\n> My strategy for update-index was to create static globals \"repo\" and\n> \"istate\" that point to the_repository and the_index, respectively. Then, I\n> was able to remove macros one-by-one without changing method prototypes\n> within the file.\n>\n> I had started trying to keep everything local to the method signatures, but\n> I hit a snag when reaching the command-line parsing callbacks, which I could\n> not modify their call signature. [...]\n\nYou should be able to do this, not by modifying the callback\nsignature, but by taking advantage of the `extra` member of `struct\noption` which is available to callback functions or arbitrary use. If\nyou need to access the index in a callback, then assign a `struct\nindex_state *` to `extra`; likewise assign a `struct repository *` to\n`extra` to access the repository. If you need access to both the index\nand the repository, then just store the repository in `extra` since\nthe repository has an `index` field.\n\nYou won't be able to use any of the canned OPT_FOO() macros to\ninitialize an entry in the update-index.c `options[]` array which\nneeds `extra`-initialization since the macros don't let you specify\n`extra`, but you can easily bypass the macro and initialize the\n`struct option` manually. (After all, the macros exist for\nconvenience; they are not a hard requirement.)\n\nWithin the callback, extract the `repository` or `index_state` as you\nwould any other field. For instance:\n\n    const struct repository *repo = opt->extra;\n\nThis should allow you to get rid of the globals introduced by patch\n[4/12] (assuming passing the index and repo arguments around\neverywhere doesn't get overly hairy).\n"},{"id":"413353","messageId":"f3d0ef14-c753-c107-4693-67cec504964a@gmail.com","threadId":"54916","inReplyTo":"68d88b651c74659eb171e88d701b89d11e7f5f24.1609506428.git.gitgitgadget@gmail.com","subject":"Re: [PATCH 01/12] merge-index: drop index compatibility macros","fromName":"Alban Gruin","fromEmail":"alban.gruin@gmail.com","sentAt":"2021-01-03T23:31:22Z","receivedAt":"2021-01-03T23:32:38Z","isPatch":true,"sender":{"key":"alban.gruin@gmail.com","avatar":"https://avatars.githubusercontent.com/u/6310153?v=4"},"body":"Hi Derrick,\n\nLe 01/01/2021 à 14:06, Derrick Stolee via GitGitGadget a écrit :\n> From: Derrick Stolee <dstolee@microsoft.com>\n> \n> Replace uses of the old macros for the_index and instead pass around a\n> 'struct index_state' pointer. This allows dropping the compatibility\n> flag.\n> \n> Signed-off-by: Derrick Stolee <dstolee@microsoft.com>\n\nI already libified builtin/merge-index.c in ag/merge-strategies-in-c,\nand such dropped the_index.  I modified merge_entry(), merge_one_path()\nand merge_all() to take a callback, itself taking a repository.  As\nsuch, in my series, these functions take a `struct repository *' instead\nof an index state.\n\nI'm not sure how we should proceed with our respective patches.\n\nCheers,\nAlban\n\n"},{"id":"413354","messageId":"1b124600-9e3a-9bce-a1e8-49ceef0d595f@gmail.com","threadId":"54916","inReplyTo":"CABPp-BEboS3OG0dMi6kzaXkJ3vELKgpV1Km0m3ZjACA2nGa5QA@mail.gmail.com","subject":"Re: [PATCH 04/12] update-index: drop the_index, the_repository","fromName":"Derrick Stolee","fromEmail":"stolee@gmail.com","sentAt":"2021-01-04T00:56:12Z","receivedAt":"2021-01-04T00:58:32Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"On 1/1/2021 4:05 PM, Elijah Newren wrote:\n> On Fri, Jan 1, 2021 at 5:10 AM Derrick Stolee via GitGitGadget\n> <gitgitgadget@gmail.com> wrote:\n>>\n>> From: Derrick Stolee <dstolee@microsoft.com>\n>>\n>> To reduce the need for the index compatibility macros, we will replace\n>> their uses in update-index mechanically. This is the most interesting\n>> change, which creates global \"repo\" and \"istate\" pointers. The macros\n>> can then be mechanically replaced by instances that use the istate\n>> pointer instead of the version that autocompletes to use the_index.\n> \n> autocompletes seems a bit weird to me here.  Perhaps s/autocompletes\n> to use/implicitly uses/ ?\n\nMy intention was \"instead of the macro expansion that uses the_index\".\nThe preprocessor is really just an early version of autocomplete, right?\nThanks.\n\n> Also, it seems like in the last few patches you just used\n> the_repository whereas here you're trying to avoid it.  Is that\n> because there are more uses here and only one in the other patches?\n\nMy goal isn't to remove the_repository, but the earlier patches also\navoided static globals in favor of method parameters. I needed to\nchange the strategy for update-index because of the vast number of\nmethods needing an update. Since I was making a static global for\nthe current index, it was not a huge step to also add one for the\ncurrent repository.\n\nFurther, the cmd_update_index() already had a local pointer that\nreplaced using the_repository, giving me some reason to include\nthe_repository in these updates.\n\n> Otherwise, all the changes in this patch (and the other ones I've read\n> so far; going through them in order) seem like the obvious mechanical\n> changes necessary to update to avoid the index compatibility macros.\n> So, looking good so far.\n\nThanks,\n-Stolee\n\n"},{"id":"413355","messageId":"65af825c-00b1-5852-3a4a-81babfc5040f@gmail.com","threadId":"54916","inReplyTo":"CAPig+cS-oDfCX-LaDEW2U+9Aa9VNZUPs54isODoHCv6HxAdZeQ@mail.gmail.com","subject":"Re: [PATCH 00/12] Remove more index compatibility macros","fromName":"Derrick Stolee","fromEmail":"stolee@gmail.com","sentAt":"2021-01-04T01:01:36Z","receivedAt":"2021-01-04T01:02:26Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"On 1/2/2021 1:12 AM, Eric Sunshine wrote:\n> On Fri, Jan 1, 2021 at 8:09 AM Derrick Stolee via GitGitGadget\n> <gitgitgadget@gmail.com> wrote:\n>> My strategy for update-index was to create static globals \"repo\" and\n>> \"istate\" that point to the_repository and the_index, respectively. Then, I\n>> was able to remove macros one-by-one without changing method prototypes\n>> within the file.\n>>\n>> I had started trying to keep everything local to the method signatures, but\n>> I hit a snag when reaching the command-line parsing callbacks, which I could\n>> not modify their call signature. [...]\n> \n> You should be able to do this, not by modifying the callback\n> signature, but by taking advantage of the `extra` member of `struct\n> option` which is available to callback functions or arbitrary use. If\n> you need to access the index in a callback, then assign a `struct\n> index_state *` to `extra`; likewise assign a `struct repository *` to\n> `extra` to access the repository. If you need access to both the index\n> and the repository, then just store the repository in `extra` since\n> the repository has an `index` field.\n> \n> You won't be able to use any of the canned OPT_FOO() macros to\n> initialize an entry in the update-index.c `options[]` array which\n> needs `extra`-initialization since the macros don't let you specify\n> `extra`, but you can easily bypass the macro and initialize the\n> `struct option` manually. (After all, the macros exist for\n> convenience; they are not a hard requirement.)\n> \n> Within the callback, extract the `repository` or `index_state` as you\n> would any other field. For instance:\n> \n>     const struct repository *repo = opt->extra;\n\nYes, this is definitely the way to make it possible.\n\n> This should allow you to get rid of the globals introduced by patch\n> [4/12] (assuming passing the index and repo arguments around\n> everywhere doesn't get overly hairy).\n\nMy attempts just getting to the point of hitting these callbacks was\nalready making me frustrated with how complicated the code became with\nthat approach.\n\nPerhaps now that I've removed the compatibility macros, it would be\neasier to insert the method parameters since most of the lines that\nneed to change would be method prototypes and the calls to those methods\n(plus the callback function details).\n\nIs that a valuable effort? I could give it a try, but I want to be sure\nthat adjusting all of those helper methods in the builtin would indeed\nhave valuable improvements over the static globals used here.\n\nThanks,\n-Stolee\n\n"},{"id":"413369","messageId":"CAPig+cTxCLbfsk4D-_Rd=XF=A4zje1_pETyD9CJRtJNyADb=tg@mail.gmail.com","threadId":"54916","inReplyTo":"65af825c-00b1-5852-3a4a-81babfc5040f@gmail.com","subject":"Re: [PATCH 00/12] Remove more index compatibility macros","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2021-01-04T06:22:52Z","receivedAt":"2021-01-04T06:24:01Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Sun, Jan 3, 2021 at 8:01 PM Derrick Stolee <stolee@gmail.com> wrote:\n> On 1/2/2021 1:12 AM, Eric Sunshine wrote:\n> > This should allow you to get rid of the globals introduced by patch\n> > [4/12] (assuming passing the index and repo arguments around\n> > everywhere doesn't get overly hairy).\n>\n> Perhaps now that I've removed the compatibility macros, it would be\n> easier to insert the method parameters since most of the lines that\n> need to change would be method prototypes and the calls to those methods\n> (plus the callback function details).\n>\n> Is that a valuable effort? I could give it a try, but I want to be sure\n> that adjusting all of those helper methods in the builtin would indeed\n> have valuable improvements over the static globals used here.\n\nMy impression was that the goal of the earlier work was to pass the\nindex and repository to each function specifically to avoid tying the\nfunction to a particular index or repository. This helps in cases in\nwhich client code needs to operate on a different index or repository\n(for instance, a submodule). Generally speaking, making the index and\nrepository file-static rather than global does not help reach that\ngoal since functions are still tied to state which is not local to the\nfunction itself.\n\nWould the extra effort be valuable in this particular case? I'm not\nfamiliar with this code, but given that `update-index` is a builtin,\nsuch effort may not be too meaningful. If, however, any of the code\nfrom `buildin/update-index.c` ever gets \"libified\" and moved into the\ncore library, then that would be a good time to update the functions\nto take those values as arguments rather than relying on file-static\nor globals. But that's not something that this series necessarily\nneeds to do; the task can wait until the code needs to be shared by\nother modules, I would think.\n"},{"id":"413371","messageId":"961af585-1b2a-e4e8-d60f-9becbc75b98c@gmail.com","threadId":"54916","inReplyTo":"f3d0ef14-c753-c107-4693-67cec504964a@gmail.com","subject":"Re: [PATCH 01/12] merge-index: drop index compatibility macros","fromName":"Derrick Stolee","fromEmail":"stolee@gmail.com","sentAt":"2021-01-04T11:08:40Z","receivedAt":"2021-01-04T11:09:38Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"On 1/3/2021 6:31 PM, Alban Gruin wrote:\n> Hi Derrick,\n> \n> Le 01/01/2021 à 14:06, Derrick Stolee via GitGitGadget a écrit :\n>> From: Derrick Stolee <dstolee@microsoft.com>\n>>\n>> Replace uses of the old macros for the_index and instead pass around a\n>> 'struct index_state' pointer. This allows dropping the compatibility\n>> flag.\n>>\n>> Signed-off-by: Derrick Stolee <dstolee@microsoft.com>\n> \n> I already libified builtin/merge-index.c in ag/merge-strategies-in-c,\n> and such dropped the_index.  I modified merge_entry(), merge_one_path()\n> and merge_all() to take a callback, itself taking a repository.  As\n> such, in my series, these functions take a `struct repository *' instead\n> of an index state.\n> \n> I'm not sure how we should proceed with our respective patches.\n\nHi Alban,\n\nSorry I didn't realize that. I'll drop this patch. Thanks for letting\nme know!\n\nThanks,\n-Stolee\n"},{"id":"413416","messageId":"d459a931-049d-f445-2fa7-abb03c962c86@gmail.com","threadId":"54916","inReplyTo":"CAPig+cTxCLbfsk4D-_Rd=XF=A4zje1_pETyD9CJRtJNyADb=tg@mail.gmail.com","subject":"Re: [PATCH 00/12] Remove more index compatibility macros","fromName":"Derrick Stolee","fromEmail":"stolee@gmail.com","sentAt":"2021-01-05T04:41:37Z","receivedAt":"2021-01-05T04:42:36Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"On 1/4/2021 1:22 AM, Eric Sunshine wrote:\n> On Sun, Jan 3, 2021 at 8:01 PM Derrick Stolee <stolee@gmail.com> wrote:\n>> On 1/2/2021 1:12 AM, Eric Sunshine wrote:\n>>> This should allow you to get rid of the globals introduced by patch\n>>> [4/12] (assuming passing the index and repo arguments around\n>>> everywhere doesn't get overly hairy).\n>>\n>> Perhaps now that I've removed the compatibility macros, it would be\n>> easier to insert the method parameters since most of the lines that\n>> need to change would be method prototypes and the calls to those methods\n>> (plus the callback function details).\n>>\n>> Is that a valuable effort? I could give it a try, but I want to be sure\n>> that adjusting all of those helper methods in the builtin would indeed\n>> have valuable improvements over the static globals used here.\n> \n> My impression was that the goal of the earlier work was to pass the\n> index and repository to each function specifically to avoid tying the\n> function to a particular index or repository. This helps in cases in\n> which client code needs to operate on a different index or repository\n> (for instance, a submodule). Generally speaking, making the index and\n> repository file-static rather than global does not help reach that\n> goal since functions are still tied to state which is not local to the\n> function itself.\n> \n> Would the extra effort be valuable in this particular case? I'm not\n> familiar with this code, but given that `update-index` is a builtin,\n> such effort may not be too meaningful. If, however, any of the code\n> from `buildin/update-index.c` ever gets \"libified\" and moved into the\n> core library, then that would be a good time to update the functions\n> to take those values as arguments rather than relying on file-static\n> or globals. But that's not something that this series necessarily\n> needs to do; the task can wait until the code needs to be shared by\n> other modules, I would think.\n\nI tried again tonight, and it started getting messy, but then I\nrealized that I could group the callbacks that need the repo and\nindex to use a common struct that holds the other parameters they\nneed. It's still a bigger patch than I'd like, but it is more\nreasonable.\n\nv2 is incoming with my attempt at this.\n\nThanks,\n-Stolee\n\n"},{"id":"413417","messageId":"4bf3c582f9d211769333939f5adfb176c3e42a90.1609821783.git.gitgitgadget@gmail.com","threadId":"54916","inReplyTo":"pull.830.v2.git.1609821783.gitgitgadget@gmail.com","subject":"[PATCH v2 03/14] update-index: drop the_index, the_repository","fromName":"Derrick Stolee via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-01-05T04:42:52Z","receivedAt":"2021-01-05T04:44:06Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"From: Derrick Stolee <dstolee@microsoft.com>\n\nTo reduce the need for the index compatibility macros, we will replace\ntheir uses in update-index mechanically. This is the most interesting\nchange, which creates global \"repo\" and \"istate\" pointers. The macros\nthat expand to use the_index can then be mechanically replaced by\nreferences to the istate pointer.\n\nSigned-off-by: Derrick Stolee <dstolee@microsoft.com>\n---\n builtin/update-index.c | 59 +++++++++++++++++++++++-------------------\n 1 file changed, 32 insertions(+), 27 deletions(-)\n\ndiff --git a/builtin/update-index.c b/builtin/update-index.c\nindex 44862f5e1de..dde5b01a949 100644\n--- a/builtin/update-index.c\n+++ b/builtin/update-index.c\n@@ -40,6 +40,9 @@ static int ignore_skip_worktree_entries;\n #define UNMARK_FLAG 2\n static struct strbuf mtime_dir = STRBUF_INIT;\n \n+static struct repository *repo;\n+static struct index_state *istate;\n+\n /* Untracked cache mode */\n enum uc_mode {\n \tUC_UNSPECIFIED = -1,\n@@ -232,13 +235,13 @@ static int mark_ce_flags(const char *path, int flag, int mark)\n \tint namelen = strlen(path);\n \tint pos = cache_name_pos(path, namelen);\n \tif (0 <= pos) {\n-\t\tmark_fsmonitor_invalid(&the_index, active_cache[pos]);\n+\t\tmark_fsmonitor_invalid(istate, active_cache[pos]);\n \t\tif (mark)\n \t\t\tactive_cache[pos]->ce_flags |= flag;\n \t\telse\n \t\t\tactive_cache[pos]->ce_flags &= ~flag;\n \t\tactive_cache[pos]->ce_flags |= CE_UPDATE_IN_BASE;\n-\t\tcache_tree_invalidate_path(&the_index, path);\n+\t\tcache_tree_invalidate_path(istate, path);\n \t\tactive_cache_changed |= CE_ENTRY_CHANGED;\n \t\treturn 0;\n \t}\n@@ -277,14 +280,14 @@ static int add_one_path(const struct cache_entry *old, const char *path, int len\n \tif (old && !ce_stage(old) && !ce_match_stat(old, st, 0))\n \t\treturn 0;\n \n-\tce = make_empty_cache_entry(&the_index, len);\n+\tce = make_empty_cache_entry(istate, len);\n \tmemcpy(ce->name, path, len);\n \tce->ce_flags = create_ce_flags(0);\n \tce->ce_namelen = len;\n-\tfill_stat_cache_info(&the_index, ce, st);\n+\tfill_stat_cache_info(istate, ce, st);\n \tce->ce_mode = ce_mode_from_stat(old, st->st_mode);\n \n-\tif (index_path(&the_index, &ce->oid, path, st,\n+\tif (index_path(istate, &ce->oid, path, st,\n \t\t       info_only ? 0 : HASH_WRITE_OBJECT)) {\n \t\tdiscard_cache_entry(ce);\n \t\treturn -1;\n@@ -406,7 +409,7 @@ static int add_cacheinfo(unsigned int mode, const struct object_id *oid,\n {\n \tint res;\n \n-\tres = add_to_index_cacheinfo(&the_index, mode, oid, path, stage,\n+\tres = add_to_index_cacheinfo(istate, mode, oid, path, stage,\n \t\t\t\t     allow_add, allow_replace, NULL);\n \tif (res == -1)\n \t\treturn res;\n@@ -592,7 +595,7 @@ static struct cache_entry *read_one_ent(const char *which,\n \tstruct object_id oid;\n \tstruct cache_entry *ce;\n \n-\tif (get_tree_entry(the_repository, ent, path, &oid, &mode)) {\n+\tif (get_tree_entry(repo, ent, path, &oid, &mode)) {\n \t\tif (which)\n \t\t\terror(\"%s: not in %s branch.\", path, which);\n \t\treturn NULL;\n@@ -602,7 +605,7 @@ static struct cache_entry *read_one_ent(const char *which,\n \t\t\terror(\"%s: not a blob in %s branch.\", path, which);\n \t\treturn NULL;\n \t}\n-\tce = make_empty_cache_entry(&the_index, namelen);\n+\tce = make_empty_cache_entry(istate, namelen);\n \n \toidcpy(&ce->oid, &oid);\n \tmemcpy(ce->name, path, namelen);\n@@ -740,7 +743,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(&the_index, ce, &pathspec, NULL))\n+\t\tif (ce_stage(ce) || !ce_path_match(istate, ce, &pathspec, NULL))\n \t\t\tcontinue;\n \t\tif (has_head)\n \t\t\told = read_one_ent(NULL, &head_oid,\n@@ -957,7 +960,6 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \tstruct parse_opt_ctx_t ctx;\n \tstrbuf_getline_fn getline_fn;\n \tint parseopt_state = PARSE_OPT_UNKNOWN;\n-\tstruct repository *r = the_repository;\n \tstruct option options[] = {\n \t\tOPT_BIT('q', NULL, &refresh_args.flags,\n \t\t\tN_(\"continue refresh even when index needs update\"),\n@@ -1066,16 +1068,19 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \n \tgit_config(git_default_config, NULL);\n \n+\trepo = the_repository;\n+\n \t/* we will diagnose later if it turns out that we need to update it */\n-\tnewfd = hold_locked_index(&lock_file, 0);\n+\tnewfd = repo_hold_locked_index(repo, &lock_file, 0);\n \tif (newfd < 0)\n \t\tlock_error = errno;\n \n-\tentries = read_cache();\n+\tentries = repo_read_index(repo);\n \tif (entries < 0)\n \t\tdie(\"cache corrupted\");\n \n-\tthe_index.updated_skipworktree = 1;\n+\tistate = repo->index;\n+\tistate->updated_skipworktree = 1;\n \n \t/*\n \t * Custom copy of parse_options() because we want to handle\n@@ -1129,9 +1134,9 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \t\t\t    preferred_index_format,\n \t\t\t    INDEX_FORMAT_LB, INDEX_FORMAT_UB);\n \n-\t\tif (the_index.version != preferred_index_format)\n+\t\tif (istate->version != preferred_index_format)\n \t\t\tactive_cache_changed |= SOMETHING_CHANGED;\n-\t\tthe_index.version = preferred_index_format;\n+\t\tistate->version = preferred_index_format;\n \t}\n \n \tif (read_from_stdin) {\n@@ -1162,28 +1167,28 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \t\t\twarning(_(\"core.splitIndex is set to false; \"\n \t\t\t\t  \"remove or change it, if you really want to \"\n \t\t\t\t  \"enable split index\"));\n-\t\tif (the_index.split_index)\n-\t\t\tthe_index.cache_changed |= SPLIT_INDEX_ORDERED;\n+\t\tif (istate->split_index)\n+\t\t\tistate->cache_changed |= SPLIT_INDEX_ORDERED;\n \t\telse\n-\t\t\tadd_split_index(&the_index);\n+\t\t\tadd_split_index(istate);\n \t} else if (!split_index) {\n \t\tif (git_config_get_split_index() == 1)\n \t\t\twarning(_(\"core.splitIndex is set to true; \"\n \t\t\t\t  \"remove or change it, if you really want to \"\n \t\t\t\t  \"disable split index\"));\n-\t\tremove_split_index(&the_index);\n+\t\tremove_split_index(istate);\n \t}\n \n-\tprepare_repo_settings(r);\n+\tprepare_repo_settings(repo);\n \tswitch (untracked_cache) {\n \tcase UC_UNSPECIFIED:\n \t\tbreak;\n \tcase UC_DISABLE:\n-\t\tif (r->settings.core_untracked_cache == UNTRACKED_CACHE_WRITE)\n+\t\tif (repo->settings.core_untracked_cache == UNTRACKED_CACHE_WRITE)\n \t\t\twarning(_(\"core.untrackedCache is set to true; \"\n \t\t\t\t  \"remove or change it, if you really want to \"\n \t\t\t\t  \"disable the untracked cache\"));\n-\t\tremove_untracked_cache(&the_index);\n+\t\tremove_untracked_cache(istate);\n \t\treport(_(\"Untracked cache disabled\"));\n \t\tbreak;\n \tcase UC_TEST:\n@@ -1191,11 +1196,11 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \t\treturn !test_if_untracked_cache_is_supported();\n \tcase UC_ENABLE:\n \tcase UC_FORCE:\n-\t\tif (r->settings.core_untracked_cache == UNTRACKED_CACHE_REMOVE)\n+\t\tif (repo->settings.core_untracked_cache == UNTRACKED_CACHE_REMOVE)\n \t\t\twarning(_(\"core.untrackedCache is set to false; \"\n \t\t\t\t  \"remove or change it, if you really want to \"\n \t\t\t\t  \"enable the untracked cache\"));\n-\t\tadd_untracked_cache(&the_index);\n+\t\tadd_untracked_cache(istate);\n \t\treport(_(\"Untracked cache enabled for '%s'\"), get_git_work_tree());\n \t\tbreak;\n \tdefault:\n@@ -1207,14 +1212,14 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \t\t\twarning(_(\"core.fsmonitor is unset; \"\n \t\t\t\t\"set it if you really want to \"\n \t\t\t\t\"enable fsmonitor\"));\n-\t\tadd_fsmonitor(&the_index);\n+\t\tadd_fsmonitor(istate);\n \t\treport(_(\"fsmonitor enabled\"));\n \t} else if (!fsmonitor) {\n \t\tif (git_config_get_fsmonitor() == 1)\n \t\t\twarning(_(\"core.fsmonitor is set; \"\n \t\t\t\t\"remove it if you really want to \"\n \t\t\t\t\"disable fsmonitor\"));\n-\t\tremove_fsmonitor(&the_index);\n+\t\tremove_fsmonitor(istate);\n \t\treport(_(\"fsmonitor disabled\"));\n \t}\n \n@@ -1224,7 +1229,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \t\t\t\texit(128);\n \t\t\tunable_to_lock_die(get_index_file(), lock_error);\n \t\t}\n-\t\tif (write_locked_index(&the_index, &lock_file, COMMIT_LOCK))\n+\t\tif (write_locked_index(istate, &lock_file, COMMIT_LOCK))\n \t\t\tdie(\"Unable to write new index file\");\n \t}\n \n-- \ngitgitgadget\n\n"},{"id":"413418","messageId":"pull.830.v2.git.1609821783.gitgitgadget@gmail.com","threadId":"54916","inReplyTo":"pull.830.git.1609506428.gitgitgadget@gmail.com","subject":"[PATCH v2 00/14] Remove more index compatibility macros","fromName":"Derrick Stolee via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-01-05T04:42:49Z","receivedAt":"2021-01-05T04:44:06Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"UPDATE: this is now based on ag/merge-strategies-in-c to avoid conflicts in\n'seen'. The changes in builtin/rm.c still conflict with\nmt/rm-sparse-checkout, but that branch seems to be waiting for a clearer\nplan on some corner cases. I thought about ejecting it, but 'rm' still uses\nce_match_stat(), so just dropping the patch gives less of a final stake at\nthe end of the series. (I'm still open to it, if necessary.)\n\nI noticed that Duy's project around USE_THE_INDEX_COMPATIBILITY_MACROS has\nbeen on pause for a while. Here is my attempt to continue that project a\nlittle.\n\nI started going through the builtins that still use cache_name_pos() and the\nfirst was easy: mv and rm.\n\nThen I hit update-index and it was a bit bigger.\n\nMy strategy for update-index was to create static globals \"repo\" and\n\"istate\" that point to the_repository and the_index, respectively. Then, I\nwas able to remove macros one-by-one without changing method prototypes\nwithin the file. Then, these static globals were also removed by\nsystematically updating the local method prototypes, plus some fancy\nstructure stuff for the option parsing callbacks.\n\nI had started trying to keep everything local to the method signatures, but\nI hit a snag when reaching the command-line parsing callbacks, which I could\nnot modify their call signature. At that point, I had something that was\nalready much more complicated than what I present now. Outside of the first\nupdate-index commit, everything was a mechanical find/replace.\n\nIn total, this allows us to remove four of the compatibility macros because\nthey are no longer used.\n\n\nUpdates in V2\n=============\n\n * newly based on ag/merge-strategies-in-c, as there were some interesting\n   conflicts in buitin/update-index.c.\n\n * Patch to update builtin/merge-index.c was dropped as that is already\n   handled in ag/merge-strategies-in-c\n\n * I added patches that remove the static globals that I injected to make\n   the compatibility macros easy to delete. I do this in three parts.\n\n * Commit messages improved.\n\nThanks, -Stolee\n\nDerrick Stolee (14):\n  mv: remove index compatibility macros\n  rm: remove compatilibity macros\n  update-index: drop the_index, the_repository\n  update-index: use istate->cache over active_cache\n  update-index: use index->cache_nr over active_nr\n  update-index: use istate->cache_changed\n  update-index: use index_name_pos() over cache_name_pos()\n  update-index: use remove_file_from_index()\n  update-index: use add_index_entry()\n  update-index: replace several compatibility macros\n  update-index: remove ce_match_stat(), all macros\n  update-index: reduce static globals, part 1\n  update-index: reduce static globals, part 2\n  update-index: remove static globals from callbacks\n\n Documentation/technical/racy-git.txt |   6 +-\n builtin/mv.c                         |  42 ++--\n builtin/rm.c                         |  56 ++---\n builtin/update-index.c               | 320 +++++++++++++++------------\n cache.h                              |   4 -\n 5 files changed, 233 insertions(+), 195 deletions(-)\n\n\nbase-commit: 3da8920d38a007157ccf8e53382e5206b909dafe\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-830%2Fderrickstolee%2Findex-compatibility-1-v2\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-830/derrickstolee/index-compatibility-1-v2\nPull-Request: https://github.com/gitgitgadget/git/pull/830\n\nRange-diff vs v1:\n\n  2:  84330533d4f =  1:  5ccc464cf26 mv: remove index compatibility macros\n  3:  54e167d5872 =  2:  e715c703cb8 rm: remove compatilibity macros\n  4:  77f6510bb68 !  3:  4bf3c582f9d update-index: drop the_index, the_repository\n     @@ Commit message\n          To reduce the need for the index compatibility macros, we will replace\n          their uses in update-index mechanically. This is the most interesting\n          change, which creates global \"repo\" and \"istate\" pointers. The macros\n     -    can then be mechanically replaced by instances that use the istate\n     -    pointer instead of the version that autocompletes to use the_index.\n     +    that expand to use the_index can then be mechanically replaced by\n     +    references to the istate pointer.\n      \n          Signed-off-by: Derrick Stolee <dstolee@microsoft.com>\n      \n     @@ builtin/update-index.c: static int add_one_path(const struct cache_entry *old, c\n       \t\tdiscard_cache_entry(ce);\n       \t\treturn -1;\n      @@ builtin/update-index.c: static int add_cacheinfo(unsigned int mode, const struct object_id *oid,\n     - \t\treturn error(\"Invalid path '%s'\", path);\n     - \n     - \tlen = strlen(path);\n     --\tce = make_empty_cache_entry(&the_index, len);\n     -+\tce = make_empty_cache_entry(istate, len);\n     - \n     - \toidcpy(&ce->oid, oid);\n     - \tmemcpy(ce->name, path, len);\n     + {\n     + \tint res;\n     + \n     +-\tres = add_to_index_cacheinfo(&the_index, mode, oid, path, stage,\n     ++\tres = add_to_index_cacheinfo(istate, mode, oid, path, stage,\n     + \t\t\t\t     allow_add, allow_replace, NULL);\n     + \tif (res == -1)\n     + \t\treturn res;\n      @@ builtin/update-index.c: static struct cache_entry *read_one_ent(const char *which,\n       \tstruct object_id oid;\n       \tstruct cache_entry *ce;\n  5:  cc5df3566df =  4:  4b509ba5fa2 update-index: use istate->cache over active_cache\n  6:  e99b8bddb3a =  5:  6c0e019f91c update-index: use index->cache_nr over active_nr\n  7:  f841500c663 =  6:  5091e2661d1 update-index: use istate->cache_changed\n  8:  d2af7e21ca1 =  7:  5b14fa10a4b update-index: use index_name_pos() over cache_name_pos()\n  9:  c576e2d9676 =  8:  a1a9fb01b07 update-index: use remove_file_from_index()\n 10:  cf091799cae !  9:  620e300ad6b update-index: use add_index_entry()\n     @@ builtin/update-index.c: static int add_one_path(const struct cache_entry *old, c\n       \t\tdiscard_cache_entry(ce);\n       \t\treturn error(\"%s: cannot add to the index - missing --add option?\", path);\n       \t}\n     -@@ builtin/update-index.c: static int add_cacheinfo(unsigned int mode, const struct object_id *oid,\n     - \t\tce->ce_flags |= CE_VALID;\n     - \toption = allow_add ? ADD_CACHE_OK_TO_ADD : 0;\n     - \toption |= allow_replace ? ADD_CACHE_OK_TO_REPLACE : 0;\n     --\tif (add_cache_entry(ce, option))\n     -+\tif (add_index_entry(istate, ce, option))\n     - \t\treturn error(\"%s: cannot add to the index - missing --add option?\",\n     - \t\t\t     path);\n     - \treport(\"add '%s'\", path);\n      @@ builtin/update-index.c: static int unresolve_one(const char *path)\n       \t}\n       \n 11:  d7856e2e772 = 10:  68b26a11d77 update-index: replace several compatibility macros\n 12:  8fb307c3bee ! 11:  f1cffe2b455 update-index: remove ce_match_stat(), all macros\n     @@ Commit message\n          update-index: remove ce_match_stat(), all macros\n      \n          The final index compatibility macro to remove from the update-index\n     -    builtin is ce_match_state(). Further, this is the last use of that macro\n     +    builtin is ce_match_stat(). Further, this is the last use of that macro\n          anywhere, so it should be removed.\n      \n          There are some remaining references in the racy-git.txt technical\n  -:  ----------- > 12:  79e267f39ec update-index: reduce static globals, part 1\n  1:  68d88b651c7 ! 13:  457402b4fdc merge-index: drop index compatibility macros\n     @@ Metadata\n      Author: Derrick Stolee <dstolee@microsoft.com>\n      \n       ## Commit message ##\n     -    merge-index: drop index compatibility macros\n     +    update-index: reduce static globals, part 2\n      \n     -    Replace uses of the old macros for the_index and instead pass around a\n     -    'struct index_state' pointer. This allows dropping the compatibility\n     -    flag.\n     +    In order to remove index compatibility macros cleanly, we relied upon\n     +    static globals 'repo' and 'istate' to be pointers to the_repository and\n     +    the_index, respectively. We can continue reducing the need for these\n     +    static globals by modifying method prototypes to use them when\n     +    necessary.\n     +\n     +    Move these static globals further down the file so we can identify which\n     +    methods need both 'struct repository *repo' and 'struct index_state\n     +    *istate' parameters. The only changes included here adjust method\n     +    prototypes and their call locations.\n     +\n     +    The only remaining change is to remove the static globals entirely, but\n     +    that requires updating the parse-opt callbacks, which need a different\n     +    solution.\n      \n          Signed-off-by: Derrick Stolee <dstolee@microsoft.com>\n      \n     - ## builtin/merge-index.c ##\n     -@@\n     --#define USE_THE_INDEX_COMPATIBILITY_MACROS\n     - #include \"builtin.h\"\n     - #include \"run-command.h\"\n     + ## builtin/update-index.c ##\n     +@@ builtin/update-index.c: static const char * const update_index_usage[] = {\n     + static struct object_id head_oid;\n     + static struct object_id merge_head_oid;\n       \n     -@@ builtin/merge-index.c: static const char *pgm;\n     - static int one_shot, quiet;\n     - static int err;\n     - \n     --static int merge_entry(int pos, const char *path)\n     -+static int merge_entry(struct index_state *istate,\n     -+\t\t       int pos, const char *path)\n     +-static struct repository *repo;\n     +-static struct index_state *istate;\n     +-\n     +-static struct cache_entry *read_one_ent(const char *which,\n     ++static struct cache_entry *read_one_ent(struct repository *repo,\n     ++\t\t\t\t\tstruct index_state *istate,\n     ++\t\t\t\t\tconst char *which,\n     + \t\t\t\t\tstruct object_id *ent, const char *path,\n     + \t\t\t\t\tint namelen, int stage)\n       {\n     - \tint found;\n     - \tconst char *arguments[] = { pgm, \"\", \"\", \"\", path, \"\", \"\", \"\", NULL };\n     - \tchar hexbuf[4][GIT_MAX_HEXSZ + 1];\n     - \tchar ownbuf[4][60];\n     - \n     --\tif (pos >= active_nr)\n     -+\tif (pos >= istate->cache_nr)\n     - \t\tdie(\"git merge-index: %s not in the cache\", path);\n     - \tfound = 0;\n     - \tdo {\n     --\t\tconst struct cache_entry *ce = active_cache[pos];\n     -+\t\tconst struct cache_entry *ce = istate->cache[pos];\n     - \t\tint stage = ce_stage(ce);\n     - \n     - \t\tif (strcmp(ce->name, path))\n     -@@ builtin/merge-index.c: static int merge_entry(int pos, const char *path)\n     - \t\txsnprintf(ownbuf[stage], sizeof(ownbuf[stage]), \"%o\", ce->ce_mode);\n     - \t\targuments[stage] = hexbuf[stage];\n     - \t\targuments[stage + 4] = ownbuf[stage];\n     --\t} while (++pos < active_nr);\n     -+\t} while (++pos < istate->cache_nr);\n     - \tif (!found)\n     - \t\tdie(\"git merge-index: %s not in the cache\", path);\n     - \n     -@@ builtin/merge-index.c: static int merge_entry(int pos, const char *path)\n     - \treturn found;\n     +@@ builtin/update-index.c: static struct cache_entry *read_one_ent(const char *which,\n     + \treturn ce;\n       }\n       \n     --static void merge_one_path(const char *path)\n     -+static void merge_one_path(struct index_state *istate,\n     -+\t\t\t   const char *path)\n     +-static int unresolve_one(const char *path)\n     ++static int unresolve_one(struct repository *repo,\n     ++\t\t\t struct index_state *istate,\n     ++\t\t\t const char *path)\n       {\n     --\tint pos = cache_name_pos(path, strlen(path));\n     -+\tint pos = index_name_pos(istate, path, strlen(path));\n     - \n     - \t/*\n     - \t * If it already exists in the cache as stage0, it's\n     - \t * already merged and there is nothing to do.\n     + \tint namelen = strlen(path);\n     + \tint pos;\n     +@@ builtin/update-index.c: static int unresolve_one(const char *path)\n     + \t * stuff HEAD version in stage #2,\n     + \t * stuff MERGE_HEAD version in stage #3.\n       \t */\n     - \tif (pos < 0)\n     --\t\tmerge_entry(-pos-1, path);\n     -+\t\tmerge_entry(istate, -pos - 1, path);\n     +-\tce_2 = read_one_ent(\"our\", &head_oid, path, namelen, 2);\n     +-\tce_3 = read_one_ent(\"their\", &merge_head_oid, path, namelen, 3);\n     ++\tce_2 = read_one_ent(repo, istate, \"our\", &head_oid, path, namelen, 2);\n     ++\tce_3 = read_one_ent(repo, istate, \"their\", &merge_head_oid, path, namelen, 3);\n     + \n     + \tif (!ce_2 || !ce_3) {\n     + \t\tret = -1;\n     +@@ builtin/update-index.c: static void read_head_pointers(void)\n     + \t}\n       }\n       \n     --static void merge_all(void)\n     -+static void merge_all(struct index_state *istate)\n     +-static int do_unresolve(int ac, const char **av,\n     ++static int do_unresolve(struct repository *repo,\n     ++\t\t\tstruct index_state *istate,\n     ++\t\t\tint ac, const char **av,\n     + \t\t\tconst char *prefix, int prefix_length)\n       {\n       \tint i;\n     --\tfor (i = 0; i < active_nr; i++) {\n     --\t\tconst struct cache_entry *ce = active_cache[i];\n     -+\tfor (i = 0; i < istate->cache_nr; i++) {\n     -+\t\tconst struct cache_entry *ce = istate->cache[i];\n     - \t\tif (!ce_stage(ce))\n     - \t\t\tcontinue;\n     --\t\ti += merge_entry(i, ce->name)-1;\n     -+\t\ti += merge_entry(istate, i, ce->name)-1;\n     +@@ builtin/update-index.c: static int do_unresolve(int ac, const char **av,\n     + \tfor (i = 1; i < ac; i++) {\n     + \t\tconst char *arg = av[i];\n     + \t\tchar *p = prefix_path(prefix, prefix_length, arg);\n     +-\t\terr |= unresolve_one(p);\n     ++\t\terr |= unresolve_one(repo, istate, p);\n     + \t\tfree(p);\n       \t}\n     + \treturn err;\n       }\n       \n     - int cmd_merge_index(int argc, const char **argv, const char *prefix)\n     +-static int do_reupdate(int ac, const char **av,\n     ++static int do_reupdate(struct repository *repo,\n     ++\t\t       struct index_state *istate,\n     ++\t\t       int ac, const char **av,\n     + \t\t       const char *prefix)\n       {\n     - \tint i, force_file = 0;\n     -+\tstruct index_state *istate;\n     + \t/* Read HEAD and run update-index on paths that are\n     +@@ builtin/update-index.c: static int do_reupdate(int ac, const char **av,\n     + \t\tif (ce_stage(ce) || !ce_path_match(istate, ce, &pathspec, NULL))\n     + \t\t\tcontinue;\n     + \t\tif (has_head)\n     +-\t\t\told = read_one_ent(NULL, &head_oid,\n     ++\t\t\told = read_one_ent(repo, istate, NULL, &head_oid,\n     + \t\t\t\t\t   ce->name, ce_namelen(ce), 0);\n     + \t\tif (old && ce->ce_mode == old->ce_mode &&\n     + \t\t    oideq(&ce->oid, &old->oid)) {\n     +@@ builtin/update-index.c: struct refresh_params {\n     + \tint *has_errors;\n     + };\n       \n     - \t/* Without this we cannot rely on waitpid() to tell\n     - \t * what happened to our children.\n     -@@ builtin/merge-index.c: int cmd_merge_index(int argc, const char **argv, const char *prefix)\n     - \tif (argc < 3)\n     - \t\tusage(\"git merge-index [-o] [-q] <merge-program> (-a | [--] [<filename>...])\");\n     ++static struct repository *repo;\n     ++static struct index_state *istate;\n     ++\n     + static int refresh(struct refresh_params *o, unsigned int flag)\n     + {\n     + \tsetup_work_tree();\n     +@@ builtin/update-index.c: static enum parse_opt_result unresolve_callback(\n     + \tBUG_ON_OPT_ARG(arg);\n       \n     --\tread_cache();\n     -+\trepo_read_index(the_repository);\n     -+\tistate = the_repository->index;\n     + \t/* consume remaining arguments. */\n     +-\t*has_errors = do_unresolve(ctx->argc, ctx->argv,\n     +-\t\t\t\tprefix, prefix ? strlen(prefix) : 0);\n     ++\t*has_errors = do_unresolve(repo, istate, ctx->argc, ctx->argv,\n     ++\t\t\t\t   prefix, prefix ? strlen(prefix) : 0);\n     + \tif (*has_errors)\n     + \t\tistate->cache_changed = 0;\n     + \n     +@@ builtin/update-index.c: static enum parse_opt_result reupdate_callback(\n     + \n     + \t/* consume remaining arguments. */\n     + \tsetup_work_tree();\n     +-\t*has_errors = do_reupdate(ctx->argc, ctx->argv, prefix);\n     ++\t*has_errors = do_reupdate(repo, istate, ctx->argc, ctx->argv, prefix);\n     + \tif (*has_errors)\n     + \t\tistate->cache_changed = 0;\n       \n     - \ti = 1;\n     - \tif (!strcmp(argv[i], \"-o\")) {\n     -@@ builtin/merge-index.c: int cmd_merge_index(int argc, const char **argv, const char *prefix)\n     - \t\t\t\tcontinue;\n     - \t\t\t}\n     - \t\t\tif (!strcmp(arg, \"-a\")) {\n     --\t\t\t\tmerge_all();\n     -+\t\t\t\tmerge_all(istate);\n     - \t\t\t\tcontinue;\n     - \t\t\t}\n     - \t\t\tdie(\"git merge-index: unknown option %s\", arg);\n     - \t\t}\n     --\t\tmerge_one_path(arg);\n     -+\t\tmerge_one_path(istate, arg);\n     - \t}\n     - \tif (err && !quiet)\n     - \t\tdie(\"merge program failed\");\n  -:  ----------- > 14:  2b171a142b3 update-index: remove static globals from callbacks\n\n-- \ngitgitgadget\n"},{"id":"413419","messageId":"e715c703cb88d9a153e2925ae24c31b5bf5957ec.1609821783.git.gitgitgadget@gmail.com","threadId":"54916","inReplyTo":"pull.830.v2.git.1609821783.gitgitgadget@gmail.com","subject":"[PATCH v2 02/14] rm: remove compatilibity macros","fromName":"Derrick Stolee via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-01-05T04:42:51Z","receivedAt":"2021-01-05T04:44:06Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"From: Derrick Stolee <dstolee@microsoft.com>\n\nThe rm builtin still uses the antiquated compatibility macros for\ninteracting with the index. Update these to the more modern uses by\npassing around a 'struct index_state' pointer.\n\nSigned-off-by: Derrick Stolee <dstolee@microsoft.com>\n---\n builtin/rm.c | 56 ++++++++++++++++++++++++++++------------------------\n 1 file changed, 30 insertions(+), 26 deletions(-)\n\ndiff --git a/builtin/rm.c b/builtin/rm.c\nindex 4858631e0f0..767df8d6b25 100644\n--- a/builtin/rm.c\n+++ b/builtin/rm.c\n@@ -3,7 +3,6 @@\n  *\n  * Copyright (C) Linus Torvalds 2006\n  */\n-#define USE_THE_INDEX_COMPATIBILITY_MACROS\n #include \"builtin.h\"\n #include \"config.h\"\n #include \"lockfile.h\"\n@@ -28,12 +27,14 @@ static struct {\n \t} *entry;\n } list;\n \n-static int get_ours_cache_pos(const char *path, int pos)\n+static int get_ours_cache_pos(struct index_state *istate,\n+\t\t\t      const char *path, int pos)\n {\n \tint i = -pos - 1;\n \n-\twhile ((i < active_nr) && !strcmp(active_cache[i]->name, path)) {\n-\t\tif (ce_stage(active_cache[i]) == 2)\n+\twhile ((i < istate->cache_nr) &&\n+\t       !strcmp(istate->cache[i]->name, path)) {\n+\t\tif (ce_stage(istate->cache[i]) == 2)\n \t\t\treturn i;\n \t\ti++;\n \t}\n@@ -61,7 +62,7 @@ static void print_error_files(struct string_list *files_list,\n \t}\n }\n \n-static void submodules_absorb_gitdir_if_needed(void)\n+static void submodules_absorb_gitdir_if_needed(struct index_state *istate)\n {\n \tint i;\n \tfor (i = 0; i < list.nr; i++) {\n@@ -69,13 +70,13 @@ static void submodules_absorb_gitdir_if_needed(void)\n \t\tint pos;\n \t\tconst struct cache_entry *ce;\n \n-\t\tpos = cache_name_pos(name, strlen(name));\n+\t\tpos = index_name_pos(istate, name, strlen(name));\n \t\tif (pos < 0) {\n-\t\t\tpos = get_ours_cache_pos(name, pos);\n+\t\t\tpos = get_ours_cache_pos(istate, name, pos);\n \t\t\tif (pos < 0)\n \t\t\t\tcontinue;\n \t\t}\n-\t\tce = active_cache[pos];\n+\t\tce = istate->cache[pos];\n \n \t\tif (!S_ISGITLINK(ce->ce_mode) ||\n \t\t    !file_exists(ce->name) ||\n@@ -88,7 +89,8 @@ static void submodules_absorb_gitdir_if_needed(void)\n \t}\n }\n \n-static int check_local_mod(struct object_id *head, int index_only)\n+static int check_local_mod(struct index_state *istate,\n+\t\t\t   struct object_id *head, int index_only)\n {\n \t/*\n \t * Items in list are already sorted in the cache order,\n@@ -114,21 +116,21 @@ static int check_local_mod(struct object_id *head, int index_only)\n \t\tint local_changes = 0;\n \t\tint staged_changes = 0;\n \n-\t\tpos = cache_name_pos(name, strlen(name));\n+\t\tpos = index_name_pos(istate, name, strlen(name));\n \t\tif (pos < 0) {\n \t\t\t/*\n \t\t\t * Skip unmerged entries except for populated submodules\n \t\t\t * that could lose history when removed.\n \t\t\t */\n-\t\t\tpos = get_ours_cache_pos(name, pos);\n+\t\t\tpos = get_ours_cache_pos(istate, name, pos);\n \t\t\tif (pos < 0)\n \t\t\t\tcontinue;\n \n-\t\t\tif (!S_ISGITLINK(active_cache[pos]->ce_mode) ||\n+\t\t\tif (!S_ISGITLINK(istate->cache[pos]->ce_mode) ||\n \t\t\t    is_empty_dir(name))\n \t\t\t\tcontinue;\n \t\t}\n-\t\tce = active_cache[pos];\n+\t\tce = istate->cache[pos];\n \n \t\tif (lstat(ce->name, &st) < 0) {\n \t\t\tif (!is_missing_file_error(errno))\n@@ -165,7 +167,7 @@ static int check_local_mod(struct object_id *head, int index_only)\n \t\t * Is the index different from the file in the work tree?\n \t\t * If it's a submodule, is its work tree modified?\n \t\t */\n-\t\tif (ce_match_stat(ce, &st, 0) ||\n+\t\tif (ie_match_stat(istate, ce, &st, 0) ||\n \t\t    (S_ISGITLINK(ce->ce_mode) &&\n \t\t     bad_to_remove_submodule(ce->name,\n \t\t\t\tSUBMODULE_REMOVAL_DIE_ON_ERROR |\n@@ -257,6 +259,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix)\n \tint i;\n \tstruct pathspec pathspec;\n \tchar *seen;\n+\tstruct index_state *istate;\n \n \tgit_config(git_default_config, NULL);\n \n@@ -284,24 +287,25 @@ int cmd_rm(int argc, const char **argv, const char *prefix)\n \tif (!index_only)\n \t\tsetup_work_tree();\n \n-\thold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);\n+\trepo_hold_locked_index(the_repository, &lock_file, LOCK_DIE_ON_ERROR);\n \n-\tif (read_cache() < 0)\n+\tif (repo_read_index(the_repository) < 0)\n \t\tdie(_(\"index file corrupt\"));\n \n-\trefresh_index(&the_index, REFRESH_QUIET|REFRESH_UNMERGED, &pathspec, NULL, NULL);\n+\tistate = the_repository->index;\n+\trefresh_index(istate, REFRESH_QUIET|REFRESH_UNMERGED, &pathspec, NULL, NULL);\n \n \tseen = xcalloc(pathspec.nr, 1);\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(&the_index, ce, &pathspec, seen))\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(istate, 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);\n \t\tlist.entry[list.nr].is_submodule = S_ISGITLINK(ce->ce_mode);\n \t\tif (list.entry[list.nr++].is_submodule &&\n-\t\t    !is_staging_gitmodules_ok(&the_index))\n+\t\t    !is_staging_gitmodules_ok(istate))\n \t\t\tdie(_(\"please stage your changes to .gitmodules or stash them to proceed\"));\n \t}\n \n@@ -329,7 +333,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix)\n \t}\n \n \tif (!index_only)\n-\t\tsubmodules_absorb_gitdir_if_needed();\n+\t\tsubmodules_absorb_gitdir_if_needed(istate);\n \n \t/*\n \t * If not forced, the file, the index and the HEAD (if exists)\n@@ -345,7 +349,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix)\n \t\tstruct object_id oid;\n \t\tif (get_oid(\"HEAD\", &oid))\n \t\t\toidclr(&oid);\n-\t\tif (check_local_mod(&oid, index_only))\n+\t\tif (check_local_mod(istate, &oid, index_only))\n \t\t\texit(1);\n \t}\n \n@@ -358,7 +362,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix)\n \t\tif (!quiet)\n \t\t\tprintf(\"rm '%s'\\n\", path);\n \n-\t\tif (remove_file_from_cache(path))\n+\t\tif (remove_file_from_index(istate, path))\n \t\t\tdie(_(\"git rm: unable to remove %s\"), path);\n \t}\n \n@@ -398,10 +402,10 @@ int cmd_rm(int argc, const char **argv, const char *prefix)\n \t\t}\n \t\tstrbuf_release(&buf);\n \t\tif (gitmodules_modified)\n-\t\t\tstage_updated_gitmodules(&the_index);\n+\t\t\tstage_updated_gitmodules(istate);\n \t}\n \n-\tif (write_locked_index(&the_index, &lock_file,\n+\tif (write_locked_index(istate, &lock_file,\n \t\t\t       COMMIT_LOCK | SKIP_IF_UNCHANGED))\n \t\tdie(_(\"Unable to write new index file\"));\n \n-- \ngitgitgadget\n\n"},{"id":"413420","messageId":"5ccc464cf268476932197c790693e1ecea9e778c.1609821783.git.gitgitgadget@gmail.com","threadId":"54916","inReplyTo":"pull.830.v2.git.1609821783.gitgitgadget@gmail.com","subject":"[PATCH v2 01/14] mv: remove index compatibility macros","fromName":"Derrick Stolee via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-01-05T04:42:50Z","receivedAt":"2021-01-05T04:44:06Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"From: Derrick Stolee <dstolee@microsoft.com>\n\nThe mv builtin uses the compatibility macros to interact with the index.\nUpdate these to use modern methods referring to a 'struct index_state'\npointer. Several helper methods need to be updated to consider such a\npointer, but the modifications are rudimentary.\n\nTwo macros can be deleted from cache.h because these are the last uses.\n\nSigned-off-by: Derrick Stolee <dstolee@microsoft.com>\n---\n builtin/mv.c | 42 +++++++++++++++++++++++-------------------\n cache.h      |  2 --\n 2 files changed, 23 insertions(+), 21 deletions(-)\n\ndiff --git a/builtin/mv.c b/builtin/mv.c\nindex 7dac714af90..0055d49a8a7 100644\n--- a/builtin/mv.c\n+++ b/builtin/mv.c\n@@ -3,7 +3,6 @@\n  *\n  * Copyright (C) 2006 Johannes Schindelin\n  */\n-#define USE_THE_INDEX_COMPATIBILITY_MACROS\n #include \"builtin.h\"\n #include \"config.h\"\n #include \"pathspec.h\"\n@@ -75,13 +74,14 @@ static const char *add_slash(const char *path)\n \n #define SUBMODULE_WITH_GITDIR ((const char *)1)\n \n-static void prepare_move_submodule(const char *src, int first,\n+static void prepare_move_submodule(struct index_state *istate,\n+\t\t\t\t   const char *src, int first,\n \t\t\t\t   const char **submodule_gitfile)\n {\n \tstruct strbuf submodule_dotgit = STRBUF_INIT;\n-\tif (!S_ISGITLINK(active_cache[first]->ce_mode))\n+\tif (!S_ISGITLINK(istate->cache[first]->ce_mode))\n \t\tdie(_(\"Directory %s is in index and no submodule?\"), src);\n-\tif (!is_staging_gitmodules_ok(&the_index))\n+\tif (!is_staging_gitmodules_ok(istate))\n \t\tdie(_(\"Please stage your changes to .gitmodules or stash them to proceed\"));\n \tstrbuf_addf(&submodule_dotgit, \"%s/.git\", src);\n \t*submodule_gitfile = read_gitfile(submodule_dotgit.buf);\n@@ -92,19 +92,20 @@ static void prepare_move_submodule(const char *src, int first,\n \tstrbuf_release(&submodule_dotgit);\n }\n \n-static int index_range_of_same_dir(const char *src, int length,\n+static int index_range_of_same_dir(struct index_state *istate,\n+\t\t\t\t   const char *src, int length,\n \t\t\t\t   int *first_p, int *last_p)\n {\n \tconst char *src_w_slash = add_slash(src);\n \tint first, last, len_w_slash = length + 1;\n \n-\tfirst = cache_name_pos(src_w_slash, len_w_slash);\n+\tfirst = index_name_pos(istate, src_w_slash, len_w_slash);\n \tif (first >= 0)\n \t\tdie(_(\"%.*s is in index\"), len_w_slash, src_w_slash);\n \n \tfirst = -1 - first;\n-\tfor (last = first; last < active_nr; last++) {\n-\t\tconst char *path = active_cache[last]->name;\n+\tfor (last = first; last < istate->cache_nr; last++) {\n+\t\tconst char *path = istate->cache[last]->name;\n \t\tif (strncmp(path, src_w_slash, len_w_slash))\n \t\t\tbreak;\n \t}\n@@ -133,6 +134,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix)\n \tstruct string_list src_for_dst = STRING_LIST_INIT_NODUP;\n \tstruct lock_file lock_file = LOCK_INIT;\n \tstruct cache_entry *ce;\n+\tstruct index_state *istate;\n \n \tgit_config(git_default_config, NULL);\n \n@@ -141,9 +143,10 @@ int cmd_mv(int argc, const char **argv, const char *prefix)\n \tif (--argc < 1)\n \t\tusage_with_options(builtin_mv_usage, builtin_mv_options);\n \n-\thold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);\n-\tif (read_cache() < 0)\n+\trepo_hold_locked_index(the_repository, &lock_file, LOCK_DIE_ON_ERROR);\n+\tif (repo_read_index(the_repository) < 0)\n \t\tdie(_(\"index file corrupt\"));\n+\tistate = the_repository->index;\n \n \tsource = internal_prefix_pathspec(prefix, argv, argc, 0);\n \tmodes = xcalloc(argc, sizeof(enum update_mode));\n@@ -190,12 +193,13 @@ int cmd_mv(int argc, const char **argv, const char *prefix)\n \t\t\t\t&& lstat(dst, &st) == 0)\n \t\t\tbad = _(\"cannot move directory over file\");\n \t\telse if (src_is_dir) {\n-\t\t\tint first = cache_name_pos(src, length), last;\n+\t\t\tint first = index_name_pos(istate, src, length);\n+\t\t\tint last;\n \n \t\t\tif (first >= 0)\n-\t\t\t\tprepare_move_submodule(src, first,\n+\t\t\t\tprepare_move_submodule(istate, src, first,\n \t\t\t\t\t\t       submodule_gitfile + i);\n-\t\t\telse if (index_range_of_same_dir(src, length,\n+\t\t\telse if (index_range_of_same_dir(istate, src, length,\n \t\t\t\t\t\t\t &first, &last) < 1)\n \t\t\t\tbad = _(\"source directory is empty\");\n \t\t\telse { /* last - first >= 1 */\n@@ -212,7 +216,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix)\n \t\t\t\tdst_len = strlen(dst);\n \n \t\t\t\tfor (j = 0; j < last - first; j++) {\n-\t\t\t\t\tconst char *path = active_cache[first + j]->name;\n+\t\t\t\t\tconst char *path = istate->cache[first + j]->name;\n \t\t\t\t\tsource[argc + j] = path;\n \t\t\t\t\tdestination[argc + j] =\n \t\t\t\t\t\tprefix_path(dst, dst_len, path + length + 1);\n@@ -221,7 +225,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix)\n \t\t\t\t}\n \t\t\t\targc += last - first;\n \t\t\t}\n-\t\t} else if (!(ce = cache_file_exists(src, length, ignore_case))) {\n+\t\t} else if (!(ce = index_file_exists(istate, src, length, ignore_case))) {\n \t\t\tbad = _(\"not under version control\");\n \t\t} else if (ce_stage(ce)) {\n \t\t\tbad = _(\"conflicted\");\n@@ -291,15 +295,15 @@ int cmd_mv(int argc, const char **argv, const char *prefix)\n \t\tif (mode == WORKING_DIRECTORY)\n \t\t\tcontinue;\n \n-\t\tpos = cache_name_pos(src, strlen(src));\n+\t\tpos = index_name_pos(istate, src, strlen(src));\n \t\tassert(pos >= 0);\n-\t\trename_cache_entry_at(pos, dst);\n+\t\trename_index_entry_at(istate, pos, dst);\n \t}\n \n \tif (gitmodules_modified)\n-\t\tstage_updated_gitmodules(&the_index);\n+\t\tstage_updated_gitmodules(istate);\n \n-\tif (write_locked_index(&the_index, &lock_file,\n+\tif (write_locked_index(istate, &lock_file,\n \t\t\t       COMMIT_LOCK | SKIP_IF_UNCHANGED))\n \t\tdie(_(\"Unable to write new index file\"));\n \ndiff --git a/cache.h b/cache.h\nindex 2d844576ead..fdf061cac56 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -409,7 +409,6 @@ extern struct index_state the_index;\n #define unmerged_cache() unmerged_index(&the_index)\n #define cache_name_pos(name, namelen) index_name_pos(&the_index,(name),(namelen))\n #define add_cache_entry(ce, option) add_index_entry(&the_index, (ce), (option))\n-#define rename_cache_entry_at(pos, new_name) rename_index_entry_at(&the_index, (pos), (new_name))\n #define remove_cache_entry_at(pos) remove_index_entry_at(&the_index, (pos))\n #define remove_file_from_cache(path) remove_file_from_index(&the_index, (path))\n #define add_to_cache(path, st, flags) add_to_index(&the_index, (path), (st), (flags))\n@@ -420,7 +419,6 @@ extern struct index_state the_index;\n #define ce_match_stat(ce, st, options) ie_match_stat(&the_index, (ce), (st), (options))\n #define ce_modified(ce, st, options) ie_modified(&the_index, (ce), (st), (options))\n #define cache_dir_exists(name, namelen) index_dir_exists(&the_index, (name), (namelen))\n-#define cache_file_exists(name, namelen, igncase) index_file_exists(&the_index, (name), (namelen), (igncase))\n #define cache_name_is_other(name, namelen) index_name_is_other(&the_index, (name), (namelen))\n #define resolve_undo_clear() resolve_undo_clear_index(&the_index)\n #define unmerge_cache_entry_at(at) unmerge_index_entry_at(&the_index, at)\n-- \ngitgitgadget\n\n"},{"id":"413421","messageId":"4b509ba5fa283d29c320e39a9225fadf966e53a8.1609821783.git.gitgitgadget@gmail.com","threadId":"54916","inReplyTo":"pull.830.v2.git.1609821783.gitgitgadget@gmail.com","subject":"[PATCH v2 04/14] update-index: use istate->cache over active_cache","fromName":"Derrick Stolee via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-01-05T04:42:53Z","receivedAt":"2021-01-05T04:44:17Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"From: Derrick Stolee <dstolee@microsoft.com>\n\nSigned-off-by: Derrick Stolee <dstolee@microsoft.com>\n---\n builtin/update-index.c | 22 +++++++++++-----------\n 1 file changed, 11 insertions(+), 11 deletions(-)\n\ndiff --git a/builtin/update-index.c b/builtin/update-index.c\nindex dde5b01a949..3e459d2b9de 100644\n--- a/builtin/update-index.c\n+++ b/builtin/update-index.c\n@@ -235,12 +235,12 @@ static int mark_ce_flags(const char *path, int flag, int mark)\n \tint namelen = strlen(path);\n \tint pos = cache_name_pos(path, namelen);\n \tif (0 <= pos) {\n-\t\tmark_fsmonitor_invalid(istate, active_cache[pos]);\n+\t\tmark_fsmonitor_invalid(istate, istate->cache[pos]);\n \t\tif (mark)\n-\t\t\tactive_cache[pos]->ce_flags |= flag;\n+\t\t\tistate->cache[pos]->ce_flags |= flag;\n \t\telse\n-\t\t\tactive_cache[pos]->ce_flags &= ~flag;\n-\t\tactive_cache[pos]->ce_flags |= CE_UPDATE_IN_BASE;\n+\t\t\tistate->cache[pos]->ce_flags &= ~flag;\n+\t\tistate->cache[pos]->ce_flags |= CE_UPDATE_IN_BASE;\n \t\tcache_tree_invalidate_path(istate, path);\n \t\tactive_cache_changed |= CE_ENTRY_CHANGED;\n \t\treturn 0;\n@@ -331,7 +331,7 @@ static int process_directory(const char *path, int len, struct stat *st)\n \n \t/* Exact match: file or existing gitlink */\n \tif (pos >= 0) {\n-\t\tconst struct cache_entry *ce = active_cache[pos];\n+\t\tconst struct cache_entry *ce = istate->cache[pos];\n \t\tif (S_ISGITLINK(ce->ce_mode)) {\n \n \t\t\t/* Do nothing to the index if there is no HEAD! */\n@@ -347,7 +347,7 @@ static int process_directory(const char *path, int len, struct stat *st)\n \t/* Inexact match: is there perhaps a subdirectory match? */\n \tpos = -pos-1;\n \twhile (pos < active_nr) {\n-\t\tconst struct cache_entry *ce = active_cache[pos++];\n+\t\tconst struct cache_entry *ce = istate->cache[pos++];\n \n \t\tif (strncmp(ce->name, path, len))\n \t\t\tbreak;\n@@ -378,7 +378,7 @@ static int process_path(const char *path, struct stat *st, int stat_errno)\n \t\treturn error(\"'%s' is beyond a symbolic link\", path);\n \n \tpos = cache_name_pos(path, len);\n-\tce = pos < 0 ? NULL : active_cache[pos];\n+\tce = pos < 0 ? NULL : istate->cache[pos];\n \tif (ce && ce_skip_worktree(ce)) {\n \t\t/*\n \t\t * working directory version is assumed \"good\"\n@@ -429,7 +429,7 @@ static void chmod_path(char flip, const char *path)\n \tpos = cache_name_pos(path, strlen(path));\n \tif (pos < 0)\n \t\tgoto fail;\n-\tce = active_cache[pos];\n+\tce = istate->cache[pos];\n \tif (chmod_cache_entry(ce, flip) < 0)\n \t\tgoto fail;\n \n@@ -628,7 +628,7 @@ static int unresolve_one(const char *path)\n \t\t/* already merged */\n \t\tpos = unmerge_cache_entry_at(pos);\n \t\tif (pos < active_nr) {\n-\t\t\tconst struct cache_entry *ce = active_cache[pos];\n+\t\t\tconst struct cache_entry *ce = istate->cache[pos];\n \t\t\tif (ce_stage(ce) &&\n \t\t\t    ce_namelen(ce) == namelen &&\n \t\t\t    !memcmp(ce->name, path, namelen))\n@@ -642,7 +642,7 @@ static int unresolve_one(const char *path)\n \t\t */\n \t\tpos = -pos-1;\n \t\tif (pos < active_nr) {\n-\t\t\tconst struct cache_entry *ce = active_cache[pos];\n+\t\t\tconst struct cache_entry *ce = istate->cache[pos];\n \t\t\tif (ce_namelen(ce) == namelen &&\n \t\t\t    !memcmp(ce->name, path, namelen)) {\n \t\t\t\tfprintf(stderr,\n@@ -738,7 +738,7 @@ static int do_reupdate(int ac, const char **av,\n \t\thas_head = 0;\n  redo:\n \tfor (pos = 0; pos < active_nr; pos++) {\n-\t\tconst struct cache_entry *ce = active_cache[pos];\n+\t\tconst struct cache_entry *ce = istate->cache[pos];\n \t\tstruct cache_entry *old = NULL;\n \t\tint save_nr;\n \t\tchar *path;\n-- \ngitgitgadget\n\n"},{"id":"413422","messageId":"6c0e019f91ce50bef8a98ac60072a61c77710080.1609821783.git.gitgitgadget@gmail.com","threadId":"54916","inReplyTo":"pull.830.v2.git.1609821783.gitgitgadget@gmail.com","subject":"[PATCH v2 05/14] update-index: use index->cache_nr over active_nr","fromName":"Derrick Stolee via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-01-05T04:42:54Z","receivedAt":"2021-01-05T04:44:17Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"From: Derrick Stolee <dstolee@microsoft.com>\n\nSigned-off-by: Derrick Stolee <dstolee@microsoft.com>\n---\n builtin/update-index.c | 14 +++++++-------\n 1 file changed, 7 insertions(+), 7 deletions(-)\n\ndiff --git a/builtin/update-index.c b/builtin/update-index.c\nindex 3e459d2b9de..106bfdab78e 100644\n--- a/builtin/update-index.c\n+++ b/builtin/update-index.c\n@@ -346,7 +346,7 @@ static int process_directory(const char *path, int len, struct stat *st)\n \n \t/* Inexact match: is there perhaps a subdirectory match? */\n \tpos = -pos-1;\n-\twhile (pos < active_nr) {\n+\twhile (pos < istate->cache_nr) {\n \t\tconst struct cache_entry *ce = istate->cache[pos++];\n \n \t\tif (strncmp(ce->name, path, len))\n@@ -627,7 +627,7 @@ static int unresolve_one(const char *path)\n \tif (0 <= pos) {\n \t\t/* already merged */\n \t\tpos = unmerge_cache_entry_at(pos);\n-\t\tif (pos < active_nr) {\n+\t\tif (pos < istate->cache_nr) {\n \t\t\tconst struct cache_entry *ce = istate->cache[pos];\n \t\t\tif (ce_stage(ce) &&\n \t\t\t    ce_namelen(ce) == namelen &&\n@@ -641,7 +641,7 @@ static int unresolve_one(const char *path)\n \t\t * want to do anything in the former case.\n \t\t */\n \t\tpos = -pos-1;\n-\t\tif (pos < active_nr) {\n+\t\tif (pos < istate->cache_nr) {\n \t\t\tconst struct cache_entry *ce = istate->cache[pos];\n \t\t\tif (ce_namelen(ce) == namelen &&\n \t\t\t    !memcmp(ce->name, path, namelen)) {\n@@ -737,7 +737,7 @@ static int do_reupdate(int ac, const char **av,\n \t\t */\n \t\thas_head = 0;\n  redo:\n-\tfor (pos = 0; pos < active_nr; pos++) {\n+\tfor (pos = 0; pos < istate->cache_nr; pos++) {\n \t\tconst struct cache_entry *ce = istate->cache[pos];\n \t\tstruct cache_entry *old = NULL;\n \t\tint save_nr;\n@@ -755,14 +755,14 @@ static int do_reupdate(int ac, const char **av,\n \t\t}\n \t\t/* Be careful.  The working tree may not have the\n \t\t * path anymore, in which case, under 'allow_remove',\n-\t\t * or worse yet 'allow_replace', active_nr may decrease.\n+\t\t * or worse yet 'allow_replace', istate->cache_nr may decrease.\n \t\t */\n-\t\tsave_nr = active_nr;\n+\t\tsave_nr = istate->cache_nr;\n \t\tpath = xstrdup(ce->name);\n \t\tupdate_one(path);\n \t\tfree(path);\n \t\tdiscard_cache_entry(old);\n-\t\tif (save_nr != active_nr)\n+\t\tif (save_nr != istate->cache_nr)\n \t\t\tgoto redo;\n \t}\n \tclear_pathspec(&pathspec);\n-- \ngitgitgadget\n\n"},{"id":"413423","messageId":"5b14fa10a4bec330bb31e9c7cb2c4375ce914ca9.1609821783.git.gitgitgadget@gmail.com","threadId":"54916","inReplyTo":"pull.830.v2.git.1609821783.gitgitgadget@gmail.com","subject":"[PATCH v2 07/14] update-index: use index_name_pos() over cache_name_pos()","fromName":"Derrick Stolee via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-01-05T04:42:56Z","receivedAt":"2021-01-05T04:44:31Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"From: Derrick Stolee <dstolee@microsoft.com>\n\nSigned-off-by: Derrick Stolee <dstolee@microsoft.com>\n---\n builtin/update-index.c | 10 +++++-----\n 1 file changed, 5 insertions(+), 5 deletions(-)\n\ndiff --git a/builtin/update-index.c b/builtin/update-index.c\nindex 346d798c60b..096cbdfa8ac 100644\n--- a/builtin/update-index.c\n+++ b/builtin/update-index.c\n@@ -233,7 +233,7 @@ static int test_if_untracked_cache_is_supported(void)\n static int mark_ce_flags(const char *path, int flag, int mark)\n {\n \tint namelen = strlen(path);\n-\tint pos = cache_name_pos(path, namelen);\n+\tint pos = index_name_pos(istate, path, namelen);\n \tif (0 <= pos) {\n \t\tmark_fsmonitor_invalid(istate, istate->cache[pos]);\n \t\tif (mark)\n@@ -327,7 +327,7 @@ static int add_one_path(const struct cache_entry *old, const char *path, int len\n static int process_directory(const char *path, int len, struct stat *st)\n {\n \tstruct object_id oid;\n-\tint pos = cache_name_pos(path, len);\n+\tint pos = index_name_pos(istate, path, len);\n \n \t/* Exact match: file or existing gitlink */\n \tif (pos >= 0) {\n@@ -377,7 +377,7 @@ static int process_path(const char *path, struct stat *st, int stat_errno)\n \tif (has_symlink_leading_path(path, len))\n \t\treturn error(\"'%s' is beyond a symbolic link\", path);\n \n-\tpos = cache_name_pos(path, len);\n+\tpos = index_name_pos(istate, path, len);\n \tce = pos < 0 ? NULL : istate->cache[pos];\n \tif (ce && ce_skip_worktree(ce)) {\n \t\t/*\n@@ -426,7 +426,7 @@ static void chmod_path(char flip, const char *path)\n \tint pos;\n \tstruct cache_entry *ce;\n \n-\tpos = cache_name_pos(path, strlen(path));\n+\tpos = index_name_pos(istate, path, strlen(path));\n \tif (pos < 0)\n \t\tgoto fail;\n \tce = istate->cache[pos];\n@@ -623,7 +623,7 @@ static int unresolve_one(const char *path)\n \tstruct cache_entry *ce_2 = NULL, *ce_3 = NULL;\n \n \t/* See if there is such entry in the index. */\n-\tpos = cache_name_pos(path, namelen);\n+\tpos = index_name_pos(istate, path, namelen);\n \tif (0 <= pos) {\n \t\t/* already merged */\n \t\tpos = unmerge_cache_entry_at(pos);\n-- \ngitgitgadget\n\n"},{"id":"413424","messageId":"620e300ad6b346af6b73feec625a3e125afaa53f.1609821783.git.gitgitgadget@gmail.com","threadId":"54916","inReplyTo":"pull.830.v2.git.1609821783.gitgitgadget@gmail.com","subject":"[PATCH v2 09/14] update-index: use add_index_entry()","fromName":"Derrick Stolee via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-01-05T04:42:58Z","receivedAt":"2021-01-05T04:44:32Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"From: Derrick Stolee <dstolee@microsoft.com>\n\nThis is a mechanical replacement of add_cache_entry().\n\nSigned-off-by: Derrick Stolee <dstolee@microsoft.com>\n---\n builtin/update-index.c | 6 +++---\n 1 file changed, 3 insertions(+), 3 deletions(-)\n\ndiff --git a/builtin/update-index.c b/builtin/update-index.c\nindex aa859c4e018..ffa42813370 100644\n--- a/builtin/update-index.c\n+++ b/builtin/update-index.c\n@@ -294,7 +294,7 @@ static int add_one_path(const struct cache_entry *old, const char *path, int len\n \t}\n \toption = allow_add ? ADD_CACHE_OK_TO_ADD : 0;\n \toption |= allow_replace ? ADD_CACHE_OK_TO_REPLACE : 0;\n-\tif (add_cache_entry(ce, option)) {\n+\tif (add_index_entry(istate, ce, option)) {\n \t\tdiscard_cache_entry(ce);\n \t\treturn error(\"%s: cannot add to the index - missing --add option?\", path);\n \t}\n@@ -672,12 +672,12 @@ static int unresolve_one(const char *path)\n \t}\n \n \tremove_file_from_index(istate, path);\n-\tif (add_cache_entry(ce_2, ADD_CACHE_OK_TO_ADD)) {\n+\tif (add_index_entry(istate, ce_2, ADD_CACHE_OK_TO_ADD)) {\n \t\terror(\"%s: cannot add our version to the index.\", path);\n \t\tret = -1;\n \t\tgoto free_return;\n \t}\n-\tif (!add_cache_entry(ce_3, ADD_CACHE_OK_TO_ADD))\n+\tif (!add_index_entry(istate, ce_3, ADD_CACHE_OK_TO_ADD))\n \t\treturn 0;\n \terror(\"%s: cannot add their version to the index.\", path);\n \tret = -1;\n-- \ngitgitgadget\n\n"},{"id":"413425","messageId":"79e267f39ec764e03788ba1ddfe1051156a625fa.1609821783.git.gitgitgadget@gmail.com","threadId":"54916","inReplyTo":"pull.830.v2.git.1609821783.gitgitgadget@gmail.com","subject":"[PATCH v2 12/14] update-index: reduce static globals, part 1","fromName":"Derrick Stolee via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-01-05T04:43:01Z","receivedAt":"2021-01-05T04:44:32Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"From: Derrick Stolee <dstolee@microsoft.com>\n\nIn order to remove index compatibility macros cleanly, we relied upon\nstatic globals 'repo' and 'istate' to be pointers to the_repository and\nthe_index, respectively. We can now start reducing the need for these\nstatic globals by modifying method prototypes to use them when\nnecessary.\n\nMove these static globals further down in the file so we can identify\nwhich method only need to add a 'struct index_state *istate' parameter.\nThe only changes included here adjust method prototypes and their call\nlocations.\n\nSigned-off-by: Derrick Stolee <dstolee@microsoft.com>\n---\n builtin/update-index.c | 77 ++++++++++++++++++++++++------------------\n 1 file changed, 44 insertions(+), 33 deletions(-)\n\ndiff --git a/builtin/update-index.c b/builtin/update-index.c\nindex 8fc680090be..6b585fb8ede 100644\n--- a/builtin/update-index.c\n+++ b/builtin/update-index.c\n@@ -39,9 +39,6 @@ static int ignore_skip_worktree_entries;\n #define UNMARK_FLAG 2\n static struct strbuf mtime_dir = STRBUF_INIT;\n \n-static struct repository *repo;\n-static struct index_state *istate;\n-\n /* Untracked cache mode */\n enum uc_mode {\n \tUC_UNSPECIFIED = -1,\n@@ -229,7 +226,8 @@ static int test_if_untracked_cache_is_supported(void)\n \treturn ret;\n }\n \n-static int mark_ce_flags(const char *path, int flag, int mark)\n+static int mark_ce_flags(struct index_state *istate,\n+\t\t\t const char *path, int flag, int mark)\n {\n \tint namelen = strlen(path);\n \tint pos = index_name_pos(istate, path, namelen);\n@@ -247,7 +245,7 @@ static int mark_ce_flags(const char *path, int flag, int mark)\n \treturn -1;\n }\n \n-static int remove_one_path(const char *path)\n+static int remove_one_path(struct index_state *istate, const char *path)\n {\n \tif (!allow_remove)\n \t\treturn error(\"%s: does not exist and --remove not passed\", path);\n@@ -263,14 +261,17 @@ static int remove_one_path(const char *path)\n  *    succeeds.\n  *  - permission error. That's never ok.\n  */\n-static int process_lstat_error(const char *path, int err)\n+static int process_lstat_error(struct index_state *istate,\n+\t\t\t       const char *path, int err)\n {\n \tif (is_missing_file_error(err))\n-\t\treturn remove_one_path(path);\n+\t\treturn remove_one_path(istate, path);\n \treturn error(\"lstat(\\\"%s\\\"): %s\", path, strerror(err));\n }\n \n-static int add_one_path(const struct cache_entry *old, const char *path, int len, struct stat *st)\n+static int add_one_path(struct index_state *istate,\n+\t\t\tconst struct cache_entry *old,\n+\t\t\tconst char *path, int len, struct stat *st)\n {\n \tint option;\n \tstruct cache_entry *ce;\n@@ -323,7 +324,8 @@ static int add_one_path(const struct cache_entry *old, const char *path, int len\n  *  - it doesn't exist at all in the index, but it is a valid\n  *    git directory, and it should be *added* as a gitlink.\n  */\n-static int process_directory(const char *path, int len, struct stat *st)\n+static int process_directory(struct index_state *istate,\n+\t\t\t     const char *path, int len, struct stat *st)\n {\n \tstruct object_id oid;\n \tint pos = index_name_pos(istate, path, len);\n@@ -337,10 +339,10 @@ static int process_directory(const char *path, int len, struct stat *st)\n \t\t\tif (resolve_gitlink_ref(path, \"HEAD\", &oid) < 0)\n \t\t\t\treturn 0;\n \n-\t\t\treturn add_one_path(ce, path, len, st);\n+\t\t\treturn add_one_path(istate, ce, path, len, st);\n \t\t}\n \t\t/* Should this be an unconditional error? */\n-\t\treturn remove_one_path(path);\n+\t\treturn remove_one_path(istate, path);\n \t}\n \n \t/* Inexact match: is there perhaps a subdirectory match? */\n@@ -361,13 +363,14 @@ static int process_directory(const char *path, int len, struct stat *st)\n \n \t/* No match - should we add it as a gitlink? */\n \tif (!resolve_gitlink_ref(path, \"HEAD\", &oid))\n-\t\treturn add_one_path(NULL, path, len, st);\n+\t\treturn add_one_path(istate, NULL, path, len, st);\n \n \t/* Error out. */\n \treturn error(\"%s: is a directory - add files inside instead\", path);\n }\n \n-static int process_path(const char *path, struct stat *st, int stat_errno)\n+static int process_path(struct index_state *istate,\n+\t\t\tconst char *path, struct stat *st, int stat_errno)\n {\n \tint pos, len;\n \tconst struct cache_entry *ce;\n@@ -395,15 +398,16 @@ static int process_path(const char *path, struct stat *st, int stat_errno)\n \t * what to do about the pathname!\n \t */\n \tif (stat_errno)\n-\t\treturn process_lstat_error(path, stat_errno);\n+\t\treturn process_lstat_error(istate, path, stat_errno);\n \n \tif (S_ISDIR(st->st_mode))\n-\t\treturn process_directory(path, len, st);\n+\t\treturn process_directory(istate, path, len, st);\n \n-\treturn add_one_path(ce, path, len, st);\n+\treturn add_one_path(istate, ce, path, len, st);\n }\n \n-static int add_cacheinfo(unsigned int mode, const struct object_id *oid,\n+static int add_cacheinfo(struct index_state *istate,\n+\t\t\t unsigned int mode, const struct object_id *oid,\n \t\t\t const char *path, int stage)\n {\n \tint res;\n@@ -420,7 +424,8 @@ static int add_cacheinfo(unsigned int mode, const struct object_id *oid,\n \treturn 0;\n }\n \n-static void chmod_path(char flip, const char *path)\n+static void chmod_path(struct index_state *istate,\n+\t\t       char flip, const char *path)\n {\n \tint pos;\n \tstruct cache_entry *ce;\n@@ -438,7 +443,7 @@ static void chmod_path(char flip, const char *path)\n \tdie(\"git update-index: cannot chmod %cx '%s'\", flip, path);\n }\n \n-static void update_one(const char *path)\n+static void update_one(struct index_state *istate, const char *path)\n {\n \tint stat_errno = 0;\n \tstruct stat st;\n@@ -456,17 +461,20 @@ static void update_one(const char *path)\n \t\treturn;\n \t}\n \tif (mark_valid_only) {\n-\t\tif (mark_ce_flags(path, CE_VALID, mark_valid_only == MARK_FLAG))\n+\t\tif (mark_ce_flags(istate, path, CE_VALID,\n+\t\t\t\t  mark_valid_only == MARK_FLAG))\n \t\t\tdie(\"Unable to mark file %s\", path);\n \t\treturn;\n \t}\n \tif (mark_skip_worktree_only) {\n-\t\tif (mark_ce_flags(path, CE_SKIP_WORKTREE, mark_skip_worktree_only == MARK_FLAG))\n+\t\tif (mark_ce_flags(istate, path, CE_SKIP_WORKTREE,\n+\t\t\t\t  mark_skip_worktree_only == MARK_FLAG))\n \t\t\tdie(\"Unable to mark file %s\", path);\n \t\treturn;\n \t}\n \tif (mark_fsmonitor_only) {\n-\t\tif (mark_ce_flags(path, CE_FSMONITOR_VALID, mark_fsmonitor_only == MARK_FLAG))\n+\t\tif (mark_ce_flags(istate, path, CE_FSMONITOR_VALID,\n+\t\t\t\t  mark_fsmonitor_only == MARK_FLAG))\n \t\t\tdie(\"Unable to mark file %s\", path);\n \t\treturn;\n \t}\n@@ -477,12 +485,12 @@ static void update_one(const char *path)\n \t\treport(\"remove '%s'\", path);\n \t\treturn;\n \t}\n-\tif (process_path(path, &st, stat_errno))\n+\tif (process_path(istate, path, &st, stat_errno))\n \t\tdie(\"Unable to process path %s\", path);\n \treport(\"add '%s'\", path);\n }\n \n-static void read_index_info(int nul_term_line)\n+static void read_index_info(struct index_state *istate, int nul_term_line)\n {\n \tconst int hexsz = the_hash_algo->hexsz;\n \tstruct strbuf buf = STRBUF_INIT;\n@@ -565,7 +573,7 @@ static void read_index_info(int nul_term_line)\n \t\t\t * ptr[-41] is at the beginning of sha1\n \t\t\t */\n \t\t\tptr[-(hexsz + 2)] = ptr[-1] = 0;\n-\t\t\tif (add_cacheinfo(mode, &oid, path_name, stage))\n+\t\t\tif (add_cacheinfo(istate, mode, &oid, path_name, stage))\n \t\t\t\tdie(\"git update-index: unable to update %s\",\n \t\t\t\t    path_name);\n \t\t}\n@@ -586,6 +594,9 @@ static const char * const update_index_usage[] = {\n static struct object_id head_oid;\n static struct object_id merge_head_oid;\n \n+static struct repository *repo;\n+static struct index_state *istate;\n+\n static struct cache_entry *read_one_ent(const char *which,\n \t\t\t\t\tstruct object_id *ent, const char *path,\n \t\t\t\t\tint namelen, int stage)\n@@ -758,7 +769,7 @@ static int do_reupdate(int ac, const char **av,\n \t\t */\n \t\tsave_nr = istate->cache_nr;\n \t\tpath = xstrdup(ce->name);\n-\t\tupdate_one(path);\n+\t\tupdate_one(istate, path);\n \t\tfree(path);\n \t\tdiscard_cache_entry(old);\n \t\tif (save_nr != istate->cache_nr)\n@@ -854,7 +865,7 @@ static enum parse_opt_result cacheinfo_callback(\n \tBUG_ON_OPT_ARG(arg);\n \n \tif (!parse_new_style_cacheinfo(ctx->argv[1], &mode, &oid, &path)) {\n-\t\tif (add_cacheinfo(mode, &oid, path, 0))\n+\t\tif (add_cacheinfo(istate, mode, &oid, path, 0))\n \t\t\tdie(\"git update-index: --cacheinfo cannot add %s\", path);\n \t\tctx->argv++;\n \t\tctx->argc--;\n@@ -864,7 +875,7 @@ static enum parse_opt_result cacheinfo_callback(\n \t\treturn error(\"option 'cacheinfo' expects <mode>,<sha1>,<path>\");\n \tif (strtoul_ui(*++ctx->argv, 8, &mode) ||\n \t    get_oid_hex(*++ctx->argv, &oid) ||\n-\t    add_cacheinfo(mode, &oid, *++ctx->argv, 0))\n+\t    add_cacheinfo(istate, mode, &oid, *++ctx->argv, 0))\n \t\tdie(\"git update-index: --cacheinfo cannot add %s\", *ctx->argv);\n \tctx->argc -= 3;\n \treturn 0;\n@@ -882,7 +893,7 @@ static enum parse_opt_result stdin_cacheinfo_callback(\n \tif (ctx->argc != 1)\n \t\treturn error(\"option '%s' must be the last argument\", opt->long_name);\n \tallow_add = allow_replace = allow_remove = 1;\n-\tread_index_info(*nul_term_line);\n+\tread_index_info(istate, *nul_term_line);\n \treturn 0;\n }\n \n@@ -1108,9 +1119,9 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \n \t\t\tsetup_work_tree();\n \t\t\tp = prefix_path(prefix, prefix_length, path);\n-\t\t\tupdate_one(p);\n+\t\t\tupdate_one(istate, p);\n \t\t\tif (set_executable_bit)\n-\t\t\t\tchmod_path(set_executable_bit, p);\n+\t\t\t\tchmod_path(istate, set_executable_bit, p);\n \t\t\tfree(p);\n \t\t\tctx.argc--;\n \t\t\tctx.argv++;\n@@ -1153,9 +1164,9 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \t\t\t\tstrbuf_swap(&buf, &unquoted);\n \t\t\t}\n \t\t\tp = prefix_path(prefix, prefix_length, buf.buf);\n-\t\t\tupdate_one(p);\n+\t\t\tupdate_one(istate, p);\n \t\t\tif (set_executable_bit)\n-\t\t\t\tchmod_path(set_executable_bit, p);\n+\t\t\t\tchmod_path(istate, set_executable_bit, p);\n \t\t\tfree(p);\n \t\t}\n \t\tstrbuf_release(&unquoted);\n-- \ngitgitgadget\n\n"},{"id":"413426","messageId":"2b171a142b36b114d5ff526073fe3fd9517a4d32.1609821783.git.gitgitgadget@gmail.com","threadId":"54916","inReplyTo":"pull.830.v2.git.1609821783.gitgitgadget@gmail.com","subject":"[PATCH v2 14/14] update-index: remove static globals from callbacks","fromName":"Derrick Stolee via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-01-05T04:43:03Z","receivedAt":"2021-01-05T04:44:34Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"From: Derrick Stolee <dstolee@microsoft.com>\n\nIn order to remove index compatibility macros cleanly, we relied upon\nstatic globals 'repo' and 'istate' to be pointers to the_repository and\nthe_index, respectively. We remove these static globals inside the\noption parsing callbacks, which are the final uses in update-index.\n\nThe callbacks cannot change their method signature, so we must use the\nvalue member of 'struct option', assigned in the array of option macros.\nThere are several callback methods that require at least one of 'repo'\nand 'istate', but they use a variety of different data types for the\ncallback value.\n\nUnify these callback methods to use a consistent 'struct callback_data'\nthat contains 'repo' and 'istate', ready to use. This takes the place of\nthe previous 'struct refresh_params' which served only to group the\n'flags' and 'has_errors' ints. We also collect other one-off settings,\nbut only those that require access to the index or repository in their\noperation.\n\nSigned-off-by: Derrick Stolee <dstolee@microsoft.com>\n---\n builtin/update-index.c | 110 ++++++++++++++++++++++-------------------\n 1 file changed, 60 insertions(+), 50 deletions(-)\n\ndiff --git a/builtin/update-index.c b/builtin/update-index.c\nindex fb8d7879783..258db619a40 100644\n--- a/builtin/update-index.c\n+++ b/builtin/update-index.c\n@@ -784,19 +784,21 @@ static int do_reupdate(struct repository *repo,\n \treturn 0;\n }\n \n-struct refresh_params {\n+struct callback_data {\n+\tstruct repository *repo;\n+\tstruct index_state *istate;\n+\n \tunsigned int flags;\n-\tint *has_errors;\n+\tunsigned int has_errors;\n+\tunsigned nul_term_line;\n+\tunsigned read_from_stdin;\n };\n \n-static struct repository *repo;\n-static struct index_state *istate;\n-\n-static int refresh(struct refresh_params *o, unsigned int flag)\n+static int refresh(struct callback_data *cd, unsigned int flag)\n {\n \tsetup_work_tree();\n-\trepo_read_index(repo);\n-\t*o->has_errors |= refresh_index(istate, o->flags | flag,\n+\trepo_read_index(cd->repo);\n+\tcd->has_errors |= refresh_index(cd->istate, cd->flags | flag,\n \t\t\t\t\tNULL, NULL, NULL);\n \treturn 0;\n }\n@@ -818,7 +820,7 @@ static int really_refresh_callback(const struct option *opt,\n }\n \n static int chmod_callback(const struct option *opt,\n-\t\t\t\tconst char *arg, int unset)\n+\t\t\t  const char *arg, int unset)\n {\n \tchar *flip = opt->value;\n \tBUG_ON_OPT_NEG(unset);\n@@ -829,11 +831,12 @@ static int chmod_callback(const struct option *opt,\n }\n \n static int resolve_undo_clear_callback(const struct option *opt,\n-\t\t\t\tconst char *arg, int unset)\n+\t\t\t\t       const char *arg, int unset)\n {\n+\tstruct callback_data *cd = opt->value;\n \tBUG_ON_OPT_NEG(unset);\n \tBUG_ON_OPT_ARG(arg);\n-\tresolve_undo_clear_index(istate);\n+\tresolve_undo_clear_index(cd->istate);\n \treturn 0;\n }\n \n@@ -868,12 +871,13 @@ static enum parse_opt_result cacheinfo_callback(\n \tstruct object_id oid;\n \tunsigned int mode;\n \tconst char *path;\n+\tstruct callback_data *cd = opt->value;\n \n \tBUG_ON_OPT_NEG(unset);\n \tBUG_ON_OPT_ARG(arg);\n \n \tif (!parse_new_style_cacheinfo(ctx->argv[1], &mode, &oid, &path)) {\n-\t\tif (add_cacheinfo(istate, mode, &oid, path, 0))\n+\t\tif (add_cacheinfo(cd->istate, mode, &oid, path, 0))\n \t\t\tdie(\"git update-index: --cacheinfo cannot add %s\", path);\n \t\tctx->argv++;\n \t\tctx->argc--;\n@@ -883,7 +887,7 @@ static enum parse_opt_result cacheinfo_callback(\n \t\treturn error(\"option 'cacheinfo' expects <mode>,<sha1>,<path>\");\n \tif (strtoul_ui(*++ctx->argv, 8, &mode) ||\n \t    get_oid_hex(*++ctx->argv, &oid) ||\n-\t    add_cacheinfo(istate, mode, &oid, *++ctx->argv, 0))\n+\t    add_cacheinfo(cd->istate, mode, &oid, *++ctx->argv, 0))\n \t\tdie(\"git update-index: --cacheinfo cannot add %s\", *ctx->argv);\n \tctx->argc -= 3;\n \treturn 0;\n@@ -893,7 +897,7 @@ static enum parse_opt_result stdin_cacheinfo_callback(\n \tstruct parse_opt_ctx_t *ctx, const struct option *opt,\n \tconst char *arg, int unset)\n {\n-\tint *nul_term_line = opt->value;\n+\tstruct callback_data *cd = opt->value;\n \n \tBUG_ON_OPT_NEG(unset);\n \tBUG_ON_OPT_ARG(arg);\n@@ -901,7 +905,7 @@ static enum parse_opt_result stdin_cacheinfo_callback(\n \tif (ctx->argc != 1)\n \t\treturn error(\"option '%s' must be the last argument\", opt->long_name);\n \tallow_add = allow_replace = allow_remove = 1;\n-\tread_index_info(istate, *nul_term_line);\n+\tread_index_info(cd->istate, cd->nul_term_line);\n \treturn 0;\n }\n \n@@ -909,14 +913,14 @@ static enum parse_opt_result stdin_callback(\n \tstruct parse_opt_ctx_t *ctx, const struct option *opt,\n \tconst char *arg, int unset)\n {\n-\tint *read_from_stdin = opt->value;\n+\tstruct callback_data *cd = opt->value;\n \n \tBUG_ON_OPT_NEG(unset);\n \tBUG_ON_OPT_ARG(arg);\n \n \tif (ctx->argc != 1)\n \t\treturn error(\"option '%s' must be the last argument\", opt->long_name);\n-\t*read_from_stdin = 1;\n+\tcd->read_from_stdin = 1;\n \treturn 0;\n }\n \n@@ -924,17 +928,17 @@ static enum parse_opt_result unresolve_callback(\n \tstruct parse_opt_ctx_t *ctx, const struct option *opt,\n \tconst char *arg, int unset)\n {\n-\tint *has_errors = opt->value;\n \tconst char *prefix = startup_info->prefix;\n+\tstruct callback_data *cd = opt->value;\n \n \tBUG_ON_OPT_NEG(unset);\n \tBUG_ON_OPT_ARG(arg);\n \n \t/* consume remaining arguments. */\n-\t*has_errors = do_unresolve(repo, istate, ctx->argc, ctx->argv,\n-\t\t\t\t   prefix, prefix ? strlen(prefix) : 0);\n-\tif (*has_errors)\n-\t\tistate->cache_changed = 0;\n+\tcd->has_errors = do_unresolve(cd->repo, cd->istate, ctx->argc, ctx->argv,\n+\t\t\t\t      prefix, prefix ? strlen(prefix) : 0);\n+\tif (cd->has_errors)\n+\t\tcd->istate->cache_changed = 0;\n \n \tctx->argv += ctx->argc - 1;\n \tctx->argc = 1;\n@@ -945,17 +949,18 @@ static enum parse_opt_result reupdate_callback(\n \tstruct parse_opt_ctx_t *ctx, const struct option *opt,\n \tconst char *arg, int unset)\n {\n-\tint *has_errors = opt->value;\n \tconst char *prefix = startup_info->prefix;\n+\tstruct callback_data *cd = opt->value;\n \n \tBUG_ON_OPT_NEG(unset);\n \tBUG_ON_OPT_ARG(arg);\n \n \t/* consume remaining arguments. */\n \tsetup_work_tree();\n-\t*has_errors = do_reupdate(repo, istate, ctx->argc, ctx->argv, prefix);\n-\tif (*has_errors)\n-\t\tistate->cache_changed = 0;\n+\tcd->has_errors = do_reupdate(cd->repo, cd->istate,\n+\t\t\t\t     ctx->argc, ctx->argv, prefix);\n+\tif (cd->has_errors)\n+\t\tcd->istate->cache_changed = 0;\n \n \tctx->argv += ctx->argc - 1;\n \tctx->argc = 1;\n@@ -964,13 +969,13 @@ static enum parse_opt_result reupdate_callback(\n \n int cmd_update_index(int argc, const char **argv, const char *prefix)\n {\n-\tint newfd, entries, has_errors = 0, nul_term_line = 0;\n+\tstruct repository *repo = the_repository;\n+\tstruct callback_data cd;\n+\tint newfd, entries;\n \tenum uc_mode untracked_cache = UC_UNSPECIFIED;\n-\tint read_from_stdin = 0;\n \tint prefix_length = prefix ? strlen(prefix) : 0;\n \tint preferred_index_format = 0;\n \tchar set_executable_bit = 0;\n-\tstruct refresh_params refresh_args = {0, &has_errors};\n \tint lock_error = 0;\n \tint split_index = -1;\n \tint force_write = 0;\n@@ -979,11 +984,13 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \tstruct parse_opt_ctx_t ctx;\n \tstrbuf_getline_fn getline_fn;\n \tint parseopt_state = PARSE_OPT_UNKNOWN;\n+\tstruct index_state *istate;\n+\n \tstruct option options[] = {\n-\t\tOPT_BIT('q', NULL, &refresh_args.flags,\n+\t\tOPT_BIT('q', NULL, &cd.flags,\n \t\t\tN_(\"continue refresh even when index needs update\"),\n \t\t\tREFRESH_QUIET),\n-\t\tOPT_BIT(0, \"ignore-submodules\", &refresh_args.flags,\n+\t\tOPT_BIT(0, \"ignore-submodules\", &cd.flags,\n \t\t\tN_(\"refresh: ignore submodules\"),\n \t\t\tREFRESH_IGNORE_SUBMODULES),\n \t\tOPT_SET_INT(0, \"add\", &allow_add,\n@@ -992,18 +999,18 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \t\t\tN_(\"let files replace directories and vice-versa\"), 1),\n \t\tOPT_SET_INT(0, \"remove\", &allow_remove,\n \t\t\tN_(\"notice files missing from worktree\"), 1),\n-\t\tOPT_BIT(0, \"unmerged\", &refresh_args.flags,\n+\t\tOPT_BIT(0, \"unmerged\", &cd.flags,\n \t\t\tN_(\"refresh even if index contains unmerged entries\"),\n \t\t\tREFRESH_UNMERGED),\n-\t\tOPT_CALLBACK_F(0, \"refresh\", &refresh_args, NULL,\n+\t\tOPT_CALLBACK_F(0, \"refresh\", &cd, NULL,\n \t\t\tN_(\"refresh stat information\"),\n \t\t\tPARSE_OPT_NOARG | PARSE_OPT_NONEG,\n \t\t\trefresh_callback),\n-\t\tOPT_CALLBACK_F(0, \"really-refresh\", &refresh_args, NULL,\n+\t\tOPT_CALLBACK_F(0, \"really-refresh\", &cd, NULL,\n \t\t\tN_(\"like --refresh, but ignore assume-unchanged setting\"),\n \t\t\tPARSE_OPT_NOARG | PARSE_OPT_NONEG,\n \t\t\treally_refresh_callback),\n-\t\t{OPTION_LOWLEVEL_CALLBACK, 0, \"cacheinfo\", NULL,\n+\t\t{OPTION_LOWLEVEL_CALLBACK, 0, \"cacheinfo\", &cd,\n \t\t\tN_(\"<mode>,<object>,<path>\"),\n \t\t\tN_(\"add the specified entry to the index\"),\n \t\t\tPARSE_OPT_NOARG | /* disallow --cacheinfo=<mode> form */\n@@ -1032,30 +1039,30 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \t\t\tN_(\"add to index only; do not add content to object database\"), 1),\n \t\tOPT_SET_INT(0, \"force-remove\", &force_remove,\n \t\t\tN_(\"remove named paths even if present in worktree\"), 1),\n-\t\tOPT_BOOL('z', NULL, &nul_term_line,\n+\t\tOPT_BOOL('z', NULL, &cd.nul_term_line,\n \t\t\t N_(\"with --stdin: input lines are terminated by null bytes\")),\n-\t\t{OPTION_LOWLEVEL_CALLBACK, 0, \"stdin\", &read_from_stdin, NULL,\n+\t\t{OPTION_LOWLEVEL_CALLBACK, 0, \"stdin\", &cd, NULL,\n \t\t\tN_(\"read list of paths to be updated from standard input\"),\n \t\t\tPARSE_OPT_NONEG | PARSE_OPT_NOARG,\n \t\t\tNULL, 0, stdin_callback},\n-\t\t{OPTION_LOWLEVEL_CALLBACK, 0, \"index-info\", &nul_term_line, NULL,\n+\t\t{OPTION_LOWLEVEL_CALLBACK, 0, \"index-info\", &cd, NULL,\n \t\t\tN_(\"add entries from standard input to the index\"),\n \t\t\tPARSE_OPT_NONEG | PARSE_OPT_NOARG,\n \t\t\tNULL, 0, stdin_cacheinfo_callback},\n-\t\t{OPTION_LOWLEVEL_CALLBACK, 0, \"unresolve\", &has_errors, NULL,\n+\t\t{OPTION_LOWLEVEL_CALLBACK, 0, \"unresolve\", &cd, NULL,\n \t\t\tN_(\"repopulate stages #2 and #3 for the listed paths\"),\n \t\t\tPARSE_OPT_NONEG | PARSE_OPT_NOARG,\n \t\t\tNULL, 0, unresolve_callback},\n-\t\t{OPTION_LOWLEVEL_CALLBACK, 'g', \"again\", &has_errors, NULL,\n+\t\t{OPTION_LOWLEVEL_CALLBACK, 'g', \"again\", &cd, NULL,\n \t\t\tN_(\"only update entries that differ from HEAD\"),\n \t\t\tPARSE_OPT_NONEG | PARSE_OPT_NOARG,\n \t\t\tNULL, 0, reupdate_callback},\n-\t\tOPT_BIT(0, \"ignore-missing\", &refresh_args.flags,\n+\t\tOPT_BIT(0, \"ignore-missing\", &cd.flags,\n \t\t\tN_(\"ignore files missing from worktree\"),\n \t\t\tREFRESH_IGNORE_MISSING),\n \t\tOPT_SET_INT(0, \"verbose\", &verbose,\n \t\t\tN_(\"report actions to standard output\"), 1),\n-\t\tOPT_CALLBACK_F(0, \"clear-resolve-undo\", NULL, NULL,\n+\t\tOPT_CALLBACK_F(0, \"clear-resolve-undo\", &cd, NULL,\n \t\t\tN_(\"(for porcelains) forget saved unresolved conflicts\"),\n \t\t\tPARSE_OPT_NOARG | PARSE_OPT_NONEG,\n \t\t\tresolve_undo_clear_callback),\n@@ -1087,8 +1094,6 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \n \tgit_config(git_default_config, NULL);\n \n-\trepo = the_repository;\n-\n \t/* we will diagnose later if it turns out that we need to update it */\n \tnewfd = repo_hold_locked_index(repo, &lock_file, 0);\n \tif (newfd < 0)\n@@ -1098,8 +1103,13 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \tif (entries < 0)\n \t\tdie(\"cache corrupted\");\n \n-\tistate = repo->index;\n+\tcd.repo = repo;\n+\tcd.istate = istate = repo->index;\n \tistate->updated_skipworktree = 1;\n+\tcd.flags = 0;\n+\tcd.has_errors = 0;\n+\tcd.nul_term_line = 0;\n+\tcd.read_from_stdin = 0;\n \n \t/*\n \t * Custom copy of parse_options() because we want to handle\n@@ -1145,7 +1155,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \t}\n \targc = parse_options_end(&ctx);\n \n-\tgetline_fn = nul_term_line ? strbuf_getline_nul : strbuf_getline_lf;\n+\tgetline_fn = cd.nul_term_line ? strbuf_getline_nul : strbuf_getline_lf;\n \tif (preferred_index_format) {\n \t\tif (preferred_index_format < INDEX_FORMAT_LB ||\n \t\t    INDEX_FORMAT_UB < preferred_index_format)\n@@ -1158,14 +1168,14 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \t\tistate->version = preferred_index_format;\n \t}\n \n-\tif (read_from_stdin) {\n+\tif (cd.read_from_stdin) {\n \t\tstruct strbuf buf = STRBUF_INIT;\n \t\tstruct strbuf unquoted = STRBUF_INIT;\n \n \t\tsetup_work_tree();\n \t\twhile (getline_fn(&buf, stdin) != EOF) {\n \t\t\tchar *p;\n-\t\t\tif (!nul_term_line && buf.buf[0] == '\"') {\n+\t\t\tif (!cd.nul_term_line && buf.buf[0] == '\"') {\n \t\t\t\tstrbuf_reset(&unquoted);\n \t\t\t\tif (unquote_c_style(&unquoted, buf.buf, NULL))\n \t\t\t\t\tdie(\"line is badly quoted\");\n@@ -1244,7 +1254,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \n \tif (istate->cache_changed || force_write) {\n \t\tif (newfd < 0) {\n-\t\t\tif (refresh_args.flags & REFRESH_QUIET)\n+\t\t\tif (cd.flags & REFRESH_QUIET)\n \t\t\t\texit(128);\n \t\t\tunable_to_lock_die(get_index_file(), lock_error);\n \t\t}\n@@ -1254,5 +1264,5 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \n \trollback_lock_file(&lock_file);\n \n-\treturn has_errors ? 1 : 0;\n+\treturn cd.has_errors ? 1 : 0;\n }\n-- \ngitgitgadget\n"},{"id":"413427","messageId":"68b26a11d779e225566f8581f4afcd514ef1cd70.1609821783.git.gitgitgadget@gmail.com","threadId":"54916","inReplyTo":"pull.830.v2.git.1609821783.gitgitgadget@gmail.com","subject":"[PATCH v2 10/14] update-index: replace several compatibility macros","fromName":"Derrick Stolee via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-01-05T04:42:59Z","receivedAt":"2021-01-05T04:44:34Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"From: Derrick Stolee <dstolee@microsoft.com>\n\nThis is also the last usage of unmerge_cache_entry_at(), so it can be\nremoved from cache.h.\n\nSigned-off-by: Derrick Stolee <dstolee@microsoft.com>\n---\n builtin/update-index.c | 11 ++++++-----\n cache.h                |  1 -\n 2 files changed, 6 insertions(+), 6 deletions(-)\n\ndiff --git a/builtin/update-index.c b/builtin/update-index.c\nindex ffa42813370..dd8e0acc52e 100644\n--- a/builtin/update-index.c\n+++ b/builtin/update-index.c\n@@ -430,7 +430,7 @@ static void chmod_path(char flip, const char *path)\n \tif (pos < 0)\n \t\tgoto fail;\n \tce = istate->cache[pos];\n-\tif (chmod_cache_entry(ce, flip) < 0)\n+\tif (chmod_index_entry(istate, ce, flip) < 0)\n \t\tgoto fail;\n \n \treport(\"chmod %cx '%s'\", flip, path);\n@@ -626,7 +626,7 @@ static int unresolve_one(const char *path)\n \tpos = index_name_pos(istate, path, namelen);\n \tif (0 <= pos) {\n \t\t/* already merged */\n-\t\tpos = unmerge_cache_entry_at(pos);\n+\t\tpos = unmerge_index_entry_at(istate, pos);\n \t\tif (pos < istate->cache_nr) {\n \t\t\tconst struct cache_entry *ce = istate->cache[pos];\n \t\t\tif (ce_stage(ce) &&\n@@ -777,8 +777,9 @@ struct refresh_params {\n static int refresh(struct refresh_params *o, unsigned int flag)\n {\n \tsetup_work_tree();\n-\tread_cache();\n-\t*o->has_errors |= refresh_cache(o->flags | flag);\n+\trepo_read_index(repo);\n+\t*o->has_errors |= refresh_index(istate, o->flags | flag,\n+\t\t\t\t\tNULL, NULL, NULL);\n \treturn 0;\n }\n \n@@ -814,7 +815,7 @@ static int resolve_undo_clear_callback(const struct option *opt,\n {\n \tBUG_ON_OPT_NEG(unset);\n \tBUG_ON_OPT_ARG(arg);\n-\tresolve_undo_clear();\n+\tresolve_undo_clear_index(istate);\n \treturn 0;\n }\n \ndiff --git a/cache.h b/cache.h\nindex fdf061cac56..8c091be6256 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -421,7 +421,6 @@ extern struct index_state the_index;\n #define cache_dir_exists(name, namelen) index_dir_exists(&the_index, (name), (namelen))\n #define cache_name_is_other(name, namelen) index_name_is_other(&the_index, (name), (namelen))\n #define resolve_undo_clear() resolve_undo_clear_index(&the_index)\n-#define unmerge_cache_entry_at(at) unmerge_index_entry_at(&the_index, at)\n #define unmerge_cache(pathspec) unmerge_index(&the_index, pathspec)\n #define read_blob_data_from_cache(path, sz) read_blob_data_from_index(&the_index, (path), (sz))\n #define hold_locked_index(lock_file, flags) repo_hold_locked_index(the_repository, (lock_file), (flags))\n-- \ngitgitgadget\n\n"},{"id":"413428","messageId":"a1a9fb01b07727a55ddb64ee5a3d9d4311642952.1609821783.git.gitgitgadget@gmail.com","threadId":"54916","inReplyTo":"pull.830.v2.git.1609821783.gitgitgadget@gmail.com","subject":"[PATCH v2 08/14] update-index: use remove_file_from_index()","fromName":"Derrick Stolee via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-01-05T04:42:57Z","receivedAt":"2021-01-05T04:44:35Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"From: Derrick Stolee <dstolee@microsoft.com>\n\nThis is a mechanical replacement of remove_file_from_cache().\n\nSigned-off-by: Derrick Stolee <dstolee@microsoft.com>\n---\n builtin/update-index.c | 10 +++++-----\n 1 file changed, 5 insertions(+), 5 deletions(-)\n\ndiff --git a/builtin/update-index.c b/builtin/update-index.c\nindex 096cbdfa8ac..aa859c4e018 100644\n--- a/builtin/update-index.c\n+++ b/builtin/update-index.c\n@@ -252,7 +252,7 @@ static int remove_one_path(const char *path)\n {\n \tif (!allow_remove)\n \t\treturn error(\"%s: does not exist and --remove not passed\", path);\n-\tif (remove_file_from_cache(path))\n+\tif (remove_file_from_index(istate, path))\n \t\treturn error(\"%s: cannot remove from the index\", path);\n \treturn 0;\n }\n@@ -386,7 +386,7 @@ static int process_path(const char *path, struct stat *st, int stat_errno)\n \t\t * On the other hand, removing it from index should work\n \t\t */\n \t\tif (!ignore_skip_worktree_entries && allow_remove &&\n-\t\t    remove_file_from_cache(path))\n+\t\t    remove_file_from_index(istate, path))\n \t\t\treturn error(\"%s: cannot remove from the index\", path);\n \t\treturn 0;\n \t}\n@@ -473,7 +473,7 @@ static void update_one(const char *path)\n \t}\n \n \tif (force_remove) {\n-\t\tif (remove_file_from_cache(path))\n+\t\tif (remove_file_from_index(istate, path))\n \t\t\tdie(\"git update-index: unable to remove %s\", path);\n \t\treport(\"remove '%s'\", path);\n \t\treturn;\n@@ -556,7 +556,7 @@ static void read_index_info(int nul_term_line)\n \n \t\tif (!mode) {\n \t\t\t/* mode == 0 means there is no such path -- remove */\n-\t\t\tif (remove_file_from_cache(path_name))\n+\t\t\tif (remove_file_from_index(istate, path_name))\n \t\t\t\tdie(\"git update-index: unable to remove %s\",\n \t\t\t\t    ptr);\n \t\t}\n@@ -671,7 +671,7 @@ static int unresolve_one(const char *path)\n \t\tgoto free_return;\n \t}\n \n-\tremove_file_from_cache(path);\n+\tremove_file_from_index(istate, path);\n \tif (add_cache_entry(ce_2, ADD_CACHE_OK_TO_ADD)) {\n \t\terror(\"%s: cannot add our version to the index.\", path);\n \t\tret = -1;\n-- \ngitgitgadget\n\n"},{"id":"413429","messageId":"5091e2661d1a38a24883a8e366a07d92be95c9e6.1609821783.git.gitgitgadget@gmail.com","threadId":"54916","inReplyTo":"pull.830.v2.git.1609821783.gitgitgadget@gmail.com","subject":"[PATCH v2 06/14] update-index: use istate->cache_changed","fromName":"Derrick Stolee via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-01-05T04:42:55Z","receivedAt":"2021-01-05T04:44:37Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"From: Derrick Stolee <dstolee@microsoft.com>\n\nThis is a mechanical replacement of active_cache_changed.\n\nSigned-off-by: Derrick Stolee <dstolee@microsoft.com>\n---\n builtin/update-index.c | 10 +++++-----\n 1 file changed, 5 insertions(+), 5 deletions(-)\n\ndiff --git a/builtin/update-index.c b/builtin/update-index.c\nindex 106bfdab78e..346d798c60b 100644\n--- a/builtin/update-index.c\n+++ b/builtin/update-index.c\n@@ -242,7 +242,7 @@ static int mark_ce_flags(const char *path, int flag, int mark)\n \t\t\tistate->cache[pos]->ce_flags &= ~flag;\n \t\tistate->cache[pos]->ce_flags |= CE_UPDATE_IN_BASE;\n \t\tcache_tree_invalidate_path(istate, path);\n-\t\tactive_cache_changed |= CE_ENTRY_CHANGED;\n+\t\tistate->cache_changed |= CE_ENTRY_CHANGED;\n \t\treturn 0;\n \t}\n \treturn -1;\n@@ -915,7 +915,7 @@ static enum parse_opt_result unresolve_callback(\n \t*has_errors = do_unresolve(ctx->argc, ctx->argv,\n \t\t\t\tprefix, prefix ? strlen(prefix) : 0);\n \tif (*has_errors)\n-\t\tactive_cache_changed = 0;\n+\t\tistate->cache_changed = 0;\n \n \tctx->argv += ctx->argc - 1;\n \tctx->argc = 1;\n@@ -936,7 +936,7 @@ static enum parse_opt_result reupdate_callback(\n \tsetup_work_tree();\n \t*has_errors = do_reupdate(ctx->argc, ctx->argv, prefix);\n \tif (*has_errors)\n-\t\tactive_cache_changed = 0;\n+\t\tistate->cache_changed = 0;\n \n \tctx->argv += ctx->argc - 1;\n \tctx->argc = 1;\n@@ -1135,7 +1135,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \t\t\t    INDEX_FORMAT_LB, INDEX_FORMAT_UB);\n \n \t\tif (istate->version != preferred_index_format)\n-\t\t\tactive_cache_changed |= SOMETHING_CHANGED;\n+\t\t\tistate->cache_changed |= SOMETHING_CHANGED;\n \t\tistate->version = preferred_index_format;\n \t}\n \n@@ -1223,7 +1223,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \t\treport(_(\"fsmonitor disabled\"));\n \t}\n \n-\tif (active_cache_changed || force_write) {\n+\tif (istate->cache_changed || force_write) {\n \t\tif (newfd < 0) {\n \t\t\tif (refresh_args.flags & REFRESH_QUIET)\n \t\t\t\texit(128);\n-- \ngitgitgadget\n\n"},{"id":"413430","messageId":"457402b4fdcab4b2d390733d1d5cc9174a318e89.1609821783.git.gitgitgadget@gmail.com","threadId":"54916","inReplyTo":"pull.830.v2.git.1609821783.gitgitgadget@gmail.com","subject":"[PATCH v2 13/14] update-index: reduce static globals, part 2","fromName":"Derrick Stolee via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-01-05T04:43:02Z","receivedAt":"2021-01-05T04:44:39Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"From: Derrick Stolee <dstolee@microsoft.com>\n\nIn order to remove index compatibility macros cleanly, we relied upon\nstatic globals 'repo' and 'istate' to be pointers to the_repository and\nthe_index, respectively. We can continue reducing the need for these\nstatic globals by modifying method prototypes to use them when\nnecessary.\n\nMove these static globals further down the file so we can identify which\nmethods need both 'struct repository *repo' and 'struct index_state\n*istate' parameters. The only changes included here adjust method\nprototypes and their call locations.\n\nThe only remaining change is to remove the static globals entirely, but\nthat requires updating the parse-opt callbacks, which need a different\nsolution.\n\nSigned-off-by: Derrick Stolee <dstolee@microsoft.com>\n---\n builtin/update-index.c | 36 ++++++++++++++++++++++--------------\n 1 file changed, 22 insertions(+), 14 deletions(-)\n\ndiff --git a/builtin/update-index.c b/builtin/update-index.c\nindex 6b585fb8ede..fb8d7879783 100644\n--- a/builtin/update-index.c\n+++ b/builtin/update-index.c\n@@ -594,10 +594,9 @@ static const char * const update_index_usage[] = {\n static struct object_id head_oid;\n static struct object_id merge_head_oid;\n \n-static struct repository *repo;\n-static struct index_state *istate;\n-\n-static struct cache_entry *read_one_ent(const char *which,\n+static struct cache_entry *read_one_ent(struct repository *repo,\n+\t\t\t\t\tstruct index_state *istate,\n+\t\t\t\t\tconst char *which,\n \t\t\t\t\tstruct object_id *ent, const char *path,\n \t\t\t\t\tint namelen, int stage)\n {\n@@ -625,7 +624,9 @@ static struct cache_entry *read_one_ent(const char *which,\n \treturn ce;\n }\n \n-static int unresolve_one(const char *path)\n+static int unresolve_one(struct repository *repo,\n+\t\t\t struct index_state *istate,\n+\t\t\t const char *path)\n {\n \tint namelen = strlen(path);\n \tint pos;\n@@ -667,8 +668,8 @@ static int unresolve_one(const char *path)\n \t * stuff HEAD version in stage #2,\n \t * stuff MERGE_HEAD version in stage #3.\n \t */\n-\tce_2 = read_one_ent(\"our\", &head_oid, path, namelen, 2);\n-\tce_3 = read_one_ent(\"their\", &merge_head_oid, path, namelen, 3);\n+\tce_2 = read_one_ent(repo, istate, \"our\", &head_oid, path, namelen, 2);\n+\tce_3 = read_one_ent(repo, istate, \"their\", &merge_head_oid, path, namelen, 3);\n \n \tif (!ce_2 || !ce_3) {\n \t\tret = -1;\n@@ -707,7 +708,9 @@ static void read_head_pointers(void)\n \t}\n }\n \n-static int do_unresolve(int ac, const char **av,\n+static int do_unresolve(struct repository *repo,\n+\t\t\tstruct index_state *istate,\n+\t\t\tint ac, const char **av,\n \t\t\tconst char *prefix, int prefix_length)\n {\n \tint i;\n@@ -721,13 +724,15 @@ static int do_unresolve(int ac, const char **av,\n \tfor (i = 1; i < ac; i++) {\n \t\tconst char *arg = av[i];\n \t\tchar *p = prefix_path(prefix, prefix_length, arg);\n-\t\terr |= unresolve_one(p);\n+\t\terr |= unresolve_one(repo, istate, p);\n \t\tfree(p);\n \t}\n \treturn err;\n }\n \n-static int do_reupdate(int ac, const char **av,\n+static int do_reupdate(struct repository *repo,\n+\t\t       struct index_state *istate,\n+\t\t       int ac, const char **av,\n \t\t       const char *prefix)\n {\n \t/* Read HEAD and run update-index on paths that are\n@@ -756,7 +761,7 @@ static int do_reupdate(int ac, const char **av,\n \t\tif (ce_stage(ce) || !ce_path_match(istate, ce, &pathspec, NULL))\n \t\t\tcontinue;\n \t\tif (has_head)\n-\t\t\told = read_one_ent(NULL, &head_oid,\n+\t\t\told = read_one_ent(repo, istate, NULL, &head_oid,\n \t\t\t\t\t   ce->name, ce_namelen(ce), 0);\n \t\tif (old && ce->ce_mode == old->ce_mode &&\n \t\t    oideq(&ce->oid, &old->oid)) {\n@@ -784,6 +789,9 @@ struct refresh_params {\n \tint *has_errors;\n };\n \n+static struct repository *repo;\n+static struct index_state *istate;\n+\n static int refresh(struct refresh_params *o, unsigned int flag)\n {\n \tsetup_work_tree();\n@@ -923,8 +931,8 @@ static enum parse_opt_result unresolve_callback(\n \tBUG_ON_OPT_ARG(arg);\n \n \t/* consume remaining arguments. */\n-\t*has_errors = do_unresolve(ctx->argc, ctx->argv,\n-\t\t\t\tprefix, prefix ? strlen(prefix) : 0);\n+\t*has_errors = do_unresolve(repo, istate, ctx->argc, ctx->argv,\n+\t\t\t\t   prefix, prefix ? strlen(prefix) : 0);\n \tif (*has_errors)\n \t\tistate->cache_changed = 0;\n \n@@ -945,7 +953,7 @@ static enum parse_opt_result reupdate_callback(\n \n \t/* consume remaining arguments. */\n \tsetup_work_tree();\n-\t*has_errors = do_reupdate(ctx->argc, ctx->argv, prefix);\n+\t*has_errors = do_reupdate(repo, istate, ctx->argc, ctx->argv, prefix);\n \tif (*has_errors)\n \t\tistate->cache_changed = 0;\n \n-- \ngitgitgadget\n\n"},{"id":"413431","messageId":"f1cffe2b4552378b79c501d52dc67711d8d1e21c.1609821783.git.gitgitgadget@gmail.com","threadId":"54916","inReplyTo":"pull.830.v2.git.1609821783.gitgitgadget@gmail.com","subject":"[PATCH v2 11/14] update-index: remove ce_match_stat(), all macros","fromName":"Derrick Stolee via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-01-05T04:43:00Z","receivedAt":"2021-01-05T04:44:39Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"From: Derrick Stolee <dstolee@microsoft.com>\n\nThe final index compatibility macro to remove from the update-index\nbuiltin is ce_match_stat(). Further, this is the last use of that macro\nanywhere, so it should be removed.\n\nThere are some remaining references in the racy-git.txt technical\ndocument that are updated to ie_match_stat().\n\nSigned-off-by: Derrick Stolee <dstolee@microsoft.com>\n---\n Documentation/technical/racy-git.txt | 6 +++---\n builtin/update-index.c               | 3 +--\n cache.h                              | 1 -\n 3 files changed, 4 insertions(+), 6 deletions(-)\n\ndiff --git a/Documentation/technical/racy-git.txt b/Documentation/technical/racy-git.txt\nindex ceda4bbfda4..65188e04559 100644\n--- a/Documentation/technical/racy-git.txt\n+++ b/Documentation/technical/racy-git.txt\n@@ -26,7 +26,7 @@ information obtained from the filesystem via `lstat(2)` system\n call when they were last updated.  When checking if they differ,\n Git first runs `lstat(2)` on the files and compares the result\n with this information (this is what was originally done by the\n-`ce_match_stat()` function, but the current code does it in\n+`ie_match_stat()` function, but the current code does it in\n `ce_match_stat_basic()` function).  If some of these \"cached\n stat information\" fields do not match, Git can tell that the\n files are modified without even looking at their contents.\n@@ -102,7 +102,7 @@ timestamp as the index file itself.\n \n The callers that want to check if an index entry matches the\n corresponding file in the working tree continue to call\n-`ce_match_stat()`, but with this change, `ce_match_stat()` uses\n+`ie_match_stat()`, but with this change, `ie_match_stat()` uses\n `ce_modified_check_fs()` to see if racily clean ones are\n actually clean after comparing the cached stat information using\n `ce_match_stat_basic()`.\n@@ -128,7 +128,7 @@ Runtime penalty\n ---------------\n \n The runtime penalty of falling back to `ce_modified_check_fs()`\n-from `ce_match_stat()` can be very expensive when there are many\n+from `ie_match_stat()` can be very expensive when there are many\n racily clean entries.  An obvious way to artificially create\n this situation is to give the same timestamp to all the files in\n the working tree in a large project, run `git update-index` on\ndiff --git a/builtin/update-index.c b/builtin/update-index.c\nindex dd8e0acc52e..8fc680090be 100644\n--- a/builtin/update-index.c\n+++ b/builtin/update-index.c\n@@ -3,7 +3,6 @@\n  *\n  * Copyright (C) Linus Torvalds, 2005\n  */\n-#define USE_THE_INDEX_COMPATIBILITY_MACROS\n #include \"cache.h\"\n #include \"config.h\"\n #include \"lockfile.h\"\n@@ -277,7 +276,7 @@ static int add_one_path(const struct cache_entry *old, const char *path, int len\n \tstruct cache_entry *ce;\n \n \t/* Was the old index entry already up-to-date? */\n-\tif (old && !ce_stage(old) && !ce_match_stat(old, st, 0))\n+\tif (old && !ce_stage(old) && !ie_match_stat(istate, old, st, 0))\n \t\treturn 0;\n \n \tce = make_empty_cache_entry(istate, len);\ndiff --git a/cache.h b/cache.h\nindex 8c091be6256..740bd0aa1dd 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -416,7 +416,6 @@ extern struct index_state the_index;\n #define chmod_cache_entry(ce, flip) chmod_index_entry(&the_index, (ce), (flip))\n #define refresh_cache(flags) refresh_index(&the_index, (flags), NULL, NULL, NULL)\n #define refresh_and_write_cache(refresh_flags, write_flags, gentle) repo_refresh_and_write_index(the_repository, (refresh_flags), (write_flags), (gentle), NULL, NULL, NULL)\n-#define ce_match_stat(ce, st, options) ie_match_stat(&the_index, (ce), (st), (options))\n #define ce_modified(ce, st, options) ie_modified(&the_index, (ce), (st), (options))\n #define cache_dir_exists(name, namelen) index_dir_exists(&the_index, (name), (namelen))\n #define cache_name_is_other(name, namelen) index_name_is_other(&the_index, (name), (namelen))\n-- \ngitgitgadget\n\n"},{"id":"413525","messageId":"xmqqczyiwwgl.fsf@gitster.c.googlers.com","threadId":"54916","inReplyTo":"pull.830.git.1609506428.gitgitgadget@gmail.com","subject":"Re: [PATCH 00/12] Remove more index compatibility macros","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2021-01-06T03:55:22Z","receivedAt":"2021-01-06T03:56:11Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Derrick Stolee via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n\n> My strategy for update-index was to create static globals \"repo\" and\n> \"istate\" that point to the_repository and the_index, respectively. Then, I\n> was able to remove macros one-by-one without changing method prototypes\n> within the file.\n\nKnee-jerk reaction: swapping one pair of global with another?  Would\nthat give us enough upside?  It may allow some codepaths involved to\nwork on an in-core index instance that is different from the_index,\nbut does not make them reentrant.\n\nDo we now have callers that actually pass an in-core index instance\nthat is different from the_index, and more importantly, that fail\nloudly if the codepaths involved in this conversion forgets to\nupdate some accesses to the_index not to the specified one?\n\nIf not, ... \n\n> In total, this allows us to remove four of the compatibility macros because\n> they are no longer used.\n\n... a conversion like this, removing the use of the compatibility\nmacros for the sake of removing them, invites future headaches by\nleaving untested code churn behind with potential bugs that will\nonly get discovered after somebody actually starts making calls\nwith the non-default in-core index instances.\n\nI've come to know the competence of you well enough to trust your\npatches like patches from other proficient, prolific and prominent\ncontributors (I won't name names, but you know who you are), but we\nare all human and are prone to introduce bugs.\n\nThat's all my knee-jerk impression before actually reading the\nseries through, though.  I'll certainloy know more after reading\nthem.\n\nThanks.\n\n> Derrick Stolee (12):\n>   merge-index: drop index compatibility macros\n>   mv: remove index compatibility macros\n>   rm: remove compatilibity macros\n>   update-index: drop the_index, the_repository\n>   update-index: use istate->cache over active_cache\n>   update-index: use index->cache_nr over active_nr\n>   update-index: use istate->cache_changed\n>   update-index: use index_name_pos() over cache_name_pos()\n>   update-index: use remove_file_from_index()\n>   update-index: use add_index_entry()\n>   update-index: replace several compatibility macros\n>   update-index: remove ce_match_stat(), all macros\n>\n>  Documentation/technical/racy-git.txt |   6 +-\n>  builtin/merge-index.c                |  33 +++---\n>  builtin/mv.c                         |  42 ++++----\n>  builtin/rm.c                         |  56 ++++++-----\n>  builtin/update-index.c               | 145 ++++++++++++++-------------\n>  cache.h                              |   4 -\n>  6 files changed, 149 insertions(+), 137 deletions(-)\n>\n>\n> base-commit: 71ca53e8125e36efbda17293c50027d31681a41f\n> Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-830%2Fderrickstolee%2Findex-compatibility-1-v1\n> Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-830/derrickstolee/index-compatibility-1-v1\n> Pull-Request: https://github.com/gitgitgadget/git/pull/830\n"},{"id":"413564","messageId":"a93359c3-66bf-80bc-f053-4742563163d0@gmail.com","threadId":"54916","inReplyTo":"xmqqczyiwwgl.fsf@gitster.c.googlers.com","subject":"Re: [PATCH 00/12] Remove more index compatibility macros","fromName":"Derrick Stolee","fromEmail":"stolee@gmail.com","sentAt":"2021-01-06T11:35:53Z","receivedAt":"2021-01-06T11:36:56Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"On 1/5/2021 10:55 PM, Junio C Hamano wrote:\n> \"Derrick Stolee via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n> \n>> My strategy for update-index was to create static globals \"repo\" and\n>> \"istate\" that point to the_repository and the_index, respectively. Then, I\n>> was able to remove macros one-by-one without changing method prototypes\n>> within the file.\n> \n> Knee-jerk reaction: swapping one pair of global with another?  Would\n> that give us enough upside?  It may allow some codepaths involved to\n> work on an in-core index instance that is different from the_index,\n> but does not make them reentrant.\n\nMy intention was to reduce the use of globals in libgit.a while keeping\nwith existing patterns of static globals in the builtin code. While\nthis can be thought of \"module variables\" instead of true globals, they\naren't exactly desirable. In v2, these static globals are temporary to\nthe series and are completely removed by the end.\n\nThe new patch sequence can hopefully be seen as \"this preprocessor\nmacro was expanded\" and then \"static globals are replaced with\nmethod parameters\" which are pretty straightforward.\n\n> Do we now have callers that actually pass an in-core index instance\n> that is different from the_index, and more importantly, that fail\n> loudly if the codepaths involved in this conversion forgets to\n> update some accesses to the_index not to the specified one?\n> \n> If not, ... \n> \n>> In total, this allows us to remove four of the compatibility macros because\n>> they are no longer used.\n> \n> ... a conversion like this, removing the use of the compatibility\n> macros for the sake of removing them, invites future headaches by\n> leaving untested code churn behind with potential bugs that will\n> only get discovered after somebody actually starts making calls\n> with the non-default in-core index instances.\n\nPerhaps I had misunderstood the state of the conversion project. I\nthought that the full conversion was just paused because Duy moved\non to other things. I thought it might be valuable to pick up the\nbaton while also thinking about the space.\n\nIf this is _not_ a valuable project to continue, then I can hold\noff for now.\n\nUnfortunately, we'll never know if everything is safe from assuming\nthe_index until the macro itself is gone. It helps that libgit.a\ndoesn't use it at \n\n> I've come to know the competence of you well enough to trust your\n> patches like patches from other proficient, prolific and prominent\n> contributors (I won't name names, but you know who you are), but we\n> are all human and are prone to introduce bugs.\n\nThat means a lot, thanks. And yes, I'm well aware that bugs can be\nintroduced. I've added my share.\n\n> That's all my knee-jerk impression before actually reading the\n> series through, though.  I'll certainloy know more after reading\n> them.\n\nI look forward to your thoughts.\n\nThanks,\n-Stolee\n"},{"id":"413603","messageId":"xmqqpn2hrdo1.fsf@gitster.c.googlers.com","threadId":"54916","inReplyTo":"a93359c3-66bf-80bc-f053-4742563163d0@gmail.com","subject":"Re: [PATCH 00/12] Remove more index compatibility macros","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2021-01-06T20:52:30Z","receivedAt":"2021-01-06T20:53:18Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Derrick Stolee <stolee@gmail.com> writes:\n\n> My intention was to reduce the use of globals in libgit.a while keeping\n> with existing patterns of static globals in the builtin code.\n\nThe above (without having thought about it too hard or long enough\nyet) sounds a sensible guideline to go by.  Thanks for a helpful\nhint to keep in mind while reading the series.\n\n> While\n> this can be thought of \"module variables\" instead of true globals, they\n> aren't exactly desirable. In v2, these static globals are temporary to\n> the series and are completely removed by the end.\n\n;-)\n"},{"id":"413643","messageId":"CAPig+cTfHsd7WMvcX1_433WVOG+y4FceUACBx_4UfnjJTgVY6g@mail.gmail.com","threadId":"54916","inReplyTo":"2b171a142b36b114d5ff526073fe3fd9517a4d32.1609821783.git.gitgitgadget@gmail.com","subject":"Re: [PATCH v2 14/14] update-index: remove static globals from callbacks","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2021-01-07T05:09:18Z","receivedAt":"2021-01-07T05:10:13Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Mon, Jan 4, 2021 at 11:43 PM Derrick Stolee via GitGitGadget\n<gitgitgadget@gmail.com> wrote:\n> In order to remove index compatibility macros cleanly, we relied upon\n> static globals 'repo' and 'istate' to be pointers to the_repository and\n> the_index, respectively. We remove these static globals inside the\n> option parsing callbacks, which are the final uses in update-index.\n>\n> The callbacks cannot change their method signature, so we must use the\n> value member of 'struct option', assigned in the array of option macros.\n> There are several callback methods that require at least one of 'repo'\n> and 'istate', but they use a variety of different data types for the\n> callback value.\n>\n> Unify these callback methods to use a consistent 'struct callback_data'\n> that contains 'repo' and 'istate', ready to use. This takes the place of\n> the previous 'struct refresh_params' which served only to group the\n> 'flags' and 'has_errors' ints. We also collect other one-off settings,\n> but only those that require access to the index or repository in their\n> operation.\n\nMakes sense. The patch itself is necessarily a bit noisy, but there's\nnothing particularly complicated in that noise.\n\n> Signed-off-by: Derrick Stolee <dstolee@microsoft.com>\n> ---\n> diff --git a/builtin/update-index.c b/builtin/update-index.c\n> @@ -784,19 +784,21 @@ static int do_reupdate(struct repository *repo,\n> -struct refresh_params {\n> +struct callback_data {\n> +       struct repository *repo;\n> +       struct index_state *istate;\n> +\n>         unsigned int flags;\n> -       int *has_errors;\n> +       unsigned int has_errors;\n> +       unsigned nul_term_line;\n> +       unsigned read_from_stdin;\n>  };\n\nThe only mildly unexpected thing here is that `has_errors` is now a\nsimple value rather than a pointer to a value, but you handle that\neasily enough by always accessing `has_error` directly from the\nstructure, even within the function in which `has_error` used to be a\nlocal variable. Fine.\n\n> @@ -818,7 +820,7 @@ static int really_refresh_callback(const struct option *opt,\n>  static int chmod_callback(const struct option *opt,\n> -                               const char *arg, int unset)\n> +                         const char *arg, int unset)\n> @@ -829,11 +831,12 @@ static int chmod_callback(const struct option *opt,\n>  static int resolve_undo_clear_callback(const struct option *opt,\n> -                               const char *arg, int unset)\n> +                                      const char *arg, int unset)\n\nA couple drive-by indentation fixes. Okay.\n\n> @@ -1098,8 +1103,13 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n> -       istate = repo->index;\n> +       cd.repo = repo;\n> +       cd.istate = istate = repo->index;\n\nWill there ever be a case in which `cd.istate` will be different from\n`cd.repo->index`? If not, then we could get by with having only\n`cd.repo`; callers requiring access to `istate` can fetch it from\n`cd.repo`. If, on the other hand, `cd.istate` can be different from\n`cd.repo->istate` -- or if that might become a possibility in the\nfuture -- then having `cd.istate` makes sense. Not a big deal, though.\nJust generally curious about it.\n"},{"id":"413682","messageId":"73f51832-583a-27e8-65fa-86eb0ebac4cf@gmail.com","threadId":"54916","inReplyTo":"CAPig+cTfHsd7WMvcX1_433WVOG+y4FceUACBx_4UfnjJTgVY6g@mail.gmail.com","subject":"Re: [PATCH v2 14/14] update-index: remove static globals from callbacks","fromName":"Derrick Stolee","fromEmail":"stolee@gmail.com","sentAt":"2021-01-07T11:19:47Z","receivedAt":"2021-01-07T11:20:46Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"On 1/7/2021 12:09 AM, Eric Sunshine wrote:\n> On Mon, Jan 4, 2021 at 11:43 PM Derrick Stolee via GitGitGadget\n> <gitgitgadget@gmail.com> wrote:\n>> @@ -1098,8 +1103,13 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n>> -       istate = repo->index;\n>> +       cd.repo = repo;\n>> +       cd.istate = istate = repo->index;\n> \n> Will there ever be a case in which `cd.istate` will be different from\n> `cd.repo->index`? If not, then we could get by with having only\n> `cd.repo`; callers requiring access to `istate` can fetch it from\n> `cd.repo`. If, on the other hand, `cd.istate` can be different from\n> `cd.repo->istate` -- or if that might become a possibility in the\n> future -- then having `cd.istate` makes sense. Not a big deal, though.\n> Just generally curious about it.\n \nI don't believe that 'istate' and 'repo->index' will ever be\ndifferent in this file. This includes the members of the\ncallback_data struct, but also the method parameters throughout.\n\nMostly, this could be seen as an artifact of how we got here:\n\n1. References to the_index or other compatibility macros were\n   converted to use the static global 'istate'.\n\n2. References to the static global 'istate' were replaced with\n   method parameters for everything except these callbacks.\n\n3. These callbacks were updated to use 'cd.istate' instead of\n   the (now defunct) static global 'istate'.\n\nIt could be possible to replace all references to 'istate' with\n'repo->index' but the patches get slightly more messy. I also\nthink the code looks messier, but you do make a good point that\nthere is no concrete reason to separate the two.\n\nThanks,\n-Stolee\n"},{"id":"413719","messageId":"CAPig+cSLsLibDik3YYTPdwbHpywStMxR_4rRBZfYrX7S-cFnNA@mail.gmail.com","threadId":"54916","inReplyTo":"73f51832-583a-27e8-65fa-86eb0ebac4cf@gmail.com","subject":"Re: [PATCH v2 14/14] update-index: remove static globals from callbacks","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2021-01-07T18:53:40Z","receivedAt":"2021-01-07T18:54:55Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Thu, Jan 7, 2021 at 6:19 AM Derrick Stolee <stolee@gmail.com> wrote:\n> On 1/7/2021 12:09 AM, Eric Sunshine wrote:\n> > Will there ever be a case in which `cd.istate` will be different from\n> > `cd.repo->index`? If not, then we could get by with having only\n> > `cd.repo`; callers requiring access to `istate` can fetch it from\n> > `cd.repo`. If, on the other hand, `cd.istate` can be different from\n> > `cd.repo->istate` -- or if that might become a possibility in the\n> > future -- then having `cd.istate` makes sense. Not a big deal, though.\n> > Just generally curious about it.\n>\n> I don't believe that 'istate' and 'repo->index' will ever be\n> different in this file. This includes the members of the\n> callback_data struct, but also the method parameters throughout.\n>\n> It could be possible to replace all references to 'istate' with\n> 'repo->index' but the patches get slightly more messy. I also\n> think the code looks messier, but you do make a good point that\n> there is no concrete reason to separate the two.\n\nI agree that it would make the code a bit noisier (to read) if\n`istate` is eliminated from the callback structure, however, even\nthough I didn't originally feel strongly one way or the other about\nhaving both `repo` and `istate` in the structure, I'm now leaning more\ntoward seeing `istate` eliminated. My one (big) concern with `istate`\nis that it confuses readers into wondering whether `istate` and\n`repo->istate` will ever be different. One way to avoid such confusion\nwould be to leave a comment in the code stating that the two values\nwill always be the same. The other way, of course, is to eliminate\n`istate` from the structure altogether. I don't want to make more work\nfor you, but the more I think about it, the more I feel that removing\n`istate` is the sensible thing to do. (And it doesn't require an extra\npatch -- it can just be how this patch is crafted -- without ever\nintroducing `istate` to the structure in the first place.)\n"},{"id":"413720","messageId":"xmqq4kjsmses.fsf@gitster.c.googlers.com","threadId":"54916","inReplyTo":"CAPig+cSLsLibDik3YYTPdwbHpywStMxR_4rRBZfYrX7S-cFnNA@mail.gmail.com","subject":"Re: [PATCH v2 14/14] update-index: remove static globals from callbacks","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2021-01-07T19:57:31Z","receivedAt":"2021-01-07T19:58:20Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Eric Sunshine <sunshine@sunshineco.com> writes:\n\n>> It could be possible to replace all references to 'istate' with\n>> 'repo->index' but the patches get slightly more messy. I also\n>> think the code looks messier, but you do make a good point that\n>> there is no concrete reason to separate the two.\n>\n> I agree that it would make the code a bit noisier (to read) if\n> `istate` is eliminated from the callback structure, however, even\n> though I didn't originally feel strongly one way or the other about\n> having both `repo` and `istate` in the structure, I'm now leaning more\n> toward seeing `istate` eliminated. My one (big) concern with `istate`\n> is that it confuses readers into wondering whether `istate` and\n> `repo->istate` will ever be different.\n\nSome applications may want to work on more than one in-core index at\nthe same time (perhaps a merge strategy may want to keep a copy of\nthe original index and update a second copy with the result of the\nmerge), and it may be useful for such applications if 'repo->istate'\ndoes not have to be the in-core index instance to be worked on.  So\nthings that go in libgit.a may want to allow such distinction.\n\nBut what goes in builtin/ is a different story.  As long as this\napplication has no need for such a feature and will always work on\nthe primary in-core index, prepared for the in-core repository\nstructure for convenience, it may not worth it to support such a\nfeature that no callers benefit from.\n\nThanks.\n"},{"id":"413776","messageId":"e598f0e4-bdd9-4b59-f267-545204829a63@gmail.com","threadId":"54916","inReplyTo":"xmqq4kjsmses.fsf@gitster.c.googlers.com","subject":"Re: [PATCH v2 14/14] update-index: remove static globals from callbacks","fromName":"Derrick Stolee","fromEmail":"stolee@gmail.com","sentAt":"2021-01-08T01:52:12Z","receivedAt":"2021-01-08T01:53:11Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"On 1/7/2021 2:57 PM, Junio C Hamano wrote:\n> Eric Sunshine <sunshine@sunshineco.com> writes:\n> \n>>> It could be possible to replace all references to 'istate' with\n>>> 'repo->index' but the patches get slightly more messy. I also\n>>> think the code looks messier, but you do make a good point that\n>>> there is no concrete reason to separate the two.\n>>\n>> I agree that it would make the code a bit noisier (to read) if\n>> `istate` is eliminated from the callback structure, however, even\n>> though I didn't originally feel strongly one way or the other about\n>> having both `repo` and `istate` in the structure, I'm now leaning more\n>> toward seeing `istate` eliminated. My one (big) concern with `istate`\n>> is that it confuses readers into wondering whether `istate` and\n>> `repo->istate` will ever be different.\n> \n> Some applications may want to work on more than one in-core index at\n> the same time (perhaps a merge strategy may want to keep a copy of\n> the original index and update a second copy with the result of the\n> merge), and it may be useful for such applications if 'repo->istate'\n> does not have to be the in-core index instance to be worked on.  So\n> things that go in libgit.a may want to allow such distinction.\n> \n> But what goes in builtin/ is a different story.  As long as this\n> application has no need for such a feature and will always work on\n> the primary in-core index, prepared for the in-core repository\n> structure for convenience, it may not worth it to support such a\n> feature that no callers benefit from.\n\nI'll try to restructure my patches to do the following order:\n\n1. replace compatibility macros with static global references, except\n   i. use 'istate' in the methods that don't need a repository.\n  ii. use 'repo->index' in the methods that need a repository.\n\n2. replace static globals with method parameters.\n   i. drop 'istate' static global with method parameters. Methods that\n      have a repo will pass 'repo->index' to these methods.\n  ii. drop 'repo' static global with method parameters.\n\n3. replace static globals in callback methods using 'repo->index',\n   where 'repo' is a member of the callback_data struct.\n\nThat should keep the structure as presented in v2 while also avoiding\nthis question of \"can istate differ from repo->index?\"\n\nThanks,\n-Stolee\n"},{"id":"413872","messageId":"5ccc464cf268476932197c790693e1ecea9e778c.1610136177.git.gitgitgadget@gmail.com","threadId":"54916","inReplyTo":"pull.830.v3.git.1610136177.gitgitgadget@gmail.com","subject":"[PATCH v3 01/14] mv: remove index compatibility macros","fromName":"Derrick Stolee via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-01-08T20:02:44Z","receivedAt":"2021-01-08T20:03:57Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"From: Derrick Stolee <dstolee@microsoft.com>\n\nThe mv builtin uses the compatibility macros to interact with the index.\nUpdate these to use modern methods referring to a 'struct index_state'\npointer. Several helper methods need to be updated to consider such a\npointer, but the modifications are rudimentary.\n\nTwo macros can be deleted from cache.h because these are the last uses.\n\nSigned-off-by: Derrick Stolee <dstolee@microsoft.com>\n---\n builtin/mv.c | 42 +++++++++++++++++++++++-------------------\n cache.h      |  2 --\n 2 files changed, 23 insertions(+), 21 deletions(-)\n\ndiff --git a/builtin/mv.c b/builtin/mv.c\nindex 7dac714af90..0055d49a8a7 100644\n--- a/builtin/mv.c\n+++ b/builtin/mv.c\n@@ -3,7 +3,6 @@\n  *\n  * Copyright (C) 2006 Johannes Schindelin\n  */\n-#define USE_THE_INDEX_COMPATIBILITY_MACROS\n #include \"builtin.h\"\n #include \"config.h\"\n #include \"pathspec.h\"\n@@ -75,13 +74,14 @@ static const char *add_slash(const char *path)\n \n #define SUBMODULE_WITH_GITDIR ((const char *)1)\n \n-static void prepare_move_submodule(const char *src, int first,\n+static void prepare_move_submodule(struct index_state *istate,\n+\t\t\t\t   const char *src, int first,\n \t\t\t\t   const char **submodule_gitfile)\n {\n \tstruct strbuf submodule_dotgit = STRBUF_INIT;\n-\tif (!S_ISGITLINK(active_cache[first]->ce_mode))\n+\tif (!S_ISGITLINK(istate->cache[first]->ce_mode))\n \t\tdie(_(\"Directory %s is in index and no submodule?\"), src);\n-\tif (!is_staging_gitmodules_ok(&the_index))\n+\tif (!is_staging_gitmodules_ok(istate))\n \t\tdie(_(\"Please stage your changes to .gitmodules or stash them to proceed\"));\n \tstrbuf_addf(&submodule_dotgit, \"%s/.git\", src);\n \t*submodule_gitfile = read_gitfile(submodule_dotgit.buf);\n@@ -92,19 +92,20 @@ static void prepare_move_submodule(const char *src, int first,\n \tstrbuf_release(&submodule_dotgit);\n }\n \n-static int index_range_of_same_dir(const char *src, int length,\n+static int index_range_of_same_dir(struct index_state *istate,\n+\t\t\t\t   const char *src, int length,\n \t\t\t\t   int *first_p, int *last_p)\n {\n \tconst char *src_w_slash = add_slash(src);\n \tint first, last, len_w_slash = length + 1;\n \n-\tfirst = cache_name_pos(src_w_slash, len_w_slash);\n+\tfirst = index_name_pos(istate, src_w_slash, len_w_slash);\n \tif (first >= 0)\n \t\tdie(_(\"%.*s is in index\"), len_w_slash, src_w_slash);\n \n \tfirst = -1 - first;\n-\tfor (last = first; last < active_nr; last++) {\n-\t\tconst char *path = active_cache[last]->name;\n+\tfor (last = first; last < istate->cache_nr; last++) {\n+\t\tconst char *path = istate->cache[last]->name;\n \t\tif (strncmp(path, src_w_slash, len_w_slash))\n \t\t\tbreak;\n \t}\n@@ -133,6 +134,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix)\n \tstruct string_list src_for_dst = STRING_LIST_INIT_NODUP;\n \tstruct lock_file lock_file = LOCK_INIT;\n \tstruct cache_entry *ce;\n+\tstruct index_state *istate;\n \n \tgit_config(git_default_config, NULL);\n \n@@ -141,9 +143,10 @@ int cmd_mv(int argc, const char **argv, const char *prefix)\n \tif (--argc < 1)\n \t\tusage_with_options(builtin_mv_usage, builtin_mv_options);\n \n-\thold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);\n-\tif (read_cache() < 0)\n+\trepo_hold_locked_index(the_repository, &lock_file, LOCK_DIE_ON_ERROR);\n+\tif (repo_read_index(the_repository) < 0)\n \t\tdie(_(\"index file corrupt\"));\n+\tistate = the_repository->index;\n \n \tsource = internal_prefix_pathspec(prefix, argv, argc, 0);\n \tmodes = xcalloc(argc, sizeof(enum update_mode));\n@@ -190,12 +193,13 @@ int cmd_mv(int argc, const char **argv, const char *prefix)\n \t\t\t\t&& lstat(dst, &st) == 0)\n \t\t\tbad = _(\"cannot move directory over file\");\n \t\telse if (src_is_dir) {\n-\t\t\tint first = cache_name_pos(src, length), last;\n+\t\t\tint first = index_name_pos(istate, src, length);\n+\t\t\tint last;\n \n \t\t\tif (first >= 0)\n-\t\t\t\tprepare_move_submodule(src, first,\n+\t\t\t\tprepare_move_submodule(istate, src, first,\n \t\t\t\t\t\t       submodule_gitfile + i);\n-\t\t\telse if (index_range_of_same_dir(src, length,\n+\t\t\telse if (index_range_of_same_dir(istate, src, length,\n \t\t\t\t\t\t\t &first, &last) < 1)\n \t\t\t\tbad = _(\"source directory is empty\");\n \t\t\telse { /* last - first >= 1 */\n@@ -212,7 +216,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix)\n \t\t\t\tdst_len = strlen(dst);\n \n \t\t\t\tfor (j = 0; j < last - first; j++) {\n-\t\t\t\t\tconst char *path = active_cache[first + j]->name;\n+\t\t\t\t\tconst char *path = istate->cache[first + j]->name;\n \t\t\t\t\tsource[argc + j] = path;\n \t\t\t\t\tdestination[argc + j] =\n \t\t\t\t\t\tprefix_path(dst, dst_len, path + length + 1);\n@@ -221,7 +225,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix)\n \t\t\t\t}\n \t\t\t\targc += last - first;\n \t\t\t}\n-\t\t} else if (!(ce = cache_file_exists(src, length, ignore_case))) {\n+\t\t} else if (!(ce = index_file_exists(istate, src, length, ignore_case))) {\n \t\t\tbad = _(\"not under version control\");\n \t\t} else if (ce_stage(ce)) {\n \t\t\tbad = _(\"conflicted\");\n@@ -291,15 +295,15 @@ int cmd_mv(int argc, const char **argv, const char *prefix)\n \t\tif (mode == WORKING_DIRECTORY)\n \t\t\tcontinue;\n \n-\t\tpos = cache_name_pos(src, strlen(src));\n+\t\tpos = index_name_pos(istate, src, strlen(src));\n \t\tassert(pos >= 0);\n-\t\trename_cache_entry_at(pos, dst);\n+\t\trename_index_entry_at(istate, pos, dst);\n \t}\n \n \tif (gitmodules_modified)\n-\t\tstage_updated_gitmodules(&the_index);\n+\t\tstage_updated_gitmodules(istate);\n \n-\tif (write_locked_index(&the_index, &lock_file,\n+\tif (write_locked_index(istate, &lock_file,\n \t\t\t       COMMIT_LOCK | SKIP_IF_UNCHANGED))\n \t\tdie(_(\"Unable to write new index file\"));\n \ndiff --git a/cache.h b/cache.h\nindex 2d844576ead..fdf061cac56 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -409,7 +409,6 @@ extern struct index_state the_index;\n #define unmerged_cache() unmerged_index(&the_index)\n #define cache_name_pos(name, namelen) index_name_pos(&the_index,(name),(namelen))\n #define add_cache_entry(ce, option) add_index_entry(&the_index, (ce), (option))\n-#define rename_cache_entry_at(pos, new_name) rename_index_entry_at(&the_index, (pos), (new_name))\n #define remove_cache_entry_at(pos) remove_index_entry_at(&the_index, (pos))\n #define remove_file_from_cache(path) remove_file_from_index(&the_index, (path))\n #define add_to_cache(path, st, flags) add_to_index(&the_index, (path), (st), (flags))\n@@ -420,7 +419,6 @@ extern struct index_state the_index;\n #define ce_match_stat(ce, st, options) ie_match_stat(&the_index, (ce), (st), (options))\n #define ce_modified(ce, st, options) ie_modified(&the_index, (ce), (st), (options))\n #define cache_dir_exists(name, namelen) index_dir_exists(&the_index, (name), (namelen))\n-#define cache_file_exists(name, namelen, igncase) index_file_exists(&the_index, (name), (namelen), (igncase))\n #define cache_name_is_other(name, namelen) index_name_is_other(&the_index, (name), (namelen))\n #define resolve_undo_clear() resolve_undo_clear_index(&the_index)\n #define unmerge_cache_entry_at(at) unmerge_index_entry_at(&the_index, at)\n-- \ngitgitgadget\n\n"},{"id":"413873","messageId":"e715c703cb88d9a153e2925ae24c31b5bf5957ec.1610136177.git.gitgitgadget@gmail.com","threadId":"54916","inReplyTo":"pull.830.v3.git.1610136177.gitgitgadget@gmail.com","subject":"[PATCH v3 02/14] rm: remove compatilibity macros","fromName":"Derrick Stolee via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-01-08T20:02:45Z","receivedAt":"2021-01-08T20:03:57Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"From: Derrick Stolee <dstolee@microsoft.com>\n\nThe rm builtin still uses the antiquated compatibility macros for\ninteracting with the index. Update these to the more modern uses by\npassing around a 'struct index_state' pointer.\n\nSigned-off-by: Derrick Stolee <dstolee@microsoft.com>\n---\n builtin/rm.c | 56 ++++++++++++++++++++++++++++------------------------\n 1 file changed, 30 insertions(+), 26 deletions(-)\n\ndiff --git a/builtin/rm.c b/builtin/rm.c\nindex 4858631e0f0..767df8d6b25 100644\n--- a/builtin/rm.c\n+++ b/builtin/rm.c\n@@ -3,7 +3,6 @@\n  *\n  * Copyright (C) Linus Torvalds 2006\n  */\n-#define USE_THE_INDEX_COMPATIBILITY_MACROS\n #include \"builtin.h\"\n #include \"config.h\"\n #include \"lockfile.h\"\n@@ -28,12 +27,14 @@ static struct {\n \t} *entry;\n } list;\n \n-static int get_ours_cache_pos(const char *path, int pos)\n+static int get_ours_cache_pos(struct index_state *istate,\n+\t\t\t      const char *path, int pos)\n {\n \tint i = -pos - 1;\n \n-\twhile ((i < active_nr) && !strcmp(active_cache[i]->name, path)) {\n-\t\tif (ce_stage(active_cache[i]) == 2)\n+\twhile ((i < istate->cache_nr) &&\n+\t       !strcmp(istate->cache[i]->name, path)) {\n+\t\tif (ce_stage(istate->cache[i]) == 2)\n \t\t\treturn i;\n \t\ti++;\n \t}\n@@ -61,7 +62,7 @@ static void print_error_files(struct string_list *files_list,\n \t}\n }\n \n-static void submodules_absorb_gitdir_if_needed(void)\n+static void submodules_absorb_gitdir_if_needed(struct index_state *istate)\n {\n \tint i;\n \tfor (i = 0; i < list.nr; i++) {\n@@ -69,13 +70,13 @@ static void submodules_absorb_gitdir_if_needed(void)\n \t\tint pos;\n \t\tconst struct cache_entry *ce;\n \n-\t\tpos = cache_name_pos(name, strlen(name));\n+\t\tpos = index_name_pos(istate, name, strlen(name));\n \t\tif (pos < 0) {\n-\t\t\tpos = get_ours_cache_pos(name, pos);\n+\t\t\tpos = get_ours_cache_pos(istate, name, pos);\n \t\t\tif (pos < 0)\n \t\t\t\tcontinue;\n \t\t}\n-\t\tce = active_cache[pos];\n+\t\tce = istate->cache[pos];\n \n \t\tif (!S_ISGITLINK(ce->ce_mode) ||\n \t\t    !file_exists(ce->name) ||\n@@ -88,7 +89,8 @@ static void submodules_absorb_gitdir_if_needed(void)\n \t}\n }\n \n-static int check_local_mod(struct object_id *head, int index_only)\n+static int check_local_mod(struct index_state *istate,\n+\t\t\t   struct object_id *head, int index_only)\n {\n \t/*\n \t * Items in list are already sorted in the cache order,\n@@ -114,21 +116,21 @@ static int check_local_mod(struct object_id *head, int index_only)\n \t\tint local_changes = 0;\n \t\tint staged_changes = 0;\n \n-\t\tpos = cache_name_pos(name, strlen(name));\n+\t\tpos = index_name_pos(istate, name, strlen(name));\n \t\tif (pos < 0) {\n \t\t\t/*\n \t\t\t * Skip unmerged entries except for populated submodules\n \t\t\t * that could lose history when removed.\n \t\t\t */\n-\t\t\tpos = get_ours_cache_pos(name, pos);\n+\t\t\tpos = get_ours_cache_pos(istate, name, pos);\n \t\t\tif (pos < 0)\n \t\t\t\tcontinue;\n \n-\t\t\tif (!S_ISGITLINK(active_cache[pos]->ce_mode) ||\n+\t\t\tif (!S_ISGITLINK(istate->cache[pos]->ce_mode) ||\n \t\t\t    is_empty_dir(name))\n \t\t\t\tcontinue;\n \t\t}\n-\t\tce = active_cache[pos];\n+\t\tce = istate->cache[pos];\n \n \t\tif (lstat(ce->name, &st) < 0) {\n \t\t\tif (!is_missing_file_error(errno))\n@@ -165,7 +167,7 @@ static int check_local_mod(struct object_id *head, int index_only)\n \t\t * Is the index different from the file in the work tree?\n \t\t * If it's a submodule, is its work tree modified?\n \t\t */\n-\t\tif (ce_match_stat(ce, &st, 0) ||\n+\t\tif (ie_match_stat(istate, ce, &st, 0) ||\n \t\t    (S_ISGITLINK(ce->ce_mode) &&\n \t\t     bad_to_remove_submodule(ce->name,\n \t\t\t\tSUBMODULE_REMOVAL_DIE_ON_ERROR |\n@@ -257,6 +259,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix)\n \tint i;\n \tstruct pathspec pathspec;\n \tchar *seen;\n+\tstruct index_state *istate;\n \n \tgit_config(git_default_config, NULL);\n \n@@ -284,24 +287,25 @@ int cmd_rm(int argc, const char **argv, const char *prefix)\n \tif (!index_only)\n \t\tsetup_work_tree();\n \n-\thold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);\n+\trepo_hold_locked_index(the_repository, &lock_file, LOCK_DIE_ON_ERROR);\n \n-\tif (read_cache() < 0)\n+\tif (repo_read_index(the_repository) < 0)\n \t\tdie(_(\"index file corrupt\"));\n \n-\trefresh_index(&the_index, REFRESH_QUIET|REFRESH_UNMERGED, &pathspec, NULL, NULL);\n+\tistate = the_repository->index;\n+\trefresh_index(istate, REFRESH_QUIET|REFRESH_UNMERGED, &pathspec, NULL, NULL);\n \n \tseen = xcalloc(pathspec.nr, 1);\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(&the_index, ce, &pathspec, seen))\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(istate, 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);\n \t\tlist.entry[list.nr].is_submodule = S_ISGITLINK(ce->ce_mode);\n \t\tif (list.entry[list.nr++].is_submodule &&\n-\t\t    !is_staging_gitmodules_ok(&the_index))\n+\t\t    !is_staging_gitmodules_ok(istate))\n \t\t\tdie(_(\"please stage your changes to .gitmodules or stash them to proceed\"));\n \t}\n \n@@ -329,7 +333,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix)\n \t}\n \n \tif (!index_only)\n-\t\tsubmodules_absorb_gitdir_if_needed();\n+\t\tsubmodules_absorb_gitdir_if_needed(istate);\n \n \t/*\n \t * If not forced, the file, the index and the HEAD (if exists)\n@@ -345,7 +349,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix)\n \t\tstruct object_id oid;\n \t\tif (get_oid(\"HEAD\", &oid))\n \t\t\toidclr(&oid);\n-\t\tif (check_local_mod(&oid, index_only))\n+\t\tif (check_local_mod(istate, &oid, index_only))\n \t\t\texit(1);\n \t}\n \n@@ -358,7 +362,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix)\n \t\tif (!quiet)\n \t\t\tprintf(\"rm '%s'\\n\", path);\n \n-\t\tif (remove_file_from_cache(path))\n+\t\tif (remove_file_from_index(istate, path))\n \t\t\tdie(_(\"git rm: unable to remove %s\"), path);\n \t}\n \n@@ -398,10 +402,10 @@ int cmd_rm(int argc, const char **argv, const char *prefix)\n \t\t}\n \t\tstrbuf_release(&buf);\n \t\tif (gitmodules_modified)\n-\t\t\tstage_updated_gitmodules(&the_index);\n+\t\t\tstage_updated_gitmodules(istate);\n \t}\n \n-\tif (write_locked_index(&the_index, &lock_file,\n+\tif (write_locked_index(istate, &lock_file,\n \t\t\t       COMMIT_LOCK | SKIP_IF_UNCHANGED))\n \t\tdie(_(\"Unable to write new index file\"));\n \n-- \ngitgitgadget\n\n"},{"id":"413874","messageId":"pull.830.v3.git.1610136177.gitgitgadget@gmail.com","threadId":"54916","inReplyTo":"pull.830.v2.git.1609821783.gitgitgadget@gmail.com","subject":"[PATCH v3 00/14] Remove more index compatibility macros","fromName":"Derrick Stolee via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-01-08T20:02:43Z","receivedAt":"2021-01-08T20:03:57Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"UPDATE: this is now based on ag/merge-strategies-in-c to avoid conflicts in\n'seen'. The changes in builtin/rm.c still conflict with\nmt/rm-sparse-checkout, but that branch seems to be waiting for a clearer\nplan on some corner cases. I thought about ejecting it, but 'rm' still uses\nce_match_stat(), so just dropping the patch gives less of a final stake at\nthe end of the series. (I'm still open to it, if necessary.)\n\nI noticed that Duy's project around USE_THE_INDEX_COMPATIBILITY_MACROS has\nbeen on pause for a while. Here is my attempt to continue that project a\nlittle.\n\nI started going through the builtins that still use cache_name_pos() and the\nfirst was easy: mv and rm.\n\nThen I hit update-index and it was a bit bigger.\n\nMy strategy for update-index was to create static globals \"repo\" and\n\"istate\" that point to the_repository and the_index, respectively. Then, I\nwas able to remove macros one-by-one without changing method prototypes\nwithin the file. Then, these static globals were also removed by\nsystematically updating the local method prototypes, plus some fancy\nstructure stuff for the option parsing callbacks.\n\nI had started trying to keep everything local to the method signatures, but\nI hit a snag when reaching the command-line parsing callbacks, which I could\nnot modify their call signature. At that point, I had something that was\nalready much more complicated than what I present now. Outside of the first\nupdate-index commit, everything was a mechanical find/replace.\n\nIn total, this allows us to remove four of the compatibility macros because\nthey are no longer used.\n\n\nUpdates in V3\n=============\n\n * Methods that know about the 'repo' pointer no longer also have an\n   'istate' pointer and instead prefer 'repo->index'\n\n * This includes the callback_data struct which only has a 'repo' member, no\n   'istate'.\n\nThanks, -Stolee\n\nDerrick Stolee (14):\n  mv: remove index compatibility macros\n  rm: remove compatilibity macros\n  update-index: drop the_index, the_repository\n  update-index: use istate->cache over active_cache\n  update-index: use istate->cache_nr over active_nr\n  update-index: use istate->cache_changed\n  update-index: use index_name_pos() over cache_name_pos()\n  update-index: use remove_file_from_index()\n  update-index: use add_index_entry()\n  update-index: replace several compatibility macros\n  update-index: remove ce_match_stat(), all macros\n  update-index: reduce static globals, part 1\n  update-index: reduce static globals, part 2\n  update-index: remove static globals from callbacks\n\n Documentation/technical/racy-git.txt |   6 +-\n builtin/mv.c                         |  42 ++--\n builtin/rm.c                         |  56 ++---\n builtin/update-index.c               | 312 +++++++++++++++------------\n cache.h                              |   4 -\n 5 files changed, 225 insertions(+), 195 deletions(-)\n\n\nbase-commit: 3da8920d38a007157ccf8e53382e5206b909dafe\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-830%2Fderrickstolee%2Findex-compatibility-1-v3\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-830/derrickstolee/index-compatibility-1-v3\nPull-Request: https://github.com/gitgitgadget/git/pull/830\n\nRange-diff vs v2:\n\n  1:  5ccc464cf26 =  1:  5ccc464cf26 mv: remove index compatibility macros\n  2:  e715c703cb8 =  2:  e715c703cb8 rm: remove compatilibity macros\n  3:  4bf3c582f9d !  3:  f60f34ac1f5 update-index: drop the_index, the_repository\n     @@ Commit message\n          that expand to use the_index can then be mechanically replaced by\n          references to the istate pointer.\n      \n     +    We will be careful to use \"repo->index\" over \"istate\" whenever repo is\n     +    needed by a method.\n     +\n          Signed-off-by: Derrick Stolee <dstolee@microsoft.com>\n      \n       ## builtin/update-index.c ##\n     -@@ builtin/update-index.c: static int ignore_skip_worktree_entries;\n     - #define UNMARK_FLAG 2\n     - static struct strbuf mtime_dir = STRBUF_INIT;\n     +@@ builtin/update-index.c: static int test_if_untracked_cache_is_supported(void)\n     + \treturn ret;\n     + }\n       \n     -+static struct repository *repo;\n      +static struct index_state *istate;\n      +\n     - /* Untracked cache mode */\n     - enum uc_mode {\n     - \tUC_UNSPECIFIED = -1,\n     -@@ builtin/update-index.c: static int mark_ce_flags(const char *path, int flag, int mark)\n     + static int mark_ce_flags(const char *path, int flag, int mark)\n     + {\n       \tint namelen = strlen(path);\n       \tint pos = cache_name_pos(path, namelen);\n       \tif (0 <= pos) {\n     @@ builtin/update-index.c: static int add_cacheinfo(unsigned int mode, const struct\n       \t\t\t\t     allow_add, allow_replace, NULL);\n       \tif (res == -1)\n       \t\treturn res;\n     +@@ builtin/update-index.c: static const char * const update_index_usage[] = {\n     + \n     + static struct object_id head_oid;\n     + static struct object_id merge_head_oid;\n     ++static struct repository *repo;\n     + \n     + static struct cache_entry *read_one_ent(const char *which,\n     + \t\t\t\t\tstruct object_id *ent, const char *path,\n      @@ builtin/update-index.c: static struct cache_entry *read_one_ent(const char *which,\n       \tstruct object_id oid;\n       \tstruct cache_entry *ce;\n     @@ builtin/update-index.c: static struct cache_entry *read_one_ent(const char *whic\n       \t\treturn NULL;\n       \t}\n      -\tce = make_empty_cache_entry(&the_index, namelen);\n     -+\tce = make_empty_cache_entry(istate, namelen);\n     ++\tce = make_empty_cache_entry(repo->index, namelen);\n       \n       \toidcpy(&ce->oid, &oid);\n       \tmemcpy(ce->name, path, namelen);\n     @@ builtin/update-index.c: static int do_reupdate(int ac, const char **av,\n       \t\tchar *path;\n       \n      -\t\tif (ce_stage(ce) || !ce_path_match(&the_index, ce, &pathspec, NULL))\n     -+\t\tif (ce_stage(ce) || !ce_path_match(istate, ce, &pathspec, NULL))\n     ++\t\tif (ce_stage(ce) || !ce_path_match(repo->index, ce, &pathspec, NULL))\n       \t\t\tcontinue;\n       \t\tif (has_head)\n       \t\t\told = read_one_ent(NULL, &head_oid,\n     @@ builtin/update-index.c: int cmd_update_index(int argc, const char **argv, const\n       \n      -\tthe_index.updated_skipworktree = 1;\n      +\tistate = repo->index;\n     -+\tistate->updated_skipworktree = 1;\n     ++\trepo->index->updated_skipworktree = 1;\n       \n       \t/*\n       \t * Custom copy of parse_options() because we want to handle\n     @@ builtin/update-index.c: int cmd_update_index(int argc, const char **argv, const\n       \t\t\t    INDEX_FORMAT_LB, INDEX_FORMAT_UB);\n       \n      -\t\tif (the_index.version != preferred_index_format)\n     -+\t\tif (istate->version != preferred_index_format)\n     ++\t\tif (repo->index->version != preferred_index_format)\n       \t\t\tactive_cache_changed |= SOMETHING_CHANGED;\n      -\t\tthe_index.version = preferred_index_format;\n     -+\t\tistate->version = preferred_index_format;\n     ++\t\trepo->index->version = preferred_index_format;\n       \t}\n       \n       \tif (read_from_stdin) {\n     @@ builtin/update-index.c: int cmd_update_index(int argc, const char **argv, const\n       \t\t\t\t  \"enable split index\"));\n      -\t\tif (the_index.split_index)\n      -\t\t\tthe_index.cache_changed |= SPLIT_INDEX_ORDERED;\n     -+\t\tif (istate->split_index)\n     -+\t\t\tistate->cache_changed |= SPLIT_INDEX_ORDERED;\n     ++\t\tif (repo->index->split_index)\n     ++\t\t\trepo->index->cache_changed |= SPLIT_INDEX_ORDERED;\n       \t\telse\n      -\t\t\tadd_split_index(&the_index);\n     -+\t\t\tadd_split_index(istate);\n     ++\t\t\tadd_split_index(repo->index);\n       \t} else if (!split_index) {\n       \t\tif (git_config_get_split_index() == 1)\n       \t\t\twarning(_(\"core.splitIndex is set to true; \"\n       \t\t\t\t  \"remove or change it, if you really want to \"\n       \t\t\t\t  \"disable split index\"));\n      -\t\tremove_split_index(&the_index);\n     -+\t\tremove_split_index(istate);\n     ++\t\tremove_split_index(repo->index);\n       \t}\n       \n      -\tprepare_repo_settings(r);\n     @@ builtin/update-index.c: int cmd_update_index(int argc, const char **argv, const\n       \t\t\t\t  \"remove or change it, if you really want to \"\n       \t\t\t\t  \"disable the untracked cache\"));\n      -\t\tremove_untracked_cache(&the_index);\n     -+\t\tremove_untracked_cache(istate);\n     ++\t\tremove_untracked_cache(repo->index);\n       \t\treport(_(\"Untracked cache disabled\"));\n       \t\tbreak;\n       \tcase UC_TEST:\n     @@ builtin/update-index.c: int cmd_update_index(int argc, const char **argv, const\n       \t\t\t\t  \"remove or change it, if you really want to \"\n       \t\t\t\t  \"enable the untracked cache\"));\n      -\t\tadd_untracked_cache(&the_index);\n     -+\t\tadd_untracked_cache(istate);\n     ++\t\tadd_untracked_cache(repo->index);\n       \t\treport(_(\"Untracked cache enabled for '%s'\"), get_git_work_tree());\n       \t\tbreak;\n       \tdefault:\n     @@ builtin/update-index.c: int cmd_update_index(int argc, const char **argv, const\n       \t\t\t\t\"set it if you really want to \"\n       \t\t\t\t\"enable fsmonitor\"));\n      -\t\tadd_fsmonitor(&the_index);\n     -+\t\tadd_fsmonitor(istate);\n     ++\t\tadd_fsmonitor(repo->index);\n       \t\treport(_(\"fsmonitor enabled\"));\n       \t} else if (!fsmonitor) {\n       \t\tif (git_config_get_fsmonitor() == 1)\n     @@ builtin/update-index.c: int cmd_update_index(int argc, const char **argv, const\n       \t\t\t\t\"remove it if you really want to \"\n       \t\t\t\t\"disable fsmonitor\"));\n      -\t\tremove_fsmonitor(&the_index);\n     -+\t\tremove_fsmonitor(istate);\n     ++\t\tremove_fsmonitor(repo->index);\n       \t\treport(_(\"fsmonitor disabled\"));\n       \t}\n       \n     @@ builtin/update-index.c: int cmd_update_index(int argc, const char **argv, const\n       \t\t\tunable_to_lock_die(get_index_file(), lock_error);\n       \t\t}\n      -\t\tif (write_locked_index(&the_index, &lock_file, COMMIT_LOCK))\n     -+\t\tif (write_locked_index(istate, &lock_file, COMMIT_LOCK))\n     ++\t\tif (write_locked_index(repo->index, &lock_file, COMMIT_LOCK))\n       \t\t\tdie(\"Unable to write new index file\");\n       \t}\n       \n  4:  4b509ba5fa2 !  4:  b8fcdd8b3da update-index: use istate->cache over active_cache\n     @@ Metadata\n       ## Commit message ##\n          update-index: use istate->cache over active_cache\n      \n     +    Also use repo->index over istate, when possible.\n     +\n          Signed-off-by: Derrick Stolee <dstolee@microsoft.com>\n      \n       ## builtin/update-index.c ##\n     @@ builtin/update-index.c: static int unresolve_one(const char *path)\n       \t\tpos = unmerge_cache_entry_at(pos);\n       \t\tif (pos < active_nr) {\n      -\t\t\tconst struct cache_entry *ce = active_cache[pos];\n     -+\t\t\tconst struct cache_entry *ce = istate->cache[pos];\n     ++\t\t\tconst struct cache_entry *ce = repo->index->cache[pos];\n       \t\t\tif (ce_stage(ce) &&\n       \t\t\t    ce_namelen(ce) == namelen &&\n       \t\t\t    !memcmp(ce->name, path, namelen))\n     @@ builtin/update-index.c: static int unresolve_one(const char *path)\n       \t\tpos = -pos-1;\n       \t\tif (pos < active_nr) {\n      -\t\t\tconst struct cache_entry *ce = active_cache[pos];\n     -+\t\t\tconst struct cache_entry *ce = istate->cache[pos];\n     ++\t\t\tconst struct cache_entry *ce = repo->index->cache[pos];\n       \t\t\tif (ce_namelen(ce) == namelen &&\n       \t\t\t    !memcmp(ce->name, path, namelen)) {\n       \t\t\t\tfprintf(stderr,\n     @@ builtin/update-index.c: static int do_reupdate(int ac, const char **av,\n        redo:\n       \tfor (pos = 0; pos < active_nr; pos++) {\n      -\t\tconst struct cache_entry *ce = active_cache[pos];\n     -+\t\tconst struct cache_entry *ce = istate->cache[pos];\n     ++\t\tconst struct cache_entry *ce = repo->index->cache[pos];\n       \t\tstruct cache_entry *old = NULL;\n       \t\tint save_nr;\n       \t\tchar *path;\n  5:  6c0e019f91c !  5:  586371ee769 update-index: use index->cache_nr over active_nr\n     @@ Metadata\n      Author: Derrick Stolee <dstolee@microsoft.com>\n      \n       ## Commit message ##\n     -    update-index: use index->cache_nr over active_nr\n     +    update-index: use istate->cache_nr over active_nr\n     +\n     +    Also use \"repo->index\" over \"istate\" when possible.\n      \n          Signed-off-by: Derrick Stolee <dstolee@microsoft.com>\n      \n     @@ builtin/update-index.c: static int unresolve_one(const char *path)\n       \t\t/* already merged */\n       \t\tpos = unmerge_cache_entry_at(pos);\n      -\t\tif (pos < active_nr) {\n     -+\t\tif (pos < istate->cache_nr) {\n     - \t\t\tconst struct cache_entry *ce = istate->cache[pos];\n     ++\t\tif (pos < repo->index->cache_nr) {\n     + \t\t\tconst struct cache_entry *ce = repo->index->cache[pos];\n       \t\t\tif (ce_stage(ce) &&\n       \t\t\t    ce_namelen(ce) == namelen &&\n      @@ builtin/update-index.c: static int unresolve_one(const char *path)\n     @@ builtin/update-index.c: static int unresolve_one(const char *path)\n       \t\t */\n       \t\tpos = -pos-1;\n      -\t\tif (pos < active_nr) {\n     -+\t\tif (pos < istate->cache_nr) {\n     - \t\t\tconst struct cache_entry *ce = istate->cache[pos];\n     ++\t\tif (pos < repo->index->cache_nr) {\n     + \t\t\tconst struct cache_entry *ce = repo->index->cache[pos];\n       \t\t\tif (ce_namelen(ce) == namelen &&\n       \t\t\t    !memcmp(ce->name, path, namelen)) {\n      @@ builtin/update-index.c: static int do_reupdate(int ac, const char **av,\n     @@ builtin/update-index.c: static int do_reupdate(int ac, const char **av,\n       \t\thas_head = 0;\n        redo:\n      -\tfor (pos = 0; pos < active_nr; pos++) {\n     -+\tfor (pos = 0; pos < istate->cache_nr; pos++) {\n     - \t\tconst struct cache_entry *ce = istate->cache[pos];\n     ++\tfor (pos = 0; pos < repo->index->cache_nr; pos++) {\n     + \t\tconst struct cache_entry *ce = repo->index->cache[pos];\n       \t\tstruct cache_entry *old = NULL;\n       \t\tint save_nr;\n      @@ builtin/update-index.c: static int do_reupdate(int ac, const char **av,\n     @@ builtin/update-index.c: static int do_reupdate(int ac, const char **av,\n       \t\t/* Be careful.  The working tree may not have the\n       \t\t * path anymore, in which case, under 'allow_remove',\n      -\t\t * or worse yet 'allow_replace', active_nr may decrease.\n     -+\t\t * or worse yet 'allow_replace', istate->cache_nr may decrease.\n     ++\t\t * or worse yet 'allow_replace', repo->index->cache_nr may decrease.\n       \t\t */\n      -\t\tsave_nr = active_nr;\n     -+\t\tsave_nr = istate->cache_nr;\n     ++\t\tsave_nr = repo->index->cache_nr;\n       \t\tpath = xstrdup(ce->name);\n       \t\tupdate_one(path);\n       \t\tfree(path);\n       \t\tdiscard_cache_entry(old);\n      -\t\tif (save_nr != active_nr)\n     -+\t\tif (save_nr != istate->cache_nr)\n     ++\t\tif (save_nr != repo->index->cache_nr)\n       \t\t\tgoto redo;\n       \t}\n       \tclear_pathspec(&pathspec);\n  6:  5091e2661d1 !  6:  f450f43cd0d update-index: use istate->cache_changed\n     @@ builtin/update-index.c: static enum parse_opt_result unresolve_callback(\n       \t\t\t\tprefix, prefix ? strlen(prefix) : 0);\n       \tif (*has_errors)\n      -\t\tactive_cache_changed = 0;\n     -+\t\tistate->cache_changed = 0;\n     ++\t\trepo->index->cache_changed = 0;\n       \n       \tctx->argv += ctx->argc - 1;\n       \tctx->argc = 1;\n     @@ builtin/update-index.c: static enum parse_opt_result reupdate_callback(\n       \t*has_errors = do_reupdate(ctx->argc, ctx->argv, prefix);\n       \tif (*has_errors)\n      -\t\tactive_cache_changed = 0;\n     -+\t\tistate->cache_changed = 0;\n     ++\t\trepo->index->cache_changed = 0;\n       \n       \tctx->argv += ctx->argc - 1;\n       \tctx->argc = 1;\n      @@ builtin/update-index.c: int cmd_update_index(int argc, const char **argv, const char *prefix)\n       \t\t\t    INDEX_FORMAT_LB, INDEX_FORMAT_UB);\n       \n     - \t\tif (istate->version != preferred_index_format)\n     + \t\tif (repo->index->version != preferred_index_format)\n      -\t\t\tactive_cache_changed |= SOMETHING_CHANGED;\n     -+\t\t\tistate->cache_changed |= SOMETHING_CHANGED;\n     - \t\tistate->version = preferred_index_format;\n     ++\t\t\trepo->index->cache_changed |= SOMETHING_CHANGED;\n     + \t\trepo->index->version = preferred_index_format;\n       \t}\n       \n      @@ builtin/update-index.c: int cmd_update_index(int argc, const char **argv, const char *prefix)\n     @@ builtin/update-index.c: int cmd_update_index(int argc, const char **argv, const\n       \t}\n       \n      -\tif (active_cache_changed || force_write) {\n     -+\tif (istate->cache_changed || force_write) {\n     ++\tif (repo->index->cache_changed || force_write) {\n       \t\tif (newfd < 0) {\n       \t\t\tif (refresh_args.flags & REFRESH_QUIET)\n       \t\t\t\texit(128);\n  7:  5b14fa10a4b !  7:  fc640ae6e65 update-index: use index_name_pos() over cache_name_pos()\n     @@ Commit message\n          Signed-off-by: Derrick Stolee <dstolee@microsoft.com>\n      \n       ## builtin/update-index.c ##\n     -@@ builtin/update-index.c: static int test_if_untracked_cache_is_supported(void)\n     +@@ builtin/update-index.c: static struct index_state *istate;\n       static int mark_ce_flags(const char *path, int flag, int mark)\n       {\n       \tint namelen = strlen(path);\n     @@ builtin/update-index.c: static int unresolve_one(const char *path)\n       \n       \t/* See if there is such entry in the index. */\n      -\tpos = cache_name_pos(path, namelen);\n     -+\tpos = index_name_pos(istate, path, namelen);\n     ++\tpos = index_name_pos(repo->index, path, namelen);\n       \tif (0 <= pos) {\n       \t\t/* already merged */\n       \t\tpos = unmerge_cache_entry_at(pos);\n  8:  a1a9fb01b07 !  8:  2eead833fba update-index: use remove_file_from_index()\n     @@ builtin/update-index.c: static int unresolve_one(const char *path)\n       \t}\n       \n      -\tremove_file_from_cache(path);\n     -+\tremove_file_from_index(istate, path);\n     ++\tremove_file_from_index(repo->index, path);\n       \tif (add_cache_entry(ce_2, ADD_CACHE_OK_TO_ADD)) {\n       \t\terror(\"%s: cannot add our version to the index.\", path);\n       \t\tret = -1;\n  9:  620e300ad6b !  9:  8016b089556 update-index: use add_index_entry()\n     @@ builtin/update-index.c: static int add_one_path(const struct cache_entry *old, c\n      @@ builtin/update-index.c: static int unresolve_one(const char *path)\n       \t}\n       \n     - \tremove_file_from_index(istate, path);\n     + \tremove_file_from_index(repo->index, path);\n      -\tif (add_cache_entry(ce_2, ADD_CACHE_OK_TO_ADD)) {\n     -+\tif (add_index_entry(istate, ce_2, ADD_CACHE_OK_TO_ADD)) {\n     ++\tif (add_index_entry(repo->index, ce_2, ADD_CACHE_OK_TO_ADD)) {\n       \t\terror(\"%s: cannot add our version to the index.\", path);\n       \t\tret = -1;\n       \t\tgoto free_return;\n       \t}\n      -\tif (!add_cache_entry(ce_3, ADD_CACHE_OK_TO_ADD))\n     -+\tif (!add_index_entry(istate, ce_3, ADD_CACHE_OK_TO_ADD))\n     ++\tif (!add_index_entry(repo->index, ce_3, ADD_CACHE_OK_TO_ADD))\n       \t\treturn 0;\n       \terror(\"%s: cannot add their version to the index.\", path);\n       \tret = -1;\n 10:  68b26a11d77 ! 10:  efe9fddd0a9 update-index: replace several compatibility macros\n     @@ builtin/update-index.c: static void chmod_path(char flip, const char *path)\n       \n       \treport(\"chmod %cx '%s'\", flip, path);\n      @@ builtin/update-index.c: static int unresolve_one(const char *path)\n     - \tpos = index_name_pos(istate, path, namelen);\n     + \tpos = index_name_pos(repo->index, path, namelen);\n       \tif (0 <= pos) {\n       \t\t/* already merged */\n      -\t\tpos = unmerge_cache_entry_at(pos);\n     -+\t\tpos = unmerge_index_entry_at(istate, pos);\n     - \t\tif (pos < istate->cache_nr) {\n     - \t\t\tconst struct cache_entry *ce = istate->cache[pos];\n     ++\t\tpos = unmerge_index_entry_at(repo->index, pos);\n     + \t\tif (pos < repo->index->cache_nr) {\n     + \t\t\tconst struct cache_entry *ce = repo->index->cache[pos];\n       \t\t\tif (ce_stage(ce) &&\n      @@ builtin/update-index.c: struct refresh_params {\n       static int refresh(struct refresh_params *o, unsigned int flag)\n     @@ builtin/update-index.c: struct refresh_params {\n      -\tread_cache();\n      -\t*o->has_errors |= refresh_cache(o->flags | flag);\n      +\trepo_read_index(repo);\n     -+\t*o->has_errors |= refresh_index(istate, o->flags | flag,\n     ++\t*o->has_errors |= refresh_index(repo->index, o->flags | flag,\n      +\t\t\t\t\tNULL, NULL, NULL);\n       \treturn 0;\n       }\n     @@ builtin/update-index.c: static int resolve_undo_clear_callback(const struct opti\n       \tBUG_ON_OPT_NEG(unset);\n       \tBUG_ON_OPT_ARG(arg);\n      -\tresolve_undo_clear();\n     -+\tresolve_undo_clear_index(istate);\n     ++\tresolve_undo_clear_index(repo->index);\n       \treturn 0;\n       }\n       \n 11:  f1cffe2b455 = 11:  e9d4fa613a6 update-index: remove ce_match_stat(), all macros\n 12:  79e267f39ec ! 12:  4754a9214ee update-index: reduce static globals, part 1\n     @@ Commit message\n          static globals by modifying method prototypes to use them when\n          necessary.\n      \n     -    Move these static globals further down in the file so we can identify\n     -    which method only need to add a 'struct index_state *istate' parameter.\n     -    The only changes included here adjust method prototypes and their call\n     -    locations.\n     +    Remove the 'istate' static global in favor of method parameters. This\n     +    adjusts some callers, which either use their own 'istate' parameter or\n     +    'repo->index'.\n      \n          Signed-off-by: Derrick Stolee <dstolee@microsoft.com>\n      \n       ## builtin/update-index.c ##\n     -@@ builtin/update-index.c: static int ignore_skip_worktree_entries;\n     - #define UNMARK_FLAG 2\n     - static struct strbuf mtime_dir = STRBUF_INIT;\n     - \n     --static struct repository *repo;\n     --static struct index_state *istate;\n     --\n     - /* Untracked cache mode */\n     - enum uc_mode {\n     - \tUC_UNSPECIFIED = -1,\n      @@ builtin/update-index.c: static int test_if_untracked_cache_is_supported(void)\n       \treturn ret;\n       }\n       \n     +-static struct index_state *istate;\n     +-\n      -static int mark_ce_flags(const char *path, int flag, int mark)\n      +static int mark_ce_flags(struct index_state *istate,\n      +\t\t\t const char *path, int flag, int mark)\n     @@ builtin/update-index.c: static void read_index_info(int nul_term_line)\n       \t\t\t\tdie(\"git update-index: unable to update %s\",\n       \t\t\t\t    path_name);\n       \t\t}\n     -@@ builtin/update-index.c: static const char * const update_index_usage[] = {\n     - static struct object_id head_oid;\n     - static struct object_id merge_head_oid;\n     - \n     -+static struct repository *repo;\n     -+static struct index_state *istate;\n     -+\n     - static struct cache_entry *read_one_ent(const char *which,\n     - \t\t\t\t\tstruct object_id *ent, const char *path,\n     - \t\t\t\t\tint namelen, int stage)\n      @@ builtin/update-index.c: static int do_reupdate(int ac, const char **av,\n       \t\t */\n     - \t\tsave_nr = istate->cache_nr;\n     + \t\tsave_nr = repo->index->cache_nr;\n       \t\tpath = xstrdup(ce->name);\n      -\t\tupdate_one(path);\n     -+\t\tupdate_one(istate, path);\n     ++\t\tupdate_one(repo->index, path);\n       \t\tfree(path);\n       \t\tdiscard_cache_entry(old);\n     - \t\tif (save_nr != istate->cache_nr)\n     + \t\tif (save_nr != repo->index->cache_nr)\n      @@ builtin/update-index.c: static enum parse_opt_result cacheinfo_callback(\n       \tBUG_ON_OPT_ARG(arg);\n       \n       \tif (!parse_new_style_cacheinfo(ctx->argv[1], &mode, &oid, &path)) {\n      -\t\tif (add_cacheinfo(mode, &oid, path, 0))\n     -+\t\tif (add_cacheinfo(istate, mode, &oid, path, 0))\n     ++\t\tif (add_cacheinfo(repo->index, mode, &oid, path, 0))\n       \t\t\tdie(\"git update-index: --cacheinfo cannot add %s\", path);\n       \t\tctx->argv++;\n       \t\tctx->argc--;\n     @@ builtin/update-index.c: static enum parse_opt_result cacheinfo_callback(\n       \tif (strtoul_ui(*++ctx->argv, 8, &mode) ||\n       \t    get_oid_hex(*++ctx->argv, &oid) ||\n      -\t    add_cacheinfo(mode, &oid, *++ctx->argv, 0))\n     -+\t    add_cacheinfo(istate, mode, &oid, *++ctx->argv, 0))\n     ++\t    add_cacheinfo(repo->index, mode, &oid, *++ctx->argv, 0))\n       \t\tdie(\"git update-index: --cacheinfo cannot add %s\", *ctx->argv);\n       \tctx->argc -= 3;\n       \treturn 0;\n     @@ builtin/update-index.c: static enum parse_opt_result stdin_cacheinfo_callback(\n       \t\treturn error(\"option '%s' must be the last argument\", opt->long_name);\n       \tallow_add = allow_replace = allow_remove = 1;\n      -\tread_index_info(*nul_term_line);\n     -+\tread_index_info(istate, *nul_term_line);\n     ++\tread_index_info(repo->index, *nul_term_line);\n       \treturn 0;\n       }\n       \n     +@@ builtin/update-index.c: int cmd_update_index(int argc, const char **argv, const char *prefix)\n     + \tif (entries < 0)\n     + \t\tdie(\"cache corrupted\");\n     + \n     +-\tistate = repo->index;\n     + \trepo->index->updated_skipworktree = 1;\n     + \n     + \t/*\n      @@ builtin/update-index.c: int cmd_update_index(int argc, const char **argv, const char *prefix)\n       \n       \t\t\tsetup_work_tree();\n       \t\t\tp = prefix_path(prefix, prefix_length, path);\n      -\t\t\tupdate_one(p);\n     -+\t\t\tupdate_one(istate, p);\n     ++\t\t\tupdate_one(repo->index, p);\n       \t\t\tif (set_executable_bit)\n      -\t\t\t\tchmod_path(set_executable_bit, p);\n     -+\t\t\t\tchmod_path(istate, set_executable_bit, p);\n     ++\t\t\t\tchmod_path(repo->index, set_executable_bit, p);\n       \t\t\tfree(p);\n       \t\t\tctx.argc--;\n       \t\t\tctx.argv++;\n     @@ builtin/update-index.c: int cmd_update_index(int argc, const char **argv, const\n       \t\t\t}\n       \t\t\tp = prefix_path(prefix, prefix_length, buf.buf);\n      -\t\t\tupdate_one(p);\n     -+\t\t\tupdate_one(istate, p);\n     ++\t\t\tupdate_one(repo->index, p);\n       \t\t\tif (set_executable_bit)\n      -\t\t\t\tchmod_path(set_executable_bit, p);\n     -+\t\t\t\tchmod_path(istate, set_executable_bit, p);\n     ++\t\t\t\tchmod_path(repo->index, set_executable_bit, p);\n       \t\t\tfree(p);\n       \t\t}\n       \t\tstrbuf_release(&unquoted);\n 13:  457402b4fdc ! 13:  a9185af4740 update-index: reduce static globals, part 2\n     @@ Commit message\n          static globals by modifying method prototypes to use them when\n          necessary.\n      \n     -    Move these static globals further down the file so we can identify which\n     -    methods need both 'struct repository *repo' and 'struct index_state\n     -    *istate' parameters. The only changes included here adjust method\n     -    prototypes and their call locations.\n     +    Move the remaining 'struct repository *repo' further down the file and\n     +    use method parameters to pass it around instead.\n      \n     -    The only remaining change is to remove the static globals entirely, but\n     +    The only remaining change is to remove the static global entirely, but\n          that requires updating the parse-opt callbacks, which need a different\n          solution.\n      \n     @@ Commit message\n      \n       ## builtin/update-index.c ##\n      @@ builtin/update-index.c: static const char * const update_index_usage[] = {\n     + \n       static struct object_id head_oid;\n       static struct object_id merge_head_oid;\n     - \n      -static struct repository *repo;\n     --static struct index_state *istate;\n     --\n     + \n      -static struct cache_entry *read_one_ent(const char *which,\n      +static struct cache_entry *read_one_ent(struct repository *repo,\n     -+\t\t\t\t\tstruct index_state *istate,\n      +\t\t\t\t\tconst char *which,\n       \t\t\t\t\tstruct object_id *ent, const char *path,\n       \t\t\t\t\tint namelen, int stage)\n     @@ builtin/update-index.c: static struct cache_entry *read_one_ent(const char *whic\n       \n      -static int unresolve_one(const char *path)\n      +static int unresolve_one(struct repository *repo,\n     -+\t\t\t struct index_state *istate,\n      +\t\t\t const char *path)\n       {\n       \tint namelen = strlen(path);\n     @@ builtin/update-index.c: static int unresolve_one(const char *path)\n       \t */\n      -\tce_2 = read_one_ent(\"our\", &head_oid, path, namelen, 2);\n      -\tce_3 = read_one_ent(\"their\", &merge_head_oid, path, namelen, 3);\n     -+\tce_2 = read_one_ent(repo, istate, \"our\", &head_oid, path, namelen, 2);\n     -+\tce_3 = read_one_ent(repo, istate, \"their\", &merge_head_oid, path, namelen, 3);\n     ++\tce_2 = read_one_ent(repo, \"our\", &head_oid, path, namelen, 2);\n     ++\tce_3 = read_one_ent(repo, \"their\", &merge_head_oid, path, namelen, 3);\n       \n       \tif (!ce_2 || !ce_3) {\n       \t\tret = -1;\n     @@ builtin/update-index.c: static void read_head_pointers(void)\n       \n      -static int do_unresolve(int ac, const char **av,\n      +static int do_unresolve(struct repository *repo,\n     -+\t\t\tstruct index_state *istate,\n      +\t\t\tint ac, const char **av,\n       \t\t\tconst char *prefix, int prefix_length)\n       {\n     @@ builtin/update-index.c: static int do_unresolve(int ac, const char **av,\n       \t\tconst char *arg = av[i];\n       \t\tchar *p = prefix_path(prefix, prefix_length, arg);\n      -\t\terr |= unresolve_one(p);\n     -+\t\terr |= unresolve_one(repo, istate, p);\n     ++\t\terr |= unresolve_one(repo, p);\n       \t\tfree(p);\n       \t}\n       \treturn err;\n     @@ builtin/update-index.c: static int do_unresolve(int ac, const char **av,\n       \n      -static int do_reupdate(int ac, const char **av,\n      +static int do_reupdate(struct repository *repo,\n     -+\t\t       struct index_state *istate,\n      +\t\t       int ac, const char **av,\n       \t\t       const char *prefix)\n       {\n       \t/* Read HEAD and run update-index on paths that are\n      @@ builtin/update-index.c: static int do_reupdate(int ac, const char **av,\n     - \t\tif (ce_stage(ce) || !ce_path_match(istate, ce, &pathspec, NULL))\n     + \t\tif (ce_stage(ce) || !ce_path_match(repo->index, ce, &pathspec, NULL))\n       \t\t\tcontinue;\n       \t\tif (has_head)\n      -\t\t\told = read_one_ent(NULL, &head_oid,\n     -+\t\t\told = read_one_ent(repo, istate, NULL, &head_oid,\n     ++\t\t\told = read_one_ent(repo, NULL, &head_oid,\n       \t\t\t\t\t   ce->name, ce_namelen(ce), 0);\n       \t\tif (old && ce->ce_mode == old->ce_mode &&\n       \t\t    oideq(&ce->oid, &old->oid)) {\n     @@ builtin/update-index.c: struct refresh_params {\n       };\n       \n      +static struct repository *repo;\n     -+static struct index_state *istate;\n      +\n       static int refresh(struct refresh_params *o, unsigned int flag)\n       {\n     @@ builtin/update-index.c: static enum parse_opt_result unresolve_callback(\n       \t/* consume remaining arguments. */\n      -\t*has_errors = do_unresolve(ctx->argc, ctx->argv,\n      -\t\t\t\tprefix, prefix ? strlen(prefix) : 0);\n     -+\t*has_errors = do_unresolve(repo, istate, ctx->argc, ctx->argv,\n     ++\t*has_errors = do_unresolve(repo, ctx->argc, ctx->argv,\n      +\t\t\t\t   prefix, prefix ? strlen(prefix) : 0);\n       \tif (*has_errors)\n     - \t\tistate->cache_changed = 0;\n     + \t\trepo->index->cache_changed = 0;\n       \n      @@ builtin/update-index.c: static enum parse_opt_result reupdate_callback(\n       \n       \t/* consume remaining arguments. */\n       \tsetup_work_tree();\n      -\t*has_errors = do_reupdate(ctx->argc, ctx->argv, prefix);\n     -+\t*has_errors = do_reupdate(repo, istate, ctx->argc, ctx->argv, prefix);\n     ++\t*has_errors = do_reupdate(repo, ctx->argc, ctx->argv, prefix);\n       \tif (*has_errors)\n     - \t\tistate->cache_changed = 0;\n     + \t\trepo->index->cache_changed = 0;\n       \n 14:  2b171a142b3 ! 14:  414ef816845 update-index: remove static globals from callbacks\n     @@ Commit message\n          callback value.\n      \n          Unify these callback methods to use a consistent 'struct callback_data'\n     -    that contains 'repo' and 'istate', ready to use. This takes the place of\n     +    that contains a 'repo' member, ready to use. This takes the place of\n          the previous 'struct refresh_params' which served only to group the\n          'flags' and 'has_errors' ints. We also collect other one-off settings,\n          but only those that require access to the index or repository in their\n     @@ builtin/update-index.c: static int do_reupdate(struct repository *repo,\n      -struct refresh_params {\n      +struct callback_data {\n      +\tstruct repository *repo;\n     -+\tstruct index_state *istate;\n      +\n       \tunsigned int flags;\n      -\tint *has_errors;\n     @@ builtin/update-index.c: static int do_reupdate(struct repository *repo,\n       };\n       \n      -static struct repository *repo;\n     --static struct index_state *istate;\n      -\n      -static int refresh(struct refresh_params *o, unsigned int flag)\n      +static int refresh(struct callback_data *cd, unsigned int flag)\n       {\n       \tsetup_work_tree();\n      -\trepo_read_index(repo);\n     --\t*o->has_errors |= refresh_index(istate, o->flags | flag,\n     +-\t*o->has_errors |= refresh_index(repo->index, o->flags | flag,\n      +\trepo_read_index(cd->repo);\n     -+\tcd->has_errors |= refresh_index(cd->istate, cd->flags | flag,\n     ++\tcd->has_errors |= refresh_index(cd->repo->index, cd->flags | flag,\n       \t\t\t\t\tNULL, NULL, NULL);\n       \treturn 0;\n       }\n     @@ builtin/update-index.c: static int chmod_callback(const struct option *opt,\n      +\tstruct callback_data *cd = opt->value;\n       \tBUG_ON_OPT_NEG(unset);\n       \tBUG_ON_OPT_ARG(arg);\n     --\tresolve_undo_clear_index(istate);\n     -+\tresolve_undo_clear_index(cd->istate);\n     +-\tresolve_undo_clear_index(repo->index);\n     ++\tresolve_undo_clear_index(cd->repo->index);\n       \treturn 0;\n       }\n       \n     @@ builtin/update-index.c: static enum parse_opt_result cacheinfo_callback(\n       \tBUG_ON_OPT_ARG(arg);\n       \n       \tif (!parse_new_style_cacheinfo(ctx->argv[1], &mode, &oid, &path)) {\n     --\t\tif (add_cacheinfo(istate, mode, &oid, path, 0))\n     -+\t\tif (add_cacheinfo(cd->istate, mode, &oid, path, 0))\n     +-\t\tif (add_cacheinfo(repo->index, mode, &oid, path, 0))\n     ++\t\tif (add_cacheinfo(cd->repo->index, mode, &oid, path, 0))\n       \t\t\tdie(\"git update-index: --cacheinfo cannot add %s\", path);\n       \t\tctx->argv++;\n       \t\tctx->argc--;\n     @@ builtin/update-index.c: static enum parse_opt_result cacheinfo_callback(\n       \t\treturn error(\"option 'cacheinfo' expects <mode>,<sha1>,<path>\");\n       \tif (strtoul_ui(*++ctx->argv, 8, &mode) ||\n       \t    get_oid_hex(*++ctx->argv, &oid) ||\n     --\t    add_cacheinfo(istate, mode, &oid, *++ctx->argv, 0))\n     -+\t    add_cacheinfo(cd->istate, mode, &oid, *++ctx->argv, 0))\n     +-\t    add_cacheinfo(repo->index, mode, &oid, *++ctx->argv, 0))\n     ++\t    add_cacheinfo(cd->repo->index, mode, &oid, *++ctx->argv, 0))\n       \t\tdie(\"git update-index: --cacheinfo cannot add %s\", *ctx->argv);\n       \tctx->argc -= 3;\n       \treturn 0;\n     @@ builtin/update-index.c: static enum parse_opt_result stdin_cacheinfo_callback(\n       \tif (ctx->argc != 1)\n       \t\treturn error(\"option '%s' must be the last argument\", opt->long_name);\n       \tallow_add = allow_replace = allow_remove = 1;\n     --\tread_index_info(istate, *nul_term_line);\n     -+\tread_index_info(cd->istate, cd->nul_term_line);\n     +-\tread_index_info(repo->index, *nul_term_line);\n     ++\tread_index_info(cd->repo->index, cd->nul_term_line);\n       \treturn 0;\n       }\n       \n     @@ builtin/update-index.c: static enum parse_opt_result unresolve_callback(\n       \tBUG_ON_OPT_ARG(arg);\n       \n       \t/* consume remaining arguments. */\n     --\t*has_errors = do_unresolve(repo, istate, ctx->argc, ctx->argv,\n     +-\t*has_errors = do_unresolve(repo, ctx->argc, ctx->argv,\n      -\t\t\t\t   prefix, prefix ? strlen(prefix) : 0);\n      -\tif (*has_errors)\n     --\t\tistate->cache_changed = 0;\n     -+\tcd->has_errors = do_unresolve(cd->repo, cd->istate, ctx->argc, ctx->argv,\n     +-\t\trepo->index->cache_changed = 0;\n     ++\tcd->has_errors = do_unresolve(cd->repo, ctx->argc, ctx->argv,\n      +\t\t\t\t      prefix, prefix ? strlen(prefix) : 0);\n      +\tif (cd->has_errors)\n     -+\t\tcd->istate->cache_changed = 0;\n     ++\t\tcd->repo->index->cache_changed = 0;\n       \n       \tctx->argv += ctx->argc - 1;\n       \tctx->argc = 1;\n     @@ builtin/update-index.c: static enum parse_opt_result reupdate_callback(\n       \n       \t/* consume remaining arguments. */\n       \tsetup_work_tree();\n     --\t*has_errors = do_reupdate(repo, istate, ctx->argc, ctx->argv, prefix);\n     +-\t*has_errors = do_reupdate(repo, ctx->argc, ctx->argv, prefix);\n      -\tif (*has_errors)\n     --\t\tistate->cache_changed = 0;\n     -+\tcd->has_errors = do_reupdate(cd->repo, cd->istate,\n     -+\t\t\t\t     ctx->argc, ctx->argv, prefix);\n     +-\t\trepo->index->cache_changed = 0;\n     ++\tcd->has_errors = do_reupdate(cd->repo, ctx->argc, ctx->argv, prefix);\n      +\tif (cd->has_errors)\n     -+\t\tcd->istate->cache_changed = 0;\n     ++\t\tcd->repo->index->cache_changed = 0;\n       \n       \tctx->argv += ctx->argc - 1;\n       \tctx->argc = 1;\n     @@ builtin/update-index.c: int cmd_update_index(int argc, const char **argv, const\n       \tstruct parse_opt_ctx_t ctx;\n       \tstrbuf_getline_fn getline_fn;\n       \tint parseopt_state = PARSE_OPT_UNKNOWN;\n     -+\tstruct index_state *istate;\n      +\n       \tstruct option options[] = {\n      -\t\tOPT_BIT('q', NULL, &refresh_args.flags,\n     @@ builtin/update-index.c: int cmd_update_index(int argc, const char **argv, const\n       \tnewfd = repo_hold_locked_index(repo, &lock_file, 0);\n       \tif (newfd < 0)\n      @@ builtin/update-index.c: int cmd_update_index(int argc, const char **argv, const char *prefix)\n     - \tif (entries < 0)\n       \t\tdie(\"cache corrupted\");\n       \n     --\tistate = repo->index;\n     + \trepo->index->updated_skipworktree = 1;\n      +\tcd.repo = repo;\n     -+\tcd.istate = istate = repo->index;\n     - \tistate->updated_skipworktree = 1;\n      +\tcd.flags = 0;\n      +\tcd.has_errors = 0;\n      +\tcd.nul_term_line = 0;\n     @@ builtin/update-index.c: int cmd_update_index(int argc, const char **argv, const\n       \t\tif (preferred_index_format < INDEX_FORMAT_LB ||\n       \t\t    INDEX_FORMAT_UB < preferred_index_format)\n      @@ builtin/update-index.c: int cmd_update_index(int argc, const char **argv, const char *prefix)\n     - \t\tistate->version = preferred_index_format;\n     + \t\trepo->index->version = preferred_index_format;\n       \t}\n       \n      -\tif (read_from_stdin) {\n     @@ builtin/update-index.c: int cmd_update_index(int argc, const char **argv, const\n       \t\t\t\t\tdie(\"line is badly quoted\");\n      @@ builtin/update-index.c: int cmd_update_index(int argc, const char **argv, const char *prefix)\n       \n     - \tif (istate->cache_changed || force_write) {\n     + \tif (repo->index->cache_changed || force_write) {\n       \t\tif (newfd < 0) {\n      -\t\t\tif (refresh_args.flags & REFRESH_QUIET)\n      +\t\t\tif (cd.flags & REFRESH_QUIET)\n\n-- \ngitgitgadget\n"},{"id":"413875","messageId":"b8fcdd8b3da062e3e14a5d755870dffe313fc495.1610136177.git.gitgitgadget@gmail.com","threadId":"54916","inReplyTo":"pull.830.v3.git.1610136177.gitgitgadget@gmail.com","subject":"[PATCH v3 04/14] update-index: use istate->cache over active_cache","fromName":"Derrick Stolee via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-01-08T20:02:47Z","receivedAt":"2021-01-08T20:04:00Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"From: Derrick Stolee <dstolee@microsoft.com>\n\nAlso use repo->index over istate, when possible.\n\nSigned-off-by: Derrick Stolee <dstolee@microsoft.com>\n---\n builtin/update-index.c | 22 +++++++++++-----------\n 1 file changed, 11 insertions(+), 11 deletions(-)\n\ndiff --git a/builtin/update-index.c b/builtin/update-index.c\nindex 22284f301dc..0c5a10f5dba 100644\n--- a/builtin/update-index.c\n+++ b/builtin/update-index.c\n@@ -234,12 +234,12 @@ static int mark_ce_flags(const char *path, int flag, int mark)\n \tint namelen = strlen(path);\n \tint pos = cache_name_pos(path, namelen);\n \tif (0 <= pos) {\n-\t\tmark_fsmonitor_invalid(istate, active_cache[pos]);\n+\t\tmark_fsmonitor_invalid(istate, istate->cache[pos]);\n \t\tif (mark)\n-\t\t\tactive_cache[pos]->ce_flags |= flag;\n+\t\t\tistate->cache[pos]->ce_flags |= flag;\n \t\telse\n-\t\t\tactive_cache[pos]->ce_flags &= ~flag;\n-\t\tactive_cache[pos]->ce_flags |= CE_UPDATE_IN_BASE;\n+\t\t\tistate->cache[pos]->ce_flags &= ~flag;\n+\t\tistate->cache[pos]->ce_flags |= CE_UPDATE_IN_BASE;\n \t\tcache_tree_invalidate_path(istate, path);\n \t\tactive_cache_changed |= CE_ENTRY_CHANGED;\n \t\treturn 0;\n@@ -330,7 +330,7 @@ static int process_directory(const char *path, int len, struct stat *st)\n \n \t/* Exact match: file or existing gitlink */\n \tif (pos >= 0) {\n-\t\tconst struct cache_entry *ce = active_cache[pos];\n+\t\tconst struct cache_entry *ce = istate->cache[pos];\n \t\tif (S_ISGITLINK(ce->ce_mode)) {\n \n \t\t\t/* Do nothing to the index if there is no HEAD! */\n@@ -346,7 +346,7 @@ static int process_directory(const char *path, int len, struct stat *st)\n \t/* Inexact match: is there perhaps a subdirectory match? */\n \tpos = -pos-1;\n \twhile (pos < active_nr) {\n-\t\tconst struct cache_entry *ce = active_cache[pos++];\n+\t\tconst struct cache_entry *ce = istate->cache[pos++];\n \n \t\tif (strncmp(ce->name, path, len))\n \t\t\tbreak;\n@@ -377,7 +377,7 @@ static int process_path(const char *path, struct stat *st, int stat_errno)\n \t\treturn error(\"'%s' is beyond a symbolic link\", path);\n \n \tpos = cache_name_pos(path, len);\n-\tce = pos < 0 ? NULL : active_cache[pos];\n+\tce = pos < 0 ? NULL : istate->cache[pos];\n \tif (ce && ce_skip_worktree(ce)) {\n \t\t/*\n \t\t * working directory version is assumed \"good\"\n@@ -428,7 +428,7 @@ static void chmod_path(char flip, const char *path)\n \tpos = cache_name_pos(path, strlen(path));\n \tif (pos < 0)\n \t\tgoto fail;\n-\tce = active_cache[pos];\n+\tce = istate->cache[pos];\n \tif (chmod_cache_entry(ce, flip) < 0)\n \t\tgoto fail;\n \n@@ -628,7 +628,7 @@ static int unresolve_one(const char *path)\n \t\t/* already merged */\n \t\tpos = unmerge_cache_entry_at(pos);\n \t\tif (pos < active_nr) {\n-\t\t\tconst struct cache_entry *ce = active_cache[pos];\n+\t\t\tconst struct cache_entry *ce = repo->index->cache[pos];\n \t\t\tif (ce_stage(ce) &&\n \t\t\t    ce_namelen(ce) == namelen &&\n \t\t\t    !memcmp(ce->name, path, namelen))\n@@ -642,7 +642,7 @@ static int unresolve_one(const char *path)\n \t\t */\n \t\tpos = -pos-1;\n \t\tif (pos < active_nr) {\n-\t\t\tconst struct cache_entry *ce = active_cache[pos];\n+\t\t\tconst struct cache_entry *ce = repo->index->cache[pos];\n \t\t\tif (ce_namelen(ce) == namelen &&\n \t\t\t    !memcmp(ce->name, path, namelen)) {\n \t\t\t\tfprintf(stderr,\n@@ -738,7 +738,7 @@ static int do_reupdate(int ac, const char **av,\n \t\thas_head = 0;\n  redo:\n \tfor (pos = 0; pos < active_nr; pos++) {\n-\t\tconst struct cache_entry *ce = active_cache[pos];\n+\t\tconst struct cache_entry *ce = repo->index->cache[pos];\n \t\tstruct cache_entry *old = NULL;\n \t\tint save_nr;\n \t\tchar *path;\n-- \ngitgitgadget\n\n"},{"id":"413876","messageId":"f60f34ac1f5a9933742892c7d5ef03e864faf52b.1610136177.git.gitgitgadget@gmail.com","threadId":"54916","inReplyTo":"pull.830.v3.git.1610136177.gitgitgadget@gmail.com","subject":"[PATCH v3 03/14] update-index: drop the_index, the_repository","fromName":"Derrick Stolee via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-01-08T20:02:46Z","receivedAt":"2021-01-08T20:04:00Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"From: Derrick Stolee <dstolee@microsoft.com>\n\nTo reduce the need for the index compatibility macros, we will replace\ntheir uses in update-index mechanically. This is the most interesting\nchange, which creates global \"repo\" and \"istate\" pointers. The macros\nthat expand to use the_index can then be mechanically replaced by\nreferences to the istate pointer.\n\nWe will be careful to use \"repo->index\" over \"istate\" whenever repo is\nneeded by a method.\n\nSigned-off-by: Derrick Stolee <dstolee@microsoft.com>\n---\n builtin/update-index.c | 59 +++++++++++++++++++++++-------------------\n 1 file changed, 32 insertions(+), 27 deletions(-)\n\ndiff --git a/builtin/update-index.c b/builtin/update-index.c\nindex 44862f5e1de..22284f301dc 100644\n--- a/builtin/update-index.c\n+++ b/builtin/update-index.c\n@@ -227,18 +227,20 @@ static int test_if_untracked_cache_is_supported(void)\n \treturn ret;\n }\n \n+static struct index_state *istate;\n+\n static int mark_ce_flags(const char *path, int flag, int mark)\n {\n \tint namelen = strlen(path);\n \tint pos = cache_name_pos(path, namelen);\n \tif (0 <= pos) {\n-\t\tmark_fsmonitor_invalid(&the_index, active_cache[pos]);\n+\t\tmark_fsmonitor_invalid(istate, active_cache[pos]);\n \t\tif (mark)\n \t\t\tactive_cache[pos]->ce_flags |= flag;\n \t\telse\n \t\t\tactive_cache[pos]->ce_flags &= ~flag;\n \t\tactive_cache[pos]->ce_flags |= CE_UPDATE_IN_BASE;\n-\t\tcache_tree_invalidate_path(&the_index, path);\n+\t\tcache_tree_invalidate_path(istate, path);\n \t\tactive_cache_changed |= CE_ENTRY_CHANGED;\n \t\treturn 0;\n \t}\n@@ -277,14 +279,14 @@ static int add_one_path(const struct cache_entry *old, const char *path, int len\n \tif (old && !ce_stage(old) && !ce_match_stat(old, st, 0))\n \t\treturn 0;\n \n-\tce = make_empty_cache_entry(&the_index, len);\n+\tce = make_empty_cache_entry(istate, len);\n \tmemcpy(ce->name, path, len);\n \tce->ce_flags = create_ce_flags(0);\n \tce->ce_namelen = len;\n-\tfill_stat_cache_info(&the_index, ce, st);\n+\tfill_stat_cache_info(istate, ce, st);\n \tce->ce_mode = ce_mode_from_stat(old, st->st_mode);\n \n-\tif (index_path(&the_index, &ce->oid, path, st,\n+\tif (index_path(istate, &ce->oid, path, st,\n \t\t       info_only ? 0 : HASH_WRITE_OBJECT)) {\n \t\tdiscard_cache_entry(ce);\n \t\treturn -1;\n@@ -406,7 +408,7 @@ static int add_cacheinfo(unsigned int mode, const struct object_id *oid,\n {\n \tint res;\n \n-\tres = add_to_index_cacheinfo(&the_index, mode, oid, path, stage,\n+\tres = add_to_index_cacheinfo(istate, mode, oid, path, stage,\n \t\t\t\t     allow_add, allow_replace, NULL);\n \tif (res == -1)\n \t\treturn res;\n@@ -583,6 +585,7 @@ static const char * const update_index_usage[] = {\n \n static struct object_id head_oid;\n static struct object_id merge_head_oid;\n+static struct repository *repo;\n \n static struct cache_entry *read_one_ent(const char *which,\n \t\t\t\t\tstruct object_id *ent, const char *path,\n@@ -592,7 +595,7 @@ static struct cache_entry *read_one_ent(const char *which,\n \tstruct object_id oid;\n \tstruct cache_entry *ce;\n \n-\tif (get_tree_entry(the_repository, ent, path, &oid, &mode)) {\n+\tif (get_tree_entry(repo, ent, path, &oid, &mode)) {\n \t\tif (which)\n \t\t\terror(\"%s: not in %s branch.\", path, which);\n \t\treturn NULL;\n@@ -602,7 +605,7 @@ static struct cache_entry *read_one_ent(const char *which,\n \t\t\terror(\"%s: not a blob in %s branch.\", path, which);\n \t\treturn NULL;\n \t}\n-\tce = make_empty_cache_entry(&the_index, namelen);\n+\tce = make_empty_cache_entry(repo->index, namelen);\n \n \toidcpy(&ce->oid, &oid);\n \tmemcpy(ce->name, path, namelen);\n@@ -740,7 +743,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(&the_index, ce, &pathspec, NULL))\n+\t\tif (ce_stage(ce) || !ce_path_match(repo->index, ce, &pathspec, NULL))\n \t\t\tcontinue;\n \t\tif (has_head)\n \t\t\told = read_one_ent(NULL, &head_oid,\n@@ -957,7 +960,6 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \tstruct parse_opt_ctx_t ctx;\n \tstrbuf_getline_fn getline_fn;\n \tint parseopt_state = PARSE_OPT_UNKNOWN;\n-\tstruct repository *r = the_repository;\n \tstruct option options[] = {\n \t\tOPT_BIT('q', NULL, &refresh_args.flags,\n \t\t\tN_(\"continue refresh even when index needs update\"),\n@@ -1066,16 +1068,19 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \n \tgit_config(git_default_config, NULL);\n \n+\trepo = the_repository;\n+\n \t/* we will diagnose later if it turns out that we need to update it */\n-\tnewfd = hold_locked_index(&lock_file, 0);\n+\tnewfd = repo_hold_locked_index(repo, &lock_file, 0);\n \tif (newfd < 0)\n \t\tlock_error = errno;\n \n-\tentries = read_cache();\n+\tentries = repo_read_index(repo);\n \tif (entries < 0)\n \t\tdie(\"cache corrupted\");\n \n-\tthe_index.updated_skipworktree = 1;\n+\tistate = repo->index;\n+\trepo->index->updated_skipworktree = 1;\n \n \t/*\n \t * Custom copy of parse_options() because we want to handle\n@@ -1129,9 +1134,9 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \t\t\t    preferred_index_format,\n \t\t\t    INDEX_FORMAT_LB, INDEX_FORMAT_UB);\n \n-\t\tif (the_index.version != preferred_index_format)\n+\t\tif (repo->index->version != preferred_index_format)\n \t\t\tactive_cache_changed |= SOMETHING_CHANGED;\n-\t\tthe_index.version = preferred_index_format;\n+\t\trepo->index->version = preferred_index_format;\n \t}\n \n \tif (read_from_stdin) {\n@@ -1162,28 +1167,28 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \t\t\twarning(_(\"core.splitIndex is set to false; \"\n \t\t\t\t  \"remove or change it, if you really want to \"\n \t\t\t\t  \"enable split index\"));\n-\t\tif (the_index.split_index)\n-\t\t\tthe_index.cache_changed |= SPLIT_INDEX_ORDERED;\n+\t\tif (repo->index->split_index)\n+\t\t\trepo->index->cache_changed |= SPLIT_INDEX_ORDERED;\n \t\telse\n-\t\t\tadd_split_index(&the_index);\n+\t\t\tadd_split_index(repo->index);\n \t} else if (!split_index) {\n \t\tif (git_config_get_split_index() == 1)\n \t\t\twarning(_(\"core.splitIndex is set to true; \"\n \t\t\t\t  \"remove or change it, if you really want to \"\n \t\t\t\t  \"disable split index\"));\n-\t\tremove_split_index(&the_index);\n+\t\tremove_split_index(repo->index);\n \t}\n \n-\tprepare_repo_settings(r);\n+\tprepare_repo_settings(repo);\n \tswitch (untracked_cache) {\n \tcase UC_UNSPECIFIED:\n \t\tbreak;\n \tcase UC_DISABLE:\n-\t\tif (r->settings.core_untracked_cache == UNTRACKED_CACHE_WRITE)\n+\t\tif (repo->settings.core_untracked_cache == UNTRACKED_CACHE_WRITE)\n \t\t\twarning(_(\"core.untrackedCache is set to true; \"\n \t\t\t\t  \"remove or change it, if you really want to \"\n \t\t\t\t  \"disable the untracked cache\"));\n-\t\tremove_untracked_cache(&the_index);\n+\t\tremove_untracked_cache(repo->index);\n \t\treport(_(\"Untracked cache disabled\"));\n \t\tbreak;\n \tcase UC_TEST:\n@@ -1191,11 +1196,11 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \t\treturn !test_if_untracked_cache_is_supported();\n \tcase UC_ENABLE:\n \tcase UC_FORCE:\n-\t\tif (r->settings.core_untracked_cache == UNTRACKED_CACHE_REMOVE)\n+\t\tif (repo->settings.core_untracked_cache == UNTRACKED_CACHE_REMOVE)\n \t\t\twarning(_(\"core.untrackedCache is set to false; \"\n \t\t\t\t  \"remove or change it, if you really want to \"\n \t\t\t\t  \"enable the untracked cache\"));\n-\t\tadd_untracked_cache(&the_index);\n+\t\tadd_untracked_cache(repo->index);\n \t\treport(_(\"Untracked cache enabled for '%s'\"), get_git_work_tree());\n \t\tbreak;\n \tdefault:\n@@ -1207,14 +1212,14 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \t\t\twarning(_(\"core.fsmonitor is unset; \"\n \t\t\t\t\"set it if you really want to \"\n \t\t\t\t\"enable fsmonitor\"));\n-\t\tadd_fsmonitor(&the_index);\n+\t\tadd_fsmonitor(repo->index);\n \t\treport(_(\"fsmonitor enabled\"));\n \t} else if (!fsmonitor) {\n \t\tif (git_config_get_fsmonitor() == 1)\n \t\t\twarning(_(\"core.fsmonitor is set; \"\n \t\t\t\t\"remove it if you really want to \"\n \t\t\t\t\"disable fsmonitor\"));\n-\t\tremove_fsmonitor(&the_index);\n+\t\tremove_fsmonitor(repo->index);\n \t\treport(_(\"fsmonitor disabled\"));\n \t}\n \n@@ -1224,7 +1229,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \t\t\t\texit(128);\n \t\t\tunable_to_lock_die(get_index_file(), lock_error);\n \t\t}\n-\t\tif (write_locked_index(&the_index, &lock_file, COMMIT_LOCK))\n+\t\tif (write_locked_index(repo->index, &lock_file, COMMIT_LOCK))\n \t\t\tdie(\"Unable to write new index file\");\n \t}\n \n-- \ngitgitgadget\n\n"},{"id":"413877","messageId":"4754a9214ee9900302fc01501c4b15083ed2c2db.1610136177.git.gitgitgadget@gmail.com","threadId":"54916","inReplyTo":"pull.830.v3.git.1610136177.gitgitgadget@gmail.com","subject":"[PATCH v3 12/14] update-index: reduce static globals, part 1","fromName":"Derrick Stolee via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-01-08T20:02:55Z","receivedAt":"2021-01-08T20:04:15Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"From: Derrick Stolee <dstolee@microsoft.com>\n\nIn order to remove index compatibility macros cleanly, we relied upon\nstatic globals 'repo' and 'istate' to be pointers to the_repository and\nthe_index, respectively. We can now start reducing the need for these\nstatic globals by modifying method prototypes to use them when\nnecessary.\n\nRemove the 'istate' static global in favor of method parameters. This\nadjusts some callers, which either use their own 'istate' parameter or\n'repo->index'.\n\nSigned-off-by: Derrick Stolee <dstolee@microsoft.com>\n---\n builtin/update-index.c | 74 +++++++++++++++++++++++-------------------\n 1 file changed, 41 insertions(+), 33 deletions(-)\n\ndiff --git a/builtin/update-index.c b/builtin/update-index.c\nindex 1c1cb8f8d4a..9a83603c0db 100644\n--- a/builtin/update-index.c\n+++ b/builtin/update-index.c\n@@ -226,9 +226,8 @@ static int test_if_untracked_cache_is_supported(void)\n \treturn ret;\n }\n \n-static struct index_state *istate;\n-\n-static int mark_ce_flags(const char *path, int flag, int mark)\n+static int mark_ce_flags(struct index_state *istate,\n+\t\t\t const char *path, int flag, int mark)\n {\n \tint namelen = strlen(path);\n \tint pos = index_name_pos(istate, path, namelen);\n@@ -246,7 +245,7 @@ static int mark_ce_flags(const char *path, int flag, int mark)\n \treturn -1;\n }\n \n-static int remove_one_path(const char *path)\n+static int remove_one_path(struct index_state *istate, const char *path)\n {\n \tif (!allow_remove)\n \t\treturn error(\"%s: does not exist and --remove not passed\", path);\n@@ -262,14 +261,17 @@ static int remove_one_path(const char *path)\n  *    succeeds.\n  *  - permission error. That's never ok.\n  */\n-static int process_lstat_error(const char *path, int err)\n+static int process_lstat_error(struct index_state *istate,\n+\t\t\t       const char *path, int err)\n {\n \tif (is_missing_file_error(err))\n-\t\treturn remove_one_path(path);\n+\t\treturn remove_one_path(istate, path);\n \treturn error(\"lstat(\\\"%s\\\"): %s\", path, strerror(err));\n }\n \n-static int add_one_path(const struct cache_entry *old, const char *path, int len, struct stat *st)\n+static int add_one_path(struct index_state *istate,\n+\t\t\tconst struct cache_entry *old,\n+\t\t\tconst char *path, int len, struct stat *st)\n {\n \tint option;\n \tstruct cache_entry *ce;\n@@ -322,7 +324,8 @@ static int add_one_path(const struct cache_entry *old, const char *path, int len\n  *  - it doesn't exist at all in the index, but it is a valid\n  *    git directory, and it should be *added* as a gitlink.\n  */\n-static int process_directory(const char *path, int len, struct stat *st)\n+static int process_directory(struct index_state *istate,\n+\t\t\t     const char *path, int len, struct stat *st)\n {\n \tstruct object_id oid;\n \tint pos = index_name_pos(istate, path, len);\n@@ -336,10 +339,10 @@ static int process_directory(const char *path, int len, struct stat *st)\n \t\t\tif (resolve_gitlink_ref(path, \"HEAD\", &oid) < 0)\n \t\t\t\treturn 0;\n \n-\t\t\treturn add_one_path(ce, path, len, st);\n+\t\t\treturn add_one_path(istate, ce, path, len, st);\n \t\t}\n \t\t/* Should this be an unconditional error? */\n-\t\treturn remove_one_path(path);\n+\t\treturn remove_one_path(istate, path);\n \t}\n \n \t/* Inexact match: is there perhaps a subdirectory match? */\n@@ -360,13 +363,14 @@ static int process_directory(const char *path, int len, struct stat *st)\n \n \t/* No match - should we add it as a gitlink? */\n \tif (!resolve_gitlink_ref(path, \"HEAD\", &oid))\n-\t\treturn add_one_path(NULL, path, len, st);\n+\t\treturn add_one_path(istate, NULL, path, len, st);\n \n \t/* Error out. */\n \treturn error(\"%s: is a directory - add files inside instead\", path);\n }\n \n-static int process_path(const char *path, struct stat *st, int stat_errno)\n+static int process_path(struct index_state *istate,\n+\t\t\tconst char *path, struct stat *st, int stat_errno)\n {\n \tint pos, len;\n \tconst struct cache_entry *ce;\n@@ -394,15 +398,16 @@ static int process_path(const char *path, struct stat *st, int stat_errno)\n \t * what to do about the pathname!\n \t */\n \tif (stat_errno)\n-\t\treturn process_lstat_error(path, stat_errno);\n+\t\treturn process_lstat_error(istate, path, stat_errno);\n \n \tif (S_ISDIR(st->st_mode))\n-\t\treturn process_directory(path, len, st);\n+\t\treturn process_directory(istate, path, len, st);\n \n-\treturn add_one_path(ce, path, len, st);\n+\treturn add_one_path(istate, ce, path, len, st);\n }\n \n-static int add_cacheinfo(unsigned int mode, const struct object_id *oid,\n+static int add_cacheinfo(struct index_state *istate,\n+\t\t\t unsigned int mode, const struct object_id *oid,\n \t\t\t const char *path, int stage)\n {\n \tint res;\n@@ -419,7 +424,8 @@ static int add_cacheinfo(unsigned int mode, const struct object_id *oid,\n \treturn 0;\n }\n \n-static void chmod_path(char flip, const char *path)\n+static void chmod_path(struct index_state *istate,\n+\t\t       char flip, const char *path)\n {\n \tint pos;\n \tstruct cache_entry *ce;\n@@ -437,7 +443,7 @@ static void chmod_path(char flip, const char *path)\n \tdie(\"git update-index: cannot chmod %cx '%s'\", flip, path);\n }\n \n-static void update_one(const char *path)\n+static void update_one(struct index_state *istate, const char *path)\n {\n \tint stat_errno = 0;\n \tstruct stat st;\n@@ -455,17 +461,20 @@ static void update_one(const char *path)\n \t\treturn;\n \t}\n \tif (mark_valid_only) {\n-\t\tif (mark_ce_flags(path, CE_VALID, mark_valid_only == MARK_FLAG))\n+\t\tif (mark_ce_flags(istate, path, CE_VALID,\n+\t\t\t\t  mark_valid_only == MARK_FLAG))\n \t\t\tdie(\"Unable to mark file %s\", path);\n \t\treturn;\n \t}\n \tif (mark_skip_worktree_only) {\n-\t\tif (mark_ce_flags(path, CE_SKIP_WORKTREE, mark_skip_worktree_only == MARK_FLAG))\n+\t\tif (mark_ce_flags(istate, path, CE_SKIP_WORKTREE,\n+\t\t\t\t  mark_skip_worktree_only == MARK_FLAG))\n \t\t\tdie(\"Unable to mark file %s\", path);\n \t\treturn;\n \t}\n \tif (mark_fsmonitor_only) {\n-\t\tif (mark_ce_flags(path, CE_FSMONITOR_VALID, mark_fsmonitor_only == MARK_FLAG))\n+\t\tif (mark_ce_flags(istate, path, CE_FSMONITOR_VALID,\n+\t\t\t\t  mark_fsmonitor_only == MARK_FLAG))\n \t\t\tdie(\"Unable to mark file %s\", path);\n \t\treturn;\n \t}\n@@ -476,12 +485,12 @@ static void update_one(const char *path)\n \t\treport(\"remove '%s'\", path);\n \t\treturn;\n \t}\n-\tif (process_path(path, &st, stat_errno))\n+\tif (process_path(istate, path, &st, stat_errno))\n \t\tdie(\"Unable to process path %s\", path);\n \treport(\"add '%s'\", path);\n }\n \n-static void read_index_info(int nul_term_line)\n+static void read_index_info(struct index_state *istate, int nul_term_line)\n {\n \tconst int hexsz = the_hash_algo->hexsz;\n \tstruct strbuf buf = STRBUF_INIT;\n@@ -564,7 +573,7 @@ static void read_index_info(int nul_term_line)\n \t\t\t * ptr[-41] is at the beginning of sha1\n \t\t\t */\n \t\t\tptr[-(hexsz + 2)] = ptr[-1] = 0;\n-\t\t\tif (add_cacheinfo(mode, &oid, path_name, stage))\n+\t\t\tif (add_cacheinfo(istate, mode, &oid, path_name, stage))\n \t\t\t\tdie(\"git update-index: unable to update %s\",\n \t\t\t\t    path_name);\n \t\t}\n@@ -758,7 +767,7 @@ static int do_reupdate(int ac, const char **av,\n \t\t */\n \t\tsave_nr = repo->index->cache_nr;\n \t\tpath = xstrdup(ce->name);\n-\t\tupdate_one(path);\n+\t\tupdate_one(repo->index, path);\n \t\tfree(path);\n \t\tdiscard_cache_entry(old);\n \t\tif (save_nr != repo->index->cache_nr)\n@@ -854,7 +863,7 @@ static enum parse_opt_result cacheinfo_callback(\n \tBUG_ON_OPT_ARG(arg);\n \n \tif (!parse_new_style_cacheinfo(ctx->argv[1], &mode, &oid, &path)) {\n-\t\tif (add_cacheinfo(mode, &oid, path, 0))\n+\t\tif (add_cacheinfo(repo->index, mode, &oid, path, 0))\n \t\t\tdie(\"git update-index: --cacheinfo cannot add %s\", path);\n \t\tctx->argv++;\n \t\tctx->argc--;\n@@ -864,7 +873,7 @@ static enum parse_opt_result cacheinfo_callback(\n \t\treturn error(\"option 'cacheinfo' expects <mode>,<sha1>,<path>\");\n \tif (strtoul_ui(*++ctx->argv, 8, &mode) ||\n \t    get_oid_hex(*++ctx->argv, &oid) ||\n-\t    add_cacheinfo(mode, &oid, *++ctx->argv, 0))\n+\t    add_cacheinfo(repo->index, mode, &oid, *++ctx->argv, 0))\n \t\tdie(\"git update-index: --cacheinfo cannot add %s\", *ctx->argv);\n \tctx->argc -= 3;\n \treturn 0;\n@@ -882,7 +891,7 @@ static enum parse_opt_result stdin_cacheinfo_callback(\n \tif (ctx->argc != 1)\n \t\treturn error(\"option '%s' must be the last argument\", opt->long_name);\n \tallow_add = allow_replace = allow_remove = 1;\n-\tread_index_info(*nul_term_line);\n+\tread_index_info(repo->index, *nul_term_line);\n \treturn 0;\n }\n \n@@ -1079,7 +1088,6 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \tif (entries < 0)\n \t\tdie(\"cache corrupted\");\n \n-\tistate = repo->index;\n \trepo->index->updated_skipworktree = 1;\n \n \t/*\n@@ -1108,9 +1116,9 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \n \t\t\tsetup_work_tree();\n \t\t\tp = prefix_path(prefix, prefix_length, path);\n-\t\t\tupdate_one(p);\n+\t\t\tupdate_one(repo->index, p);\n \t\t\tif (set_executable_bit)\n-\t\t\t\tchmod_path(set_executable_bit, p);\n+\t\t\t\tchmod_path(repo->index, set_executable_bit, p);\n \t\t\tfree(p);\n \t\t\tctx.argc--;\n \t\t\tctx.argv++;\n@@ -1153,9 +1161,9 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \t\t\t\tstrbuf_swap(&buf, &unquoted);\n \t\t\t}\n \t\t\tp = prefix_path(prefix, prefix_length, buf.buf);\n-\t\t\tupdate_one(p);\n+\t\t\tupdate_one(repo->index, p);\n \t\t\tif (set_executable_bit)\n-\t\t\t\tchmod_path(set_executable_bit, p);\n+\t\t\t\tchmod_path(repo->index, set_executable_bit, p);\n \t\t\tfree(p);\n \t\t}\n \t\tstrbuf_release(&unquoted);\n-- \ngitgitgadget\n\n"},{"id":"413878","messageId":"586371ee769f61cc42957bd53bd6a257eacec211.1610136177.git.gitgitgadget@gmail.com","threadId":"54916","inReplyTo":"pull.830.v3.git.1610136177.gitgitgadget@gmail.com","subject":"[PATCH v3 05/14] update-index: use istate->cache_nr over active_nr","fromName":"Derrick Stolee via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-01-08T20:02:48Z","receivedAt":"2021-01-08T20:04:22Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"From: Derrick Stolee <dstolee@microsoft.com>\n\nAlso use \"repo->index\" over \"istate\" when possible.\n\nSigned-off-by: Derrick Stolee <dstolee@microsoft.com>\n---\n builtin/update-index.c | 14 +++++++-------\n 1 file changed, 7 insertions(+), 7 deletions(-)\n\ndiff --git a/builtin/update-index.c b/builtin/update-index.c\nindex 0c5a10f5dba..2b03b29261b 100644\n--- a/builtin/update-index.c\n+++ b/builtin/update-index.c\n@@ -345,7 +345,7 @@ static int process_directory(const char *path, int len, struct stat *st)\n \n \t/* Inexact match: is there perhaps a subdirectory match? */\n \tpos = -pos-1;\n-\twhile (pos < active_nr) {\n+\twhile (pos < istate->cache_nr) {\n \t\tconst struct cache_entry *ce = istate->cache[pos++];\n \n \t\tif (strncmp(ce->name, path, len))\n@@ -627,7 +627,7 @@ static int unresolve_one(const char *path)\n \tif (0 <= pos) {\n \t\t/* already merged */\n \t\tpos = unmerge_cache_entry_at(pos);\n-\t\tif (pos < active_nr) {\n+\t\tif (pos < repo->index->cache_nr) {\n \t\t\tconst struct cache_entry *ce = repo->index->cache[pos];\n \t\t\tif (ce_stage(ce) &&\n \t\t\t    ce_namelen(ce) == namelen &&\n@@ -641,7 +641,7 @@ static int unresolve_one(const char *path)\n \t\t * want to do anything in the former case.\n \t\t */\n \t\tpos = -pos-1;\n-\t\tif (pos < active_nr) {\n+\t\tif (pos < repo->index->cache_nr) {\n \t\t\tconst struct cache_entry *ce = repo->index->cache[pos];\n \t\t\tif (ce_namelen(ce) == namelen &&\n \t\t\t    !memcmp(ce->name, path, namelen)) {\n@@ -737,7 +737,7 @@ static int do_reupdate(int ac, const char **av,\n \t\t */\n \t\thas_head = 0;\n  redo:\n-\tfor (pos = 0; pos < active_nr; pos++) {\n+\tfor (pos = 0; pos < repo->index->cache_nr; pos++) {\n \t\tconst struct cache_entry *ce = repo->index->cache[pos];\n \t\tstruct cache_entry *old = NULL;\n \t\tint save_nr;\n@@ -755,14 +755,14 @@ static int do_reupdate(int ac, const char **av,\n \t\t}\n \t\t/* Be careful.  The working tree may not have the\n \t\t * path anymore, in which case, under 'allow_remove',\n-\t\t * or worse yet 'allow_replace', active_nr may decrease.\n+\t\t * or worse yet 'allow_replace', repo->index->cache_nr may decrease.\n \t\t */\n-\t\tsave_nr = active_nr;\n+\t\tsave_nr = repo->index->cache_nr;\n \t\tpath = xstrdup(ce->name);\n \t\tupdate_one(path);\n \t\tfree(path);\n \t\tdiscard_cache_entry(old);\n-\t\tif (save_nr != active_nr)\n+\t\tif (save_nr != repo->index->cache_nr)\n \t\t\tgoto redo;\n \t}\n \tclear_pathspec(&pathspec);\n-- \ngitgitgadget\n\n"},{"id":"413879","messageId":"fc640ae6e652c175e2bbbe7bba3b856ae20265d1.1610136177.git.gitgitgadget@gmail.com","threadId":"54916","inReplyTo":"pull.830.v3.git.1610136177.gitgitgadget@gmail.com","subject":"[PATCH v3 07/14] update-index: use index_name_pos() over cache_name_pos()","fromName":"Derrick Stolee via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-01-08T20:02:50Z","receivedAt":"2021-01-08T20:04:24Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"From: Derrick Stolee <dstolee@microsoft.com>\n\nSigned-off-by: Derrick Stolee <dstolee@microsoft.com>\n---\n builtin/update-index.c | 10 +++++-----\n 1 file changed, 5 insertions(+), 5 deletions(-)\n\ndiff --git a/builtin/update-index.c b/builtin/update-index.c\nindex 70ca47e712c..a24b1fc90e4 100644\n--- a/builtin/update-index.c\n+++ b/builtin/update-index.c\n@@ -232,7 +232,7 @@ static struct index_state *istate;\n static int mark_ce_flags(const char *path, int flag, int mark)\n {\n \tint namelen = strlen(path);\n-\tint pos = cache_name_pos(path, namelen);\n+\tint pos = index_name_pos(istate, path, namelen);\n \tif (0 <= pos) {\n \t\tmark_fsmonitor_invalid(istate, istate->cache[pos]);\n \t\tif (mark)\n@@ -326,7 +326,7 @@ static int add_one_path(const struct cache_entry *old, const char *path, int len\n static int process_directory(const char *path, int len, struct stat *st)\n {\n \tstruct object_id oid;\n-\tint pos = cache_name_pos(path, len);\n+\tint pos = index_name_pos(istate, path, len);\n \n \t/* Exact match: file or existing gitlink */\n \tif (pos >= 0) {\n@@ -376,7 +376,7 @@ static int process_path(const char *path, struct stat *st, int stat_errno)\n \tif (has_symlink_leading_path(path, len))\n \t\treturn error(\"'%s' is beyond a symbolic link\", path);\n \n-\tpos = cache_name_pos(path, len);\n+\tpos = index_name_pos(istate, path, len);\n \tce = pos < 0 ? NULL : istate->cache[pos];\n \tif (ce && ce_skip_worktree(ce)) {\n \t\t/*\n@@ -425,7 +425,7 @@ static void chmod_path(char flip, const char *path)\n \tint pos;\n \tstruct cache_entry *ce;\n \n-\tpos = cache_name_pos(path, strlen(path));\n+\tpos = index_name_pos(istate, path, strlen(path));\n \tif (pos < 0)\n \t\tgoto fail;\n \tce = istate->cache[pos];\n@@ -623,7 +623,7 @@ static int unresolve_one(const char *path)\n \tstruct cache_entry *ce_2 = NULL, *ce_3 = NULL;\n \n \t/* See if there is such entry in the index. */\n-\tpos = cache_name_pos(path, namelen);\n+\tpos = index_name_pos(repo->index, path, namelen);\n \tif (0 <= pos) {\n \t\t/* already merged */\n \t\tpos = unmerge_cache_entry_at(pos);\n-- \ngitgitgadget\n\n"},{"id":"413880","messageId":"8016b089556c7ae3633480a4e11c0b2ef055cd42.1610136177.git.gitgitgadget@gmail.com","threadId":"54916","inReplyTo":"pull.830.v3.git.1610136177.gitgitgadget@gmail.com","subject":"[PATCH v3 09/14] update-index: use add_index_entry()","fromName":"Derrick Stolee via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-01-08T20:02:52Z","receivedAt":"2021-01-08T20:04:25Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"From: Derrick Stolee <dstolee@microsoft.com>\n\nThis is a mechanical replacement of add_cache_entry().\n\nSigned-off-by: Derrick Stolee <dstolee@microsoft.com>\n---\n builtin/update-index.c | 6 +++---\n 1 file changed, 3 insertions(+), 3 deletions(-)\n\ndiff --git a/builtin/update-index.c b/builtin/update-index.c\nindex 87fbc580032..a1e4ee89056 100644\n--- a/builtin/update-index.c\n+++ b/builtin/update-index.c\n@@ -293,7 +293,7 @@ static int add_one_path(const struct cache_entry *old, const char *path, int len\n \t}\n \toption = allow_add ? ADD_CACHE_OK_TO_ADD : 0;\n \toption |= allow_replace ? ADD_CACHE_OK_TO_REPLACE : 0;\n-\tif (add_cache_entry(ce, option)) {\n+\tif (add_index_entry(istate, ce, option)) {\n \t\tdiscard_cache_entry(ce);\n \t\treturn error(\"%s: cannot add to the index - missing --add option?\", path);\n \t}\n@@ -672,12 +672,12 @@ static int unresolve_one(const char *path)\n \t}\n \n \tremove_file_from_index(repo->index, path);\n-\tif (add_cache_entry(ce_2, ADD_CACHE_OK_TO_ADD)) {\n+\tif (add_index_entry(repo->index, ce_2, ADD_CACHE_OK_TO_ADD)) {\n \t\terror(\"%s: cannot add our version to the index.\", path);\n \t\tret = -1;\n \t\tgoto free_return;\n \t}\n-\tif (!add_cache_entry(ce_3, ADD_CACHE_OK_TO_ADD))\n+\tif (!add_index_entry(repo->index, ce_3, ADD_CACHE_OK_TO_ADD))\n \t\treturn 0;\n \terror(\"%s: cannot add their version to the index.\", path);\n \tret = -1;\n-- \ngitgitgadget\n\n"},{"id":"413881","messageId":"e9d4fa613a65e0fedde0648b5fbf71e16f8fe8a0.1610136177.git.gitgitgadget@gmail.com","threadId":"54916","inReplyTo":"pull.830.v3.git.1610136177.gitgitgadget@gmail.com","subject":"[PATCH v3 11/14] update-index: remove ce_match_stat(), all macros","fromName":"Derrick Stolee via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-01-08T20:02:54Z","receivedAt":"2021-01-08T20:04:25Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"From: Derrick Stolee <dstolee@microsoft.com>\n\nThe final index compatibility macro to remove from the update-index\nbuiltin is ce_match_stat(). Further, this is the last use of that macro\nanywhere, so it should be removed.\n\nThere are some remaining references in the racy-git.txt technical\ndocument that are updated to ie_match_stat().\n\nSigned-off-by: Derrick Stolee <dstolee@microsoft.com>\n---\n Documentation/technical/racy-git.txt | 6 +++---\n builtin/update-index.c               | 3 +--\n cache.h                              | 1 -\n 3 files changed, 4 insertions(+), 6 deletions(-)\n\ndiff --git a/Documentation/technical/racy-git.txt b/Documentation/technical/racy-git.txt\nindex ceda4bbfda4..65188e04559 100644\n--- a/Documentation/technical/racy-git.txt\n+++ b/Documentation/technical/racy-git.txt\n@@ -26,7 +26,7 @@ information obtained from the filesystem via `lstat(2)` system\n call when they were last updated.  When checking if they differ,\n Git first runs `lstat(2)` on the files and compares the result\n with this information (this is what was originally done by the\n-`ce_match_stat()` function, but the current code does it in\n+`ie_match_stat()` function, but the current code does it in\n `ce_match_stat_basic()` function).  If some of these \"cached\n stat information\" fields do not match, Git can tell that the\n files are modified without even looking at their contents.\n@@ -102,7 +102,7 @@ timestamp as the index file itself.\n \n The callers that want to check if an index entry matches the\n corresponding file in the working tree continue to call\n-`ce_match_stat()`, but with this change, `ce_match_stat()` uses\n+`ie_match_stat()`, but with this change, `ie_match_stat()` uses\n `ce_modified_check_fs()` to see if racily clean ones are\n actually clean after comparing the cached stat information using\n `ce_match_stat_basic()`.\n@@ -128,7 +128,7 @@ Runtime penalty\n ---------------\n \n The runtime penalty of falling back to `ce_modified_check_fs()`\n-from `ce_match_stat()` can be very expensive when there are many\n+from `ie_match_stat()` can be very expensive when there are many\n racily clean entries.  An obvious way to artificially create\n this situation is to give the same timestamp to all the files in\n the working tree in a large project, run `git update-index` on\ndiff --git a/builtin/update-index.c b/builtin/update-index.c\nindex 64feb47c97f..1c1cb8f8d4a 100644\n--- a/builtin/update-index.c\n+++ b/builtin/update-index.c\n@@ -3,7 +3,6 @@\n  *\n  * Copyright (C) Linus Torvalds, 2005\n  */\n-#define USE_THE_INDEX_COMPATIBILITY_MACROS\n #include \"cache.h\"\n #include \"config.h\"\n #include \"lockfile.h\"\n@@ -276,7 +275,7 @@ static int add_one_path(const struct cache_entry *old, const char *path, int len\n \tstruct cache_entry *ce;\n \n \t/* Was the old index entry already up-to-date? */\n-\tif (old && !ce_stage(old) && !ce_match_stat(old, st, 0))\n+\tif (old && !ce_stage(old) && !ie_match_stat(istate, old, st, 0))\n \t\treturn 0;\n \n \tce = make_empty_cache_entry(istate, len);\ndiff --git a/cache.h b/cache.h\nindex 8c091be6256..740bd0aa1dd 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -416,7 +416,6 @@ extern struct index_state the_index;\n #define chmod_cache_entry(ce, flip) chmod_index_entry(&the_index, (ce), (flip))\n #define refresh_cache(flags) refresh_index(&the_index, (flags), NULL, NULL, NULL)\n #define refresh_and_write_cache(refresh_flags, write_flags, gentle) repo_refresh_and_write_index(the_repository, (refresh_flags), (write_flags), (gentle), NULL, NULL, NULL)\n-#define ce_match_stat(ce, st, options) ie_match_stat(&the_index, (ce), (st), (options))\n #define ce_modified(ce, st, options) ie_modified(&the_index, (ce), (st), (options))\n #define cache_dir_exists(name, namelen) index_dir_exists(&the_index, (name), (namelen))\n #define cache_name_is_other(name, namelen) index_name_is_other(&the_index, (name), (namelen))\n-- \ngitgitgadget\n\n"},{"id":"413882","messageId":"f450f43cd0dc837622ada37d45b35f465ef902c8.1610136177.git.gitgitgadget@gmail.com","threadId":"54916","inReplyTo":"pull.830.v3.git.1610136177.gitgitgadget@gmail.com","subject":"[PATCH v3 06/14] update-index: use istate->cache_changed","fromName":"Derrick Stolee via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-01-08T20:02:49Z","receivedAt":"2021-01-08T20:04:26Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"From: Derrick Stolee <dstolee@microsoft.com>\n\nThis is a mechanical replacement of active_cache_changed.\n\nSigned-off-by: Derrick Stolee <dstolee@microsoft.com>\n---\n builtin/update-index.c | 10 +++++-----\n 1 file changed, 5 insertions(+), 5 deletions(-)\n\ndiff --git a/builtin/update-index.c b/builtin/update-index.c\nindex 2b03b29261b..70ca47e712c 100644\n--- a/builtin/update-index.c\n+++ b/builtin/update-index.c\n@@ -241,7 +241,7 @@ static int mark_ce_flags(const char *path, int flag, int mark)\n \t\t\tistate->cache[pos]->ce_flags &= ~flag;\n \t\tistate->cache[pos]->ce_flags |= CE_UPDATE_IN_BASE;\n \t\tcache_tree_invalidate_path(istate, path);\n-\t\tactive_cache_changed |= CE_ENTRY_CHANGED;\n+\t\tistate->cache_changed |= CE_ENTRY_CHANGED;\n \t\treturn 0;\n \t}\n \treturn -1;\n@@ -915,7 +915,7 @@ static enum parse_opt_result unresolve_callback(\n \t*has_errors = do_unresolve(ctx->argc, ctx->argv,\n \t\t\t\tprefix, prefix ? strlen(prefix) : 0);\n \tif (*has_errors)\n-\t\tactive_cache_changed = 0;\n+\t\trepo->index->cache_changed = 0;\n \n \tctx->argv += ctx->argc - 1;\n \tctx->argc = 1;\n@@ -936,7 +936,7 @@ static enum parse_opt_result reupdate_callback(\n \tsetup_work_tree();\n \t*has_errors = do_reupdate(ctx->argc, ctx->argv, prefix);\n \tif (*has_errors)\n-\t\tactive_cache_changed = 0;\n+\t\trepo->index->cache_changed = 0;\n \n \tctx->argv += ctx->argc - 1;\n \tctx->argc = 1;\n@@ -1135,7 +1135,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \t\t\t    INDEX_FORMAT_LB, INDEX_FORMAT_UB);\n \n \t\tif (repo->index->version != preferred_index_format)\n-\t\t\tactive_cache_changed |= SOMETHING_CHANGED;\n+\t\t\trepo->index->cache_changed |= SOMETHING_CHANGED;\n \t\trepo->index->version = preferred_index_format;\n \t}\n \n@@ -1223,7 +1223,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \t\treport(_(\"fsmonitor disabled\"));\n \t}\n \n-\tif (active_cache_changed || force_write) {\n+\tif (repo->index->cache_changed || force_write) {\n \t\tif (newfd < 0) {\n \t\t\tif (refresh_args.flags & REFRESH_QUIET)\n \t\t\t\texit(128);\n-- \ngitgitgadget\n\n"},{"id":"413883","messageId":"efe9fddd0a9a44d6fb04eeb01d2868fe7829f2f6.1610136177.git.gitgitgadget@gmail.com","threadId":"54916","inReplyTo":"pull.830.v3.git.1610136177.gitgitgadget@gmail.com","subject":"[PATCH v3 10/14] update-index: replace several compatibility macros","fromName":"Derrick Stolee via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-01-08T20:02:53Z","receivedAt":"2021-01-08T20:04:28Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"From: Derrick Stolee <dstolee@microsoft.com>\n\nThis is also the last usage of unmerge_cache_entry_at(), so it can be\nremoved from cache.h.\n\nSigned-off-by: Derrick Stolee <dstolee@microsoft.com>\n---\n builtin/update-index.c | 11 ++++++-----\n cache.h                |  1 -\n 2 files changed, 6 insertions(+), 6 deletions(-)\n\ndiff --git a/builtin/update-index.c b/builtin/update-index.c\nindex a1e4ee89056..64feb47c97f 100644\n--- a/builtin/update-index.c\n+++ b/builtin/update-index.c\n@@ -429,7 +429,7 @@ static void chmod_path(char flip, const char *path)\n \tif (pos < 0)\n \t\tgoto fail;\n \tce = istate->cache[pos];\n-\tif (chmod_cache_entry(ce, flip) < 0)\n+\tif (chmod_index_entry(istate, ce, flip) < 0)\n \t\tgoto fail;\n \n \treport(\"chmod %cx '%s'\", flip, path);\n@@ -626,7 +626,7 @@ static int unresolve_one(const char *path)\n \tpos = index_name_pos(repo->index, path, namelen);\n \tif (0 <= pos) {\n \t\t/* already merged */\n-\t\tpos = unmerge_cache_entry_at(pos);\n+\t\tpos = unmerge_index_entry_at(repo->index, pos);\n \t\tif (pos < repo->index->cache_nr) {\n \t\t\tconst struct cache_entry *ce = repo->index->cache[pos];\n \t\t\tif (ce_stage(ce) &&\n@@ -777,8 +777,9 @@ struct refresh_params {\n static int refresh(struct refresh_params *o, unsigned int flag)\n {\n \tsetup_work_tree();\n-\tread_cache();\n-\t*o->has_errors |= refresh_cache(o->flags | flag);\n+\trepo_read_index(repo);\n+\t*o->has_errors |= refresh_index(repo->index, o->flags | flag,\n+\t\t\t\t\tNULL, NULL, NULL);\n \treturn 0;\n }\n \n@@ -814,7 +815,7 @@ static int resolve_undo_clear_callback(const struct option *opt,\n {\n \tBUG_ON_OPT_NEG(unset);\n \tBUG_ON_OPT_ARG(arg);\n-\tresolve_undo_clear();\n+\tresolve_undo_clear_index(repo->index);\n \treturn 0;\n }\n \ndiff --git a/cache.h b/cache.h\nindex fdf061cac56..8c091be6256 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -421,7 +421,6 @@ extern struct index_state the_index;\n #define cache_dir_exists(name, namelen) index_dir_exists(&the_index, (name), (namelen))\n #define cache_name_is_other(name, namelen) index_name_is_other(&the_index, (name), (namelen))\n #define resolve_undo_clear() resolve_undo_clear_index(&the_index)\n-#define unmerge_cache_entry_at(at) unmerge_index_entry_at(&the_index, at)\n #define unmerge_cache(pathspec) unmerge_index(&the_index, pathspec)\n #define read_blob_data_from_cache(path, sz) read_blob_data_from_index(&the_index, (path), (sz))\n #define hold_locked_index(lock_file, flags) repo_hold_locked_index(the_repository, (lock_file), (flags))\n-- \ngitgitgadget\n\n"},{"id":"413884","messageId":"2eead833fbafdc3cb408532cdcb7e7bd0909d03a.1610136177.git.gitgitgadget@gmail.com","threadId":"54916","inReplyTo":"pull.830.v3.git.1610136177.gitgitgadget@gmail.com","subject":"[PATCH v3 08/14] update-index: use remove_file_from_index()","fromName":"Derrick Stolee via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-01-08T20:02:51Z","receivedAt":"2021-01-08T20:04:29Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"From: Derrick Stolee <dstolee@microsoft.com>\n\nThis is a mechanical replacement of remove_file_from_cache().\n\nSigned-off-by: Derrick Stolee <dstolee@microsoft.com>\n---\n builtin/update-index.c | 10 +++++-----\n 1 file changed, 5 insertions(+), 5 deletions(-)\n\ndiff --git a/builtin/update-index.c b/builtin/update-index.c\nindex a24b1fc90e4..87fbc580032 100644\n--- a/builtin/update-index.c\n+++ b/builtin/update-index.c\n@@ -251,7 +251,7 @@ static int remove_one_path(const char *path)\n {\n \tif (!allow_remove)\n \t\treturn error(\"%s: does not exist and --remove not passed\", path);\n-\tif (remove_file_from_cache(path))\n+\tif (remove_file_from_index(istate, path))\n \t\treturn error(\"%s: cannot remove from the index\", path);\n \treturn 0;\n }\n@@ -385,7 +385,7 @@ static int process_path(const char *path, struct stat *st, int stat_errno)\n \t\t * On the other hand, removing it from index should work\n \t\t */\n \t\tif (!ignore_skip_worktree_entries && allow_remove &&\n-\t\t    remove_file_from_cache(path))\n+\t\t    remove_file_from_index(istate, path))\n \t\t\treturn error(\"%s: cannot remove from the index\", path);\n \t\treturn 0;\n \t}\n@@ -472,7 +472,7 @@ static void update_one(const char *path)\n \t}\n \n \tif (force_remove) {\n-\t\tif (remove_file_from_cache(path))\n+\t\tif (remove_file_from_index(istate, path))\n \t\t\tdie(\"git update-index: unable to remove %s\", path);\n \t\treport(\"remove '%s'\", path);\n \t\treturn;\n@@ -555,7 +555,7 @@ static void read_index_info(int nul_term_line)\n \n \t\tif (!mode) {\n \t\t\t/* mode == 0 means there is no such path -- remove */\n-\t\t\tif (remove_file_from_cache(path_name))\n+\t\t\tif (remove_file_from_index(istate, path_name))\n \t\t\t\tdie(\"git update-index: unable to remove %s\",\n \t\t\t\t    ptr);\n \t\t}\n@@ -671,7 +671,7 @@ static int unresolve_one(const char *path)\n \t\tgoto free_return;\n \t}\n \n-\tremove_file_from_cache(path);\n+\tremove_file_from_index(repo->index, path);\n \tif (add_cache_entry(ce_2, ADD_CACHE_OK_TO_ADD)) {\n \t\terror(\"%s: cannot add our version to the index.\", path);\n \t\tret = -1;\n-- \ngitgitgadget\n\n"},{"id":"413885","messageId":"a9185af4740d7b7fe2325604045ca8b6df0a52c0.1610136177.git.gitgitgadget@gmail.com","threadId":"54916","inReplyTo":"pull.830.v3.git.1610136177.gitgitgadget@gmail.com","subject":"[PATCH v3 13/14] update-index: reduce static globals, part 2","fromName":"Derrick Stolee via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-01-08T20:02:56Z","receivedAt":"2021-01-08T20:04:51Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"From: Derrick Stolee <dstolee@microsoft.com>\n\nIn order to remove index compatibility macros cleanly, we relied upon\nstatic globals 'repo' and 'istate' to be pointers to the_repository and\nthe_index, respectively. We can continue reducing the need for these\nstatic globals by modifying method prototypes to use them when\nnecessary.\n\nMove the remaining 'struct repository *repo' further down the file and\nuse method parameters to pass it around instead.\n\nThe only remaining change is to remove the static global entirely, but\nthat requires updating the parse-opt callbacks, which need a different\nsolution.\n\nSigned-off-by: Derrick Stolee <dstolee@microsoft.com>\n---\n builtin/update-index.c | 29 +++++++++++++++++------------\n 1 file changed, 17 insertions(+), 12 deletions(-)\n\ndiff --git a/builtin/update-index.c b/builtin/update-index.c\nindex 9a83603c0db..3e01d62865f 100644\n--- a/builtin/update-index.c\n+++ b/builtin/update-index.c\n@@ -593,9 +593,9 @@ static const char * const update_index_usage[] = {\n \n static struct object_id head_oid;\n static struct object_id merge_head_oid;\n-static struct repository *repo;\n \n-static struct cache_entry *read_one_ent(const char *which,\n+static struct cache_entry *read_one_ent(struct repository *repo,\n+\t\t\t\t\tconst char *which,\n \t\t\t\t\tstruct object_id *ent, const char *path,\n \t\t\t\t\tint namelen, int stage)\n {\n@@ -623,7 +623,8 @@ static struct cache_entry *read_one_ent(const char *which,\n \treturn ce;\n }\n \n-static int unresolve_one(const char *path)\n+static int unresolve_one(struct repository *repo,\n+\t\t\t const char *path)\n {\n \tint namelen = strlen(path);\n \tint pos;\n@@ -665,8 +666,8 @@ static int unresolve_one(const char *path)\n \t * stuff HEAD version in stage #2,\n \t * stuff MERGE_HEAD version in stage #3.\n \t */\n-\tce_2 = read_one_ent(\"our\", &head_oid, path, namelen, 2);\n-\tce_3 = read_one_ent(\"their\", &merge_head_oid, path, namelen, 3);\n+\tce_2 = read_one_ent(repo, \"our\", &head_oid, path, namelen, 2);\n+\tce_3 = read_one_ent(repo, \"their\", &merge_head_oid, path, namelen, 3);\n \n \tif (!ce_2 || !ce_3) {\n \t\tret = -1;\n@@ -705,7 +706,8 @@ static void read_head_pointers(void)\n \t}\n }\n \n-static int do_unresolve(int ac, const char **av,\n+static int do_unresolve(struct repository *repo,\n+\t\t\tint ac, const char **av,\n \t\t\tconst char *prefix, int prefix_length)\n {\n \tint i;\n@@ -719,13 +721,14 @@ static int do_unresolve(int ac, const char **av,\n \tfor (i = 1; i < ac; i++) {\n \t\tconst char *arg = av[i];\n \t\tchar *p = prefix_path(prefix, prefix_length, arg);\n-\t\terr |= unresolve_one(p);\n+\t\terr |= unresolve_one(repo, p);\n \t\tfree(p);\n \t}\n \treturn err;\n }\n \n-static int do_reupdate(int ac, const char **av,\n+static int do_reupdate(struct repository *repo,\n+\t\t       int ac, const char **av,\n \t\t       const char *prefix)\n {\n \t/* Read HEAD and run update-index on paths that are\n@@ -754,7 +757,7 @@ static int do_reupdate(int ac, const char **av,\n \t\tif (ce_stage(ce) || !ce_path_match(repo->index, ce, &pathspec, NULL))\n \t\t\tcontinue;\n \t\tif (has_head)\n-\t\t\told = read_one_ent(NULL, &head_oid,\n+\t\t\told = read_one_ent(repo, NULL, &head_oid,\n \t\t\t\t\t   ce->name, ce_namelen(ce), 0);\n \t\tif (old && ce->ce_mode == old->ce_mode &&\n \t\t    oideq(&ce->oid, &old->oid)) {\n@@ -782,6 +785,8 @@ struct refresh_params {\n \tint *has_errors;\n };\n \n+static struct repository *repo;\n+\n static int refresh(struct refresh_params *o, unsigned int flag)\n {\n \tsetup_work_tree();\n@@ -921,8 +926,8 @@ static enum parse_opt_result unresolve_callback(\n \tBUG_ON_OPT_ARG(arg);\n \n \t/* consume remaining arguments. */\n-\t*has_errors = do_unresolve(ctx->argc, ctx->argv,\n-\t\t\t\tprefix, prefix ? strlen(prefix) : 0);\n+\t*has_errors = do_unresolve(repo, ctx->argc, ctx->argv,\n+\t\t\t\t   prefix, prefix ? strlen(prefix) : 0);\n \tif (*has_errors)\n \t\trepo->index->cache_changed = 0;\n \n@@ -943,7 +948,7 @@ static enum parse_opt_result reupdate_callback(\n \n \t/* consume remaining arguments. */\n \tsetup_work_tree();\n-\t*has_errors = do_reupdate(ctx->argc, ctx->argv, prefix);\n+\t*has_errors = do_reupdate(repo, ctx->argc, ctx->argv, prefix);\n \tif (*has_errors)\n \t\trepo->index->cache_changed = 0;\n \n-- \ngitgitgadget\n\n"},{"id":"413886","messageId":"414ef816845b6e08dd0e3d9316f8ba3b9ae7d996.1610136177.git.gitgitgadget@gmail.com","threadId":"54916","inReplyTo":"pull.830.v3.git.1610136177.gitgitgadget@gmail.com","subject":"[PATCH v3 14/14] update-index: remove static globals from callbacks","fromName":"Derrick Stolee via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-01-08T20:02:57Z","receivedAt":"2021-01-08T20:05:20Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"From: Derrick Stolee <dstolee@microsoft.com>\n\nIn order to remove index compatibility macros cleanly, we relied upon\nstatic globals 'repo' and 'istate' to be pointers to the_repository and\nthe_index, respectively. We remove these static globals inside the\noption parsing callbacks, which are the final uses in update-index.\n\nThe callbacks cannot change their method signature, so we must use the\nvalue member of 'struct option', assigned in the array of option macros.\nThere are several callback methods that require at least one of 'repo'\nand 'istate', but they use a variety of different data types for the\ncallback value.\n\nUnify these callback methods to use a consistent 'struct callback_data'\nthat contains a 'repo' member, ready to use. This takes the place of\nthe previous 'struct refresh_params' which served only to group the\n'flags' and 'has_errors' ints. We also collect other one-off settings,\nbut only those that require access to the index or repository in their\noperation.\n\nSigned-off-by: Derrick Stolee <dstolee@microsoft.com>\n---\n builtin/update-index.c | 104 ++++++++++++++++++++++-------------------\n 1 file changed, 56 insertions(+), 48 deletions(-)\n\ndiff --git a/builtin/update-index.c b/builtin/update-index.c\nindex 3e01d62865f..2c67a870cdc 100644\n--- a/builtin/update-index.c\n+++ b/builtin/update-index.c\n@@ -780,18 +780,20 @@ static int do_reupdate(struct repository *repo,\n \treturn 0;\n }\n \n-struct refresh_params {\n+struct callback_data {\n+\tstruct repository *repo;\n+\n \tunsigned int flags;\n-\tint *has_errors;\n+\tunsigned int has_errors;\n+\tunsigned nul_term_line;\n+\tunsigned read_from_stdin;\n };\n \n-static struct repository *repo;\n-\n-static int refresh(struct refresh_params *o, unsigned int flag)\n+static int refresh(struct callback_data *cd, unsigned int flag)\n {\n \tsetup_work_tree();\n-\trepo_read_index(repo);\n-\t*o->has_errors |= refresh_index(repo->index, o->flags | flag,\n+\trepo_read_index(cd->repo);\n+\tcd->has_errors |= refresh_index(cd->repo->index, cd->flags | flag,\n \t\t\t\t\tNULL, NULL, NULL);\n \treturn 0;\n }\n@@ -813,7 +815,7 @@ static int really_refresh_callback(const struct option *opt,\n }\n \n static int chmod_callback(const struct option *opt,\n-\t\t\t\tconst char *arg, int unset)\n+\t\t\t  const char *arg, int unset)\n {\n \tchar *flip = opt->value;\n \tBUG_ON_OPT_NEG(unset);\n@@ -824,11 +826,12 @@ static int chmod_callback(const struct option *opt,\n }\n \n static int resolve_undo_clear_callback(const struct option *opt,\n-\t\t\t\tconst char *arg, int unset)\n+\t\t\t\t       const char *arg, int unset)\n {\n+\tstruct callback_data *cd = opt->value;\n \tBUG_ON_OPT_NEG(unset);\n \tBUG_ON_OPT_ARG(arg);\n-\tresolve_undo_clear_index(repo->index);\n+\tresolve_undo_clear_index(cd->repo->index);\n \treturn 0;\n }\n \n@@ -863,12 +866,13 @@ static enum parse_opt_result cacheinfo_callback(\n \tstruct object_id oid;\n \tunsigned int mode;\n \tconst char *path;\n+\tstruct callback_data *cd = opt->value;\n \n \tBUG_ON_OPT_NEG(unset);\n \tBUG_ON_OPT_ARG(arg);\n \n \tif (!parse_new_style_cacheinfo(ctx->argv[1], &mode, &oid, &path)) {\n-\t\tif (add_cacheinfo(repo->index, mode, &oid, path, 0))\n+\t\tif (add_cacheinfo(cd->repo->index, mode, &oid, path, 0))\n \t\t\tdie(\"git update-index: --cacheinfo cannot add %s\", path);\n \t\tctx->argv++;\n \t\tctx->argc--;\n@@ -878,7 +882,7 @@ static enum parse_opt_result cacheinfo_callback(\n \t\treturn error(\"option 'cacheinfo' expects <mode>,<sha1>,<path>\");\n \tif (strtoul_ui(*++ctx->argv, 8, &mode) ||\n \t    get_oid_hex(*++ctx->argv, &oid) ||\n-\t    add_cacheinfo(repo->index, mode, &oid, *++ctx->argv, 0))\n+\t    add_cacheinfo(cd->repo->index, mode, &oid, *++ctx->argv, 0))\n \t\tdie(\"git update-index: --cacheinfo cannot add %s\", *ctx->argv);\n \tctx->argc -= 3;\n \treturn 0;\n@@ -888,7 +892,7 @@ static enum parse_opt_result stdin_cacheinfo_callback(\n \tstruct parse_opt_ctx_t *ctx, const struct option *opt,\n \tconst char *arg, int unset)\n {\n-\tint *nul_term_line = opt->value;\n+\tstruct callback_data *cd = opt->value;\n \n \tBUG_ON_OPT_NEG(unset);\n \tBUG_ON_OPT_ARG(arg);\n@@ -896,7 +900,7 @@ static enum parse_opt_result stdin_cacheinfo_callback(\n \tif (ctx->argc != 1)\n \t\treturn error(\"option '%s' must be the last argument\", opt->long_name);\n \tallow_add = allow_replace = allow_remove = 1;\n-\tread_index_info(repo->index, *nul_term_line);\n+\tread_index_info(cd->repo->index, cd->nul_term_line);\n \treturn 0;\n }\n \n@@ -904,14 +908,14 @@ static enum parse_opt_result stdin_callback(\n \tstruct parse_opt_ctx_t *ctx, const struct option *opt,\n \tconst char *arg, int unset)\n {\n-\tint *read_from_stdin = opt->value;\n+\tstruct callback_data *cd = opt->value;\n \n \tBUG_ON_OPT_NEG(unset);\n \tBUG_ON_OPT_ARG(arg);\n \n \tif (ctx->argc != 1)\n \t\treturn error(\"option '%s' must be the last argument\", opt->long_name);\n-\t*read_from_stdin = 1;\n+\tcd->read_from_stdin = 1;\n \treturn 0;\n }\n \n@@ -919,17 +923,17 @@ static enum parse_opt_result unresolve_callback(\n \tstruct parse_opt_ctx_t *ctx, const struct option *opt,\n \tconst char *arg, int unset)\n {\n-\tint *has_errors = opt->value;\n \tconst char *prefix = startup_info->prefix;\n+\tstruct callback_data *cd = opt->value;\n \n \tBUG_ON_OPT_NEG(unset);\n \tBUG_ON_OPT_ARG(arg);\n \n \t/* consume remaining arguments. */\n-\t*has_errors = do_unresolve(repo, ctx->argc, ctx->argv,\n-\t\t\t\t   prefix, prefix ? strlen(prefix) : 0);\n-\tif (*has_errors)\n-\t\trepo->index->cache_changed = 0;\n+\tcd->has_errors = do_unresolve(cd->repo, ctx->argc, ctx->argv,\n+\t\t\t\t      prefix, prefix ? strlen(prefix) : 0);\n+\tif (cd->has_errors)\n+\t\tcd->repo->index->cache_changed = 0;\n \n \tctx->argv += ctx->argc - 1;\n \tctx->argc = 1;\n@@ -940,17 +944,17 @@ static enum parse_opt_result reupdate_callback(\n \tstruct parse_opt_ctx_t *ctx, const struct option *opt,\n \tconst char *arg, int unset)\n {\n-\tint *has_errors = opt->value;\n \tconst char *prefix = startup_info->prefix;\n+\tstruct callback_data *cd = opt->value;\n \n \tBUG_ON_OPT_NEG(unset);\n \tBUG_ON_OPT_ARG(arg);\n \n \t/* consume remaining arguments. */\n \tsetup_work_tree();\n-\t*has_errors = do_reupdate(repo, ctx->argc, ctx->argv, prefix);\n-\tif (*has_errors)\n-\t\trepo->index->cache_changed = 0;\n+\tcd->has_errors = do_reupdate(cd->repo, ctx->argc, ctx->argv, prefix);\n+\tif (cd->has_errors)\n+\t\tcd->repo->index->cache_changed = 0;\n \n \tctx->argv += ctx->argc - 1;\n \tctx->argc = 1;\n@@ -959,13 +963,13 @@ static enum parse_opt_result reupdate_callback(\n \n int cmd_update_index(int argc, const char **argv, const char *prefix)\n {\n-\tint newfd, entries, has_errors = 0, nul_term_line = 0;\n+\tstruct repository *repo = the_repository;\n+\tstruct callback_data cd;\n+\tint newfd, entries;\n \tenum uc_mode untracked_cache = UC_UNSPECIFIED;\n-\tint read_from_stdin = 0;\n \tint prefix_length = prefix ? strlen(prefix) : 0;\n \tint preferred_index_format = 0;\n \tchar set_executable_bit = 0;\n-\tstruct refresh_params refresh_args = {0, &has_errors};\n \tint lock_error = 0;\n \tint split_index = -1;\n \tint force_write = 0;\n@@ -974,11 +978,12 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \tstruct parse_opt_ctx_t ctx;\n \tstrbuf_getline_fn getline_fn;\n \tint parseopt_state = PARSE_OPT_UNKNOWN;\n+\n \tstruct option options[] = {\n-\t\tOPT_BIT('q', NULL, &refresh_args.flags,\n+\t\tOPT_BIT('q', NULL, &cd.flags,\n \t\t\tN_(\"continue refresh even when index needs update\"),\n \t\t\tREFRESH_QUIET),\n-\t\tOPT_BIT(0, \"ignore-submodules\", &refresh_args.flags,\n+\t\tOPT_BIT(0, \"ignore-submodules\", &cd.flags,\n \t\t\tN_(\"refresh: ignore submodules\"),\n \t\t\tREFRESH_IGNORE_SUBMODULES),\n \t\tOPT_SET_INT(0, \"add\", &allow_add,\n@@ -987,18 +992,18 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \t\t\tN_(\"let files replace directories and vice-versa\"), 1),\n \t\tOPT_SET_INT(0, \"remove\", &allow_remove,\n \t\t\tN_(\"notice files missing from worktree\"), 1),\n-\t\tOPT_BIT(0, \"unmerged\", &refresh_args.flags,\n+\t\tOPT_BIT(0, \"unmerged\", &cd.flags,\n \t\t\tN_(\"refresh even if index contains unmerged entries\"),\n \t\t\tREFRESH_UNMERGED),\n-\t\tOPT_CALLBACK_F(0, \"refresh\", &refresh_args, NULL,\n+\t\tOPT_CALLBACK_F(0, \"refresh\", &cd, NULL,\n \t\t\tN_(\"refresh stat information\"),\n \t\t\tPARSE_OPT_NOARG | PARSE_OPT_NONEG,\n \t\t\trefresh_callback),\n-\t\tOPT_CALLBACK_F(0, \"really-refresh\", &refresh_args, NULL,\n+\t\tOPT_CALLBACK_F(0, \"really-refresh\", &cd, NULL,\n \t\t\tN_(\"like --refresh, but ignore assume-unchanged setting\"),\n \t\t\tPARSE_OPT_NOARG | PARSE_OPT_NONEG,\n \t\t\treally_refresh_callback),\n-\t\t{OPTION_LOWLEVEL_CALLBACK, 0, \"cacheinfo\", NULL,\n+\t\t{OPTION_LOWLEVEL_CALLBACK, 0, \"cacheinfo\", &cd,\n \t\t\tN_(\"<mode>,<object>,<path>\"),\n \t\t\tN_(\"add the specified entry to the index\"),\n \t\t\tPARSE_OPT_NOARG | /* disallow --cacheinfo=<mode> form */\n@@ -1027,30 +1032,30 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \t\t\tN_(\"add to index only; do not add content to object database\"), 1),\n \t\tOPT_SET_INT(0, \"force-remove\", &force_remove,\n \t\t\tN_(\"remove named paths even if present in worktree\"), 1),\n-\t\tOPT_BOOL('z', NULL, &nul_term_line,\n+\t\tOPT_BOOL('z', NULL, &cd.nul_term_line,\n \t\t\t N_(\"with --stdin: input lines are terminated by null bytes\")),\n-\t\t{OPTION_LOWLEVEL_CALLBACK, 0, \"stdin\", &read_from_stdin, NULL,\n+\t\t{OPTION_LOWLEVEL_CALLBACK, 0, \"stdin\", &cd, NULL,\n \t\t\tN_(\"read list of paths to be updated from standard input\"),\n \t\t\tPARSE_OPT_NONEG | PARSE_OPT_NOARG,\n \t\t\tNULL, 0, stdin_callback},\n-\t\t{OPTION_LOWLEVEL_CALLBACK, 0, \"index-info\", &nul_term_line, NULL,\n+\t\t{OPTION_LOWLEVEL_CALLBACK, 0, \"index-info\", &cd, NULL,\n \t\t\tN_(\"add entries from standard input to the index\"),\n \t\t\tPARSE_OPT_NONEG | PARSE_OPT_NOARG,\n \t\t\tNULL, 0, stdin_cacheinfo_callback},\n-\t\t{OPTION_LOWLEVEL_CALLBACK, 0, \"unresolve\", &has_errors, NULL,\n+\t\t{OPTION_LOWLEVEL_CALLBACK, 0, \"unresolve\", &cd, NULL,\n \t\t\tN_(\"repopulate stages #2 and #3 for the listed paths\"),\n \t\t\tPARSE_OPT_NONEG | PARSE_OPT_NOARG,\n \t\t\tNULL, 0, unresolve_callback},\n-\t\t{OPTION_LOWLEVEL_CALLBACK, 'g', \"again\", &has_errors, NULL,\n+\t\t{OPTION_LOWLEVEL_CALLBACK, 'g', \"again\", &cd, NULL,\n \t\t\tN_(\"only update entries that differ from HEAD\"),\n \t\t\tPARSE_OPT_NONEG | PARSE_OPT_NOARG,\n \t\t\tNULL, 0, reupdate_callback},\n-\t\tOPT_BIT(0, \"ignore-missing\", &refresh_args.flags,\n+\t\tOPT_BIT(0, \"ignore-missing\", &cd.flags,\n \t\t\tN_(\"ignore files missing from worktree\"),\n \t\t\tREFRESH_IGNORE_MISSING),\n \t\tOPT_SET_INT(0, \"verbose\", &verbose,\n \t\t\tN_(\"report actions to standard output\"), 1),\n-\t\tOPT_CALLBACK_F(0, \"clear-resolve-undo\", NULL, NULL,\n+\t\tOPT_CALLBACK_F(0, \"clear-resolve-undo\", &cd, NULL,\n \t\t\tN_(\"(for porcelains) forget saved unresolved conflicts\"),\n \t\t\tPARSE_OPT_NOARG | PARSE_OPT_NONEG,\n \t\t\tresolve_undo_clear_callback),\n@@ -1082,8 +1087,6 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \n \tgit_config(git_default_config, NULL);\n \n-\trepo = the_repository;\n-\n \t/* we will diagnose later if it turns out that we need to update it */\n \tnewfd = repo_hold_locked_index(repo, &lock_file, 0);\n \tif (newfd < 0)\n@@ -1094,6 +1097,11 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \t\tdie(\"cache corrupted\");\n \n \trepo->index->updated_skipworktree = 1;\n+\tcd.repo = repo;\n+\tcd.flags = 0;\n+\tcd.has_errors = 0;\n+\tcd.nul_term_line = 0;\n+\tcd.read_from_stdin = 0;\n \n \t/*\n \t * Custom copy of parse_options() because we want to handle\n@@ -1139,7 +1147,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \t}\n \targc = parse_options_end(&ctx);\n \n-\tgetline_fn = nul_term_line ? strbuf_getline_nul : strbuf_getline_lf;\n+\tgetline_fn = cd.nul_term_line ? strbuf_getline_nul : strbuf_getline_lf;\n \tif (preferred_index_format) {\n \t\tif (preferred_index_format < INDEX_FORMAT_LB ||\n \t\t    INDEX_FORMAT_UB < preferred_index_format)\n@@ -1152,14 +1160,14 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \t\trepo->index->version = preferred_index_format;\n \t}\n \n-\tif (read_from_stdin) {\n+\tif (cd.read_from_stdin) {\n \t\tstruct strbuf buf = STRBUF_INIT;\n \t\tstruct strbuf unquoted = STRBUF_INIT;\n \n \t\tsetup_work_tree();\n \t\twhile (getline_fn(&buf, stdin) != EOF) {\n \t\t\tchar *p;\n-\t\t\tif (!nul_term_line && buf.buf[0] == '\"') {\n+\t\t\tif (!cd.nul_term_line && buf.buf[0] == '\"') {\n \t\t\t\tstrbuf_reset(&unquoted);\n \t\t\t\tif (unquote_c_style(&unquoted, buf.buf, NULL))\n \t\t\t\t\tdie(\"line is badly quoted\");\n@@ -1238,7 +1246,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \n \tif (repo->index->cache_changed || force_write) {\n \t\tif (newfd < 0) {\n-\t\t\tif (refresh_args.flags & REFRESH_QUIET)\n+\t\t\tif (cd.flags & REFRESH_QUIET)\n \t\t\t\texit(128);\n \t\t\tunable_to_lock_die(get_index_file(), lock_error);\n \t\t}\n@@ -1248,5 +1256,5 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \n \trollback_lock_file(&lock_file);\n \n-\treturn has_errors ? 1 : 0;\n+\treturn cd.has_errors ? 1 : 0;\n }\n-- \ngitgitgadget\n"},{"id":"413955","messageId":"xmqq1retclzr.fsf@gitster.c.googlers.com","threadId":"54916","inReplyTo":"pull.830.v3.git.1610136177.gitgitgadget@gmail.com","subject":"Re: [PATCH v3 00/14] Remove more index compatibility macros","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2021-01-10T07:03:04Z","receivedAt":"2021-01-10T07:04:10Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Derrick Stolee via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n\n> UPDATE: this is now based on ag/merge-strategies-in-c to avoid conflicts in\n> 'seen'. The changes in builtin/rm.c still conflict with\n> mt/rm-sparse-checkout, but that branch seems to be waiting for a clearer\n> plan on some corner cases. I thought about ejecting it, but 'rm' still uses\n> ce_match_stat(), so just dropping the patch gives less of a final stake at\n> the end of the series. (I'm still open to it, if necessary.)\n\nI haven't read this latest iteration myself yet beyond the cover\nletter, but tonight's 'seen' has this queued near its tip.  I expect\nit would either stay there or occasionally ejected, until the base\ntopic solidifies a bit more.\n\n>  * Methods that know about the 'repo' pointer no longer also have an\n>    'istate' pointer and instead prefer 'repo->index'\n>\n>  * This includes the callback_data struct which only has a 'repo' member, no\n>    'istate'.\n\nOK.\n"},{"id":"413958","messageId":"CAPig+cQnZbKRu+iSGDzhMsG6bgEL1NbAu15DR3dNXM-Nfc9w8A@mail.gmail.com","threadId":"54916","inReplyTo":"xmqq1retclzr.fsf@gitster.c.googlers.com","subject":"Re: [PATCH v3 00/14] Remove more index compatibility macros","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2021-01-10T07:32:00Z","receivedAt":"2021-01-10T07:33:09Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Sun, Jan 10, 2021 at 2:03 AM Junio C Hamano <gitster@pobox.com> wrote:\n> \"Derrick Stolee via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n> > UPDATE: this is now based on ag/merge-strategies-in-c to avoid conflicts in\n> > 'seen'. The changes in builtin/rm.c still conflict with\n> > mt/rm-sparse-checkout, but that branch seems to be waiting for a clearer\n> > plan on some corner cases. I thought about ejecting it, but 'rm' still uses\n> > ce_match_stat(), so just dropping the patch gives less of a final stake at\n> > the end of the series. (I'm still open to it, if necessary.)\n>\n> I haven't read this latest iteration myself yet beyond the cover\n> letter, but tonight's 'seen' has this queued near its tip.  I expect\n> it would either stay there or occasionally ejected, until the base\n> topic solidifies a bit more.\n>\n> >  * Methods that know about the 'repo' pointer no longer also have an\n> >    'istate' pointer and instead prefer 'repo->index'\n> >\n> >  * This includes the callback_data struct which only has a 'repo' member, no\n> >    'istate'.\n>\n> OK.\n\nI looked this version of the series over and did not find anything\nelse about which to comment.\n"},{"id":"413960","messageId":"1c428df5-849d-7e30-76b7-498bdd827f5e@gmail.com","threadId":"54916","inReplyTo":"xmqq1retclzr.fsf@gitster.c.googlers.com","subject":"Re: [PATCH v3 00/14] Remove more index compatibility macros","fromName":"Derrick Stolee","fromEmail":"stolee@gmail.com","sentAt":"2021-01-10T11:57:05Z","receivedAt":"2021-01-10T11:58:12Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"On 1/10/2021 2:03 AM, Junio C Hamano wrote:\n> \"Derrick Stolee via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n> \n>> UPDATE: this is now based on ag/merge-strategies-in-c to avoid conflicts in\n>> 'seen'. The changes in builtin/rm.c still conflict with\n>> mt/rm-sparse-checkout, but that branch seems to be waiting for a clearer\n>> plan on some corner cases. I thought about ejecting it, but 'rm' still uses\n>> ce_match_stat(), so just dropping the patch gives less of a final stake at\n>> the end of the series. (I'm still open to it, if necessary.)\n> \n> I haven't read this latest iteration myself yet beyond the cover\n> letter, but tonight's 'seen' has this queued near its tip.  I expect\n> it would either stay there or occasionally ejected, until the base\n> topic solidifies a bit more.\n\nThanks. I'll continue to watch that topic and provide review as\nnew versions come out.\n\n-Stolee\n\n"},{"id":"415325","messageId":"a6906459-3a93-ecad-c460-b6c763819389@gmail.com","threadId":"54916","inReplyTo":"xmqq1retclzr.fsf@gitster.c.googlers.com","subject":"Re: [PATCH v3 00/14] Remove more index compatibility macros","fromName":"Derrick Stolee","fromEmail":"stolee@gmail.com","sentAt":"2021-01-25T13:04:11Z","receivedAt":"2021-01-26T20:54:08Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"On 1/10/2021 2:03 AM, Junio C Hamano wrote:\n> \"Derrick Stolee via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n> \n>> UPDATE: this is now based on ag/merge-strategies-in-c to avoid conflicts in\n>> 'seen'. The changes in builtin/rm.c still conflict with\n>> mt/rm-sparse-checkout, but that branch seems to be waiting for a clearer\n>> plan on some corner cases. I thought about ejecting it, but 'rm' still uses\n>> ce_match_stat(), so just dropping the patch gives less of a final stake at\n>> the end of the series. (I'm still open to it, if necessary.)\n> \n> I haven't read this latest iteration myself yet beyond the cover\n> letter, but tonight's 'seen' has this queued near its tip.  I expect\n> it would either stay there or occasionally ejected, until the base\n> topic solidifies a bit more.\n\nJunio,\n\nPlease drop this series for now. I'll be introducing a new series soon\nthat will collide with it and this is a lower priority.\n\nI'll probably come back to revisit removing these macros, but I'll do\nso one builtin at a time when others are not modifying them at the\nsame time.\n\nThanks,\n-Stolee\n"}]}