comparison mercurial/util.py @ 26493:13272104bb07

util: use tuple accessor to get accurate st_mtime value (issue4836) Because st.st_mtime is computed as 'sec + 1e-9 * nsec' and double is too narrow to represent nanoseconds, int(st.st_mtime) can be 'sec + 1'. Therefore, that value could be different from the one got by osutils.listdir(). This patch fixes the problem by accessing to raw st_mtime by tuple index. It catches TypeError to fall back to st.st_mtime because our osutil.stat does not support tuple index. In dirstate.normal(), 'st' is always a Python stat, but in dirstate.status(), it can be either a Python stat or an osutil.stat. Thanks to vgatien-baron@janestreet.com for finding the root cause of this subtle problem.
author Yuya Nishihara <yuya@tcha.org>
date Sun, 04 Oct 2015 22:35:36 +0900
parents 3a0bb61371c5
children 56b2bcea2529
comparison
equal deleted inserted replaced
26492:3a0bb61371c5 26493:13272104bb07
17 _ = i18n._ 17 _ = i18n._
18 import error, osutil, encoding, parsers 18 import error, osutil, encoding, parsers
19 import errno, shutil, sys, tempfile, traceback 19 import errno, shutil, sys, tempfile, traceback
20 import re as remod 20 import re as remod
21 import os, time, datetime, calendar, textwrap, signal, collections 21 import os, time, datetime, calendar, textwrap, signal, collections
22 import stat
22 import imp, socket, urllib 23 import imp, socket, urllib
23 import gc 24 import gc
24 import bz2 25 import bz2
25 import zlib 26 import zlib
26 27
951 return os.fstat(fp.fileno()) 952 return os.fstat(fp.fileno())
952 except AttributeError: 953 except AttributeError:
953 return os.stat(fp.name) 954 return os.stat(fp.name)
954 955
955 def statmtimesec(st): 956 def statmtimesec(st):
956 return int(st.st_mtime) 957 """Get mtime as integer of seconds
958
959 'int(st.st_mtime)' cannot be used because st.st_mtime is computed as
960 'sec + 1e-9 * nsec' and double-precision floating-point type is too narrow
961 to represent nanoseconds. If 'nsec' is close to 1 sec, 'int(st.st_mtime)'
962 can be 'sec + 1'. (issue4836)
963 """
964 try:
965 return st[stat.ST_MTIME]
966 except TypeError:
967 # osutil.stat doesn't allow index access and its st_mtime is int
968 return st.st_mtime
957 969
958 # File system features 970 # File system features
959 971
960 def checkcase(path): 972 def checkcase(path):
961 """ 973 """