[PATCH 4 of 4 evolve-ext] fold: rehaul handling of multiple and single revisions (BC)

Jordi Gutiérrez Hermoso jordigh at octave.org
Fri Apr 11 21:03:00 CDT 2014


# HG changeset patch
# User Jordi Gutiérrez Hermoso <jordigh at octave.org>
# Date 1397267702 14400
#      Fri Apr 11 21:55:02 2014 -0400
# Branch stable
# Node ID 9c091f86aa395a09e81771f7967ce314e4aeb6ce
# Parent  625907cf8d34b3fb8086db6131ef22724c2045be
fold: rehaul handling of multiple and single revisions (BC)

The fold command parsed the revision arguments in a very peculiar and
idiosyncratic fashion: either a single revision could be specified or
multiple revisions could be specified with --rev (but not both). This
is inconsistent with the way all other hg commands parse revision
arguments. We have several examples of command where several revisions
are passed, and the --rev option is optional for specifying those
revisions (update, strip, export).

This patch alters the way in which fold parses its revision arguments.
No distinction is made between revisions passed with or without the
--rev argument. If a single revision is passed, then as before, all
commits betwen the current commit and the target revision are folded
into one. If multiple revisions are specified, they must specify a
unique contiguous line.

The docstring and error messages are modified accordingly, as well as
the tests.

diff --git a/hgext/evolve.py b/hgext/evolve.py
--- a/hgext/evolve.py
+++ b/hgext/evolve.py
@@ -1716,41 +1716,47 @@
         lockmod.release(lock, wlock)
 
 @command('^fold|squash',
-    [('r', 'rev', [], _("explicitly specify the full set of revision to fold")),
+    [('r', 'rev', [], _("revision(s) to fold")),
     ] + commitopts + commitopts2,
     # allow to choose the seed ?
-    _('rev'))
+    _('hg fold [OPTION]... [-r] REV'))
 def fold(ui, repo, *revs, **opts):
-    """Fold multiple revisions into a single one
+    """fold multiple revisions into a single one
 
-    The revisions from your current working directory to the given one are folded
-    into a single successor revision.
+    Folds all revisions between the specified revision and the parent
+    of working directory into a single revision. The folded revisions
+    will be marked as obsolete and replaced by the resulting revision.
 
-    you can alternatively use --rev to explicitly specify revisions to be folded,
-    ignoring the current working directory parent.
+    If multiple revisions are specified, they will all be folded into
+    one, without implicitly folding from the parent of the current
+    working directory.
     """
     revs = list(revs)
-    if revs:
-        if opts.get('rev', ()):
-            raise util.Abort("cannot specify both --rev and a target revision")
-        targets = scmutil.revrange(repo, revs)
-        revs = repo.revs('(%ld::.) or (.::%ld)', targets, targets)
-    elif 'rev' in opts:
-        revs = scmutil.revrange(repo, opts['rev'])
-    else:
-        revs = ()
+    revs.extend(opts['rev'])
     if not revs:
-        ui.write_err('no revision to fold\n')
-        return 1
+        raise util.Abort('no revisions specified')
+
+    revs = scmutil.revrange(repo, revs)
+    if len(revs) == 1:
+        # Try to extend given revision starting from the working directory
+        revs = repo.revs('(%ld::.) or (.::%ld)', revs, revs)
+        if len(revs) == 1:
+            # If that didn't extend, then there's nothing to fold.
+            raise util.Abort('cannot fold current revision with itself\n'
+                             '(specify target revision other than '
+                             'current revision)')
+
     roots = repo.revs('roots(%ld)', revs)
     if len(roots) > 1:
-        raise util.Abort("set has multiple roots")
+        raise util.Abort("cannot fold non-contiguous revisions\n"
+                         "(multiple roots detected)")
     root = repo[roots[0]]
     if root.phase() <= phases.public:
-        raise util.Abort("can't fold public revisions")
+        raise util.Abort("cannot fold public revisions")
     heads = repo.revs('heads(%ld)', revs)
     if len(heads) > 1:
-        raise util.Abort("set has multiple heads")
+        raise util.Abort("cannot fold non-contiguous revisions\n"
+                         "(multiple heads detected)")
     head = repo[heads[0]]
     wlock = lock = None
     try:
diff --git a/tests/test-evolve.t b/tests/test-evolve.t
--- a/tests/test-evolve.t
+++ b/tests/test-evolve.t
@@ -585,10 +585,15 @@
 
   $ rm *.orig
   $ hg fold
-  no revision to fold
-  [1]
-  $ hg fold 6 --rev 10
-  abort: cannot specify both --rev and a target revision
+  abort: no revisions specified
+  [255]
+  $ hg fold 5 --rev 10
+  abort: cannot fold non-contiguous revisions
+  (multiple roots detected)
+  [255]
+  $ hg fold -r .
+  abort: cannot fold current revision with itself
+  (specify target revision other than current revision)
   [255]
   $ hg fold 6 # want to run hg fold 6
   2 changesets folded


More information about the Mercurial-devel mailing list