changeset 1077:accae5d6de6f draft stable jordi

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. Whether a single or multiple revision is specified, it will all be folded together into one, by connecting them to the parent of the working directory. If the --exact argument is passed, then the parent of the working directory is ignored and the specified revisions must be a single contiguous line. The docstring and error messages are modified accordingly, as well as the tests.
author Jordi Gutiérrez Hermoso <jordigh@octave.org>
date Fri, 11 Apr 2014 21:55:02 -0400
parents 6d691fefdbd1
children
files hgext/evolve.py tests/test-evolve.t
diffstat 2 files changed, 41 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- a/hgext/evolve.py
+++ b/hgext/evolve.py
@@ -2046,41 +2046,53 @@
         lockmod.release(lock, wlock)
 
 @command('^fold|squash',
-    [('r', 'rev', [], _("explicitly specify the full set of revision to fold")),
+    [('r', 'rev', [], _("revision to fold")),
+     ('', 'exact', None, _("ignore parent of working directory"))
     ] + 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
+
+    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.
 
-    The revisions from your current working directory to the given one are folded
-    into a single successor revision.
+    If multiple revisions are specified, they will all be folded
+    together with the parent of the working directory, along with any
+    intermediate revisions.
 
-    you can alternatively use --rev to explicitly specify revisions to be folded,
-    ignoring the current working directory parent.
+    If specifying multiple revisions, use --exact for folding those
+    revisions while ignoring the parent of the working directory. In
+    this case, the given revisions must form a linear unbroken chain.
     """
     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')
+        ui.write_err(_('no revisions specified'))
         return 1
+
+    revs = scmutil.revrange(repo, revs)
+
+    if not opts['exact']:
+        # Try to extend given revision starting from the working directory
+        revs = repo.revs('(%ld::.) or (.::%ld)', revs, revs)
+
+    if len(revs) == 1:
+        ui.write_err(_('single revision specified, nothing to fold\n'))
+        return 2
+
     roots = repo.revs('roots(%ld)', revs)
     if len(roots) > 1:
-        raise util.Abort("set has multiple roots")
+        raise util.Abort(_("cannot fold non-linear revisions "
+                           "(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-linear revisions "
+                           "(multiple heads detected)"))
     head = repo[heads[0]]
     wlock = lock = None
     try:
--- a/tests/test-evolve.t
+++ b/tests/test-evolve.t
@@ -592,10 +592,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