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

login
register
mail settings
Submitter Jordi Gutiérrez Hermoso
Date April 12, 2014, 2:03 a.m.
Message ID <9c091f86aa395a09e817.1397268180@Iris>
Download mbox | patch
Permalink /patch/4294/
State Not Applicable
Headers show

Comments

Jordi Gutiérrez Hermoso - April 12, 2014, 2:03 a.m.
# HG changeset patch
# User Jordi Gutiérrez Hermoso <jordigh@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.
Martin Geisler - April 12, 2014, 9:13 a.m.
Jordi Gutiérrez Hermoso <jordigh@octave.org> writes:

> # HG changeset patch
> # User Jordi Gutiérrez Hermoso <jordigh@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")),

We normally don't use use the (s) style for things that can be plural.
For options, the help system will add a "[+]" to flags that can be
specified multiple times.

For --rev in particular, 'hg log' talk about revision in singular,
though one can specify multiple revisions using a single --rev flag.

Patch

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