# HG changeset patch # User Matt Mackall # Date 2015-12-16 23:40:01 # Node ID 4eeef1b2d689bad18f473b5e118cca061f6ca560 # Parent 8bc6ece9a2e1cbb606d2e94c7c72143944bb4e1e # Parent d9e3ebe56970dc6e86648351de3ad13d9ac47cf9 merge with stable diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py --- a/mercurial/cmdutil.py +++ b/mercurial/cmdutil.py @@ -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 @@ def dorecord(ui, repo, commitfunc, cmdsu 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 @@ def dorecord(ui, repo, commitfunc, cmdsu # 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 --git a/mercurial/util.py b/mercurial/util.py --- a/mercurial/util.py +++ b/mercurial/util.py @@ -990,8 +990,9 @@ def checksignature(func): 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 @@ def copyfile(src, dest, hardlink=False): 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))