Patchwork [3,of,5,EVOLVE] fold: overhaul handling of multiple and single revisions (BC)

login
register
mail settings
Submitter Jordi Gutiérrez Hermoso
Date June 30, 2014, 6:28 p.m.
Message ID <0a970a5c0fecd98f16e4.1404152910@Iris>
Download mbox | patch
Permalink /patch/5085/
State Changes Requested
Headers show

Comments

Jordi Gutiérrez Hermoso - June 30, 2014, 6:28 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 0a970a5c0fecd98f16e4b9591713a5f516905646
# Parent  04afee1615a9823298b011ed1ab1ff1e2b686a1e
fold: overhaul 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 tests are modified accordingly.
Pierre-Yves David - June 30, 2014, 6:58 p.m.
On 06/30/2014 08:28 PM, Jordi Gutiérrez Hermoso wrote:
> # HG changeset patch
> # User Jordi Gutiérrez Hermoso <jordigh@octave.org>
> # Date 1404149389 14400
> #      Mon Jun 30 13:29:49 2014 -0400
> # Node ID 0a970a5c0fecd98f16e4b9591713a5f516905646
> # Parent  04afee1615a9823298b011ed1ab1ff1e2b686a1e
> fold: overhaul 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).

You are getting confuse about "single revision" vs "multiple revision". 
The only confusing and non-standar behavior is the semantic change when 
--rev is specified.

But both option alway accepted multiple revision.

> 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.

I feel like this sentence is over complicated. but this is not too 
important in the commit message.

> 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.
>
> diff --git a/hgext/evolve.py b/hgext/evolve.py
> --- a/hgext/evolve.py
> +++ b/hgext/evolve.py
> @@ -2074,32 +2074,42 @@ 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, _("ignore parent of working directory"))

No super fan of the --exact help test.
What about "Fold specified revision only"

>       ] + 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.

Fold a set of revision with working directory parent?

 >      The folded revisions
> +    will be marked as obsolete and replaced by the resulting revision.

I do not believe we want to mention obsolescence here. obsolescence is a 
global behavior of mercurial (so we do not need to specify it all the 
time) and and advances concept (should be thrown at new user so quickly 
in the help)

> -    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
> +    together with the parent of the working directory, along with any
> +    intermediate revisions.

Not sure this this is necessary, but usually does not hurt to tell the 
same thing in differnt way.


> +    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.

I find this a bit confusing. What about:

  You can use --exact to fold just the revision specified. Ignoring the 
working directory parent.
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:
>           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
>
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel@selenic.com
> http://selenic.com/mailman/listinfo/mercurial-devel
>

Patch

diff --git a/hgext/evolve.py b/hgext/evolve.py
--- a/hgext/evolve.py
+++ b/hgext/evolve.py
@@ -2074,32 +2074,42 @@  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, _("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
 
-    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
+    together with the parent of the working directory, along with any
+    intermediate revisions.
+
+    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:
         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