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

login
register
mail settings
Submitter adgar@google.com
Date Aug. 13, 2014, 9:43 p.m.
Message ID <9e3f88c009891744862c.1407966183@adgar.nyc.corp.google.com>
Download mbox | patch
Permalink /patch/5375/
State Accepted
Headers show

Comments

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

This new histedit command (short for "rollup") is a variant of "fold" akin to
"hg amend" for working copy: it accumulates changes without interrupting
the user and asking for an updated commit message.
Augie Fackler - Aug. 14, 2014, 6:26 p.m.
On Wed, Aug 13, 2014 at 05:43:03PM -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 9e3f88c009891744862cc51ee306c1897f7dbb66
> # Parent  4354b1e35f533f72d5b6ccc76e8bc742f8cb5257
> histedit: add "roll" command to fold commit data and drop message (issue4256)

Looks good, queued. Thanks!

>
> This new histedit command (short for "rollup") is a variant of "fold" akin to
> "hg amend" for working copy: it accumulates changes without interrupting
> the user and asking for an updated commit message.
>
> diff -r 4354b1e35f53 -r 9e3f88c00989 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
> + #  r, roll = like fold, but discard this commit's description
>   #  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
> + #  r, roll = like fold, but discard this commit's description
>   #  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
> +#  r, roll = like fold, but discard this commit's description
>  #  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('rollup'):
> +        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 rollup(ui, repo, ctx, ha, opts):
> +    rollupopts = opts.copy()
> +    rollupopts['rollup'] = True
> +    return fold(ui, repo, ctx, ha, rollupopts)
> +
>  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('rollup'):
> +        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,
> +               'r': rollup,
> +               'roll': rollup,
>                 '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', 'r', 'roll'):
>              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', 'r', 'roll'):
>          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 ('r', 'roll'):
> +                foldopts = foldopts.copy()
> +                foldopts['rollup'] = 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 9e3f88c00989 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
> +  #  r, roll = like fold, but discard this commit's description
>    #  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
> +  #  r, roll = like fold, but discard this commit's description
>    #  d, drop = remove commit from history
>    #  m, mess = edit message without changing commit content
>    #
> diff -r 4354b1e35f53 -r 9e3f88c00989 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
> +  #  r, roll = like fold, but discard this commit's description
>    #  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
> +  #  r, roll = like fold, but discard this commit's description
>    #  d, drop = remove commit from history
>    #  m, mess = edit message without changing commit content
>    #
> diff -r 4354b1e35f53 -r 9e3f88c00989 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
> +  #  r, roll = like fold, but discard this commit's description
>    #  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
> +  #  r, roll = like fold, but discard this commit's description
>    #  d, drop = remove commit from history
>    #  m, mess = edit message without changing commit content
>    #
> diff -r 4354b1e35f53 -r 9e3f88c00989 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 "roll", not "fold". "roll" 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 'roll {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
> +  roll 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 rollup target 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 9e3f88c00989 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 @@
>
>
>
> +rollup will fold without preserving the folded commit's message
> +
> +  $ hg histedit d2ae7f538514 --commands - 2>&1 <<EOF | fixbundle
> +  > pick d2ae7f538514 b
> +  > roll 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 rollup target 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 9e3f88c00989 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
> +  #  r, roll = like fold, but discard this commit's description
>    #  d, drop = remove commit from history
>    #  m, mess = edit message without changing commit content
>    #
> diff -r 4354b1e35f53 -r 9e3f88c00989 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
> +  #  r, roll = like fold, but discard this commit's description
>    #  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
> +  #  r, roll = like fold, but discard this commit's description
>    #  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
> +  #  r, roll = like fold, but discard this commit's description
>    #  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

Patch

diff -r 4354b1e35f53 -r 9e3f88c00989 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
+ #  r, roll = like fold, but discard this commit's description
  #  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
+ #  r, roll = like fold, but discard this commit's description
  #  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
+#  r, roll = like fold, but discard this commit's description
 #  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('rollup'):
+        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 rollup(ui, repo, ctx, ha, opts):
+    rollupopts = opts.copy()
+    rollupopts['rollup'] = True
+    return fold(ui, repo, ctx, ha, rollupopts)
+
 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('rollup'):
+        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,
+               'r': rollup,
+               'roll': rollup,
                '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', 'r', 'roll'):
             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', 'r', 'roll'):
         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 ('r', 'roll'):
+                foldopts = foldopts.copy()
+                foldopts['rollup'] = 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 9e3f88c00989 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
+  #  r, roll = like fold, but discard this commit's description
   #  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
+  #  r, roll = like fold, but discard this commit's description
   #  d, drop = remove commit from history
   #  m, mess = edit message without changing commit content
   #
diff -r 4354b1e35f53 -r 9e3f88c00989 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
+  #  r, roll = like fold, but discard this commit's description
   #  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
+  #  r, roll = like fold, but discard this commit's description
   #  d, drop = remove commit from history
   #  m, mess = edit message without changing commit content
   #
diff -r 4354b1e35f53 -r 9e3f88c00989 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
+  #  r, roll = like fold, but discard this commit's description
   #  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
+  #  r, roll = like fold, but discard this commit's description
   #  d, drop = remove commit from history
   #  m, mess = edit message without changing commit content
   #
diff -r 4354b1e35f53 -r 9e3f88c00989 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 "roll", not "fold". "roll" 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 'roll {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
+  roll 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 rollup target 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 9e3f88c00989 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 @@ 
   
   
 
+rollup will fold without preserving the folded commit's message
+
+  $ hg histedit d2ae7f538514 --commands - 2>&1 <<EOF | fixbundle
+  > pick d2ae7f538514 b
+  > roll 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 rollup target 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 9e3f88c00989 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
+  #  r, roll = like fold, but discard this commit's description
   #  d, drop = remove commit from history
   #  m, mess = edit message without changing commit content
   #
diff -r 4354b1e35f53 -r 9e3f88c00989 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
+  #  r, roll = like fold, but discard this commit's description
   #  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
+  #  r, roll = like fold, but discard this commit's description
   #  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
+  #  r, roll = like fold, but discard this commit's description
   #  d, drop = remove commit from history
   #  m, mess = edit message without changing commit content
   #