summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--builtin/update-index.c11
-rw-r--r--cache.h1
-rw-r--r--read-cache.c2
-rwxr-xr-xt/t2108-update-index-refresh-racy.sh64
4 files changed, 77 insertions, 1 deletions
diff --git a/builtin/update-index.c b/builtin/update-index.c
index 187203e8bb..7e0a0d9bf8 100644
--- a/builtin/update-index.c
+++ b/builtin/update-index.c
@@ -787,6 +787,17 @@ static int refresh(struct refresh_params *o, unsigned int flag)
setup_work_tree();
read_cache();
*o->has_errors |= refresh_cache(o->flags | flag);
+ if (has_racy_timestamp(&the_index)) {
+ /*
+ * Even if nothing else has changed, updating the file
+ * increases the chance that racy timestamps become
+ * non-racy, helping future run-time performance.
+ * We do that even in case of "errors" returned by
+ * refresh_cache() as these are no actual errors.
+ * cmd_status() does the same.
+ */
+ active_cache_changed |= SOMETHING_CHANGED;
+ }
return 0;
}
diff --git a/cache.h b/cache.h
index cfba463aa9..dd1932e2d0 100644
--- a/cache.h
+++ b/cache.h
@@ -891,6 +891,7 @@ void *read_blob_data_from_index(struct index_state *, const char *, unsigned lon
#define CE_MATCH_IGNORE_FSMONITOR 0X20
int is_racy_timestamp(const struct index_state *istate,
const struct cache_entry *ce);
+int has_racy_timestamp(struct index_state *istate);
int ie_match_stat(struct index_state *, const struct cache_entry *, struct stat *, unsigned int);
int ie_modified(struct index_state *, const struct cache_entry *, struct stat *, unsigned int);
diff --git a/read-cache.c b/read-cache.c
index cbe73f14e5..ed297635a3 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -2775,7 +2775,7 @@ static int repo_verify_index(struct repository *repo)
return verify_index_from(repo->index, repo->index_file);
}
-static int has_racy_timestamp(struct index_state *istate)
+int has_racy_timestamp(struct index_state *istate)
{
int entries = istate->cache_nr;
int i;
diff --git a/t/t2108-update-index-refresh-racy.sh b/t/t2108-update-index-refresh-racy.sh
new file mode 100755
index 0000000000..bc5f2886fa
--- /dev/null
+++ b/t/t2108-update-index-refresh-racy.sh
@@ -0,0 +1,64 @@
+#!/bin/sh
+
+test_description='update-index refresh tests related to racy timestamps'
+
+TEST_PASSES_SANITIZE_LEAK=true
+. ./test-lib.sh
+
+reset_files () {
+ echo content >file &&
+ echo content >other &&
+ test_set_magic_mtime file &&
+ test_set_magic_mtime other
+}
+
+update_assert_changed () {
+ test_set_magic_mtime .git/index &&
+ test_might_fail git update-index "$1" &&
+ ! test_is_magic_mtime .git/index
+}
+
+test_expect_success 'setup' '
+ reset_files &&
+ # we are calling reset_files() a couple of times during tests;
+ # test-tool chmtime does not change the ctime; to not weaken
+ # or even break our tests, disable ctime-checks entirely
+ git config core.trustctime false &&
+ git add file other &&
+ git commit -m "initial import"
+'
+
+test_expect_success '--refresh has no racy timestamps to fix' '
+ reset_files &&
+ # set the index time far enough to the future;
+ # it must be at least 3 seconds for VFAT
+ test_set_magic_mtime .git/index +60 &&
+ git update-index --refresh &&
+ test_is_magic_mtime .git/index +60
+'
+
+test_expect_success '--refresh should fix racy timestamp' '
+ reset_files &&
+ update_assert_changed --refresh
+'
+
+test_expect_success '--really-refresh should fix racy timestamp' '
+ reset_files &&
+ update_assert_changed --really-refresh
+'
+
+test_expect_success '--refresh should fix racy timestamp if other file needs update' '
+ reset_files &&
+ echo content2 >other &&
+ test_set_magic_mtime other &&
+ update_assert_changed --refresh
+'
+
+test_expect_success '--refresh should fix racy timestamp if racy file needs update' '
+ reset_files &&
+ echo content2 >file &&
+ test_set_magic_mtime file &&
+ update_assert_changed --refresh
+'
+
+test_done