hgext/evolve.py
changeset 996 b98dd5d3065c
parent 995 0f3a7efd6ee9
child 997 f48cd2f48d14
--- a/hgext/evolve.py	Mon Jun 30 10:25:08 2014 -0400
+++ b/hgext/evolve.py	Mon Jun 30 13:29:49 2014 -0400
@@ -2074,32 +2074,61 @@
         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, _("only fold specified revisions"))
     ] + 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 a set of revisions with the parent of the working directory.
+    All revisions linearly between the given revisions and the parent
+    of the working directory will also be folded.
+
+    Use --exact for folding only the specified revisions while ignoring the
+    parent of the working directory. In this case, the given revisions must
+    form a linear unbroken chain.
+
+    .. container:: verbose
+
+     Some examples:
+
+     - Fold the current revision with its parent::
 
-    The revisions from your current working directory to the given one are folded
-    into a single successor revision.
+         hg fold .^
+
+     - Fold all draft revisions with working directory parent::
+
+         hg fold 'draft()'
 
-    you can alternatively use --rev to explicitly specify revisions to be folded,
-    ignoring the current working directory parent.
+       See :hg:`help phases` for more about draft revisions and
+       :hg:`help revsets` for more about the `draft()` keyword
+
+     - Fold revisions 3, 4, 5, and 6 with the working directory parent::
+
+         hg fold 3:6
+
+     - Only fold revisions linearly between foo and @::
+
+         hg fold foo::@ --exact
     """
     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:
         raise util.Abort(_('no revisions specified'))
 
+    revs = scmutil.revrange(repo, revs)
+
+    if not opts['exact']:
+        # Try to extend given revision starting from the working directory
+        extrevs = repo.revs('(%ld::.) or (.::%ld)', revs, revs)
+        discardedrevs = [r for r in revs if r not in extrevs]
+        if discardedrevs:
+            raise util.Abort(_("cannot fold non-linear revisions"),
+                               hint=_("given revisions are unrelated to parent "
+                                      "of working directory"))
+        revs = extrevs
+
     if len(revs) == 1:
         ui.write_err(_('single revision specified, nothing to fold\n'))
         return 1