hgext/evolve.py
changeset 1686 474db2d60202
parent 1685 4fd0db2f6d84
child 1687 73e0018c423f
--- a/hgext/evolve.py	Mon Apr 25 16:24:42 2016 -0700
+++ b/hgext/evolve.py	Mon Apr 25 16:24:42 2016 -0700
@@ -3160,14 +3160,18 @@
 
 @command('^metaedit',
          [('r', 'rev', [], _("revision to edit")),
+         ('', 'fold', None, _("also fold specified revisions into one")),
          ] + commitopts + commitopts2,
          _('hg metaedit [OPTION]... [-r] [REV]'))
 def metaedit(ui, repo, *revs, **opts):
     """edit commit information
 
-    Edits the commit information for the specified revision. By default, edits
+    Edits the commit information for the specified revisions. By default, edits
     commit information for the working directory parent.
 
+    With --fold, also folds multiple revisions into one if necessary. In this
+    case, the given revisions must form a linear unbroken chain.
+
     .. container:: verbose
 
      Some examples:
@@ -3180,10 +3184,19 @@
 
          hg metaedit --user 'New User <new-email@example.com>'
 
+     - Combine all draft revisions that are ancestors of foo but not of @ into
+       one::
+
+         hg metaedit --fold 'draft() and only(foo,@)'
+
+       See :hg:`help phases` for more about draft revisions, and
+       :hg:`help revsets` for more about the `draft()` and `only()` keywords.
     """
     revs = list(revs)
     revs.extend(opts['rev'])
     if not revs:
+        if opts['fold']:
+            raise error.Abort(_('revisions must be specified with --fold'))
         revs = ['.']
 
     wlock = lock = None
@@ -3192,7 +3205,7 @@
         lock = repo.lock()
 
         revs = scmutil.revrange(repo, revs)
-        if len(revs) > 1:
+        if not opts['fold'] and len(revs) > 1:
             # TODO: handle multiple revisions. This is somewhat tricky because
             # if we want to edit a series of commits:
             #
@@ -3201,18 +3214,21 @@
             # we need to rewrite a first, then directly rewrite b on top of the
             # new a, then rewrite c on top of the new b. So we need to handle
             # revisions in topological order.
-            raise error.Abort(_('editing multiple revisions is not '
-                                'currently supported'))
-
-        newunstable = _disallowednewunstable(repo, revs)
-        if newunstable:
-            raise error.Abort(
-                _('cannot edit commit information in the middle of a stack'),
-                hint=_('%s will be affected') % repo[newunstable.first()])
-        if repo.revs("%ld and public()", revs):
-            raise error.Abort(_('cannot edit commit information for public '
-                                'revisions'))
-        root = head = repo[revs.first()]
+            raise error.Abort(_('editing multiple revisions without --fold is '
+                                'not currently supported'))
+
+        if opts['fold']:
+            root, head = _foldcheck(repo, revs)
+        else:
+            newunstable = _disallowednewunstable(repo, revs)
+            if newunstable:
+                raise error.Abort(
+                    _('cannot edit commit information in the middle of a stack'),
+                    hint=_('%s will be affected') % repo[newunstable.first()])
+            if repo.revs("%ld and public()", revs):
+                raise error.Abort(_('cannot edit commit information for public '
+                                    'revisions'))
+            root = head = repo[revs.first()]
 
         wctx = repo[None]
         p1 = wctx.p1()
@@ -3226,7 +3242,12 @@
             if commitopts.get('message') or commitopts.get('logfile'):
                 commitopts['edit'] = False
             else:
-                msgs = [head.description()]
+                if opts['fold']:
+                    msgs = ["HG: This is a fold of %d changesets." % len(allctx)]
+                    msgs += ["HG: Commit message of changeset %s.\n\n%s\n" %
+                             (c.rev(), c.description()) for c in allctx]
+                else:
+                    msgs = [head.description()]
                 commitopts['message'] =  "\n".join(msgs)
                 commitopts['edit'] = True
 
@@ -3248,6 +3269,8 @@
         finally:
             tr.release()
 
+        if opts['fold']:
+            ui.status('%i changesets folded\n' % len(revs))
         if newp1 is not None:
             hg.update(repo, newp1)
     finally: