Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/util.py @ 29204:ce2d81aafbae
util: make copyfile avoid ambiguity of file stat if needed
In some cases below, copying from backup is used to restore original
contents of a file. If copying 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 (from '.hg/journal.backup.*')
- rollback of previous transaction (from '.hg/undo.backup.*')
To avoid such problem, this patch makes copyfile() avoid ambiguity of
file stat, if needed.
Ambiguity check is executed, only if:
- checkambig=True is specified (not all copying needs ambiguity check), and
- destination file exists before copying
This patch also adds 'not (copystat and checkambig)' assertion,
because combination of copystat and checkambig is meaningless.
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 | a109bf7e0dc2 |
children | 1eff545cef52 |
comparison
equal
deleted
inserted
replaced
29203:731ced087a4b | 29204:ce2d81aafbae |
---|---|
1008 raise error.SignatureError | 1008 raise error.SignatureError |
1009 raise | 1009 raise |
1010 | 1010 |
1011 return check | 1011 return check |
1012 | 1012 |
1013 def copyfile(src, dest, hardlink=False, copystat=False): | 1013 def copyfile(src, dest, hardlink=False, copystat=False, checkambig=False): |
1014 '''copy a file, preserving mode and optionally other stat info like | 1014 '''copy a file, preserving mode and optionally other stat info like |
1015 atime/mtime''' | 1015 atime/mtime''' |
1016 assert not (copystat and checkambig) | |
1017 oldstat = None | |
1016 if os.path.lexists(dest): | 1018 if os.path.lexists(dest): |
1019 if checkambig: | |
1020 oldstat = checkambig and filestat(dest) | |
1017 unlink(dest) | 1021 unlink(dest) |
1018 # hardlinks are problematic on CIFS, quietly ignore this flag | 1022 # hardlinks are problematic on CIFS, quietly ignore this flag |
1019 # until we find a way to work around it cleanly (issue4546) | 1023 # until we find a way to work around it cleanly (issue4546) |
1020 if False and hardlink: | 1024 if False and hardlink: |
1021 try: | 1025 try: |
1033 if copystat: | 1037 if copystat: |
1034 # copystat also copies mode | 1038 # copystat also copies mode |
1035 shutil.copystat(src, dest) | 1039 shutil.copystat(src, dest) |
1036 else: | 1040 else: |
1037 shutil.copymode(src, dest) | 1041 shutil.copymode(src, dest) |
1042 if oldstat and oldstat.stat: | |
1043 newstat = filestat(dest) | |
1044 if newstat.isambig(oldstat): | |
1045 # stat of copied file is ambiguous to original one | |
1046 advanced = (oldstat.stat.st_mtime + 1) & 0x7fffffff | |
1047 os.utime(dest, (advanced, advanced)) | |
1038 except shutil.Error as inst: | 1048 except shutil.Error as inst: |
1039 raise Abort(str(inst)) | 1049 raise Abort(str(inst)) |
1040 | 1050 |
1041 def copyfiles(src, dst, hardlink=None, progress=lambda t, pos: None): | 1051 def copyfiles(src, dst, hardlink=None, progress=lambda t, pos: None): |
1042 """Copy a directory tree using hardlinks if possible.""" | 1052 """Copy a directory tree using hardlinks if possible.""" |