changeset 17733:3c775c5a6c03

dirstate: handle large dates and times with masking (issue2608) Dates and times that are outside the 31-bit signed range are now 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.
author Matt Mackall <mpm@selenic.com>
date Mon, 08 Oct 2012 17:50:42 -0500
parents 93d97a212559
children 619068c280fd
files mercurial/dirstate.py tests/test-dirstate.t
diffstat 2 files changed, 18 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/dirstate.py	Tue Aug 07 11:04:41 2012 +0200
+++ b/mercurial/dirstate.py	Mon Oct 08 17:50:42 2012 -0500
@@ -15,6 +15,7 @@
 _format = ">cllll"
 propertycache = util.propertycache
 filecache = scmutil.filecache
+_rangemask = 0x7fffffff
 
 class repocache(filecache):
     """filecache for files in .hg/"""
@@ -334,7 +335,8 @@
         '''Mark a file normal and clean.'''
         s = os.lstat(self._join(f))
         mtime = int(s.st_mtime)
-        self._addpath(f, 'n', s.st_mode, s.st_size, mtime)
+        self._addpath(f, 'n', s.st_mode,
+                      s.st_size & _rangemask, mtime & _rangemask)
         if f in self._copymap:
             del self._copymap[f]
         if mtime > self._lastnormaltime:
@@ -401,7 +403,8 @@
         if self._pl[1] == nullid:
             return self.normallookup(f)
         s = os.lstat(self._join(f))
-        self._addpath(f, 'm', s.st_mode, s.st_size, int(s.st_mtime))
+        self._addpath(f, 'm', s.st_mode,
+                      s.st_size & _rangemask, int(s.st_mtime) & _rangemask)
         if f in self._copymap:
             del self._copymap[f]
 
@@ -769,13 +772,13 @@
                 # means "can we check links?".
                 mtime = int(st.st_mtime)
                 if (size >= 0 and
-                    (size != st.st_size
+                    ((size != st.st_size and size != st.st_size & _rangemask)
                      or ((mode ^ st.st_mode) & 0100 and self._checkexec))
                     and (mode & lnkkind != lnkkind or self._checklink)
                     or size == -2 # other parent
                     or fn in self._copymap):
                     madd(fn)
-                elif (mtime != time
+                elif ((time != mtime and time != mtime & _rangemask)
                       and (mode & lnkkind != lnkkind or self._checklink)):
                     ladd(fn)
                 elif mtime == self._lastnormaltime:
--- a/tests/test-dirstate.t	Tue Aug 07 11:04:41 2012 +0200
+++ b/tests/test-dirstate.t	Mon Oct 08 17:50:42 2012 -0500
@@ -52,5 +52,15 @@
   $ hg status
   $ hg debugstate
   n 644          2 2021-01-01 12:00:00 a
-  $ cd ..
+
+Test modulo storage/comparison of absurd dates:
 
+  $ touch -t 250001011200 a
+  $ hg st
+  $ hg debugstate
+  n 644          2 2023-08-24 13:21:04 a
+  $ touch -t 195001011200 a
+  $ hg st
+  $ hg debugstate
+  n 644          2 2018-01-19 15:14:08 a
+