{"thread":{"id":"41006","subject":"[PATCH v2 01/10] update-index: use enum for untracked cache options","startedAt":"2015-12-15T16:28:17Z","lastAt":"2015-12-18T08:32:03Z","messageCount":18,"participants":["Christian Couder","Junio C Hamano","Torsten Bögershausen","David Turner"],"isPatch":true,"patchVersion":2,"patchTotal":10},"messages":[{"id":"274497","messageId":"1450196907-17805-1-git-send-email-chriscool@tuxfamily.org","threadId":"41006","inReplyTo":null,"subject":"[PATCH v2 00/10] Untracked cache improvements","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2015-12-15T16:28:17Z","receivedAt":"2015-12-15T16:28:17Z","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 v2 still implements core.untrackedCache as a simple bool config\nvariable. When it's true, Git should always try to use the untracked\ncache, and when false, Git should never use it.\n\nPatchs 1/10 to 3/10 add some features that are missing. Patch 3/10 has\nbeen moved after the two other patches and has been changed a bit\naccording to Duy's and Junio's suggestions. In patch 2/10 the enum\nnames have been changed as discussed with Junio.\n\nPatchs 4/10, 5/10 and 6/10, which have not been changed, are some\nrefactoring to prepare for patch 8/10 which implements\ncore.untrackedCache.\n\nPatch 7/10 is a small bug fix suggested by Junio.\n\nPatch 8/10, which adds core.untrackedCache, contains many\ndocumentation and commit message improvements, some by AEvar.\n\nPatch 9/10 has not been changed.\n\nPatch 10/10 is new and removes code that is now useless.\n\nSo the changes compared to v1 are mostly small updates, and patchs\n7/10 and 10/10.\n\nThe patch series is also available there:\n\nhttps://github.com/chriscool/git/tree/uc-notifs25\n\nThanks to the reviewers and helpers.\n\nChristian Couder (10):\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 add_untracked_cache()\n  dir: add remove_untracked_cache()\n  dir: free untracked cache when removing it\n  config: add core.untrackedCache\n  t7063: add tests for core.untrackedCache\n  dir: do not use untracked cache ident anymore\n\n Documentation/config.txt               |  7 ++++\n Documentation/git-update-index.txt     | 61 ++++++++++++++++++++++++++++------\n builtin/update-index.c                 | 54 +++++++++++++++++-------------\n cache.h                                |  1 +\n config.c                               |  4 +++\n contrib/completion/git-completion.bash |  1 +\n dir.c                                  | 53 +++++++++++++----------------\n dir.h                                  |  4 ++-\n environment.c                          |  1 +\n t/t7063-status-untracked-cache.sh      | 52 ++++++++++++++++++++++++++---\n wt-status.c                            |  9 +++++\n 11 files changed, 178 insertions(+), 69 deletions(-)\n\n-- \n2.6.3.479.g8eb29d4\n"},{"id":"274496","messageId":"1450196907-17805-2-git-send-email-chriscool@tuxfamily.org","threadId":"41006","inReplyTo":"1450196907-17805-1-git-send-email-chriscool@tuxfamily.org","subject":"[PATCH v2 01/10] update-index: use enum for untracked cache options","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2015-12-15T16:28:18Z","receivedAt":"2015-12-15T16:28:18Z","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 | 18 +++++++++++++-----\n 1 file changed, 13 insertions(+), 5 deletions(-)\n\ndiff --git a/builtin/update-index.c b/builtin/update-index.c\nindex 7431938..2430a68 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\tthe_index.untracked = NULL;\n \t\tthe_index.cache_changed |= UNTRACKED_CHANGED;\n \t}\n-- \n2.6.3.479.g8eb29d4\n"},{"id":"274499","messageId":"1450196907-17805-3-git-send-email-chriscool@tuxfamily.org","threadId":"41006","inReplyTo":"1450196907-17805-1-git-send-email-chriscool@tuxfamily.org","subject":"[PATCH v2 02/10] update-index: add --test-untracked-cache","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2015-12-15T16:28:19Z","receivedAt":"2015-12-15T16:28:19Z","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>\n---\n Documentation/git-update-index.txt | 9 ++++++++-\n builtin/update-index.c             | 5 +++++\n 2 files changed, 13 insertions(+), 1 deletion(-)\n\ndiff --git a/Documentation/git-update-index.txt b/Documentation/git-update-index.txt\nindex 3df9c26..0ff7396 100644\n--- a/Documentation/git-update-index.txt\n+++ b/Documentation/git-update-index.txt\n@@ -17,7 +17,7 @@ SYNOPSIS\n \t     [--[no-]assume-unchanged]\n \t     [--[no-]skip-worktree]\n \t     [--ignore-submodules]\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@@ -179,6 +179,13 @@ 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.\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 2430a68..e747a6c 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.6.3.479.g8eb29d4\n"},{"id":"274501","messageId":"1450196907-17805-4-git-send-email-chriscool@tuxfamily.org","threadId":"41006","inReplyTo":"1450196907-17805-1-git-send-email-chriscool@tuxfamily.org","subject":"[PATCH v2 03/10] update-index: add untracked cache notifications","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2015-12-15T16:28:20Z","receivedAt":"2015-12-15T16:28:20Z","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>\n---\n builtin/update-index.c | 6 +++++-\n 1 file changed, 5 insertions(+), 1 deletion(-)\n\ndiff --git a/builtin/update-index.c b/builtin/update-index.c\nindex e747a6c..e84674f 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,9 +1135,13 @@ 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\tif (verbose)\n+\t\t\tprintf(_(\"Untracked cache enabled\\n\"));\n \t} else if (untracked_cache == UC_DISABLE && the_index.untracked) {\n \t\tthe_index.untracked = NULL;\n \t\tthe_index.cache_changed |= UNTRACKED_CHANGED;\n+\t\tif (verbose)\n+\t\t\tprintf(_(\"Untracked cache disabled\\n\"));\n \t}\n \n \tif (active_cache_changed) {\n-- \n2.6.3.479.g8eb29d4\n"},{"id":"274498","messageId":"1450196907-17805-5-git-send-email-chriscool@tuxfamily.org","threadId":"41006","inReplyTo":"1450196907-17805-1-git-send-email-chriscool@tuxfamily.org","subject":"[PATCH v2 04/10] update-index: move 'uc' var declaration","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2015-12-15T16:28:21Z","receivedAt":"2015-12-15T16:28:21Z","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 e84674f..fffad79 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.6.3.479.g8eb29d4\n"},{"id":"274500","messageId":"1450196907-17805-6-git-send-email-chriscool@tuxfamily.org","threadId":"41006","inReplyTo":"1450196907-17805-1-git-send-email-chriscool@tuxfamily.org","subject":"[PATCH v2 05/10] dir: add add_untracked_cache()","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2015-12-15T16:28:22Z","receivedAt":"2015-12-15T16:28:22Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Factor out code into add_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 | 11 +----------\n dir.c                  | 14 ++++++++++++++\n dir.h                  |  1 +\n 3 files changed, 16 insertions(+), 10 deletions(-)\n\ndiff --git a/builtin/update-index.c b/builtin/update-index.c\nindex fffad79..5f009cf 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();\n \t\tif (verbose)\n \t\t\tprintf(_(\"Untracked cache enabled\\n\"));\n \t} else if (untracked_cache == UC_DISABLE && the_index.untracked) {\ndiff --git a/dir.c b/dir.c\nindex d2a8f06..0f7e293 100644\n--- a/dir.c\n+++ b/dir.c\n@@ -1938,6 +1938,20 @@ void add_untracked_ident(struct untracked_cache *uc)\n \tstrbuf_addch(&uc->ident, 0);\n }\n \n+void add_untracked_cache(void)\n+{\n+\tif (!the_index.untracked) {\n+\t\tstruct untracked_cache *uc = xcalloc(1, sizeof(*uc));\n+\t\tstrbuf_init(&uc->ident, 100);\n+\t\tuc->exclude_per_dir = \".gitignore\";\n+\t\t/* should be the same flags used by git-status */\n+\t\tuc->dir_flags = DIR_SHOW_OTHER_DIRECTORIES | DIR_HIDE_EMPTY_DIRECTORIES;\n+\t\tthe_index.untracked = uc;\n+\t}\n+\tadd_untracked_ident(the_index.untracked);\n+\tthe_index.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..ee94c76 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(void);\n #endif\n-- \n2.6.3.479.g8eb29d4\n"},{"id":"274503","messageId":"1450196907-17805-7-git-send-email-chriscool@tuxfamily.org","threadId":"41006","inReplyTo":"1450196907-17805-1-git-send-email-chriscool@tuxfamily.org","subject":"[PATCH v2 06/10] dir: add remove_untracked_cache()","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2015-12-15T16:28:23Z","receivedAt":"2015-12-15T16:28:23Z","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 | 3 +--\n dir.c                  | 6 ++++++\n dir.h                  | 1 +\n 3 files changed, 8 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin/update-index.c b/builtin/update-index.c\nindex 5f009cf..4ca6d94 100644\n--- a/builtin/update-index.c\n+++ b/builtin/update-index.c\n@@ -1127,8 +1127,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)\n \t\tif (verbose)\n \t\t\tprintf(_(\"Untracked cache enabled\\n\"));\n \t} else if (untracked_cache == UC_DISABLE && the_index.untracked) {\n-\t\tthe_index.untracked = NULL;\n-\t\tthe_index.cache_changed |= UNTRACKED_CHANGED;\n+\t\tremove_untracked_cache();\n \t\tif (verbose)\n \t\t\tprintf(_(\"Untracked cache disabled\\n\"));\n \t}\ndiff --git a/dir.c b/dir.c\nindex 0f7e293..ffc0286 100644\n--- a/dir.c\n+++ b/dir.c\n@@ -1952,6 +1952,12 @@ void add_untracked_cache(void)\n \tthe_index.cache_changed |= UNTRACKED_CHANGED;\n }\n \n+void remove_untracked_cache(void)\n+{\n+\tthe_index.untracked = NULL;\n+\tthe_index.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 ee94c76..3e5114d 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(void);\n+void remove_untracked_cache(void);\n #endif\n-- \n2.6.3.479.g8eb29d4\n"},{"id":"274502","messageId":"1450196907-17805-8-git-send-email-chriscool@tuxfamily.org","threadId":"41006","inReplyTo":"1450196907-17805-1-git-send-email-chriscool@tuxfamily.org","subject":"[PATCH v2 07/10] dir: free untracked cache when removing it","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2015-12-15T16:28:24Z","receivedAt":"2015-12-15T16:28:24Z","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 dir.c | 1 +\n 1 file changed, 1 insertion(+)\n\ndiff --git a/dir.c b/dir.c\nindex ffc0286..3b83cc0 100644\n--- a/dir.c\n+++ b/dir.c\n@@ -1954,6 +1954,7 @@ void add_untracked_cache(void)\n \n void remove_untracked_cache(void)\n {\n+\tfree_untracked_cache(the_index.untracked);\n \tthe_index.untracked = NULL;\n \tthe_index.cache_changed |= UNTRACKED_CHANGED;\n }\n-- \n2.6.3.479.g8eb29d4\n"},{"id":"274504","messageId":"1450196907-17805-9-git-send-email-chriscool@tuxfamily.org","threadId":"41006","inReplyTo":"1450196907-17805-1-git-send-email-chriscool@tuxfamily.org","subject":"[PATCH v2 08/10] config: add core.untrackedCache","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2015-12-15T16:28:25Z","receivedAt":"2015-12-15T16:28:25Z","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,\nthen we might want 'git update-index --untracked-cache' to fail\nimmediately instead of performing tests (because it might work on\nsome systems using the repo over the network file system but not\nothers).\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\nTo keep things simple, this variable is a bool which default to\nfalse.\n\nWhen \"git status\" is run, it now adds or removes the untracked\ncache in the index to respect the value of this variable.\n\nThe job of `git update-index --[no-|force-]untracked-cache` was\nto add or remove the untracked cache from the index. This was a\nkind of configuration because this was persistant across git\ncommands. To make this kind of configuration compatible with the\nnew config variable, the simple thing to do, and what this patch\ndoes, is to make `git update-index --[no-|force-]untracked-cache`\nset or unset this config option.\n\nThis new behavior is a backward incompatible change, but that is\ndeliberate. The untracked cache feature has been experimental\nand is very unlikely used by beginners.\n\nWhen people will upgrade, this will remove any untracked cache\nthey used unless they set \"core.untrackedCache\" before upgrading.\nThis should be stated in the release notes.\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\nAll the changes to `--[no-|force-]untracked-cache` make it\npossible to deprecate those options in the future.\n\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Documentation/config.txt               |  7 ++++\n Documentation/git-update-index.txt     | 58 +++++++++++++++++++++++++++-------\n builtin/update-index.c                 | 25 ++++++++-------\n cache.h                                |  1 +\n config.c                               |  4 +++\n contrib/completion/git-completion.bash |  1 +\n dir.c                                  |  2 +-\n environment.c                          |  1 +\n t/t7063-status-untracked-cache.sh      |  4 +--\n wt-status.c                            |  9 ++++++\n 10 files changed, 85 insertions(+), 27 deletions(-)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex 2d06b11..94820eb 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -308,6 +308,13 @@ core.trustctime::\n \tcrawlers and some backup systems).\n \tSee linkgit:git-update-index[1]. True by default.\n \n+core.untrackedCache::\n+\tDetermines if untracked cache will be enabled. Using\n+\t'git update-index --[no-|force-]untracked-cache' will set\n+\tthis variable. Before setting it to true, you should check\n+\tthat mtime is working properly on your system.\n+\tSee linkgit:git-update-index[1]. False 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 0ff7396..cd02de4 100644\n--- a/Documentation/git-update-index.txt\n+++ b/Documentation/git-update-index.txt\n@@ -173,24 +173,29 @@ 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 extension. Please use\n+\t`--test-untracked-cache` before enabling it.\n++\n+These options are mostly aliases for setting the `core.untrackedCache`\n+configuration variable to 'true' or 'false' in the local config file\n+(see linkgit:git-config[1]). You can equivalently just set those\n+configuration values directly. These options are just provided for\n+backwards compatibility with the older versions of Git where this was\n+the only way to enable or disable the untracked cache extension.\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.\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.\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@@ -381,6 +386,33 @@ 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+It is recommended to use the `core.untrackedCache` configuration\n+variable (see linkgit:git-config[1]) to enable or disable this feature\n+instead of using the `--[no-|force-]untracked-cache` which are going\n+to set or unset this configuration variable anyway.\n+\n+When the `core.untrackedCache` configuration variable is changed, the\n+untracked cache is added or removed from the index the next time \"git\n+status\" is run, while when `--[no-|force-]untracked-cache` are used,\n+the untracked cache is immediately added to the index.\n \n Configuration\n -------------\n@@ -406,6 +438,8 @@ 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 is enabled by the `core.untrackedCache`\n+configuration variable (see linkgit:git-config[1]).\n \n SEE ALSO\n --------\ndiff --git a/builtin/update-index.c b/builtin/update-index.c\nindex 4ca6d94..98e3bac 100644\n--- a/builtin/update-index.c\n+++ b/builtin/update-index.c\n@@ -1115,21 +1115,24 @@ 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_TEST) {\n+\t\tsetup_work_tree();\n+\t\treturn !test_if_untracked_cache_is_supported();\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\tif (!use_untracked_cache && git_config_set(\"core.untrackedCache\", \"true\"))\n+\t\t\tdie(\"could not set core.untrackedCache to true\");\n \t\tadd_untracked_cache();\n \t\tif (verbose)\n \t\t\tprintf(_(\"Untracked cache enabled\\n\"));\n-\t} else if (untracked_cache == UC_DISABLE && the_index.untracked) {\n-\t\tremove_untracked_cache();\n-\t\tif (verbose)\n-\t\t\tprintf(_(\"Untracked cache disabled\\n\"));\n+\t} else if (untracked_cache == UC_DISABLE) {\n+\t\tif (use_untracked_cache > 0 && git_config_set(\"core.untrackedCache\", \"false\"))\n+\t\t\tdie(\"could not set core.untrackedCache to false\");\n+\t\tif (the_index.untracked) {\n+\t\t\tremove_untracked_cache();\n+\t\t\tif (verbose)\n+\t\t\t\tprintf(_(\"Untracked cache disabled\\n\"));\n+\t\t}\n \t}\n \n \tif (active_cache_changed) {\ndiff --git a/cache.h b/cache.h\nindex 2a9e902..0cc2c2f 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -619,6 +619,7 @@ extern void set_alternate_index_output(const char *);\n /* Environment bits from configuration mechanism */\n extern int trust_executable_bit;\n extern int trust_ctime;\n+extern int use_untracked_cache;\n extern int check_stat;\n extern int quote_path_fully;\n extern int has_symlinks;\ndiff --git a/config.c b/config.c\nindex 248a21a..f023ee7 100644\n--- a/config.c\n+++ b/config.c\n@@ -691,6 +691,10 @@ static int git_default_core_config(const char *var, const char *value)\n \t\ttrust_ctime = git_config_bool(var, value);\n \t\treturn 0;\n \t}\n+\tif (!strcmp(var, \"core.untrackedcache\")) {\n+\t\tuse_untracked_cache = git_config_bool(var, value);\n+\t\treturn 0;\n+\t}\n \tif (!strcmp(var, \"core.checkstat\")) {\n \t\tif (!strcasecmp(value, \"default\"))\n \t\t\tcheck_stat = 1;\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 111b053..b7e5736 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -2054,6 +2054,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/dir.c b/dir.c\nindex 3b83cc0..0b07ba7 100644\n--- a/dir.c\n+++ b/dir.c\n@@ -2015,7 +2015,7 @@ static struct untracked_cache_dir *validate_untracked_cache(struct dir_struct *d\n \tif (dir->exclude_list_group[EXC_CMDL].nr)\n \t\treturn NULL;\n \n-\tif (!ident_in_untracked(dir->untracked)) {\n+\tif (use_untracked_cache != 1 && !ident_in_untracked(dir->untracked)) {\n \t\twarning(_(\"Untracked cache is disabled on this system.\"));\n \t\treturn NULL;\n \t}\ndiff --git a/environment.c b/environment.c\nindex 2da7fe2..9ca71b1 100644\n--- a/environment.c\n+++ b/environment.c\n@@ -14,6 +14,7 @@\n \n int trust_executable_bit = 1;\n int trust_ctime = 1;\n+int use_untracked_cache;\n int check_stat = 1;\n int has_symlinks = 1;\n int minimum_abbrev = 4, default_abbrev = 7;\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 \ndiff --git a/wt-status.c b/wt-status.c\nindex 435fc28..3e0fe02 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -586,6 +586,15 @@ static void wt_status_collect_untracked(struct wt_status *s)\n \t\tdir.flags |= DIR_SHOW_IGNORED_TOO;\n \telse\n \t\tdir.untracked = the_index.untracked;\n+\n+\tif (!dir.untracked && use_untracked_cache == 1) {\n+\t\tadd_untracked_cache();\n+\t\tdir.untracked = the_index.untracked;\n+\t} else if (dir.untracked && use_untracked_cache == 0) {\n+\t\tremove_untracked_cache();\n+\t\tdir.untracked = NULL;\n+\t}\n+\n \tsetup_standard_excludes(&dir);\n \n \tfill_directory(&dir, &s->pathspec);\n-- \n2.6.3.479.g8eb29d4\n"},{"id":"274505","messageId":"1450196907-17805-10-git-send-email-chriscool@tuxfamily.org","threadId":"41006","inReplyTo":"1450196907-17805-1-git-send-email-chriscool@tuxfamily.org","subject":"[PATCH v2 09/10] t7063: add tests for core.untrackedCache","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2015-12-15T16:28:26Z","receivedAt":"2015-12-15T16:28:26Z","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 | 48 +++++++++++++++++++++++++++++++++++++--\n 1 file changed, 46 insertions(+), 2 deletions(-)\n\ndiff --git a/t/t7063-status-untracked-cache.sh b/t/t7063-status-untracked-cache.sh\nindex 253160a..f0af41c 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@@ -28,6 +32,11 @@ test_expect_success 'setup' '\n \tgit update-index --untracked-cache\n '\n \n+test_expect_success 'core.untrackedCache is true' '\n+\tUC=$(git config core.untrackedCache) &&\n+\ttest \"$UC\" = \"true\"\n+'\n+\n test_expect_success 'untracked cache is empty' '\n \ttest-dump-untracked-cache >../actual &&\n \tcat >../expect <<EOF &&\n@@ -506,7 +515,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 +534,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 +578,39 @@ 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+\tUC=$(git config core.untrackedCache) &&\n+\ttest \"$UC\" = \"false\" &&\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+\tUC=$(git config core.untrackedCache) &&\n+\ttest \"$UC\" = \"false\"\n+'\n+\n+test_expect_success 'setting core.untrackedCache 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 'unsetting core.untrackedCache and using git status removes the cache' '\n+\tgit config --unset core.untrackedCache &&\n+\ttest-dump-untracked-cache >../actual &&\n+\ttest_cmp ../expect-from-test-dump ../actual &&\n+\tgit status &&\n+\ttest-dump-untracked-cache >../actual &&\n+\ttest_cmp ../expect ../actual\n+'\n+\n test_done\n-- \n2.6.3.479.g8eb29d4\n"},{"id":"274506","messageId":"1450196907-17805-11-git-send-email-chriscool@tuxfamily.org","threadId":"41006","inReplyTo":"1450196907-17805-1-git-send-email-chriscool@tuxfamily.org","subject":"[PATCH v2 10/10] dir: do not use untracked cache ident anymore","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2015-12-15T16:28:27Z","receivedAt":"2015-12-15T16:28:27Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"A previous commit disabled the check to see if the untracked cache\nident field was matching the current environment. So this field is\nnow useless and we can remove some related code.\n\nWe don't remove the ident field from \"struct untracked_cache\" as\nit would break compatibility with old indexes that already have an\nuntracked cache with this field.\n\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n dir.c | 38 +++++---------------------------------\n dir.h |  2 +-\n 2 files changed, 6 insertions(+), 34 deletions(-)\n\ndiff --git a/dir.c b/dir.c\nindex 0b07ba7..94fba2a 100644\n--- a/dir.c\n+++ b/dir.c\n@@ -1904,36 +1904,13 @@ static int treat_leading_path(struct dir_struct *dir,\n \treturn rc;\n }\n \n-static const char *get_ident_string(void)\n-{\n-\tstatic struct strbuf sb = STRBUF_INIT;\n-\tstruct utsname uts;\n-\n-\tif (sb.len)\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-\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-\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-}\n-\n+/*\n+ * We used to save the location of the work tree and the kernel version,\n+ * but it was not a good idea, so we now just save an empty string.\n+ */\n void add_untracked_ident(struct untracked_cache *uc)\n {\n-\tif (ident_in_untracked(uc))\n-\t\treturn;\n-\tstrbuf_addstr(&uc->ident, get_ident_string());\n+\tstrbuf_addstr(&uc->ident, \"\");\n \t/* this strbuf contains a list of strings, save NUL too */\n \tstrbuf_addch(&uc->ident, 0);\n }\n@@ -2015,11 +1992,6 @@ static struct untracked_cache_dir *validate_untracked_cache(struct dir_struct *d\n \tif (dir->exclude_list_group[EXC_CMDL].nr)\n \t\treturn NULL;\n \n-\tif (use_untracked_cache != 1 && !ident_in_untracked(dir->untracked)) {\n-\t\twarning(_(\"Untracked cache is disabled on this system.\"));\n-\t\treturn NULL;\n-\t}\n-\n \tif (!dir->untracked->root) {\n \t\tconst int len = sizeof(*dir->untracked->root);\n \t\tdir->untracked->root = xmalloc(len);\ndiff --git a/dir.h b/dir.h\nindex 3e5114d..1935b76 100644\n--- a/dir.h\n+++ b/dir.h\n@@ -127,7 +127,7 @@ struct untracked_cache {\n \tstruct sha1_stat ss_info_exclude;\n \tstruct sha1_stat ss_excludes_file;\n \tconst char *exclude_per_dir;\n-\tstruct strbuf ident;\n+\tstruct strbuf ident; /* unused now */\n \t/*\n \t * dir_struct#flags must match dir_flags or the untracked\n \t * cache is ignored.\n-- \n2.6.3.479.g8eb29d4\n"},{"id":"274509","messageId":"xmqqlh8vfs6v.fsf@gitster.mtv.corp.google.com","threadId":"41006","inReplyTo":"1450196907-17805-8-git-send-email-chriscool@tuxfamily.org","subject":"Re: [PATCH v2 07/10] dir: free untracked cache when removing it","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-12-15T19:05:44Z","receivedAt":"2015-12-15T19:05:44Z","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> Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n> ---\n>  dir.c | 1 +\n>  1 file changed, 1 insertion(+)\n>\n> diff --git a/dir.c b/dir.c\n> index ffc0286..3b83cc0 100644\n> --- a/dir.c\n> +++ b/dir.c\n> @@ -1954,6 +1954,7 @@ void add_untracked_cache(void)\n>  \n>  void remove_untracked_cache(void)\n>  {\n> +\tfree_untracked_cache(the_index.untracked);\n>  \tthe_index.untracked = NULL;\n>  \tthe_index.cache_changed |= UNTRACKED_CHANGED;\n>  }\n\nUp to this point the series makes sense (again, I am not saying the\nremainder does not ;-)).  But shouldn't this step, as a bugfix,\nappear a lot earlier in the series?\n"},{"id":"274511","messageId":"xmqqd1u7fq5r.fsf@gitster.mtv.corp.google.com","threadId":"41006","inReplyTo":"1450196907-17805-11-git-send-email-chriscool@tuxfamily.org","subject":"Re: [PATCH v2 10/10] dir: do not use untracked cache ident anymore","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-12-15T19:49:36Z","receivedAt":"2015-12-15T19:49:36Z","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> +/*\n> + * We used to save the location of the work tree and the kernel version,\n> + * but it was not a good idea, so we now just save an empty string.\n> + */\n\nI do agree that storing the kernel version (or hostname or whatever\nspecific to the machine) was not a good idea.  I however suspect\nthat you must save and check the location of the working tree,\nthough, for correctness.  If you use one GIT_DIR and GIT_WORK_TREE\nto do \"git add\" or whatever, and then use the same GIT_DIR but a\ndifferent GIT_WORK_TREE, you should be able to notice that a\ndirectory D in the old GIT_WORK_TREE whose modification time you\nrecorded is different from the directory D with the same name but in\nthe new GIT_WORK_TREE, no?\n"},{"id":"274664","messageId":"5672A537.2060408@web.de","threadId":"41006","inReplyTo":"1450196907-17805-2-git-send-email-chriscool@tuxfamily.org","subject":"Re: [PATCH v2 01/10] update-index: use enum for untracked cache options","fromName":"Torsten Bögershausen","fromEmail":"tboegi@web.de","sentAt":"2015-12-17T12:06:15Z","receivedAt":"2015-12-17T12:06:15Z","isPatch":true,"sender":{"key":"tboegi@web.de","avatar":"https://avatars.githubusercontent.com/u/7138363?v=4"},"body":"On 15.12.15 17:28, Christian Couder wrote:\n> Signed-off-by: Christian Couder <chriscool@tuxfamily.org>\n> ---\n>  builtin/update-index.c | 18 +++++++++++++-----\n>  1 file changed, 13 insertions(+), 5 deletions(-)\n> \n> diff --git a/builtin/update-index.c b/builtin/update-index.c\n> index 7431938..2430a68 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) {\nI think the \"correct way\" for a comparison between an enum and an int is to cast the enum\ninto an int.\nBut, if we have an enum, these kind of comparision should go away, and replaced\nwith a switch-case (or if) statemant.\n>  \t\tstruct untracked_cache *uc;\n>  \n> -\t\tif (untracked_cache < 2) {\n> +\t\tif (untracked_cache < UC_FORCE) {\n\nSame here\n"},{"id":"274673","messageId":"CAP8UFD0Y252vmqxziy4Y8Bp3cw6fS0iOVFzZG+=wGt7K25V8Yg@mail.gmail.com","threadId":"41006","inReplyTo":"xmqqd1u7fq5r.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH v2 10/10] dir: do not use untracked cache ident anymore","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2015-12-17T16:54:34Z","receivedAt":"2015-12-17T16:54:34Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"On Tue, Dec 15, 2015 at 8:49 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Christian Couder <christian.couder@gmail.com> writes:\n>\n>> +/*\n>> + * We used to save the location of the work tree and the kernel version,\n>> + * but it was not a good idea, so we now just save an empty string.\n>> + */\n>\n> I do agree that storing the kernel version (or hostname or whatever\n> specific to the machine) was not a good idea.  I however suspect\n> that you must save and check the location of the working tree,\n> though, for correctness.  If you use one GIT_DIR and GIT_WORK_TREE\n> to do \"git add\" or whatever, and then use the same GIT_DIR but a\n> different GIT_WORK_TREE, you should be able to notice that a\n> directory D in the old GIT_WORK_TREE whose modification time you\n> recorded is different from the directory D with the same name but in\n> the new GIT_WORK_TREE, no?\n\nYeah, if people use many worktrees made using \"git worktree\", the code\nabove should be fine because there is one index per worktree, but if\nthey just use one GIT_DIR with many GIT_WORK_TREE then there will be\nonly one index used.\n\nI am wondering about the case when the worktree is moved and then\nGIT_WORK_TREE is changed to reflect the new path were the worktree has\nbeen moved.\n\nIn the \"git worktree\" documentation there is:\n\n\"If you move a linked working tree to another file system, or within a\nfile system that does not support hard links, you need to run at least\none git command inside the linked working tree (e.g. git status) in\norder to update its administrative files in the repository so that\nthey do not get automatically pruned.\"\n\nIt looks like git can detect when a worktree created with \"git\nworktree\" has been moved and I wonder if it would be possible to\ndetect if the main worktree pointed to by GIT_WORK_TREE as moved.\n"},{"id":"274676","messageId":"1450375527.11927.3.camel@twopensource.com","threadId":"41006","inReplyTo":"1450196907-17805-3-git-send-email-chriscool@tuxfamily.org","subject":"Re: [PATCH v2 02/10] update-index: add --test-untracked-cache","fromName":"David Turner","fromEmail":"dturner@twopensource.com","sentAt":"2015-12-17T18:05:27Z","receivedAt":"2015-12-17T18:05:27Z","isPatch":true,"sender":{"key":"novalis@novalis.org","avatar":"https://avatars.githubusercontent.com/u/77003?v=4"},"body":"On Tue, 2015-12-15 at 17:28 +0100, Christian Couder wrote: \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.\n\nIt would be nice if this said how the result would be reported (by exit\ncode, it appears).\n"},{"id":"274680","messageId":"xmqq1talc4co.fsf@gitster.mtv.corp.google.com","threadId":"41006","inReplyTo":"CAP8UFD0Y252vmqxziy4Y8Bp3cw6fS0iOVFzZG+=wGt7K25V8Yg@mail.gmail.com","subject":"Re: [PATCH v2 10/10] dir: do not use untracked cache ident anymore","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-12-17T18:33:27Z","receivedAt":"2015-12-17T18:33:27Z","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> In the \"git worktree\" documentation there is:\n>\n> \"If you move a linked working tree to another file system, or within a\n> file system that does not support hard links, you need to run at least\n> one git command inside the linked working tree (e.g. git status) in\n> order to update its administrative files in the repository so that\n> they do not get automatically pruned.\"\n>\n> It looks like git can detect when a worktree created with \"git\n> worktree\" has been moved and I wonder if it would be possible to\n> detect if the main worktree pointed to by GIT_WORK_TREE as moved.\n\nAs I personally do not find \"moving a working tree\" a very\ncompelling use case, I'd be fine if cached information is not used\nwhen the actual worktree and the root of the cached untracked paths\nare different.\n\nIf you are going to change the in-index data of untracked cache\nanyway (like you attempted with 10/10 patch), I think a lot more\nsensible simplification may be to make the mechanism _always_ keep\ntrack of the worktree that is rooted one level above the index, and\nnot use the cache in all other cases.  That way, if you move the\nworking tree in its entirety (i.e. $foo/{Makefile,.git/,untracked}\nall move to $bar/. at the same time), the untracked cache data that\nwas in $foo/.git/index, which knew about $foo/untracked, will now\nknow about $bar/untracked when the index is moved to $bar/.git/index\nautomatically.\n"},{"id":"274717","messageId":"CAP8UFD2UzNW6ZsrrOjRO-+5BSpx6Ntz+7gk4FsnOZ74KbEiTJg@mail.gmail.com","threadId":"41006","inReplyTo":"xmqq1talc4co.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH v2 10/10] dir: do not use untracked cache ident anymore","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2015-12-18T08:32:03Z","receivedAt":"2015-12-18T08:32:03Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"On Thu, Dec 17, 2015 at 7:33 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Christian Couder <christian.couder@gmail.com> writes:\n>\n>> In the \"git worktree\" documentation there is:\n>>\n>> \"If you move a linked working tree to another file system, or within a\n>> file system that does not support hard links, you need to run at least\n>> one git command inside the linked working tree (e.g. git status) in\n>> order to update its administrative files in the repository so that\n>> they do not get automatically pruned.\"\n>>\n>> It looks like git can detect when a worktree created with \"git\n>> worktree\" has been moved and I wonder if it would be possible to\n>> detect if the main worktree pointed to by GIT_WORK_TREE as moved.\n>\n> As I personally do not find \"moving a working tree\" a very\n> compelling use case, I'd be fine if cached information is not used\n> when the actual worktree and the root of the cached untracked paths\n> are different.\n\nYeah, I could just discard and recreate the UC from scratch if the\nactual worktree and the root of the UC paths are different.\n\n> If you are going to change the in-index data of untracked cache\n> anyway (like you attempted with 10/10 patch), I think a lot more\n> sensible simplification may be to make the mechanism _always_ keep\n> track of the worktree that is rooted one level above the index, and\n> not use the cache in all other cases.  That way, if you move the\n> working tree in its entirety (i.e. $foo/{Makefile,.git/,untracked}\n> all move to $bar/. at the same time), the untracked cache data that\n> was in $foo/.git/index, which knew about $foo/untracked, will now\n> know about $bar/untracked when the index is moved to $bar/.git/index\n> automatically.\n\nI am ok with that, though I worry a bit about some people having a\nsetup where they always use a worktree that is not one level above the\n.git directory.\n"}]}