changeset 399:22b749f7ced5

Timestamps now handles shelve and unshelve. BUGS: Unit-tests for "unshelve" not yet implemented.
author Franz Glasner <fzglas.hg@dom66.de>
date Thu, 08 Aug 2019 09:03:38 +0200
parents 8ac53bee87ff
children 0074f3ca8a0e
files extensions/timestamps.py tests/lib-test-timestamps.sh tests/test-timestamps.t
diffstat 3 files changed, 91 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- a/extensions/timestamps.py	Thu Aug 08 09:02:55 2019 +0200
+++ b/extensions/timestamps.py	Thu Aug 08 09:03:38 2019 +0200
@@ -210,6 +210,8 @@
     ui.setconfig(b"hooks", b"post-resolve.timestamps", generic_post_hook)
     ui.setconfig(b"hooks", b"pre-revert.timestamps", generic_pre_hook)
     ui.setconfig(b"hooks", b"post-revert.timestamps", generic_post_hook)
+    ui.setconfig(b"hooks", b"post-shelve.timestamps", generic_post_hook)
+    ui.setconfig(b"hooks", b"post-unshelve.timestamps", generic_post_hook)
 
 
 def reposetup(ui, repo):
@@ -274,7 +276,7 @@
                 # collect the timestamps
                 #
 
-                self.ui.note(_(b"collecting timestamps\n"))
+                self.ui.note(_(b"timestamps: collecting timestamps\n"))
 
                 #
                 # get the status of all files w/o timestamps database and
@@ -342,7 +344,7 @@
                              _matchmod_exact(self.root,
                                              b"",
                                              auto_included)])
-                self.ui.note(_(b"timestamps have been collected\n"))
+                self.ui.note(_(b"timestamps: timestamps have been collected\n"))
             else:
                 self.ui.debug(b"timestamps: TimestampedRepo.commit():"
                               b" timestamps not activated/configured\n")
@@ -356,26 +358,27 @@
             self._tss_from_parents = [p.hex() for p in self[None].parents()]
 
         def _tss_on_update(self, parent1=None, parent2=None, error=0, preview=False):
-            """Called on :hg:`hg update` and :hg:`hg merge`
+            """Called on :hg:`update`, :hg:`merge`, :hg:`shelve` and
+            :hg:`unshelve` via the installed update hook.
 
             """
             self._tss_ensure_vars()
             if not self._tss_hooktype \
                    or self._tss_hooktype not in (b"pre-update",
                                                  b"pre-merge"):
-                self.ui.warn(_(b"timestamps: no recorded update hook data for use in `_tss_on_update()'\n"))
+                self.ui.warn(_(b"timestamps: no recorded hook data\n"))
                 return
             if preview:
-                self.ui.note(_(b"skipping updating timestamps in preview mode\n"))
+                self.ui.note(_(b"timestamps: skipping updating timestamps in preview mode\n"))
                 return
-            self.ui.note(_(b"restoring timestamps\n"))
+            self.ui.note(_(b"timestamps: restoring timestamps\n"))
             wctx = self[None]
             tsconfmatch = _gen_matcher_from_tsconfig(wctx)
             if tsconfmatch is not None:
                 ts = _Timestamps.from_ctx(wctx,
                                           self.ui, name=TIMESTAMPS_DATABASE)
                 if ts is None:
-                    self.ui.warn(_(b"update.timestamps: timestamps database file could not be found or read\n"))
+                    self.ui.warn(_(b"timestamps: update.timestamps: timestamps database file could not be found or read\n"))
                 else:
                     if not parent2:
                         self._tss_update_update(tsconfmatch, ts)
@@ -421,8 +424,9 @@
     This generic dispatcher hook simplifies configuration.
 
     """
-    ui.debug(b"timestamps: GENERIC PRE HOOK: " + hooktype + b'\n')
-    ui.debug("timestamps: GENERIC PRE HOOK: " + repr(kwds) + '\n')
+    if _DEV:
+        ui.debug(b"timestamps: GENERIC PRE HOOK: " + hooktype + b'\n')
+        ui.debug("timestamps: GENERIC PRE HOOK: " + repr(kwds) + '\n')
     if not repo.local():
         return
     repo._tss_record_pre_data(hooktype, **kwds)
@@ -437,8 +441,9 @@
     Current implementations exist for :hg:`revert` and :hg:`resolve`.
 
     """
-    ui.debug(b"timestamps: GENERIC POST HOOK: " + hooktype + b'\n')
-    ui.debug("timestamps: GENERIC POST HOOK: " + repr(kwds) + '\n')
+    if _DEV:
+        ui.debug(b"timestamps: GENERIC POST HOOK: " + hooktype + b'\n')
+        ui.debug("timestamps: GENERIC POST HOOK: " + repr(kwds) + '\n')
 
     if not repo.local():
         return
@@ -451,7 +456,7 @@
         ts = _Timestamps.from_filename(ui, name=repo.wjoin(TIMESTAMPS_DATABASE))
         if ts is None:
             return
-        ui.note(_(b"restoring timestamps\n"))
+        ui.note(_(b"timestamps: restoring timestamps\n"))
         if opts.get(b"all"):
             candidates = wctx
         else:
@@ -466,16 +471,40 @@
             return
         ts = _Timestamps.from_filename(ui, name=repo.wjoin(TIMESTAMPS_DATABASE))
         if ts is None:
-            ui.warn(_(b"update.timestamps: timestamps database file could not be found or read\n"))
+            ui.warn(_(b"timestamps: timestamps database file could not be found or read\n"))
+            return
         if opts.get(b"list") or opts.get(b"mark") or opts.get(b"unmark"):
             return
-        ui.note(_(b"restoring timestamps\n"))
+        ui.note(_(b"timestamps: restoring timestamps\n"))
         tool = opts.get(b"tool")
         patsmatch = scmutil.match(wctx, kwds.get("pats"), opts)
+    elif hooktype == b"post-shelve":
+        wctx = repo[None]
+        tsconfmatch = _gen_matcher_from_tsconfig(wctx, ui=ui)
+        if tsconfmatch is None:
+            return
+        ts = _Timestamps.from_filename(ui, name=repo.wjoin(TIMESTAMPS_DATABASE))
+        if ts is None:
+            ui.warn(_(b"timestamps: timestamps database file could not be found or read\n"))
+            return
+        if opts.get(b"list") or opts.get(b"delete") or opts.get(b"patch") \
+           or opts.get(b"stat"):
+            return
+        ui.note(_(b"timestamps: restoring timestamps\n"))
+        if kwds.get("pats") is None:
+            candidates = wctx
+        else:
+            patterns = scmutil.match(wctx, kwds.get("pats"), opts=opts)
+            candidates = wctx.walk(patterns)
+        _do_restore_timestamps(repo, candidates, None, tsconfmatch, ts, ui=ui)
+    elif hooktype == b"post-unshelve":
+        # just drop a note
+        ui.note(_(b"timestamps: leaving timestamps\n"))
 
 
 def update_hook(ui, repo, hooktype, **kwds):
-    """Hook called by :hg:`update` and :hg:`merge` if configured correctly.
+    """Hook called by :hg:`update`, :hg:`merge`, :hg:`shelve` and
+    :hg:`unshelve` if configured correctly.
 
     """
     if _DEV:
@@ -500,10 +529,11 @@
                      amend=False):
     repo = ctx.repo()
     if not repo.local():
-        raise error.Abort(_(b"repository is not local"))
+        raise error.Abort(_(b"timestamps: repository is not local"))
     tsconfmatch = _gen_matcher_from_tsconfig(ctx, tsconfigname=tsconfig, ui=ui)
     if tsconfmatch is None:
-        raise error.Abort(_(b"timestamps are not activated/configured"))
+        raise error.Abort(_(b"timestamps: timestamps are not"
+                            b" activated/configured"))
     if amend:
         ts = _Timestamps.from_filename(ui, name=repo.wjoin(TIMESTAMPS_DATABASE))
         if ts is None:
@@ -535,7 +565,8 @@
     else:
         ts = _Timestamps.from_ctx(ctx, ui)
     if ts is None:
-        raise error.Abort(_(b"timestamps database file does not exist"))
+        raise error.Abort(_(b"timestamps: timestamps database file does"
+                            b" not exist"))
     _do_restore_timestamps(repo, ctx, pats, tsconfmatch, ts,
                            ui=ui, destdir=destdir)
 
@@ -553,7 +584,8 @@
         or _matchmod_never(ctx.repo().root, b"")
     ts = _Timestamps.from_ctx(ctx, ui, name=TIMESTAMPS_DATABASE)
     if ts is None:
-        raise error.Abort(_(b"timestamps database file does not exist"))
+        raise error.Abort(_(b"timestamps:"
+                            b" timestamps database file does not exist"))
     if ui.debugflag or ui.verbose:
         files = iter(ts)
     else:
@@ -598,22 +630,22 @@
                        all=False):
     repo = ctx.repo()
     if not repo.local():
-        raise error.Abort(_(b"repository is not local"))
+        raise error.Abort(_(b"timestamps: repository is not local"))
     tsconfmatch = _gen_matcher_from_tsconfig(ctx, tsconfigname=tsconfig, ui=ui)
     if tsconfmatch is None:
-        raise error.Abort(_(b"timestamps are not activated/configured"))
+        raise error.Abort(_(b"timestamps: timestamps are not activated/configured"))
     if amend:
         ts = _Timestamps.from_filename(ui, name=repo.wjoin(TIMESTAMPS_DATABASE))
         if ts is None:
-            raise error.Abort(_(b"timestamps database file does not exist"
-                                b" -- cannot amend"))
+            raise error.Abort(_(b"timestamps: timestamps database file"
+                                b"does not exist -- cannot amend"))
     else:
         ts = _Timestamps.create(ui)
     try:
         sourcetsfile = io.open(repo.wjoin(b".hgtimestamp"), "rt",
                                encoding="utf-8")
     except IOError:
-        raise error.Abort(_(b"no .hgtimestamp database file"))
+        raise error.Abort(_(b"timestamps: no .hgtimestamp database file"))
     try:
         for line in sourcetsfile:
             fname, mtime = line.strip().split(b',')
@@ -1245,7 +1277,8 @@
                         try:
                             os.utime(real_fname, (time.time(), mt))
                         except IOError:
-                            ui.warn(_(b"timestamps: cannot set mtime for file: %s") % real_fname)
+                            ui.warn(_(b"timestamps: cannot set mtime"
+                                      b"for file: %s") % real_fname)
 
 
 def _debug_mergestate(ui, ms):
--- a/tests/lib-test-timestamps.sh	Thu Aug 08 09:02:55 2019 +0200
+++ b/tests/lib-test-timestamps.sh	Thu Aug 08 09:03:38 2019 +0200
@@ -52,6 +52,7 @@
 EOF
     cat >>$LOCAL_HGRCPATH <<EOF
 [extensions]
+shelve=
 timestamps=$LOCAL_TESTDIR/../extensions/timestamps.py
 EOF
     hg add .hgtimestamps
--- a/tests/test-timestamps.t	Thu Aug 08 09:02:55 2019 +0200
+++ b/tests/test-timestamps.t	Thu Aug 08 09:03:38 2019 +0200
@@ -417,3 +417,35 @@
   $ "$TSPY" "$TESTDIR/lib-stat.py" --check=2017-12-01T06:07:08Z files/test4-2.txt
 
   $ cd ..
+
+
+7. Test shelve / unshelve
+=========================
+
+All changed files
+
+  $ prepare_repo "ts8"
+  $ cd ts8
+  $ echo "CHANGE IN 1" >>files/test1.txt
+  $ echo "CHANGE IN 2" >>files/test2.txt
+  $ hg shelve --quiet -n temp
+  timestamps: no recorded hook data
+  $ hg status
+  $ "$TSPY" "$TESTDIR/lib-stat.py" --check=2017-12-01T02:03:04Z files/test1.txt
+  $ "$TSPY" "$TESTDIR/lib-stat.py" --check=2017-12-01T08:09:10Z files/test2.txt
+  $ cd ..
+
+
+Some changed files
+
+  $ prepare_repo "ts9"
+  $ cd ts9
+  $ echo "CHANGE IN 1" >>files/test1.txt
+  $ echo "CHANGE IN 2" >>files/test2.txt
+  $ hg shelve --quiet -n temp files/test1.txt
+  timestamps: no recorded hook data
+  $ hg status
+  M files/test2.txt
+  $ "$TSPY" "$TESTDIR/lib-stat.py" --check=2017-12-01T02:03:04Z files/test1.txt
+  $ "$TSPY" "$TESTDIR/lib-stat.py" --differs=2017-12-01T08:09:10Z files/test2.txt
+  $ cd ..