# HG changeset patch # User Matt Mackall # Date 1450309201 21600 # Node ID 4eeef1b2d689bad18f473b5e118cca061f6ca560 # Parent 8bc6ece9a2e1cbb606d2e94c7c72143944bb4e1e# Parent d9e3ebe56970dc6e86648351de3ad13d9ac47cf9 merge with stable diff -r 8bc6ece9a2e1 -r 4eeef1b2d689 mercurial/cmdutil.py --- a/mercurial/cmdutil.py Tue Dec 15 07:57:04 2015 +0000 +++ b/mercurial/cmdutil.py Wed Dec 16 17:40:01 2015 -0600 @@ -7,7 +7,7 @@ from node import hex, bin, nullid, nullrev, short from i18n import _ -import os, sys, errno, re, tempfile, cStringIO, shutil +import os, sys, errno, re, tempfile, cStringIO import util, scmutil, templater, patch, error, templatekw, revlog, copies import match as matchmod import repair, graphmod, revset, phases, obsolete, pathutil @@ -167,8 +167,7 @@ dir=backupdir) os.close(fd) ui.debug('backup %r as %r\n' % (f, tmpname)) - util.copyfile(repo.wjoin(f), tmpname) - shutil.copystat(repo.wjoin(f), tmpname) + util.copyfile(repo.wjoin(f), tmpname, copystat=True) backups[f] = tmpname fp = cStringIO.StringIO() @@ -217,15 +216,12 @@ # to be treated as unmodified dirstate.normallookup(realname) - util.copyfile(tmpname, repo.wjoin(realname)) - # Our calls to copystat() here and above are a - # hack to trick any editors that have f open that - # we haven't modified them. + # copystat=True here and above are a hack to trick any + # editors that have f open that we haven't modified them. # - # Also note that this racy as an editor could - # notice the file's mtime before we've finished - # writing it. - shutil.copystat(tmpname, repo.wjoin(realname)) + # Also note that this racy as an editor could notice the + # file's mtime before we've finished writing it. + util.copyfile(tmpname, repo.wjoin(realname), copystat=True) os.unlink(tmpname) if tobackup: os.rmdir(backupdir) diff -r 8bc6ece9a2e1 -r 4eeef1b2d689 mercurial/util.py --- a/mercurial/util.py Tue Dec 15 07:57:04 2015 +0000 +++ b/mercurial/util.py Wed Dec 16 17:40:01 2015 -0600 @@ -990,8 +990,9 @@ return check -def copyfile(src, dest, hardlink=False): - "copy a file, preserving mode and atime/mtime" +def copyfile(src, dest, hardlink=False, copystat=False): + '''copy a file, preserving mode and optionally other stat info like + atime/mtime''' if os.path.lexists(dest): unlink(dest) # hardlinks are problematic on CIFS, quietly ignore this flag @@ -1004,10 +1005,16 @@ pass # fall back to normal copy if os.path.islink(src): os.symlink(os.readlink(src), dest) + # copytime is ignored for symlinks, but in general copytime isn't needed + # for them anyway else: try: shutil.copyfile(src, dest) - shutil.copymode(src, dest) + if copystat: + # copystat also copies mode + shutil.copystat(src, dest) + else: + shutil.copymode(src, dest) except shutil.Error as inst: raise Abort(str(inst))