From 83c094ad0dd2104adbbec034f802dceb1d052981 Mon Sep 17 00:00:00 2001 From: Nguyễn Thái Ngọc Duy Date: Sun, 8 Mar 2015 17:12:33 +0700 Subject: untracked cache: save to an index extension MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Helped-by: Stefan Beller Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano --- cache.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'cache.h') diff --git a/cache.h b/cache.h index 761c5704b2..811cc36547 100644 --- a/cache.h +++ b/cache.h @@ -291,6 +291,8 @@ static inline unsigned int canon_mode(unsigned int mode) #define SPLIT_INDEX_ORDERED (1 << 6) struct split_index; +struct untracked_cache; + struct index_state { struct cache_entry **cache; unsigned int version; @@ -304,6 +306,7 @@ struct index_state { struct hashmap name_hash; struct hashmap dir_hash; unsigned char sha1[20]; + struct untracked_cache *untracked; }; extern struct index_state the_index; -- cgit v1.3 From ed4efab1b17e883b761b4482c40c04a4529be8f9 Mon Sep 17 00:00:00 2001 From: Nguyễn Thái Ngọc Duy Date: Sun, 8 Mar 2015 17:12:37 +0700 Subject: untracked cache: avoid racy timestamps MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Signed-off-by: Junio C Hamano --- cache.h | 2 ++ dir.c | 4 ++-- read-cache.c | 8 ++++++++ 3 files changed, 12 insertions(+), 2 deletions(-) (limited to 'cache.h') 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) -- cgit v1.3 From 1bbb3dba3fbf733db45f073ddafe89f5972c516a Mon Sep 17 00:00:00 2001 From: Nguyễn Thái Ngọc Duy Date: Sun, 8 Mar 2015 17:12:39 +0700 Subject: untracked cache: mark index dirty if untracked cache is updated MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano --- cache.h | 1 + dir.c | 9 +++++++++ read-cache.c | 2 +- 3 files changed, 11 insertions(+), 1 deletion(-) (limited to 'cache.h') diff --git a/cache.h b/cache.h index 120d337bd4..1392be1030 100644 --- a/cache.h +++ b/cache.h @@ -289,6 +289,7 @@ static inline unsigned int canon_mode(unsigned int mode) #define RESOLVE_UNDO_CHANGED (1 << 4) #define CACHE_TREE_CHANGED (1 << 5) #define SPLIT_INDEX_ORDERED (1 << 6) +#define UNTRACKED_CHANGED (1 << 7) struct split_index; struct untracked_cache; diff --git a/dir.c b/dir.c index 1cf1e3002e..592b5fa795 100644 --- a/dir.c +++ b/dir.c @@ -1934,6 +1934,15 @@ int read_directory(struct dir_struct *dir, const char *path, int len, const stru dir->untracked->gitignore_invalidated, dir->untracked->dir_invalidated, dir->untracked->dir_opened); + if (dir->untracked == the_index.untracked && + (dir->untracked->dir_opened || + dir->untracked->gitignore_invalidated || + dir->untracked->dir_invalidated)) + the_index.cache_changed |= UNTRACKED_CHANGED; + if (dir->untracked != the_index.untracked) { + free(dir->untracked); + dir->untracked = NULL; + } } return dir->nr; } diff --git a/read-cache.c b/read-cache.c index 57828bb3f3..705469eb7a 100644 --- a/read-cache.c +++ b/read-cache.c @@ -44,7 +44,7 @@ static struct cache_entry *refresh_cache_entry(struct cache_entry *ce, /* changes that can be kept in $GIT_DIR/index (basically all extensions) */ #define EXTMASK (RESOLVE_UNDO_CHANGED | CACHE_TREE_CHANGED | \ CE_ENTRY_ADDED | CE_ENTRY_REMOVED | CE_ENTRY_CHANGED | \ - SPLIT_INDEX_ORDERED) + SPLIT_INDEX_ORDERED | UNTRACKED_CHANGED) struct index_state the_index; static const char *alternate_index_output; -- cgit v1.3