hgext3rd/evolve/rewind.py
changeset 3871 2e32a1ef0c60
parent 3869 bbfbaf46f7b0
child 3872 bbc3cfdfe42b
--- a/hgext3rd/evolve/rewind.py	Sun Jun 17 03:29:34 2018 +0200
+++ b/hgext3rd/evolve/rewind.py	Sun Jun 17 03:10:19 2018 +0200
@@ -29,6 +29,7 @@
     [('', 'to', [], _("rewind to these revision")),
      ('', 'as-divergence', None, _("preserve current latest successors")),
      ('', 'exact', None, _("only rewind explicitly selected revisions")),
+     ('', 'from', [], _("rewind these revisions to their predecessors")),
     ],
     _(''))
 def rewind(ui, repo, **opts):
@@ -37,6 +38,11 @@
     This command can be used to restore stacks of changesets to an obsolete
     state, creating identical identical copies.
 
+    There are two mains way to select the rewind target. Rewinding "from"
+    changesets will restore the direct precursors of theses changesets (and
+    obsolete the changeset you rewind from). Rewinding "to" will restore the
+    changeset you have selected (and obsolete their latest successors).
+
     When we rewind to an obsolete version, we also rewind to all its obsolete
     ancestors. To only rewind to the explicitly selection changesets use the
     `--exact` flag. Using the `--exact` flag can restore some changesets as
@@ -53,6 +59,14 @@
               problematic. The fold result is marked obsolete and the part not
               rewinded too are "lost".  Please use --as-divergence when you
               need to perform such operation.
+
+      * :hg:`rewind` might affect changeset outside the current stack. Without --exact, we
+              also restore ancestors of the rewind target, obsoleting their
+              latest successors (unless --as-divergent is provided). In some
+              case, these latest successors will be on branches unrelated to
+              the changeset you rewind from.
+              (We plan to automatically detect this cases in the future)
+
     """
     unfi = repo.unfiltered()
 
@@ -104,15 +118,21 @@
 def _select_rewinded(repo, opts):
     """select the revision we shoudl rewind to
     """
-    if not opts.get('to'):
+    unfi = repo.unfiltered()
+    rewinded = set()
+    if opts.get('to'):
+        rewinded.update(scmutil.revrange(repo, opts.get('to')))
+    if opts.get('from'):
+        succs = scmutil.revrange(repo, opts.get('from'))
+        rewinded.update(unfi.revs('precursors(%ld)', succs))
+
+    if not rewinded:
         raise error.Abort('no revision to rewind to')
 
-    rewinded = scmutil.revrange(repo, opts.get('to'))
+    if not opts['exact']:
+        rewinded = unfi.revs('obsolete() and ::%ld', rewinded)
 
-    if not opts['exact']:
-        rewinded = repo.revs('obsolete() and ::%ld', rewinded)
-
-    return rewinded
+    return sorted(rewinded)
 
 def _revive_revision(unfi, rev, rewindmap):
     """rewind a single revision rev.