{"thread":{"id":"41196","subject":"[PATCH v5 00/11] Untracked cache improvements","startedAt":"2016-01-15T06:59:41Z","lastAt":"2016-01-20T10:12:56Z","messageCount":20,"participants":["Christian Couder","Junio C Hamano","Torsten Bögershausen"],"isPatch":true,"patchVersion":5,"patchTotal":11},"messages":[{"id":"276128","messageId":"1452841192-620-1-git-send-email-chriscool@tuxfamily.org","threadId":"41196","inReplyTo":null,"subject":"[PATCH v5 00/11] Untracked cache improvements","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-01-15T06:59:41Z","receivedAt":"2016-01-15T06:59:41Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Here is a new version of a patch series to improve the untracked cache\nfeature.\n\nThis v5 implements core.untrackedCache as a tristate config\nvariable. When it's `true`, Git commands, especially `git status`,\nshould always add the untracked cache and use it, and when `false`,\nGit commands should remove it. The default is `keep` in which case the\nuntracked cache is neither removed nor added, and used if it is there.\n\nPatch 1/11 is a small bugfix that has not changed.\n\nPatch 2/11 to 4/11 add some small features that are missing. There are\nno changes compared to v4.\n\nPatchs 5/11 to 7/11 are some refactoring to prepare for the following\npatchs. The interface of the new functions has changed as they are now\npassed a \"struct index_state *istate\" parameter on which they will\noperate instead of modifying \"the_index\".\n\nPatch 8/11 deals with the \"ident\" field in \"struct\nuntracked_cache\". Following Torsten and Junio's suggestions, the\ndifferences compared to v4 are the following:\n\n\t- we store only the kernel \"sysname\" and not the full kernel version,\n\t- we match the full \"ident\" string instead of just the beginning of the string,\n\t- a warning has been improved.\n\nPatch 9/11 adds core.untrackedCache. Following Junio's suggestions, it\nhas been changed compared to v4 in the following ways:\n\n  - we don't die() and we exit 0, if \"git update-index\n  --[no-|force-]untracked-cache\" is used in a way that goes against\n  the value of core.untrackedCache,\n\n  - we add or remove the untracked cache in read_index_from() instead\n    of wt_status_collect_untracked().\n\nPatch 10/11 is a new hack that is needed to have\ntest-dump-untracked-cache work like it used to, now that we add or\nremove the untracked cache in read_index_from(). Because\ntest-dump-untracked-cache indirectly calls read_index_from(), we have\nto prevent it from addind or removing the untracked cache.\n\nPatch 11/11, which contains tests, has been changed to reflect changes\nin 9/11.\n\nSo the changes compared to v4 are mostly small updates, and patchs\n8/11, 9/11 and 10/11.\n\nThe patch series is also available there:\n\nhttps://github.com/chriscool/git/tree/uc-notifs63\n\nThanks to the reviewers and helpers.\n\n\nChristian Couder (11):\n  dir: free untracked cache when removing it\n  update-index: use enum for untracked cache options\n  update-index: add --test-untracked-cache\n  update-index: add untracked cache notifications\n  update-index: move 'uc' var declaration\n  dir: add {new,add}_untracked_cache()\n  dir: add remove_untracked_cache()\n  dir: simplify untracked cache \"ident\" field\n  config: add core.untrackedCache\n  test-dump-untracked-cache: don't modify the untracked cache\n  t7063: add tests for core.untrackedCache\n\n Documentation/config.txt               |  9 ++++\n Documentation/git-update-index.txt     | 67 +++++++++++++++++++++----\n builtin/update-index.c                 | 62 ++++++++++++++---------\n cache.h                                |  3 ++\n config.c                               | 23 +++++++++\n contrib/completion/git-completion.bash |  1 +\n dir.c                                  | 62 ++++++++++++++++++-----\n dir.h                                  |  3 +-\n environment.c                          |  6 +++\n read-cache.c                           | 14 ++++++\n t/t7063-status-untracked-cache.sh      | 89 +++++++++++++++++++++++++++++++---\n test-dump-untracked-cache.c            |  2 +\n 12 files changed, 287 insertions(+), 54 deletions(-)\n\n-- \n2.7.0.36.g20612a7\n"},{"id":"276129","messageId":"1452841192-620-2-git-send-email-chriscool@tuxfamily.org","threadId":"41196","inReplyTo":"1452841192-620-1-git-send-email-chriscool@tuxfamily.org","subject":"[PATCH v5 01/11] dir: free untracked cache when removing it","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-01-15T06:59:42Z","receivedAt":"2016-01-15T06:59:42Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/update-index.c | 1 +\n 1 file changed, 1 insertion(+)\n\ndiff --git a/builtin/update-index.c b/builtin/update-index.c\nindex 7431938..a6fff87 100644\n--- a/builtin/update-index.c\n+++ b/builtin/update-index.c\n@@ -1123,6 +1123,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \t\tadd_untracked_ident(the_index.untracked);\n \t\tthe_index.cache_changed |= UNTRACKED_CHANGED;\n \t} else if (!untracked_cache && the_index.untracked) {\n+\t\tfree_untracked_cache(the_index.untracked);\n \t\tthe_index.untracked = NULL;\n \t\tthe_index.cache_changed |= UNTRACKED_CHANGED;\n \t}\n-- \n2.7.0.36.g20612a7\n"},{"id":"276130","messageId":"1452841192-620-3-git-send-email-chriscool@tuxfamily.org","threadId":"41196","inReplyTo":"1452841192-620-1-git-send-email-chriscool@tuxfamily.org","subject":"[PATCH v5 02/11] update-index: use enum for untracked cache options","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-01-15T06:59:43Z","receivedAt":"2016-01-15T06:59:43Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\nHelped-by: Duy Nguyen <pclouds@gmail.com>\n---\n builtin/update-index.c | 18 +++++++++++++-----\n 1 file changed, 13 insertions(+), 5 deletions(-)\n\ndiff --git a/builtin/update-index.c b/builtin/update-index.c\nindex a6fff87..1e546a3 100644\n--- a/builtin/update-index.c\n+++ b/builtin/update-index.c\n@@ -35,6 +35,14 @@ static int mark_skip_worktree_only;\n #define UNMARK_FLAG 2\n static struct strbuf mtime_dir = STRBUF_INIT;\n \n+/* Untracked cache mode */\n+enum uc_mode {\n+\tUC_UNSPECIFIED = -1,\n+\tUC_DISABLE = 0,\n+\tUC_ENABLE,\n+\tUC_FORCE\n+};\n+\n __attribute__((format (printf, 1, 2)))\n static void report(const char *fmt, ...)\n {\n@@ -902,7 +910,7 @@ static int reupdate_callback(struct parse_opt_ctx_t *ctx,\n int cmd_update_index(int argc, const char **argv, const char *prefix)\n {\n \tint newfd, entries, has_errors = 0, line_termination = '\\n';\n-\tint untracked_cache = -1;\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@@ -997,7 +1005,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \t\tOPT_BOOL(0, \"untracked-cache\", &untracked_cache,\n \t\t\tN_(\"enable/disable untracked cache\")),\n \t\tOPT_SET_INT(0, \"force-untracked-cache\", &untracked_cache,\n-\t\t\t    N_(\"enable untracked cache without testing the filesystem\"), 2),\n+\t\t\t    N_(\"enable untracked cache without testing the filesystem\"), UC_FORCE),\n \t\tOPT_END()\n \t};\n \n@@ -1104,10 +1112,10 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \t\tthe_index.split_index = NULL;\n \t\tthe_index.cache_changed |= SOMETHING_CHANGED;\n \t}\n-\tif (untracked_cache > 0) {\n+\tif (untracked_cache > UC_DISABLE) {\n \t\tstruct untracked_cache *uc;\n \n-\t\tif (untracked_cache < 2) {\n+\t\tif (untracked_cache < UC_FORCE) {\n \t\t\tsetup_work_tree();\n \t\t\tif (!test_if_untracked_cache_is_supported())\n \t\t\t\treturn 1;\n@@ -1122,7 +1130,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \t\t}\n \t\tadd_untracked_ident(the_index.untracked);\n \t\tthe_index.cache_changed |= UNTRACKED_CHANGED;\n-\t} else if (!untracked_cache && the_index.untracked) {\n+\t} else if (untracked_cache == UC_DISABLE && the_index.untracked) {\n \t\tfree_untracked_cache(the_index.untracked);\n \t\tthe_index.untracked = NULL;\n \t\tthe_index.cache_changed |= UNTRACKED_CHANGED;\n-- \n2.7.0.36.g20612a7\n"},{"id":"276137","messageId":"1452841192-620-4-git-send-email-chriscool@tuxfamily.org","threadId":"41196","inReplyTo":"1452841192-620-1-git-send-email-chriscool@tuxfamily.org","subject":"[PATCH v5 03/11] update-index: add --test-untracked-cache","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-01-15T06:59:44Z","receivedAt":"2016-01-15T06:59:44Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"It is nice to just be able to test if untracked cache is\nsupported without enabling it.\n\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\nHelped-by: David Turner <dturner@twopensource.com>\n---\n Documentation/git-update-index.txt | 12 +++++++++++-\n builtin/update-index.c             |  5 +++++\n 2 files changed, 16 insertions(+), 1 deletion(-)\n\ndiff --git a/Documentation/git-update-index.txt b/Documentation/git-update-index.txt\nindex f4e5a85..a0afe17 100644\n--- a/Documentation/git-update-index.txt\n+++ b/Documentation/git-update-index.txt\n@@ -18,7 +18,7 @@ SYNOPSIS\n \t     [--[no-]skip-worktree]\n \t     [--ignore-submodules]\n \t     [--[no-]split-index]\n-\t     [--[no-|force-]untracked-cache]\n+\t     [--[no-|test-|force-]untracked-cache]\n \t     [--really-refresh] [--unresolve] [--again | -g]\n \t     [--info-only] [--index-info]\n \t     [-z] [--stdin] [--index-version <n>]\n@@ -180,6 +180,16 @@ may not support it yet.\n \tsystem must change `st_mtime` field of a directory if files\n \tare added or deleted in that directory.\n \n+--test-untracked-cache::\n+\tOnly perform tests on the working directory to make sure\n+\tuntracked cache can be used. You have to manually enable\n+\tuntracked cache using `--force-untracked-cache` (or\n+\t`--untracked-cache` but this will run the tests again)\n+\tafterwards if you really want to use it. If a test fails\n+\tthe exit code is 1 and a message explains what is not\n+\tworking as needed, otherwise the exit code is 0 and OK is\n+\tprinted.\n+\n --force-untracked-cache::\n \tFor safety, `--untracked-cache` performs tests on the working\n \tdirectory to make sure untracked cache can be used. These\ndiff --git a/builtin/update-index.c b/builtin/update-index.c\nindex 1e546a3..62222dd 100644\n--- a/builtin/update-index.c\n+++ b/builtin/update-index.c\n@@ -40,6 +40,7 @@ enum uc_mode {\n \tUC_UNSPECIFIED = -1,\n \tUC_DISABLE = 0,\n \tUC_ENABLE,\n+\tUC_TEST,\n \tUC_FORCE\n };\n \n@@ -1004,6 +1005,8 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \t\t\tN_(\"enable or disable split index\")),\n \t\tOPT_BOOL(0, \"untracked-cache\", &untracked_cache,\n \t\t\tN_(\"enable/disable untracked cache\")),\n+\t\tOPT_SET_INT(0, \"test-untracked-cache\", &untracked_cache,\n+\t\t\t    N_(\"test if the filesystem supports untracked cache\"), UC_TEST),\n \t\tOPT_SET_INT(0, \"force-untracked-cache\", &untracked_cache,\n \t\t\t    N_(\"enable untracked cache without testing the filesystem\"), UC_FORCE),\n \t\tOPT_END()\n@@ -1119,6 +1122,8 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \t\t\tsetup_work_tree();\n \t\t\tif (!test_if_untracked_cache_is_supported())\n \t\t\t\treturn 1;\n+\t\t\tif (untracked_cache == UC_TEST)\n+\t\t\t\treturn 0;\n \t\t}\n \t\tif (!the_index.untracked) {\n \t\t\tuc = xcalloc(1, sizeof(*uc));\n-- \n2.7.0.36.g20612a7\n"},{"id":"276131","messageId":"1452841192-620-5-git-send-email-chriscool@tuxfamily.org","threadId":"41196","inReplyTo":"1452841192-620-1-git-send-email-chriscool@tuxfamily.org","subject":"[PATCH v5 04/11] update-index: add untracked cache notifications","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-01-15T06:59:45Z","receivedAt":"2016-01-15T06:59:45Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Attempting to flip the untracked-cache feature on for a random index\nfile with\n\n    cd /random/unrelated/place\n    git --git-dir=/somewhere/else/.git update-index --untracked-cache\n\nwould not work as you might expect. Because flipping the feature on\nin the index also records the location of the corresponding working\ntree (/random/unrelated/place in the above example), when the index\nis subsequently used to keep track of files in the working tree in\n/somewhere/else, the feature is disabled.\n\nWith this patch \"git update-index --[test-]untracked-cache\" tells the\nuser in which directory tests are performed. This makes it easy to\nspot any problem.\n\nAlso in verbose mode, let's tell the user when the cache is enabled\nor disabled.\n\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\nHelped-by: Duy Nguyen <pclouds@gmail.com>\n---\n builtin/update-index.c | 14 +++++++++-----\n 1 file changed, 9 insertions(+), 5 deletions(-)\n\ndiff --git a/builtin/update-index.c b/builtin/update-index.c\nindex 62222dd..369c207 100644\n--- a/builtin/update-index.c\n+++ b/builtin/update-index.c\n@@ -130,7 +130,7 @@ static int test_if_untracked_cache_is_supported(void)\n \tif (!mkdtemp(mtime_dir.buf))\n \t\tdie_errno(\"Could not make temporary directory\");\n \n-\tfprintf(stderr, _(\"Testing \"));\n+\tfprintf(stderr, _(\"Testing mtime in '%s' \"), xgetcwd());\n \tatexit(remove_test_directory);\n \txstat_mtime_dir(&st);\n \tfill_stat_data(&base, &st);\n@@ -1135,10 +1135,14 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \t\t}\n \t\tadd_untracked_ident(the_index.untracked);\n \t\tthe_index.cache_changed |= UNTRACKED_CHANGED;\n-\t} else if (untracked_cache == UC_DISABLE && the_index.untracked) {\n-\t\tfree_untracked_cache(the_index.untracked);\n-\t\tthe_index.untracked = NULL;\n-\t\tthe_index.cache_changed |= UNTRACKED_CHANGED;\n+\t\treport(_(\"Untracked cache enabled for '%s'\"), get_git_work_tree());\n+\t} else if (untracked_cache == UC_DISABLE) {\n+\t\tif (the_index.untracked) {\n+\t\t\tfree_untracked_cache(the_index.untracked);\n+\t\t\tthe_index.untracked = NULL;\n+\t\t\tthe_index.cache_changed |= UNTRACKED_CHANGED;\n+\t\t}\n+\t\treport(_(\"Untracked cache disabled\"));\n \t}\n \n \tif (active_cache_changed) {\n-- \n2.7.0.36.g20612a7\n"},{"id":"276133","messageId":"1452841192-620-6-git-send-email-chriscool@tuxfamily.org","threadId":"41196","inReplyTo":"1452841192-620-1-git-send-email-chriscool@tuxfamily.org","subject":"[PATCH v5 05/11] update-index: move 'uc' var declaration","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-01-15T06:59:46Z","receivedAt":"2016-01-15T06:59:46Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/update-index.c | 4 +---\n 1 file changed, 1 insertion(+), 3 deletions(-)\n\ndiff --git a/builtin/update-index.c b/builtin/update-index.c\nindex 369c207..fe7aaa3 100644\n--- a/builtin/update-index.c\n+++ b/builtin/update-index.c\n@@ -1116,8 +1116,6 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \t\tthe_index.cache_changed |= SOMETHING_CHANGED;\n \t}\n \tif (untracked_cache > UC_DISABLE) {\n-\t\tstruct untracked_cache *uc;\n-\n \t\tif (untracked_cache < UC_FORCE) {\n \t\t\tsetup_work_tree();\n \t\t\tif (!test_if_untracked_cache_is_supported())\n@@ -1126,7 +1124,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \t\t\t\treturn 0;\n \t\t}\n \t\tif (!the_index.untracked) {\n-\t\t\tuc = xcalloc(1, sizeof(*uc));\n+\t\t\tstruct untracked_cache *uc = xcalloc(1, sizeof(*uc));\n \t\t\tstrbuf_init(&uc->ident, 100);\n \t\t\tuc->exclude_per_dir = \".gitignore\";\n \t\t\t/* should be the same flags used by git-status */\n-- \n2.7.0.36.g20612a7\n"},{"id":"276132","messageId":"1452841192-620-7-git-send-email-chriscool@tuxfamily.org","threadId":"41196","inReplyTo":"1452841192-620-1-git-send-email-chriscool@tuxfamily.org","subject":"[PATCH v5 06/11] dir: add {new,add}_untracked_cache()","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-01-15T06:59:47Z","receivedAt":"2016-01-15T06:59:47Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Factor out code into new_untracked_cache() and\nadd_untracked_cache(), which will be used\nin later commits.\n\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\nHelped-by: Eric Sunshine <sunshine@sunshineco.com>\n---\n builtin/update-index.c | 11 +----------\n dir.c                  | 18 ++++++++++++++++++\n dir.h                  |  1 +\n 3 files changed, 20 insertions(+), 10 deletions(-)\n\ndiff --git a/builtin/update-index.c b/builtin/update-index.c\nindex fe7aaa3..5f8630c 100644\n--- a/builtin/update-index.c\n+++ b/builtin/update-index.c\n@@ -1123,16 +1123,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \t\t\tif (untracked_cache == UC_TEST)\n \t\t\t\treturn 0;\n \t\t}\n-\t\tif (!the_index.untracked) {\n-\t\t\tstruct untracked_cache *uc = xcalloc(1, sizeof(*uc));\n-\t\t\tstrbuf_init(&uc->ident, 100);\n-\t\t\tuc->exclude_per_dir = \".gitignore\";\n-\t\t\t/* should be the same flags used by git-status */\n-\t\t\tuc->dir_flags = DIR_SHOW_OTHER_DIRECTORIES | DIR_HIDE_EMPTY_DIRECTORIES;\n-\t\t\tthe_index.untracked = uc;\n-\t\t}\n-\t\tadd_untracked_ident(the_index.untracked);\n-\t\tthe_index.cache_changed |= UNTRACKED_CHANGED;\n+\t\tadd_untracked_cache(&the_index);\n \t\treport(_(\"Untracked cache enabled for '%s'\"), get_git_work_tree());\n \t} else if (untracked_cache == UC_DISABLE) {\n \t\tif (the_index.untracked) {\ndiff --git a/dir.c b/dir.c\nindex d2a8f06..31eae37 100644\n--- a/dir.c\n+++ b/dir.c\n@@ -1938,6 +1938,24 @@ void add_untracked_ident(struct untracked_cache *uc)\n \tstrbuf_addch(&uc->ident, 0);\n }\n \n+static void new_untracked_cache(struct index_state *istate)\n+{\n+\tstruct untracked_cache *uc = xcalloc(1, sizeof(*uc));\n+\tstrbuf_init(&uc->ident, 100);\n+\tuc->exclude_per_dir = \".gitignore\";\n+\t/* should be the same flags used by git-status */\n+\tuc->dir_flags = DIR_SHOW_OTHER_DIRECTORIES | DIR_HIDE_EMPTY_DIRECTORIES;\n+\tistate->untracked = uc;\n+}\n+\n+void add_untracked_cache(struct index_state *istate)\n+{\n+\tif (!istate->untracked) {\n+\t\tnew_untracked_cache(istate);\n+\tadd_untracked_ident(istate->untracked);\n+\tistate->cache_changed |= UNTRACKED_CHANGED;\n+}\n+\n static struct untracked_cache_dir *validate_untracked_cache(struct dir_struct *dir,\n \t\t\t\t\t\t      int base_len,\n \t\t\t\t\t\t      const struct pathspec *pathspec)\ndiff --git a/dir.h b/dir.h\nindex 7b5855d..cfd3636 100644\n--- a/dir.h\n+++ b/dir.h\n@@ -308,4 +308,5 @@ void free_untracked_cache(struct untracked_cache *);\n struct untracked_cache *read_untracked_extension(const void *data, unsigned long sz);\n void write_untracked_extension(struct strbuf *out, struct untracked_cache *untracked);\n void add_untracked_ident(struct untracked_cache *);\n+void add_untracked_cache(struct index_state *istate);\n #endif\n-- \n2.7.0.36.g20612a7\n"},{"id":"276139","messageId":"1452841192-620-8-git-send-email-chriscool@tuxfamily.org","threadId":"41196","inReplyTo":"1452841192-620-1-git-send-email-chriscool@tuxfamily.org","subject":"[PATCH v5 07/11] dir: add remove_untracked_cache()","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-01-15T06:59:48Z","receivedAt":"2016-01-15T06:59:48Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Factor out code into remove_untracked_cache(), which will be used\nin a later commit.\n\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/update-index.c | 6 +-----\n dir.c                  | 9 +++++++++\n dir.h                  | 1 +\n 3 files changed, 11 insertions(+), 5 deletions(-)\n\ndiff --git a/builtin/update-index.c b/builtin/update-index.c\nindex 5f8630c..d90154c 100644\n--- a/builtin/update-index.c\n+++ b/builtin/update-index.c\n@@ -1126,11 +1126,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \t\tadd_untracked_cache(&the_index);\n \t\treport(_(\"Untracked cache enabled for '%s'\"), get_git_work_tree());\n \t} else if (untracked_cache == UC_DISABLE) {\n-\t\tif (the_index.untracked) {\n-\t\t\tfree_untracked_cache(the_index.untracked);\n-\t\t\tthe_index.untracked = NULL;\n-\t\t\tthe_index.cache_changed |= UNTRACKED_CHANGED;\n-\t\t}\n+\t\tremove_untracked_cache(&the_index);\n \t\treport(_(\"Untracked cache disabled\"));\n \t}\n \ndiff --git a/dir.c b/dir.c\nindex 31eae37..0d069c9 100644\n--- a/dir.c\n+++ b/dir.c\n@@ -1956,6 +1956,15 @@ void add_untracked_cache(struct index_state *istate)\n \tistate->cache_changed |= UNTRACKED_CHANGED;\n }\n \n+void remove_untracked_cache(struct index_state *istate)\n+{\n+\tif (istate->untracked) {\n+\t\tfree_untracked_cache(istate->untracked);\n+\t\tistate->untracked = NULL;\n+\t\tistate->cache_changed |= UNTRACKED_CHANGED;\n+\t}\n+}\n+\n static struct untracked_cache_dir *validate_untracked_cache(struct dir_struct *dir,\n \t\t\t\t\t\t      int base_len,\n \t\t\t\t\t\t      const struct pathspec *pathspec)\ndiff --git a/dir.h b/dir.h\nindex cfd3636..a3dacdb 100644\n--- a/dir.h\n+++ b/dir.h\n@@ -309,4 +309,5 @@ struct untracked_cache *read_untracked_extension(const void *data, unsigned long\n void write_untracked_extension(struct strbuf *out, struct untracked_cache *untracked);\n void add_untracked_ident(struct untracked_cache *);\n void add_untracked_cache(struct index_state *istate);\n+void remove_untracked_cache(struct index_state *istate);\n #endif\n-- \n2.7.0.36.g20612a7\n"},{"id":"276134","messageId":"1452841192-620-9-git-send-email-chriscool@tuxfamily.org","threadId":"41196","inReplyTo":"1452841192-620-1-git-send-email-chriscool@tuxfamily.org","subject":"[PATCH v5 08/11] dir: simplify untracked cache \"ident\" field","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-01-15T06:59:49Z","receivedAt":"2016-01-15T06:59:49Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"It is not a good idea to compare kernel versions and disable\nthe untracked cache if it changes as people may upgrade and\nstill want the untracked cache to work. So let's just\ncompare work tree locations and kernel name to decide if we\nshould disable it.\n\nAlso it's not useful to store many locations in the ident\nfield and compare to any of them. It can even be dangerous\nif GIT_WORK_TREE is used with different values. So let's\njust store one location, the location of the current work\ntree.\n\nIf this location changed and we still want an untracked\ncache, let's delete the cache and recreate it.\n\nNote that if an untracked cache has been created by a\nprevious Git version, then the kernel version is stored in\nthe ident field. As we now compare with just the kernel\nname the comparison will fail and the untracked cache will\nbe disabled until it's recreated.\n\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\nHelped-by: Torsten Bögershausen <tboegi@web.de>\n---\n dir.c | 39 ++++++++++++++++++++++++---------------\n dir.h |  1 -\n 2 files changed, 24 insertions(+), 16 deletions(-)\n\ndiff --git a/dir.c b/dir.c\nindex 0d069c9..42d3b6b 100644\n--- a/dir.c\n+++ b/dir.c\n@@ -1913,28 +1913,31 @@ static const char *get_ident_string(void)\n \t\treturn sb.buf;\n \tif (uname(&uts) < 0)\n \t\tdie_errno(_(\"failed to get kernel name and information\"));\n-\tstrbuf_addf(&sb, \"Location %s, system %s %s %s\", get_git_work_tree(),\n-\t\t    uts.sysname, uts.release, uts.version);\n+\tstrbuf_addf(&sb, \"Location %s, system %s\", get_git_work_tree(),\n+\t\t    uts.sysname);\n \treturn sb.buf;\n }\n \n static int ident_in_untracked(const struct untracked_cache *uc)\n {\n-\tconst char *end = uc->ident.buf + uc->ident.len;\n-\tconst char *p   = uc->ident.buf;\n+\t/*\n+\t * Previous git versions may have saved many NUL separated\n+\t * strings in the \"ident\" field, but it is insane to manage\n+\t * many locations, so just take care of the first one.\n+\t */\n \n-\tfor (p = uc->ident.buf; p < end; p += strlen(p) + 1)\n-\t\tif (!strcmp(p, get_ident_string()))\n-\t\t\treturn 1;\n-\treturn 0;\n+\treturn !strcmp(uc->ident.buf, get_ident_string());\n }\n \n-void add_untracked_ident(struct untracked_cache *uc)\n+static void set_untracked_ident(struct untracked_cache *uc)\n {\n-\tif (ident_in_untracked(uc))\n-\t\treturn;\n+\tstrbuf_reset(&uc->ident);\n \tstrbuf_addstr(&uc->ident, get_ident_string());\n-\t/* this strbuf contains a list of strings, save NUL too */\n+\n+\t/*\n+\t * This strbuf used to contain a list of NUL separated\n+\t * strings, so save NUL too for backward compatibility.\n+\t */\n \tstrbuf_addch(&uc->ident, 0);\n }\n \n@@ -1945,15 +1948,21 @@ static void new_untracked_cache(struct index_state *istate)\n \tuc->exclude_per_dir = \".gitignore\";\n \t/* should be the same flags used by git-status */\n \tuc->dir_flags = DIR_SHOW_OTHER_DIRECTORIES | DIR_HIDE_EMPTY_DIRECTORIES;\n+\tset_untracked_ident(uc);\n \tistate->untracked = uc;\n+\tistate->cache_changed |= UNTRACKED_CHANGED;\n }\n \n void add_untracked_cache(struct index_state *istate)\n {\n \tif (!istate->untracked) {\n \t\tnew_untracked_cache(istate);\n-\tadd_untracked_ident(istate->untracked);\n-\tistate->cache_changed |= UNTRACKED_CHANGED;\n+\t} else {\n+\t\tif (!ident_in_untracked(istate->untracked)) {\n+\t\t\tfree_untracked_cache(istate->untracked);\n+\t\t\tnew_untracked_cache(istate);\n+\t\t}\n+\t}\n }\n \n void remove_untracked_cache(struct index_state *istate)\n@@ -2022,7 +2031,7 @@ static struct untracked_cache_dir *validate_untracked_cache(struct dir_struct *d\n \t\treturn NULL;\n \n \tif (!ident_in_untracked(dir->untracked)) {\n-\t\twarning(_(\"Untracked cache is disabled on this system.\"));\n+\t\twarning(_(\"Untracked cache is disabled on this system or location.\"));\n \t\treturn NULL;\n \t}\n \ndiff --git a/dir.h b/dir.h\nindex a3dacdb..cd46f30 100644\n--- a/dir.h\n+++ b/dir.h\n@@ -307,7 +307,6 @@ void untracked_cache_add_to_index(struct index_state *, const char *);\n void free_untracked_cache(struct untracked_cache *);\n struct untracked_cache *read_untracked_extension(const void *data, unsigned long sz);\n void write_untracked_extension(struct strbuf *out, struct untracked_cache *untracked);\n-void add_untracked_ident(struct untracked_cache *);\n void add_untracked_cache(struct index_state *istate);\n void remove_untracked_cache(struct index_state *istate);\n #endif\n-- \n2.7.0.36.g20612a7\n"},{"id":"276135","messageId":"1452841192-620-10-git-send-email-chriscool@tuxfamily.org","threadId":"41196","inReplyTo":"1452841192-620-1-git-send-email-chriscool@tuxfamily.org","subject":"[PATCH v5 09/11] config: add core.untrackedCache","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-01-15T06:59:50Z","receivedAt":"2016-01-15T06:59:50Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"When we know that mtime is fully supported by the environment, we\nmight want the untracked cache to be always used by default without\nany mtime test or kernel version check being performed.\n\nAlso when we know that mtime is not supported by the environment,\nfor example because the repo is shared over a network file system,\nwe might want the untracked-cache to be automatically remove from\nthe index.\n\nThe normal way to achieve the above in Git is to use a config\nvariable. That's why this patch introduces \"core.untrackedCache\".\n\nThis variable is a tristate, `keep`, `false` and `true`, which\ndefault to `keep`.\n\nWhen read_index_from() is called, it now adds or removes the\nuntracked cache in the index to respect the value of this\nvariable. So it does nothing if the value is `keep` or if the\nvariable is unset; it adds the untracked cache if the value is\n`true`; and it removes the cache if the value is `false`.\n\n`git update-index --[no-|force-]untracked-cache` still adds or\nremoves the untracked cache from the index, but this shows a\nwarning if it goes against the value of core.untrackedCache,\nas the untracked cache will go back to its previous state the\nnext time read_index_from() is called.\n\nAlso `--untracked-cache` used to check that the underlying\noperating system and file system change `st_mtime` field of a\ndirectory if files are added or deleted in that directory. But\nthose tests take a long time and there is now\n`--test-untracked-cache` to perform them.\n\nThat's why, to be more consistent with other git commands, this\npatch prevents `--untracked-cache` to perform tests, so that\nafter this patch there is no difference any more between\n`--untracked-cache` and `--force-untracked-cache`.\n\nThis last change is backward incompatible and should be\nmentioned in the release notes.\n\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\nHelped-by: Duy Nguyen <pclouds@gmail.com>\nHelped-by: Torsten Bögershausen <tboegi@web.de>\n---\n Documentation/config.txt               |  9 +++++\n Documentation/git-update-index.txt     | 67 ++++++++++++++++++++++++++--------\n builtin/update-index.c                 | 35 ++++++++++++------\n cache.h                                |  1 +\n config.c                               | 20 ++++++++++\n contrib/completion/git-completion.bash |  1 +\n read-cache.c                           | 14 +++++++\n t/t7063-status-untracked-cache.sh      |  4 +-\n 8 files changed, 122 insertions(+), 29 deletions(-)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex beb18da..485aa5e 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -308,6 +308,15 @@ core.trustctime::\n \tcrawlers and some backup systems).\n \tSee linkgit:git-update-index[1]. True by default.\n \n+core.untrackedCache::\n+\tDetermines what to do about the untracked cache feature of the\n+\tindex. It will be kept, if this variable is unset or set to\n+\t`keep`. It will automatically be added if set to `true`. And\n+\tit will automatically be removed, if set to `false`. Before\n+\tsetting it to `true`, you should check that mtime is working\n+\tproperly on your system.\n+\tSee linkgit:git-update-index[1]. `keep` by default.\n+\n core.checkStat::\n \tDetermines which stat fields to match between the index\n \tand work tree. The user can set this to 'default' or\ndiff --git a/Documentation/git-update-index.txt b/Documentation/git-update-index.txt\nindex a0afe17..5853dcd 100644\n--- a/Documentation/git-update-index.txt\n+++ b/Documentation/git-update-index.txt\n@@ -174,27 +174,30 @@ may not support it yet.\n \n --untracked-cache::\n --no-untracked-cache::\n-\tEnable or disable untracked cache extension. This could speed\n-\tup for commands that involve determining untracked files such\n-\tas `git status`. The underlying operating system and file\n-\tsystem must change `st_mtime` field of a directory if files\n-\tare added or deleted in that directory.\n+\tEnable or disable untracked cache feature. Please use\n+\t`--test-untracked-cache` before enabling it.\n++\n+These options take effect whatever the value of the `core.untrackedCache`\n+configuration variable (see linkgit:git-config[1]). But a warning is\n+emitted when the change goes against the configured value, as the\n+configured value will take effect next time the index is read and this\n+will remove the intended effect of the option.\n \n --test-untracked-cache::\n \tOnly perform tests on the working directory to make sure\n \tuntracked cache can be used. You have to manually enable\n-\tuntracked cache using `--force-untracked-cache` (or\n-\t`--untracked-cache` but this will run the tests again)\n-\tafterwards if you really want to use it. If a test fails\n-\tthe exit code is 1 and a message explains what is not\n-\tworking as needed, otherwise the exit code is 0 and OK is\n-\tprinted.\n+\tuntracked cache using `--untracked-cache` or\n+\t`--force-untracked-cache` or the `core.untrackedCache`\n+\tconfiguration variable afterwards if you really want to use\n+\tit. If a test fails the exit code is 1 and a message\n+\texplains what is not working as needed, otherwise the exit\n+\tcode is 0 and OK is printed.\n \n --force-untracked-cache::\n-\tFor safety, `--untracked-cache` performs tests on the working\n-\tdirectory to make sure untracked cache can be used. These\n-\ttests can take a few seconds. `--force-untracked-cache` can be\n-\tused to skip the tests.\n+\tSame as `--untracked-cache`. Provided for backwards\n+\tcompatibility with older versions of Git where\n+\t`--untracked-cache` used to imply `--test-untracked-cache` but\n+\tthis option would enable the extension unconditionally.\n \n \\--::\n \tDo not interpret any more arguments as options.\n@@ -385,6 +388,37 @@ Although this bit looks similar to assume-unchanged bit, its goal is\n different from assume-unchanged bit's. Skip-worktree also takes\n precedence over assume-unchanged bit when both are set.\n \n+Untracked cache\n+---------------\n+\n+This cache could speed up commands that involve determining untracked\n+files such as `git status`.\n+\n+This feature works by recording the mtime of the working tree\n+directories and then omitting reading directories and stat calls\n+against files in those directories whose mtime hasn't changed. For\n+this to work the underlying operating system and file system must\n+change the `st_mtime` field of directories if files in the directory\n+are added, modified or deleted.\n+\n+You can test whether the filesystem supports that with the\n+`--test-untracked-cache` option. The `--untracked-cache` option used\n+to implicitly perform that test in older versions of Git, but that's\n+no longer the case.\n+\n+If you want to enable (or disable) this feature, it is easier to use\n+the `core.untrackedCache` configuration variable (see\n+linkgit:git-config[1]) than using the `--untracked-cache` option to\n+`git update-index` in each repository, especially if you want to do so\n+across all repositories you use, because you can set the configuration\n+variable to `true` (or `false`) in your `$HOME/.gitconfig` just once\n+and have it affect all repositories you touch.\n+\n+When the `core.untrackedCache` configuration variable is changed, the\n+untracked cache is added to or removed from the index the next time a\n+command reads the index; while when `--[no-|force-]untracked-cache`\n+are used, the untracked cache is immediately added to or removed from\n+the index.\n \n Configuration\n -------------\n@@ -410,6 +444,9 @@ It can be useful when the inode change time is regularly modified by\n something outside Git (file system crawlers and backup systems use\n ctime for marking files processed) (see linkgit:git-config[1]).\n \n+The untracked cache extension can be enabled by the\n+`core.untrackedCache` configuration variable (see\n+linkgit:git-config[1]).\n \n SEE ALSO\n --------\ndiff --git a/builtin/update-index.c b/builtin/update-index.c\nindex d90154c..7a55334 100644\n--- a/builtin/update-index.c\n+++ b/builtin/update-index.c\n@@ -1115,19 +1115,32 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \t\tthe_index.split_index = NULL;\n \t\tthe_index.cache_changed |= SOMETHING_CHANGED;\n \t}\n-\tif (untracked_cache > UC_DISABLE) {\n-\t\tif (untracked_cache < UC_FORCE) {\n-\t\t\tsetup_work_tree();\n-\t\t\tif (!test_if_untracked_cache_is_supported())\n-\t\t\t\treturn 1;\n-\t\t\tif (untracked_cache == UC_TEST)\n-\t\t\t\treturn 0;\n-\t\t}\n-\t\tadd_untracked_cache(&the_index);\n-\t\treport(_(\"Untracked cache enabled for '%s'\"), get_git_work_tree());\n-\t} else if (untracked_cache == UC_DISABLE) {\n+\n+\tswitch (untracked_cache) {\n+\tcase UC_UNSPECIFIED:\n+\t\tbreak;\n+\tcase UC_DISABLE:\n+\t\tif (git_config_get_untracked_cache() == 1)\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\treport(_(\"Untracked cache disabled\"));\n+\t\tbreak;\n+\tcase UC_TEST:\n+\t\tsetup_work_tree();\n+\t\treturn !test_if_untracked_cache_is_supported();\n+\tcase UC_ENABLE:\n+\tcase UC_FORCE:\n+\t\tif (git_config_get_untracked_cache() == 0)\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\treport(_(\"Untracked cache enabled for '%s'\"), get_git_work_tree());\n+\t\tbreak;\n+\tdefault:\n+\t\tdie(\"Bug: bad untracked_cache value: %d\", untracked_cache);\n \t}\n \n \tif (active_cache_changed) {\ndiff --git a/cache.h b/cache.h\nindex c63fcc1..59a15fd 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -1603,6 +1603,7 @@ extern int git_config_get_bool(const char *key, int *dest);\n extern int git_config_get_bool_or_int(const char *key, int *is_bool, int *dest);\n extern int git_config_get_maybe_bool(const char *key, int *dest);\n extern int git_config_get_pathname(const char *key, const char **dest);\n+extern int git_config_get_untracked_cache(void);\n \n struct key_value_info {\n \tconst char *filename;\ndiff --git a/config.c b/config.c\nindex 86a5eb2..647a15e 100644\n--- a/config.c\n+++ b/config.c\n@@ -1594,6 +1594,26 @@ int git_config_get_pathname(const char *key, const char **dest)\n \treturn ret;\n }\n \n+int git_config_get_untracked_cache(void)\n+{\n+\tint val = -1;\n+\tconst char *v;\n+\n+\tif (!git_config_get_maybe_bool(\"core.untrackedcache\", &val))\n+\t\treturn val;\n+\n+\tif (!git_config_get_value(\"core.untrackedcache\", &v)) {\n+\t\tif (!strcasecmp(v, \"keep\"))\n+\t\t\treturn -1;\n+\n+\t\terror(\"unknown core.untrackedCache value '%s'; \"\n+\t\t      \"using 'keep' default value\", v);\n+\t\treturn -1;\n+\t}\n+\n+\treturn -1; /* default value */\n+}\n+\n NORETURN\n void git_die_config_linenr(const char *key, const char *filename, int linenr)\n {\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex ab4da7f..de4b5ed 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -2056,6 +2056,7 @@ _git_config ()\n \t\tcore.sparseCheckout\n \t\tcore.symlinks\n \t\tcore.trustctime\n+\t\tcore.untrackedCache\n \t\tcore.warnAmbiguousRefs\n \t\tcore.whitespace\n \t\tcore.worktree\ndiff --git a/read-cache.c b/read-cache.c\nindex 84616c8..1d5696c 100644\n--- a/read-cache.c\n+++ b/read-cache.c\n@@ -1622,6 +1622,20 @@ int read_index_from(struct index_state *istate, const char *path)\n \t\treturn istate->cache_nr;\n \n \tret = do_read_index(istate, path, 0);\n+\n+\tswitch (git_config_get_untracked_cache()) {\n+\tcase -1: /* keep: do nothing */\n+\t\tbreak;\n+\tcase 0: /* false */\n+\t\tremove_untracked_cache(istate);\n+\t\tbreak;\n+\tcase 1: /* true */\n+\t\tadd_untracked_cache(istate);\n+\t\tbreak;\n+\tdefault: /* unknown value: do nothing */\n+\t\tbreak;\n+\t}\n+\n \tsplit_index = istate->split_index;\n \tif (!split_index || is_null_sha1(split_index->base_sha1)) {\n \t\tcheck_ce_order(istate);\ndiff --git a/t/t7063-status-untracked-cache.sh b/t/t7063-status-untracked-cache.sh\nindex 0e8d0d4..253160a 100755\n--- a/t/t7063-status-untracked-cache.sh\n+++ b/t/t7063-status-untracked-cache.sh\n@@ -8,10 +8,8 @@ avoid_racy() {\n \tsleep 1\n }\n \n-# It's fine if git update-index returns an error code other than one,\n-# it'll be caught in the first test.\n test_lazy_prereq UNTRACKED_CACHE '\n-\t{ git update-index --untracked-cache; ret=$?; } &&\n+\t{ git update-index --test-untracked-cache; ret=$?; } &&\n \ttest $ret -ne 1\n '\n \n-- \n2.7.0.36.g20612a7\n"},{"id":"276136","messageId":"1452841192-620-11-git-send-email-chriscool@tuxfamily.org","threadId":"41196","inReplyTo":"1452841192-620-1-git-send-email-chriscool@tuxfamily.org","subject":"[PATCH v5 10/11] test-dump-untracked-cache: don't modify the untracked cache","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-01-15T06:59:51Z","receivedAt":"2016-01-15T06:59:51Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"To correctly perform its testing function,\ntest-dump-untracked-cache should not change the state of the\nuntracked cache in the index.\n\nAs a previous patch makes read_index_from() change the untracked\ncache status and as test-dump-untracked-cache indirectly calls\nthis function, we need a mechanism to prevent read_index_from()\nto change the untracked cache state when it's called from\ntest-dump-untracked-cache.\n\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n cache.h                     | 2 ++\n config.c                    | 3 +++\n environment.c               | 6 ++++++\n test-dump-untracked-cache.c | 2 ++\n 4 files changed, 13 insertions(+)\n\ndiff --git a/cache.h b/cache.h\nindex 59a15fd..89c7e10 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -1605,6 +1605,8 @@ extern int git_config_get_maybe_bool(const char *key, int *dest);\n extern int git_config_get_pathname(const char *key, const char **dest);\n extern int git_config_get_untracked_cache(void);\n \n+extern int ignore_untracked_cache_config;\n+\n struct key_value_info {\n \tconst char *filename;\n \tint linenr;\ndiff --git a/config.c b/config.c\nindex 647a15e..a4f70f7 100644\n--- a/config.c\n+++ b/config.c\n@@ -1599,6 +1599,9 @@ int git_config_get_untracked_cache(void)\n \tint val = -1;\n \tconst char *v;\n \n+\tif (ignore_untracked_cache_config)\n+\t\treturn -1;\n+\n \tif (!git_config_get_maybe_bool(\"core.untrackedcache\", &val))\n \t\treturn val;\n \ndiff --git a/environment.c b/environment.c\nindex 1cc4aab..74294ee 100644\n--- a/environment.c\n+++ b/environment.c\n@@ -87,6 +87,12 @@ int auto_comment_line_char;\n /* Parallel index stat data preload? */\n int core_preload_index = 1;\n \n+/*\n+ * This is to ensure that the untracked cache is not modified, for\n+ * example in test programs like test-dump-untracked-cache.\n+ */\n+int ignore_untracked_cache_config;\n+\n /* This is set by setup_git_dir_gently() and/or git_default_config() */\n char *git_work_tree_cfg;\n static char *work_tree;\ndiff --git a/test-dump-untracked-cache.c b/test-dump-untracked-cache.c\nindex 25d855d..8d1293c 100644\n--- a/test-dump-untracked-cache.c\n+++ b/test-dump-untracked-cache.c\n@@ -44,6 +44,8 @@ int main(int ac, char **av)\n {\n \tstruct untracked_cache *uc;\n \tstruct strbuf base = STRBUF_INIT;\n+\n+\tignore_untracked_cache_config = 1;\n \tsetup_git_directory();\n \tif (read_cache() < 0)\n \t\tdie(\"unable to read index file\");\n-- \n2.7.0.36.g20612a7\n"},{"id":"276138","messageId":"1452841192-620-12-git-send-email-chriscool@tuxfamily.org","threadId":"41196","inReplyTo":"1452841192-620-1-git-send-email-chriscool@tuxfamily.org","subject":"[PATCH v5 11/11] t7063: add tests for core.untrackedCache","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-01-15T06:59:52Z","receivedAt":"2016-01-15T06:59:52Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n t/t7063-status-untracked-cache.sh | 85 +++++++++++++++++++++++++++++++++++++--\n 1 file changed, 81 insertions(+), 4 deletions(-)\n\ndiff --git a/t/t7063-status-untracked-cache.sh b/t/t7063-status-untracked-cache.sh\nindex 253160a..b1dc860 100755\n--- a/t/t7063-status-untracked-cache.sh\n+++ b/t/t7063-status-untracked-cache.sh\n@@ -18,6 +18,10 @@ if ! test_have_prereq UNTRACKED_CACHE; then\n \ttest_done\n fi\n \n+test_expect_success 'core.untrackedCache is unset' '\n+\ttest_must_fail git config --get core.untrackedCache\n+'\n+\n test_expect_success 'setup' '\n \tgit init worktree &&\n \tcd worktree &&\n@@ -30,13 +34,13 @@ test_expect_success 'setup' '\n \n test_expect_success 'untracked cache is empty' '\n \ttest-dump-untracked-cache >../actual &&\n-\tcat >../expect <<EOF &&\n+\tcat >../expect-empty <<EOF &&\n info/exclude 0000000000000000000000000000000000000000\n core.excludesfile 0000000000000000000000000000000000000000\n exclude_per_dir .gitignore\n flags 00000006\n EOF\n-\ttest_cmp ../expect ../actual\n+\ttest_cmp ../expect-empty ../actual\n '\n \n cat >../status.expect <<EOF &&\n@@ -506,7 +510,7 @@ EOF\n \n test_expect_success 'verify untracked cache dump (sparse/subdirs)' '\n \ttest-dump-untracked-cache >../actual &&\n-\tcat >../expect <<EOF &&\n+\tcat >../expect-from-test-dump <<EOF &&\n info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0\n core.excludesfile 0000000000000000000000000000000000000000\n exclude_per_dir .gitignore\n@@ -525,7 +529,7 @@ file\n /dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid\n two\n EOF\n-\ttest_cmp ../expect ../actual\n+\ttest_cmp ../expect-from-test-dump ../actual\n '\n \n test_expect_success 'test sparse status again with untracked cache and subdir' '\n@@ -569,4 +573,77 @@ EOF\n \ttest_cmp ../status.expect ../status.actual\n '\n \n+test_expect_success '--no-untracked-cache removes the cache' '\n+\tgit update-index --no-untracked-cache &&\n+\ttest-dump-untracked-cache >../actual &&\n+\techo \"no untracked cache\" >../expect &&\n+\ttest_cmp ../expect ../actual\n+'\n+\n+test_expect_success 'git status does not change anything' '\n+\tgit status &&\n+\ttest-dump-untracked-cache >../actual &&\n+\ttest_cmp ../expect ../actual\n+'\n+\n+test_expect_success 'setting core.untrackedCache to true and using git status creates the cache' '\n+\tgit config core.untrackedCache true &&\n+\ttest-dump-untracked-cache >../actual &&\n+\ttest_cmp ../expect ../actual &&\n+\tgit status &&\n+\ttest-dump-untracked-cache >../actual &&\n+\ttest_cmp ../expect-from-test-dump ../actual\n+'\n+\n+test_expect_success 'using --no-untracked-cache does not fail when core.untrackedCache is true' '\n+\tgit update-index --no-untracked-cache &&\n+\ttest-dump-untracked-cache >../actual &&\n+\ttest_cmp ../expect ../actual &&\n+\tgit update-index --untracked-cache &&\n+\ttest-dump-untracked-cache >../actual &&\n+\ttest_cmp ../expect-empty ../actual\n+'\n+\n+test_expect_success 'setting core.untrackedCache to false and using git status removes the cache' '\n+\tgit config core.untrackedCache false &&\n+\ttest-dump-untracked-cache >../actual &&\n+\ttest_cmp ../expect-empty ../actual &&\n+\tgit status &&\n+\ttest-dump-untracked-cache >../actual &&\n+\ttest_cmp ../expect ../actual\n+'\n+\n+test_expect_success 'using --untracked-cache does not fail when core.untrackedCache is false' '\n+\tgit update-index --untracked-cache &&\n+\ttest-dump-untracked-cache >../actual &&\n+\ttest_cmp ../expect-empty ../actual\n+'\n+\n+test_expect_success 'setting core.untrackedCache to keep' '\n+\tgit config core.untrackedCache keep &&\n+\tgit update-index --untracked-cache &&\n+\ttest-dump-untracked-cache >../actual &&\n+\ttest_cmp ../expect-empty ../actual &&\n+\tgit status &&\n+\ttest-dump-untracked-cache >../actual &&\n+\ttest_cmp ../expect-from-test-dump ../actual &&\n+\tgit update-index --no-untracked-cache &&\n+\ttest-dump-untracked-cache >../actual &&\n+\ttest_cmp ../expect ../actual &&\n+\tgit update-index --force-untracked-cache &&\n+\ttest-dump-untracked-cache >../actual &&\n+\ttest_cmp ../expect-empty ../actual &&\n+\tgit status &&\n+\ttest-dump-untracked-cache >../actual &&\n+\ttest_cmp ../expect-from-test-dump ../actual\n+'\n+\n+test_expect_success 'test ident field is working' '\n+\tmkdir ../other_worktree &&\n+\tcp -R done dthree dtwo four three ../other_worktree &&\n+\tGIT_WORK_TREE=../other_worktree git status 2>../err &&\n+\techo \"warning: Untracked cache is disabled on this system or location.\" >../expect &&\n+\ttest_cmp ../expect ../err\n+'\n+\n test_done\n-- \n2.7.0.36.g20612a7\n"},{"id":"276192","messageId":"xmqqlh7qha5k.fsf@gitster.mtv.corp.google.com","threadId":"41196","inReplyTo":"1452841192-620-10-git-send-email-chriscool@tuxfamily.org","subject":"Re: [PATCH v5 09/11] config: add core.untrackedCache","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-01-15T20:15:19Z","receivedAt":"2016-01-15T20:15:19Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Christian Couder <christian.couder@gmail.com> writes:\n\n> When we know that mtime is fully supported by the environment, we\n> might want the untracked cache to be always used by default without\n> any mtime test or kernel version check being performed.\n>\n> Also when we know that mtime is not supported by the environment,\n> for example because the repo is shared over a network file system,\n> we might want the untracked-cache to be automatically remove from\n> the index.\n\nI'd say \"fully supported\" and \"not supported\" are bad phrasing.\nNetwork file system may give you mtime, but for the purpose of uc,\nit may not be usable, and that is when you do not want to rely on\nit.  So perhaps \"When we know that mtime on directory the\nenvironment gives us is usable for the purpose of untracked cache\",\nand \"Also when we know that mtime is not usable\" or something like\nthat?\n\nI think \"we might want\" can become a stronger \"we may want\" in both\nparagraphs.  The second paragraph needs s/remove/removed/.\n\n> The normal way to achieve the above in Git is to use a config\n> variable. That's why this patch introduces \"core.untrackedCache\".\n>\n> This variable is a tristate, `keep`, `false` and `true`, which\n> default to `keep`.\n\nThe above makes a reader wonder what are abnormal ways ;-).\n\n    Allow the user to express such preference by setting the\n    'core.untrackedCache' configuration variable, which can take\n    'keep', 'false', or 'true'.\n\nwould be clearer without being muddied by an unnecessary value\njudgement.\n\n> When read_index_from() is called, it now adds or removes the\n> untracked cache in the index to respect the value of this\n> variable. So it does nothing if the value is `keep` or if the\n> variable is unset; it adds the untracked cache if the value is\n> `true`; and it removes the cache if the value is `false`.\n\nOK.\n\n> `git update-index --[no-|force-]untracked-cache` still adds or\n> removes the untracked cache from the index,\n\nThe above is meant to be a contraction of \"... still adds UC to the\nindex or removes UC from the index\", but reads as if the original\nwere \"... still adds UC from the index or removes UC from the\nindex\".\n\n\"... still adds UC to or removes from the index\" perhaps?\n\n> but this shows a\n> warning if it goes against the value of core.untrackedCache,\n> as the untracked cache will go back to its previous state the\n> next time read_index_from() is called.\n\nNot incorrect per-se, but\n\n    ... shows a warning ... because the next time the index is read\n    UC will be added or removed if the configuration is set to do so.\n\nmay make it more clear that `keep` in core.untrackedCache does not\nhave to issue a warning (I saw your code correctly handles the\nwarning in this patch).\n\n> Also `--untracked-cache` used to check that the underlying\n> operating system and file system change `st_mtime` field of a\n> directory if files are added or deleted in that directory. But\n> those tests take a long time and there is now\n> `--test-untracked-cache` to perform them.\n> That's why, to be more consistent with other git commands, this\n> patch prevents `--untracked-cache` to perform tests, so that\n> after this patch there is no difference any more between\n> `--untracked-cache` and `--force-untracked-cache`.\n\n    But because those tests take a long time, `--untracked-cache` no\n    longer performs them.  Instead, there is now `--test-untracked-cache`\n    to perform the tests.  This change makes `--untracked-cache` the\n    same as `--force-untracked-cache`.\n\n> +Untracked cache\n> +---------------\n> +\n> +This cache could speed up commands that involve determining untracked\n> +files such as `git status`.\n\nYou are being a bit too modest by saying \"could\" here, I think.  If\nyou do not want to be overly assertive, perhaps say \"is meant to\"?\n\n> +This feature works by recording the mtime of the working tree\n> +directories and then omitting reading directories and stat calls\n> +against files in those directories whose mtime hasn't changed. For\n> +this to work the underlying operating system and file system must\n> +change the `st_mtime` field of directories if files in the directory\n> +are added, modified or deleted.\n\nA reader who read only this without reading the code would wonder if\nthe code works correctly after a untracked path is added to a\ndiretory A/B (the timestamp of B would be updated, while A would\nstay the same) and we ask what are the untracked things inside the\nwhole tree.  Of course we shouldn't \"omit\" scanning A down to B, but\nit is a bit unclear that we didn't have such a design bug from this\ndescription.\n\nUnfortunately I don't have a good rephrasing suggestion.\n\nThanks.\n"},{"id":"276193","messageId":"xmqqh9ieha3v.fsf@gitster.mtv.corp.google.com","threadId":"41196","inReplyTo":"1452841192-620-1-git-send-email-chriscool@tuxfamily.org","subject":"Re: [PATCH v5 00/11] Untracked cache improvements","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-01-15T20:16:20Z","receivedAt":"2016-01-15T20:16:20Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Christian Couder <christian.couder@gmail.com> writes:\n\n> Here is a new version of a patch series to improve the untracked cache\n> feature.\n\nWill replace.  This mostly looks ready for 'next' modulo minor nits\nI sent separately.\n\nThanks.\n"},{"id":"276194","messageId":"xmqqa8o6ha3e.fsf@gitster.mtv.corp.google.com","threadId":"41196","inReplyTo":"1452841192-620-11-git-send-email-chriscool@tuxfamily.org","subject":"Re: [PATCH v5 10/11] test-dump-untracked-cache: don't modify the untracked cache","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-01-15T20:16:37Z","receivedAt":"2016-01-15T20:16:37Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Christian Couder <christian.couder@gmail.com> writes:\n\n> diff --git a/cache.h b/cache.h\n> index 59a15fd..89c7e10 100644\n> --- a/cache.h\n> +++ b/cache.h\n> @@ -1605,6 +1605,8 @@ extern int git_config_get_maybe_bool(const char *key, int *dest);\n>  extern int git_config_get_pathname(const char *key, const char **dest);\n>  extern int git_config_get_untracked_cache(void);\n>  \n> +extern int ignore_untracked_cache_config;\n> +\n\nI know you said this is a hack to support the test, but I really do\nnot like to have a test-only global variable exposed to everybody\nlike this, as I do not think \"ignore_untracked_cache_config\" should\nbe necessary outside the context of testing [*1*].\n\nIf the config cache layer that is used by the implementation of\ngit_config_get_untracked_cache() had a way to be told to pretend\nthat the value of a particular configuration variable is a given\nvalue, then we could do\n\n\tgit_config_pretend_value(\"core.untrackedcache\", \"keep\");\n\nat the beginning of the test program without harming anybody else.\n\nThe above is just me \"thinking aloud\", without assessing if the\ndamage to the entire codebase with that approach to extend the\nconfig layer would be larger than the damabe by this patch, and it\nis certainly not a suggestion to redo this patch along that line.\nBut I am saying it aloud because it may turn out to be a good\ndirection to go in the larger picture once this series is done--it\nmay be a solution that is applicable to a class of similar problems\nin a more general way.\n\nInside the scope of this series, can we at least add a comment next\nto this variable telling everybody to never use it in normal\nprograms, or something?\n\nThanks.\n\n\n[Footnote]\n\n*1* Otherwise, we have a larger problem; it would mean that \"we\ntrust the configuration variable better than the fact that the user\nsaid the feature must (or must not) be used with this index file\" is\nflawed, which would contradict with the whole premise of this\nseries.\n\n\n> diff --git a/config.c b/config.c\n> index 647a15e..a4f70f7 100644\n> --- a/config.c\n> +++ b/config.c\n> @@ -1599,6 +1599,9 @@ int git_config_get_untracked_cache(void)\n>  \tint val = -1;\n>  \tconst char *v;\n>  \n> +\tif (ignore_untracked_cache_config)\n> +\t\treturn -1;\n> +\n>  \tif (!git_config_get_maybe_bool(\"core.untrackedcache\", &val))\n>  \t\treturn val;\n>  \n> diff --git a/environment.c b/environment.c\n> index 1cc4aab..74294ee 100644\n> --- a/environment.c\n> +++ b/environment.c\n> @@ -87,6 +87,12 @@ int auto_comment_line_char;\n>  /* Parallel index stat data preload? */\n>  int core_preload_index = 1;\n>  \n> +/*\n> + * This is to ensure that the untracked cache is not modified, for\n> + * example in test programs like test-dump-untracked-cache.\n> + */\n> +int ignore_untracked_cache_config;\n> +\n>  /* This is set by setup_git_dir_gently() and/or git_default_config() */\n>  char *git_work_tree_cfg;\n>  static char *work_tree;\n> diff --git a/test-dump-untracked-cache.c b/test-dump-untracked-cache.c\n> index 25d855d..8d1293c 100644\n> --- a/test-dump-untracked-cache.c\n> +++ b/test-dump-untracked-cache.c\n> @@ -44,6 +44,8 @@ int main(int ac, char **av)\n>  {\n>  \tstruct untracked_cache *uc;\n>  \tstruct strbuf base = STRBUF_INIT;\n> +\n> +\tignore_untracked_cache_config = 1;\n>  \tsetup_git_directory();\n>  \tif (read_cache() < 0)\n>  \t\tdie(\"unable to read index file\");\n"},{"id":"276229","messageId":"569A59DA.9050008@web.de","threadId":"41196","inReplyTo":"1452841192-620-9-git-send-email-chriscool@tuxfamily.org","subject":"Re: [PATCH v5 08/11] dir: simplify untracked cache \"ident\" field","fromName":"Torsten Bögershausen","fromEmail":"tboegi@web.de","sentAt":"2016-01-16T14:55:22Z","receivedAt":"2016-01-16T14:55:22Z","isPatch":true,"sender":{"key":"tboegi@web.de","avatar":"https://avatars.githubusercontent.com/u/7138363?v=4"},"body":"\n\nOn 2016-01-15 07.59, Christian Couder wrote:\n> It is not a good idea to compare kernel versions and disable\n> the untracked cache if it changes as people may upgrade and\n> still want the untracked cache to work. So let's just\n> compare work tree locations and kernel name to decide if we\n> should disable it.\n>\n> Also it's not useful to store many locations in the ident\n> field and compare to any of them. It can even be dangerous\n> if GIT_WORK_TREE is used with different values. So let's\n> just store one location, the location of the current work\n> tree.\n>\n> If this location changed and we still want an untracked\n> cache, let's delete the cache and recreate it.\n>\n> Note that if an untracked cache has been created by a\n> previous Git version, then the kernel version is stored in\n> the ident field. As we now compare with just the kernel\n> name the comparison will fail and the untracked cache will\n> be disabled until it's recreated.\n>\n> Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n> Helped-by: Torsten Bögershausen <tboegi@web.de>\nThis could be my version of a commit message:\n\nIt is not a good idea to compare kernel versions and disable\nthe untracked cache if it changes as people may upgrade and\nstill want the untracked cache to work.\n\nDrop the major and minor version from uname stored in ident.\n\nIt can be dangerous if GIT_WORK_TREE is used with different values.\n\nSo let's simplify the handling and store just store one line,\nthe uname of the system the location of the current work tree.\n\nIf this location changed and we still want an untracked\ncache, let's delete the cache and recreate it.\n\nThe untracked cache can only be used by one type of OS, exporting a git repo\nto different clients via a network to e.g. Linux and Windows means that\nonly one can use the untracked cache.\n\nNote that if an untracked cache has been created by a\nprevious Git version, then the kernel version is stored in\nthe ident field. As we now compare with just the kernel\nname the comparison will fail and the untracked cache will\nbe disabled until it's recreated.\n"},{"id":"276230","messageId":"569A5A66.3090907@web.de","threadId":"41196","inReplyTo":"1452841192-620-1-git-send-email-chriscool@tuxfamily.org","subject":"Re: [PATCH v5 00/11] Untracked cache improvements","fromName":"Torsten Bögershausen","fromEmail":"tboegi@web.de","sentAt":"2016-01-16T14:57:42Z","receivedAt":"2016-01-16T14:57:42Z","isPatch":true,"sender":{"key":"tboegi@web.de","avatar":"https://avatars.githubusercontent.com/u/7138363?v=4"},"body":"General question after testing UC on a slow network share:\n\ntime ./git status\nOn branch uc-notifs63\nYour branch is up-to-date with 'cc/uc-notifs63'.\n\nIt took 6.27 seconds to enumerate untracked files. 'status -uno'\nmay speed it up, but you have to be careful not to forget to add\nnew files yourself (see 'git help status').\nnothing to commit, working directory clean\n\nreal    0m19.159s\nuser    0m0.085s\nsys     0m0.293s\n----------------------\nDoes it makes sense  to hint the user about the untracked cache ?\n"},{"id":"276344","messageId":"CAP8UFD27rFvCrPPs7q+bve9VoyXcg2bBjkz96VfaUm8TDh4c9w@mail.gmail.com","threadId":"41196","inReplyTo":"569A5A66.3090907@web.de","subject":"Re: [PATCH v5 00/11] Untracked cache improvements","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-01-19T14:43:43Z","receivedAt":"2016-01-19T14:43:43Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"On Sat, Jan 16, 2016 at 3:57 PM, Torsten Bögershausen <tboegi@web.de> wrote:\n> General question after testing UC on a slow network share:\n>\n> time ./git status\n> On branch uc-notifs63\n> Your branch is up-to-date with 'cc/uc-notifs63'.\n>\n> It took 6.27 seconds to enumerate untracked files. 'status -uno'\n> may speed it up, but you have to be careful not to forget to add\n> new files yourself (see 'git help status').\n> nothing to commit, working directory clean\n>\n> real    0m19.159s\n> user    0m0.085s\n> sys     0m0.293s\n> ----------------------\n> Does it makes sense  to hint the user about the untracked cache ?\n\nI don't think it makes sense to hint about it for now.\nWhen more people will have used it for a significant time perhaps.\n"},{"id":"276348","messageId":"xmqqoachbgwj.fsf@gitster.mtv.corp.google.com","threadId":"41196","inReplyTo":"CAP8UFD27rFvCrPPs7q+bve9VoyXcg2bBjkz96VfaUm8TDh4c9w@mail.gmail.com","subject":"Re: [PATCH v5 00/11] Untracked cache improvements","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-01-19T17:47:24Z","receivedAt":"2016-01-19T17:47:24Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Christian Couder <christian.couder@gmail.com> writes:\n\n> On Sat, Jan 16, 2016 at 3:57 PM, Torsten Bögershausen <tboegi@web.de> wrote:\n>> General question after testing UC on a slow network share:\n>>\n>> time ./git status\n>> On branch uc-notifs63\n>> Your branch is up-to-date with 'cc/uc-notifs63'.\n>>\n>> It took 6.27 seconds to enumerate untracked files. 'status -uno'\n>> may speed it up, but you have to be careful not to forget to add\n>> new files yourself (see 'git help status').\n>> nothing to commit, working directory clean\n>>\n>> real    0m19.159s\n>> user    0m0.085s\n>> sys     0m0.293s\n>> ----------------------\n>> Does it makes sense  to hint the user about the untracked cache ?\n>\n> I don't think it makes sense to hint about it for now.\n> When more people will have used it for a significant time perhaps.\n\nChicken or Egg?\n\nI tend to think updating this message is outside of the scope of\nyour series, but you would not get wider adoption (hence more guinea\npigs that 'have used it for a significant time') unless you\nadvertise it, and I agree with Torsten that this is the message that\nmatters most--it is shown when we know we spent a lot of time on\nwhat UC is meant to speed up and no other time.\n"},{"id":"276431","messageId":"CAP8UFD2-Bg6K36WnJxqCQjCOj5-FhSW2H5ciafQv5na3AaTPnw@mail.gmail.com","threadId":"41196","inReplyTo":"xmqqa8o6ha3e.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH v5 10/11] test-dump-untracked-cache: don't modify the untracked cache","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-01-20T10:12:56Z","receivedAt":"2016-01-20T10:12:56Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"On Fri, Jan 15, 2016 at 9:16 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Christian Couder <christian.couder@gmail.com> writes:\n>\n>> diff --git a/cache.h b/cache.h\n>> index 59a15fd..89c7e10 100644\n>> --- a/cache.h\n>> +++ b/cache.h\n>> @@ -1605,6 +1605,8 @@ extern int git_config_get_maybe_bool(const char *key, int *dest);\n>>  extern int git_config_get_pathname(const char *key, const char **dest);\n>>  extern int git_config_get_untracked_cache(void);\n>>\n>> +extern int ignore_untracked_cache_config;\n>> +\n>\n> I know you said this is a hack to support the test, but I really do\n> not like to have a test-only global variable exposed to everybody\n> like this, as I do not think \"ignore_untracked_cache_config\" should\n> be necessary outside the context of testing [*1*].\n>\n> If the config cache layer that is used by the implementation of\n> git_config_get_untracked_cache() had a way to be told to pretend\n> that the value of a particular configuration variable is a given\n> value, then we could do\n>\n>         git_config_pretend_value(\"core.untrackedcache\", \"keep\");\n>\n> at the beginning of the test program without harming anybody else.\n>\n> The above is just me \"thinking aloud\", without assessing if the\n> damage to the entire codebase with that approach to extend the\n> config layer would be larger than the damabe by this patch, and it\n> is certainly not a suggestion to redo this patch along that line.\n> But I am saying it aloud because it may turn out to be a good\n> direction to go in the larger picture once this series is done--it\n> may be a solution that is applicable to a class of similar problems\n> in a more general way.\n>\n> Inside the scope of this series, can we at least add a comment next\n> to this variable telling everybody to never use it in normal\n> programs, or something?\n\nOk, the comments have been added or rewritten telling that in the v6 I\njust sent, thanks.\n"}]}