diff options
-rw-r--r-- | builtin/update-index.c | 11 | ||||
-rw-r--r-- | cache.h | 1 | ||||
-rw-r--r-- | read-cache.c | 2 | ||||
-rwxr-xr-x | t/t2108-update-index-refresh-racy.sh | 64 |
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; } @@ -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 |