Mercurial > public > mercurial-scm > hg
diff mercurial/util.py @ 29201:a109bf7e0dc2
util: make atomictempfile avoid ambiguity of file stat if needed
Ambiguity check is executed at close(), only if:
- atomictempfile is created with checkambig=True, and
- target file exists before renaming
This restriction avoids performance decrement by needless examination
of file stat (for example, filelog doesn't need exact cache
validation, even though it uses atomictempfile to write changes out).
See description of filestat class for detail about why the logic in
this patch works as expected.
This patch is a part of preparation for "Exact Cache Validation Plan":
https://www.mercurial-scm.org/wiki/ExactCacheValidationPlan
author | FUJIWARA Katsunori <foozy@lares.dti.ne.jp> |
---|---|
date | Thu, 19 May 2016 00:20:38 +0900 |
parents | ca4065028e00 |
children | ce2d81aafbae |
line wrap: on
line diff
--- a/mercurial/util.py Thu May 19 00:20:37 2016 +0900 +++ b/mercurial/util.py Thu May 19 00:20:38 2016 +0900 @@ -1453,11 +1453,12 @@ visible. If the object is destroyed without being closed, all your writes are discarded. ''' - def __init__(self, name, mode='w+b', createmode=None): + def __init__(self, name, mode='w+b', createmode=None, checkambig=False): self.__name = name # permanent name self._tempname = mktempcopy(name, emptyok=('w' in mode), createmode=createmode) self._fp = posixfile(self._tempname, mode) + self._checkambig = checkambig # delegated methods self.write = self._fp.write @@ -1468,7 +1469,17 @@ def close(self): if not self._fp.closed: self._fp.close() - rename(self._tempname, localpath(self.__name)) + filename = localpath(self.__name) + oldstat = self._checkambig and filestat(filename) + if oldstat and oldstat.stat: + rename(self._tempname, filename) + newstat = filestat(filename) + if newstat.isambig(oldstat): + # stat of changed file is ambiguous to original one + advanced = (oldstat.stat.st_mtime + 1) & 0x7fffffff + os.utime(filename, (advanced, advanced)) + else: + rename(self._tempname, filename) def discard(self): if not self._fp.closed: