Patchwork histedit: use a single editor when multiple folds happen in a row (issue3524)

login
register
mail settings
Submitter Augie Fackler
Date Aug. 27, 2015, 7:02 p.m.
Message ID <348aa15022c88435679f.1440702124@arthedain.pit.corp.google.com>
Download mbox | patch
Permalink /patch/10297/
State Changes Requested
Headers show

Comments

Augie Fackler - Aug. 27, 2015, 7:02 p.m.
# HG changeset patch
# User Augie Fackler <augie@google.com>
# Date 1440701186 14400
#      Thu Aug 27 14:46:26 2015 -0400
# Node ID 348aa15022c88435679f0b376037e2318c467a38
# Parent  3670efdc70885ea0d1eaec101d598416d95490e2
histedit: use a single editor when multiple folds happen in a row (issue3524)

This was the first ever feature request for histedit, originally filed
back on April 4, 2009. Finally fixed.
Augie Fackler - Aug. 27, 2015, 7:35 p.m.
Derp, I just realized this has no test. v2 coming soon.

On Thu, Aug 27, 2015 at 3:02 PM, Augie Fackler <raf@durin42.com> wrote:
> # HG changeset patch
> # User Augie Fackler <augie@google.com>
> # Date 1440701186 14400
> #      Thu Aug 27 14:46:26 2015 -0400
> # Node ID 348aa15022c88435679f0b376037e2318c467a38
> # Parent  3670efdc70885ea0d1eaec101d598416d95490e2
> histedit: use a single editor when multiple folds happen in a row (issue3524)
>
> This was the first ever feature request for histedit, originally filed
> back on April 4, 2009. Finally fixed.
>
> diff --git a/hgext/histedit.py b/hgext/histedit.py
> --- a/hgext/histedit.py
> +++ b/hgext/histedit.py
> @@ -559,6 +559,9 @@ class fold(histeditaction):
>      def skipprompt(self):
>          return False
>
> +    def mergedescs(self):
> +        return True
> +
>      def finishfold(self, ui, repo, ctx, oldctx, newnode, internalchanges):
>          parent = ctx.parents()[0].node()
>          hg.update(repo, parent)
> @@ -566,7 +569,7 @@ class fold(histeditaction):
>          commitopts = {}
>          commitopts['user'] = ctx.user()
>          # commit message
> -        if self.skipprompt():
> +        if not self.mergedescs():
>              newmessage = ctx.description()
>          else:
>              newmessage = '\n***\n'.join(
> @@ -601,7 +604,22 @@ class fold(histeditaction):
>              replacements.append((ich, (n,)))
>          return repo[n], replacements
>
> +class _multifold(fold):
> +    """fold subclass used for when multiple folds happen in a row
> +
> +    We only want to fire the editor for the folded message once when
> +    (say) four CLs are folded down into a single change. This is
> +    similar to rollup, but we should preserve both messages so that
> +    when the last fold operation runs we can show the user all the
> +    commit messages in their editor.
> +    """
> +    def skipprompt(self):
> +        return True
> +
>  class rollup(fold):
> +    def mergedescs(self):
> +        return False
> +
>      def skipprompt(self):
>          return True
>
> @@ -644,6 +662,7 @@ actiontable = {'p': pick,
>                 'edit': edit,
>                 'f': fold,
>                 'fold': fold,
> +               '_multifold': _multifold,
>                 'r': rollup,
>                 'roll': rollup,
>                 'd': drop,
> @@ -850,6 +869,17 @@ def _histedit(ui, repo, state, *freeargs
>                                          'histedit')
>          state.backupfile = backupfile
>
> +    # preprocess rules so that we can hide inner folds from the user
> +    # and only show one editor
> +    rules = state.rules[:]
> +    for idx, ((prevact, unused), (action, ha), (nextact, unused)) in enumerate(
> +            zip(rules, rules[1:], rules[2:])):
> +        if (action == 'fold'
> +            and prevact in ('fold', '_multifold')
> +            and nextact == 'fold'):
> +            print 'mutated rule', idx, 'to a multifold'
> +            state.rules[idx] = '_multifold', ha
> +
>      while state.rules:
>          state.write()
>          action, ha = state.rules.pop(0)
> @@ -995,7 +1025,7 @@ def verifyrules(rules, repo, ctxs):
>              raise util.Abort(_('duplicated command for changeset %s') %
>                      ha[:12])
>          seen.add(ha)
> -        if action not in actiontable:
> +        if action not in actiontable or action.startswith('_'):
>              raise util.Abort(_('unknown action "%s"') % action)
>          parsed.append([action, ha])
>      missing = sorted(expected - seen)  # sort to stabilize output
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel@selenic.com
> https://selenic.com/mailman/listinfo/mercurial-devel

Patch

diff --git a/hgext/histedit.py b/hgext/histedit.py
--- a/hgext/histedit.py
+++ b/hgext/histedit.py
@@ -559,6 +559,9 @@  class fold(histeditaction):
     def skipprompt(self):
         return False
 
+    def mergedescs(self):
+        return True
+
     def finishfold(self, ui, repo, ctx, oldctx, newnode, internalchanges):
         parent = ctx.parents()[0].node()
         hg.update(repo, parent)
@@ -566,7 +569,7 @@  class fold(histeditaction):
         commitopts = {}
         commitopts['user'] = ctx.user()
         # commit message
-        if self.skipprompt():
+        if not self.mergedescs():
             newmessage = ctx.description()
         else:
             newmessage = '\n***\n'.join(
@@ -601,7 +604,22 @@  class fold(histeditaction):
             replacements.append((ich, (n,)))
         return repo[n], replacements
 
+class _multifold(fold):
+    """fold subclass used for when multiple folds happen in a row
+
+    We only want to fire the editor for the folded message once when
+    (say) four CLs are folded down into a single change. This is
+    similar to rollup, but we should preserve both messages so that
+    when the last fold operation runs we can show the user all the
+    commit messages in their editor.
+    """
+    def skipprompt(self):
+        return True
+
 class rollup(fold):
+    def mergedescs(self):
+        return False
+
     def skipprompt(self):
         return True
 
@@ -644,6 +662,7 @@  actiontable = {'p': pick,
                'edit': edit,
                'f': fold,
                'fold': fold,
+               '_multifold': _multifold,
                'r': rollup,
                'roll': rollup,
                'd': drop,
@@ -850,6 +869,17 @@  def _histedit(ui, repo, state, *freeargs
                                         'histedit')
         state.backupfile = backupfile
 
+    # preprocess rules so that we can hide inner folds from the user
+    # and only show one editor
+    rules = state.rules[:]
+    for idx, ((prevact, unused), (action, ha), (nextact, unused)) in enumerate(
+            zip(rules, rules[1:], rules[2:])):
+        if (action == 'fold'
+            and prevact in ('fold', '_multifold')
+            and nextact == 'fold'):
+            print 'mutated rule', idx, 'to a multifold'
+            state.rules[idx] = '_multifold', ha
+
     while state.rules:
         state.write()
         action, ha = state.rules.pop(0)
@@ -995,7 +1025,7 @@  def verifyrules(rules, repo, ctxs):
             raise util.Abort(_('duplicated command for changeset %s') %
                     ha[:12])
         seen.add(ha)
-        if action not in actiontable:
+        if action not in actiontable or action.startswith('_'):
             raise util.Abort(_('unknown action "%s"') % action)
         parsed.append([action, ha])
     missing = sorted(expected - seen)  # sort to stabilize output