diff options
-rw-r--r-- | cache.h | 2 | ||||
-rw-r--r-- | read-cache.c | 2 | ||||
-rw-r--r-- | split-index.c | 42 | ||||
-rwxr-xr-x | t/t1701-racy-split-index.sh | 8 |
4 files changed, 46 insertions, 8 deletions
@@ -781,6 +781,8 @@ extern void *read_blob_data_from_index(const struct index_state *, const char *, #define CE_MATCH_REFRESH 0x10 /* don't refresh_fsmonitor state or do stat comparison even if CE_FSMONITOR_VALID is true */ #define CE_MATCH_IGNORE_FSMONITOR 0X20 +extern int is_racy_timestamp(const struct index_state *istate, + const struct cache_entry *ce); extern int ie_match_stat(struct index_state *, const struct cache_entry *, struct stat *, unsigned int); extern 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 7b1354d..8f644f6 100644 --- a/read-cache.c +++ b/read-cache.c @@ -337,7 +337,7 @@ static int is_racy_stat(const struct index_state *istate, ); } -static int is_racy_timestamp(const struct index_state *istate, +int is_racy_timestamp(const struct index_state *istate, const struct cache_entry *ce) { return (!S_ISGITLINK(ce->ce_mode) && diff --git a/split-index.c b/split-index.c index 187b910..875f538 100644 --- a/split-index.c +++ b/split-index.c @@ -259,8 +259,39 @@ void prepare_to_write_split_index(struct index_state *istate) } ce->ce_flags |= CE_MATCHED; /* or "shared" */ base = si->base->cache[ce->index - 1]; - if (ce == base) + if (ce == base) { + /* The entry is present in the shared index. */ + if (ce->ce_flags & CE_UPDATE_IN_BASE) { + /* + * Already marked for inclusion in + * the split index, either because + * the corresponding file was + * modified and the cached stat data + * was refreshed, or because there + * is already a replacement entry in + * the split index. + * Nothing more to do here. + */ + } else if (!ce_uptodate(ce) && + is_racy_timestamp(istate, ce)) { + /* + * A racily clean cache entry stored + * only in the shared index: it must + * be added to the split index, so + * the subsequent do_write_index() + * can smudge its stat data. + */ + ce->ce_flags |= CE_UPDATE_IN_BASE; + } else { + /* + * The entry is only present in the + * shared index and it was not + * refreshed. + * Just leave it there. + */ + } continue; + } if (ce->ce_namelen != base->ce_namelen || strcmp(ce->name, base->name)) { ce->index = 0; @@ -281,6 +312,15 @@ void prepare_to_write_split_index(struct index_state *istate) * the split index. * Nothing to do. */ + } else if (!ce_uptodate(ce) && + is_racy_timestamp(istate, ce)) { + /* + * A copy of a racily clean cache entry from + * the shared index. It must be added to + * the split index, so the subsequent + * do_write_index() can smudge its stat data. + */ + ce->ce_flags |= CE_UPDATE_IN_BASE; } else { /* * Thoroughly compare the cached data to see diff --git a/t/t1701-racy-split-index.sh b/t/t1701-racy-split-index.sh index fbb7704..5dc221e 100755 --- a/t/t1701-racy-split-index.sh +++ b/t/t1701-racy-split-index.sh @@ -148,7 +148,7 @@ done for trial in $trials do - test_expect_failure "update the split index when a racily clean cache entry is stored only in the shared index $trial" ' + test_expect_success "update the split index when a racily clean cache entry is stored only in the shared index #$trial" ' rm -f .git/index .git/sharedindex.* && # The next three commands must be run within the same @@ -170,8 +170,6 @@ do # entry of racy-file is only stored in the shared index. # A corresponding replacement cache entry with smudged # stat data should be added to the new split index. - # - # Alas, such a smudged replacement entry is not added! git update-index --add other-file && # Subsequent git commands should notice the smudged @@ -182,7 +180,7 @@ done for trial in $trials do - test_expect_failure "update the split index after unpack trees() copied a racily clean cache entry from the shared index $trial" ' + test_expect_success "update the split index after unpack trees() copied a racily clean cache entry from the shared index #$trial" ' rm -f .git/index .git/sharedindex.* && # The next three commands must be run within the same @@ -205,8 +203,6 @@ do # index. A corresponding replacement cache entry # with smudged stat data should be added to the new # split index. - # - # Alas, such a smudged replacement entry is not added! git read-tree -m HEAD && # Subsequent git commands should notice the smudged |