changeset 368:281b0086337c

Restoring timestamps into an alternate destination root directory (eventually archives)
author Franz Glasner <fzglas.hg@dom66.de>
date Mon, 25 Feb 2019 09:30:08 +0100
parents 4aa43c79fbf8
children 1b3671d1e57d
files extensions/timestamps.py tests/test-timestamps.t
diffstat 2 files changed, 48 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/extensions/timestamps.py	Mon Feb 25 00:48:16 2019 +0100
+++ b/extensions/timestamps.py	Mon Feb 25 09:30:08 2019 +0100
@@ -143,6 +143,7 @@
         ("", "tsconfig", "", _("use an alternate configuration file"), _("TSCONFIG")),
         ("", "amend", None, _("amend an existing database file instead of generating a fresh one")),
         ("", "all", None, _("when importing import all timestamps instead of only the matching ones")),
+        ("", "destdir", "", _("when restoring timestamps give an alternate base directory for settings timestamps (e.g. an archived directory tree)"), _("DESTDIR")),
     ] + cmdutil.walkopts,
     _("hg timestamps OPTION [OPTION]... [FILE]..."),
     inferrepo=True)
@@ -179,7 +180,12 @@
                          tsconfig=opts.get("tsconfig"),
                          amend=opts.get("amend"))
     elif opts.get("restore"):
-        _restore_timestamps(ui, ctx, tsconfig=opts.get("tsconfig"))
+        destdir = opts.get("destdir")
+        if not destdir:
+            destdir = None
+        _restore_timestamps(ui, ctx,
+                            tsconfig=opts.get("tsconfig"),
+                            destdir=destdir)
     elif opts.get("show"):
         with ui.formatter("timestamps", opts) as fm:
             _show_timestamps(ui, ctx, fm, tsconfig=opts.get("tsconfig"))
@@ -473,7 +479,7 @@
         ts.write(fp)
 
 
-def _restore_timestamps(ui, ctx, tsconfig=None):
+def _restore_timestamps(ui, ctx, tsconfig=None, destdir=None):
     repo = ctx.repo()
     if not repo.local():
         raise error.Abort(_("repository is not local"))
@@ -482,10 +488,13 @@
     matcher = _gen_matcher_from_tsconfig(ctx, tsconfig=tsconfig, ui=ui)
     if matcher is None:
         raise error.Abort(_("timestamps are not activated/configured"))
-    ts = _Timestamps.from_filename(ui, name=repo.wjoin(TIMESTAMPS_DATABASE))
+    if destdir is None:
+        ts = _Timestamps.from_filename(ui, name=repo.wjoin(TIMESTAMPS_DATABASE))
+    else:
+        ts = _Timestamps.from_ctx(ctx, ui)
     if ts is None:
         raise error.Abort(_("timestamps database file does not exist"))
-    _do_restore_timestamps(repo, ctx, matcher, ts, ui=ui)
+    _do_restore_timestamps(repo, ctx, matcher, ts, ui=ui, destdir=destdir)
 
 
 def _show_timestamps(ui, ctx, formatter,
@@ -1149,6 +1158,7 @@
 
 
 def _do_restore_timestamps(repo, candidates, tsconfmatch, tsdb,
+                           destdir=None,
                            ui=None,
                            alt=None,
                            allow_other_region=False):
@@ -1172,13 +1182,18 @@
                     mtime = tsdb.getalt(f, alt)
                 if mtime is not None:
                     mt = calendar.timegm(_dt_from_isoformat(mtime).timetuple())
+                    if destdir is None:
+                        real_fname = repo.wjoin(f)
+                        visu_fname = f
+                    else:
+                        real_fname = visu_fname = os.path.join(destdir, f)
                     if _DEV:
-                        ui.debug("RESTORING TIMESTAMP: " + f + ' -> '
+                        ui.debug("RESTORING TIMESTAMP: " + visu_fname + ' -> '
                                  + mtime + '\n')
                     try:
-                        os.utime(repo.wjoin(f), (time.time(), mt))
+                        os.utime(real_fname, (time.time(), mt))
                     except IOError:
-                        ui.warn(_("cannot set mtime for file: %s") % f)
+                        ui.warn(_("cannot set mtime for file: %s") % real_fname)
 
 
 def _debug_mergestate(ui, ms):
--- a/tests/test-timestamps.t	Mon Feb 25 00:48:16 2019 +0100
+++ b/tests/test-timestamps.t	Mon Feb 25 09:30:08 2019 +0100
@@ -191,6 +191,30 @@
 
   $ "$TSPY" "$TESTDIR/lib-stat.py" --check=2018-02-03T00:01:02Z files/test-not-in-db.txt
 
+
+Test restoring timestamps into archives..
+
+  $ hg archive -t files __arch
+  $ hg timestamps --restore --destdir __arch
+
+... and the mtimes of the archived "tracked" files should be retained to the
+ contents of the current .hgtimestamps.db in the fs
+
+  $ "$TSPY" "$TESTDIR/lib-stat.py" --check=2017-12-01T02:03:04Z __arch/files/test1.txt
+  $ "$TSPY" "$TESTDIR/lib-stat.py" --check=2017-12-01T08:09:10Z __arch/files/test2.txt
+  $ "$TSPY" "$TESTDIR/lib-stat.py" --check=2017-12-01T05:06:07Z __arch/files/test3.txt
+
+Test archiving an explicit revision...
+
+  $ hg archive -r 5 -t files __arch5
+  $ hg timestamps -r5 --restore --destdir __arch5
+
+... and the mtimes should be retained to the revisions values also
+
+  $ "$TSPY" "$TESTDIR/lib-stat.py" --check=2017-12-01T02:03:04Z __arch5/files/test1.txt
+  $ "$TSPY" "$TESTDIR/lib-stat.py" --check=2017-12-01T04:05:06Z __arch5/files/test2.txt
+  $ "$TSPY" "$TESTDIR/lib-stat.py" --check=2017-12-01T05:06:07Z __arch5/files/test3.txt
+
   $ cd ..
 
 
@@ -350,8 +374,8 @@
 6. Test the merge with conflicts the other way round
 ====================================================
 
-  $ prepare_repo "ts6"
-  $ cd ts6
+  $ prepare_repo "ts7"
+  $ cd ts7
   $ hg update --quiet -r7
   $ hg merge -r8 --tool=:merge3
   merging .hgtimestamps.db