summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNguyễn Thái Ngọc Duy <pclouds@gmail.com>2015-03-08 17:12:37 +0700
committerJunio C Hamano <gitster@pobox.com>2015-03-12 13:45:17 -0700
commited4efab1b17e883b761b4482c40c04a4529be8f9 (patch)
treeb5f43046f55053b9d8e4396e0d88b60395f9b244
parent2bb4cda1987afe6911a1c193283213babda328d2 (diff)
downloadgit-ed4efab1b17e883b761b4482c40c04a4529be8f9.tar.gz
untracked cache: avoid racy timestamps
When a directory is updated within the same second that its timestamp is last saved, we cannot realize the directory has been updated by checking timestamps. Assume the worst (something is update). See 29e4d36 (Racy GIT - 2005-12-20) for more information. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--cache.h2
-rw-r--r--dir.c4
-rw-r--r--read-cache.c8
3 files changed, 12 insertions, 2 deletions
diff --git a/cache.h b/cache.h
index 811cc36547..120d337bd4 100644
--- a/cache.h
+++ b/cache.h
@@ -555,6 +555,8 @@ extern void fill_stat_data(struct stat_data *sd, struct stat *st);
* INODE_CHANGED, and DATA_CHANGED.
*/
extern int match_stat_data(const struct stat_data *sd, struct stat *st);
+extern int match_stat_data_racy(const struct index_state *istate,
+ const struct stat_data *sd, struct stat *st);
extern void fill_stat_cache_info(struct cache_entry *ce, struct stat *st);
diff --git a/dir.c b/dir.c
index 68b46d0acb..741484aa97 100644
--- a/dir.c
+++ b/dir.c
@@ -682,7 +682,7 @@ static int add_excludes(const char *fname, const char *base, int baselen,
if (sha1_stat) {
int pos;
if (sha1_stat->valid &&
- !match_stat_data(&sha1_stat->stat, &st))
+ !match_stat_data_racy(&the_index, &sha1_stat->stat, &st))
; /* no content change, ss->sha1 still good */
else if (check_index &&
(pos = cache_name_pos(fname, strlen(fname))) >= 0 &&
@@ -1539,7 +1539,7 @@ static int valid_cached_dir(struct dir_struct *dir,
return 0;
}
if (!untracked->valid ||
- match_stat_data(&untracked->stat_data, &st)) {
+ match_stat_data_racy(&the_index, &untracked->stat_data, &st)) {
if (untracked->valid)
invalidate_directory(dir->untracked, untracked);
fill_stat_data(&untracked->stat_data, &st);
diff --git a/read-cache.c b/read-cache.c
index b5e9c3f8ac..57828bb3f3 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -294,6 +294,14 @@ static int is_racy_timestamp(const struct index_state *istate,
is_racy_stat(istate, &ce->ce_stat_data));
}
+int match_stat_data_racy(const struct index_state *istate,
+ const struct stat_data *sd, struct stat *st)
+{
+ if (is_racy_stat(istate, sd))
+ return MTIME_CHANGED;
+ return match_stat_data(sd, st);
+}
+
int ie_match_stat(const struct index_state *istate,
const struct cache_entry *ce, struct stat *st,
unsigned int options)