untracked cache: avoid racy timestamps
authorNguyễn Thái Ngọc Duy <pclouds@gmail.com>
Sun, 8 Mar 2015 10:12:37 +0000 (17:12 +0700)
committerJunio C Hamano <gitster@pobox.com>
Thu, 12 Mar 2015 20:45:17 +0000 (13:45 -0700)
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>
cache.h
dir.c
read-cache.c
diff --git a/cache.h b/cache.h
index 811cc36547aa5b2b036f56e7d4a2c6dd100e913d..120d337bd452a97cc6f70f6ae14ca0a6026945bb 100644 (file)
--- 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 68b46d0acb53f85398171a97b664d7ccfcfe4bbd..741484aa975348e71cb908a1ed775b53ace90512 100644 (file)
--- 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);
index b5e9c3f8acb58f26ad4f08874585e1684caf2077..57828bb3f3a4da75e7ce23346e8c9acede869068 100644 (file)
@@ -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)