Patchwork D7300: rust-status: refactor dispatch case for normal files

login
register
mail settings
Submitter phabricator
Date Nov. 11, 2019, 9:09 p.m.
Message ID <6aa639139f75cbf8b05d877ea2c9d73b@localhost.localdomain>
Download mbox | patch
Permalink /patch/43123/
State Not Applicable
Headers show

Comments

phabricator - Nov. 11, 2019, 9:09 p.m.
Closed by commit rHG51cd86735608: rust-status: refactor dispatch case for normal files (authored by Alphare).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7300?vs=17741&id=18019

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7300/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7300

AFFECTED FILES
  rust/hg-core/src/dirstate/status.rs

CHANGE DETAILS




To: Alphare, #hg-reviewers, kevincox
Cc: durin42, kevincox, mercurial-devel

Patch

diff --git a/rust/hg-core/src/dirstate/status.rs b/rust/hg-core/src/dirstate/status.rs
--- a/rust/hg-core/src/dirstate/status.rs
+++ b/rust/hg-core/src/dirstate/status.rs
@@ -28,6 +28,17 @@ 
     Unknown,
 }
 
+/// Dates and times that are outside the 31-bit signed range are compared
+/// modulo 2^31. This should prevent hg from behaving badly with very large
+/// files or corrupt dates while still having a high probability of detecting
+/// changes. (issue2608)
+/// TODO I haven't found a way of having `b` be `Into<i32>`, since `From<u64>`
+/// is not defined for `i32`, and there is no `As` trait. This forces the
+/// caller to cast `b` as `i32`.
+fn mod_compare(a: i32, b: i32) -> bool {
+    a & i32::max_value() != b & i32::max_value()
+}
+
 /// The file corresponding to the dirstate entry was found on the filesystem.
 fn dispatch_found(
     filename: impl AsRef<HgPath>,
@@ -54,26 +65,17 @@ 
 
     match state {
         EntryState::Normal => {
-            // Dates and times that are outside the 31-bit signed
-            // range are compared modulo 2^31. This should prevent
-            // it from behaving badly with very large files or
-            // corrupt dates while still having a high probability
-            // of detecting changes. (issue2608)
-            let range_mask = 0x7fffffff;
-
-            let size_changed = (size != st_size as i32)
-                && size != (st_size as i32 & range_mask);
+            let size_changed = mod_compare(size, st_size as i32);
             let mode_changed =
                 (mode ^ st_mode as i32) & 0o100 != 0o000 && check_exec;
-            if size >= 0
-                            && (size_changed || mode_changed)
-                            || size == -2  // other parent
-                            || copy_map.contains_key(filename.as_ref())
+            let metadata_changed = size >= 0 && (size_changed || mode_changed);
+            let other_parent = size == -2;
+            if metadata_changed
+                || other_parent
+                || copy_map.contains_key(filename.as_ref())
             {
                 Dispatch::Modified
-            } else if mtime != st_mtime as i32
-                && mtime != (st_mtime as i32 & range_mask)
-            {
+            } else if mod_compare(mtime, st_mtime as i32) {
                 Dispatch::Unsure
             } else if st_mtime == last_normal_time {
                 // the file may have just been marked as normal and