changeset 4729:076b6813a7ea

branching: merge with stable
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Wed, 17 Jul 2019 18:06:14 +0200
parents f162cafc5000 (diff) ef8907df73fc (current diff)
children a95c6f578f70
files CHANGELOG hgext3rd/evolve/cmdrewrite.py hgext3rd/evolve/evolvecmd.py tests/test-touch.t
diffstat 64 files changed, 1012 insertions(+), 492 deletions(-) [+]
line wrap: on
line diff
--- a/CHANGELOG	Wed Jul 17 17:58:44 2019 +0200
+++ b/CHANGELOG	Wed Jul 17 18:06:14 2019 +0200
@@ -1,6 +1,18 @@
 Changelog
 =========
 
+9.1.0 - in progress
+-------------------
+
+  * evolve: use the same wording as core in case of unresolved conflict
+  * evolve: minor output message improvements
+  * evolve: improve `hg evolve --all` behavior when "." is obsolete
+  * topic: fix confusion in branch heads checking logic
+  * touch: now works on merge commit too
+  * rewind: fix behavior for merge commit
+  * fold: allow fold with merge commit
+  * metaedit: now also operates on merge commit
+
 9.0.1 - in progress
 -------------------
 
--- a/hgext3rd/evolve/__init__.py	Wed Jul 17 17:58:44 2019 +0200
+++ b/hgext3rd/evolve/__init__.py	Wed Jul 17 18:06:14 2019 +0200
@@ -329,7 +329,7 @@
 _pack = struct.pack
 _unpack = struct.unpack
 
-aliases, entry = cmdutil.findcmd('commit', commands.table)
+aliases, entry = cmdutil.findcmd(b'commit', commands.table)
 commitopts3 = cmdrewrite.commitopts3
 interactiveopt = cmdrewrite.interactiveopt
 rewrite = rewriteutil.rewrite
@@ -467,7 +467,7 @@
     _alias, statuscmd = cmdutil.findcmd('status', commands.table)
     pstatusopts = [o for o in statuscmd[1] if o[1] != 'rev']
 
-    @eh.command('pstatus', pstatusopts)
+    @eh.command(b'pstatus', pstatusopts)
     def pstatus(ui, repo, *args, **kwargs):
         """show status combining committed and uncommited changes
 
@@ -482,7 +482,7 @@
     _alias, diffcmd = cmdutil.findcmd('diff', commands.table)
     pdiffopts = [o for o in diffcmd[1] if o[1] != 'rev']
 
-    @eh.command('pdiff', pdiffopts)
+    @eh.command(b'pdiff', pdiffopts)
     def pdiff(ui, repo, *args, **kwargs):
         """show diff combining committed and uncommited changes
 
@@ -503,7 +503,7 @@
 
 ### Unstable revset symbol
 
-@eh.revsetpredicate('unstable()')
+@eh.revsetpredicate(b'unstable()')
 def revsetunstable(repo, subset, x):
     """Changesets with instabilities.
     """
@@ -516,7 +516,7 @@
     troubled.sort() # set is non-ordered, enforce order
     return subset & troubled
 
-@eh.revsetpredicate('troubled()')    # legacy name
+@eh.revsetpredicate(b'troubled()')    # legacy name
 def revsettroubled(repo, subset, x):
     return revsetunstable(repo, subset, x)
 
@@ -615,7 +615,7 @@
 
 
 ### XXX I'm not sure this revset is useful
-@eh.revsetpredicate('suspended()')
+@eh.revsetpredicate(b'suspended()')
 def revsetsuspended(repo, subset, x):
     """Obsolete changesets with non-obsolete descendants.
     """
@@ -625,7 +625,7 @@
     return subset & suspended
 
 
-@eh.revsetpredicate('predecessors(set)')
+@eh.revsetpredicate(b'predecessors(set)')
 def revsetpredecessors(repo, subset, x):
     """Immediate predecessors of changesets in set.
     """
@@ -635,12 +635,12 @@
     return subset & s
 
 
-@eh.revsetpredicate('precursors(set)')   # legacy name for predecessors
+@eh.revsetpredicate(b'precursors(set)')   # legacy name for predecessors
 def revsetprecursors(repo, subset, x):
     return revsetpredecessors(repo, subset, x)
 
 
-@eh.revsetpredicate('allpredecessors(set)')
+@eh.revsetpredicate(b'allpredecessors(set)')
 def revsetallpredecessors(repo, subset, x):
     """Transitive predecessors of changesets in set.
     """
@@ -650,12 +650,12 @@
     return subset & s
 
 
-@eh.revsetpredicate('allprecursors(set)')   # legacy name for allpredecessors
+@eh.revsetpredicate(b'allprecursors(set)')   # legacy name for allpredecessors
 def revsetallprecursors(repo, subset, x):
     return revsetallpredecessors(repo, subset, x)
 
 
-@eh.revsetpredicate('successors(set)')
+@eh.revsetpredicate(b'successors(set)')
 def revsetsuccessors(repo, subset, x):
     """Immediate successors of changesets in set.
     """
@@ -664,7 +664,7 @@
     s.sort()
     return subset & s
 
-@eh.revsetpredicate('allsuccessors(set)')
+@eh.revsetpredicate(b'allsuccessors(set)')
 def revsetallsuccessors(repo, subset, x):
     """Transitive successors of changesets in set.
     """
@@ -983,14 +983,14 @@
     return target, bookmark
 
 @eh.command(
-    'previous',
-    [('B', 'move-bookmark', False,
-        _('move active bookmark after update')),
-     ('m', 'merge', False, _('bring uncommitted change along')),
-     ('', 'no-topic', False, _('ignore topic and move topologically')),
-     ('n', 'dry-run', False,
-        _('do not perform actions, just print what would be done'))],
-    '[OPTION]...',
+    b'previous',
+    [(b'B', b'move-bookmark', False,
+        _(b'move active bookmark after update')),
+     (b'm', b'merge', False, _(b'bring uncommitted change along')),
+     (b'', b'no-topic', False, _(b'ignore topic and move topologically')),
+     (b'n', b'dry-run', False,
+        _(b'do not perform actions, just print what would be done'))],
+    b'[OPTION]...',
     helpbasic=True)
 def cmdprevious(ui, repo, **opts):
     """update to parent revision
@@ -1041,15 +1041,15 @@
         lockmod.release(wlock)
 
 @eh.command(
-    'next',
-    [('B', 'move-bookmark', False,
-        _('move active bookmark after update')),
-     ('m', 'merge', False, _('bring uncommitted change along')),
-     ('', 'evolve', True, _('evolve the next changeset if necessary')),
-     ('', 'no-topic', False, _('ignore topic and move topologically')),
-     ('n', 'dry-run', False,
-      _('do not perform actions, just print what would be done'))],
-    '[OPTION]...',
+    b'next',
+    [(b'B', b'move-bookmark', False,
+        _(b'move active bookmark after update')),
+     (b'm', b'merge', False, _(b'bring uncommitted change along')),
+     (b'', b'evolve', True, _(b'evolve the next changeset if necessary')),
+     (b'', b'no-topic', False, _(b'ignore topic and move topologically')),
+     (b'n', b'dry-run', False,
+      _(b'do not perform actions, just print what would be done'))],
+    b'[OPTION]...',
     helpbasic=True)
 def cmdnext(ui, repo, **opts):
     """update to next child revision
@@ -1302,9 +1302,9 @@
             raise error.Abort(msg, hint=hint)
 
 @eh.command(
-    'debugobsconvert',
-    [('', 'new-format', obsexchange._bestformat, _('Destination format for markers.'))],
-    '')
+    b'debugobsconvert',
+    [(b'', b'new-format', obsexchange._bestformat, _(b'Destination format for markers.'))],
+    b'')
 def debugobsconvert(ui, repo, new_format):
     origmarkers = repo.obsstore._all  # settle version
     if new_format == repo.obsstore._version:
@@ -1355,17 +1355,29 @@
 
 @eh.uisetup
 def setupevolveunfinished(ui):
-    estate = ('evolvestate', False, False, _('evolve in progress'),
-              _("use 'hg evolve --continue' or 'hg evolve --abort' to abort"))
-    cmdutil.unfinishedstates.append(estate)
-    pstate = ('pickstate', False, False, _('pick in progress'),
-              _("use 'hg pick --continue' or 'hg pick --abort' to abort"))
-    cmdutil.unfinishedstates.append(pstate)
+    if not util.safehasattr(cmdutil, 'unfinishedstates'):
+        from mercurial import state as statemod
+        _msg = _('To continue:    hg evolve --continue\n'
+                 'To abort:       hg evolve --abort\n'
+                 'To stop:        hg evolve --stop\n'
+                 '(also see `hg help evolve.interrupted`)')
+        statemod.addunfinished('evolve', fname='evolvestate',
+                               continueflag=True, stopflag=True,
+                               statushint=_msg)
+        statemod.addunfinished('pick', fname='pickstate', continueflag=True)
+    else:
+        # compat <= hg-5.0 (5f2f6912c9e6)
+        estate = ('evolvestate', False, False, _('evolve in progress'),
+                  _("use 'hg evolve --continue' or 'hg evolve --abort' to abort"))
+        cmdutil.unfinishedstates.append(estate)
+        pstate = ('pickstate', False, False, _('pick in progress'),
+                  _("use 'hg pick --continue' or 'hg pick --abort' to abort"))
+        cmdutil.unfinishedstates.append(pstate)
 
-    afterresolved = ('evolvestate', _('hg evolve --continue'))
-    pickresolved = ('pickstate', _('hg pick --continue'))
-    cmdutil.afterresolvedstates.append(afterresolved)
-    cmdutil.afterresolvedstates.append(pickresolved)
+        afterresolved = ('evolvestate', _('hg evolve --continue'))
+        pickresolved = ('pickstate', _('hg pick --continue'))
+        cmdutil.afterresolvedstates.append(afterresolved)
+        cmdutil.afterresolvedstates.append(pickresolved)
 
     if util.safehasattr(cmdutil, 'STATES'):
         statedata = ('evolve', cmdutil.fileexistspredicate('evolvestate'),
--- a/hgext3rd/evolve/cmdrewrite.py	Wed Jul 17 17:58:44 2019 +0200
+++ b/hgext3rd/evolve/cmdrewrite.py	Wed Jul 17 18:06:14 2019 +0200
@@ -86,28 +86,28 @@
         opts['user'] = ui.username()
 
 commitopts3 = [
-    ('D', 'current-date', None,
-     _('record the current date as commit date')),
-    ('U', 'current-user', None,
-     _('record the current user as committer')),
+    (b'D', b'current-date', None,
+     _(b'record the current date as commit date')),
+    (b'U', b'current-user', None,
+     _(b'record the current user as committer')),
 ]
 
-interactiveopt = [['i', 'interactive', None, _('use interactive mode')]]
+interactiveopt = [[b'i', b'interactive', None, _(b'use interactive mode')]]
 
 @eh.command(
-    'amend|refresh',
-    [('A', 'addremove', None,
-      _('mark new/missing files as added/removed before committing')),
-     ('a', 'all', False, _("match all files")),
-     ('e', 'edit', False, _('invoke editor on commit messages')),
-     ('', 'extract', False, _('extract changes from the commit to the working copy')),
-     ('', 'patch', False, _('make changes to wdir parent by editing patch')),
-     ('', 'close-branch', None,
-      _('mark a branch as closed, hiding it from the branch list')),
-     ('s', 'secret', None, _('use the secret phase for committing')),
-     ('n', 'note', '', _('store a note on amend'), _('TEXT')),
-    ] + walkopts + commitopts + commitopts2 + commitopts3 + interactiveopt,
-    _('[OPTION]... [FILE]...'),
+    b'amend|refresh',
+    [(b'A', b'addremove', None,
+      _(b'mark new/missing files as added/removed before committing')),
+     (b'a', b'all', False, _(b"match all files")),
+     (b'e', b'edit', False, _(b'invoke editor on commit messages')),
+     (b'', b'extract', False, _(b'extract changes from the commit to the working copy')),
+     (b'', b'patch', False, _(b'make changes to wdir parent by editing patch')),
+     (b'', b'close-branch', None,
+      _(b'mark a branch as closed, hiding it from the branch list')),
+     (b's', b'secret', None, _(b'use the secret phase for committing')),
+     (b'n', b'note', b'', _(b'store a note on amend'), _(b'TEXT')),
+     ] + walkopts + commitopts + commitopts2 + commitopts3 + interactiveopt,
+    _(b'[OPTION]... [FILE]...'),
     helpbasic=True)
 def amend(ui, repo, *pats, **opts):
     """combine a changeset with updates and replace it with a new one
@@ -320,7 +320,7 @@
 
     # Filter copies
     copied = copies.pathcopies(target, ctx)
-    copied = dict((dst, src) for dst, src in copied.iteritems()
+    copied = dict((dst, src) for dst, src in copied.items()
                   if dst in files)
 
     def filectxfn(repo, memctx, path, contentctx=ctx, redirect=newcontent):
@@ -441,22 +441,22 @@
             oldcopies[f] = src[0]
     oldcopies.update(copies)
     copies = dict((dst, oldcopies.get(src, src))
-                  for dst, src in oldcopies.iteritems())
+                  for dst, src in oldcopies.items())
     # Adjust the dirstate copies
-    for dst, src in copies.iteritems():
+    for dst, src in copies.items():
         if (src not in ctx or dst in ctx or ds[dst] != 'a'):
             src = None
         ds.copy(src, dst)
 
 @eh.command(
-    'uncommit',
-    [('a', 'all', None, _('uncommit all changes when no arguments given')),
-     ('i', 'interactive', False, _('interactive mode to uncommit (EXPERIMENTAL)')),
-     ('r', 'rev', '', _('revert commit content to REV instead'), _('REV')),
-     ('', 'revert', False, _('discard working directory changes after uncommit')),
-     ('n', 'note', '', _('store a note on uncommit'), _('TEXT')),
+    b'uncommit',
+    [(b'a', b'all', None, _(b'uncommit all changes when no arguments given')),
+     (b'i', b'interactive', False, _(b'interactive mode to uncommit (EXPERIMENTAL)')),
+     (b'r', b'rev', b'', _(b'revert commit content to REV instead'), _(b'REV')),
+     (b'', b'revert', False, _(b'discard working directory changes after uncommit')),
+     (b'n', b'note', b'', _(b'store a note on uncommit'), _(b'TEXT')),
      ] + commands.walkopts + commitopts + commitopts2 + commitopts3,
-    _('[OPTION]... [NAME]'))
+    _(b'[OPTION]... [NAME]'))
 def uncommit(ui, repo, *pats, **opts):
     """move changes from parent revision to working directory
 
@@ -685,13 +685,13 @@
     return newcm
 
 @eh.command(
-    'fold|squash',
-    [('r', 'rev', [], _("revision to fold"), _('REV')),
-     ('', 'exact', None, _("only fold specified revisions")),
-     ('', 'from', None, _("fold revisions linearly to working copy parent")),
-     ('n', 'note', '', _('store a note on fold'), _('TEXT')),
-    ] + commitopts + commitopts2 + commitopts3,
-    _('hg fold [OPTION]... [-r] REV'),
+    b'fold|squash',
+    [(b'r', b'rev', [], _(b"revision to fold"), _(b'REV')),
+     (b'', b'exact', None, _(b"only fold specified revisions")),
+     (b'', b'from', None, _(b"fold revisions linearly to working copy parent")),
+     (b'n', b'note', b'', _(b'store a note on fold'), _(b'TEXT')),
+     ] + commitopts + commitopts2 + commitopts3,
+    _(b'hg fold [OPTION]... [-r] REV'),
     helpbasic=True)
 def fold(ui, repo, *revs, **opts):
     """fold multiple revisions into a single one
@@ -773,7 +773,7 @@
         wlock = repo.wlock()
         lock = repo.lock()
 
-        root, head = rewriteutil.foldcheck(repo, revs)
+        root, head, p2 = rewriteutil.foldcheck(repo, revs)
 
         tr = repo.transaction('fold')
         try:
@@ -794,10 +794,13 @@
             if opts.get('note'):
                 metadata['note'] = opts['note']
 
-            newid, unusedvariable = rewriteutil.rewrite(repo, root, allctx,
+            updates = allctx[:]
+            if p2 is not None and root.p2() != p2:
+                updates.append(p2)
+            newid, unusedvariable = rewriteutil.rewrite(repo, root, updates,
                                                         head,
                                                         [root.p1().node(),
-                                                         root.p2().node()],
+                                                         p2.node()],
                                                         commitopts=commitopts)
             phases.retractboundary(repo, tr, targetphase, [newid])
             replacements = {ctx.node(): [newid] for ctx in allctx}
@@ -813,12 +816,12 @@
         lockmod.release(lock, wlock)
 
 @eh.command(
-    'metaedit',
-    [('r', 'rev', [], _("revision to edit"), _('REV')),
-     ('', 'fold', None, _("also fold specified revisions into one")),
-     ('n', 'note', '', _('store a note on metaedit'), _('TEXT')),
-    ] + commitopts + commitopts2 + commitopts3,
-    _('hg metaedit [OPTION]... [-r] [REV]'))
+    b'metaedit',
+    [(b'r', b'rev', [], _(b"revision to edit"), _(b'REV')),
+     (b'', b'fold', None, _(b"also fold specified revisions into one")),
+     (b'n', b'note', b'', _(b'store a note on metaedit'), _(b'TEXT')),
+     ] + commitopts + commitopts2 + commitopts3,
+    _(b'hg metaedit [OPTION]... [-r] [REV]'))
 def metaedit(ui, repo, *revs, **opts):
     """edit commit information
 
@@ -872,7 +875,7 @@
                                 'not currently supported'))
 
         if opts['fold']:
-            root, head = rewriteutil.foldcheck(repo, revs)
+            root, head, p2 = rewriteutil.foldcheck(repo, revs)
         else:
             if repo.revs("%ld and public()", revs):
                 raise error.Abort(_('cannot edit commit information for public '
@@ -886,6 +889,7 @@
                 hint %= repo[newunstable.first()]
                 raise error.Abort(msg, hint=hint)
             root = head = repo[revs.first()]
+            p2 = root.p2()
 
         wctx = repo[None]
         p1 = wctx.p1()
@@ -908,12 +912,15 @@
                 commitopts['message'] = "\n".join(msgs)
                 commitopts['edit'] = True
 
+            updates = allctx[:]
+            if p2 is not None and (root.p2() != p2 or not opts['fold']):
+                updates.append(p2)
             # TODO: if the author and message are the same, don't create a new
             # hash. Right now we create a new hash because the date can be
             # different.
-            newid, created = rewriteutil.rewrite(repo, root, allctx, head,
+            newid, created = rewriteutil.rewrite(repo, root, updates, head,
                                                  [root.p1().node(),
-                                                  root.p2().node()],
+                                                  p2.node()],
                                                  commitopts=commitopts)
             if created:
                 if p1.rev() in revs:
@@ -939,10 +946,10 @@
             hg.update(repo, newp1)
 
 metadataopts = [
-    ('d', 'date', '',
-     _('record the specified date in metadata'), _('DATE')),
-    ('u', 'user', '',
-     _('record the specified user in metadata'), _('USER')),
+    (b'd', b'date', b'',
+     _(b'record the specified date in metadata'), _(b'DATE')),
+    (b'u', b'user', b'',
+     _(b'record the specified user in metadata'), _(b'USER')),
 ]
 
 def _getmetadata(**opts):
@@ -956,22 +963,22 @@
     return metadata
 
 @eh.command(
-    'prune|obsolete',
-    [('n', 'new', [], _("successor changeset (DEPRECATED)")),
-     ('s', 'succ', [], _("successor changeset"), _('REV')),
-     ('r', 'rev', [], _("revisions to prune"), _('REV')),
-     ('k', 'keep', None, _("does not modify working copy during prune")),
-     ('n', 'note', '', _('store a note on prune'), _('TEXT')),
-     ('', 'pair', False, _("record a pairing, such as a rebase or divergence resolution "
-                           "(pairing multiple precursors to multiple successors)")),
-     ('', 'biject', False, _("alias to --pair (DEPRECATED)")),
-     ('', 'fold', False,
-      _("record a fold (multiple precursors, one successors)")),
-     ('', 'split', False,
-      _("record a split (on precursor, multiple successors)")),
-     ('B', 'bookmark', [], _("remove revs only reachable from given"
-                             " bookmark"), _('BOOKMARK'))] + metadataopts,
-    _('[OPTION] [-r] REV...'),
+    b'prune|obsolete',
+    [(b'n', b'new', [], _(b"successor changeset (DEPRECATED)")),
+     (b's', b'succ', [], _(b"successor changeset"), _(b'REV')),
+     (b'r', b'rev', [], _(b"revisions to prune"), _(b'REV')),
+     (b'k', b'keep', None, _(b"does not modify working copy during prune")),
+     (b'n', b'note', b'', _(b'store a note on prune'), _(b'TEXT')),
+     (b'', b'pair', False, _(b"record a pairing, such as a rebase or divergence resolution "
+                             b"(pairing multiple precursors to multiple successors)")),
+     (b'', b'biject', False, _(b"alias to --pair (DEPRECATED)")),
+     (b'', b'fold', False,
+      _(b"record a fold (multiple precursors, one successors)")),
+     (b'', b'split', False,
+      _(b"record a split (on precursor, multiple successors)")),
+     (b'B', b'bookmark', [], _(b"remove revs only reachable from given"
+                               b" bookmark"), _(b'BOOKMARK'))] + metadataopts,
+    _(b'[OPTION] [-r] REV...'),
     helpbasic=True)
 # XXX -U  --noupdate option to prevent wc update and or bookmarks update ?
 def cmdprune(ui, repo, *revs, **opts):
@@ -1153,12 +1160,12 @@
         lockmod.release(tr, lock, wlock)
 
 @eh.command(
-    'split',
-    [('i', 'interactive', True, _('use interactive mode')),
-     ('r', 'rev', [], _("revision to split"), _('REV')),
-     ('n', 'note', '', _("store a note on split"), _('TEXT')),
-    ] + commitopts + commitopts2 + commitopts3,
-    _('hg split [OPTION] [-r REV] [FILES]'),
+    b'split',
+    [(b'i', b'interactive', True, _(b'use interactive mode')),
+     (b'r', b'rev', [], _(b"revision to split"), _(b'REV')),
+     (b'n', b'note', b'', _(b"store a note on split"), _(b'TEXT')),
+     ] + commitopts + commitopts2 + commitopts3,
+    _(b'hg split [OPTION] [-r REV] [FILES]'),
     helpbasic=True)
 def cmdsplit(ui, repo, *pats, **opts):
     """split a changeset into smaller changesets
@@ -1325,14 +1332,14 @@
         lockmod.release(tr, lock, wlock)
 
 @eh.command(
-    'touch',
-    [('r', 'rev', [], _('revision to update'), _('REV')),
-     ('n', 'note', '', _('store a note on touch'), _('TEXT')),
-     ('D', 'duplicate', False,
-      'do not mark the new revision as successor of the old one'),
-     ('A', 'allowdivergence', False,
-      'mark the new revision as successor of the old one potentially creating '
-      'divergence')],
+    b'touch',
+    [(b'r', b'rev', [], _(b'revision to update'), _(b'REV')),
+     (b'n', b'note', b'', _(b'store a note on touch'), _(b'TEXT')),
+     (b'D', b'duplicate', False,
+      b'do not mark the new revision as successor of the old one'),
+     (b'A', b'allowdivergence', False,
+      b'mark the new revision as successor of the old one potentially creating '
+      b'divergence')],
     # allow to choose the seed ?
     _('[-r] revs'))
 def touch(ui, repo, *revs, **opts):
@@ -1355,10 +1362,8 @@
         rewriteutil.precheck(repo, revs, 'touch')
     tmpl = utility.shorttemplate
     displayer = compat.changesetdisplayer(ui, repo, {'template': tmpl})
-    with repo.wlock(), repo.lock():
-        tr = repo.transaction('touch')
-        with util.acceptintervention(tr):
-            touchnodes(ui, repo, revs, displayer, **opts)
+    with repo.wlock(), repo.lock(), repo.transaction('touch'):
+        touchnodes(ui, repo, revs, displayer, **opts)
 
 def touchnodes(ui, repo, revs, displayer, **opts):
     duplicate = opts['duplicate']
@@ -1409,8 +1414,11 @@
                 else:
                     duplicate = True
 
+        updates = []
+        if len(ctx.parents()) > 1:
+            updates = ctx.parents()
         extradict = {'extra': extra}
-        new, unusedvariable = rewriteutil.rewrite(repo, ctx, [], ctx,
+        new, unusedvariable = rewriteutil.rewrite(repo, ctx, updates, ctx,
                                                   [p1, p2],
                                                   commitopts=extradict)
         # store touched version to help potential children
@@ -1429,12 +1437,12 @@
                 repo.dirstate.setparents(new, node.nullid)
 
 @eh.command(
-    'pick|grab',
-    [('r', 'rev', '', _('revision to pick'), _('REV')),
-     ('c', 'continue', False, 'continue interrupted pick'),
-     ('a', 'abort', False, 'abort interrupted pick'),
+    b'pick|grab',
+    [(b'r', b'rev', b'', _(b'revision to pick'), _(b'REV')),
+     (b'c', b'continue', False, b'continue interrupted pick'),
+     (b'a', b'abort', False, b'abort interrupted pick'),
     ] + mergetoolopts,
-    _('[-r] rev'))
+    _(b'[-r] rev'))
 def cmdpick(ui, repo, *revs, **opts):
     """move a commit on the top of working directory parent and updates to it."""
 
@@ -1448,8 +1456,7 @@
     if opts.get('rev'):
         revs.append(opts['rev'])
 
-    overrides = {('ui', 'forcemerge'): opts.get('tool', '')}
-    with repo.wlock(), repo.lock(), ui.configoverride(overrides, 'pick'):
+    with repo.wlock(), repo.lock():
         pickstate = state.cmdstate(repo, path='pickstate')
         pctx = repo['.']
 
@@ -1471,8 +1478,10 @@
             ui.status(_('picking %d:%s "%s"\n') %
                       (origctx.rev(), origctx,
                        origctx.description().split("\n", 1)[0]))
-            stats = merge.graft(repo, origctx, origctx.p1(), ['local',
-                                                              'destination'])
+            overrides = {('ui', 'forcemerge'): opts.get('tool', '')}
+            with ui.configoverride(overrides, 'pick'):
+                stats = merge.graft(repo, origctx, origctx.p1(),
+                                    ['local', 'destination'])
             if compat.hasconflict(stats):
                 pickstate.addopts({'orignode': origctx.node(),
                                    'oldpctx': pctx.node()})
--- a/hgext3rd/evolve/compat.py	Wed Jul 17 17:58:44 2019 +0200
+++ b/hgext3rd/evolve/compat.py	Wed Jul 17 18:06:14 2019 +0200
@@ -123,7 +123,7 @@
     makedate = mercurial.util.makedate
     parsedate = mercurial.util.parsedate
 
-def wireprotocommand(exthelper, name, args='', permission='pull'):
+def wireprotocommand(exthelper, name, args=b'', permission=b'pull'):
     try:
         # Since b4d85bc1
         from mercurial.wireprotov1server import wireprotocommand
@@ -371,7 +371,7 @@
 
     # examine each file copy for a potential directory move, which is
     # when all the files in a directory are moved to a new directory
-    for dst, src in fullcopy.iteritems():
+    for dst, src in fullcopy.items():
         dsrc, ddst = pathutil.dirname(src), pathutil.dirname(dst)
         if dsrc in invalid:
             # already seen to be uninteresting
--- a/hgext3rd/evolve/debugcmd.py	Wed Jul 17 17:58:44 2019 +0200
+++ b/hgext3rd/evolve/debugcmd.py	Wed Jul 17 18:06:14 2019 +0200
@@ -21,7 +21,7 @@
 
 eh = exthelper.exthelper()
 
-@eh.command('debugobsstorestat', [], '')
+@eh.command(b'debugobsstorestat', [], b'')
 def cmddebugobsstorestat(ui, repo):
     """print statistics about obsolescence markers in the repo"""
     def _updateclustermap(nodes, mark, clustersmap):
--- a/hgext3rd/evolve/depthcache.py	Wed Jul 17 17:58:44 2019 +0200
+++ b/hgext3rd/evolve/depthcache.py	Wed Jul 17 18:06:14 2019 +0200
@@ -35,12 +35,12 @@
     return len(repo.revs('::%d', rev))
 
 @eh.command(
-    'debugdepth',
+    b'debugdepth',
     [
-        ('r', 'rev', [], 'revs to print depth for'),
-        ('', 'method', 'cached', "one of 'simple', 'cached', 'compare'"),
+        (b'r', b'rev', [], b'revs to print depth for'),
+        (b'', b'method', b'cached', b"one of 'simple', 'cached', 'compare'"),
     ],
-    _('REVS'))
+    _(b'REVS'))
 def debugdepth(ui, repo, **opts):
     """display depth of REVS
     """
--- a/hgext3rd/evolve/evolvecmd.py	Wed Jul 17 17:58:44 2019 +0200
+++ b/hgext3rd/evolve/evolvecmd.py	Wed Jul 17 18:06:14 2019 +0200
@@ -217,7 +217,7 @@
         displayer.show(bumped)
         repo.ui.write(_('atop:'))
         displayer.show(prec)
-    if confirm and ui.prompt('perform evolve? [Ny]', 'n') != 'y':
+    if confirm and ui.prompt(_('perform evolve? [Ny]'), 'n') != 'y':
         raise error.Abort(_('evolve aborted by user'))
     if dryrun:
         todo = 'hg rebase --rev %s --dest %s;\n' % (bumped, prec.p1())
@@ -578,8 +578,9 @@
     # conflicts while merging content-divergent changesets
     if compat.hasconflict(stats):
         evolvestate.save()
-        raise error.InterventionRequired(_("fix conflicts and see `hg help "
-                                           "evolve.interrupted`"))
+        hint = _("see 'hg help evolve.interrupted'")
+        raise error.InterventionRequired(_("unresolved merge conflicts"),
+                                         hint=hint)
 
 def _completecontentdivergent(ui, repo, progresscb, divergent, other,
                               base, evolvestate):
@@ -984,8 +985,9 @@
             copies.duplicatecopies(repo, repo[None], dest.rev(),
                                    orig.p1().rev())
             dirstatedance(repo, dest, orig.node(), None)
-        raise error.InterventionRequired(_("fix conflicts and see `hg help "
-                                           "evolve.interrupted`"))
+        hint = _("see 'hg help evolve.interrupted'")
+        raise error.InterventionRequired(_("unresolved merge conflicts"),
+                                         hint=hint)
     nodenew = _relocatecommit(repo, orig, commitmsg)
     _finalizerelocate(repo, orig, dest, nodenew, tr, category, evolvestate)
     return nodenew
@@ -1476,7 +1478,7 @@
                 continue
             base[tuple(nsuccset)] = n
     divergence = []
-    for divset, b in base.iteritems():
+    for divset, b in base.items():
         divergence.append({
             'divergentnodes': divset,
             'commonprecursor': b
@@ -1592,8 +1594,8 @@
     situation:
 
       - `hg evolve --continue`:
-         fix all the conflicts using `hg resolve` and then run this to continue the
-         interrupted evolve
+         resolve all the conflicts using `hg resolve` and then run this to
+         continue the interrupted evolve
 
       - `hg evolve --stop`:
          stops the current interrupted evolve, keeping all the successful steps,
@@ -1629,15 +1631,11 @@
         return
 
     targetcat = 'orphan'
-    has_some_opts = bool(revopt or anyopt or allopt or contopt or stopopt or abortopt)
     if 1 < len(specifiedcategories):
         msg = _('cannot specify more than one trouble category to solve (yet)')
         raise error.Abort(msg)
     elif len(specifiedcategories) == 1:
         targetcat = specifiedcategories[0]
-    elif repo['.'].obsolete() and not has_some_opts:
-        # if no args and parent is obsolete, update to successors
-        return solveobswdp(ui, repo, opts)
 
     ui.setconfig('ui', 'forcemerge', opts.get('tool', ''), 'evolve')
 
@@ -1664,7 +1662,7 @@
         return
     elif abortopt:
         if not evolvestate:
-            raise error.Abort(_('no interrupted evolve to stop'))
+            raise error.Abort(_('no interrupted evolve to abort'))
         evolvestate.load()
         # `hg next --evolve` in play
         if evolvestate['command'] != 'evolve':
@@ -1679,19 +1677,20 @@
     else:
         cmdutil.bailifchanged(repo)
 
+        obswdir = repo['.'].obsolete()
         revs = _selectrevs(repo, allopt, revopt, anyopt, targetcat)
 
-        # Case: when wdir parent is obsolete and args passed.
-        # Handling it here otherwise `revs` set would change, after
-        # performing update to successor of obsolete wdir parent.
-        # (in case when user passes a revset related to wdir parent '.::')
-        if repo['.'].obsolete():
+        if not (revs or obswdir):
+            return _handlenotrouble(ui, repo, allopt, revopt, anyopt, targetcat)
+        obswdironly = not revs and obswdir
+
+        if obswdir:
             result = solveobswdp(ui, repo, opts)
             if result != 0 or result is True:
+                # return as solving obswdp wasn't successful
                 return result
-
-        if not revs:
-            return _handlenotrouble(ui, repo, allopt, revopt, anyopt, targetcat)
+        if obswdironly:
+            return 0
 
         # Progress handling
         seen = 1
@@ -1838,7 +1837,7 @@
         # boolean value to say whether we should strip or not
         cleanup = True
         startnode = evolvestate['startnode']
-        for old, new in evolvestate['replacements'].iteritems():
+        for old, new in evolvestate['replacements'].items():
             if new:
                 evolvedctx.append(repo[new])
         for temp in evolvestate['temprevs']:
--- a/hgext3rd/evolve/exthelper.py	Wed Jul 17 17:58:44 2019 +0200
+++ b/hgext3rd/evolve/exthelper.py	Wed Jul 17 18:06:14 2019 +0200
@@ -111,7 +111,7 @@
         self._functionwrappers.extend(other._functionwrappers)
         self._duckpunchers.extend(other._duckpunchers)
         self.cmdtable.update(other.cmdtable)
-        for section, items in other.configtable.iteritems():
+        for section, items in other.configtable.items():
             if section in self.configtable:
                 self.configtable[section].update(items)
             else:
--- a/hgext3rd/evolve/legacy.py	Wed Jul 17 17:58:44 2019 +0200
+++ b/hgext3rd/evolve/legacy.py	Wed Jul 17 18:06:14 2019 +0200
@@ -139,7 +139,7 @@
 
                     oldmark['date'] = '%i %i' % tuple(oldmark['date'])
                     meta = dict((k.encode('utf-8'), v.encode('utf-8'))
-                                for k, v in oldmark.iteritems())
+                                for k, v in oldmark.items())
                     try:
                         succs = [bin(n) for n in oldsubjects]
                         succs = [n for n in succs if n != nullid]
--- a/hgext3rd/evolve/metadata.py	Wed Jul 17 17:58:44 2019 +0200
+++ b/hgext3rd/evolve/metadata.py	Wed Jul 17 18:06:14 2019 +0200
@@ -5,7 +5,7 @@
 # This software may be used and distributed according to the terms of the
 # GNU General Public License version 2 or any later version.
 
-__version__ = '9.0.1.dev'
-testedwith = '4.5.2 4.6.2 4.7 4.8 4.9 5.0'
-minimumhgversion = '4.5'
-buglink = 'https://bz.mercurial-scm.org/'
+__version__ = b'9.1.0.dev'
+testedwith = b'4.5.2 4.6.2 4.7 4.8 4.9 5.0'
+minimumhgversion = b'4.5'
+buglink = b'https://bz.mercurial-scm.org/'
--- a/hgext3rd/evolve/obsdiscovery.py	Wed Jul 17 17:58:44 2019 +0200
+++ b/hgext3rd/evolve/obsdiscovery.py	Wed Jul 17 18:06:14 2019 +0200
@@ -186,12 +186,12 @@
 ##############################
 
 @eh.command(
-    'debugobshashrange',
+    b'debugobshashrange',
     [
-        ('', 'rev', [], 'display obshash for all (rev, 0) range in REVS'),
-        ('', 'subranges', False, 'display all subranges'),
+        (b'', b'rev', [], b'display obshash for all (rev, 0) range in REVS'),
+        (b'', b'subranges', False, b'display all subranges'),
     ],
-    _(''))
+    _(b''))
 def debugobshashrange(ui, repo, **opts):
     """display the ::REVS set topologically sorted in a stable way
     """
@@ -688,7 +688,7 @@
     except ValueError:
         self._abort(error.ResponseError(_("unexpected response:"), d))
 
-@compat.wireprotocommand(eh, 'evoext_obshashrange_v1', 'ranges')
+@compat.wireprotocommand(eh, b'evoext_obshashrange_v1', b'ranges')
 def srv_obshashrange_v1(repo, proto, ranges):
     ranges = decodelist(ranges)
     ranges = [_decrange(r) for r in ranges]
--- a/hgext3rd/evolve/obsexchange.py	Wed Jul 17 17:58:44 2019 +0200
+++ b/hgext3rd/evolve/obsexchange.py	Wed Jul 17 18:06:14 2019 +0200
@@ -221,7 +221,7 @@
         from mercurial import wireproto as wireprototypes
         wireprotov1server = wireprototypes
     opts = wireprotov1server.options('', ['heads', 'common'], others)
-    for k, v in opts.iteritems():
+    for k, v in opts.items():
         if k in ('heads', 'common'):
             opts[k] = wireprototypes.decodelist(v)
     obsdata = _getobsmarkersstream(repo, **opts)
--- a/hgext3rd/evolve/obshashtree.py	Wed Jul 17 17:58:44 2019 +0200
+++ b/hgext3rd/evolve/obshashtree.py	Wed Jul 17 18:06:14 2019 +0200
@@ -28,9 +28,9 @@
 # the obshash of its parents.  This is similar to what happend for changeset
 # node where the parent is used in the computation
 @eh.command(
-    'debugobsrelsethashtree',
-    [('', 'v0', None, 'hash on marker format "0"'),
-     ('', 'v1', None, 'hash on marker format "1" (default)')], _(''))
+    b'debugobsrelsethashtree',
+    [(b'', b'v0', None, b'hash on marker format "0"'),
+     (b'', b'v1', None, b'hash on marker format "1" (default)')], _(b''))
 def debugobsrelsethashtree(ui, repo, v0=False, v1=False):
     """display Obsolete markers, Relevant Set, Hash Tree
     changeset-node obsrelsethashtree-node
--- a/hgext3rd/evolve/obshistory.py	Wed Jul 17 17:58:44 2019 +0200
+++ b/hgext3rd/evolve/obshistory.py	Wed Jul 17 18:06:14 2019 +0200
@@ -42,14 +42,14 @@
         efd.clear()
 
 @eh.command(
-    'obslog|olog',
-    [('G', 'graph', True, _("show the revision DAG")),
-     ('r', 'rev', [], _('show the specified revision or revset'), _('REV')),
-     ('a', 'all', False, _('show all related changesets, not only precursors')),
-     ('p', 'patch', False, _('show the patch between two obs versions')),
-     ('f', 'filternonlocal', False, _('filter out non local commits')),
-    ] + commands.formatteropts,
-    _('hg olog [OPTION]... [REV]'))
+    b'obslog|olog',
+    [(b'G', b'graph', True, _(b"show the revision DAG")),
+     (b'r', b'rev', [], _(b'show the specified revision or revset'), _(b'REV')),
+     (b'a', b'all', False, _(b'show all related changesets, not only precursors')),
+     (b'p', b'patch', False, _(b'show the patch between two obs versions')),
+     (b'f', b'filternonlocal', False, _(b'filter out non local commits')),
+     ] + commands.formatteropts,
+    _(b'hg olog [OPTION]... [REV]'))
 def cmdobshistory(ui, repo, *revs, **opts):
     """show the obsolescence history of the specified revisions
 
--- a/hgext3rd/evolve/rewind.py	Wed Jul 17 17:58:44 2019 +0200
+++ b/hgext3rd/evolve/rewind.py	Wed Jul 17 18:06:14 2019 +0200
@@ -26,14 +26,14 @@
 identicalflag = 4
 
 @eh.command(
-    'rewind|undo',
-    [('', 'to', [], _("rewind to these revisions"), _('REV')),
-     ('', 'as-divergence', None, _("preserve current latest successors")),
-     ('', 'exact', None, _("only rewind explicitly selected revisions")),
-     ('', 'from', [],
-      _("rewind these revisions to their predecessors"), _('REV')),
-    ],
-    _(''),
+    b'rewind|undo',
+    [(b'', b'to', [], _(b"rewind to these revisions"), _(b'REV')),
+     (b'', b'as-divergence', None, _(b"preserve current latest successors")),
+     (b'', b'exact', None, _(b"only rewind explicitly selected revisions")),
+     (b'', b'from', [],
+      _(b"rewind these revisions to their predecessors"), _(b'REV')),
+     ],
+    _(b''),
     helpbasic=True)
 def rewind(ui, repo, **opts):
     """rewind a stack of changesets to a previous state
@@ -166,9 +166,12 @@
     p2 = ctx.p2().node()
     p2 = rewindmap.get(p2, p2)
 
+    updates = []
+    if len(ctx.parents()) > 1:
+        updates = ctx.parents()
     extradict = {'extra': extra}
 
-    new, unusedvariable = rewriteutil.rewrite(unfi, ctx, [], ctx,
+    new, unusedvariable = rewriteutil.rewrite(unfi, ctx, updates, ctx,
                                               [p1, p2],
                                               commitopts=extradict)
 
--- a/hgext3rd/evolve/rewriteutil.py	Wed Jul 17 17:58:44 2019 +0200
+++ b/hgext3rd/evolve/rewriteutil.py	Wed Jul 17 18:06:14 2019 +0200
@@ -113,7 +113,14 @@
         raise error.Abort(_("cannot fold non-linear revisions "
                             "(multiple heads given)"))
     head = repo[heads.first()]
-    return root, head
+    baseparents = repo.revs('parents(%ld) - %ld', revs, revs)
+    if len(baseparents) > 2:
+        raise error.Abort(_("cannot fold revisions that merge with more than "
+                            "one external changeset (not in revisions)"))
+    # root's p1 is already used as the target ctx p1
+    baseparents -= {root.p1().rev()}
+    p2 = repo[baseparents.first()]
+    return root, head, p2
 
 def deletebookmark(repo, repomarks, bookmarks):
     wlock = lock = tr = None
@@ -150,7 +157,7 @@
     # a revision we have to only delete the bookmark and not strip
     # anything. revsets cannot detect that case.
     nodetobookmarks = {}
-    for mark, bnode in repomarks.iteritems():
+    for mark, bnode in repomarks.items():
         nodetobookmarks.setdefault(bnode, []).append(mark)
     for marks in nodetobookmarks.values():
         if bookmarks.issuperset(marks):
@@ -171,8 +178,6 @@
         wlock = repo.wlock()
         lock = repo.lock()
         tr = repo.transaction('rewrite')
-        if len(old.parents()) > 1: # XXX remove this unnecessary limitation.
-            raise error.Abort(_('cannot amend merge changesets'))
         base = old.p1()
         updatebookmarks = bookmarksupdater(repo, old.node(), tr)
 
--- a/hgext3rd/evolve/stablerange.py	Wed Jul 17 17:58:44 2019 +0200
+++ b/hgext3rd/evolve/stablerange.py	Wed Jul 17 18:06:14 2019 +0200
@@ -72,15 +72,15 @@
 }
 
 @eh.command(
-    'debugstablerange',
+    b'debugstablerange',
     [
-        ('r', 'rev', [], 'operate on (rev, 0) ranges for rev in REVS'),
-        ('', 'subranges', False, 'recursively display data for subranges too'),
-        ('', 'verify', False, 'checks subranges content (EXPENSIVE)'),
-        ('', 'method', 'branchpoint',
-         'method to use, one of "branchpoint", "mergepoint"')
+        (b'r', b'rev', [], b'operate on (rev, 0) ranges for rev in REVS'),
+        (b'', b'subranges', False, b'recursively display data for subranges too'),
+        (b'', b'verify', False, b'checks subranges content (EXPENSIVE)'),
+        (b'', b'method', b'branchpoint',
+         b'method to use, one of "branchpoint", "mergepoint"')
     ],
-    _(''))
+    _(b''))
 def debugstablerange(ui, repo, **opts):
     """display standard stable subrange for a set of ranges
 
--- a/hgext3rd/evolve/stablesort.py	Wed Jul 17 17:58:44 2019 +0200
+++ b/hgext3rd/evolve/stablesort.py	Wed Jul 17 18:06:14 2019 +0200
@@ -52,14 +52,14 @@
     return key
 
 @eh.command(
-    'debugstablesort',
+    b'debugstablesort',
     [
-        ('r', 'rev', [], 'heads to start from'),
-        ('', 'method', 'branchpoint', "method used for sorting, one of: "
-         "branchpoint, basic-mergepoint and basic-headstart"),
-        ('l', 'limit', '', 'number of revision display (default to all)')
+        (b'r', b'rev', [], b'heads to start from'),
+        (b'', b'method', b'branchpoint', b"method used for sorting, one of: "
+         b"branchpoint, basic-mergepoint and basic-headstart"),
+        (b'l', b'limit', b'', b'number of revision display (default to all)')
     ] + commands.formatteropts,
-    _(''))
+    _(b''))
 def debugstablesort(ui, repo, **opts):
     """display the ::REVS set topologically sorted in a stable way
     """
--- a/hgext3rd/evolve/templatekw.py	Wed Jul 17 17:58:44 2019 +0200
+++ b/hgext3rd/evolve/templatekw.py	Wed Jul 17 18:06:14 2019 +0200
@@ -15,6 +15,7 @@
 )
 
 from mercurial import (
+    pycompat,
     templatekw,
     util
 )
@@ -24,7 +25,7 @@
 ### template keywords
 
 if util.safehasattr(templatekw, 'compatlist'):
-    @eh.templatekeyword('instabilities', requires=set(['ctx', 'templ']))
+    @eh.templatekeyword(b'instabilities', requires=set([b'ctx', b'templ']))
     def showinstabilities(context, mapping):
         """List of strings. Evolution instabilities affecting the changeset
         (zero or more of "orphan", "content-divergent" or "phase-divergent")."""
@@ -33,14 +34,14 @@
                                      ctx.instabilities(),
                                      plural='instabilities')
 
-    @eh.templatekeyword('troubles', requires=set(['ctx', 'templ']))
+    @eh.templatekeyword(b'troubles', requires=set([b'ctx', b'templ']))
     def showtroubles(context, mapping):   # legacy name for instabilities
         ctx = context.resource(mapping, 'ctx')
         return templatekw.compatlist(context, mapping, 'trouble',
                                      ctx.instabilities(), plural='troubles')
 else:
     # older template API in hg < 4.6
-    @eh.templatekeyword('instabilities')
+    @eh.templatekeyword(b'instabilities')
     def showinstabilities(**args):
         """List of strings. Evolution instabilities affecting the changeset
         (zero or more of "orphan", "content-divergent" or "phase-divergent")."""
@@ -48,7 +49,7 @@
         return templatekw.showlist('instability', ctx.instabilities(), args,
                                    plural='instabilities')
 
-    @eh.templatekeyword('troubles')
+    @eh.templatekeyword(b'troubles')
     def showtroubles(**args):
         ctx = args['ctx']
         return templatekw.showlist('trouble', ctx.instabilities(), args,
@@ -58,11 +59,11 @@
 if util.safehasattr(_sp, '_requires'):
     def showprecursors(context, mapping):
         return _sp(context, mapping)
-    showprecursors.__doc__ = _sp._origdoc
-    _tk = templatekw.templatekeyword("precursors", requires=_sp._requires)
+    showprecursors.__doc__ = pycompat.sysstr(_sp._origdoc)
+    _tk = templatekw.templatekeyword(b"precursors", requires=_sp._requires)
     _tk(showprecursors)
 else:
-    templatekw.keywords["precursors"] = _sp
+    templatekw.keywords[b"precursors"] = _sp
 
 
 def closestsuccessors(repo, nodeid):
@@ -74,11 +75,11 @@
 if util.safehasattr(_ss, '_requires'):
     def showsuccessors(context, mapping):
         return _ss(context, mapping)
-    showsuccessors.__doc__ = _ss._origdoc
-    _tk = templatekw.templatekeyword("successors", requires=_ss._requires)
+    showsuccessors.__doc__ = pycompat.sysstr(_ss._origdoc)
+    _tk = templatekw.templatekeyword(b"successors", requires=_ss._requires)
     _tk(showsuccessors)
 else:
-    templatekw.keywords["successors"] = _ss
+    templatekw.keywords[b"successors"] = _ss
 
 def _getusername(ui):
     """the default username in the config or None"""
@@ -207,7 +208,7 @@
     return "\n".join(lines)
 
 if not util.safehasattr(templatekw, 'obsfateverb'): # <= hg-4.5
-    @eh.templatekeyword("obsfatedata")
+    @eh.templatekeyword(b"obsfatedata")
     def showobsfatedata(repo, ctx, **args):
         # Get the needed obsfate data
         values = obsfatedata(repo, ctx)
--- a/hgext3rd/evolve/thirdparty/cbor.py	Wed Jul 17 17:58:44 2019 +0200
+++ b/hgext3rd/evolve/thirdparty/cbor.py	Wed Jul 17 18:06:14 2019 +0200
@@ -193,7 +193,7 @@
                 parts.append(dumps(k, sort_keys=sort_keys))
                 parts.append(dumps(v, sort_keys=sort_keys))
         else:
-            for k,v in d.iteritems():
+            for k,v in d.items():
                 parts.append(dumps(k, sort_keys=sort_keys))
                 parts.append(dumps(v, sort_keys=sort_keys))
         return b''.join(parts)
--- a/hgext3rd/topic/__init__.py	Wed Jul 17 17:58:44 2019 +0200
+++ b/hgext3rd/topic/__init__.py	Wed Jul 17 18:06:14 2019 +0200
@@ -186,11 +186,11 @@
               'topic.active': 'green',
              }
 
-__version__ = '0.15.1.dev'
+__version__ = b'0.16.0.dev'
 
-testedwith = '4.5.2 4.6.2 4.7 4.8 4.9 5.0'
-minimumhgversion = '4.5'
-buglink = 'https://bz.mercurial-scm.org/'
+testedwith = b'4.5.2 4.6.2 4.7 4.8 4.9 5.0'
+minimumhgversion = b'4.5'
+buglink = b'https://bz.mercurial-scm.org/'
 
 if util.safehasattr(registrar, 'configitem'):
 
@@ -436,6 +436,15 @@
                 return super(topicrepo, self).branchmap()
             return self.filtered(topicfilter).branchmap()
 
+        def branchheads(self, branch=None, start=None, closed=False):
+            if branch is None:
+                branch = self[None].branch()
+            if self.currenttopic:
+                branch = "%s:%s" % (branch, self.currenttopic)
+            return super(topicrepo, self).branchheads(branch=branch,
+                                                      start=start,
+                                                      closed=closed)
+
         def invalidatevolatilesets(self):
             # XXX we might be able to move this to something invalidated less often
             super(topicrepo, self).invalidatevolatilesets()
@@ -563,13 +572,13 @@
             listnames=lambda repo: repo.topics))
 
 if post45template:
-    @templatekeyword('topic', requires={'ctx'})
+    @templatekeyword(b'topic', requires={b'ctx'})
     def topickw(context, mapping):
         """:topic: String. The topic of the changeset"""
         ctx = context.resource(mapping, 'ctx')
         return ctx.topic()
 
-    @templatekeyword('topicidx', requires={'ctx'})
+    @templatekeyword(b'topicidx', requires={b'ctx'})
     def topicidxkw(context, mapping):
         """:topicidx: Integer. Index of the changeset as a stack alias"""
         ctx = context.resource(mapping, 'ctx')
@@ -617,14 +626,14 @@
 # revset predicates are automatically registered at loading via this symbol
 revsetpredicate = topicrevset.revsetpredicate
 
-@command('topics', [
-        ('', 'clear', False, 'clear active topic if any'),
-        ('r', 'rev', [], 'revset of existing revisions', _('REV')),
-        ('l', 'list', False, 'show the stack of changeset in the topic'),
-        ('', 'age', False, 'show when you last touched the topics'),
-        ('', 'current', None, 'display the current topic only'),
+@command(b'topics', [
+        (b'', b'clear', False, b'clear active topic if any'),
+        (b'r', b'rev', [], b'revset of existing revisions', _(b'REV')),
+        (b'l', b'list', False, b'show the stack of changeset in the topic'),
+        (b'', b'age', False, b'show when you last touched the topics'),
+        (b'', b'current', None, b'display the current topic only'),
     ] + commands.formatteropts,
-    _('hg topics [TOPIC]'))
+    _(b'hg topics [TOPIC]'))
 def topics(ui, repo, topic=None, **opts):
     """View current topic, set current topic, change topic for a set of revisions, or see all topics.
 
--- a/hgext3rd/topic/revset.py	Wed Jul 17 17:58:44 2019 +0200
+++ b/hgext3rd/topic/revset.py	Wed Jul 17 18:06:14 2019 +0200
@@ -28,7 +28,7 @@
         return x[1]
     raise error.ParseError(err)
 
-@revsetpredicate('topic([string or set])')
+@revsetpredicate(b'topic([string or set])')
 def topicset(repo, subset, x):
     """All changesets with the specified topic or the topics of the given
     changesets. Without the argument, all changesets with any topic specified.
@@ -76,7 +76,7 @@
 
     return (subset & mutable).filter(matches)
 
-@revsetpredicate('ngtip([branch])')
+@revsetpredicate(b'ngtip([branch])')
 def ngtipset(repo, subset, x):
     """The untopiced tip.
 
@@ -89,7 +89,7 @@
         branch = repo['.'].branch()
     return subset & revset.baseset(destination.ngtip(repo, branch))
 
-@revsetpredicate('stack()')
+@revsetpredicate(b'stack()')
 def stackset(repo, subset, x):
     """All relevant changes in the current topic,
 
--- a/hgext3rd/topic/topicmap.py	Wed Jul 17 17:58:44 2019 +0200
+++ b/hgext3rd/topic/topicmap.py	Wed Jul 17 18:06:14 2019 +0200
@@ -100,8 +100,7 @@
     # wrap commit status use the topic branch heads
     ctx = repo[node]
     if ctx.topic() and ctx.branch() == branch:
-        subbranch = "%s:%s" % (branch, ctx.topic())
-        bheads = repo.branchheads("%s:%s" % (subbranch, ctx.topic()))
+        bheads = repo.branchheads("%s:%s" % (branch, ctx.topic()))
 
     ret = orig(repo, node, branch, bheads=bheads, opts=opts)
 
--- a/tests/test-discovery-obshashrange.t	Wed Jul 17 17:58:44 2019 +0200
+++ b/tests/test-discovery-obshashrange.t	Wed Jul 17 18:06:14 2019 +0200
@@ -40,8 +40,8 @@
   * @0000000000000000000000000000000000000000 (*)> -R server serve --stdio exited 0 after *.?? seconds (glob)
   * @0000000000000000000000000000000000000000 (*)> debugbuilddag .+7 (glob) (no-windows !)
   * @0000000000000000000000000000000000000000 (*)> debugbuilddag ".+7" (glob) (windows !)
-  * @0000000000000000000000000000000000000000 (*)> updated served branch cache in *.???? seconds (glob)
-  * @0000000000000000000000000000000000000000 (*)> wrote served branch cache with 1 labels and 1 nodes (glob)
+  * @0000000000000000000000000000000000000000 (*)> updated branch cache (served) in *.???? seconds (glob)
+  * @0000000000000000000000000000000000000000 (*)> wrote branch cache (served) with 1 labels and 1 nodes (glob)
   * @0000000000000000000000000000000000000000 (*)> updated evo-ext-obscache in *.???? seconds (8r, 0o) (glob)
   * @0000000000000000000000000000000000000000 (*)> debugbuilddag .+7 exited 0 after *.?? seconds (glob) (no-windows !)
   * @0000000000000000000000000000000000000000 (*)> debugbuilddag ".+7" exited 0 after *.?? seconds (glob) (windows !)
@@ -162,8 +162,8 @@
   $ hg blackbox
   * @0000000000000000000000000000000000000000 (*)> clone *ssh://user@dummy/server* client exited 0 after *.?? seconds (glob)
   * @0000000000000000000000000000000000000000 (*)> pull --rev 4 (glob)
-  * @0000000000000000000000000000000000000000 (*)> updated base branch cache in *.???? seconds (glob)
-  * @0000000000000000000000000000000000000000 (*)> wrote base branch cache with 1 labels and 1 nodes (glob)
+  * @0000000000000000000000000000000000000000 (*)> updated branch cache (base) in *.???? seconds (glob)
+  * @0000000000000000000000000000000000000000 (*)> wrote branch cache (base) with 1 labels and 1 nodes (glob)
   * @0000000000000000000000000000000000000000 (*)> updated evo-ext-obscache in *.???? seconds (5r, 3o) (glob)
   * @0000000000000000000000000000000000000000 (*)> 5 incoming changes - new heads: bebd167eb94d (glob)
   * @0000000000000000000000000000000000000000 (*)> pull --rev 4 exited 0 after *.?? seconds (glob)
@@ -247,8 +247,8 @@
   * @0000000000000000000000000000000000000000 (*)> updated evo-ext-stablerange-mergepoint in *.???? seconds (1r) (glob)
   1970/01/01 00:00:00 * @0000000000000000000000000000000000000000 (*)> updated evo-ext-obshashrange in *.???? seconds (1r, 1o) (glob)
   * @0000000000000000000000000000000000000000 (*)> obscache is out of date, falling back to slower obsstore version (glob)
-  * @0000000000000000000000000000000000000000 (*)> updated served branch cache in *.???? seconds (glob)
-  * @0000000000000000000000000000000000000000 (*)> wrote served branch cache with 1 labels and 2 nodes (glob)
+  * @0000000000000000000000000000000000000000 (*)> updated branch cache (served) in *.???? seconds (glob)
+  * @0000000000000000000000000000000000000000 (*)> wrote branch cache (served) with 1 labels and 2 nodes (glob)
   * @0000000000000000000000000000000000000000 (*)> updated evo-ext-obscache in *.???? seconds (1r, 1o) (glob)
   * @0000000000000000000000000000000000000000 (*)> 1 incoming changes - new heads: 45f8b879de92 (glob)
   * @0000000000000000000000000000000000000000 (*)> -R server serve --stdio exited 0 after *.?? seconds (glob)
@@ -307,8 +307,8 @@
   * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> add foo exited 0 after *.?? seconds (glob)
   * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> commit -m foo (glob)
   * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> obscache is out of date, falling back to slower obsstore version (glob)
-  * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated served branch cache in *.???? seconds (glob)
-  * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> wrote served branch cache with 1 labels and 1 nodes (glob)
+  * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated branch cache (served) in *.???? seconds (glob)
+  * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> wrote branch cache (served) with 1 labels and 1 nodes (glob)
   * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated evo-ext-obscache in *.???? seconds (1r, 0o) (glob)
   * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> commit -m foo exited 0 after *.?? seconds (glob)
   * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> debugobsolete ffffffffffffffffffffffffffffffffffffffff 45f8b879de922f6a6e620ba04205730335b6fc7e (glob)
@@ -465,8 +465,8 @@
   * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> log -G exited 0 after *.?? seconds (glob)
   * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> pull -r 6 (glob)
   * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> obsdiscovery, 2/6 mismatch - 1 obshashrange queries in *.???? seconds (glob)
-  * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated served branch cache in *.???? seconds (glob)
-  * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> wrote served branch cache with 1 labels and 2 nodes (glob)
+  * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated branch cache (served) in *.???? seconds (glob)
+  * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> wrote branch cache (served) with 1 labels and 2 nodes (glob)
   * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated evo-ext-obscache in *.???? seconds (2r, 3o) (glob)
   * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> 2 incoming changes - new heads: f69452c5b1af (glob)
   * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> pull -r 6 exited 0 after *.?? seconds (glob)
@@ -902,14 +902,14 @@
   * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> debugobshashrange --subranges --rev "heads(all())" exited 0 after *.?? seconds (glob) (windows !)
   * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> pull (glob)
   1970/01/01 00:00:00 * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> obsdiscovery, 0/8 mismatch - 1 obshashrange queries in *.???? seconds (glob)
-  * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated served branch cache in *.???? seconds (glob)
-  * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> wrote served branch cache with 1 labels and 2 nodes (glob)
+  * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated branch cache (served) in *.???? seconds (glob)
+  * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> wrote branch cache (served) with 1 labels and 2 nodes (glob)
   1970/01/01 00:00:00 * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated evo-ext-obscache in *.???? seconds (1r, 1o) (glob)
   1970/01/01 00:00:00 * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> 1 incoming changes - new heads: 4de32a90b66c (glob)
   * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> pull exited 0 after *.?? seconds (glob)
   * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> rollback (glob)
-  * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated base branch cache in *.???? seconds (glob)
-  * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> wrote base branch cache with 1 labels and 2 nodes (glob)
+  * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated branch cache (base) in *.???? seconds (glob)
+  * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> wrote branch cache (base) with 1 labels and 2 nodes (glob)
   * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> strip detected, evo-ext-obscache cache reset (glob)
   1970/01/01 00:00:00 * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated evo-ext-obscache in *.???? seconds (8r, 15o) (glob)
   * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> rollback exited 0 after *.?? seconds (glob)
@@ -1071,8 +1071,8 @@
   * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> strip detected, evo-ext-obscache cache reset (glob)
   * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> updated evo-ext-obscache in *.???? seconds (5r, 11o) (glob)
   * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> updated evo-ext-obscache in *.???? seconds (3r, 0o) (glob)
-  * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> updated base branch cache in *.???? seconds (glob)
-  * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> wrote base branch cache with 1 labels and 1 nodes (glob)
+  * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> updated branch cache (base) in *.???? seconds (glob)
+  * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> wrote branch cache (base) with 1 labels and 1 nodes (glob)
   * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> 3 incoming changes - new heads: 4de32a90b66c (glob)
   * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> --config "extensions.strip=" strip -r "desc(\"foo\")" exited 0 after *.?? seconds (glob) (windows !)
   * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> --config 'extensions.strip=' strip -r 'desc("foo")' exited 0 after *.?? seconds (glob) (no-windows !)
@@ -1091,8 +1091,8 @@
   * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> strip detected, evo-ext-firstmerge cache reset (glob)
   * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> updated evo-ext-firstmerge in *.???? seconds (8r) (glob)
   * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> obsdiscovery, 1/8 mismatch - 1 obshashrange queries in *.???? seconds (glob)
-  1970/01/01 00:00:00 * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> updated base branch cache in *.???? seconds (glob)
-  1970/01/01 00:00:00 * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> wrote base branch cache with 1 labels and 2 nodes (glob)
+  1970/01/01 00:00:00 * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> updated branch cache (base) in *.???? seconds (glob)
+  1970/01/01 00:00:00 * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> wrote branch cache (base) with 1 labels and 2 nodes (glob)
   1970/01/01 00:00:00 * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> updated evo-ext-obscache in *.???? seconds (1r, 5o) (glob)
   1970/01/01 00:00:00 * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> 1 incoming changes - new heads: 45f8b879de92 (glob)
   * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> pull exited 0 after *.?? seconds (glob)
@@ -1142,7 +1142,7 @@
   [1]
   $ hg debugupdatecache --debug
   updating the branch cache
-  invalid branchheads cache (served): tip differs
+  invalid branch cache (served): tip differs
   $ f -s .hg/cache/evoext*
   .hg/cache/evoext-depthcache-00: size=96
   .hg/cache/evoext-firstmerge-00: size=96
--- a/tests/test-evolve-abort-orphan.t	Wed Jul 17 17:58:44 2019 +0200
+++ b/tests/test-evolve-abort-orphan.t	Wed Jul 17 18:06:14 2019 +0200
@@ -42,7 +42,7 @@
 =============================================
 
   $ hg evolve --abort
-  abort: no interrupted evolve to stop
+  abort: no interrupted evolve to abort
   [255]
 
 Testing with wrong combination of flags
@@ -85,7 +85,8 @@
   atop:[5] added c
   merging d
   warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
 
   $ hg parents
@@ -132,7 +133,8 @@
   atop:[5] added c
   merging d
   warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
   $ echo foo > d
   $ hg resolve -m
@@ -159,7 +161,8 @@
   move:[5] added c
   merging c
   warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
 
 testing that interrupted evolve shows up in morestatus
@@ -270,7 +273,8 @@
   atop:[7] added a
   merging a
   warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
 
   $ hg glog
@@ -334,7 +338,8 @@
   atop:[7] added a
   merging a
   warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
   $ hg glog
   o  9:7f8e8bd9f0b6 added c
@@ -411,7 +416,8 @@
   atop:[7] added a
   merging a
   warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
 
   $ hg glog
@@ -486,7 +492,8 @@
   move:[3] added c
   merging c
   warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
 
   $ hg glog
@@ -532,7 +539,8 @@
   atop:[5] added b
   merging c
   warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
 
   $ hg evolve --abort
--- a/tests/test-evolve-abort-phasediv.t	Wed Jul 17 17:58:44 2019 +0200
+++ b/tests/test-evolve-abort-phasediv.t	Wed Jul 17 18:06:14 2019 +0200
@@ -87,7 +87,8 @@
   rebasing to destination parent: ca1b80f7960a
   merging c
   warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
 
 testing that interrupted evolve shows up in morestatus
@@ -213,7 +214,8 @@
   rebasing to destination parent: b1661037fa25
   merging b
   warning: conflicts while merging b! (edit, then use 'hg resolve --mark')
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
 
   $ hg evolve --abort
@@ -282,7 +284,8 @@
   rebasing to destination parent: b1661037fa25
   merging b
   warning: conflicts while merging b! (edit, then use 'hg resolve --mark')
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
 
   $ echo watwat > c
@@ -297,7 +300,8 @@
   rebasing to destination parent: ca1b80f7960a
   merging c
   warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
 
   $ hg evolve --abort
--- a/tests/test-evolve-content-divergent-basic.t	Wed Jul 17 17:58:44 2019 +0200
+++ b/tests/test-evolve-content-divergent-basic.t	Wed Jul 17 18:06:14 2019 +0200
@@ -340,7 +340,8 @@
   merging d
   warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
   0 files updated, 0 files merged, 0 files removed, 1 files unresolved
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
 
   $ echo foobar > d
@@ -399,7 +400,8 @@
   merging d
   warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
   0 files updated, 0 files merged, 0 files removed, 1 files unresolved
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
 
   $ echo watbar > d
@@ -609,7 +611,8 @@
   merging a
   warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
   0 files updated, 0 files merged, 0 files removed, 1 files unresolved
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
 
   $ cat > a <<EOF
--- a/tests/test-evolve-content-divergent-corner-cases.t	Wed Jul 17 17:58:44 2019 +0200
+++ b/tests/test-evolve-content-divergent-corner-cases.t	Wed Jul 17 18:06:14 2019 +0200
@@ -277,7 +277,8 @@
   rebasing "other" content-divergent changeset de4ea3103326 on 9150fe93bec6
   merging d
   warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
 
   $ hg diff --no-git --config diff.unified=3
--- a/tests/test-evolve-content-divergent-interrupted.t	Wed Jul 17 17:58:44 2019 +0200
+++ b/tests/test-evolve-content-divergent-interrupted.t	Wed Jul 17 18:06:14 2019 +0200
@@ -86,7 +86,8 @@
   merging d
   warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
   0 files updated, 0 files merged, 0 files removed, 1 files unresolved
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
 
   $ hg status -v
@@ -197,7 +198,8 @@
   merging d
   warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
   0 files updated, 0 files merged, 0 files removed, 1 files unresolved
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
 
   $ hg evolve --abort
@@ -303,7 +305,8 @@
   rebasing "other" content-divergent changeset 69bdd23a9b0d on ca1b80f7960a
   merging c
   warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
 
   $ hg evolve --abort
@@ -356,7 +359,8 @@
   merging d
   warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
   0 files updated, 0 files merged, 0 files removed, 1 files unresolved
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
 
   $ hg evolve --abort
@@ -447,7 +451,8 @@
   merging d
   warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
   0 files updated, 0 files merged, 0 files removed, 1 files unresolved
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
 
   $ hg evolve --stop
@@ -499,7 +504,8 @@
   merging d
   warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
   0 files updated, 0 files merged, 0 files removed, 1 files unresolved
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
 
   $ hg evolve --stop
@@ -548,7 +554,8 @@
   rebasing "other" content-divergent changeset 8fd1c4bd144c on ca1b80f7960a
   merging c
   warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
 
   $ hg diff
--- a/tests/test-evolve-content-divergent-relocation.t	Wed Jul 17 17:58:44 2019 +0200
+++ b/tests/test-evolve-content-divergent-relocation.t	Wed Jul 17 18:06:14 2019 +0200
@@ -255,7 +255,8 @@
   merging y
   warning: conflicts while merging y! (edit, then use 'hg resolve --mark')
   0 files updated, 0 files merged, 0 files removed, 1 files unresolved
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
 
   $ echo watbar > y
@@ -389,7 +390,8 @@
   rebasing "other" content-divergent changeset 3f7a1f693080 on 7bbcf24ddecf
   merging y
   warning: conflicts while merging y! (edit, then use 'hg resolve --mark')
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
 
   $ hg diff
@@ -418,7 +420,8 @@
   merging y
   warning: conflicts while merging y! (edit, then use 'hg resolve --mark')
   0 files updated, 0 files merged, 0 files removed, 1 files unresolved
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
 
   $ hg diff
--- a/tests/test-evolve-continue.t	Wed Jul 17 17:58:44 2019 +0200
+++ b/tests/test-evolve-continue.t	Wed Jul 17 18:06:14 2019 +0200
@@ -58,7 +58,8 @@
   atop:[5] added c
   merging d
   warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
 
   $ echo foo > d
@@ -118,7 +119,8 @@
   atop:[8] added d
   merging e
   warning: conflicts while merging e! (edit, then use 'hg resolve --mark')
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
 
   $ echo bar > e
@@ -158,7 +160,8 @@
   atop:[9] added a
   merging b
   warning: conflicts while merging b! (edit, then use 'hg resolve --mark')
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
 
   $ echo foo > b
@@ -242,7 +245,8 @@
   move:[13] added f
   merging f
   warning: conflicts while merging f! (edit, then use 'hg resolve --mark')
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
 
   $ echo foo > f
@@ -256,7 +260,8 @@
   move:[15] added h
   merging h
   warning: conflicts while merging h! (edit, then use 'hg resolve --mark')
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
 
   $ echo foo > h
@@ -302,7 +307,8 @@
   perform evolve? [Ny] y
   merging g
   warning: conflicts while merging g! (edit, then use 'hg resolve --mark')
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
 
   $ echo foo > g
@@ -350,7 +356,8 @@
   atop:[24] added f
   merging g
   warning: conflicts while merging g! (edit, then use 'hg resolve --mark')
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
   $ echo foo > g
   $ hg resolve -m
@@ -416,7 +423,8 @@
   atop:[5] added c
   merging c
   warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
 
 Status mentions file 'b' (copied from 'a') here, even though it wasn't
--- a/tests/test-evolve-issue5966.t	Wed Jul 17 17:58:44 2019 +0200
+++ b/tests/test-evolve-issue5966.t	Wed Jul 17 18:06:14 2019 +0200
@@ -57,7 +57,8 @@
   $ hg evolve -t :fail --rev 'first(orphan())'
   move:[2] banana
   atop:[4] apricot
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
   $ hg evolve --list
   34a690fcf6ab: banana
--- a/tests/test-evolve-issue5967.t	Wed Jul 17 17:58:44 2019 +0200
+++ b/tests/test-evolve-issue5967.t	Wed Jul 17 18:06:14 2019 +0200
@@ -41,7 +41,8 @@
   atop:[2] apricot
   merging a
   warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
 
   $ echo apricot > a
--- a/tests/test-evolve-obshistory-complex.t	Wed Jul 17 17:58:44 2019 +0200
+++ b/tests/test-evolve-obshistory-complex.t	Wed Jul 17 18:06:14 2019 +0200
@@ -153,25 +153,30 @@
   adding B
   diff --git a/A b/A
   new file mode 100644
-  examine changes to 'A'? [Ynesfdaq?] Y
+  examine changes to 'A'?
+  (enter ? for help) [Ynesfdaq?] Y
   
   @@ -0,0 +1,1 @@
   +A
-  record change 1/2 to 'A'? [Ynesfdaq?] Y
+  record change 1/2 to 'A'?
+  (enter ? for help) [Ynesfdaq?] Y
   
   diff --git a/B b/B
   new file mode 100644
-  examine changes to 'B'? [Ynesfdaq?] N
+  examine changes to 'B'?
+  (enter ? for help) [Ynesfdaq?] N
   
   created new head
   continue splitting? [Ycdq?] Y
   diff --git a/B b/B
   new file mode 100644
-  examine changes to 'B'? [Ynesfdaq?] Y
+  examine changes to 'B'?
+  (enter ? for help) [Ynesfdaq?] Y
   
   @@ -0,0 +1,1 @@
   +B
-  record this change to 'B'? [Ynesfdaq?] Y
+  record this change to 'B'?
+  (enter ? for help) [Ynesfdaq?] Y
   
   no more change to split
   $ hg split --rev "desc(fold1)" -d "0 0" << EOF
@@ -187,25 +192,30 @@
   adding D
   diff --git a/C b/C
   new file mode 100644
-  examine changes to 'C'? [Ynesfdaq?] Y
+  examine changes to 'C'?
+  (enter ? for help) [Ynesfdaq?] Y
   
   @@ -0,0 +1,1 @@
   +C
-  record change 1/2 to 'C'? [Ynesfdaq?] Y
+  record change 1/2 to 'C'?
+  (enter ? for help) [Ynesfdaq?] Y
   
   diff --git a/D b/D
   new file mode 100644
-  examine changes to 'D'? [Ynesfdaq?] N
+  examine changes to 'D'?
+  (enter ? for help) [Ynesfdaq?] N
   
   created new head
   continue splitting? [Ycdq?] Y
   diff --git a/D b/D
   new file mode 100644
-  examine changes to 'D'? [Ynesfdaq?] Y
+  examine changes to 'D'?
+  (enter ? for help) [Ynesfdaq?] Y
   
   @@ -0,0 +1,1 @@
   +D
-  record this change to 'D'? [Ynesfdaq?] Y
+  record this change to 'D'?
+  (enter ? for help) [Ynesfdaq?] Y
   
   no more change to split
   1 new orphan changesets
@@ -222,25 +232,30 @@
   adding F
   diff --git a/E b/E
   new file mode 100644
-  examine changes to 'E'? [Ynesfdaq?] Y
+  examine changes to 'E'?
+  (enter ? for help) [Ynesfdaq?] Y
   
   @@ -0,0 +1,1 @@
   +E
-  record change 1/2 to 'E'? [Ynesfdaq?] Y
+  record change 1/2 to 'E'?
+  (enter ? for help) [Ynesfdaq?] Y
   
   diff --git a/F b/F
   new file mode 100644
-  examine changes to 'F'? [Ynesfdaq?] N
+  examine changes to 'F'?
+  (enter ? for help) [Ynesfdaq?] N
   
   created new head
   continue splitting? [Ycdq?] Y
   diff --git a/F b/F
   new file mode 100644
-  examine changes to 'F'? [Ynesfdaq?] Y
+  examine changes to 'F'?
+  (enter ? for help) [Ynesfdaq?] Y
   
   @@ -0,0 +1,1 @@
   +F
-  record this change to 'F'? [Ynesfdaq?] Y
+  record this change to 'F'?
+  (enter ? for help) [Ynesfdaq?] Y
   
   no more change to split
   1 new orphan changesets
--- a/tests/test-evolve-obshistory-lots-of-splits.t	Wed Jul 17 17:58:44 2019 +0200
+++ b/tests/test-evolve-obshistory-lots-of-splits.t	Wed Jul 17 18:06:14 2019 +0200
@@ -63,63 +63,77 @@
   adding d
   diff --git a/a b/a
   new file mode 100644
-  examine changes to 'a'? [Ynesfdaq?] y
+  examine changes to 'a'?
+  (enter ? for help) [Ynesfdaq?] y
   
   @@ -0,0 +1,1 @@
   +42
-  record change 1/4 to 'a'? [Ynesfdaq?] y
+  record change 1/4 to 'a'?
+  (enter ? for help) [Ynesfdaq?] y
   
   diff --git a/b b/b
   new file mode 100644
-  examine changes to 'b'? [Ynesfdaq?] n
+  examine changes to 'b'?
+  (enter ? for help) [Ynesfdaq?] n
   
   diff --git a/c b/c
   new file mode 100644
-  examine changes to 'c'? [Ynesfdaq?] n
+  examine changes to 'c'?
+  (enter ? for help) [Ynesfdaq?] n
   
   diff --git a/d b/d
   new file mode 100644
-  examine changes to 'd'? [Ynesfdaq?] n
+  examine changes to 'd'?
+  (enter ? for help) [Ynesfdaq?] n
   
   created new head
   continue splitting? [Ycdq?] y
   diff --git a/b b/b
   new file mode 100644
-  examine changes to 'b'? [Ynesfdaq?] y
+  examine changes to 'b'?
+  (enter ? for help) [Ynesfdaq?] y
   
   @@ -0,0 +1,1 @@
   +43
-  record change 1/3 to 'b'? [Ynesfdaq?] y
+  record change 1/3 to 'b'?
+  (enter ? for help) [Ynesfdaq?] y
   
   diff --git a/c b/c
   new file mode 100644
-  examine changes to 'c'? [Ynesfdaq?] n
+  examine changes to 'c'?
+  (enter ? for help) [Ynesfdaq?] n
   
   diff --git a/d b/d
   new file mode 100644
-  examine changes to 'd'? [Ynesfdaq?] n
+  examine changes to 'd'?
+  (enter ? for help) [Ynesfdaq?] n
   
   continue splitting? [Ycdq?] y
   diff --git a/c b/c
   new file mode 100644
-  examine changes to 'c'? [Ynesfdaq?] y
+  examine changes to 'c'?
+  (enter ? for help) [Ynesfdaq?] y
   
   @@ -0,0 +1,1 @@
   +44
-  record change 1/2 to 'c'? [Ynesfdaq?] y
+  record change 1/2 to 'c'?
+  (enter ? for help) [Ynesfdaq?] y
   
   diff --git a/d b/d
   new file mode 100644
-  examine changes to 'd'? [Ynesfdaq?] n
+  examine changes to 'd'?
+  (enter ? for help) [Ynesfdaq?] n
   
   continue splitting? [Ycdq?] y
   diff --git a/d b/d
   new file mode 100644
-  examine changes to 'd'? [Ynesfdaq?] y
+  examine changes to 'd'?
+  (enter ? for help) [Ynesfdaq?] y
   
   @@ -0,0 +1,1 @@
   +45
-  record this change to 'd'? [Ynesfdaq?] y
+  record this change to 'd'?
+  (enter ? for help) [Ynesfdaq?] y
   
   no more change to split
 
--- a/tests/test-evolve-obshistory-split.t	Wed Jul 17 17:58:44 2019 +0200
+++ b/tests/test-evolve-obshistory-split.t	Wed Jul 17 18:06:14 2019 +0200
@@ -47,25 +47,30 @@
   adding b
   diff --git a/a b/a
   new file mode 100644
-  examine changes to 'a'? [Ynesfdaq?] y
+  examine changes to 'a'?
+  (enter ? for help) [Ynesfdaq?] y
   
   @@ -0,0 +1,1 @@
   +42
-  record change 1/2 to 'a'? [Ynesfdaq?] y
+  record change 1/2 to 'a'?
+  (enter ? for help) [Ynesfdaq?] y
   
   diff --git a/b b/b
   new file mode 100644
-  examine changes to 'b'? [Ynesfdaq?] n
+  examine changes to 'b'?
+  (enter ? for help) [Ynesfdaq?] n
   
   created new head
   continue splitting? [Ycdq?] y
   diff --git a/b b/b
   new file mode 100644
-  examine changes to 'b'? [Ynesfdaq?] y
+  examine changes to 'b'?
+  (enter ? for help) [Ynesfdaq?] y
   
   @@ -0,0 +1,1 @@
   +43
-  record this change to 'b'? [Ynesfdaq?] y
+  record this change to 'b'?
+  (enter ? for help) [Ynesfdaq?] y
   
   no more change to split
 
--- a/tests/test-evolve-orphan-merge.t	Wed Jul 17 17:58:44 2019 +0200
+++ b/tests/test-evolve-orphan-merge.t	Wed Jul 17 18:06:14 2019 +0200
@@ -219,7 +219,8 @@
   atop:[11] foo to c
   merging c
   warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
 
   $ echo FOObar > c
@@ -274,7 +275,8 @@
   atop:[13] foo to c
   merging c
   warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
 
   $ echo foobar > c
--- a/tests/test-evolve-orphan-split.t	Wed Jul 17 17:58:44 2019 +0200
+++ b/tests/test-evolve-orphan-split.t	Wed Jul 17 18:06:14 2019 +0200
@@ -48,15 +48,18 @@
   adding b
   diff --git a/a b/a
   new file mode 100644
-  examine changes to 'a'? [Ynesfdaq?] y
+  examine changes to 'a'?
+  (enter ? for help) [Ynesfdaq?] y
   
   @@ -0,0 +1,1 @@
   +foo
-  record change 1/2 to 'a'? [Ynesfdaq?] y
+  record change 1/2 to 'a'?
+  (enter ? for help) [Ynesfdaq?] y
   
   diff --git a/b b/b
   new file mode 100644
-  examine changes to 'b'? [Ynesfdaq?] n
+  examine changes to 'b'?
+  (enter ? for help) [Ynesfdaq?] n
   
   created new head
   continue splitting? [Ycdq?] c
@@ -129,27 +132,33 @@
   adding c
   diff --git a/a b/a
   new file mode 100644
-  examine changes to 'a'? [Ynesfdaq?] y
+  examine changes to 'a'?
+  (enter ? for help) [Ynesfdaq?] y
   
   @@ -0,0 +1,1 @@
   +foo
-  record change 1/3 to 'a'? [Ynesfdaq?] n
+  record change 1/3 to 'a'?
+  (enter ? for help) [Ynesfdaq?] n
   
   diff --git a/b b/b
   new file mode 100644
-  examine changes to 'b'? [Ynesfdaq?] y
+  examine changes to 'b'?
+  (enter ? for help) [Ynesfdaq?] y
   
   @@ -0,0 +1,1 @@
   +foo
-  record change 2/3 to 'b'? [Ynesfdaq?] y
+  record change 2/3 to 'b'?
+  (enter ? for help) [Ynesfdaq?] y
   
   diff --git a/c b/c
   new file mode 100644
-  examine changes to 'c'? [Ynesfdaq?] y
+  examine changes to 'c'?
+  (enter ? for help) [Ynesfdaq?] y
   
   @@ -0,0 +1,1 @@
   +foo
-  record change 3/3 to 'c'? [Ynesfdaq?] y
+  record change 3/3 to 'c'?
+  (enter ? for help) [Ynesfdaq?] y
   
   created new head
   continue splitting? [Ycdq?] c
--- a/tests/test-evolve-phase-divergence.t	Wed Jul 17 17:58:44 2019 +0200
+++ b/tests/test-evolve-phase-divergence.t	Wed Jul 17 18:06:14 2019 +0200
@@ -807,7 +807,8 @@
   rebasing to destination parent: 8c2bb6fb44e9
   merging x
   warning: conflicts while merging x! (edit, then use 'hg resolve --mark')
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
 
   $ hg diff
--- a/tests/test-evolve-phase.t	Wed Jul 17 17:58:44 2019 +0200
+++ b/tests/test-evolve-phase.t	Wed Jul 17 18:06:14 2019 +0200
@@ -85,7 +85,8 @@
   atop:[3] b
   merging a
   warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
 
   $ hg diff
--- a/tests/test-evolve-progress.t	Wed Jul 17 17:58:44 2019 +0200
+++ b/tests/test-evolve-progress.t	Wed Jul 17 18:06:14 2019 +0200
@@ -28,7 +28,6 @@
   atop:[4] first v2
   hg rebase -r 4f60c78b6d58 -d fd0a2402f834
   evolve: 1/3 changesets (33.33%)
-    searching for copies back to rev 0
   resolving manifests
    branchmerge: True, force: True, partial: False
    ancestor: a87874c6ec31, local: fd0a2402f834+, remote: 4f60c78b6d58
@@ -43,10 +42,7 @@
   move:[2] third
   hg rebase -r 769574b07a96 -d 5f16d91ecde0
   evolve: 2/3 changesets (66.67%)
-    searching for copies back to rev 0
-    unmatched files in other (from base):
-     b
-    unmatched files in other (from topological common ancestor):
+    unmatched files in other:
      b
   resolving manifests
    branchmerge: True, force: True, partial: False
@@ -62,7 +58,6 @@
   move:[3] fourth
   hg rebase -r 22782fddc0ab -d 53c0008d98a0
   evolve: 3/3 changesets (100.00%)
-    searching for copies back to rev 0
   resolving manifests
    branchmerge: True, force: True, partial: False
    ancestor: 769574b07a96, local: 53c0008d98a0+, remote: 22782fddc0ab
@@ -75,7 +70,7 @@
   committing changelog
   updating the branch cache
   obscache is out of date
-  invalid branchheads cache (served): tip differs
+  invalid branch cache (served): tip differs
   resolving manifests
    branchmerge: False, force: False, partial: False
    ancestor: 385376d04062, local: 385376d04062+, remote: fd0a2402f834
@@ -96,7 +91,6 @@
   atop:[8] first v3
   hg rebase -r 5f16d91ecde0 -d 152c368c622b
   evolve: 1/1 changesets (100.00%)
-    searching for copies back to rev 4
   resolving manifests
    branchmerge: True, force: True, partial: False
    ancestor: fd0a2402f834, local: 152c368c622b+, remote: 5f16d91ecde0
@@ -127,7 +121,6 @@
   atop:[10] first v4
   hg rebase -r df5d742141b0 -d f8d7d38c0a88
   evolve: 1/3 changesets (33.33%)
-    searching for copies back to rev 8
   resolving manifests
    branchmerge: True, force: True, partial: False
    ancestor: 152c368c622b, local: f8d7d38c0a88+, remote: df5d742141b0
@@ -142,7 +135,8 @@
   picked tool ':merge' for a (binary False symlink False changedelete False)
   my a@f8d7d38c0a88+ other a@df5d742141b0 ancestor a@152c368c622b
   warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
   $ echo resolved > a
   $ hg resolve -m a
@@ -160,10 +154,7 @@
   atop:[11] second
   hg rebase -r 53c0008d98a0 -d 60a86497fbfe
   evolve: 2/3 changesets (66.67%)
-    searching for copies back to rev 4
-    unmatched files in other (from base):
-     b
-    unmatched files in other (from topological common ancestor):
+    unmatched files in other:
      b
   resolving manifests
    branchmerge: True, force: True, partial: False
@@ -178,7 +169,6 @@
   move:[7] fourth
   hg rebase -r 385376d04062 -d b2de95304e32
   evolve: 3/3 changesets (100.00%)
-    searching for copies back to rev 4
   resolving manifests
    branchmerge: True, force: True, partial: False
    ancestor: 53c0008d98a0, local: b2de95304e32+, remote: 385376d04062
@@ -191,7 +181,7 @@
   committing changelog
   updating the branch cache
   obscache is out of date
-  invalid branchheads cache (served): tip differs
+  invalid branch cache (served): tip differs
   resolving manifests
    branchmerge: False, force: False, partial: False
    ancestor: c6e6fdb1d046, local: c6e6fdb1d046+, remote: f8d7d38c0a88
--- a/tests/test-evolve-public-content-divergent-corner-cases.t	Wed Jul 17 17:58:44 2019 +0200
+++ b/tests/test-evolve-public-content-divergent-corner-cases.t	Wed Jul 17 18:06:14 2019 +0200
@@ -389,7 +389,8 @@
   rebasing "other" content-divergent changeset e568fd1029bb on 155349b645be
   merging c
   warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
 
   $ hg diff
@@ -416,10 +417,11 @@
   $ hg evolve --continue
   evolving 4:e568fd1029bb "added c e"
   file 'd' was deleted in other but was modified in local.
-  What do you want to do?
-  use (c)hanged version, (d)elete, or leave (u)nresolved? u
+  You can use (c)hanged version, (d)elete, or leave (u)nresolved.
+  What do you want to do? u
   1 files updated, 0 files merged, 0 files removed, 1 files unresolved
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
 
   $ hg sum
--- a/tests/test-evolve-public-content-divergent-discard.t	Wed Jul 17 17:58:44 2019 +0200
+++ b/tests/test-evolve-public-content-divergent-discard.t	Wed Jul 17 18:06:14 2019 +0200
@@ -269,7 +269,8 @@
   merging ch
   warning: conflicts while merging ch! (edit, then use 'hg resolve --mark')
   0 files updated, 0 files merged, 0 files removed, 1 files unresolved
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
 
   $ hg diff
@@ -383,7 +384,8 @@
   rebasing "other" content-divergent changeset f89a8e2f86ac on 155349b645be
   merging c
   warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
 
   $ echo c > c
@@ -488,7 +490,8 @@
   merging dh
   warning: conflicts while merging dh! (edit, then use 'hg resolve --mark')
   0 files updated, 0 files merged, 0 files removed, 1 files unresolved
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
 
   $ echo dh > dh
@@ -591,7 +594,8 @@
   rebasing "other" content-divergent changeset 67b19bbd770f on 155349b645be
   merging c
   warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
 
   $ echo c > c
@@ -604,7 +608,8 @@
   merging dh
   warning: conflicts while merging dh! (edit, then use 'hg resolve --mark')
   0 files updated, 0 files merged, 0 files removed, 1 files unresolved
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
 
   $ echo dh > dh
--- a/tests/test-evolve-public-content-divergent-main.t	Wed Jul 17 17:58:44 2019 +0200
+++ b/tests/test-evolve-public-content-divergent-main.t	Wed Jul 17 18:06:14 2019 +0200
@@ -170,7 +170,8 @@
   merging b
   warning: conflicts while merging b! (edit, then use 'hg resolve --mark')
   0 files updated, 0 files merged, 0 files removed, 1 files unresolved
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
 
   $ echo "I am foobar" > b
@@ -356,7 +357,8 @@
   rebasing "other" content-divergent changeset f31bcc378766 on 155349b645be
   merging c
   warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
 
   $ hg diff
@@ -486,7 +488,8 @@
   merging d
   warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
   0 files updated, 0 files merged, 0 files removed, 1 files unresolved
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
 
   $ echo d > d
@@ -578,7 +581,8 @@
   rebasing "other" content-divergent changeset 3c17c7afaf6e on 155349b645be
   merging c
   warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
 
   $ hg diff
@@ -612,7 +616,8 @@
   merging d
   warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
   2 files updated, 0 files merged, 0 files removed, 1 files unresolved
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
 
   $ echo d > d
--- a/tests/test-evolve-stop-orphan.t	Wed Jul 17 17:58:44 2019 +0200
+++ b/tests/test-evolve-stop-orphan.t	Wed Jul 17 18:06:14 2019 +0200
@@ -90,7 +90,8 @@
   atop:[5] added c
   merging d
   warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
 
   $ hg evolve --stop
@@ -135,7 +136,8 @@
   atop:[5] added c
   merging d
   warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
 
   $ hg diff
@@ -196,7 +198,8 @@
   atop:[5] added c
   merging d
   warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
   $ echo foo > d
   $ hg resolve -m
@@ -245,7 +248,8 @@
   move:[5] added c
   merging c
   warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
 
   $ hg status
@@ -282,7 +286,8 @@
   atop:[9] added b
   merging c
   warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
 
   $ echo foobar > c
@@ -357,7 +362,8 @@
   move:[10] added c
   merging c
   warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
 
   $ hg evolve --stop
--- a/tests/test-evolve-stop-phasediv.t	Wed Jul 17 17:58:44 2019 +0200
+++ b/tests/test-evolve-stop-phasediv.t	Wed Jul 17 18:06:14 2019 +0200
@@ -84,7 +84,8 @@
   rebasing to destination parent: ca1b80f7960a
   merging c
   warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
 
   $ hg evolve --stop
--- a/tests/test-evolve-templates.t	Wed Jul 17 17:58:44 2019 +0200
+++ b/tests/test-evolve-templates.t	Wed Jul 17 18:06:14 2019 +0200
@@ -281,25 +281,30 @@
   adding b
   diff --git a/a b/a
   new file mode 100644
-  examine changes to 'a'? [Ynesfdaq?] y
+  examine changes to 'a'?
+  (enter ? for help) [Ynesfdaq?] y
   
   @@ -0,0 +1,1 @@
   +42
-  record change 1/2 to 'a'? [Ynesfdaq?] y
+  record change 1/2 to 'a'?
+  (enter ? for help) [Ynesfdaq?] y
   
   diff --git a/b b/b
   new file mode 100644
-  examine changes to 'b'? [Ynesfdaq?] n
+  examine changes to 'b'?
+  (enter ? for help) [Ynesfdaq?] n
   
   created new head
   continue splitting? [Ycdq?] y
   diff --git a/b b/b
   new file mode 100644
-  examine changes to 'b'? [Ynesfdaq?] y
+  examine changes to 'b'?
+  (enter ? for help) [Ynesfdaq?] y
   
   @@ -0,0 +1,1 @@
   +43
-  record this change to 'b'? [Ynesfdaq?] y
+  record this change to 'b'?
+  (enter ? for help) [Ynesfdaq?] y
   
   no more change to split
 
--- a/tests/test-evolve-topic.t	Wed Jul 17 17:58:44 2019 +0200
+++ b/tests/test-evolve-topic.t	Wed Jul 17 18:06:14 2019 +0200
@@ -426,7 +426,8 @@
   move:[s3] add hhh
   merging hhh
   warning: conflicts while merging hhh! (edit, then use 'hg resolve --mark')
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
   $ echo "resolved hhh" > hhh
   $ hg resolve --mark hhh
@@ -438,3 +439,22 @@
   atop:[s3] add hhh
   move:[s5] add jjj
   working directory is now at 2c295936ac04
+
+Test to make sure that evolve don't crash with FilteredRepoLookupError when obsolete revs are in play:
+------------------------------------------------------------------------------------------------------
+
+update to obsolete revision
+  $ hg up -r 'min(desc("add fff"))' --hidden
+  switching to topic foo
+  2 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  updated to hidden changeset 6a6b7365c751
+  (hidden revision '6a6b7365c751' was rewritten as: 2c295936ac04)
+  working directory parent is obsolete! (6a6b7365c751)
+  (use 'hg evolve' to update to its successor: 2c295936ac04)
+
+Evolve:
+  $ hg evolve
+  update:[26] add fff
+  switching to topic bar
+  3 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  working directory is now at 2c295936ac04
--- a/tests/test-evolve.t	Wed Jul 17 17:58:44 2019 +0200
+++ b/tests/test-evolve.t	Wed Jul 17 18:06:14 2019 +0200
@@ -1389,7 +1389,8 @@
   move:[31] will cause conflict at evolve
   merging newfile
   warning: conflicts while merging newfile! (edit, then use 'hg resolve --mark')
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
 
   $ glog -r "desc('add unstableifparentisfolded')::" --hidden
@@ -1441,7 +1442,6 @@
   update:[1] added a
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   working directory is now at ab832e43dd5a
-  no troubled changesets
 
   $ hg log -GT "{rev}:{node|short} {desc} ({bookmarks})\n" --hidden
   @  1:ab832e43dd5a added a (book)
--- a/tests/test-fold.t	Wed Jul 17 17:58:44 2019 +0200
+++ b/tests/test-fold.t	Wed Jul 17 18:06:14 2019 +0200
@@ -7,9 +7,17 @@
   > fold=-d "0 0"
   > [extensions]
   > evolve=
+  > [alias]
+  > glog = log -GT "{rev}: {desc}"
+  > glf = log -GT "{rev}: {desc} ({files})"
   > [ui]
   > logtemplate = '{rev} - {node|short} {desc|firstline} [{author}] ({phase}) {bookmarks}\n'
   > EOF
+  $ mkcommit() {
+  >    echo "$1" > "$1"
+  >    hg add "$1"
+  >    hg ci -qm "$1"
+  > }
 
   $ hg init fold-tests
   $ cd fold-tests/
@@ -270,3 +278,106 @@
 
   $ cd ..
 
+One merge commit
+
+  $ hg init fold-a-merge
+  $ cd fold-a-merge
+
+  $ mkcommit zebra
+
+  $ hg up null
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ mkcommit apple
+  $ mkcommit banana
+
+  $ hg merge
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  $ hg ci -m merge
+
+  $ mkcommit coconut
+
+  $ hg glf
+  @  4: coconut (coconut)
+  |
+  o    3: merge ()
+  |\
+  | o  2: banana (banana)
+  | |
+  | o  1: apple (apple)
+  |
+  o  0: zebra (zebra)
+  
+
+now we merge some of the fruits
+
+  $ hg fold --exact -r 'desc("banana")::desc("coconut")' -m 'banana+coconut in a merge with zebra'
+  3 changesets folded
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg glf
+  @    5: banana+coconut in a merge with zebra (banana coconut)
+  |\
+  | o  1: apple (apple)
+  |
+  o  0: zebra (zebra)
+  
+
+let's go even further: zebra becomes a parent of the squashed fruit commit
+
+  $ hg fold --from -r 'desc("apple")' -m 'apple+banana+coconut is a child of zebra'
+  2 changesets folded
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg glf
+  @  6: apple+banana+coconut is a child of zebra (apple banana coconut)
+  |
+  o  0: zebra (zebra)
+  
+
+make sure zebra exists at tip and has expected contents
+
+  $ hg cat -r tip zebra
+  zebra
+
+  $ cd ..
+
+Multiple merge commits
+
+  $ hg init fold-many-merges
+  $ cd fold-many-merges
+
+  $ hg debugbuilddag '+3 *3 /3 /4 /4'
+  $ hg glog
+  o    6: r6
+  |\
+  | o    5: r5
+  | |\
+  | | o  4: r4
+  | |/|
+  | | o  3: r3
+  | | |
+  o | |  2: r2
+  |/ /
+  o /  1: r1
+  |/
+  o  0: r0
+  
+
+cannot fold 5 and 6 because they have 3 external parents in total: 1, 2, 4
+
+  $ hg fold --exact -r 5:6 -m r5+r6
+  abort: cannot fold revisions that merge with more than one external changeset (not in revisions)
+  [255]
+
+now many of the parents are included in the revisions to fold, only 0 and 3 are external
+
+  $ hg fold --exact -r 1+2+4+5+6 -m r1+r2+r4+r5+r6
+  5 changesets folded
+
+  $ hg glog
+  o    7: r1+r2+r4+r5+r6
+  |\
+  | o  3: r3
+  |/
+  o  0: r0
+  
+  $ cd ..
--- a/tests/test-issue-5720.t	Wed Jul 17 17:58:44 2019 +0200
+++ b/tests/test-issue-5720.t	Wed Jul 17 18:06:14 2019 +0200
@@ -61,7 +61,8 @@
   atop:[3] b
   merging a
   warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
 
 Fix the conflict
--- a/tests/test-metaedit.t	Wed Jul 17 17:58:44 2019 +0200
+++ b/tests/test-metaedit.t	Wed Jul 17 18:06:14 2019 +0200
@@ -10,6 +10,7 @@
   > publish = False
   > [alias]
   > qlog = log --template='{rev} - {node|short} {desc} ({phase})\n'
+  > gluf = log -GT "{rev}: {desc|firstline} - {author|user} ({files})"
   > [diff]
   > git = 1
   > unified = 0
@@ -229,3 +230,54 @@
   1 changesets folded
   $ hg log -r "tip" --template '{rev}: {author}\n'
   12: foobar3
+
+working on merge commits too
+
+  $ hg up -q 11
+  $ hg merge -q 12
+  $ hg ci -m 'merge commit'
+  $ hg st --change .
+  A D
+  $ hg metaedit --user someone-else
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg st --change .
+  A D
+  $ hg gluf
+  @    14: merge commit - someone-else ()
+  |\
+  | o  12: D2 - foobar3 (D)
+  | |
+  o |  11: E - foobar2 (E F)
+  |/
+  o  3: C - test (C)
+  |
+  | o  2: B - test (B)
+  |/
+  o  1: A - test (A)
+  |
+  o  0: ROOT - test (ROOT)
+  
+  $ hg metaedit --user mr-squasher -r 3:14 --fold --message squashed
+  4 changesets folded
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg st --change .
+  A C
+  A D
+  A E
+  A F
+  $ hg gluf
+  @  15: squashed - mr-squasher (C D E F)
+  |
+  | o  2: B - test (B)
+  |/
+  o  1: A - test (A)
+  |
+  o  0: ROOT - test (ROOT)
+  
+  $ hg files
+  A
+  C
+  D
+  E
+  F
+  ROOT
--- a/tests/test-prev-next.t	Wed Jul 17 17:58:44 2019 +0200
+++ b/tests/test-prev-next.t	Wed Jul 17 18:06:14 2019 +0200
@@ -470,8 +470,8 @@
   [255]
   $ hg prev --merge --config commands.update.check=abort
   file 'bar' was deleted in other [destination] but was modified in local [working copy].
-  What do you want to do?
-  use (c)hanged version, (d)elete, or leave (u)nresolved? 
+  You can use (c)hanged version, (d)elete, or leave (u)nresolved.
+  What do you want to do? 
   0 files updated, 0 files merged, 0 files removed, 1 files unresolved
   use 'hg resolve' to retry unresolved file merges
   [1] added foo
@@ -534,26 +534,31 @@
   adding b
   diff --git a/a b/a
   1 hunks, 1 lines changed
-  examine changes to 'a'? [Ynesfdaq?] y
+  examine changes to 'a'?
+  (enter ? for help) [Ynesfdaq?] y
   
   @@ -1,1 +1,2 @@
    firstline
   +secondline
-  record change 1/2 to 'a'? [Ynesfdaq?] y
+  record change 1/2 to 'a'?
+  (enter ? for help) [Ynesfdaq?] y
   
   diff --git a/b b/b
   new file mode 100644
-  examine changes to 'b'? [Ynesfdaq?] n
+  examine changes to 'b'?
+  (enter ? for help) [Ynesfdaq?] n
   
   created new head
   continue splitting? [Ycdq?] Y
   diff --git a/b b/b
   new file mode 100644
-  examine changes to 'b'? [Ynesfdaq?] y
+  examine changes to 'b'?
+  (enter ? for help) [Ynesfdaq?] y
   
   @@ -0,0 +1,1 @@
   +bbbbb
-  record this change to 'b'? [Ynesfdaq?] y
+  record this change to 'b'?
+  (enter ? for help) [Ynesfdaq?] y
   
   no more change to split
   1 new orphan changesets
--- a/tests/test-rewind.t	Wed Jul 17 17:58:44 2019 +0200
+++ b/tests/test-rewind.t	Wed Jul 17 18:06:14 2019 +0200
@@ -9,6 +9,8 @@
   > interactive = true
   > [phases]
   > publish=False
+  > [alias]
+  > glf = log -GT "{rev}: {desc} ({files})"
   > [extensions]
   > evolve =
   > EOF
@@ -467,15 +469,18 @@
   adding D
   diff --git a/C b/C
   new file mode 100644
-  examine changes to 'C'? [Ynesfdaq?] y
+  examine changes to 'C'?
+  (enter ? for help) [Ynesfdaq?] y
   
   @@ -0,0 +1,1 @@
   +C
-  record change 1/2 to 'C'? [Ynesfdaq?] f
+  record change 1/2 to 'C'?
+  (enter ? for help) [Ynesfdaq?] f
   
   diff --git a/D b/D
   new file mode 100644
-  examine changes to 'D'? [Ynesfdaq?] d
+  examine changes to 'D'?
+  (enter ? for help) [Ynesfdaq?] d
   
   created new head
   continue splitting? [Ycdq?] c
@@ -935,3 +940,45 @@
   $ hg rewind
   abort: uncommitted changes
   [255]
+
+Merge commits
+-------------
+
+  $ hg up --clean .^
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ echo foo > foo
+  $ hg ci -qAm foo
+
+  $ hg merge
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  $ hg ci -m merge
+  $ hg st --change .
+  A B
+
+  $ echo bar > foo
+  $ hg amend -m 'merge, but foo is now bar'
+  $ hg st --change .
+  M foo
+  A B
+
+  $ hg rewind --from .
+  rewinded to 1 changesets
+  (1 changesets obsoleted)
+  working directory is now at 006fd8c2fed9
+  $ hg st --change .
+  A B
+
+  $ hg glf -r '. + allpredecessors(.) + parents(.)' --hidden
+  @    6: merge ()
+  |\
+  +---x  5: merge, but foo is now bar (foo)
+  | |/
+  +---x  4: merge ()
+  | |/
+  | o  3: foo (C foo)
+  | |
+  | ~
+  o  2: c_B0 (B)
+  |
+  ~
--- a/tests/test-split.t	Wed Jul 17 17:58:44 2019 +0200
+++ b/tests/test-split.t	Wed Jul 17 18:06:14 2019 +0200
@@ -68,29 +68,35 @@
   adding _d
   diff --git a/_a b/_a
   1 hunks, 1 lines changed
-  examine changes to '_a'? [Ynesfdaq?] y
+  examine changes to '_a'?
+  (enter ? for help) [Ynesfdaq?] y
   
   @@ -1,0 +2,1 @@
   +change to a
-  record change 1/2 to '_a'? [Ynesfdaq?] y
+  record change 1/2 to '_a'?
+  (enter ? for help) [Ynesfdaq?] y
   
   diff --git a/_d b/_d
   new file mode 100644
-  examine changes to '_d'? [Ynesfdaq?] y
+  examine changes to '_d'?
+  (enter ? for help) [Ynesfdaq?] y
   
   @@ -0,0 +1,1 @@
   +_d
-  record change 2/2 to '_d'? [Ynesfdaq?] n
+  record change 2/2 to '_d'?
+  (enter ? for help) [Ynesfdaq?] n
   
   created new head
   continue splitting? [Ycdq?] Y
   diff --git a/_d b/_d
   new file mode 100644
-  examine changes to '_d'? [Ynesfdaq?] y
+  examine changes to '_d'?
+  (enter ? for help) [Ynesfdaq?] y
   
   @@ -0,0 +1,1 @@
   +_d
-  record this change to '_d'? [Ynesfdaq?] y
+  record this change to '_d'?
+  (enter ? for help) [Ynesfdaq?] y
   
   no more change to split
 
@@ -190,19 +196,23 @@
   adding _c
   diff --git a/_b b/_b
   1 hunks, 1 lines changed
-  examine changes to '_b'? [Ynesfdaq?] y
+  examine changes to '_b'?
+  (enter ? for help) [Ynesfdaq?] y
   
   @@ -1,0 +2,1 @@
   +change to b
-  record change 1/2 to '_b'? [Ynesfdaq?] y
+  record change 1/2 to '_b'?
+  (enter ? for help) [Ynesfdaq?] y
   
   diff --git a/_c b/_c
   new file mode 100644
-  examine changes to '_c'? [Ynesfdaq?] y
+  examine changes to '_c'?
+  (enter ? for help) [Ynesfdaq?] y
   
   @@ -0,0 +1,1 @@
   +_c
-  record change 2/2 to '_c'? [Ynesfdaq?] n
+  record change 2/2 to '_c'?
+  (enter ? for help) [Ynesfdaq?] n
   
   created new head
   continue splitting? [Ycdq?] c
@@ -293,17 +303,20 @@
   adding _d
   diff --git a/_a b/_a
   1 hunks, 2 lines changed
-  examine changes to '_a'? [Ynesfdaq?] y
+  examine changes to '_a'?
+  (enter ? for help) [Ynesfdaq?] y
   
   @@ -1,2 +1,1 @@
   -_a
   -change to a
   +changetofilea
-  record change 1/2 to '_a'? [Ynesfdaq?] y
+  record change 1/2 to '_a'?
+  (enter ? for help) [Ynesfdaq?] y
   
   diff --git a/_d b/_d
   new file mode 100644
-  examine changes to '_d'? [Ynesfdaq?] n
+  examine changes to '_d'?
+  (enter ? for help) [Ynesfdaq?] n
   
   created new head
   continue splitting? [Ycdq?] c
@@ -338,7 +351,8 @@
   adding _d
   diff --git a/_d b/_d
   new file mode 100644
-  examine changes to '_d'? [Ynesfdaq?] abort: response expected
+  examine changes to '_d'?
+  (enter ? for help) [Ynesfdaq?] abort: response expected
   [255]
 
 Cannot split a commit that is not a head if instability is not allowed
@@ -364,7 +378,8 @@
   adding _d
   diff --git a/_d b/_d
   new file mode 100644
-  examine changes to '_d'? [Ynesfdaq?] q
+  examine changes to '_d'?
+  (enter ? for help) [Ynesfdaq?] q
   
   abort: user quit
   [255]
@@ -377,7 +392,8 @@
   adding _d
   diff --git a/_d b/_d
   new file mode 100644
-  examine changes to '_d'? [Ynesfdaq?] q
+  examine changes to '_d'?
+  (enter ? for help) [Ynesfdaq?] q
   
   abort: user quit
   [255]
@@ -447,15 +463,18 @@
   adding celeste
   diff --git a/babar b/babar
   new file mode 100644
-  examine changes to 'babar'? [Ynesfdaq?] Y
+  examine changes to 'babar'?
+  (enter ? for help) [Ynesfdaq?] Y
   
   @@ -0,0 +1,1 @@
   +babar
-  record change 1/2 to 'babar'? [Ynesfdaq?] Y
+  record change 1/2 to 'babar'?
+  (enter ? for help) [Ynesfdaq?] Y
   
   diff --git a/celeste b/celeste
   new file mode 100644
-  examine changes to 'celeste'? [Ynesfdaq?] N
+  examine changes to 'celeste'?
+  (enter ? for help) [Ynesfdaq?] N
   
   continue splitting? [Ycdq?] c
 
@@ -539,16 +558,19 @@
   adding SPLIT2
   diff --git a/SPLIT1 b/SPLIT1
   new file mode 100644
-  examine changes to 'SPLIT1'? [Ynesfdaq?] Y
+  examine changes to 'SPLIT1'?
+  (enter ? for help) [Ynesfdaq?] Y
   
   diff --git a/SPLIT2 b/SPLIT2
   new file mode 100644
-  examine changes to 'SPLIT2'? [Ynesfdaq?] N
+  examine changes to 'SPLIT2'?
+  (enter ? for help) [Ynesfdaq?] N
   
   continue splitting? [Ycdq?] Y
   diff --git a/SPLIT2 b/SPLIT2
   new file mode 100644
-  examine changes to 'SPLIT2'? [Ynesfdaq?] Y
+  examine changes to 'SPLIT2'?
+  (enter ? for help) [Ynesfdaq?] Y
   
   no more change to split
 
@@ -617,11 +639,13 @@
   adding SPLIT4
   diff --git a/SPLIT3 b/SPLIT3
   new file mode 100644
-  examine changes to 'SPLIT3'? [Ynesfdaq?] Y
+  examine changes to 'SPLIT3'?
+  (enter ? for help) [Ynesfdaq?] Y
   
   diff --git a/SPLIT4 b/SPLIT4
   new file mode 100644
-  examine changes to 'SPLIT4'? [Ynesfdaq?] q
+  examine changes to 'SPLIT4'?
+  (enter ? for help) [Ynesfdaq?] q
   
   abort: user quit
   [255]
@@ -663,11 +687,13 @@
   adding SPLIT4
   diff --git a/SPLIT3 b/SPLIT3
   new file mode 100644
-  examine changes to 'SPLIT3'? [Ynesfdaq?] Y
+  examine changes to 'SPLIT3'?
+  (enter ? for help) [Ynesfdaq?] Y
   
   diff --git a/SPLIT4 b/SPLIT4
   new file mode 100644
-  examine changes to 'SPLIT4'? [Ynesfdaq?] ?
+  examine changes to 'SPLIT4'?
+  (enter ? for help) [Ynesfdaq?] ?
   
   y - yes, record this change
   n - no, skip this change
@@ -678,7 +704,8 @@
   a - record all changes to all remaining files
   q - quit, recording no changes
   ? - ? (display help)
-  examine changes to 'SPLIT4'? [Ynesfdaq?] d
+  examine changes to 'SPLIT4'?
+  (enter ? for help) [Ynesfdaq?] d
   
   continue splitting? [Ycdq?] ?
   y - yes, continue selection
@@ -741,11 +768,13 @@
   adding SPLIT3
   diff --git a/SPLIT2 b/SPLIT2
   new file mode 100644
-  examine changes to 'SPLIT2'? [Ynesfdaq?] Y
+  examine changes to 'SPLIT2'?
+  (enter ? for help) [Ynesfdaq?] Y
   
   diff --git a/SPLIT3 b/SPLIT3
   new file mode 100644
-  examine changes to 'SPLIT3'? [Ynesfdaq?] d
+  examine changes to 'SPLIT3'?
+  (enter ? for help) [Ynesfdaq?] d
   
   continue splitting? [Ycdq?] d
   discarding remaining changes
@@ -801,13 +830,15 @@
   new file mode 100644
   @@ -0,0 +1,1 @@
   +sp2
-  record change 1/2 to 'SPLIT2'? [Ynesfdaq?] y
+  record change 1/2 to 'SPLIT2'?
+  (enter ? for help) [Ynesfdaq?] y
   
   diff --git a/SPLIT3 b/SPLIT3
   new file mode 100644
   @@ -0,0 +1,1 @@
   +sp3
-  record change 2/2 to 'SPLIT3'? [Ynesfdaq?] s
+  record change 2/2 to 'SPLIT3'?
+  (enter ? for help) [Ynesfdaq?] s
   
   continue splitting? [Ycdq?] c
 
@@ -836,20 +867,23 @@
   new file mode 100644
   @@ -0,0 +1,1 @@
   +sp2
-  record change 1/2 to 'SPLIT2'? [Ynesfdaq?] y
+  record change 1/2 to 'SPLIT2'?
+  (enter ? for help) [Ynesfdaq?] y
   
   diff --git a/SPLIT3 b/SPLIT3
   new file mode 100644
   @@ -0,0 +1,1 @@
   +sp3
-  record change 2/2 to 'SPLIT3'? [Ynesfdaq?] s
+  record change 2/2 to 'SPLIT3'?
+  (enter ? for help) [Ynesfdaq?] s
   
   continue splitting? [Ycdq?] y
   diff --git a/SPLIT3 b/SPLIT3
   new file mode 100644
   @@ -0,0 +1,1 @@
   +sp3
-  record this change to 'SPLIT3'? [Ynesfdaq?] y
+  record this change to 'SPLIT3'?
+  (enter ? for help) [Ynesfdaq?] y
   
   no more change to split
 
@@ -877,13 +911,15 @@
   new file mode 100644
   @@ -0,0 +1,1 @@
   +sp2
-  record change 1/2 to 'SPLIT2'? [Ynesfdaq?] y
+  record change 1/2 to 'SPLIT2'?
+  (enter ? for help) [Ynesfdaq?] y
   
   diff --git a/SPLIT3 b/SPLIT3
   new file mode 100644
   @@ -0,0 +1,1 @@
   +sp3
-  record change 2/2 to 'SPLIT3'? [Ynesfdaq?] y
+  record change 2/2 to 'SPLIT3'?
+  (enter ? for help) [Ynesfdaq?] y
   
   no more change to split
   $ hg status --change '.~1'
@@ -910,13 +946,15 @@
   new file mode 100644
   @@ -0,0 +1,1 @@
   +sp2
-  record change 1/2 to 'SPLIT2'? [Ynesfdaq?] y
+  record change 1/2 to 'SPLIT2'?
+  (enter ? for help) [Ynesfdaq?] y
   
   diff --git a/SPLIT3 b/SPLIT3
   new file mode 100644
   @@ -0,0 +1,1 @@
   +sp3
-  record change 2/2 to 'SPLIT3'? [Ynesfdaq?] s
+  record change 2/2 to 'SPLIT3'?
+  (enter ? for help) [Ynesfdaq?] s
   
   continue splitting? [Ycdq?] d
   discarding remaining changes
@@ -1058,26 +1096,31 @@
   adding b
   diff --git a/a b/a
   new file mode 100644
-  examine changes to 'a'? [Ynesfdaq?] y
+  examine changes to 'a'?
+  (enter ? for help) [Ynesfdaq?] y
   
   @@ -0,0 +1,1 @@
   +a
-  record change 1/2 to 'a'? [Ynesfdaq?] y
+  record change 1/2 to 'a'?
+  (enter ? for help) [Ynesfdaq?] y
   
   diff --git a/b b/b
   new file mode 100644
-  examine changes to 'b'? [Ynesfdaq?] n
+  examine changes to 'b'?
+  (enter ? for help) [Ynesfdaq?] n
   
   created new head
   (consider using topic for lightweight branches. See 'hg help topic')
   continue splitting? [Ycdq?] y
   diff --git a/b b/b
   new file mode 100644
-  examine changes to 'b'? [Ynesfdaq?] y
+  examine changes to 'b'?
+  (enter ? for help) [Ynesfdaq?] y
   
   @@ -0,0 +1,1 @@
   +b
-  record this change to 'b'? [Ynesfdaq?] y
+  record this change to 'b'?
+  (enter ? for help) [Ynesfdaq?] y
   
   no more change to split
   1 new orphan changesets
@@ -1200,15 +1243,18 @@
   adding c
   diff --git a/b b/b
   new file mode 100644
-  examine changes to 'b'? [Ynesfdaq?] y
+  examine changes to 'b'?
+  (enter ? for help) [Ynesfdaq?] y
   
   @@ -0,0 +1,1 @@
   +b
-  record change 1/2 to 'b'? [Ynesfdaq?] y
+  record change 1/2 to 'b'?
+  (enter ? for help) [Ynesfdaq?] y
   
   diff --git a/c b/c
   new file mode 100644
-  examine changes to 'c'? [Ynesfdaq?] n
+  examine changes to 'c'?
+  (enter ? for help) [Ynesfdaq?] n
   
   created new head
   (consider using topic for lightweight branches. See 'hg help topic')
--- a/tests/test-stabilize-conflict.t	Wed Jul 17 17:58:44 2019 +0200
+++ b/tests/test-stabilize-conflict.t	Wed Jul 17 18:06:14 2019 +0200
@@ -128,7 +128,8 @@
   atop:[5] babar count up to ten
   merging babar
   warning: conflicts while merging babar! (edit, then use 'hg resolve --mark')
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
   $ hg resolve -l
   U babar
@@ -220,7 +221,8 @@
    output file babar appears unchanged
   was merge successful (yn)? n
   merging babar failed!
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
   $ hg resolve -l
   U babar
--- a/tests/test-topic-stack-complex.t	Wed Jul 17 17:58:44 2019 +0200
+++ b/tests/test-topic-stack-complex.t	Wed Jul 17 18:06:14 2019 +0200
@@ -70,15 +70,18 @@
   adding d
   diff --git a/c b/c
   new file mode 100644
-  examine changes to 'c'? [Ynesfdaq?] y
+  examine changes to 'c'?
+  (enter ? for help) [Ynesfdaq?] y
   
   @@ -0,0 +1,1 @@
   +c
-  record change 1/2 to 'c'? [Ynesfdaq?] y
+  record change 1/2 to 'c'?
+  (enter ? for help) [Ynesfdaq?] y
   
   diff --git a/d b/d
   new file mode 100644
-  examine changes to 'd'? [Ynesfdaq?] n
+  examine changes to 'd'?
+  (enter ? for help) [Ynesfdaq?] n
   
   continue splitting? [Ycdq?] c
   1 new orphan changesets
--- a/tests/test-topic-stack-data.t	Wed Jul 17 17:58:44 2019 +0200
+++ b/tests/test-topic-stack-data.t	Wed Jul 17 18:06:14 2019 +0200
@@ -116,7 +116,7 @@
    add foo_b
   branch: lake
   commit: (clean)
-  update: 2 new changesets (update)
+  update: (current)
   phases: 22 draft
   orphan: 3 changesets
   topic:  foo
--- a/tests/test-topic-stack.t	Wed Jul 17 17:58:44 2019 +0200
+++ b/tests/test-topic-stack.t	Wed Jul 17 18:06:14 2019 +0200
@@ -315,7 +315,7 @@
    c_d
   branch: default
   commit: (clean)
-  update: (current)
+  update: 2 new changesets (update)
   phases: 4 draft
   topic:  foo
 
@@ -940,15 +940,18 @@
   adding ggg
   diff --git a/Z b/Z
   new file mode 100644
-  examine changes to 'Z'? [Ynesfdaq?] y
+  examine changes to 'Z'?
+  (enter ? for help) [Ynesfdaq?] y
   
   @@ -0,0 +1,1 @@
   +zzz
-  record change 1/2 to 'Z'? [Ynesfdaq?] y
+  record change 1/2 to 'Z'?
+  (enter ? for help) [Ynesfdaq?] y
   
   diff --git a/ggg b/ggg
   new file mode 100644
-  examine changes to 'ggg'? [Ynesfdaq?] n
+  examine changes to 'ggg'?
+  (enter ? for help) [Ynesfdaq?] n
   
   continue splitting? [Ycdq?] c
 
--- a/tests/test-topic.t	Wed Jul 17 17:58:44 2019 +0200
+++ b/tests/test-topic.t	Wed Jul 17 18:06:14 2019 +0200
@@ -1066,3 +1066,27 @@
   abort: cannot use --age while setting a topic
   [255]
   $ cd ..
+
+Test that topics doesn't confuse branchheads checking logic
+-----------------------------------------------------------
+
+  $ hg init hgtags
+  $ cd hgtags
+  $ echo a > a
+  $ hg ci -Am "added a" --config experimental.topic-mode=default
+  adding a
+  $ echo b > b
+  $ hg ci -Am "added b" --config experimental.topic-mode=default
+  adding b
+
+  $ hg topic foo -r .
+  switching to topic foo
+  changed topic on 1 changesets to "foo"
+
+Try to put a tag on current rev which also has an active topic:
+  $ hg tag 1.0
+  $ hg tags
+  tip                                3:9efc5c3ac635
+  1.0                                2:3bbb3fdb2546
+
+  $ cd ..
--- a/tests/test-touch.t	Wed Jul 17 17:58:44 2019 +0200
+++ b/tests/test-touch.t	Wed Jul 17 18:06:14 2019 +0200
@@ -4,6 +4,8 @@
   > logtemplate={rev}:{node|short} {desc}\n
   > [defaults]
   > amend=-d "0 0"
+  > [alias]
+  > glog = log -GT "{rev}: {desc}"
   > [extensions]
   > hgext.rebase=
   > EOF
@@ -171,6 +173,34 @@
   [255]
   $ hg touch --duplicate 2
 
+Reviving merge commit
+
+  $ hg up 12
+  1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ hg merge 15
+  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  $ hg ci -m merge
+  $ hg st --change .
+  A a
+  A b
+  $ hg prune -r .
+  0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+  working directory is now at * (glob)
+  1 changesets pruned
+  $ hg touch 16 --hidden
+  $ hg glog -r '12+15+17'
+  o    17: merge
+  |\
+  | o  15: ab
+  |
+  @  12: move
+  |
+  ~
+  $ hg st --change 17
+  A a
+  A b
+
   $ cd ..
 
 Make sure touch doesn't fail to warn about divergence (issue6107)
--- a/tests/test-tutorial.t	Wed Jul 17 17:58:44 2019 +0200
+++ b/tests/test-tutorial.t	Wed Jul 17 18:06:14 2019 +0200
@@ -1528,7 +1528,6 @@
   update:[8] animals
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   working directory is now at 2a2b36e14660
-  no troubled changesets
 
 Relocating unstable change after prune
 ----------------------------------------------
--- a/tests/test-uncommit-interactive.t	Wed Jul 17 17:58:44 2019 +0200
+++ b/tests/test-uncommit-interactive.t	Wed Jul 17 18:06:14 2019 +0200
@@ -41,7 +41,8 @@
   > EOF
   diff --git a/a b/a
   new file mode 100644
-  examine changes to 'a'? [Ynesfdaq?] q
+  examine changes to 'a'?
+  (enter ? for help) [Ynesfdaq?] q
   
   abort: user quit
   [255]
@@ -94,7 +95,8 @@
   > EOF
   diff --git a/a b/a
   3 hunks, 6 lines changed
-  examine changes to 'a'? [Ynesfdaq?] y
+  examine changes to 'a'?
+  (enter ? for help) [Ynesfdaq?] y
   
   @@ -1,3 +1,6 @@
   +-2
@@ -103,7 +105,8 @@
    1
    2
    3
-  discard change 1/3 to 'a'? [Ynesfdaq?] n
+  discard change 1/3 to 'a'?
+  (enter ? for help) [Ynesfdaq?] n
   
   @@ -1,5 +4,7 @@
    1
@@ -113,13 +116,15 @@
   +bar
    4
    5
-  discard change 2/3 to 'a'? [Ynesfdaq?] n
+  discard change 2/3 to 'a'?
+  (enter ? for help) [Ynesfdaq?] n
   
   @@ -4,2 +9,3 @@
    4
    5
   +babar
-  discard change 3/3 to 'a'? [Ynesfdaq?] n
+  discard change 3/3 to 'a'?
+  (enter ? for help) [Ynesfdaq?] n
   
   abort: nothing selected to uncommit
   [255]
@@ -136,7 +141,8 @@
   > EOF
   diff --git a/a b/a
   3 hunks, 6 lines changed
-  examine changes to 'a'? [Ynesfdaq?] y
+  examine changes to 'a'?
+  (enter ? for help) [Ynesfdaq?] y
   
   @@ -1,3 +1,6 @@
   +-2
@@ -145,7 +151,8 @@
    1
    2
    3
-  discard change 1/3 to 'a'? [Ynesfdaq?] y
+  discard change 1/3 to 'a'?
+  (enter ? for help) [Ynesfdaq?] y
   
   @@ -1,5 +4,7 @@
    1
@@ -155,13 +162,15 @@
   +bar
    4
    5
-  discard change 2/3 to 'a'? [Ynesfdaq?] n
+  discard change 2/3 to 'a'?
+  (enter ? for help) [Ynesfdaq?] n
   
   @@ -4,2 +9,3 @@
    4
    5
   +babar
-  discard change 3/3 to 'a'? [Ynesfdaq?] n
+  discard change 3/3 to 'a'?
+  (enter ? for help) [Ynesfdaq?] n
   
 
   $ hg obslog
@@ -235,7 +244,8 @@
   > EOF
   diff --git a/a b/a
   2 hunks, 3 lines changed
-  examine changes to 'a'? [Ynesfdaq?] y
+  examine changes to 'a'?
+  (enter ? for help) [Ynesfdaq?] y
   
   @@ -1,5 +1,7 @@
    1
@@ -245,13 +255,15 @@
   +bar
    4
    5
-  discard change 1/2 to 'a'? [Ynesfdaq?] n
+  discard change 1/2 to 'a'?
+  (enter ? for help) [Ynesfdaq?] n
   
   @@ -4,2 +6,3 @@
    4
    5
   +babar
-  discard change 2/2 to 'a'? [Ynesfdaq?] y
+  discard change 2/2 to 'a'?
+  (enter ? for help) [Ynesfdaq?] y
   
   patching file a
   Hunk #1 succeeded at 2 with fuzz 1 (offset 0 lines).
@@ -330,11 +342,13 @@
   > EOF
   diff --git a/foo b/foo
   new file mode 100644
-  examine changes to 'foo'? [Ynesfdaq?] y
+  examine changes to 'foo'?
+  (enter ? for help) [Ynesfdaq?] y
   
   @@ -0,0 +1,1 @@
   +hey
-  discard this change to 'foo'? [Ynesfdaq?] y
+  discard this change to 'foo'?
+  (enter ? for help) [Ynesfdaq?] y
   
   new changeset is empty
   (use 'hg prune .' to remove it)
@@ -397,7 +411,8 @@
   > EOF
   diff --git a/a b/a
   deleted file mode 100644
-  examine changes to 'a'? [Ynesfdaq?] n
+  examine changes to 'a'?
+  (enter ? for help) [Ynesfdaq?] n
   
   abort: nothing selected to uncommit
   [255]
@@ -414,7 +429,8 @@
   > EOF
   diff --git a/a b/a
   deleted file mode 100644
-  examine changes to 'a'? [Ynesfdaq?] y
+  examine changes to 'a'?
+  (enter ? for help) [Ynesfdaq?] y
   
   new changeset is empty
   (use 'hg prune .' to remove it)
@@ -478,20 +494,24 @@
   > EOF
   diff --git a/foo b/foo
   1 hunks, 1 lines changed
-  examine changes to 'foo'? [Ynesfdaq?] y
+  examine changes to 'foo'?
+  (enter ? for help) [Ynesfdaq?] y
   
   @@ -1,1 +1,2 @@
    hey
   +foo
-  discard change 1/2 to 'foo'? [Ynesfdaq?] y
+  discard change 1/2 to 'foo'?
+  (enter ? for help) [Ynesfdaq?] y
   
   diff --git a/x b/x
   new file mode 100644
-  examine changes to 'x'? [Ynesfdaq?] y
+  examine changes to 'x'?
+  (enter ? for help) [Ynesfdaq?] y
   
   @@ -0,0 +1,1 @@
   +abcd
-  discard change 2/2 to 'x'? [Ynesfdaq?] n
+  discard change 2/2 to 'x'?
+  (enter ? for help) [Ynesfdaq?] n
   
 
   $ hg exp
@@ -578,7 +598,8 @@
   > EOF
   diff --git a/a b/a
   3 hunks, 6 lines changed
-  examine changes to 'a'? [Ynesfdaq?] y
+  examine changes to 'a'?
+  (enter ? for help) [Ynesfdaq?] y
   
   @@ -1,3 +1,6 @@
   +-2
@@ -587,7 +608,8 @@
    1
    2
    3
-  discard change 1/3 to 'a'? [Ynesfdaq?] n
+  discard change 1/3 to 'a'?
+  (enter ? for help) [Ynesfdaq?] n
   
   @@ -1,5 +4,7 @@
    1
@@ -597,13 +619,15 @@
   +bar
    4
    5
-  discard change 2/3 to 'a'? [Ynesfdaq?] n
+  discard change 2/3 to 'a'?
+  (enter ? for help) [Ynesfdaq?] n
   
   @@ -4,2 +9,3 @@
    4
    5
   +babar
-  discard change 3/3 to 'a'? [Ynesfdaq?] y
+  discard change 3/3 to 'a'?
+  (enter ? for help) [Ynesfdaq?] y
   
   patching file a
   Hunk #1 succeeded at 1 with fuzz 1 (offset -1 lines).
@@ -662,7 +686,8 @@
   > EOF
   diff --git a/a b/a
   2 hunks, 5 lines changed
-  examine changes to 'a'? [Ynesfdaq?] y
+  examine changes to 'a'?
+  (enter ? for help) [Ynesfdaq?] y
   
   @@ -1,3 +1,6 @@
   +-2
@@ -671,7 +696,8 @@
    1
    2
    3
-  discard change 1/2 to 'a'? [Ynesfdaq?] y
+  discard change 1/2 to 'a'?
+  (enter ? for help) [Ynesfdaq?] y
   
   @@ -1,5 +4,7 @@
    1
@@ -681,7 +707,8 @@
   +bar
    4
    5
-  discard change 2/2 to 'a'? [Ynesfdaq?] n
+  discard change 2/2 to 'a'?
+  (enter ? for help) [Ynesfdaq?] n
   
 
   $ hg exp
@@ -788,7 +815,8 @@
    5
    babar
   +celeste
-  discard this change to 'a'? [Ynesfdaq?] y
+  discard this change to 'a'?
+  (enter ? for help) [Ynesfdaq?] y
   
   $ hg status
   M a
@@ -852,14 +880,16 @@
    -2
    -1
    0
-  discard change 1/2 to 'a'? [Ynesfdaq?] y
+  discard change 1/2 to 'a'?
+  (enter ? for help) [Ynesfdaq?] y
   
   @@ -9,3 +10,4 @@
    4
    5
    babar
   +celeste
-  discard change 2/2 to 'a'? [Ynesfdaq?] n
+  discard change 2/2 to 'a'?
+  (enter ? for help) [Ynesfdaq?] n
   
   $ hg status
   M a
--- a/tests/test-unstability-resolution-result.t	Wed Jul 17 17:58:44 2019 +0200
+++ b/tests/test-unstability-resolution-result.t	Wed Jul 17 18:06:14 2019 +0200
@@ -90,7 +90,8 @@
   atop:[5] changea
   merging a
   warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
-  fix conflicts and see `hg help evolve.interrupted`
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
   [1]
   $ hg revert -r "orphan()" a
   $ hg diff