diff --git a/mercurial/dirstate.py b/mercurial/dirstate.py --- a/mercurial/dirstate.py +++ b/mercurial/dirstate.py @@ -432,7 +432,8 @@ class dirstate(object): self._map = {} self._copymap = {} # ignore HG_PENDING because identity is used only for writing - self._identity = util.filestat(self._opener.join(self._filename)) + self._identity = util.filestat.frompath( + self._opener.join(self._filename)) try: fp = self._opendirstatefile() try: diff --git a/mercurial/util.py b/mercurial/util.py --- a/mercurial/util.py +++ b/mercurial/util.py @@ -1098,7 +1098,7 @@ def copyfile(src, dest, hardlink=False, oldstat = None if os.path.lexists(dest): if checkambig: - oldstat = checkambig and filestat(dest) + oldstat = checkambig and filestat.frompath(dest) unlink(dest) if hardlink: # Hardlinks are problematic on CIFS (issue4546), do not allow hardlinks @@ -1128,7 +1128,7 @@ def copyfile(src, dest, hardlink=False, else: shutil.copymode(src, dest) if oldstat and oldstat.stat: - newstat = filestat(dest) + newstat = filestat.frompath(dest) if newstat.isambig(oldstat): # stat of copied file is ambiguous to original one advanced = (oldstat.stat.st_mtime + 1) & 0x7fffffff @@ -1506,13 +1506,18 @@ class filestat(object): exists. Otherwise, it is None. This can avoid preparative 'exists()' examination on client side of this class. """ - def __init__(self, path): + def __init__(self, stat): + self.stat = stat + + @classmethod + def frompath(cls, path): try: - self.stat = os.stat(path) + stat = os.stat(path) except OSError as err: if err.errno != errno.ENOENT: raise - self.stat = None + stat = None + return cls(stat) __hash__ = object.__hash__ @@ -1622,10 +1627,10 @@ class atomictempfile(object): if not self._fp.closed: self._fp.close() filename = localpath(self.__name) - oldstat = self._checkambig and filestat(filename) + oldstat = self._checkambig and filestat.frompath(filename) if oldstat and oldstat.stat: rename(self._tempname, filename) - newstat = filestat(filename) + newstat = filestat.frompath(filename) if newstat.isambig(oldstat): # stat of changed file is ambiguous to original one advanced = (oldstat.stat.st_mtime + 1) & 0x7fffffff diff --git a/mercurial/vfs.py b/mercurial/vfs.py --- a/mercurial/vfs.py +++ b/mercurial/vfs.py @@ -176,11 +176,11 @@ class abstractvfs(object): """ srcpath = self.join(src) dstpath = self.join(dst) - oldstat = checkambig and util.filestat(dstpath) + oldstat = checkambig and util.filestat.frompath(dstpath) if oldstat and oldstat.stat: def dorename(spath, dpath): ret = util.rename(spath, dpath) - newstat = util.filestat(dpath) + newstat = util.filestat.frompath(dpath) if newstat.isambig(oldstat): # stat of renamed file is ambiguous to original one return ret, newstat.avoidambig(dpath, oldstat) @@ -625,12 +625,12 @@ class checkambigatclosing(closewrapbase) """ def __init__(self, fh): super(checkambigatclosing, self).__init__(fh) - object.__setattr__(self, r'_oldstat', util.filestat(fh.name)) + object.__setattr__(self, r'_oldstat', util.filestat.frompath(fh.name)) def _checkambig(self): oldstat = self._oldstat if oldstat.stat: - newstat = util.filestat(self._origfh.name) + newstat = util.filestat.frompath(self._origfh.name) if newstat.isambig(oldstat): # stat of changed file is ambiguous to original one newstat.avoidambig(self._origfh.name, oldstat)