Mercurial > hg
changeset 29203:731ced087a4b
vfs: make rename avoid ambiguity of file stat if needed
In some cases below, renaming from backup is used to restore original
contents of a file. If renaming keeps ctime, mtime and size of a file,
restoring is overlooked, and old contents cached before restoring
isn't invalidated as expected.
- failure of transaction before closing (only from '.hg/journal.dirstate')
- rollback of previous transaction (from '.hg/undo.*')
- failure in dirstateguard scope (from '.hg/dirstate.SUFFIX')
To avoid such problem, this patch makes vfs.rename() avoid ambiguity
of file stat, if needed.
Ambiguity check is executed, only if:
- checkambig=True is specified (not all renaming needs ambiguity check), and
- destination file exists before renaming
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 | 76f1ea360c7e |
children | ce2d81aafbae |
files | mercurial/scmutil.py |
diffstat | 1 files changed, 12 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/scmutil.py Thu May 19 00:20:38 2016 +0900 +++ b/mercurial/scmutil.py Thu May 19 00:20:38 2016 +0900 @@ -377,8 +377,18 @@ def readlock(self, path): return util.readlock(self.join(path)) - def rename(self, src, dst): - return util.rename(self.join(src), self.join(dst)) + def rename(self, src, dst, checkambig=False): + dstpath = self.join(dst) + oldstat = checkambig and util.filestat(dstpath) + if oldstat and oldstat.stat: + ret = util.rename(self.join(src), dstpath) + newstat = util.filestat(dstpath) + if newstat.isambig(oldstat): + # stat of renamed file is ambiguous to original one + advanced = (oldstat.stat.st_mtime + 1) & 0x7fffffff + os.utime(dstpath, (advanced, advanced)) + return ret + return util.rename(self.join(src), dstpath) def readlink(self, path): return os.readlink(self.join(path))