Patchwork [v2] histedit: add "amen" command to fold commit data and drop message (issue4256)

login
register
mail settings
Submitter adgar@google.com
Date Aug. 11, 2014, 6:31 p.m.
Message ID <40809b1ede87da3184d0.1407781864@adgar.nyc.corp.google.com>
Download mbox | patch
Permalink /patch/5342/
State Changes Requested
Headers show

Comments

adgar@google.com - Aug. 11, 2014, 6:31 p.m.
# HG changeset patch
# User Mike Edgar <adgar@google.com>
# Date 1407358301 14400
#      Wed Aug 06 16:51:41 2014 -0400
# Node ID 40809b1ede87da3184d06cfccee966dd4aea72fe
# Parent  4354b1e35f533f72d5b6ccc76e8bc742f8cb5257
histedit: add "amen" command to fold commit data and drop message (issue4256)

This new histedit command (short for "amend") acts like "hg amend" does for
working copy: it accumulates changes without interrupting the user and asking
for an updated commit message.
Augie Fackler - Aug. 11, 2014, 10:13 p.m.
On Aug 11, 2014, at 2:31 PM, adgar@google.com wrote:

> # HG changeset patch
> # User Mike Edgar <adgar@google.com>
> # Date 1407358301 14400
> #      Wed Aug 06 16:51:41 2014 -0400
> # Node ID 40809b1ede87da3184d06cfccee966dd4aea72fe
> # Parent  4354b1e35f533f72d5b6ccc76e8bc742f8cb5257
> histedit: add "amen" command to fold commit data and drop message (issue4256)
> 
> This new histedit command (short for "amend") acts like "hg amend" does for
> working copy: it accumulates changes without interrupting the user and asking
> for an updated commit message.
> 
> diff -r 4354b1e35f53 -r 40809b1ede87 hgext/histedit.py
> --- a/hgext/histedit.py	Wed Aug 06 12:16:58 2014 -0500
> +++ b/hgext/histedit.py	Wed Aug 06 16:51:41 2014 -0400
> @@ -36,6 +36,7 @@
>  #  p, pick = use commit
>  #  e, edit = use commit, but stop for amending
>  #  f, fold = use commit, but combine it with the one above
> + #  a, amen = add commit content to one above, dropping message (hg amend)

Sorry, I should have caught this earlier: 'hg amend' is actually from evolution, not core. Perhaps just drop that for now? I'm happy to do that during patch application if that seems sensible to everyone.

>  #  d, drop = remove commit from history
>  #  m, mess = edit message without changing commit content
>  #
> @@ -57,6 +58,7 @@
>  #  p, pick = use commit
>  #  e, edit = use commit, but stop for amending
>  #  f, fold = use commit, but combine it with the one above
> + #  a, amen = add commit content to one above, dropping message (hg amend)
>  #  d, drop = remove commit from history
>  #  m, mess = edit message without changing commit content
>  #
> @@ -179,6 +181,7 @@
> #  p, pick = use commit
> #  e, edit = use commit, but stop for amending
> #  f, fold = use commit, but combine it with the one above
> +#  a, amen = add commit content to one above, dropping message (hg amend)
> #  d, drop = remove commit from history
> #  m, mess = edit message without changing commit content
> #
> @@ -293,7 +296,9 @@
>     extra = commitopts.get('extra')
> 
>     parents = (first.p1().node(), first.p2().node())
> -    editor = cmdutil.getcommiteditor(edit=True, editform='histedit.fold')
> +    editor = None
> +    if not commitopts.get('amend'):
> +        editor = cmdutil.getcommiteditor(edit=True, editform='histedit.fold')
>     new = context.memctx(repo,
>                          parents=parents,
>                          text=message,
> @@ -335,6 +340,11 @@
>         _('Make changes as needed, you may commit or record as needed now.\n'
>           'When you are finished, run hg histedit --continue to resume.'))
> 
> +def amend(ui, repo, ctx, ha, opts):
> +    amendopts = opts.copy()
> +    amendopts['amend'] = True
> +    return fold(ui, repo, ctx, ha, amendopts)
> +
> def fold(ui, repo, ctx, ha, opts):
>     oldctx = repo[ha]
>     hg.update(repo, ctx.node())
> @@ -362,10 +372,13 @@
>         username = ui.username()
>     commitopts['user'] = username
>     # commit message
> -    newmessage = '\n***\n'.join(
> -        [ctx.description()] +
> -        [repo[r].description() for r in internalchanges] +
> -        [oldctx.description()]) + '\n'
> +    if opts.get('amend'):
> +        newmessage = ctx.description()
> +    else:
> +        newmessage = '\n***\n'.join(
> +            [ctx.description()] +
> +            [repo[r].description() for r in internalchanges] +
> +            [oldctx.description()]) + '\n'
>     commitopts['message'] = newmessage
>     # date
>     commitopts['date'] = max(ctx.date(), oldctx.date())
> @@ -446,6 +459,8 @@
>                'edit': edit,
>                'f': fold,
>                'fold': fold,
> +               'a': amend,
> +               'amen': amend,
>                'd': drop,
>                'drop': drop,
>                'm': message,
> @@ -681,7 +696,7 @@
>     m, a, r, d = repo.status()[:4]
>     if m or a or r or d:
>         # prepare the message for the commit to comes
> -        if action in ('f', 'fold'):
> +        if action in ('f', 'fold', 'a', 'amen'):
>             message = 'fold-temp-revision %s' % currentnode
>         else:
>             message = ctx.description()
> @@ -704,15 +719,19 @@
>         # to parent.
>         replacements.append((ctx.node(), tuple(newchildren)))
> 
> -    if action in ('f', 'fold'):
> +    if action in ('f', 'fold', 'a', 'amen'):
>         if newchildren:
>             # finalize fold operation if applicable
>             if new is None:
>                 new = newchildren[-1]
>             else:
>                 newchildren.pop()  # remove new from internal changes
> -            parentctx, repl = finishfold(ui, repo, parentctx, ctx, new, opts,
> -                                         newchildren)
> +            foldopts = opts
> +            if action in ('a', 'amen'):
> +                foldopts = foldopts.copy()
> +                foldopts['amend'] = True
> +            parentctx, repl = finishfold(ui, repo, parentctx, ctx, new,
> +                                         foldopts, newchildren)
>             replacements.extend(repl)
>         else:
>             # newchildren is empty if the fold did not result in any commit
> diff -r 4354b1e35f53 -r 40809b1ede87 tests/test-histedit-arguments.t
> --- a/tests/test-histedit-arguments.t	Wed Aug 06 12:16:58 2014 -0500
> +++ b/tests/test-histedit-arguments.t	Wed Aug 06 16:51:41 2014 -0400
> @@ -57,6 +57,7 @@
>   #  p, pick = use commit
>   #  e, edit = use commit, but stop for amending
>   #  f, fold = use commit, but combine it with the one above
> +  #  a, amen = add commit content to one above, dropping message (hg amend)
>   #  d, drop = remove commit from history
>   #  m, mess = edit message without changing commit content
>   #
> @@ -255,6 +256,7 @@
>   #  p, pick = use commit
>   #  e, edit = use commit, but stop for amending
>   #  f, fold = use commit, but combine it with the one above
> +  #  a, amen = add commit content to one above, dropping message (hg amend)
>   #  d, drop = remove commit from history
>   #  m, mess = edit message without changing commit content
>   #
> diff -r 4354b1e35f53 -r 40809b1ede87 tests/test-histedit-bookmark-motion.t
> --- a/tests/test-histedit-bookmark-motion.t	Wed Aug 06 12:16:58 2014 -0500
> +++ b/tests/test-histedit-bookmark-motion.t	Wed Aug 06 16:51:41 2014 -0400
> @@ -73,6 +73,7 @@
>   #  p, pick = use commit
>   #  e, edit = use commit, but stop for amending
>   #  f, fold = use commit, but combine it with the one above
> +  #  a, amen = add commit content to one above, dropping message (hg amend)
>   #  d, drop = remove commit from history
>   #  m, mess = edit message without changing commit content
>   #
> @@ -133,6 +134,7 @@
>   #  p, pick = use commit
>   #  e, edit = use commit, but stop for amending
>   #  f, fold = use commit, but combine it with the one above
> +  #  a, amen = add commit content to one above, dropping message (hg amend)
>   #  d, drop = remove commit from history
>   #  m, mess = edit message without changing commit content
>   #
> diff -r 4354b1e35f53 -r 40809b1ede87 tests/test-histedit-commute.t
> --- a/tests/test-histedit-commute.t	Wed Aug 06 12:16:58 2014 -0500
> +++ b/tests/test-histedit-commute.t	Wed Aug 06 16:51:41 2014 -0400
> @@ -67,6 +67,7 @@
>   #  p, pick = use commit
>   #  e, edit = use commit, but stop for amending
>   #  f, fold = use commit, but combine it with the one above
> +  #  a, amen = add commit content to one above, dropping message (hg amend)
>   #  d, drop = remove commit from history
>   #  m, mess = edit message without changing commit content
>   #
> @@ -344,6 +345,7 @@
>   #  p, pick = use commit
>   #  e, edit = use commit, but stop for amending
>   #  f, fold = use commit, but combine it with the one above
> +  #  a, amen = add commit content to one above, dropping message (hg amend)
>   #  d, drop = remove commit from history
>   #  m, mess = edit message without changing commit content
>   #
> diff -r 4354b1e35f53 -r 40809b1ede87 tests/test-histedit-fold-non-commute.t
> --- a/tests/test-histedit-fold-non-commute.t	Wed Aug 06 12:16:58 2014 -0500
> +++ b/tests/test-histedit-fold-non-commute.t	Wed Aug 06 16:51:41 2014 -0400
> @@ -183,3 +183,165 @@
>   f
> 
>   $ cd ..
> +
> +Repeat test using "amen", not "fold". "amen" folds in changes but drops message
> +
> +  $ initrepo r2
> +  $ cd r2
> +
> +Initial generation of the command files
> +
> +  $ EDITED="$TESTTMP/editedhistory.2"
> +  $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 3 >> $EDITED
> +  $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 4 >> $EDITED
> +  $ hg log --template 'amen {node|short} {rev} {desc}\n' -r 7 >> $EDITED
> +  $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 5 >> $EDITED
> +  $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 6 >> $EDITED
> +  $ cat $EDITED
> +  pick 65a9a84f33fd 3 c
> +  pick 00f1c5383965 4 d
> +  amen 39522b764e3d 7 does not commute with e
> +  pick 7b4e2f4b7bcd 5 e
> +  pick 500cac37a696 6 f
> +
> +log before edit
> +  $ hg log --graph
> +  @  changeset:   7:39522b764e3d
> +  |  tag:         tip
> +  |  user:        test
> +  |  date:        Thu Jan 01 00:00:00 1970 +0000
> +  |  summary:     does not commute with e
> +  |
> +  o  changeset:   6:500cac37a696
> +  |  user:        test
> +  |  date:        Thu Jan 01 00:00:00 1970 +0000
> +  |  summary:     f
> +  |
> +  o  changeset:   5:7b4e2f4b7bcd
> +  |  user:        test
> +  |  date:        Thu Jan 01 00:00:00 1970 +0000
> +  |  summary:     e
> +  |
> +  o  changeset:   4:00f1c5383965
> +  |  user:        test
> +  |  date:        Thu Jan 01 00:00:00 1970 +0000
> +  |  summary:     d
> +  |
> +  o  changeset:   3:65a9a84f33fd
> +  |  user:        test
> +  |  date:        Thu Jan 01 00:00:00 1970 +0000
> +  |  summary:     c
> +  |
> +  o  changeset:   2:da6535b52e45
> +  |  user:        test
> +  |  date:        Thu Jan 01 00:00:00 1970 +0000
> +  |  summary:     b
> +  |
> +  o  changeset:   1:c1f09da44841
> +  |  user:        test
> +  |  date:        Thu Jan 01 00:00:00 1970 +0000
> +  |  summary:     a
> +  |
> +  o  changeset:   0:1715188a53c7
> +     user:        test
> +     date:        Thu Jan 01 00:00:00 1970 +0000
> +     summary:     Initial commit
> +  
> +
> +edit the history
> +  $ hg histedit 3 --commands $EDITED 2>&1 | fixbundle
> +  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
> +  merging e
> +  warning: conflicts during merge.
> +  merging e incomplete! (edit conflicts, then use 'hg resolve --mark')
> +  Fix up the change and run hg histedit --continue
> +
> +fix up
> +  $ echo 'I can haz no commute' > e
> +  $ hg resolve --mark e
> +  (no more unresolved files)
> +  $ hg histedit --continue 2>&1 | fixbundle | grep -v '2 files removed'
> +  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
> +  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
> +  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
> +  merging e
> +  warning: conflicts during merge.
> +  merging e incomplete! (edit conflicts, then use 'hg resolve --mark')
> +  Fix up the change and run hg histedit --continue
> +
> +just continue this time
> +  $ hg revert -r 'p1()' e
> +  $ hg resolve --mark e
> +  (no more unresolved files)
> +  $ hg histedit --continue 2>&1 | fixbundle
> +  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
> +  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
> +
> +log after edit
> +  $ hg log --graph
> +  @  changeset:   5:e7c4f5d4eb75
> +  |  tag:         tip
> +  |  user:        test
> +  |  date:        Thu Jan 01 00:00:00 1970 +0000
> +  |  summary:     f
> +  |
> +  o  changeset:   4:803d1bb561fc
> +  |  user:        test
> +  |  date:        Thu Jan 01 00:00:00 1970 +0000
> +  |  summary:     d
> +  |
> +  o  changeset:   3:65a9a84f33fd
> +  |  user:        test
> +  |  date:        Thu Jan 01 00:00:00 1970 +0000
> +  |  summary:     c
> +  |
> +  o  changeset:   2:da6535b52e45
> +  |  user:        test
> +  |  date:        Thu Jan 01 00:00:00 1970 +0000
> +  |  summary:     b
> +  |
> +  o  changeset:   1:c1f09da44841
> +  |  user:        test
> +  |  date:        Thu Jan 01 00:00:00 1970 +0000
> +  |  summary:     a
> +  |
> +  o  changeset:   0:1715188a53c7
> +     user:        test
> +     date:        Thu Jan 01 00:00:00 1970 +0000
> +     summary:     Initial commit
> +  
> +
> +contents of e
> +  $ hg cat e
> +  I can haz no commute
> +
> +manifest
> +  $ hg manifest
> +  a
> +  b
> +  c
> +  d
> +  e
> +  f
> +
> +description is taken from amended commit
> +
> +  $ hg log --debug --rev 4
> +  changeset:   4:803d1bb561fceac3129ec778db9da249a3106fc3
> +  phase:       draft
> +  parent:      3:65a9a84f33fdeb1ad5679b3941ec885d2b24027b
> +  parent:      -1:0000000000000000000000000000000000000000
> +  manifest:    4:b068a323d969f22af1296ec6a5ea9384cef437ac
> +  user:        test
> +  date:        Thu Jan 01 00:00:00 1970 +0000
> +  files:       d e
> +  extra:       branch=default
> +  extra:       histedit_source=00f1c53839651fa5c76d423606811ea5455a79d0,39522b764e3d26103f08bd1fa2ccd3e3d7dbcf4e
> +  description:
> +  d
> +  
> +  
> +
> +done with repo r2
> +
> +  $ cd ..
> diff -r 4354b1e35f53 -r 40809b1ede87 tests/test-histedit-fold.t
> --- a/tests/test-histedit-fold.t	Wed Aug 06 12:16:58 2014 -0500
> +++ b/tests/test-histedit-fold.t	Wed Aug 06 16:51:41 2014 -0400
> @@ -105,6 +105,50 @@
> 
> 
> 
> +amend will fold without preserving the folded commit's message
> +
> +  $ hg histedit d2ae7f538514 --commands - 2>&1 <<EOF | fixbundle
> +  > pick d2ae7f538514 b
> +  > amen ee283cb5f2d5 e
> +  > pick 6de59d13424a f
> +  > pick 9c277da72c9b d
> +  > EOF
> +  0 files updated, 0 files merged, 4 files removed, 0 files unresolved
> +  0 files updated, 0 files merged, 2 files removed, 0 files unresolved
> +  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
> +  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
> +  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
> +  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
> +
> +log after edit
> +  $ hg logt --graph
> +  @  3:c4a9eb7989fc d
> +  |
> +  o  2:8e03a72b6f83 f
> +  |
> +  o  1:391ee782c689 b
> +  |
> +  o  0:cb9a9f314b8b a
> +  
> +
> +description is taken from amended commit
> +
> +  $ hg log --debug --rev 1
> +  changeset:   1:391ee782c68930be438ccf4c6a403daedbfbffa5
> +  phase:       draft
> +  parent:      0:cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
> +  parent:      -1:0000000000000000000000000000000000000000
> +  manifest:    1:b5e112a3a8354e269b1524729f0918662d847c38
> +  user:        test
> +  date:        Thu Jan 01 00:00:00 1970 +0000
> +  files+:      b e
> +  extra:       branch=default
> +  extra:       histedit_source=d2ae7f538514cd87c17547b0de4cea71fe1af9fb,ee283cb5f2d5955443f23a27b697a04339e9a39a
> +  description:
> +  b
> +  
> +  
> +
> check saving last-message.txt
> 
>   $ cat > $TESTTMP/abortfolding.py <<EOF
> @@ -128,9 +172,9 @@
>> EOF
> 
>   $ rm -f .hg/last-message.txt
> -  $ HGEDITOR="sh $TESTTMP/editor.sh" hg histedit 6de59d13424a --commands - 2>&1 <<EOF | fixbundle
> -  > pick 6de59d13424a f
> -  > fold 9c277da72c9b d
> +  $ HGEDITOR="sh $TESTTMP/editor.sh" hg histedit 8e03a72b6f83 --commands - 2>&1 <<EOF | fixbundle
> +  > pick 8e03a72b6f83 f
> +  > fold c4a9eb7989fc d
>> EOF
>   0 files updated, 0 files merged, 1 files removed, 0 files unresolved
>   allow non-folding commit
> diff -r 4354b1e35f53 -r 40809b1ede87 tests/test-histedit-obsolete.t
> --- a/tests/test-histedit-obsolete.t	Wed Aug 06 12:16:58 2014 -0500
> +++ b/tests/test-histedit-obsolete.t	Wed Aug 06 16:51:41 2014 -0400
> @@ -57,6 +57,7 @@
>   #  p, pick = use commit
>   #  e, edit = use commit, but stop for amending
>   #  f, fold = use commit, but combine it with the one above
> +  #  a, amen = add commit content to one above, dropping message (hg amend)
>   #  d, drop = remove commit from history
>   #  m, mess = edit message without changing commit content
>   #
> diff -r 4354b1e35f53 -r 40809b1ede87 tests/test-histedit-outgoing.t
> --- a/tests/test-histedit-outgoing.t	Wed Aug 06 12:16:58 2014 -0500
> +++ b/tests/test-histedit-outgoing.t	Wed Aug 06 16:51:41 2014 -0400
> @@ -49,6 +49,7 @@
>   #  p, pick = use commit
>   #  e, edit = use commit, but stop for amending
>   #  f, fold = use commit, but combine it with the one above
> +  #  a, amen = add commit content to one above, dropping message (hg amend)
>   #  d, drop = remove commit from history
>   #  m, mess = edit message without changing commit content
>   #
> @@ -80,6 +81,7 @@
>   #  p, pick = use commit
>   #  e, edit = use commit, but stop for amending
>   #  f, fold = use commit, but combine it with the one above
> +  #  a, amen = add commit content to one above, dropping message (hg amend)
>   #  d, drop = remove commit from history
>   #  m, mess = edit message without changing commit content
>   #
> @@ -103,6 +105,7 @@
>   #  p, pick = use commit
>   #  e, edit = use commit, but stop for amending
>   #  f, fold = use commit, but combine it with the one above
> +  #  a, amen = add commit content to one above, dropping message (hg amend)
>   #  d, drop = remove commit from history
>   #  m, mess = edit message without changing commit content
>   #
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel@selenic.com
> http://selenic.com/mailman/listinfo/mercurial-devel
Pierre-Yves David - Aug. 11, 2014, 10:16 p.m.
On 08/11/2014 03:13 PM, Augie Fackler wrote:
>
> On Aug 11, 2014, at 2:31 PM, adgar@google.com wrote:
>
>> # HG changeset patch
>> # User Mike Edgar <adgar@google.com>
>> # Date 1407358301 14400
>> #      Wed Aug 06 16:51:41 2014 -0400
>> # Node ID 40809b1ede87da3184d06cfccee966dd4aea72fe
>> # Parent  4354b1e35f533f72d5b6ccc76e8bc742f8cb5257
>> histedit: add "amen" command to fold commit data and drop message (issue4256)
>>
>> This new histedit command (short for "amend") acts like "hg amend" does for
>> working copy: it accumulates changes without interrupting the user and asking
>> for an updated commit message.
>>
>> diff -r 4354b1e35f53 -r 40809b1ede87 hgext/histedit.py
>> --- a/hgext/histedit.py	Wed Aug 06 12:16:58 2014 -0500
>> +++ b/hgext/histedit.py	Wed Aug 06 16:51:41 2014 -0400
>> @@ -36,6 +36,7 @@
>>   #  p, pick = use commit
>>   #  e, edit = use commit, but stop for amending
>>   #  f, fold = use commit, but combine it with the one above
>> + #  a, amen = add commit content to one above, dropping message (hg amend)
>
> Sorry, I should have caught this earlier: 'hg amend' is actually from evolution, not core. Perhaps just drop that for now? I'm happy to do that during patch application if that seems sensible to everyone.

Fine with me. Push it!
Matt Mackall - Aug. 12, 2014, 7:05 a.m.
On Mon, 2014-08-11 at 14:31 -0400, adgar@google.com wrote:
> # HG changeset patch
> # User Mike Edgar <adgar@google.com>
> # Date 1407358301 14400
> #      Wed Aug 06 16:51:41 2014 -0400
> # Node ID 40809b1ede87da3184d06cfccee966dd4aea72fe
> # Parent  4354b1e35f533f72d5b6ccc76e8bc742f8cb5257
> histedit: add "amen" command to fold commit data and drop message (issue4256)

So in looking closer at this, I spotted the following problem:

>   #  e, edit = use commit, but stop for amending
> + #  a, amen = add commit content to one above, dropping message (hg amend)

We're using amend in two different ways on these two lines, and arguably
the first one is the 'correct' usage (ie hg commit --amend or hg amend =
fold in working directory contents, not another commit). Plus the whole
awkward five letter thing.

A bit more brainstorming and I've come up with:

  #  f, fold = use commit, but combine it with the one above
  #  r, roll = like fold, but discard this commit's description

(The new message has the added benefit of simultaneously expanding on
fold's description.)

This suggests 'roll up', which keeps with the 'fold up' metaphor, while
suggesting a more Katamari-esque process.

Alternately, join. Both suboptimal, but 'hg help -k {roll,join}'
suggests they're both not overloaded anywhere.

A last possibility to consider: we might want to instead start adding
modifiers to the action letters instead of adding new letters to make
slight modifications.. for instance, f! or F:

  #  f, fold = use commit, but combine it with the one above
  #  F       = like fold, but discard this commit's description
adgar@google.com - Aug. 13, 2014, 6:59 p.m.
On 08/12/2014 03:05 AM, Matt Mackall wrote:
> On Mon, 2014-08-11 at 14:31 -0400, adgar@google.com wrote:
>> # HG changeset patch
>> # User Mike Edgar <adgar@google.com>
>> # Date 1407358301 14400
>> #      Wed Aug 06 16:51:41 2014 -0400
>> # Node ID 40809b1ede87da3184d06cfccee966dd4aea72fe
>> # Parent  4354b1e35f533f72d5b6ccc76e8bc742f8cb5257
>> histedit: add "amen" command to fold commit data and drop message (issue4256)
>
> So in looking closer at this, I spotted the following problem:
>
>>    #  e, edit = use commit, but stop for amending
>> + #  a, amen = add commit content to one above, dropping message (hg amend)
>
> We're using amend in two different ways on these two lines, and arguably
> the first one is the 'correct' usage (ie hg commit --amend or hg amend =
> fold in working directory contents, not another commit). Plus the whole
> awkward five letter thing.

I'm glad you brought that up, Matt - I noticed the multiple uses of 
"amend" but wasn't sure if it would be confusing for others. All told, I 
think amend is a procrustean choice and we can do better.

In the future, should I flag these sorts of details explicitly in a 
followup e-mail to my patch?

> A bit more brainstorming and I've come up with:
>
>    #  f, fold = use commit, but combine it with the one above
>    #  r, roll = like fold, but discard this commit's description
>
> (The new message has the added benefit of simultaneously expanding on
> fold's description.)
>
> This suggests 'roll up', which keeps with the 'fold up' metaphor, while
> suggesting a more Katamari-esque process.
>
> Alternately, join. Both suboptimal, but 'hg help -k {roll,join}'
> suggests they're both not overloaded anywhere.

I like roll ala 'rollup' a lot! I've seen rollup used in the context of 
cutting release branches (also reporting) and think it typically 
suggests a loss of precision in metadata in the resulting aggregate.

I had considered join but thought it might confusingly suggest a 
relational join or a partial order join.

> A last possibility to consider: we might want to instead start adding
> modifiers to the action letters instead of adding new letters to make
> slight modifications.. for instance, f! or F:
>
>    #  f, fold = use commit, but combine it with the one above
>    #  F       = like fold, but discard this commit's description
>

I'd personally be nervous about typos or mixing the two up. That's one 
reason why I currently always use the 4-letter verbs. Would this 
possibility only work for the short form?
Matt Mackall - Aug. 13, 2014, 7:16 p.m.
On Wed, 2014-08-13 at 14:59 -0400, Mike Edgar wrote:
> In the future, should I flag these sorts of details explicitly in a 
> followup e-mail to my patch?

You are encouraged to put _anything relevant_ in the commit message.
Future archaeologists (possibly you) will thank you.

> > A bit more brainstorming and I've come up with:
> >
> >    #  f, fold = use commit, but combine it with the one above
> >    #  r, roll = like fold, but discard this commit's description
..
> I like roll ala 'rollup' a lot!

Ok, let's go with 'roll'.

Patch

diff -r 4354b1e35f53 -r 40809b1ede87 hgext/histedit.py
--- a/hgext/histedit.py	Wed Aug 06 12:16:58 2014 -0500
+++ b/hgext/histedit.py	Wed Aug 06 16:51:41 2014 -0400
@@ -36,6 +36,7 @@ 
  #  p, pick = use commit
  #  e, edit = use commit, but stop for amending
  #  f, fold = use commit, but combine it with the one above
+ #  a, amen = add commit content to one above, dropping message (hg amend)
  #  d, drop = remove commit from history
  #  m, mess = edit message without changing commit content
  #
@@ -57,6 +58,7 @@ 
  #  p, pick = use commit
  #  e, edit = use commit, but stop for amending
  #  f, fold = use commit, but combine it with the one above
+ #  a, amen = add commit content to one above, dropping message (hg amend)
  #  d, drop = remove commit from history
  #  m, mess = edit message without changing commit content
  #
@@ -179,6 +181,7 @@ 
 #  p, pick = use commit
 #  e, edit = use commit, but stop for amending
 #  f, fold = use commit, but combine it with the one above
+#  a, amen = add commit content to one above, dropping message (hg amend)
 #  d, drop = remove commit from history
 #  m, mess = edit message without changing commit content
 #
@@ -293,7 +296,9 @@ 
     extra = commitopts.get('extra')
 
     parents = (first.p1().node(), first.p2().node())
-    editor = cmdutil.getcommiteditor(edit=True, editform='histedit.fold')
+    editor = None
+    if not commitopts.get('amend'):
+        editor = cmdutil.getcommiteditor(edit=True, editform='histedit.fold')
     new = context.memctx(repo,
                          parents=parents,
                          text=message,
@@ -335,6 +340,11 @@ 
         _('Make changes as needed, you may commit or record as needed now.\n'
           'When you are finished, run hg histedit --continue to resume.'))
 
+def amend(ui, repo, ctx, ha, opts):
+    amendopts = opts.copy()
+    amendopts['amend'] = True
+    return fold(ui, repo, ctx, ha, amendopts)
+
 def fold(ui, repo, ctx, ha, opts):
     oldctx = repo[ha]
     hg.update(repo, ctx.node())
@@ -362,10 +372,13 @@ 
         username = ui.username()
     commitopts['user'] = username
     # commit message
-    newmessage = '\n***\n'.join(
-        [ctx.description()] +
-        [repo[r].description() for r in internalchanges] +
-        [oldctx.description()]) + '\n'
+    if opts.get('amend'):
+        newmessage = ctx.description()
+    else:
+        newmessage = '\n***\n'.join(
+            [ctx.description()] +
+            [repo[r].description() for r in internalchanges] +
+            [oldctx.description()]) + '\n'
     commitopts['message'] = newmessage
     # date
     commitopts['date'] = max(ctx.date(), oldctx.date())
@@ -446,6 +459,8 @@ 
                'edit': edit,
                'f': fold,
                'fold': fold,
+               'a': amend,
+               'amen': amend,
                'd': drop,
                'drop': drop,
                'm': message,
@@ -681,7 +696,7 @@ 
     m, a, r, d = repo.status()[:4]
     if m or a or r or d:
         # prepare the message for the commit to comes
-        if action in ('f', 'fold'):
+        if action in ('f', 'fold', 'a', 'amen'):
             message = 'fold-temp-revision %s' % currentnode
         else:
             message = ctx.description()
@@ -704,15 +719,19 @@ 
         # to parent.
         replacements.append((ctx.node(), tuple(newchildren)))
 
-    if action in ('f', 'fold'):
+    if action in ('f', 'fold', 'a', 'amen'):
         if newchildren:
             # finalize fold operation if applicable
             if new is None:
                 new = newchildren[-1]
             else:
                 newchildren.pop()  # remove new from internal changes
-            parentctx, repl = finishfold(ui, repo, parentctx, ctx, new, opts,
-                                         newchildren)
+            foldopts = opts
+            if action in ('a', 'amen'):
+                foldopts = foldopts.copy()
+                foldopts['amend'] = True
+            parentctx, repl = finishfold(ui, repo, parentctx, ctx, new,
+                                         foldopts, newchildren)
             replacements.extend(repl)
         else:
             # newchildren is empty if the fold did not result in any commit
diff -r 4354b1e35f53 -r 40809b1ede87 tests/test-histedit-arguments.t
--- a/tests/test-histedit-arguments.t	Wed Aug 06 12:16:58 2014 -0500
+++ b/tests/test-histedit-arguments.t	Wed Aug 06 16:51:41 2014 -0400
@@ -57,6 +57,7 @@ 
   #  p, pick = use commit
   #  e, edit = use commit, but stop for amending
   #  f, fold = use commit, but combine it with the one above
+  #  a, amen = add commit content to one above, dropping message (hg amend)
   #  d, drop = remove commit from history
   #  m, mess = edit message without changing commit content
   #
@@ -255,6 +256,7 @@ 
   #  p, pick = use commit
   #  e, edit = use commit, but stop for amending
   #  f, fold = use commit, but combine it with the one above
+  #  a, amen = add commit content to one above, dropping message (hg amend)
   #  d, drop = remove commit from history
   #  m, mess = edit message without changing commit content
   #
diff -r 4354b1e35f53 -r 40809b1ede87 tests/test-histedit-bookmark-motion.t
--- a/tests/test-histedit-bookmark-motion.t	Wed Aug 06 12:16:58 2014 -0500
+++ b/tests/test-histedit-bookmark-motion.t	Wed Aug 06 16:51:41 2014 -0400
@@ -73,6 +73,7 @@ 
   #  p, pick = use commit
   #  e, edit = use commit, but stop for amending
   #  f, fold = use commit, but combine it with the one above
+  #  a, amen = add commit content to one above, dropping message (hg amend)
   #  d, drop = remove commit from history
   #  m, mess = edit message without changing commit content
   #
@@ -133,6 +134,7 @@ 
   #  p, pick = use commit
   #  e, edit = use commit, but stop for amending
   #  f, fold = use commit, but combine it with the one above
+  #  a, amen = add commit content to one above, dropping message (hg amend)
   #  d, drop = remove commit from history
   #  m, mess = edit message without changing commit content
   #
diff -r 4354b1e35f53 -r 40809b1ede87 tests/test-histedit-commute.t
--- a/tests/test-histedit-commute.t	Wed Aug 06 12:16:58 2014 -0500
+++ b/tests/test-histedit-commute.t	Wed Aug 06 16:51:41 2014 -0400
@@ -67,6 +67,7 @@ 
   #  p, pick = use commit
   #  e, edit = use commit, but stop for amending
   #  f, fold = use commit, but combine it with the one above
+  #  a, amen = add commit content to one above, dropping message (hg amend)
   #  d, drop = remove commit from history
   #  m, mess = edit message without changing commit content
   #
@@ -344,6 +345,7 @@ 
   #  p, pick = use commit
   #  e, edit = use commit, but stop for amending
   #  f, fold = use commit, but combine it with the one above
+  #  a, amen = add commit content to one above, dropping message (hg amend)
   #  d, drop = remove commit from history
   #  m, mess = edit message without changing commit content
   #
diff -r 4354b1e35f53 -r 40809b1ede87 tests/test-histedit-fold-non-commute.t
--- a/tests/test-histedit-fold-non-commute.t	Wed Aug 06 12:16:58 2014 -0500
+++ b/tests/test-histedit-fold-non-commute.t	Wed Aug 06 16:51:41 2014 -0400
@@ -183,3 +183,165 @@ 
   f
 
   $ cd ..
+
+Repeat test using "amen", not "fold". "amen" folds in changes but drops message
+
+  $ initrepo r2
+  $ cd r2
+
+Initial generation of the command files
+
+  $ EDITED="$TESTTMP/editedhistory.2"
+  $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 3 >> $EDITED
+  $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 4 >> $EDITED
+  $ hg log --template 'amen {node|short} {rev} {desc}\n' -r 7 >> $EDITED
+  $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 5 >> $EDITED
+  $ hg log --template 'pick {node|short} {rev} {desc}\n' -r 6 >> $EDITED
+  $ cat $EDITED
+  pick 65a9a84f33fd 3 c
+  pick 00f1c5383965 4 d
+  amen 39522b764e3d 7 does not commute with e
+  pick 7b4e2f4b7bcd 5 e
+  pick 500cac37a696 6 f
+
+log before edit
+  $ hg log --graph
+  @  changeset:   7:39522b764e3d
+  |  tag:         tip
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     does not commute with e
+  |
+  o  changeset:   6:500cac37a696
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     f
+  |
+  o  changeset:   5:7b4e2f4b7bcd
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     e
+  |
+  o  changeset:   4:00f1c5383965
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     d
+  |
+  o  changeset:   3:65a9a84f33fd
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     c
+  |
+  o  changeset:   2:da6535b52e45
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     b
+  |
+  o  changeset:   1:c1f09da44841
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     a
+  |
+  o  changeset:   0:1715188a53c7
+     user:        test
+     date:        Thu Jan 01 00:00:00 1970 +0000
+     summary:     Initial commit
+  
+
+edit the history
+  $ hg histedit 3 --commands $EDITED 2>&1 | fixbundle
+  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  merging e
+  warning: conflicts during merge.
+  merging e incomplete! (edit conflicts, then use 'hg resolve --mark')
+  Fix up the change and run hg histedit --continue
+
+fix up
+  $ echo 'I can haz no commute' > e
+  $ hg resolve --mark e
+  (no more unresolved files)
+  $ hg histedit --continue 2>&1 | fixbundle | grep -v '2 files removed'
+  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  merging e
+  warning: conflicts during merge.
+  merging e incomplete! (edit conflicts, then use 'hg resolve --mark')
+  Fix up the change and run hg histedit --continue
+
+just continue this time
+  $ hg revert -r 'p1()' e
+  $ hg resolve --mark e
+  (no more unresolved files)
+  $ hg histedit --continue 2>&1 | fixbundle
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+log after edit
+  $ hg log --graph
+  @  changeset:   5:e7c4f5d4eb75
+  |  tag:         tip
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     f
+  |
+  o  changeset:   4:803d1bb561fc
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     d
+  |
+  o  changeset:   3:65a9a84f33fd
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     c
+  |
+  o  changeset:   2:da6535b52e45
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     b
+  |
+  o  changeset:   1:c1f09da44841
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     a
+  |
+  o  changeset:   0:1715188a53c7
+     user:        test
+     date:        Thu Jan 01 00:00:00 1970 +0000
+     summary:     Initial commit
+  
+
+contents of e
+  $ hg cat e
+  I can haz no commute
+
+manifest
+  $ hg manifest
+  a
+  b
+  c
+  d
+  e
+  f
+
+description is taken from amended commit
+
+  $ hg log --debug --rev 4
+  changeset:   4:803d1bb561fceac3129ec778db9da249a3106fc3
+  phase:       draft
+  parent:      3:65a9a84f33fdeb1ad5679b3941ec885d2b24027b
+  parent:      -1:0000000000000000000000000000000000000000
+  manifest:    4:b068a323d969f22af1296ec6a5ea9384cef437ac
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  files:       d e
+  extra:       branch=default
+  extra:       histedit_source=00f1c53839651fa5c76d423606811ea5455a79d0,39522b764e3d26103f08bd1fa2ccd3e3d7dbcf4e
+  description:
+  d
+  
+  
+
+done with repo r2
+
+  $ cd ..
diff -r 4354b1e35f53 -r 40809b1ede87 tests/test-histedit-fold.t
--- a/tests/test-histedit-fold.t	Wed Aug 06 12:16:58 2014 -0500
+++ b/tests/test-histedit-fold.t	Wed Aug 06 16:51:41 2014 -0400
@@ -105,6 +105,50 @@ 
   
   
 
+amend will fold without preserving the folded commit's message
+
+  $ hg histedit d2ae7f538514 --commands - 2>&1 <<EOF | fixbundle
+  > pick d2ae7f538514 b
+  > amen ee283cb5f2d5 e
+  > pick 6de59d13424a f
+  > pick 9c277da72c9b d
+  > EOF
+  0 files updated, 0 files merged, 4 files removed, 0 files unresolved
+  0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+log after edit
+  $ hg logt --graph
+  @  3:c4a9eb7989fc d
+  |
+  o  2:8e03a72b6f83 f
+  |
+  o  1:391ee782c689 b
+  |
+  o  0:cb9a9f314b8b a
+  
+
+description is taken from amended commit
+
+  $ hg log --debug --rev 1
+  changeset:   1:391ee782c68930be438ccf4c6a403daedbfbffa5
+  phase:       draft
+  parent:      0:cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
+  parent:      -1:0000000000000000000000000000000000000000
+  manifest:    1:b5e112a3a8354e269b1524729f0918662d847c38
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  files+:      b e
+  extra:       branch=default
+  extra:       histedit_source=d2ae7f538514cd87c17547b0de4cea71fe1af9fb,ee283cb5f2d5955443f23a27b697a04339e9a39a
+  description:
+  b
+  
+  
+
 check saving last-message.txt
 
   $ cat > $TESTTMP/abortfolding.py <<EOF
@@ -128,9 +172,9 @@ 
   > EOF
 
   $ rm -f .hg/last-message.txt
-  $ HGEDITOR="sh $TESTTMP/editor.sh" hg histedit 6de59d13424a --commands - 2>&1 <<EOF | fixbundle
-  > pick 6de59d13424a f
-  > fold 9c277da72c9b d
+  $ HGEDITOR="sh $TESTTMP/editor.sh" hg histedit 8e03a72b6f83 --commands - 2>&1 <<EOF | fixbundle
+  > pick 8e03a72b6f83 f
+  > fold c4a9eb7989fc d
   > EOF
   0 files updated, 0 files merged, 1 files removed, 0 files unresolved
   allow non-folding commit
diff -r 4354b1e35f53 -r 40809b1ede87 tests/test-histedit-obsolete.t
--- a/tests/test-histedit-obsolete.t	Wed Aug 06 12:16:58 2014 -0500
+++ b/tests/test-histedit-obsolete.t	Wed Aug 06 16:51:41 2014 -0400
@@ -57,6 +57,7 @@ 
   #  p, pick = use commit
   #  e, edit = use commit, but stop for amending
   #  f, fold = use commit, but combine it with the one above
+  #  a, amen = add commit content to one above, dropping message (hg amend)
   #  d, drop = remove commit from history
   #  m, mess = edit message without changing commit content
   #
diff -r 4354b1e35f53 -r 40809b1ede87 tests/test-histedit-outgoing.t
--- a/tests/test-histedit-outgoing.t	Wed Aug 06 12:16:58 2014 -0500
+++ b/tests/test-histedit-outgoing.t	Wed Aug 06 16:51:41 2014 -0400
@@ -49,6 +49,7 @@ 
   #  p, pick = use commit
   #  e, edit = use commit, but stop for amending
   #  f, fold = use commit, but combine it with the one above
+  #  a, amen = add commit content to one above, dropping message (hg amend)
   #  d, drop = remove commit from history
   #  m, mess = edit message without changing commit content
   #
@@ -80,6 +81,7 @@ 
   #  p, pick = use commit
   #  e, edit = use commit, but stop for amending
   #  f, fold = use commit, but combine it with the one above
+  #  a, amen = add commit content to one above, dropping message (hg amend)
   #  d, drop = remove commit from history
   #  m, mess = edit message without changing commit content
   #
@@ -103,6 +105,7 @@ 
   #  p, pick = use commit
   #  e, edit = use commit, but stop for amending
   #  f, fold = use commit, but combine it with the one above
+  #  a, amen = add commit content to one above, dropping message (hg amend)
   #  d, drop = remove commit from history
   #  m, mess = edit message without changing commit content
   #