# HG changeset patch # User Kyle Lippincott # Date 1520538243 28800 # Node ID 08890706366ed7856abeb78759916bef1210b4ad # Parent e4640ec346ac34a9c818c6ee5db1e623b0ad5b47 copyfile: preserve stat info (mtime, etc.) when doing copies/renames Differential Revision: https://phab.mercurial-scm.org/D2729 diff -r e4640ec346ac -r 08890706366e hgext/largefiles/overrides.py --- a/hgext/largefiles/overrides.py Thu Mar 22 22:58:31 2018 -0400 +++ b/hgext/largefiles/overrides.py Thu Mar 08 11:44:03 2018 -0800 @@ -667,7 +667,7 @@ try: origcopyfile = util.copyfile copiedfiles = [] - def overridecopyfile(src, dest): + def overridecopyfile(src, dest, *args, **kwargs): if (lfutil.shortname in src and dest.startswith(repo.wjoin(lfutil.shortname))): destlfile = dest.replace(lfutil.shortname, '') @@ -675,7 +675,7 @@ raise IOError('', _('destination largefile already exists')) copiedfiles.append((src, dest)) - origcopyfile(src, dest) + origcopyfile(src, dest, *args, **kwargs) util.copyfile = overridecopyfile result += orig(ui, repo, listpats, opts, rename) diff -r e4640ec346ac -r 08890706366e mercurial/cmdutil.py --- a/mercurial/cmdutil.py Thu Mar 22 22:58:31 2018 -0400 +++ b/mercurial/cmdutil.py Thu Mar 08 11:44:03 2018 -0800 @@ -1192,7 +1192,9 @@ os.rename(src, tmp) os.rename(tmp, target) else: - util.copyfile(src, target) + # Preserve stat info on renames, not on copies; this matches + # Linux CLI behavior. + util.copyfile(src, target, copystat=rename) srcexists = True except IOError as inst: if inst.errno == errno.ENOENT: diff -r e4640ec346ac -r 08890706366e tests/test-rename.t --- a/tests/test-rename.t Thu Mar 22 22:58:31 2018 -0400 +++ b/tests/test-rename.t Thu Mar 08 11:44:03 2018 -0800 @@ -657,3 +657,36 @@ [255] $ hg status -C +check that stat information such as mtime is preserved on rename - it's unclear +whether the `touch` and `stat` commands are portable, so we mimic them using +python. Not all platforms support precision of even one-second granularity, so +we allow a rather generous fudge factor here; 1234567890 is 2009, and the +primary thing we care about is that it's not the machine's current time; +hopefully it's really unlikely for a machine to have such a broken clock that +this test fails. :) + + $ mkdir mtime +Create the file (as empty), then update its mtime and atime to be 1234567890. + >>> import os + >>> filename = "mtime/f" + >>> mtime = 1234567890 + >>> open(filename, "w").close() + >>> os.utime(filename, (mtime, mtime)) + $ hg ci -qAm 'add mtime dir' +"hg cp" does not preserve the mtime, so it should be newer than the 2009 +timestamp. + $ hg cp -q mtime mtime_cp + >>> from __future__ import print_function + >>> import os + >>> filename = "mtime_cp/f" + >>> print(os.stat(filename).st_mtime < 1234567999) + False +"hg mv" preserves the mtime, so it should be ~equal to the 2009 timestamp +(modulo some fudge factor due to not every system supporting 1s-level +precision). + $ hg mv -q mtime mtime_mv + >>> from __future__ import print_function + >>> import os + >>> filename = "mtime_mv/f" + >>> print(os.stat(filename).st_mtime < 1234567999) + True