Patchwork [4,of,6,EVOLVE,V2] fold: overhaul handling of revisions with --rev (BC)

login
register
mail settings
Submitter Jordi Gutiérrez Hermoso
Date July 4, 2014, 2:37 p.m.
Message ID <abf61b77edd9214c75b9.1404484648@Iris>
Download mbox | patch
Permalink /patch/5104/
State Not Applicable
Headers show

Comments

Jordi Gutiérrez Hermoso - July 4, 2014, 2:37 p.m.
# HG changeset patch
# User Jordi Gutiérrez Hermoso <jordigh@octave.org>
# Date 1404149389 14400
#      Mon Jun 30 13:29:49 2014 -0400
# Node ID abf61b77edd9214c75b96a969a72279630cd4d62
# Parent  9e2a2864cd20d2160c44f4eab260f364eea523b5
fold: overhaul handling of revisions with --rev (BC)

The fold command parsed the revision arguments in a very peculiar and
idiosyncratic fashion: if revisions were passed without a --rev
argument, then they would all be extended to ".", but if they were
passed with --rev, then no extension would happen. Passing revisions
both with and without --rev would abort. 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. Regardless if a single or multiple revision is
specified, all will be folded together into 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 tests are modified accordingly.

Patch

diff --git a/hgext/evolve.py b/hgext/evolve.py
--- a/hgext/evolve.py
+++ b/hgext/evolve.py
@@ -2074,32 +2074,61 @@  def touch(ui, repo, *revs, **opts):
         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
 
-    The revisions from your current working directory to the given one are folded
-    into a single successor revision.
+    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.
 
-    you can alternatively use --rev to explicitly specify revisions to be folded,
-    ignoring the current working directory parent.
+    Use --exact for folding only the specified revisions 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::
+
+         hg fold .^
+
+     - Fold all draft revisions with working directory parent::
+
+         hg fold 'draft()'
+
+       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
diff --git a/tests/test-evolve.t b/tests/test-evolve.t
--- a/tests/test-evolve.t
+++ b/tests/test-evolve.t
@@ -616,27 +616,23 @@  Test fold
   $ hg fold
   abort: no revisions specified
   [255]
-  $ hg fold 6 --rev 10
-  abort: cannot specify both --rev and a target revision
-  [255]
   $ hg fold .
   single revision specified, nothing to fold
   [1]
+  $ hg fold 10 1
+  abort: cannot fold non-linear revisions
+  (given revisions are unrelated to parent of working directory)
+  [255]
+  $ hg fold -r 5
+  3 changesets folded
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ hg fold 6 # want to run hg fold 6
-  2 changesets folded
-  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  $ glog
-  @  11:dd4682c1a481@default(draft) add 1
-  |
-  o  5:0b9e50c35132@default(draft) add 3
-  |
-  o  4:ce341209337f@default(draft) add 4
-  |
-  | o  1:73d38bb17fd7@default(draft) add 1
-  |/
-  o  0:8685c6d34325@default(draft) add 0
+  abort: unknown revision '6'!
+  [255]
+  $ hg log -r 11 --template '{desc}\n'
+  add 3
   
-  $ hg log -r 11 --template '{desc}\n'
+  
   add 1
   
   
@@ -648,8 +644,8 @@  Test fold with wc parent is not the head
 
   $ hg up 4
   0 files updated, 0 files merged, 2 files removed, 0 files unresolved
-  $ hg fold --rev 4::11 --user victor
-  3 changesets folded
+  $ hg fold --rev 4::11 --user victor --exact
+  2 changesets folded
   2 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ glog
   @  12:d26d339c513f@default(draft) add 4
@@ -680,8 +676,7 @@  Test olog
 
   $ hg olog
   4	: add 4 - test
-  5	: add 3 - test
-  11	: add 1 - test
+  11	: add 3 - test
 
 Test obsstore stat