diff options
author | Edward Thomson <ethomson@microsoft.com> | 2015-11-23 23:49:54 +0300 |
---|---|---|
committer | Edward Thomson <ethomson@microsoft.com> | 2015-11-23 23:49:54 +0300 |
commit | 25e84f959ae77f21c32849aa98f274b9d8283f2d (patch) | |
tree | bc26699de31496ffdb1f3afa14e9bee35836915d | |
parent | 66e4e6da594653c461c4344e23738bad153320a1 (diff) |
checkout: only consider nsecs when built that way
When examining the working directory and determining whether it's
up-to-date, only consider the nanoseconds in the index entry when
built with `GIT_USE_NSEC`. This prevents us from believing that
the working directory is always dirty when the index was originally
written with a git client that uinderstands nsecs (like git 2.x).
-rw-r--r-- | src/checkout.c | 3 | ||||
-rw-r--r-- | src/diff.c | 49 | ||||
-rw-r--r-- | src/diff.h | 1 | ||||
-rw-r--r-- | src/index.c | 20 | ||||
-rw-r--r-- | src/index.h | 39 |
5 files changed, 46 insertions, 66 deletions
diff --git a/src/checkout.c b/src/checkout.c index d09357f2a..a92ad0825 100644 --- a/src/checkout.c +++ b/src/checkout.c @@ -200,8 +200,7 @@ static bool checkout_is_workdir_modified( * out.) */ if ((ie = git_index_get_bypath(data->index, wditem->path, 0)) != NULL) { - if (wditem->mtime.seconds == ie->mtime.seconds && - wditem->mtime.nanoseconds == ie->mtime.nanoseconds && + if (git_index_time_eq(&wditem->mtime, &ie->mtime) && wditem->file_size == ie->file_size) return !is_workdir_base_or_new(&ie->id, baseitem, newitem); } diff --git a/src/diff.c b/src/diff.c index 0ab3b8d1f..9402b6e61 100644 --- a/src/diff.c +++ b/src/diff.c @@ -494,11 +494,6 @@ static int diff_list_apply_options( /* Don't set GIT_DIFFCAPS_USE_DEV - compile time option in core git */ - /* Don't trust nanoseconds; we do not load nanos from disk */ -#ifdef GIT_USE_NSEC - diff->diffcaps = diff->diffcaps | GIT_DIFFCAPS_TRUST_NANOSECS; -#endif - /* If not given explicit `opts`, check `diff.xyz` configs */ if (!opts) { int context = git_config__get_int_force(cfg, "diff.context", 3); @@ -699,38 +694,6 @@ int git_diff__oid_for_entry( return error; } -static bool diff_time_eq( - const git_index_time *a, const git_index_time *b, bool use_nanos) -{ - return a->seconds == b->seconds && - (!use_nanos || a->nanoseconds == b->nanoseconds); -} - -/* - * Test if the given index time is newer than the given existing index entry. - * If the timestamps are exactly equivalent, then the given index time is - * considered "racily newer" than the existing index entry. - */ -static bool diff_newer_than_index( - const git_index_time *a, const git_index *b, bool use_nanos) -{ - bool is_newer = false; - - if(!b) - return false; - - is_newer = is_newer || (a->seconds > (int32_t) b->stamp.mtime.tv_sec); - is_newer = is_newer || (!use_nanos && - (a->seconds == (int32_t) b->stamp.mtime.tv_sec)); - if(use_nanos) - { - is_newer = is_newer || ((a->seconds == (int32_t) b->stamp.mtime.tv_sec) && - (a->nanoseconds >= (uint32_t) b->stamp.mtime.tv_nsec)); - } - - return is_newer; -} - typedef struct { git_repository *repo; git_iterator *old_iter; @@ -863,11 +826,6 @@ static int maybe_modified( */ } else if (git_oid_iszero(&nitem->id) && new_is_workdir) { bool use_ctime = ((diff->diffcaps & GIT_DIFFCAPS_TRUST_CTIME) != 0); -#ifdef GIT_USE_NSEC - bool use_nanos = ((diff->diffcaps & GIT_DIFFCAPS_TRUST_NANOSECS) != 0); -#else - bool use_nanos = false; -#endif git_index *index; git_iterator_index(&index, info->new_iter); @@ -886,13 +844,12 @@ static int maybe_modified( modified_uncertain = (oitem->file_size <= 0 && nitem->file_size > 0); } - else if (!diff_time_eq(&oitem->mtime, &nitem->mtime, use_nanos) || - (use_ctime && - !diff_time_eq(&oitem->ctime, &nitem->ctime, use_nanos)) || + else if (!git_index_time_eq(&oitem->mtime, &nitem->mtime) || + (use_ctime && !git_index_time_eq(&oitem->ctime, &nitem->ctime)) || oitem->ino != nitem->ino || oitem->uid != nitem->uid || oitem->gid != nitem->gid || - diff_newer_than_index(&nitem->mtime, index, use_nanos)) + git_index_entry_newer_than_index(nitem, index)) { status = GIT_DELTA_MODIFIED; modified_uncertain = true; diff --git a/src/diff.h b/src/diff.h index 2dfc2c615..47743f88b 100644 --- a/src/diff.h +++ b/src/diff.h @@ -28,7 +28,6 @@ enum { GIT_DIFFCAPS_TRUST_MODE_BITS = (1 << 2), /* use st_mode? */ GIT_DIFFCAPS_TRUST_CTIME = (1 << 3), /* use st_ctime? */ GIT_DIFFCAPS_USE_DEV = (1 << 4), /* use st_dev? */ - GIT_DIFFCAPS_TRUST_NANOSECS = (1 << 5), /* use stat time nanoseconds */ }; #define DIFF_FLAGS_KNOWN_BINARY (GIT_DIFF_FLAG_BINARY|GIT_DIFF_FLAG_NOT_BINARY) diff --git a/src/index.c b/src/index.c index bce16348c..ca5b2c46e 100644 --- a/src/index.c +++ b/src/index.c @@ -720,27 +720,13 @@ int git_index__changed_relative_to( return !!git_oid_cmp(&index->checksum, checksum); } -static bool is_racy_timestamp(const struct timespec *stamp, git_index_entry *entry) +static bool is_racy_entry(git_index *index, const git_index_entry *entry) { /* Git special-cases submodules in the check */ if (S_ISGITLINK(entry->mode)) return false; - /* If we never read the index, we can't have this race either */ - if(stamp->tv_sec == 0) - return false; - - /* If the timestamp is the same or newer than the index, it's racy */ -#if defined(GIT_USE_NSEC) - if((int32_t) stamp->tv_sec < entry->mtime.seconds) - return true; - else if((int32_t) stamp->tv_sec > entry->mtime.seconds) - return false; - else - return (uint32_t) stamp->tv_nsec <= entry->mtime.nanoseconds; -#else - return ((int32_t) stamp->tv_sec) <= entry->mtime.seconds; -#endif + return git_index_entry_newer_than_index(entry, index); } /* @@ -768,7 +754,7 @@ static int truncate_racily_clean(git_index *index) diff_opts.flags |= GIT_DIFF_INCLUDE_TYPECHANGE | GIT_DIFF_IGNORE_SUBMODULES | GIT_DIFF_DISABLE_PATHSPEC_MATCH; git_vector_foreach(&index->entries, i, entry) { if ((entry->flags_extended & GIT_IDXENTRY_UPTODATE) == 0 && - is_racy_timestamp(&index->stamp.mtime, entry)) + is_racy_entry(index, entry)) git_vector_insert(&paths, (char *)entry->path); } diff --git a/src/index.h b/src/index.h index 546e677be..9baf976ee 100644 --- a/src/index.h +++ b/src/index.h @@ -65,6 +65,45 @@ extern int git_index_entry_icmp(const void *a, const void *b); extern int git_index_entry_srch(const void *a, const void *b); extern int git_index_entry_isrch(const void *a, const void *b); +/* Index time handling functions */ +GIT_INLINE(bool) git_index_time_eq(const git_index_time *one, const git_index_time *two) +{ + if (one->seconds != two->seconds) + return false; + +#ifdef GIT_USE_NSEC + if (one->nanoseconds != two->nanoseconds) + return false; +#endif + + return true; +} + +/* + * Test if the given index time is newer than the given existing index entry. + * If the timestamps are exactly equivalent, then the given index time is + * considered "racily newer" than the existing index entry. + */ +GIT_INLINE(bool) git_index_entry_newer_than_index( + const git_index_entry *entry, git_index *index) +{ + /* If we never read the index, we can't have this race either */ + if (!index || index->stamp.mtime.tv_sec == 0) + return false; + + /* If the timestamp is the same or newer than the index, it's racy */ +#if defined(GIT_USE_NSEC) + if ((int32_t)index->stamp.tv_sec < entry->mtime.seconds) + return true; + else if ((int32_t)index->stamp.mtime.tv_sec > entry->mtime.seconds) + return false; + else + return (uint32_t)index->stamp.mtime.tv_nsec <= entry->mtime.nanoseconds; +#else + return ((int32_t)index->stamp.mtime.tv_sec) <= entry->mtime.seconds; +#endif +} + /* Search index for `path`, returning GIT_ENOTFOUND if it does not exist * (but not setting an error message). * |