diff --git a/mercurial/cext/parsers.c b/mercurial/cext/parsers.c --- a/mercurial/cext/parsers.c +++ b/mercurial/cext/parsers.c @@ -420,6 +420,14 @@ dirstate_flag_has_meaningful_data | dirstate_flag_has_file_mtime); } + if (t->flags & dirstate_flag_mtime_second_ambiguous) { + /* The current code is not able to do the more subtle comparison + * that the MTIME_SECOND_AMBIGUOUS requires. So we ignore the + * mtime */ + t->flags &= ~(dirstate_flag_mtime_second_ambiguous | + dirstate_flag_has_meaningful_data | + dirstate_flag_has_file_mtime); + } t->mode = 0; if (t->flags & dirstate_flag_has_meaningful_data) { if (t->flags & dirstate_flag_mode_exec_perm) { diff --git a/mercurial/cext/util.h b/mercurial/cext/util.h --- a/mercurial/cext/util.h +++ b/mercurial/cext/util.h @@ -47,6 +47,7 @@ static const int dirstate_flag_has_fallback_exec = 1 << 12; static const int dirstate_flag_fallback_symlink = 1 << 13; static const int dirstate_flag_has_fallback_symlink = 1 << 14; +static const int dirstate_flag_mtime_second_ambiguous = 1 << 15; extern PyTypeObject dirstateItemType; #define dirstate_tuple_check(op) (Py_TYPE(op) == &dirstateItemType) diff --git a/mercurial/helptext/internals/dirstate-v2.txt b/mercurial/helptext/internals/dirstate-v2.txt --- a/mercurial/helptext/internals/dirstate-v2.txt +++ b/mercurial/helptext/internals/dirstate-v2.txt @@ -390,6 +390,7 @@ FALLBACK_EXEC = 1 << 12 HAS_FALLBACK_SYMLINK = 1 << 13 FALLBACK_SYMLINK = 1 << 14 + MTIME_SECOND_AMBIGUOUS = 1 << 15 The meaning of each bit is described below. @@ -592,3 +593,10 @@ this entry should be considered a symlink if that information cannot be extracted from the file system. If unset it should be considered a normal file instead. + +`MTIME_SECOND_AMBIGUOUS` + This flag is relevant only when `HAS_FILE_MTIME` is set. When set, the + `mtime` stored in the entry is only valid for comparison with timestamps + that have nanosecond information. If available timestamp does not carries + nanosecond information, the `mtime` should be ignored and no optimisation + can be applied. diff --git a/mercurial/pure/parsers.py b/mercurial/pure/parsers.py --- a/mercurial/pure/parsers.py +++ b/mercurial/pure/parsers.py @@ -60,6 +60,7 @@ DIRSTATE_V2_FALLBACK_EXEC = 1 << 12 DIRSTATE_V2_HAS_FALLBACK_SYMLINK = 1 << 13 DIRSTATE_V2_FALLBACK_SYMLINK = 1 << 14 +DIRSTATE_V2_MTIME_SECOND_AMBIGUOUS = 1 << 15 @attr.s(slots=True, init=False) @@ -140,6 +141,10 @@ """Build a new DirstateItem object from V2 data""" has_mode_size = bool(flags & DIRSTATE_V2_HAS_MODE_AND_SIZE) has_meaningful_mtime = bool(flags & DIRSTATE_V2_HAS_FILE_MTIME) + if flags & DIRSTATE_V2_MTIME_SECOND_AMBIGUOUS: + # The current code is not able to do the more subtle comparison that the + # MTIME_SECOND_AMBIGUOUS requires. So we ignore the mtime + has_meaningful_mtime = False mode = None if flags & +DIRSTATE_V2_EXPECTED_STATE_IS_MODIFIED: diff --git a/rust/hg-core/src/dirstate_tree/on_disk.rs b/rust/hg-core/src/dirstate_tree/on_disk.rs --- a/rust/hg-core/src/dirstate_tree/on_disk.rs +++ b/rust/hg-core/src/dirstate_tree/on_disk.rs @@ -117,6 +117,7 @@ const FALLBACK_EXEC = 1 << 12; const HAS_FALLBACK_SYMLINK = 1 << 13; const FALLBACK_SYMLINK = 1 << 14; + const MTIME_SECOND_AMBIGUOUS = 1 << 15; } } @@ -371,6 +372,9 @@ }; let mtime = if self.flags().contains(Flags::HAS_FILE_MTIME) && !self.flags().contains(Flags::EXPECTED_STATE_IS_MODIFIED) + // The current code is not able to do the more subtle comparison that the + // MTIME_SECOND_AMBIGUOUS requires. So we ignore the mtime + && !self.flags().contains(Flags::MTIME_SECOND_AMBIGUOUS) { // TODO: replace this by `self.mtime.try_into()?` to use // sub-second precision from the file.