changeset 6360:e959390490c2

branching: merge with stable
author Anton Shestakov <av6@dwimlabs.net>
date Fri, 09 Dec 2022 15:01:59 +0400
parents cb9e77506cbc (current diff) 453861da6922 (diff)
children 333ad3793ef3
files CHANGELOG hgext3rd/evolve/__init__.py hgext3rd/topic/__init__.py tests/test-check-sdist.t tests/test-prev-next.t
diffstat 111 files changed, 2350 insertions(+), 1520 deletions(-) [+]
line wrap: on
line diff
--- a/CHANGELOG	Fri Dec 09 14:57:14 2022 +0400
+++ b/CHANGELOG	Fri Dec 09 15:01:59 2022 +0400
@@ -1,6 +1,19 @@
 Changelog
 =========
 
+10.6.0 - in progress
+--------------------
+
+  * prune: pruning (without any successors) an already obsolete revision will
+    no longer give a false warning about divergence
+
+  * deprecate serverminitopic extension, topic extension is recommended for all
+    users, clients and servers
+
+topic (0.25.0)
+
+  * topic: allow Unicode word characters in topic names
+
 10.5.3 -- 2022-12-09
 --------------------
 
--- a/README.rst	Fri Dec 09 14:57:14 2022 +0400
+++ b/README.rst	Fri Dec 09 15:01:59 2022 +0400
@@ -125,6 +125,15 @@
 
 .. _`support for Python 3`: https://www.mercurial-scm.org/wiki/Python3
 
+Python 2 Support
+================
+
+Python 2 is supported by evolve. However, Mercurial 6.2 release dropped support
+for it, so evolve can work on Python 2 only on earlier versions.
+
+Debian packages that are built using Heptapod CI only install files for Python
+3, because they target current Debian stable.
+
 How to Contribute
 =================
 
--- a/hgext3rd/evolve/__init__.py	Fri Dec 09 14:57:14 2022 +0400
+++ b/hgext3rd/evolve/__init__.py	Fri Dec 09 15:01:59 2022 +0400
@@ -45,10 +45,10 @@
     # * abort: abort the push
     auto-publish = ignore
 
-    # For some large repository with few markers, the current  for obsolescence
-    # markers discovery can get in the way. You can disable it with the
-    # configuration option below. This means all pushes and pulls will
-    # re-exchange all markers every time.
+    # For some large repositories with few markers, the current method for
+    # obsolescence marker discovery can get in the way. You can disable it by
+    # setting the following configuration option to "no". Then all pushes and
+    # pulls will re-exchange all markers every time.
     evolution.obsdiscovery = yes
 
 Obsolescence Markers Discovery
@@ -100,8 +100,8 @@
     # ensuring no large repository will get affected.
     obshashrange.max-revs = 100000 # default is None
 
-For very large repositories, it might be useful to disable obsmarkers
-discovery (Make sure you follow release announcement to know when you can turn
+For very large repositories, it might be useful to disable obsmarkers discovery
+(make sure you follow release announcements to know when you might want to turn
 it back on)::
 
     [experimental]
@@ -298,6 +298,7 @@
     node as nodemod,
     obsolete,
     pycompat,
+    registrar,
     util,
 )
 
@@ -458,7 +459,7 @@
     pstatusopts = [o for o in statuscmd[1] if o[1] not in inapplicable]
 
     @eh.command(b'pstatus', pstatusopts,
-                **compat.helpcategorykwargs('CATEGORY_WORKING_DIRECTORY'))
+                helpcategory=registrar.command.CATEGORY_WORKING_DIRECTORY)
     def pstatus(ui, repo, *args, **kwargs):
         """show status combining committed and uncommitted changes
 
@@ -475,7 +476,7 @@
     pdiffopts = [o for o in diffcmd[1] if o[1] not in inapplicable]
 
     @eh.command(b'pdiff', pdiffopts,
-                **compat.helpcategorykwargs('CATEGORY_WORKING_DIRECTORY'))
+                helpcategory=registrar.command.CATEGORY_WORKING_DIRECTORY)
     def pdiff(ui, repo, *args, **kwargs):
         """show diff combining committed and uncommitted changes
 
@@ -766,8 +767,9 @@
      (b'n', b'dry-run', False,
         _(b'do not perform actions, just print what would be done'))],
     b'[OPTION]...',
+    helpcategory=registrar.command.CATEGORY_WORKING_DIRECTORY,
     helpbasic=True,
-    **compat.helpcategorykwargs('CATEGORY_WORKING_DIRECTORY'))
+)
 def cmdprevious(ui, repo, **opts):
     """update to parent revision
 
@@ -781,7 +783,7 @@
         wkctx = repo[None]
         wparents = wkctx.parents()
         if len(wparents) != 1:
-            raise error.Abort(_(b'merge in progress'))
+            raise compat.StateError(_(b'merge in progress'))
         if not mergeopt:
             # we only skip the check if noconflict is set
             if ui.config(b'commands', b'update.check') == b'noconflict':
@@ -827,8 +829,9 @@
       _(b'do not perform actions, just print what would be done')),
      (b'', b'abort', False, _(b'abort the interrupted next'))],
     b'[OPTION]...',
+    helpcategory=registrar.command.CATEGORY_WORKING_DIRECTORY,
     helpbasic=True,
-    **compat.helpcategorykwargs('CATEGORY_WORKING_DIRECTORY'))
+)
 def cmdnext(ui, repo, **opts):
     """update to next child revision
 
@@ -845,11 +848,11 @@
     if abortopt:
         evolvestate = state.cmdstate(repo)
         if not evolvestate:
-            raise error.Abort(_(b'no interrupted next to abort'))
+            raise compat.StateError(_(b'no interrupted next to abort'))
 
         evolvestate.load()
         if evolvestate[b'command'] != b'next':
-            raise error.Abort(_(b'no interrupted next to abort'))
+            raise compat.StateError(_(b'no interrupted next to abort'))
 
         pctx = repo[b'.']
         compat.clean_update(pctx)
@@ -865,7 +868,7 @@
         wkctx = repo[None]
         wparents = wkctx.parents()
         if len(wparents) != 1:
-            raise error.Abort(_(b'merge in progress'))
+            raise compat.StateError(_(b'merge in progress'))
 
         children = [ctx for ctx in wparents[0].children() if not ctx.obsolete()]
         topic = _getcurrenttopic(repo)
@@ -1132,16 +1135,10 @@
         if entry[0] == b"evolution":
             break
     else:
-        if util.safehasattr(help, 'TOPIC_CATEGORY_CONCEPTS'):
-            help.helptable.append(([b"evolution"],
-                                   _(b"Safely Rewriting History"),
-                                   _helploader,
-                                   help.TOPIC_CATEGORY_CONCEPTS))
-        else:
-            # hg <= 4.7 (c303d65d2e34)
-            help.helptable.append(([b"evolution"],
-                                   _(b"Safely Rewriting History"),
-                                   _helploader))
+        help.helptable.append(([b"evolution"],
+                               _(b"Safely Rewriting History"),
+                               _helploader,
+                               help.TOPIC_CATEGORY_CONCEPTS))
         help.helptable.sort()
 
 evolvestateversion = 0
@@ -1169,14 +1166,17 @@
         statemod.addunfinished(b'evolve', fname=b'evolvestate',
                                continueflag=True, stopflag=True,
                                statushint=_msg,
-                               abortfunc=evolvecmd.hgabortevolve)
+                               abortfunc=evolvecmd.hgabortevolve,
+                               continuefunc=evolvecmd.hgcontinueevolve)
         statemod.addunfinished(b'pick', fname=b'pickstate', continueflag=True,
-                               abortfunc=cmdrewrite.hgabortpick)
+                               abortfunc=cmdrewrite.hgabortpick,
+                               continuefunc=cmdrewrite.hgcontinuepick)
         _fixup_msg = _(b'To continue:    hg fixup --continue\n'
                        b'To abort:       hg fixup --abort\n')
         statemod.addunfinished(b'fixup', fname=b'fixup-state',
                                continueflag=True, statushint=_fixup_msg,
-                               abortfunc=cmdrewrite.hgabortfixup)
+                               abortfunc=cmdrewrite.hgabortfixup,
+                               continuefunc=cmdrewrite.hgcontinuefixup)
     else:
         # hg <= 5.0 (5f2f6912c9e6)
         estate = (b'evolvestate', False, False, _(b'evolve in progress'),
@@ -1206,5 +1206,5 @@
 @eh.wrapfunction(hg, 'clean')
 def clean(orig, repo, *args, **kwargs):
     ret = orig(repo, *args, **kwargs)
-    util.unlinkpath(repo.vfs.join(b'evolvestate'), ignoremissing=True)
+    repo.vfs.unlinkpath(b'evolvestate', ignoremissing=True)
     return ret
--- a/hgext3rd/evolve/cmdrewrite.py	Fri Dec 09 14:57:14 2022 +0400
+++ b/hgext3rd/evolve/cmdrewrite.py	Fri Dec 09 15:01:59 2022 +0400
@@ -28,6 +28,7 @@
     patch,
     phases,
     pycompat,
+    registrar,
     scmutil,
     util,
     repair,
@@ -104,8 +105,9 @@
      (b'n', b'note', b'', _(b'store a note on amend'), _(b'TEXT')),
      ] + walkopts + commitopts + commitopts2 + commitopts3 + interactiveopt,
     _(b'[OPTION]... [FILE]...'),
+    helpcategory=registrar.command.CATEGORY_COMMITTING,
     helpbasic=True,
-    **compat.helpcategorykwargs('CATEGORY_COMMITTING'))
+)
 def amend(ui, repo, *pats, **opts):
     """combine a changeset with updates and replace it with a new one
 
@@ -171,8 +173,8 @@
         if opts.get('note'):
             metadata[b'note'] = opts['note']
         replacements = {(old.node(),): [newnode]}
-        compat.cleanupnodes(repo, replacements, operation=b'amend',
-                            metadata=metadata)
+        scmutil.cleanupnodes(repo, replacements, operation=b'amend',
+                             metadata=metadata)
         phases.retractboundary(repo, tr, old.phase(), [newnode])
         compat.clean_update(repo[newnode])
 
@@ -351,7 +353,8 @@
      (b'n', b'note', b'', _(b'store a note on uncommit'), _(b'TEXT')),
      ] + commands.walkopts + commitopts + commitopts2 + commitopts3,
     _(b'[OPTION]... [FILE]...'),
-    **compat.helpcategorykwargs('CATEGORY_CHANGE_MANAGEMENT'))
+    helpcategory=registrar.command.CATEGORY_CHANGE_MANAGEMENT,
+)
 def uncommit(ui, repo, *pats, **opts):
     """move changes from parent revision to working directory
 
@@ -464,8 +467,8 @@
             metadata[b'note'] = opts['note']
 
         replacements = {(old.node(),): [newid]}
-        compat.cleanupnodes(repo, replacements, operation=b"uncommit",
-                            metadata=metadata)
+        scmutil.cleanupnodes(repo, replacements, operation=b"uncommit",
+                             metadata=metadata)
         phases.retractboundary(repo, tr, oldphase, [newid])
         if opts.get('revert'):
             compat.clean_update(repo[newid])
@@ -587,8 +590,9 @@
      (b'n', b'note', b'', _(b'store a note on fold'), _(b'TEXT')),
      ] + commitopts + commitopts2 + commitopts3,
     _(b'hg fold [OPTION]... [-r] REV...'),
+    helpcategory=registrar.command.CATEGORY_CHANGE_MANAGEMENT,
     helpbasic=True,
-    **compat.helpcategorykwargs('CATEGORY_CHANGE_MANAGEMENT'))
+)
 def fold(ui, repo, *revs, **opts):
     """fold multiple revisions into a single one
 
@@ -698,8 +702,8 @@
                                                         commitopts=commitopts)
             phases.retractboundary(repo, tr, targetphase, [newid])
             replacements = {tuple(ctx.node() for ctx in allctx): [newid]}
-            compat.cleanupnodes(repo, replacements, operation=b"fold",
-                                metadata=metadata)
+            scmutil.cleanupnodes(repo, replacements, operation=b"fold",
+                                 metadata=metadata)
             tr.close()
         finally:
             tr.release()
@@ -716,7 +720,8 @@
      (b'n', b'note', b'', _(b'store a note on metaedit'), _(b'TEXT')),
      ] + commitopts + commitopts2 + commitopts3,
     _(b'hg metaedit [OPTION]... [[-r] REV]...'),
-    **compat.helpcategorykwargs('CATEGORY_CHANGE_MANAGEMENT'))
+    helpcategory=registrar.command.CATEGORY_CHANGE_MANAGEMENT,
+)
 def metaedit(ui, repo, *revs, **opts):
     """edit commit information
 
@@ -823,17 +828,9 @@
                     metadata[b'note'] = opts['note']
 
                 phases.retractboundary(repo, tr, targetphase, [newid])
-                # Use this condition as a proxy since the commit we care about
-                # (b99903534e06) didn't change any signatures.
-                if util.safehasattr(scmutil, 'nullrev'):
-                    mapping = {tuple(ctx.node() for ctx in allctx): (newid,)}
-                    scmutil.cleanupnodes(repo, mapping, operation=b"metaedit",
-                                         metadata=metadata)
-                else:
-                    # hg <= 4.7 (b99903534e06)
-                    mapping = {ctx.node(): (newid,) for ctx in allctx}
-                    scmutil.cleanupnodes(repo, mapping, operation=b"metaedit",
-                                         metadata=metadata)
+                replacements = {tuple(ctx.node() for ctx in allctx): (newid,)}
+                scmutil.cleanupnodes(repo, replacements, operation=b"metaedit",
+                                     metadata=metadata)
             else:
                 ui.status(_(b"nothing changed\n"))
             tr.close()
@@ -879,8 +876,9 @@
      (b'B', b'bookmark', [], _(b"remove revs only reachable from given"
                                b" bookmark"), _(b'BOOKMARK'))] + metadataopts,
     _(b'[OPTION]... [-r] REV...'),
+    helpcategory=registrar.command.CATEGORY_CHANGE_MANAGEMENT,
     helpbasic=True,
-    **compat.helpcategorykwargs('CATEGORY_CHANGE_MANAGEMENT'))
+)
 # XXX -U  --noupdate option to prevent wc update and or bookmarks update ?
 def cmdprune(ui, repo, *revs, **opts):
     """mark changesets as obsolete or succeeded by another changeset
@@ -922,10 +920,8 @@
     fold = opts.get('fold')
     split = opts.get('split')
 
-    options = [o for o in (r'pair', r'fold', r'split') if opts.get(o)]
-    if 1 < len(options):
-        _opts = pycompat.sysbytes(r', '.join(options))
-        raise error.Abort(_(b"can only specify one of %s") % _opts)
+    compat.check_at_most_one_arg(opts, 'pair', 'fold', 'split')
+    compat.check_at_most_one_arg(opts, 'biject', 'fold', 'split')
 
     if bookmarks:
         reachablefrombookmark = rewriteutil.reachablefrombookmark
@@ -935,13 +931,13 @@
             rewriteutil.deletebookmark(repo, repomarks, bookmarks)
 
     if not revs:
-        raise error.Abort(_(b'no revisions specified to prune'))
+        raise compat.InputError(_(b'no revisions specified to prune'))
 
     wlock = lock = tr = None
     try:
         wlock = repo.wlock()
         lock = repo.lock()
-        rewriteutil.precheck(repo, revs, b'prune')
+        rewriteutil.precheck(repo, revs, b'prune', check_divergence=bool(succs))
         tr = repo.transaction(b'prune')
         # defines pruned changesets
         precs = []
@@ -957,20 +953,20 @@
         sucs.sort()
         sucs = tuple(repo[n] for n in sucs)
         if not biject and len(sucs) > 1 and len(precs) > 1:
-            msg = b"Can't use multiple successors for multiple precursors"
+            msg = b"cannot use multiple successors for multiple precursors"
             hint = _(b"use --pair to mark a series as a replacement"
                      b" for another")
-            raise error.Abort(msg, hint=hint)
+            raise compat.InputError(msg, hint=hint)
         elif biject and len(sucs) != len(precs):
-            msg = b"Can't use %d successors for %d precursors"\
+            msg = b"cannot use %d successors for %d precursors"\
                 % (len(sucs), len(precs))
-            raise error.Abort(msg)
+            raise compat.InputError(msg)
         elif (len(precs) == 1 and len(sucs) > 1) and not split:
             msg = b"please add --split if you want to do a split"
-            raise error.Abort(msg)
+            raise compat.InputError(msg)
         elif len(sucs) == 1 and len(precs) > 1 and not fold:
             msg = b"please add --fold if you want to do a fold"
-            raise error.Abort(msg)
+            raise compat.InputError(msg)
         elif biject:
             replacements = {(p.node(),): [s.node()] for p, s in zip(precs, sucs)}
         else:
@@ -1059,8 +1055,8 @@
                     break
         if len(sucs) == 1 and len(precs) > 1 and fold:
             replacements = {tuple(p.node() for p in precs): [s.node() for s in sucs]}
-        compat.cleanupnodes(repo, replacements, operation=b"prune", moves=moves,
-                            metadata=metadata)
+        scmutil.cleanupnodes(repo, replacements, operation=b"prune", moves=moves,
+                             metadata=metadata)
 
         # informs that changeset have been pruned
         ui.status(_(b'%i changesets pruned\n') % len(precs))
@@ -1076,8 +1072,9 @@
      (b'n', b'note', b'', _(b"store a note on split"), _(b'TEXT')),
      ] + commitopts + commitopts2 + commitopts3,
     _(b'hg split [OPTION]... [-r REV] [FILE]...'),
+    helpcategory=registrar.command.CATEGORY_CHANGE_MANAGEMENT,
     helpbasic=True,
-    **compat.helpcategorykwargs('CATEGORY_CHANGE_MANAGEMENT'))
+)
 def cmdsplit(ui, repo, *pats, **opts):
     """split a changeset into smaller changesets
 
@@ -1260,7 +1257,8 @@
       b'divergence')],
     # allow to choose the seed ?
     _(b'[OPTION]... [-r] REV...'),
-    **compat.helpcategorykwargs('CATEGORY_CHANGE_MANAGEMENT'))
+    helpcategory=registrar.command.CATEGORY_CHANGE_MANAGEMENT,
+)
 def touch(ui, repo, *revs, **opts):
     """create successors identical to their predecessors but the changeset ID
 
@@ -1341,7 +1339,8 @@
      (b'a', b'abort', False, b'abort interrupted pick'),
      ] + mergetoolopts,
     _(b'[OPTION]... [-r] REV'),
-    **compat.helpcategorykwargs('CATEGORY_CHANGE_MANAGEMENT'))
+    helpcategory=registrar.command.CATEGORY_CHANGE_MANAGEMENT,
+)
 def cmdpick(ui, repo, *revs, **opts):
     """move a commit onto the working directory parent and update to it.
 
@@ -1367,7 +1366,7 @@
                 raise error.Abort(_(b"cannot specify both --continue and "
                                     b"revision"))
             if not pickstate:
-                raise error.Abort(_(b"no interrupted pick state exists"))
+                raise compat.StateError(_(b"no interrupted pick state exists"))
 
             pickstate.load()
             orignode = pickstate[b'orignode']
@@ -1403,33 +1402,46 @@
                 pickstate.save()
                 raise error.InterventionRequired(_(b"unresolved merge conflicts"
                                                    b" (see hg help resolve)"))
-        overrides = {(b'phases', b'new-commit'): origctx.phase()}
-        with repo.ui.configoverride(overrides, b'pick'):
-            newnode = repo.commit(text=origctx.description(),
-                                  user=origctx.user(),
-                                  date=origctx.date(), extra=origctx.extra())
-        repo.dirstate.setbranch(origctx.branch())
+        return _dopick(ui, repo, pickstate, origctx)
+
+def _dopick(ui, repo, pickstate, origctx):
+    """shared logic for performing or continuing a pick"""
+    overrides = {(b'phases', b'new-commit'): origctx.phase()}
+    with repo.ui.configoverride(overrides, b'pick'):
+        newnode = repo.commit(text=origctx.description(),
+                              user=origctx.user(),
+                              date=origctx.date(), extra=origctx.extra())
+    repo.dirstate.setbranch(origctx.branch())
 
-        if pickstate:
-            pickstate.delete()
-        if newnode is None:
-            replacements = {(origctx.node(),): []}
-        else:
-            newctx = repo[newnode]
-            replacements = {(origctx.node(),): [newctx.node()]}
-        compat.cleanupnodes(repo, replacements, operation=b"pick")
+    if pickstate:
+        pickstate.delete()
+    if newnode is None:
+        replacements = {(origctx.node(),): []}
+    else:
+        newctx = repo[newnode]
+        replacements = {(origctx.node(),): [newctx.node()]}
+    scmutil.cleanupnodes(repo, replacements, operation=b"pick")
 
-        if newnode is None:
-            ui.warn(_(b"note: picking %d:%s created no changes to commit\n") %
-                    (origctx.rev(), origctx))
-            return 0
+    if newnode is None:
+        ui.warn(_(b"note: picking %d:%s created no changes to commit\n") %
+                (origctx.rev(), origctx))
+        return 0
+
+    return 0
 
-        return 0
+def hgcontinuepick(ui, repo):
+    """logic to continue pick using 'hg continue'"""
+    with repo.wlock(), repo.lock():
+        pickstate = state.cmdstate(repo, path=b'pickstate')
+        pickstate.load()
+        orignode = pickstate[b'orignode']
+        origctx = repo[orignode]
+        return _dopick(ui, repo, pickstate, origctx)
 
 def abortpick(ui, repo, pickstate, abortcmd=False):
     """logic to abort pick"""
     if not pickstate and not abortcmd:
-        raise error.Abort(_(b"no interrupted pick state exists"))
+        raise compat.StateError(_(b"no interrupted pick state exists"))
     pickstate.load()
     pctxnode = pickstate[b'oldpctx']
     compat.clean_update(repo[pctxnode])
@@ -1453,8 +1465,8 @@
         (b'', b'abort', False, _(b'abort an interrupted fixup')),
     ],
     _(b'[OPTION]... [-r] REV'),
+    helpcategory=registrar.command.CATEGORY_COMMITTING,
     helpbasic=True,
-    **compat.helpcategorykwargs('CATEGORY_COMMITTING')
 )
 def fixup(ui, repo, node=None, **opts):
     """add working directory changes to an arbitrary revision
@@ -1485,28 +1497,28 @@
     abortopt = opts.get('abort')
     if node or opts.get('rev'):
         if contopt:
-            raise error.Abort(_(b'cannot specify a revision with --continue'))
+            raise compat.InputError(_(b'cannot specify a revision with --continue'))
         if abortopt:
-            raise error.Abort(_(b'cannot specify a revision with --abort'))
+            raise compat.InputError(_(b'cannot specify a revision with --abort'))
     # state file for --continue/--abort cases
     fixup_state = state.cmdstate(repo, b'fixup-state')
     if contopt:
         if not fixup_state.exists():
-            raise error.Abort(_(b'no interrupted fixup to continue'))
+            raise compat.StateError(_(b'no interrupted fixup to continue'))
         fixup_state.load()
         return continuefixup(ui, repo, fixup_state)
     if abortopt:
         if not fixup_state.exists():
-            raise error.Abort(_(b'no interrupted fixup to abort'))
+            raise compat.StateError(_(b'no interrupted fixup to abort'))
         fixup_state.load()
         return abortfixup(ui, repo, fixup_state)
 
     if node and opts.get('rev'):
-        raise error.Abort(_(b'please specify just one revision'))
+        raise compat.InputError(_(b'please specify just one revision'))
     if not node:
         node = opts.get('rev')
     if not node:
-        raise error.Abort(_(b'please specify a revision to fixup'))
+        raise compat.InputError(_(b'please specify a revision to fixup'))
     target_ctx = scmutil.revsingle(repo, node)
 
     fixup_state.addopts({
@@ -1546,7 +1558,7 @@
         )
         phases.retractboundary(repo, tr, target_ctx.phase(), [newid])
         replacements = {tuple(ctx.node() for ctx in allctx): [newid]}
-        compat.cleanupnodes(repo, replacements, operation=b'fixup')
+        scmutil.cleanupnodes(repo, replacements, operation=b'fixup')
         fixup_state.delete()
         compat.update(repo.unfiltered()[tempnode])
         return 0
@@ -1574,11 +1586,18 @@
         )
         phases.retractboundary(repo, tr, target_ctx.phase(), [newid])
         replacements = {tuple(ctx.node() for ctx in allctx): [newid]}
-        compat.cleanupnodes(repo, replacements, operation=b'fixup')
+        scmutil.cleanupnodes(repo, replacements, operation=b'fixup')
         fixup_state.delete()
         compat.update(repo.unfiltered()[tempnode])
         return 0
 
+def hgcontinuefixup(ui, repo):
+    """logic for handling `hg continue' for fixup"""
+    with repo.wlock(), repo.lock():
+        fixup_state = state.cmdstate(repo, b'fixup-state')
+        fixup_state.load()
+        return continuefixup(ui, repo, fixup_state)
+
 def abortfixup(ui, repo, fixup_state):
     """logic for handling of `hg fixup --abort`"""
     with repo.wlock(), repo.lock():
--- a/hgext3rd/evolve/compat.py	Fri Dec 09 14:57:14 2022 +0400
+++ b/hgext3rd/evolve/compat.py	Fri Dec 09 15:01:59 2022 +0400
@@ -21,7 +21,6 @@
     node,
     obsolete,
     pycompat,
-    registrar,
     scmutil,
     util,
 )
@@ -54,14 +53,6 @@
     r'PHASEDIVERGENT': b'phase-divergent',
 }
 
-# XXX: Better detection of property cache
-if r'predecessors' not in dir(obsolete.obsstore):
-    @property
-    def predecessors(self):
-        return self.precursors
-
-    obsolete.obsstore.predecessors = predecessors
-
 def memfilectx(repo, ctx, fctx, flags, copied, path):
     # XXX Would it be better at the module level?
     varnames = context.memfilectx.__init__.__code__.co_varnames  # pytype: disable=attribute-error
@@ -337,15 +328,6 @@
 if not fixupstreamed:
     copiesmod._fullcopytracing = fixedcopytracing
 
-# help category compatibility
-# hg <= 4.7 (c303d65d2e34)
-def helpcategorykwargs(categoryname):
-    """Backwards-compatible specification of the helpategory argument."""
-    category = getattr(registrar.command, categoryname, None)
-    if not category:
-        return {}
-    return {'helpcategory': category}
-
 # nodemap.get and index.[has_node|rev|get_rev]
 # hg <= 5.2 (02802fa87b74)
 def getgetrev(cl):
@@ -387,21 +369,6 @@
     def clean_update(ctx):
         hg.updaterepo(ctx.repo(), ctx.node(), overwrite=True)
 
-def cleanupnodes(repo, replacements, operation, moves=None, metadata=None):
-    # Use this condition as a proxy since the commit we care about
-    # (b99903534e06) didn't change any signatures.
-    if util.safehasattr(scmutil, 'nullrev'):
-        fixedreplacements = replacements
-    else:
-        # hg <= 4.7 (b99903534e06)
-        fixedreplacements = {}
-        for oldnodes, newnodes in replacements.items():
-            for oldnode in oldnodes:
-                fixedreplacements[oldnode] = newnodes
-
-    scmutil.cleanupnodes(repo, replacements=fixedreplacements, operation=operation,
-                         moves=moves, metadata=metadata)
-
 if util.safehasattr(cmdutil, 'format_changeset_summary'):
     def format_changeset_summary_fn(ui, repo, command, default_spec):
         def show(ctx):
@@ -424,17 +391,12 @@
         def to_display(name):
             return pycompat.sysbytes(name).replace(b'_', b'-')
 
-        if util.safehasattr(error, 'InputError'):
-            err = error.InputError
-        else:
-            # hg <= 5.6 (8d72e29ad1e0)
-            err = error.Abort
         previous = None
         for x in args:
             if opts.get(x):
                 if previous:
-                    raise err(_(b'cannot specify both --%s and --%s')
-                              % (to_display(previous), to_display(x)))
+                    raise InputError(_(b'cannot specify both --%s and --%s')
+                                     % (to_display(previous), to_display(x)))
                 previous = x
         return previous
 
@@ -570,3 +532,15 @@
     # hg <= 5.9 (dcd97b082b3b)
     def dirchanges(dirstate):
         return [f for f in dirstate if dirstate[f] != b'n']
+
+if util.safehasattr(error, 'InputError'):
+    InputError = error.InputError
+else:
+    # hg <= 5.6 (8d72e29ad1e0)
+    InputError = error.Abort
+
+if util.safehasattr(error, 'StateError'):
+    StateError = error.StateError
+else:
+    # hg <= 5.6 (527ce85c2e60)
+    StateError = error.Abort
--- a/hgext3rd/evolve/evolvecmd.py	Fri Dec 09 14:57:14 2022 +0400
+++ b/hgext3rd/evolve/evolvecmd.py	Fri Dec 09 15:01:59 2022 +0400
@@ -26,6 +26,7 @@
     obsutil,
     phases,
     pycompat,
+    registrar,
     repair,
     scmutil,
     simplemerge,
@@ -757,11 +758,7 @@
         if saveeffectflag:
             # The effect flag is saved in a versioned field name for
             # future evolution
-            try:
-                effectflag = obsutil.geteffectflag(prec, (succ,))
-            except TypeError:
-                # hg <= 4.7 (bae6f1418a95)
-                effectflag = obsutil.geteffectflag((prec, (succ,)))
+            effectflag = obsutil.geteffectflag(prec, (succ,))
             metadata[obsutil.EFFECTFLAGFIELD] = b"%d" % effectflag
 
         # create markers
@@ -962,10 +959,18 @@
     _finalizerelocate(repo, orig, dest, nodenew, tr, category, evolvestate)
     return nodenew
 
+# This is copied from hgext.rebase._savegraft()
+def _savegraft(ctx, extra):
+    s = ctx.extra().get(b'source', None)
+    if s is not None:
+        extra[b'source'] = s
+    s = ctx.extra().get(b'intermediate-source', None)
+    if s is not None:
+        extra[b'intermediate-source'] = s
+
 def _relocatecommit(repo, orig, dest, pctx, keepbranch, commitmsg, update):
-    extra = dict(orig.extra())
-    if b'branch' in extra:
-        del extra[b'branch']
+    extra = {}
+    _savegraft(orig, extra)
     extra[b'rebase_source'] = orig.hex()
     targetphase = max(orig.phase(), phases.draft)
     configoverrides = {
@@ -1001,8 +1006,7 @@
         if not orig.topic() and repo.vfs.exists(b'topic'):
             repo.vfs.unlink(b'topic')
         else:
-            with repo.vfs.open(b'topic', b'w') as f:
-                f.write(orig.topic())
+            repo.vfs.write(b'topic', orig.topic())
 
     stats = merge.graft(repo, orig, pctx, [b'destination', b'evolving'], True)
 
@@ -1539,8 +1543,8 @@
                               b' in the repo')),
      ] + mergetoolopts,
     _(b'[OPTIONS]...'),
+    helpcategory=registrar.command.CATEGORY_CHANGE_MANAGEMENT,
     helpbasic=True,
-    **compat.helpcategorykwargs('CATEGORY_CHANGE_MANAGEMENT')
 )
 def evolve(ui, repo, **opts):
     """solve troubled changesets in your repository
@@ -1678,7 +1682,7 @@
     # Continuation handling
     if contopt:
         if not evolvestate:
-            raise error.Abort(_(b'no interrupted evolve to continue'))
+            raise compat.StateError(_(b'no interrupted evolve to continue'))
         evolvestate.load()
         headnode = continueevolve(ui, repo, evolvestate)
         if evolvestate[b'command'] != b'evolve':
@@ -1690,7 +1694,7 @@
         evolvestate.delete()
     elif stopopt:
         if not evolvestate:
-            raise error.Abort(_(b'no interrupted evolve to stop'))
+            raise compat.StateError(_(b'no interrupted evolve to stop'))
         evolvestate.load()
         stopevolve(ui, repo, evolvestate)
         if evolvestate[b'command'] != b'evolve':
@@ -1700,7 +1704,7 @@
         evolvestate.delete()
     elif abortopt:
         if not evolvestate:
-            raise error.Abort(_(b'no interrupted evolve to abort'))
+            raise compat.StateError(_(b'no interrupted evolve to abort'))
         evolvestate.load()
         # `hg next --evolve` in play
         if evolvestate[b'command'] != b'evolve':
@@ -2048,6 +2052,23 @@
     progress.complete()
     return headnode
 
+def hgcontinueevolve(ui, repo):
+    """logic for continuing evolve using 'hg continue'"""
+    with repo.wlock(), repo.lock():
+        evolvestate = state.cmdstate(repo)
+        evolvestate.load()
+        headnode = continueevolve(ui, repo, evolvestate)
+        if evolvestate[b'command'] != b'evolve':
+            evolvestate.delete()
+            return
+        startnode = evolvestate[b'startnode']
+        shouldupdate = False
+        if b'update' in evolvestate:
+            shouldupdate = evolvestate[b'update']
+        evolvestate.delete()
+
+        _cleanup(ui, repo, startnode, shouldupdate, headnode)
+
 def _continuecontentdivergent(ui, repo, evolvestate, progresscb):
     """function to continue the interrupted content-divergence resolution."""
     tr = repo.transaction(b'evolve')
@@ -2178,13 +2199,11 @@
 
     orig = repo[evolvestate[b'current']]
     ctx = orig
-    source = ctx.extra().get(b'source')
+
     extra = {}
-    if source:
-        extra[b'source'] = source
-        extra[b'intermediate-source'] = ctx.hex()
-    else:
-        extra[b'source'] = ctx.hex()
+    _savegraft(ctx, extra)
+    extra[b'rebase_source'] = orig.hex()
+
     user = ctx.user()
     date = ctx.date()
     message = ctx.description()
--- a/hgext3rd/evolve/exthelper.py	Fri Dec 09 14:57:14 2022 +0400
+++ b/hgext3rd/evolve/exthelper.py	Fri Dec 09 15:01:59 2022 +0400
@@ -50,7 +50,7 @@
         @eh.command('mynewcommand',
             [('r', 'rev', [], _('operate on these revisions'))],
             _('-r REV...'),
-            **compat.helpcategorykwargs('CATEGORY_XXX'))
+            helpcategory=registrar.command.CATEGORY_XXX)
         def newcommand(ui, repo, *revs, **opts):
             # implementation goes here
 
@@ -83,14 +83,6 @@
         self._duckpunchers = []
         self.cmdtable = {}
         self.command = registrar.command(self.cmdtable)
-        if b'^init' in commands.table:
-            olddoregister = self.command._doregister
-
-            def _newdoregister(self, name, *args, **kwargs):
-                if kwargs.pop('helpbasic', False):
-                    name = r'^' + name
-                return olddoregister(self, name, *args, **kwargs)
-            self.command._doregister = _newdoregister
 
         self.configtable = {}
         self.configitem = registrar.configitem(self.configtable)
@@ -103,6 +95,8 @@
         self._uipopulatecallables.extend(other._uipopulatecallables)
         self._extcallables.extend(other._extcallables)
         self._repocallables.extend(other._repocallables)
+        # use registrar._merge() here, see upstream exthelper.py
+        # hg <= 4.8 (13f50ea8ac3b)
         self.filesetpredicate._table.update(other.filesetpredicate._table)
         self.revsetpredicate._table.update(other.revsetpredicate._table)
         self.templatekeyword._table.update(other.templatekeyword._table)
@@ -161,7 +155,7 @@
             c(ui)
 
     def finalextsetup(self, ui):
-        """Method to be used as a the extension extsetup
+        """Method to be used as the extension extsetup
 
         The following operations belong here:
 
@@ -207,7 +201,7 @@
 
             @eh.uisetup
             def setupbabar(ui):
-                print 'this is uisetup!'
+                print('this is uisetup!')
         """
         self._uicallables.append(call)
         return call
@@ -219,7 +213,7 @@
 
             @eh.uipopulate
             def setupfoo(ui):
-                print 'this is uipopulate!'
+                print('this is uipopulate!')
         """
         self._uipopulatecallables.append(call)
         return call
@@ -231,7 +225,7 @@
 
             @eh.extsetup
             def setupcelestine(ui):
-                print 'this is extsetup!'
+                print('this is extsetup!')
         """
         self._extcallables.append(call)
         return call
@@ -243,7 +237,7 @@
 
             @eh.reposetup
             def setupzephir(ui, repo):
-                print 'this is reposetup!'
+                print('this is reposetup!')
         """
         self._repocallables.append(call)
         return call
@@ -300,8 +294,8 @@
 
         example::
 
-            @eh.function(discovery, 'checkheads')
-            def wrapfunction(orig, *args, **kwargs):
+            @eh.wrapfunction(discovery, 'checkheads')
+            def wrapcheckheads(orig, *args, **kwargs):
                 ui.note('His head smashed in and his heart cut out')
                 return orig(*args, **kwargs)
         """
--- a/hgext3rd/evolve/headchecking.py	Fri Dec 09 14:57:14 2022 +0400
+++ b/hgext3rd/evolve/headchecking.py	Fri Dec 09 15:01:59 2022 +0400
@@ -127,9 +127,7 @@
     # make it easy for extension with the branch logic there
     branch = ctx.branch()
     if util.safehasattr(ctx, 'topic'):
-        topic = ctx.topic()
-        if topic:
-            branch = "%s:%s" % (branch, topic)
+        branch = ctx.fqbn()
     return branch
 
 def _filter_obsolete_heads(repo, heads):
--- a/hgext3rd/evolve/metadata.py	Fri Dec 09 14:57:14 2022 +0400
+++ b/hgext3rd/evolve/metadata.py	Fri Dec 09 15:01:59 2022 +0400
@@ -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__ = b'10.5.4.dev'
-testedwith = b'4.8 4.9 5.0 5.1 5.2 5.3 5.4 5.5 5.6 5.7 5.8 5.9 6.0 6.1 6.2 6.3'
+__version__ = b'10.6.0.dev'
+testedwith = b'4.8 4.9 5.0 5.1 5.2 5.3 5.4 5.5 5.6 5.7 5.8 5.9 6.0 6.1 6.2'
 minimumhgversion = b'4.8'
 buglink = b'https://bz.mercurial-scm.org/'
--- a/hgext3rd/evolve/obshistory.py	Fri Dec 09 14:57:14 2022 +0400
+++ b/hgext3rd/evolve/obshistory.py	Fri Dec 09 15:01:59 2022 +0400
@@ -19,6 +19,7 @@
     obsutil,
     patch,
     pycompat,
+    registrar,
     scmutil,
     util,
 )
@@ -28,7 +29,6 @@
 from mercurial.i18n import _
 
 from . import (
-    compat,
     exthelper,
 )
 
@@ -62,7 +62,7 @@
      (b'o', b'origin', True, _(b'show origin of changesets instead of fate')),
      ] + commands.formatteropts,
     _(b'hg obslog [OPTION]... [[-r] REV]...'),
-    **compat.helpcategorykwargs('CATEGORY_CHANGE_NAVIGATION'))
+    helpcategory=registrar.command.CATEGORY_CHANGE_NAVIGATION)
 def cmdobshistory(ui, repo, *revs, **opts):
     """show the obsolescence history of the specified revisions
 
@@ -380,18 +380,19 @@
         # If we don't have it locally, it's obsolete
         return True
 
-def cyclic(graph):
-    """Return True if the directed graph has a cycle.
-    The graph must be represented as a dictionary mapping vertices to
-    iterables of neighbouring vertices. For example:
+def findcycle(graph):
+    """Return a set of vertices that form a cycle in the directed graph.
 
-    >>> cyclic({1: (2,), 2: (3,), 3: (1,)})
-    True
-    >>> cyclic({1: (2,), 2: (3,), 3: (4,)})
-    False
+    The first detected cycle is returned. If there's no cycle, this function
+    return None. The graph must be represented as a dictionary mapping vertices
+    to iterables of neighbouring vertices. For example:
+
+    >>> sorted(findcycle({1: (2,), 2: (3,), 3: (1,)}))
+    [1, 2, 3]
+    >>> print(findcycle({1: (2,), 2: (3,), 3: (4,)}))
+    None
 
     Taken from: https://codereview.stackexchange.com/a/86067
-
     """
     visited = set()
     o = object()
@@ -412,7 +413,7 @@
         else:
             path_set.remove(path.pop())
             stack.pop()
-    return False
+    return None
 
 def _obshistorywalker(repo, revs, walksuccessors=False, filternonlocal=False):
     """ Directly inspired by graphmod.dagwalker,
@@ -441,7 +442,7 @@
 
         # If we likely have a cycle
         if not validcandidates:
-            cycle = cyclic(nodesucc)
+            cycle = findcycle(nodesucc)
             assert cycle
 
             # Then choose a random node from the cycle
--- a/hgext3rd/evolve/rewind.py	Fri Dec 09 14:57:14 2022 +0400
+++ b/hgext3rd/evolve/rewind.py	Fri Dec 09 15:01:59 2022 +0400
@@ -9,6 +9,7 @@
     node as nodemod,
     obsolete,
     obsutil,
+    registrar,
     scmutil,
     util,
 )
@@ -42,8 +43,9 @@
       _(b'do not perform actions, just print what would be done')),
      ],
     _(b'[--as-divergence] [--exact] [--keep] [--to REV]... [--from REV]...'),
+    helpcategory=registrar.command.CATEGORY_CHANGE_MANAGEMENT,
     helpbasic=True,
-    **compat.helpcategorykwargs('CATEGORY_CHANGE_MANAGEMENT'))
+)
 def rewind(ui, repo, **opts):
     """rewind a stack of changesets to a previous state
 
@@ -133,17 +135,13 @@
                 relationships.append(rel)
                 if wctxp.node() == source:
                     update_target = newdest[-1]
-            # Use this condition as a proxy since the commit we care about
-            # (b99903534e06) didn't change any signatures.
-            if util.safehasattr(scmutil, 'nullrev'):
-                # hg <= 4.7 (b99903534e06)
-                destmap = util.sortdict()
-                for src, dest in relationships:
-                    destmap.setdefault(dest, []).append(src)
-                relationships = [
-                    (tuple(src), dest)
-                    for dest, src in destmap.items()
-                ]
+            destmap = util.sortdict()
+            for src, dest in relationships:
+                destmap.setdefault(dest, []).append(src)
+            relationships = [
+                (tuple(src), dest)
+                for dest, src in destmap.items()
+            ]
             obsolete.createmarkers(unfi, relationships, operation=b'rewind')
             if update_target is not None:
                 if opts.get('keep'):
--- a/hgext3rd/evolve/rewriteutil.py	Fri Dec 09 14:57:14 2022 +0400
+++ b/hgext3rd/evolve/rewriteutil.py	Fri Dec 09 15:01:59 2022 +0400
@@ -54,37 +54,43 @@
         summary %= (node.short(tonode(first)), numrevs - 1)
     return summary
 
-def precheck(repo, revs, action=b'rewrite'):
+def precheck(repo, revs, action=b'rewrite', check_divergence=True):
     """check if <revs> can be rewritten
 
     <action> can be used to control the commit message.
     """
-    # If this attribute exists, then core's rewriteutil is recent enough
-    # that it has all the features from our own implementation.
-    if util.safehasattr(corerewriteutil, 'find_new_divergence_from'):
-        return corerewriteutil.precheck(repo, revs, action)
+    # hg <= 6.1 (d4752aeb20f1)
+    code = corerewriteutil.precheck.__code__
+    if r'check_divergence' in code.co_varnames[:code.co_argcount]:
+        return corerewriteutil.precheck(repo, revs, action,
+                                        check_divergence=check_divergence)
 
     # hg <= 5.8 (d90f6237)
     if node.nullrev in revs:
         msg = _(b"cannot %s the null revision") % (action)
         hint = _(b"no changeset checked out")
-        raise error.Abort(msg, hint=hint)
+        raise compat.InputError(msg, hint=hint)
     if any(util.safehasattr(r, 'rev') for r in revs):
         msg = b"rewriteutil.precheck called with ctx not revs"
         repo.ui.develwarn(msg)
         revs = (r.rev() for r in revs)
+    if len(repo[None].parents()) > 1:
+        raise compat.StateError(_(b"cannot %s changesets while merging")
+                                % action)
     publicrevs = repo.revs(b'%ld and public()', revs)
     if publicrevs:
         summary = _formatrevs(repo, publicrevs)
         msg = _(b"cannot %s public changesets: %s") % (action, summary)
         hint = _(b"see 'hg help phases' for details")
-        raise error.Abort(msg, hint=hint)
+        raise compat.InputError(msg, hint=hint)
     newunstable = disallowednewunstable(repo, revs)
     if newunstable:
-        msg = _(b"%s will orphan %i descendants")
+        msg = _(b"cannot %s changeset, as that will orphan %i descendants")
         msg %= (action, len(newunstable))
         hint = _(b"see 'hg help evolution.instability'")
-        raise error.Abort(msg, hint=hint)
+        raise compat.InputError(msg, hint=hint)
+    if not check_divergence:
+        return
     allowdivergence = compat.isenabled(repo, compat.allowdivergenceopt)
     if allowdivergence:
         return
@@ -93,7 +99,7 @@
         local, other, common_prec = divergence
         localdiv = repo[local]
         otherdiv, base = repo[other], repo[common_prec]
-        msg = _(b"%s of %s creates content-divergence "
+        msg = _(b"cannot %s %s, as that creates content-divergence "
                 b"with %s") % (action, localdiv, otherdiv)
         if localdiv.rev() != base.rev():
             msg += _(b', from %s') % base
@@ -101,17 +107,17 @@
                  b"'hg help evolution.instability'")
         if repo.ui.verbose:
             if localdiv.rev() != base.rev():
-                msg += _(b'\n    changeset %s is an evolution of '
+                msg += _(b'\n    changeset %s is a successor of '
                          b'changeset %s') % (localdiv, base)
-            msg += _(b'\n    changeset %s already have a successors as '
+            msg += _(b'\n    changeset %s already has a successor in '
                      b'changeset %s\n'
                      b'    rewriting changeset %s would create '
                      b'"content-divergence"\n'
                      b'    set experimental.evolution.allowdivergence=True to '
-                     b'overwrite this check') % (base, otherdiv, localdiv)
+                     b'skip this check') % (base, otherdiv, localdiv)
             hint = _(b"see 'hg help evolution.instability' for details "
                      b"on content-divergence")
-        raise error.Abort(msg, hint=hint)
+        raise compat.InputError(msg, hint=hint)
 
 def bookmarksupdater(repo, oldid, tr):
     """Return a callable update(newid) updating the current bookmark
--- a/hgext3rd/evolve/state.py	Fri Dec 09 14:57:14 2022 +0400
+++ b/hgext3rd/evolve/state.py	Fri Dec 09 15:01:59 2022 +0400
@@ -30,7 +30,6 @@
 
 from mercurial import (
     error,
-    util,
 )
 
 from mercurial.i18n import _
@@ -100,7 +99,7 @@
 
     def delete(self):
         """drop the evolvestate file if exists"""
-        util.unlinkpath(self._repo.vfs.join(self.path), ignoremissing=True)
+        self._repo.vfs.unlinkpath(self.path, ignoremissing=True)
 
     def exists(self):
         """check whether the evolvestate file exists or not"""
--- a/hgext3rd/pullbundle.py	Fri Dec 09 14:57:14 2022 +0400
+++ b/hgext3rd/pullbundle.py	Fri Dec 09 15:01:59 2022 +0400
@@ -92,7 +92,7 @@
 
 from mercurial.i18n import _
 
-__version__ = b'0.1.4.dev'
+__version__ = b'0.2.0.dev'
 testedwith = b'4.8 4.9 5.0 5.1 5.2 5.3 5.4 5.5 5.6 5.7 5.8 5.9 6.0 6.1'
 minimumhgversion = b'4.8'
 buglink = b'https://bz.mercurial-scm.org/'
--- a/hgext3rd/serverminitopic.py	Fri Dec 09 14:57:14 2022 +0400
+++ b/hgext3rd/serverminitopic.py	Fri Dec 09 15:01:59 2022 +0400
@@ -1,4 +1,4 @@
-"""enable a minimal verison of topic for server
+"""enable a minimal verison of topic for server (DEPRECATED)
 
 ! This extensions is not actively maintained
 ! We recommand using the main topic extension instead
--- a/hgext3rd/topic/__init__.py	Fri Dec 09 14:57:14 2022 +0400
+++ b/hgext3rd/topic/__init__.py	Fri Dec 09 15:01:59 2022 +0400
@@ -168,7 +168,9 @@
     changelog,
     cmdutil,
     commands,
+    configitems,
     context,
+    encoding,
     error,
     exchange,
     extensions,
@@ -231,64 +233,86 @@
               b'log.topic': b'green_background',
               }
 
-__version__ = b'0.24.3.dev'
+__version__ = b'0.25.0.dev'
 
-testedwith = b'4.8 4.9 5.0 5.1 5.2 5.3 5.4 5.5 5.6 5.7 5.8 5.9 6.0 6.1 6.2 6.3'
+testedwith = b'4.8 4.9 5.0 5.1 5.2 5.3 5.4 5.5 5.6 5.7 5.8 5.9 6.0 6.1 6.2'
 minimumhgversion = b'4.8'
 buglink = b'https://bz.mercurial-scm.org/'
 
-if util.safehasattr(registrar, 'configitem'):
-
-    from mercurial import configitems
-
-    configtable = {}
-    configitem = registrar.configitem(configtable)
+configtable = {}
+configitem = registrar.configitem(configtable)
 
-    configitem(b'experimental', b'enforce-topic',
-               default=False,
-    )
-    configitem(b'experimental', b'enforce-single-head',
-               default=False,
-    )
-    configitem(b'experimental', b'topic-mode',
-               default=None,
-    )
-    configitem(b'experimental', b'topic.publish-bare-branch',
-               default=False,
-    )
-    configitem(b'experimental', b'topic.allow-publish',
-               default=configitems.dynamicdefault,
-    )
-    configitem(b'_internal', b'keep-topic',
-               default=False,
-    )
-    configitem(b'experimental', b'topic-mode.server',
-               default=configitems.dynamicdefault,
-    )
-    configitem(b'experimental', b'topic.server-gate-topic-changesets',
-               default=False,
-    )
-    configitem(b'experimental', b'topic.linear-merge',
-               default="reject",
-    )
+configitem(b'experimental', b'enforce-topic',
+           default=False,
+)
+configitem(b'experimental', b'enforce-single-head',
+           default=False,
+)
+configitem(b'experimental', b'topic-mode',
+           default=None,
+)
+configitem(b'experimental', b'topic.publish-bare-branch',
+           default=False,
+)
+configitem(b'experimental', b'topic.allow-publish',
+           default=configitems.dynamicdefault,
+)
+configitem(b'_internal', b'keep-topic',
+           default=False,
+)
+# used for signaling that ctx.branch() shouldn't return fqbn even if topic is
+# enabled for local repo
+configitem(b'_internal', b'tns-disable-fqbn',
+           default=False,
+)
+# used for signaling that push will publish changesets
+configitem(b'_internal', b'tns-publish',
+           default=False,
+)
+configitem(b'experimental', b'topic-mode.server',
+           default=configitems.dynamicdefault,
+)
+configitem(b'experimental', b'topic.server-gate-topic-changesets',
+           default=False,
+)
+configitem(b'experimental', b'topic.linear-merge',
+           default="reject",
+)
 
-    def extsetup(ui):
-        # register config that strictly belong to other code (thg, core, etc)
-        #
-        # To ensure all config items we used are registered, we register them if
-        # nobody else did so far.
-        from mercurial import configitems
-        extraitem = functools.partial(configitems._register, ui._knownconfig)
-        if (b'experimental' not in ui._knownconfig
-                or not ui._knownconfig[b'experimental'].get(b'thg.displaynames')):
-            extraitem(b'experimental', b'thg.displaynames',
-                      default=None,
-            )
-        if (b'devel' not in ui._knownconfig
-                or not ui._knownconfig[b'devel'].get(b'random')):
-            extraitem(b'devel', b'randomseed',
-                      default=None,
-            )
+def extsetup(ui):
+    # register config that strictly belong to other code (thg, core, etc)
+    #
+    # To ensure all config items we used are registered, we register them if
+    # nobody else did so far.
+    extraitem = functools.partial(configitems._register, ui._knownconfig)
+    if (b'experimental' not in ui._knownconfig
+            or not ui._knownconfig[b'experimental'].get(b'thg.displaynames')):
+        extraitem(b'experimental', b'thg.displaynames',
+                  default=None,
+        )
+    if (b'devel' not in ui._knownconfig
+            or not ui._knownconfig[b'devel'].get(b'random')):
+        extraitem(b'devel', b'randomseed',
+                  default=None,
+        )
+
+def _contexttns(self, force=False):
+    if not force and not self.mutable():
+        return b'default'
+    cache = getattr(self._repo, '_tnscache', None)
+    # topic loaded, but not enabled (eg: multiple repo in the same process)
+    if cache is None:
+        return b'default'
+    if self.rev() is None:
+        # don't cache volatile ctx instances that aren't stored on-disk yet
+        return self.extra().get(b'topic-namespace', b'default')
+    tns = cache.get(self.rev())
+    if tns is None:
+        tns = self.extra().get(b'topic-namespace', b'default')
+        self._repo._tnscache[self.rev()] = tns
+    return tns
+
+context.basectx.topic_namespace = _contexttns
 
 def _contexttopic(self, force=False):
     if not (force or self.mutable()):
@@ -322,6 +346,15 @@
         return None
 context.basectx.topicidx = _contexttopicidx
 
+def _contextfqbn(self):
+    """return branch//namespace/topic of the changeset, also known as fully
+    qualified branch name
+    """
+    branch = encoding.tolocal(self.extra()[b'branch'])
+    return common.formatfqbn(branch, self.topic_namespace(), self.topic())
+
+context.basectx.fqbn = _contextfqbn
+
 stackrev = re.compile(br'^s\d+$')
 topicrev = re.compile(br'^t\d+$')
 
@@ -475,6 +508,7 @@
         def _restrictcapabilities(self, caps):
             caps = super(topicrepo, self)._restrictcapabilities(caps)
             caps.add(b'topics')
+            caps.add(b'topics-namespaces')
             if self.ui.configbool(b'phases', b'publish'):
                 mode = b'all'
             elif self.ui.configbool(b'experimental',
@@ -503,6 +537,24 @@
             return super(topicrepo, self).commitctx(ctx, *args, **kwargs)
 
         @util.propertycache
+        def _tnscache(self):
+            return {}
+
+        @property
+        def topic_namespaces(self):
+            if self._topic_namespaces is not None:
+                return self._topic_namespaces
+            namespaces = set([self.currenttns])
+            for c in self.set(b'not public()'):
+                namespaces.add(c.topic_namespace())
+            self._topic_namespaces = namespaces
+            return namespaces
+
+        @property
+        def currenttns(self):
+            return self.vfs.tryread(b'topic-namespace') or b'default'
+
+        @util.propertycache
         def _topiccache(self):
             return {}
 
@@ -524,7 +576,26 @@
         # overwritten at the instance level by topicmap.py
         _autobranchmaptopic = True
 
-        def branchmap(self, topic=None):
+        def branchmap(self, topic=None, convertbm=False):
+            if topic is None:
+                topic = getattr(self, '_autobranchmaptopic', False)
+            topicfilter = topicmap.topicfilter(self.filtername)
+            if not topic or topicfilter == self.filtername:
+                return super(topicrepo, self).branchmap()
+            bm = self.filtered(topicfilter).branchmap()
+            if convertbm:
+                entries = compat.bcentries(bm)
+                for key in list(entries):
+                    branch, tns, topic = common.parsefqbn(key)
+                    if topic:
+                        value = entries.pop(key)
+                        # we lose namespace when converting to ":" format
+                        key = b'%s:%s' % (branch, topic)
+                        entries[key] = value
+            return bm
+
+        def branchmaptns(self, topic=None):
+            """branchmap using fqbn as keys"""
             if topic is None:
                 topic = getattr(self, '_autobranchmaptopic', False)
             topicfilter = topicmap.topicfilter(self.filtername)
@@ -535,8 +606,7 @@
         def branchheads(self, branch=None, start=None, closed=False):
             if branch is None:
                 branch = self[None].branch()
-                if self.currenttopic:
-                    branch = b"%s:%s" % (branch, self.currenttopic)
+                branch = common.formatfqbn(branch, self.currenttns, self.currenttopic)
             return super(topicrepo, self).branchheads(branch=branch,
                                                       start=start,
                                                       closed=closed)
@@ -548,6 +618,7 @@
         def invalidatevolatilesets(self):
             # XXX we might be able to move this to something invalidated less often
             super(topicrepo, self).invalidatevolatilesets()
+            self._topic_namespaces = None
             self._topics = None
 
         def peer(self, *args, **kwargs):
@@ -556,7 +627,11 @@
                 class topicpeer(peer.__class__):
                     def branchmap(self):
                         usetopic = not self._repo.publishing()
-                        return self._repo.branchmap(topic=usetopic)
+                        return self._repo.branchmap(topic=usetopic, convertbm=usetopic)
+
+                    def branchmaptns(self):
+                        usetopic = not self._repo.publishing()
+                        return self._repo.branchmaptns(topic=usetopic)
                 peer.__class__ = topicpeer
             return peer
 
@@ -568,13 +643,9 @@
 
             reporef = weakref.ref(self)
             if self.ui.configbool(b'experimental', b'enforce-single-head'):
-                if util.safehasattr(tr, 'validator'): # hg <= 4.7 (ebbba3ba3f66)
-                    origvalidator = tr.validator
-                elif util.safehasattr(tr, '_validator'):
+                if util.safehasattr(tr, '_validator'):
                     # hg <= 5.3 (36f08ae87ef6)
                     origvalidator = tr._validator
-                else:
-                    origvalidator = None
 
                 def _validate(tr2):
                     repo = reporef()
@@ -582,11 +653,9 @@
 
                 def validator(tr2):
                     _validate(tr2)
-                    origvalidator(tr2)
+                    return origvalidator(tr2)
 
-                if util.safehasattr(tr, 'validator'): # hg <= 4.7 (ebbba3ba3f66)
-                    tr.validator = validator
-                elif util.safehasattr(tr, '_validator'):
+                if util.safehasattr(tr, '_validator'):
                     # hg <= 5.3 (36f08ae87ef6)
                     tr._validator = validator
                 else:
@@ -598,13 +667,9 @@
                                              b'topic.publish-bare-branch')
             ispush = desc.startswith((b'push', b'serve'))
             if (topicmodeserver != b'ignore' and ispush):
-                if util.safehasattr(tr, 'validator'): # hg <= 4.7 (ebbba3ba3f66)
-                    origvalidator = tr.validator
-                elif util.safehasattr(tr, '_validator'):
+                if util.safehasattr(tr, '_validator'):
                     # hg <= 5.3 (36f08ae87ef6)
                     origvalidator = tr._validator
-                else:
-                    origvalidator = None
 
                 def _validate(tr2):
                     repo = reporef()
@@ -614,9 +679,7 @@
                     _validate(tr2)
                     return origvalidator(tr2)
 
-                if util.safehasattr(tr, 'validator'): # hg <= 4.7 (ebbba3ba3f66)
-                    tr.validator = validator
-                elif util.safehasattr(tr, '_validator'):
+                if util.safehasattr(tr, '_validator'):
                     # hg <= 5.3 (36f08ae87ef6)
                     tr._validator = validator
                 else:
@@ -636,13 +699,9 @@
                                                b'topic.allow-publish',
                                                True)
             if not allow_publish:
-                if util.safehasattr(tr, 'validator'): # hg <= 4.7 (ebbba3ba3f66)
-                    origvalidator = tr.validator
-                elif util.safehasattr(tr, '_validator'):
+                if util.safehasattr(tr, '_validator'):
                     # hg <= 5.3 (36f08ae87ef6)
                     origvalidator = tr._validator
-                else:
-                    origvalidator = None
 
                 def _validate(tr2):
                     repo = reporef()
@@ -652,9 +711,7 @@
                     _validate(tr2)
                     return origvalidator(tr2)
 
-                if util.safehasattr(tr, 'validator'): # hg <= 4.7 (ebbba3ba3f66)
-                    tr.validator = validator
-                elif util.safehasattr(tr, '_validator'):
+                if util.safehasattr(tr, '_validator'):
                     # hg <= 5.3 (36f08ae87ef6)
                     tr._validator = validator
                 else:
@@ -694,6 +751,7 @@
             return tr
 
     repo.__class__ = topicrepo
+    repo._topic_namespaces = None
     repo._topics = None
     if util.safehasattr(repo, 'names'):
         repo.names.addnamespace(namespaces.namespace(
@@ -714,10 +772,28 @@
     ctx = context.resource(mapping, b'ctx')
     return ctx.topicidx()
 
+@templatekeyword(b'topic_namespace', requires={b'ctx'})
+def topicnamespacekw(context, mapping):
+    """:topic_namespace: String. The topic namespace of the changeset"""
+    ctx = context.resource(mapping, b'ctx')
+    return ctx.topic_namespace()
+
+@templatekeyword(b'fqbn', requires={b'ctx'})
+def fqbnkw(context, mapping):
+    """:fqbn: String. The branch//namespace/topic of the changeset"""
+    ctx = context.resource(mapping, b'ctx')
+    return ctx.fqbn()
+
 def wrapinit(orig, self, repo, *args, **kwargs):
     orig(self, repo, *args, **kwargs)
     if not hastopicext(repo):
         return
+    if b'topic-namespace' not in self._extra:
+        if getattr(repo, 'currenttns', b''):
+            self._extra[b'topic-namespace'] = repo.currenttns
+        else:
+            # Default value will be dropped from extra by another hack at the changegroup level
+            self._extra[b'topic-namespace'] = b'default'
     if constants.extrakey not in self._extra:
         if getattr(repo, 'currenttopic', b''):
             self._extra[constants.extrakey] = repo.currenttopic
@@ -728,6 +804,9 @@
 def wrapadd(orig, cl, manifest, files, desc, transaction, p1, p2, user,
             date=None, extra=None, p1copies=None, p2copies=None,
             filesadded=None, filesremoved=None):
+    if b'topic-namespace' in extra and extra[b'topic-namespace'] == b'default':
+        extra = extra.copy()
+        del extra[b'topic-namespace']
     if constants.extrakey in extra and not extra[constants.extrakey]:
         extra = extra.copy()
         del extra[constants.extrakey]
@@ -767,7 +846,8 @@
         (b'', b'current', None, b'display the current topic only'),
     ] + commands.formatteropts,
     _(b'hg topics [OPTION]... [-r REV]... [TOPIC]'),
-    **compat.helpcategorykwargs('CATEGORY_CHANGE_ORGANIZATION'))
+    helpcategory=registrar.command.CATEGORY_CHANGE_ORGANIZATION,
+)
 def topics(ui, repo, topic=None, **opts):
     """View current topic, set current topic, change topic for a set of revisions, or see all topics.
 
@@ -812,13 +892,15 @@
     age = opts.get('age')
 
     if current and topic:
-        raise error.Abort(_(b"cannot use --current when setting a topic"))
+        raise compat.InputError(_(b"cannot use --current when setting a topic"))
     if current and clear:
-        raise error.Abort(_(b"cannot use --current and --clear"))
+        raise compat.InputError(_(b"cannot use --current and --clear"))
     if clear and topic:
-        raise error.Abort(_(b"cannot use --clear when setting a topic"))
+        raise compat.InputError(_(b"cannot use --clear when setting a topic"))
     if age and topic:
-        raise error.Abort(_(b"cannot use --age while setting a topic"))
+        raise compat.InputError(_(b"cannot use --age while setting a topic"))
+
+    compat.check_incompatible_arguments(opts, 'list', ('clear', 'rev'))
 
     touchedrevs = set()
     if rev:
@@ -827,20 +909,24 @@
     if topic:
         topic = topic.strip()
         if not topic:
-            raise error.Abort(_(b"topic name cannot consist entirely of whitespaces"))
+            raise compat.InputError(_(b"topic names cannot consist entirely of whitespace"))
         # Have some restrictions on the topic name just like bookmark name
         scmutil.checknewlabel(repo, topic, b'topic')
 
-        rmatch = re.match(br'[-_.\w]+', topic)
-        if not rmatch or rmatch.group(0) != topic:
-            helptxt = _(b"topic names can only consist of alphanumeric, '-'"
-                        b" '_' and '.' characters")
-            raise error.Abort(_(b"invalid topic name: '%s'") % topic, hint=helptxt)
+        helptxt = _(b"topic names can only consist of alphanumeric, '-'"
+                    b" '_' and '.' characters")
+        try:
+            utopic = encoding.unifromlocal(topic)
+        except error.Abort:
+            # Maybe we should allow these topic names as well, as long as they
+            # don't break any other rules
+            utopic = ''
+        rmatch = re.match(r'[-_.\w]+', utopic, re.UNICODE)
+        if not utopic or not rmatch or rmatch.group(0) != utopic:
+            raise compat.InputError(_(b"invalid topic name: '%s'") % topic, hint=helptxt)
 
     if list:
         ui.pager(b'topics')
-        if clear or rev:
-            raise error.Abort(_(b"cannot use --clear or --rev with --list"))
         if not topic:
             topic = repo.currenttopic
         if not topic:
@@ -912,7 +998,8 @@
             _(b'display data about children outside of the stack'))
     ] + commands.formatteropts,
     _(b'hg stack [TOPIC]'),
-    **compat.helpcategorykwargs('CATEGORY_CHANGE_NAVIGATION'))
+    helpcategory=registrar.command.CATEGORY_CHANGE_NAVIGATION,
+)
 def cmdstack(ui, repo, topic=b'', **opts):
     """list all changesets in a topic and other information
 
@@ -1058,8 +1145,7 @@
 
     if newtopic:
         with repo.wlock():
-            with repo.vfs.open(b'topic', b'w') as f:
-                f.write(newtopic)
+            repo.vfs.write(b'topic', newtopic)
     else:
         if repo.vfs.exists(b'topic'):
             repo.vfs.unlink(b'topic')
@@ -1321,8 +1407,7 @@
         hint = _(b"see 'hg help -e topic.topic-mode' for details")
         if opts.get('topic'):
             t = opts['topic']
-            with repo.vfs.open(b'topic', b'w') as f:
-                f.write(t)
+            repo.vfs.write(b'topic', t)
         elif opts.get('amend'):
             pass
         elif notopic and mayabort:
@@ -1333,8 +1418,7 @@
             if not ui.quiet:
                 ui.warn((b"(%s)\n") % hint)
         elif notopic and mayrandom:
-            with repo.vfs.open(b'topic', b'w') as f:
-                f.write(randomname.randomtopicname(ui))
+            repo.vfs.write(b'topic', randomname.randomtopicname(ui))
         return orig(ui, repo, *args, **opts)
 
 def committextwrap(orig, repo, ctx, subs, extramsg):
@@ -1377,9 +1461,11 @@
                     ret = super(overridebranch, self).__getitem__(rev)
                     if rev == node:
                         b = ret.branch()
+                        tns = ret.topic_namespace()
                         t = ret.topic()
+                        # topic is required for merging from bare branch
                         if t:
-                            ret.branch = lambda: b'%s//%s' % (b, t)
+                            ret.branch = lambda: common.formatfqbn(b, tns, t)
                     return ret
             unfi.__class__ = overridebranch
             if repo.filtername is not None:
@@ -1401,18 +1487,23 @@
         # if rebase is running and update the currenttopic to topic of new
         # rebased commit. We have explicitly stored in config if rebase is
         # running.
+        otns = repo.currenttns
         ot = repo.currenttopic
         if repo.ui.hasconfig(b'experimental', b'topicrebase'):
             isrebase = True
         if repo.ui.configbool(b'_internal', b'keep-topic'):
             ist0 = True
         if ((not partial and not branchmerge) or isrebase) and not ist0:
+            tns = b'default'
             t = b''
             pctx = repo[node]
             if pctx.phase() > phases.public:
+                tns = pctx.topic_namespace()
                 t = pctx.topic()
-            with repo.vfs.open(b'topic', b'w') as f:
-                f.write(t)
+            repo.vfs.write(b'topic-namespace', tns)
+            if tns != b'default' and tns != otns:
+                repo.ui.status(_(b"switching to topic-namespace %s\n") % tns)
+            repo.vfs.write(b'topic', t)
             if t and t != ot:
                 repo.ui.status(_(b"switching to topic %s\n") % t)
             if ot and not t:
@@ -1501,3 +1592,65 @@
     # Restore the topic if need
     if topic:
         _changecurrenttopic(repo, topic)
+
+def _changecurrenttns(repo, tns):
+    if tns:
+        with repo.wlock():
+            repo.vfs.write(b'topic-namespace', tns)
+    else:
+        repo.vfs.unlinkpath(b'topic-namespace', ignoremissing=True)
+
+@command(b'debug-topic-namespace', [
+        (b'', b'clear', False, b'clear active topic namespace if any'),
+    ],
+    _(b'[NAMESPACE|--clear]'))
+def debugtopicnamespace(ui, repo, tns=None, **opts):
+    """set or show the current topic namespace"""
+    if opts.get('clear'):
+        if tns:
+            raise error.Abort(_(b"cannot use --clear when setting a topic namespace"))
+        tns = None
+    elif not tns:
+        ui.write(b'%s\n' % repo.currenttns)
+        return
+    if tns:
+        tns = tns.strip()
+        if not tns:
+            raise error.Abort(_(b"topic namespace cannot consist entirely of whitespace"))
+        if b'/' in tns:
+            raise error.Abort(_(b"topic namespace cannot contain '/' character"))
+        scmutil.checknewlabel(repo, tns, b'topic namespace')
+    ctns = repo.currenttns
+    _changecurrenttns(repo, tns)
+    if ctns == b'default' and tns:
+        repo.ui.status(_(b'marked working directory as topic namespace: %s\n')
+                       % tns)
+
+@command(b'debug-topic-namespaces', [])
+def debugtopicnamespaces(ui, repo, **opts):
+    """list repository namespaces"""
+    for tns in repo.topic_namespaces:
+        ui.write(b'%s\n' % (tns,))
+
+@command(b'debug-parse-fqbn', commands.formatteropts, _(b'FQBN'), optionalrepo=True)
+def debugparsefqbn(ui, repo, fqbn, **opts):
+    """parse branch//namespace/topic string into its components"""
+    branch, tns, topic = common.parsefqbn(fqbn)
+    opts = pycompat.byteskwargs(opts)
+    fm = ui.formatter(b'debug-parse-namespace', opts)
+    fm.startitem()
+    fm.write(b'branch', b'branch:    %s\n', branch)
+    fm.write(b'topic_namespace', b'namespace: %s\n', tns)
+    fm.write(b'topic', b'topic:     %s\n', topic)
+    fm.end()
+
+@command(b'debug-format-fqbn', [
+        (b'b', b'branch', b'', b'branch'),
+        (b'n', b'topic-namespace', b'', b'topic namespace'),
+        (b't', b'topic', b'', b'topic'),
+        (b's', b'short', False, b'short format'),
+    ], optionalrepo=True)
+def debugformatfqbn(ui, repo, **opts):
+    """format branch, namespace and topic into branch//namespace/topic string"""
+    short = common.formatfqbn(opts.get('branch'), opts.get('topic_namespace'), opts.get('topic'), opts.get('short'))
+    ui.write(b'%s\n' % short)
--- a/hgext3rd/topic/common.py	Fri Dec 09 14:57:14 2022 +0400
+++ b/hgext3rd/topic/common.py	Fri Dec 09 15:01:59 2022 +0400
@@ -6,3 +6,102 @@
 def hastopicext(repo):
     """True if the repo use the topic extension"""
     return getattr(repo, 'hastopicext', False)
+
+def parsefqbn(string):
+    """parse branch//namespace/topic string into branch, namespace and topic
+
+    >>> parsefqbn(b'branch//topic')
+    ('branch', 'default', 'topic')
+    >>> parsefqbn(b'//namespace/topic')
+    ('default', 'namespace', 'topic')
+    >>> parsefqbn(b'branch//')
+    ('branch', 'default', '')
+    >>> parsefqbn(b'//namespace/')
+    ('default', 'namespace', '')
+    >>> parsefqbn(b'/topic')
+    ('/topic', 'default', '')
+    >>> parsefqbn(b'//topic')
+    ('default', 'default', 'topic')
+    >>> parsefqbn(b'branch//namespace/topic')
+    ('branch', 'namespace', 'topic')
+    >>> parsefqbn(b'file:///tmp/branch//')
+    ('file:///tmp/branch', 'default', '')
+    >>> parsefqbn(b'http://example.com/branch//namespace/topic')
+    ('http://example.com/branch', 'namespace', 'topic')
+    """
+    branch, sep, other = string.rpartition(b'//')
+    if not sep:
+        # when there's no // anywhere in the string, rpartition returns
+        # untouched string as the 3rd element, and the first two are empty
+        branch, other = other, b''
+    if not branch:
+        branch = b'default'
+    tns, sep, topic = other.partition(b'/')
+    if not sep:
+        # when there's no / in the rest of the string, there can only be topic
+        tns, topic = b'default', tns
+    return branch, tns, topic
+
+def formatfqbn(branch=b'', namespace=b'', topic=b'', short=True):
+    """format branch, namespace and topic into branch//namespace/topic string
+
+    >>> formatfqbn(branch=b'branch', topic=b'topic')
+    'branch//topic'
+    >>> formatfqbn(namespace=b'namespace', topic=b'topic')
+    '//namespace/topic'
+    >>> formatfqbn(branch=b'branch')
+    'branch'
+    >>> formatfqbn(branch=b'branch//')
+    'branch////'
+    >>> formatfqbn(branch=b'double//slash')
+    'double//slash//'
+    >>> formatfqbn(namespace=b'namespace')
+    '//namespace/'
+    >>> formatfqbn(branch=b'/topic')
+    '/topic'
+    >>> formatfqbn(topic=b'topic')
+    '//topic'
+    >>> formatfqbn(branch=b'branch', namespace=b'namespace', topic=b'topic')
+    'branch//namespace/topic'
+    >>> formatfqbn(branch=b'foo/bar', namespace=b'user26', topic=b'feature')
+    'foo/bar//user26/feature'
+    >>> formatfqbn(branch=b'http://example.com/branch', namespace=b'namespace', topic=b'topic')
+    'http://example.com/branch//namespace/topic'
+    """
+    result = b''
+    showbranch = True # branch and not (short and branch == b'default')
+    shownamespace = namespace and not (short and namespace == b'default')
+    if short and not showbranch and not shownamespace and not topic:
+        # if there's nothing to show, show at least branch
+        showbranch = True
+    if showbranch:
+        result += branch
+    if shownamespace or topic or b'//' in branch:
+        result += b'//'
+    if shownamespace:
+        result += namespace + b'/'
+    result += topic
+    return result
+
+def upgradeformat(branch):
+    """take branch and topic in ":" format and return fqbn in "//" format
+
+    This function can be used for transforming branchmap contents of peers that
+    don't support topic namespaces yet to work with peers with topic namespaces
+    support.
+
+    >>> upgradeformat(b'branch')
+    'branch'
+    >>> upgradeformat(b'branch:topic')
+    'branch//topic'
+    >>> upgradeformat(b'branch//')
+    'branch////'
+    >>> upgradeformat(b'branch//:topic')
+    'branch////topic'
+    """
+    if b':' not in branch:
+        # formatting anyway, because named branch could contain "//"
+        return formatfqbn(branch=branch)
+    # topic namespace cannot be extracted from ":" format
+    branch, topic = branch.split(b':', 1)
+    return formatfqbn(branch=branch, topic=topic)
--- a/hgext3rd/topic/compat.py	Fri Dec 09 14:57:14 2022 +0400
+++ b/hgext3rd/topic/compat.py	Fri Dec 09 15:01:59 2022 +0400
@@ -7,11 +7,12 @@
 """
 from __future__ import absolute_import
 
+from mercurial.i18n import _
 from mercurial import (
     cmdutil,
+    error,
     extensions,
     pycompat,
-    registrar,
     util,
 )
 
@@ -24,14 +25,12 @@
         return branchmap.iteritems()
     # py3-transform: on
 
-# help category compatibility
-# hg <= 4.7 (c303d65d2e34)
-def helpcategorykwargs(categoryname):
-    """Backwards-compatible specification of the helpategory argument."""
-    category = getattr(registrar.command, categoryname, None)
-    if not category:
-        return {}
-    return {'helpcategory': category}
+def bcentries(branchcache):
+    if util.safehasattr(branchcache, '_entries'):
+        return branchcache._entries
+    else:
+        # hg <= 4.9 (624d6683c705+b137a6793c51)
+        return branchcache
 
 # nodemap.get and index.[has_node|rev|get_rev]
 # hg <= 5.2 (02802fa87b74)
@@ -59,3 +58,54 @@
                 return orig(repo, node, branch, bheads=bheads, opts=opts)
             return overridefn(_orig, repo, node, branch, bheads=bheads, tip=None, opts=opts)
         extensions.wrapfunction(cmdutil, 'commitstatus', _override)
+
+if util.safehasattr(error, 'InputError'):
+    InputError = error.InputError
+else:
+    # hg <= 5.6 (8d72e29ad1e0)
+    InputError = error.Abort
+
+if util.safehasattr(error, 'StateError'):
+    StateError = error.StateError
+else:
+    # hg <= 5.6 (527ce85c2e60)
+    StateError = error.Abort
+
+if util.safehasattr(error, 'CanceledError'):
+    CanceledError = error.CanceledError
+else:
+    # hg <= 5.6 (ac362d5a7893)
+    CanceledError = error.Abort
+
+if util.safehasattr(cmdutil, 'check_at_most_one_arg'):
+    def check_at_most_one_arg(opts, *args):
+        return cmdutil.check_at_most_one_arg(opts, *args)
+else:
+    # hg <= 5.2 (d587937600be)
+    def check_at_most_one_arg(opts, *args):
+        def to_display(name):
+            return pycompat.sysbytes(name).replace(b'_', b'-')
+
+        previous = None
+        for x in args:
+            if opts.get(x):
+                if previous:
+                    raise InputError(_(b'cannot specify both --%s and --%s')
+                                     % (to_display(previous), to_display(x)))
+                previous = x
+        return previous
+
+if util.safehasattr(cmdutil, 'check_incompatible_arguments'):
+    code = cmdutil.check_incompatible_arguments.__code__
+    if r'others' in code.co_varnames[:code.co_argcount]:
+        def check_incompatible_arguments(opts, first, others):
+            return cmdutil.check_incompatible_arguments(opts, first, others)
+    else:
+        # hg <= 5.3 (d4c1501225c4)
+        def check_incompatible_arguments(opts, first, others):
+            return cmdutil.check_incompatible_arguments(opts, first, *others)
+else:
+    # hg <= 5.2 (023ad45e2fd2)
+    def check_incompatible_arguments(opts, first, others):
+        for other in others:
+            check_at_most_one_arg(opts, first, other)
--- a/hgext3rd/topic/discovery.py	Fri Dec 09 14:57:14 2022 +0400
+++ b/hgext3rd/topic/discovery.py	Fri Dec 09 15:01:59 2022 +0400
@@ -6,27 +6,32 @@
 
 from mercurial.i18n import _
 from mercurial import (
+    branchmap,
     bundle2,
     discovery,
+    encoding,
     error,
     exchange,
     extensions,
     scmutil,
     util,
+    wireprototypes,
+    wireprotov1server,
 )
+from mercurial.wireprotov1peer import batchable, wirepeer
 from . import (
     common,
     compat,
 )
 
-from mercurial import wireprotov1server
+urlreq = util.urlreq
 
 @contextlib.contextmanager
 def override_context_branch(repo, publishedset=()):
     unfi = repo.unfiltered()
 
     class repocls(unfi.__class__):
-        # awful hack to see branch as "branch:topic"
+        # awful hack to see branch as "branch//namespace/topic"
         def __getitem__(self, key):
             ctx = super(repocls, self).__getitem__(key)
             oldbranch = ctx.branch
@@ -36,11 +41,8 @@
             def branch():
                 branch = oldbranch()
                 if rev in publishedset:
-                    return branch
-                topic = ctx.topic()
-                if topic:
-                    branch = b"%s:%s" % (branch, topic)
-                return branch
+                    return common.formatfqbn(branch=branch)
+                return ctx.fqbn()
 
             def parents():
                 parents = oldparents()
@@ -52,11 +54,8 @@
                     def branch():
                         branch = pbranch()
                         if p.rev() in publishedset:
-                            return branch
-                        topic = p.topic()
-                        if topic:
-                            branch = b"%s:%s" % (branch, topic)
-                        return branch
+                            return common.formatfqbn(branch=branch)
+                        return p.fqbn()
                     p.branch = branch
                     p._topic_ext_branch_hack = True
                 return parents
@@ -65,24 +64,6 @@
             ctx.parents = parents
             return ctx
 
-        def revbranchcache(self):
-            rbc = super(repocls, self).revbranchcache()
-            localchangelog = self.changelog
-
-            def branchinfo(rev, changelog=None):
-                if changelog is None:
-                    changelog = localchangelog
-                branch, close = changelog.branchinfo(rev)
-                if rev in publishedset:
-                    return branch, close
-                topic = unfi[rev].topic()
-                if topic:
-                    branch = b"%s:%s" % (branch, topic)
-                return branch, close
-
-            rbc.branchinfo = branchinfo
-            return rbc
-
     oldrepocls = unfi.__class__
     try:
         unfi.__class__ = repocls
@@ -99,44 +80,60 @@
     repo = pushop.repo.unfiltered()
     remote = pushop.remote
 
-    publishing = (b'phases' not in remote.listkeys(b'namespaces')
-                  or bool(remote.listkeys(b'phases').get(b'publishing', False)))
-
-    if not common.hastopicext(pushop.repo):
-        return orig(pushop, *args, **kwargs)
-    elif ((publishing or not remote.capable(b'topics'))
-            and not getattr(pushop, 'publish', False)):
-        return orig(pushop, *args, **kwargs)
-
     publishedset = ()
     remotebranchmap = None
-    origremotebranchmap = remote.branchmap
+    if remote.capable(b'topics-namespaces'):
+        origremotebranchmap = remote.branchmaptns
+    else:
+        origremotebranchmap = remote.branchmap
     publishednode = [c.node() for c in pushop.outdatedphases]
     publishedset = repo.revs(b'ancestors(%ln + %ln)',
                              publishednode,
                              pushop.remotephases.publicheads)
 
+    publishing = (b'phases' not in remote.listkeys(b'namespaces')
+                  or bool(remote.listkeys(b'phases').get(b'publishing', False)))
+    # remote repo may be non-publishing, but if user does hg push --publish, we
+    # still need to consider push operation publishing
+    publishing = publishing or pushop.publish
+
+    ctxoverride = util.nullcontextmanager()
+    if common.hastopicext(pushop.repo) and remote.capable(b'topics'):
+        ctxoverride = override_context_branch(repo, publishedset=publishedset)
+        overrides = {(b'_internal', b'tns-publish'): publishing}
+    else:
+        overrides = {(b'_internal', b'tns-disable-fqbn'): True}
+    configoverride = repo.ui.configoverride(overrides, b'topic-namespaces')
+
+    if not common.hastopicext(pushop.repo):
+        with ctxoverride, configoverride:
+            return orig(pushop, *args, **kwargs)
+    elif ((publishing or not remote.capable(b'topics'))
+            and not getattr(pushop, 'publish', False)):
+        with ctxoverride, configoverride:
+            return orig(pushop, *args, **kwargs)
+
     getrev = compat.getgetrev(repo.unfiltered().changelog)
 
     def remotebranchmap():
         # drop topic information from changeset about to be published
         result = collections.defaultdict(list)
-        for branch, heads in compat.branchmapitems(origremotebranchmap()):
-            if b':' not in branch:
-                result[branch].extend(heads)
-            else:
-                namedbranch = branch.split(b':', 1)[0]
-                for h in heads:
-                    r = getrev(h)
-                    if r is not None and r in publishedset:
-                        result[namedbranch].append(h)
-                    else:
-                        result[branch].append(h)
+        items = list(compat.branchmapitems(origremotebranchmap()))
+        if not remote.capable(b'topics-namespaces'):
+            items = [(common.upgradeformat(branch), heads) for branch, heads in items]
+        for branch, heads in items:
+            namedbranch, tns, topic = common.parsefqbn(branch)
+            for h in heads:
+                r = getrev(h)
+                if r is not None and r in publishedset:
+                    result[common.formatfqbn(branch=namedbranch)].append(h)
+                else:
+                    result[branch].append(h)
         for heads in result.values():
             heads.sort()
         return result
 
-    with override_context_branch(repo, publishedset=publishedset):
+    with ctxoverride, configoverride:
         try:
             if remotebranchmap is not None:
                 remote.branchmap = remotebranchmap
@@ -145,7 +142,8 @@
             pushop.repo = repo
             summary = orig(pushop)
             for key, value in summary.items():
-                if b':' in key: # This is a topic
+                branch, tns, topic = common.parsefqbn(key)
+                if topic: # FIXME: also check namespace?
                     if value[0] is None and value[1]:
                         summary[key] = ([value[1][0]], ) + value[1:]
             return summary
@@ -158,17 +156,40 @@
 def wireprotobranchmap(orig, repo, proto):
     if not common.hastopicext(repo):
         return orig(repo, proto)
-    oldrepo = repo.__class__
+    unfi = repo.unfiltered()
+    oldrepocls = unfi.__class__
     try:
-        class repocls(repo.__class__):
+        class repocls(oldrepocls):
             def branchmap(self):
                 usetopic = not self.publishing()
-                return super(repocls, self).branchmap(topic=usetopic)
-        repo.__class__ = repocls
+                return super(repocls, self).branchmap(topic=usetopic, convertbm=usetopic)
+
+            # Where is branchmaptns method, you might ask? The answer is that
+            # this repocls is only relevant when we're trying to use the old
+            # branchmap server command. If we use branchmaptns command that was
+            # introduced as a part of topic namespaces support, then this
+            # repocls shouldn't be used at all.
+        unfi.__class__ = repocls
+        if repo.filtername is not None:
+            repo = unfi.filtered(repo.filtername)
+        else:
+            repo = unfi
         return orig(repo, proto)
     finally:
-        repo.__class__ = oldrepo
+        unfi.__class__ = oldrepocls
 
+def wireprotobranchmaptns(repo, proto):
+    """copied from wireprotov1server.branchmap()"""
+    if not common.hastopicext(repo):
+        return wireprotov1server.branchmap(repo, proto)
+    branchmaptns = repo.branchmaptns()
+    heads = []
+    for branch, nodes in branchmaptns.items():
+        branchname = urlreq.quote(encoding.fromlocal(branch))
+        branchnodes = wireprototypes.encodelist(nodes)
+        heads.append(b'%s %s' % (branchname, branchnodes))
+
+    return wireprototypes.bytesresponse(b'\n'.join(heads))
 
 def _get_branch_name(ctx):
     # make it easy for extension with the branch logic there
@@ -242,9 +263,7 @@
         return
     tr._prepushheads = _nbheads(op.repo)
     reporef = weakref.ref(op.repo)
-    if util.safehasattr(tr, 'validator'): # hg <= 4.7 (ebbba3ba3f66)
-        oldvalidator = tr.validator
-    elif util.safehasattr(tr, '_validator'):
+    if util.safehasattr(tr, '_validator'):
         # hg <= 5.3 (36f08ae87ef6)
         oldvalidator = tr._validator
 
@@ -263,7 +282,7 @@
                         b"push creates new heads on branch '%s': %s"
                         % (branch, heads)
                     )
-                    raise error.Abort(msg)
+                    raise compat.StateError(msg)
             for branch, newnb in finalheads.items():
                 if 1 < len(newnb):
                     cl = repo.changelog
@@ -274,15 +293,13 @@
                     )
                     hint = _(b"merge or see 'hg help push' for details about "
                              b"pushing new heads")
-                    raise error.Abort(msg, hint=hint)
+                    raise compat.StateError(msg, hint=hint)
 
     def validator(tr):
         _validate(tr)
         return oldvalidator(tr)
 
-    if util.safehasattr(tr, 'validator'): # hg <= 4.7 (ebbba3ba3f66)
-        tr.validator = validator
-    elif util.safehasattr(tr, '_validator'):
+    if util.safehasattr(tr, '_validator'):
         # hg <= 5.3 (36f08ae87ef6)
         tr._validator = validator
     else:
@@ -302,13 +319,55 @@
     caps = orig(repo, proto)
     if common.hastopicext(repo) and repo.peer().capable(b'topics'):
         caps.append(b'topics')
+        caps.append(b'topics-namespaces')
     return caps
 
+def branchmaptns(self):
+    """copied from wirepeer.branchmap()
+
+    Client-side command for communicating with a peer repository. Calls wire
+    protocol command of the same name (thanks to the batchable decorator).
+    """
+    def decode(d):
+        try:
+            branchmap = {}
+            for branchpart in d.splitlines():
+                branchname, branchheads = branchpart.split(b' ', 1)
+                branchname = encoding.tolocal(urlreq.unquote(branchname))
+                branchheads = wireprototypes.decodelist(branchheads)
+                branchmap[branchname] = branchheads
+            return branchmap
+        except TypeError:
+            self._abort(error.ResponseError(_(b"unexpected response:"), d))
+
+    return {}, decode
+
+def wrapbranchinfo(orig, self, rev):
+    b, close = orig(self, rev)
+    if common.hastopicext(self._repo):
+        if self._repo.ui.configbool(b'_internal', b'tns-disable-fqbn'):
+            # the config option prevents this function from doing anything,
+            # this happens when e.g. the remote repo doesn't have topic
+            # extension enabled
+            pass
+        elif self._repo.ui.configbool(b'_internal', b'tns-publish'):
+            # when this rev gets published, only branch will stay
+            b = common.formatfqbn(branch=b)
+        else:
+            ctx = self._repo[rev]
+            b = ctx.fqbn()
+    return b, close
+
 def modsetup(ui):
     """run at uisetup time to install all destinations wrapping"""
     extensions.wrapfunction(discovery, '_headssummary', _headssummary)
     extensions.wrapfunction(wireprotov1server, 'branchmap', wireprotobranchmap)
+    wireprotov1server.commands.pop(b'branchmap')
+    wireprotov1server.wireprotocommand(b'branchmap', permission=b'pull')(wireprotov1server.branchmap)
     extensions.wrapfunction(wireprotov1server, '_capabilities', wireprotocaps)
+    wirepeer.branchmaptns = batchable(branchmaptns)
+    wireprotov1server.wireprotocommand(b'branchmaptns', permission=b'pull')(wireprotobranchmaptns)
+    extensions.wrapfunction(branchmap.revbranchcache, 'branchinfo', wrapbranchinfo)
     # we need a proper wrap b2 part stuff
     extensions.wrapfunction(bundle2, 'handlecheckheads', handlecheckheads)
     bundle2.handlecheckheads.params = frozenset()
--- a/hgext3rd/topic/flow.py	Fri Dec 09 14:57:14 2022 +0400
+++ b/hgext3rd/topic/flow.py	Fri Dec 09 15:01:59 2022 +0400
@@ -169,7 +169,7 @@
                 _(b'push and publish %i changesets (yn)?$$ &Yes $$ &No')
                 % len(published)
             ):
-                raise error.Abort(_(b'user quit'))
+                raise compat.CanceledError(_(b'user quit'))
         elif behavior == b'abort':
             msg = _(b'push would publish %i changesets') % len(published)
             hint = _(
--- a/hgext3rd/topic/randomname.py	Fri Dec 09 14:57:14 2022 +0400
+++ b/hgext3rd/topic/randomname.py	Fri Dec 09 15:01:59 2022 +0400
@@ -60,6 +60,7 @@
     b'crow',
     b'curlew',
     b'deer',
+    b'dingo',
     b'dinosaur',
     b'dog',
     b'dogfish',
@@ -194,6 +195,7 @@
     b'quagga',
     b'quail',
     b'quelea',
+    b'quokka',
     b'rabbit',
     b'raccoon',
     b'ram',
@@ -294,8 +296,8 @@
     b'amusing',
     b'ancient',
     b'animated',
+    b'appropriate',
     b'apricot',
-    b'appropriate',
     b'aquatic',
     b'arctic',
     b'arenaceous',
@@ -650,6 +652,7 @@
     b'little',
     b'lively',
     b'living',
+    b'lone',
     b'long',
     b'longing',
     b'loud',
@@ -949,6 +952,7 @@
     b'understanding',
     b'understood',
     b'unequaled',
+    b'unidentified',
     b'unique',
     b'unusual',
     b'unwritten',
--- a/hgext3rd/topic/revset.py	Fri Dec 09 14:57:14 2022 +0400
+++ b/hgext3rd/topic/revset.py	Fri Dec 09 15:01:59 2022 +0400
@@ -7,20 +7,13 @@
     util,
 )
 
+from mercurial.utils import stringutil
+
 from . import (
     destination,
     stack,
 )
 
-try:
-    mkmatcher = revset._stringmatcher
-except AttributeError:
-    try:
-        from mercurial.utils import stringutil
-        mkmatcher = stringutil.stringmatcher
-    except (ImportError, AttributeError):
-        mkmatcher = util.stringmatcher
-
 revsetpredicate = registrar.revsetpredicate()
 
 def getstringstrict(x, err):
@@ -28,13 +21,60 @@
         return x[1]
     raise error.ParseError(err)
 
+@revsetpredicate(b'topicnamespace([string or set])')
+def topicnamespaceset(repo, subset, x):
+    """All changesets with the specified topic namespace or the topic
+    namespaces of the given changesets. Without the argument, all changesets
+    with any non-default topic namespace.
+
+     Pattern matching is supported for `string`. See
+    :hg:`help revisions.patterns`.
+    """
+    args = revset.getargs(x, 0, 1, b'topicnamespace takes one or no arguments')
+
+    mutable = revset._notpublic(repo, revset.fullreposet(repo), ())
+
+    if not args:
+        return (subset & mutable).filter(lambda r: repo[r].topic_namespace() != b'default')
+
+    try:
+        tns = getstringstrict(args[0], b'')
+    except error.ParseError:
+        # not a string, but another revset
+        pass
+    else:
+        kind, pattern, matcher = stringutil.stringmatcher(tns)
+
+        if tns.startswith(b'literal:') and pattern not in repo.topic_namespaces:
+            raise error.RepoLookupError(b"topic namespace '%s' does not exist" % pattern)
+
+        def matches(r):
+            tns = repo[r].topic_namespace()
+            if tns == b'default':
+                return False
+            return matcher(tns)
+
+        return (subset & mutable).filter(matches)
+
+    s = revset.getset(repo, revset.fullreposet(repo), x)
+    namespaces = {repo[r].topic_namespace() for r in s}
+    namespaces.discard(b'default')
+
+    def matches(r):
+        tns = repo[r].topic_namespace()
+        if tns == b'default':
+            return False
+        return tns in namespaces
+
+    return (subset & mutable).filter(matches)
+
 @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.
 
-    If `string` starts with `re:` the remainder of the name is treated
-    as a regular expression.
+     Pattern matching is supported for `string`. See
+    :hg:`help revisions.patterns`.
     """
     args = revset.getargs(x, 0, 1, b'topic takes one or no arguments')
 
@@ -49,7 +89,7 @@
         # not a string, but another revset
         pass
     else:
-        kind, pattern, matcher = mkmatcher(topic)
+        kind, pattern, matcher = stringutil.stringmatcher(topic)
 
         if topic.startswith(b'literal:') and pattern not in repo.topics:
             raise error.RepoLookupError(b"topic '%s' does not exist" % pattern)
@@ -91,10 +131,10 @@
 
 @revsetpredicate(b'stack()')
 def stackset(repo, subset, x):
-    """All relevant changes in the current topic,
+    """All relevant changes in the current topic.
 
-    This is roughly equivalent to 'topic(.) - obsolete' with a sorting moving
-    unstable changeset after there future parent (as if evolve where already
+    This is roughly equivalent to 'topic(.) - obsolete()' with a sorting moving
+    unstable changeset after their future parent (as if evolve were already
     run).
     """
     err = b'stack takes no arguments, it works on current topic'
--- a/hgext3rd/topic/topicmap.py	Fri Dec 09 14:57:14 2022 +0400
+++ b/hgext3rd/topic/topicmap.py	Fri Dec 09 15:01:59 2022 +0400
@@ -168,12 +168,8 @@
 
     def copy(self):
         """return an deep copy of the branchcache object"""
-        if util.safehasattr(self, '_entries'):
-            _entries = self._entries
-        else:
-            # hg <= 4.9 (624d6683c705+b137a6793c51)
-            _entries = self
-        args = (_entries, self.tipnode, self.tiprev, self.filteredhash,
+        entries = compat.bcentries(self)
+        args = (entries, self.tipnode, self.tiprev, self.filteredhash,
                 self._closednodes)
         if util.safehasattr(self, '_repo'):
             # hg <= 5.7 (6266d19556ad)
@@ -182,18 +178,17 @@
         new.phaseshash = self.phaseshash
         return new
 
-    def branchtip(self, branch, topic=b''):
-        '''Return the tipmost open head on branch head, otherwise return the
-        tipmost closed head on branch.
-        Raise KeyError for unknown branch.'''
-        if topic:
-            branch = b'%s:%s' % (branch, topic)
-        return super(_topiccache, self).branchtip(branch)
+    def load(self, repo, lineiter):
+        """call branchmap.load(), and then transform branch names to be in the
+        new "//" format
+        """
+        super(_topiccache, self).load(repo, lineiter)
+        entries = compat.bcentries(self)
 
-    def branchheads(self, branch, closed=False, topic=b''):
-        if topic:
-            branch = b'%s:%s' % (branch, topic)
-        return super(_topiccache, self).branchheads(branch, closed=closed)
+        for branch in tuple(entries):
+            formatted = common.formatfqbn(branch=branch)
+            if branch != formatted:
+                entries[formatted] = entries.pop(branch)
 
     def validfor(self, repo):
         """Is the cache content valid regarding a repo
@@ -215,10 +210,21 @@
                 return False
 
     def write(self, repo):
+        """write cache to disk if it's not topic-only, but first transform
+        cache keys from branches in "//" format into bare branch names
+        """
         # we expect mutable set to be small enough to be that computing it all
         # the time will be fast enough
         if not istopicfilter(repo.filtername):
-            super(_topiccache, self).write(repo)
+            cache = self.copy()
+            entries = compat.bcentries(cache)
+
+            for formatted in tuple(entries):
+                branch, tns, topic = common.parsefqbn(formatted)
+                if branch != formatted:
+                    entries[branch] = entries.pop(formatted)
+
+            super(_topiccache, cache).write(repo)
 
     def update(self, repo, revgen):
         """Given a branchhead cache, self, that may have extra nodes or be
@@ -227,22 +233,14 @@
         """
         if not istopicfilter(repo.filtername):
             return super(_topiccache, self).update(repo, revgen)
-        unfi = repo.unfiltered()
-        oldgetbranchinfo = unfi.revbranchcache().branchinfo
 
-        def branchinfo(r, changelog=None):
-            info = oldgetbranchinfo(r)
-            topic = b''
-            ctx = unfi[r]
-            if ctx.mutable():
-                topic = ctx.topic()
-            branch = info[0]
-            if topic:
-                branch = b'%s:%s' % (branch, topic)
-            return (branch, info[1])
-        try:
-            unfi.revbranchcache().branchinfo = branchinfo
-            super(_topiccache, self).update(repo, revgen)
-            self.phaseshash = _phaseshash(repo, self.tiprev)
-        finally:
-            unfi.revbranchcache().branchinfo = oldgetbranchinfo
+        # See topic.discovery._headssummary(), where repo.unfiltered gets
+        # overridden to return .filtered('unfiltered-topic'). revbranchcache
+        # only can be created for unfiltered repo (filtername is None), so we
+        # do that here, and this revbranchcache will be cached inside repo.
+        # When we get rid of *-topic filters, then this workaround can be
+        # removed too.
+        repo.unfiltered().revbranchcache()
+
+        super(_topiccache, self).update(repo, revgen)
+        self.phaseshash = _phaseshash(repo, self.tiprev)
--- a/tests/test-check-sdist.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-check-sdist.t	Fri Dec 09 15:01:59 2022 +0400
@@ -35,7 +35,7 @@
 
   $ tar -tzf hg-evolve-*.tar.gz | sed 's|^hg-evolve-[^/]*/||' | sort > files
   $ wc -l files
-  359 files
+  361 files
   $ fgrep debian files
   tests/test-check-debian.t
   $ fgrep __init__.py files
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-doctest.py	Fri Dec 09 15:01:59 2022 +0400
@@ -0,0 +1,127 @@
+# this is hack to make sure no escape characters are inserted into the output
+
+from __future__ import absolute_import
+from __future__ import print_function
+
+import doctest
+import os
+import re
+import subprocess
+import sys
+
+ispy3 = sys.version_info[0] >= 3
+
+if 'TERM' in os.environ:
+    del os.environ['TERM']
+
+
+class py3docchecker(doctest.OutputChecker):
+    def check_output(self, want, got, optionflags):
+        want2 = re.sub(r'''\bu(['"])(.*?)\1''', r'\1\2\1', want)  # py2: u''
+        got2 = re.sub(r'''\bb(['"])(.*?)\1''', r'\1\2\1', got)  # py3: b''
+        # py3: <exc.name>: b'<msg>' -> <name>: <msg>
+        #      <exc.name>: <others> -> <name>: <others>
+        # TODO: more output massaging
+        return any(
+            doctest.OutputChecker.check_output(self, w, g, optionflags)
+            for w, g in [(want, got), (want2, got2)]
+        )
+
+
+def testmod(name, optionflags=0, testtarget=None):
+    __import__(name)
+    mod = sys.modules[name]
+    if testtarget is not None:
+        mod = getattr(mod, testtarget)
+
+    # minimal copy of doctest.testmod()
+    finder = doctest.DocTestFinder()
+    checker = None
+    if ispy3:
+        checker = py3docchecker()
+    runner = doctest.DocTestRunner(checker=checker, optionflags=optionflags)
+    for test in finder.find(mod, name):
+        runner.run(test)
+    runner.summarize()
+
+
+DONT_RUN = []
+
+# Exceptions to the defaults for a given detected module. The value for each
+# module name is a list of dicts that specify the kwargs to pass to testmod.
+# testmod is called once per item in the list, so an empty list will cause the
+# module to not be tested.
+testmod_arg_overrides = {
+    # 'mercurial.statprof': DONT_RUN,  # >>> is an example, not a doctest
+}
+
+fileset = 'set:(**.py)'
+
+cwd = os.path.dirname(os.environ["TESTDIR"])
+
+# run-tests.py makes an installation of core Mercurial in /tmp/, but evolve is
+# not installed together with it, and evolve modules need to be imported to run
+# doctests. We insert it at the start to make sure wider install of evolve does not take priority.
+sys.path.insert(0, cwd)
+
+if not os.path.isdir(os.path.join(cwd, ".hg")):
+    sys.exit(0)
+
+files = subprocess.check_output(
+    "hg files --print0 \"%s\"" % fileset,
+    shell=True,
+    cwd=cwd,
+).split(b'\0')
+
+if sys.version_info[0] >= 3:
+    cwd = os.fsencode(cwd)
+
+mods_tested = set()
+for f in files:
+    if not f:
+        continue
+
+    with open(os.path.join(cwd, f), "rb") as fh:
+        if not re.search(br'\n\s*>>>', fh.read()):
+            continue
+
+    if ispy3:
+        f = f.decode()
+
+    modname = f.replace('.py', '').replace('\\', '.').replace('/', '.')
+
+    # Third-party modules aren't our responsibility to test.
+    if modname.startswith('hgext3rd.evolve.thirdparty.'):
+        continue
+
+    for kwargs in testmod_arg_overrides.get(modname, [{}]):
+        mods_tested.add((modname, '%r' % (kwargs,)))
+        if modname.startswith('tests.'):
+            # On py2, we can't import from tests.foo, but it works on both py2
+            # and py3 with the way that PYTHONPATH is setup to import without
+            # the 'tests.' prefix, so we do that.
+            modname = modname[len('tests.'):]
+
+        testmod(modname, **kwargs)
+
+# Meta-test: let's make sure that we actually ran what we expected to, above.
+# Each item in the set is a 2-tuple of module name and stringified kwargs passed
+# to testmod.
+expected_mods_tested = set(
+    [
+        ('hgext3rd.evolve.obshistory', '{}'),
+        ('hgext3rd.topic.common', '{}'),
+    ]
+)
+
+unexpectedly_run = mods_tested.difference(expected_mods_tested)
+not_run = expected_mods_tested.difference(mods_tested)
+
+if unexpectedly_run:
+    print('Unexpectedly ran (probably need to add to list):')
+    for r in sorted(unexpectedly_run):
+        print('  %r' % (r,))
+if not_run:
+    print('Expected to run, but was not run (doctest removed?):')
+    for r in sorted(not_run):
+        print('  %r' % (r,))
--- a/tests/test-evolve-abort-orphan.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-evolve-abort-orphan.t	Fri Dec 09 15:01:59 2022 +0400
@@ -60,7 +60,7 @@
 #if abortflag
   $ hg evolve --abort
   abort: no interrupted evolve to abort
-  [255]
+  [20]
 #else
   $ hg abort
   abort: no operation in progress
@@ -167,7 +167,7 @@
   continue: hg evolve --continue
   $ hg evolve --continue
   evolving 4:c41c793e0ef1 "added d"
-  working directory is now at e83de241f751
+  working directory is now at 69c43da639bb
 
   $ hg up .^^^
   0 files updated, 0 files merged, 3 files removed, 0 files unresolved
@@ -215,7 +215,7 @@
   |   () draft
   o  7:125af0ed8cae added a
   |   () draft
-  | *  6:e83de241f751 added d
+  | *  6:69c43da639bb added d
   | |   () draft orphan
   | %  5:e93a9161a274 added c
   | |   () draft orphan
@@ -234,7 +234,7 @@
   $ hg glog
   @  7:125af0ed8cae added a
   |   () draft
-  | *  6:e83de241f751 added d
+  | *  6:69c43da639bb added d
   | |   () draft orphan
   | *  5:e93a9161a274 added c
   | |   () draft orphan
--- a/tests/test-evolve-abort-phasediv.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-evolve-abort-phasediv.t	Fri Dec 09 15:01:59 2022 +0400
@@ -302,7 +302,7 @@
   continue: hg evolve --continue
   $ hg evolve --continue
   evolving 9:28cd06b3f801 "added c"
-  committed as 95d746965290
+  committed as 92acf49069a4
   recreate:[10] added d
   atop:[4] added d
   rebasing to destination parent: ca1b80f7960a
--- a/tests/test-evolve-content-divergent-case-A3.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-evolve-content-divergent-case-A3.t	Fri Dec 09 15:01:59 2022 +0400
@@ -125,10 +125,10 @@
   base: [3] C
   rebasing "other" content-divergent changeset 710d96992b40 on f6fbb35d8ac9
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  working directory is now at 3ad062d48137
+  working directory is now at b341bfa8675e
 
   $ hg log -G
-  @  7:3ad062d48137 (draft): C
+  @  7:b341bfa8675e (draft): C
   |
   o  2:f6fbb35d8ac9 (draft): B
   |
@@ -137,8 +137,8 @@
   o  0:a9bdc8b26820 (public): O
   
   $ hg log -pl 1
-  7:3ad062d48137 (draft): C 
-  diff -r f6fbb35d8ac9 -r 3ad062d48137 C
+  7:b341bfa8675e (draft): C 
+  diff -r f6fbb35d8ac9 -r b341bfa8675e C
   --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   +++ b/C	Thu Jan 01 00:00:00 1970 +0000
   @@ -0,0 +1,1 @@
@@ -178,10 +178,10 @@
   base: [3] C
   rebasing "divergent" content-divergent changeset 710d96992b40 on f6fbb35d8ac9
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  working directory is now at 8f91b97f6f9a
+  working directory is now at 0de314083dd2
 
   $ hg log -G
-  @  7:8f91b97f6f9a (draft): C
+  @  7:0de314083dd2 (draft): C
   |
   o  2:f6fbb35d8ac9 (draft): B
   |
@@ -192,8 +192,8 @@
   $ hg evolve -l
 
   $ hg log -pl1
-  7:8f91b97f6f9a (draft): C 
-  diff -r f6fbb35d8ac9 -r 8f91b97f6f9a C
+  7:0de314083dd2 (draft): C 
+  diff -r f6fbb35d8ac9 -r 0de314083dd2 C
   --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   +++ b/C	Thu Jan 01 00:00:00 1970 +0000
   @@ -0,0 +1,1 @@
--- a/tests/test-evolve-content-divergent-case-B1.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-evolve-content-divergent-case-B1.t	Fri Dec 09 15:01:59 2022 +0400
@@ -137,7 +137,7 @@
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
 
   $ hg log -G
-  o  9:6f740085e668 (draft): new_B
+  o  9:55f09418c9b0 (draft): new_B
   |
   @  5:45ed635c7cfc (draft): latest_A
   |
@@ -181,10 +181,10 @@
   base: [2] B
   rebasing "divergent" content-divergent changeset 807cc2b37fb3 on 1ffcccee011c
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  working directory is now at 2431e876af63
+  working directory is now at 6b611864f3f6
 
   $ hg log -G
-  @  8:2431e876af63 (draft): new_B [orphan]
+  @  8:6b611864f3f6 (draft): new_B [orphan]
   |
   | o  6:45ed635c7cfc (draft): latest_A
   | |
@@ -193,6 +193,6 @@
   o  0:a9bdc8b26820 (public): O
   
   $ hg evolve -l
-  2431e876af63: new_B
+  6b611864f3f6: new_B
     orphan: 1ffcccee011c (obsolete parent)
   
--- a/tests/test-evolve-content-divergent-corner-cases.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-evolve-content-divergent-corner-cases.t	Fri Dec 09 15:01:59 2022 +0400
@@ -379,10 +379,10 @@
   You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
   What do you want to do? c
   0 files updated, 1 files merged, 0 files removed, 0 files unresolved
-  working directory is now at 050a5d9ba60d
+  working directory is now at 8bcf0a598b0d
 
   $ hg glog -l1
-  @  8:050a5d9ba60d updated e
+  @  8:8bcf0a598b0d updated e
   |   () [default] draft
   ~
 
@@ -390,15 +390,15 @@
   8d71eadcc9dfb21a924e75a5796c2f011bdc55a4 ff6f7cd76a7c97d938e8fe87f0fc816b66929435 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '9', 'operation': 'amend', 'user': 'test'}
   8d71eadcc9dfb21a924e75a5796c2f011bdc55a4 de4ea3103326293994c634101e780724346ee89f 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '13', 'operation': 'prune', 'user': 'test'}
   9150fe93bec603cd88d05cda9f6ff13420cb53e9 0 {155349b645beebee15325a9a22dd0c9ef8fbbbd3} (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'prune', 'user': 'test'}
-  ff6f7cd76a7c97d938e8fe87f0fc816b66929435 8883bfaa2d02c8c54b6278551324187019862599 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'evolve', 'user': 'test'}
-  8883bfaa2d02c8c54b6278551324187019862599 050a5d9ba60d423b4401803509457515297edcf4 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'evolve', 'user': 'test'}
-  de4ea3103326293994c634101e780724346ee89f 050a5d9ba60d423b4401803509457515297edcf4 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'evolve', 'user': 'test'}
+  ff6f7cd76a7c97d938e8fe87f0fc816b66929435 8da34ee32eee606a1fca89e76ce48dcfb0e2598b 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'evolve', 'user': 'test'}
+  8da34ee32eee606a1fca89e76ce48dcfb0e2598b 8bcf0a598b0d242cb58758d78acd77e874251eef 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'evolve', 'user': 'test'}
+  de4ea3103326293994c634101e780724346ee89f 8bcf0a598b0d242cb58758d78acd77e874251eef 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'evolve', 'user': 'test'}
   $ hg obslog --all
-  @    050a5d9ba60d (8) updated e
-  |\     amended(content) from 8883bfaa2d02 using evolve by test (Thu Jan 01 00:00:00 1970 +0000)
+  @    8bcf0a598b0d (8) updated e
+  |\     amended(content) from 8da34ee32eee using evolve by test (Thu Jan 01 00:00:00 1970 +0000)
   | |    rewritten from de4ea3103326 using evolve by test (Thu Jan 01 00:00:00 1970 +0000)
   | |
-  x |  8883bfaa2d02 (7) updated e
+  x |  8da34ee32eee (7) updated e
   | |    rebased(parent) from ff6f7cd76a7c using evolve by test (Thu Jan 01 00:00:00 1970 +0000)
   | |
   | x  de4ea3103326 (6) updated e
--- a/tests/test-evolve-content-divergent-interrupted.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-evolve-content-divergent-interrupted.t	Fri Dec 09 15:01:59 2022 +0400
@@ -567,11 +567,11 @@
   $ hg next
   move:[5] added d
   atop:[8] added c
-  working directory is now at dc9ba677cba1
+  working directory is now at 543adc7eac82
   $ echo "latest_changes" >> a
   $ hg amend
   $ hg glog
-  @  10:0892835a581f added d
+  @  10:13a3da452f7f added d
   |   () draft content-divergent
   o  8:33c16a2e0eb8 added c
   |   () draft
@@ -588,7 +588,7 @@
   merge:[7] added d
   with: [10] added d
   base: [4] added d
-  rebasing "other" content-divergent changeset 0892835a581f on c7586e2a9264
+  rebasing "other" content-divergent changeset 13a3da452f7f on c7586e2a9264
   merging a
   warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
   unresolved merge conflicts
@@ -605,7 +605,7 @@
   +=======
   +some_changes
   +latest_changes
-  +>>>>>>> evolving:    0892835a581f - test: added d
+  +>>>>>>> evolving:    13a3da452f7f - test: added d
   diff -r c7586e2a9264 d
   --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   +++ b/d	Thu Jan 01 00:00:00 1970 +0000
@@ -614,10 +614,10 @@
 
   $ hg evolve --stop
   stopped the interrupted evolve
-  working directory is now at 0892835a581f
+  working directory is now at 13a3da452f7f
 
   $ hg glog
-  @  10:0892835a581f added d
+  @  10:13a3da452f7f added d
   |   () draft content-divergent
   o  8:33c16a2e0eb8 added c
   |   () draft
--- a/tests/test-evolve-content-divergent-relocation.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-evolve-content-divergent-relocation.t	Fri Dec 09 15:01:59 2022 +0400
@@ -97,10 +97,10 @@
   base: [2] added b
   rebasing "divergent" content-divergent changeset 7ed0642d644b on 8fa14d15e168
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  working directory is now at c5862ade0278
+  working directory is now at bd76a775c527
 
   $ hg glog
-  @  8:c5862ade0278 added b
+  @  8:bd76a775c527 added b
   |   () [default] draft
   | *  4:c41c793e0ef1 added d
   | |   () [default] draft
@@ -118,11 +118,11 @@
   # User test
   # Date 0 0
   #      Thu Jan 01 00:00:00 1970 +0000
-  # Node ID c5862ade02783a99f46082f4f0483c449fc4c3f2
+  # Node ID bd76a775c52744611afa76b4980e0b46a7a105f5
   # Parent  8fa14d15e1684a9720b1b065aba9d5ea51024cb2
   added b
   
-  diff -r 8fa14d15e168 -r c5862ade0278 b
+  diff -r 8fa14d15e168 -r bd76a775c527 b
   --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   +++ b/b	Thu Jan 01 00:00:00 1970 +0000
   @@ -0,0 +1,1 @@
@@ -131,21 +131,21 @@
   $ hg debugobsolete
   b1661037fa25511d0b7ccddf405e336f9d7d3424 7ed0642d644bb9ad93d252dd9ffe7b4729febe48 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'amend', 'user': 'test'}
   b1661037fa25511d0b7ccddf405e336f9d7d3424 da4b96f4a8d610a85b225583138f681d67e275dd 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
-  7ed0642d644bb9ad93d252dd9ffe7b4729febe48 2ec52f302b0f0ef30979124e92f1d9f2a26cedf8 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'evolve', 'user': 'test'}
-  2ec52f302b0f0ef30979124e92f1d9f2a26cedf8 c5862ade02783a99f46082f4f0483c449fc4c3f2 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'evolve', 'user': 'test'}
-  da4b96f4a8d610a85b225583138f681d67e275dd c5862ade02783a99f46082f4f0483c449fc4c3f2 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'evolve', 'user': 'test'}
+  7ed0642d644bb9ad93d252dd9ffe7b4729febe48 df708ef51071b9b7932664cb88742483ffa6c0af 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'evolve', 'user': 'test'}
+  df708ef51071b9b7932664cb88742483ffa6c0af bd76a775c52744611afa76b4980e0b46a7a105f5 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'evolve', 'user': 'test'}
+  da4b96f4a8d610a85b225583138f681d67e275dd bd76a775c52744611afa76b4980e0b46a7a105f5 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'evolve', 'user': 'test'}
   $ hg obslog --all
-  @    c5862ade0278 (8) added b
-  |\     rewritten from 2ec52f302b0f using evolve by test (Thu Jan 01 00:00:00 1970 +0000)
-  | |    amended(content) from da4b96f4a8d6 using evolve by test (Thu Jan 01 00:00:00 1970 +0000)
+  @    bd76a775c527 (8) added b
+  |\     amended(content) from da4b96f4a8d6 using evolve by test (Thu Jan 01 00:00:00 1970 +0000)
+  | |    rewritten from df708ef51071 using evolve by test (Thu Jan 01 00:00:00 1970 +0000)
   | |
-  x |  2ec52f302b0f (7) added b
+  x |  da4b96f4a8d6 (6) added b
+  | |    rebased(parent) from b1661037fa25 using rebase by test (Thu Jan 01 00:00:00 1970 +0000)
+  | |
+  | x  df708ef51071 (7) added b
   | |    rebased(parent) from 7ed0642d644b using evolve by test (Thu Jan 01 00:00:00 1970 +0000)
   | |
-  | x  da4b96f4a8d6 (6) added b
-  | |    rebased(parent) from b1661037fa25 using rebase by test (Thu Jan 01 00:00:00 1970 +0000)
-  | |
-  x |  7ed0642d644b (5) added b
+  | x  7ed0642d644b (5) added b
   |/     amended(content) from b1661037fa25 using amend by test (Thu Jan 01 00:00:00 1970 +0000)
   |
   x  b1661037fa25 (2) added b
@@ -158,11 +158,11 @@
   atop:[8] added b
   move:[4] added d
   $ hg glog
-  o  10:25cb1649b463 added d
+  o  10:44c908a29dde added d
   |   () [default] draft
-  o  9:81ead2f9fc61 added c
+  o  9:905d3f000de6 added c
   |   () [default] draft
-  @  8:c5862ade0278 added b
+  @  8:bd76a775c527 added b
   |   () [default] draft
   | o  1:c7586e2a9264 added a
   |/    () [default] draft
@@ -174,7 +174,7 @@
   $ echo x > x
   $ hg ci -Aqm "added x"
   $ hg glog -r .
-  @  11:f220d694b3a6 added x
+  @  11:2eea3a452f03 added x
   |   () [default] draft
   ~
 
@@ -186,24 +186,24 @@
 
   $ hg up 'predecessors(.)' --hidden
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  updated to hidden changeset f220d694b3a6
-  (hidden revision 'f220d694b3a6' was rewritten as: 91939f44a1fe)
-  working directory parent is obsolete! (f220d694b3a6)
-  (use 'hg evolve' to update to its successor: 91939f44a1fe)
+  updated to hidden changeset 2eea3a452f03
+  (hidden revision '2eea3a452f03' was rewritten as: f9c46439290c)
+  working directory parent is obsolete! (2eea3a452f03)
+  (use 'hg evolve' to update to its successor: f9c46439290c)
   $ hg rebase -r . -d 'desc("added d")' --config experimental.evolution.allowdivergence=True
-  rebasing 11:f220d694b3a6 "added x"
+  rebasing 11:2eea3a452f03 "added x"
   2 new content-divergent changesets
 
   $ hg glog
-  @  13:7af6be6736c0 added x
+  @  13:03d7f147ff42 added x
   |   () [default] draft
-  | *  12:91939f44a1fe added foo to x
+  | *  12:f9c46439290c added foo to x
   | |   () [bar] draft
-  o |  10:25cb1649b463 added d
+  o |  10:44c908a29dde added d
   | |   () [default] draft
-  o |  9:81ead2f9fc61 added c
+  o |  9:905d3f000de6 added c
   |/    () [default] draft
-  o  8:c5862ade0278 added b
+  o  8:bd76a775c527 added b
   |   () [default] draft
   | o  1:c7586e2a9264 added a
   |/    () [default] draft
@@ -214,9 +214,9 @@
   merge:[12] added foo to x
   with: [13] added x
   base: [11] added x
-  rebasing "divergent" content-divergent changeset 91939f44a1fe on 25cb1649b463
+  rebasing "divergent" content-divergent changeset f9c46439290c on 44c908a29dde
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  working directory is now at 3c4c7420a968
+  working directory is now at 60f40a789d85
 
   $ hg exp
   # HG changeset patch
@@ -224,11 +224,11 @@
   # Date 0 0
   #      Thu Jan 01 00:00:00 1970 +0000
   # Branch bar
-  # Node ID 3c4c7420a968a3f76d61fa16c3af9abe115f07b6
-  # Parent  25cb1649b46389f8e6e77c3796f01b37996b8fcd
+  # Node ID 60f40a789d85a42549e1e10c27779cfb5d5e1e1c
+  # Parent  44c908a29dde4b2a7fd1fa5714177b99a2423bbb
   added foo to x
   
-  diff -r 25cb1649b463 -r 3c4c7420a968 x
+  diff -r 44c908a29dde -r 60f40a789d85 x
   --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   +++ b/x	Thu Jan 01 00:00:00 1970 +0000
   @@ -0,0 +1,1 @@
@@ -237,13 +237,13 @@
 The above `hg exp` and the following log call demonstrates that message, content
 and branch change is preserved in case of relocation
   $ hg glog
-  @  15:3c4c7420a968 added foo to x
+  @  15:60f40a789d85 added foo to x
   |   () [bar] draft
-  o  10:25cb1649b463 added d
+  o  10:44c908a29dde added d
   |   () [default] draft
-  o  9:81ead2f9fc61 added c
+  o  9:905d3f000de6 added c
   |   () [default] draft
-  o  8:c5862ade0278 added b
+  o  8:bd76a775c527 added b
   |   () [default] draft
   | o  1:c7586e2a9264 added a
   |/    () [default] draft
@@ -253,31 +253,31 @@
   $ hg debugobsolete
   b1661037fa25511d0b7ccddf405e336f9d7d3424 7ed0642d644bb9ad93d252dd9ffe7b4729febe48 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'amend', 'user': 'test'}
   b1661037fa25511d0b7ccddf405e336f9d7d3424 da4b96f4a8d610a85b225583138f681d67e275dd 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
-  7ed0642d644bb9ad93d252dd9ffe7b4729febe48 2ec52f302b0f0ef30979124e92f1d9f2a26cedf8 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'evolve', 'user': 'test'}
-  2ec52f302b0f0ef30979124e92f1d9f2a26cedf8 c5862ade02783a99f46082f4f0483c449fc4c3f2 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'evolve', 'user': 'test'}
-  da4b96f4a8d610a85b225583138f681d67e275dd c5862ade02783a99f46082f4f0483c449fc4c3f2 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'evolve', 'user': 'test'}
-  ca1b80f7960aae2306287bab52b4090c59af8c29 81ead2f9fc6156de69d12b7b5df71c34ab8b9c10 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'evolve', 'user': 'test'}
-  c41c793e0ef1ddb463e85ea9491e377d01127ba2 25cb1649b46389f8e6e77c3796f01b37996b8fcd 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'evolve', 'user': 'test'}
-  f220d694b3a605e236b4b34ef97d3cc6959efb89 91939f44a1fe6d865ec791122014971dfff75129 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '73', 'operation': 'amend', 'user': 'test'}
-  f220d694b3a605e236b4b34ef97d3cc6959efb89 7af6be6736c0aebd226820373190e636fe9f16e9 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
-  91939f44a1fe6d865ec791122014971dfff75129 c38f731f5ae01e417ceeea09f046febf4536d356 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'evolve', 'user': 'test'}
-  c38f731f5ae01e417ceeea09f046febf4536d356 3c4c7420a968a3f76d61fa16c3af9abe115f07b6 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'evolve', 'user': 'test'}
-  7af6be6736c0aebd226820373190e636fe9f16e9 3c4c7420a968a3f76d61fa16c3af9abe115f07b6 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '73', 'operation': 'evolve', 'user': 'test'}
+  7ed0642d644bb9ad93d252dd9ffe7b4729febe48 df708ef51071b9b7932664cb88742483ffa6c0af 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'evolve', 'user': 'test'}
+  df708ef51071b9b7932664cb88742483ffa6c0af bd76a775c52744611afa76b4980e0b46a7a105f5 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'evolve', 'user': 'test'}
+  da4b96f4a8d610a85b225583138f681d67e275dd bd76a775c52744611afa76b4980e0b46a7a105f5 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'evolve', 'user': 'test'}
+  ca1b80f7960aae2306287bab52b4090c59af8c29 905d3f000de6ac0cdca8ed4bd222bf08ddb4b6d4 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'evolve', 'user': 'test'}
+  c41c793e0ef1ddb463e85ea9491e377d01127ba2 44c908a29dde4b2a7fd1fa5714177b99a2423bbb 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'evolve', 'user': 'test'}
+  2eea3a452f0362f367aa8a45ffc2ebec52971c3d f9c46439290cf371c88424caaefc92398d808666 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '73', 'operation': 'amend', 'user': 'test'}
+  2eea3a452f0362f367aa8a45ffc2ebec52971c3d 03d7f147ff4243d7ac83eba7047ab8847da35c91 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
+  f9c46439290cf371c88424caaefc92398d808666 45cdf781a3eac63e762b68047e0beee60a47a805 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'evolve', 'user': 'test'}
+  45cdf781a3eac63e762b68047e0beee60a47a805 60f40a789d85a42549e1e10c27779cfb5d5e1e1c 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'evolve', 'user': 'test'}
+  03d7f147ff4243d7ac83eba7047ab8847da35c91 60f40a789d85a42549e1e10c27779cfb5d5e1e1c 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '73', 'operation': 'evolve', 'user': 'test'}
   $ hg obslog --all
-  @    3c4c7420a968 (15) added foo to x
-  |\     rewritten(description, branch, content) from 7af6be6736c0 using evolve by test (Thu Jan 01 00:00:00 1970 +0000)
-  | |    rewritten from c38f731f5ae0 using evolve by test (Thu Jan 01 00:00:00 1970 +0000)
+  @    60f40a789d85 (15) added foo to x
+  |\     rewritten(description, branch, content) from 03d7f147ff42 using evolve by test (Thu Jan 01 00:00:00 1970 +0000)
+  | |    rewritten from 45cdf781a3ea using evolve by test (Thu Jan 01 00:00:00 1970 +0000)
   | |
-  x |  7af6be6736c0 (13) added x
-  | |    rebased(parent) from f220d694b3a6 using rebase by test (Thu Jan 01 00:00:00 1970 +0000)
+  x |  03d7f147ff42 (13) added x
+  | |    rebased(parent) from 2eea3a452f03 using rebase by test (Thu Jan 01 00:00:00 1970 +0000)
   | |
-  | x  c38f731f5ae0 (14) added foo to x
-  | |    rebased(parent) from 91939f44a1fe using evolve by test (Thu Jan 01 00:00:00 1970 +0000)
+  | x  45cdf781a3ea (14) added foo to x
+  | |    rebased(parent) from f9c46439290c using evolve by test (Thu Jan 01 00:00:00 1970 +0000)
   | |
-  | x  91939f44a1fe (12) added foo to x
-  |/     rewritten(description, branch, content) from f220d694b3a6 using amend by test (Thu Jan 01 00:00:00 1970 +0000)
+  | x  f9c46439290c (12) added foo to x
+  |/     rewritten(description, branch, content) from 2eea3a452f03 using amend by test (Thu Jan 01 00:00:00 1970 +0000)
   |
-  x  f220d694b3a6 (11) added x
+  x  2eea3a452f03 (11) added x
   
 
 Testing when both the content-divergence are on different parents and resolution
@@ -290,7 +290,7 @@
   $ echo y > y
   $ hg ci -Aqm "added y"
   $ hg glog -r .
-  @  16:d84c9e99d55b added y
+  @  16:6cba24390b74 added y
   |   () [default] draft
   ~
 
@@ -299,28 +299,28 @@
 
   $ hg up 'predecessors(.)' --hidden
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  updated to hidden changeset d84c9e99d55b
-  (hidden revision 'd84c9e99d55b' was rewritten as: 98cd38d20303)
-  working directory parent is obsolete! (d84c9e99d55b)
-  (use 'hg evolve' to update to its successor: 98cd38d20303)
+  updated to hidden changeset 6cba24390b74
+  (hidden revision '6cba24390b74' was rewritten as: 347339f712be)
+  working directory parent is obsolete! (6cba24390b74)
+  (use 'hg evolve' to update to its successor: 347339f712be)
   $ hg rebase -r . -d 'desc("added foo to x")' --config experimental.evolution.allowdivergence=True
-  rebasing 16:d84c9e99d55b "added y"
+  rebasing 16:6cba24390b74 "added y"
   2 new content-divergent changesets
   $ echo wat > y
   $ hg amend
 
   $ hg glog
-  @  19:ec9ec45c397e added y
+  @  19:7734a6171413 added y
   |   () [bar] draft
-  | *  17:98cd38d20303 added y
+  | *  17:347339f712be added y
   | |   () [default] draft
-  o |  15:3c4c7420a968 added foo to x
+  o |  15:60f40a789d85 added foo to x
   | |   () [bar] draft
-  o |  10:25cb1649b463 added d
+  o |  10:44c908a29dde added d
   | |   () [default] draft
-  o |  9:81ead2f9fc61 added c
+  o |  9:905d3f000de6 added c
   |/    () [default] draft
-  o  8:c5862ade0278 added b
+  o  8:bd76a775c527 added b
   |   () [default] draft
   | o  1:c7586e2a9264 added a
   |/    () [default] draft
@@ -331,7 +331,7 @@
   merge:[17] added y
   with: [19] added y
   base: [16] added y
-  rebasing "divergent" content-divergent changeset 98cd38d20303 on 3c4c7420a968
+  rebasing "divergent" content-divergent changeset 347339f712be on 60f40a789d85
   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
@@ -344,18 +344,18 @@
   (no more unresolved files)
   continue: hg evolve --continue
   $ hg evolve --continue
-  working directory is now at 26dd4974d99f
+  working directory is now at a1a5f649aad4
 
   $ hg glog
-  @  21:26dd4974d99f added y
+  @  21:a1a5f649aad4 added y
   |   () [bar] draft
-  o  15:3c4c7420a968 added foo to x
+  o  15:60f40a789d85 added foo to x
   |   () [bar] draft
-  o  10:25cb1649b463 added d
+  o  10:44c908a29dde added d
   |   () [default] draft
-  o  9:81ead2f9fc61 added c
+  o  9:905d3f000de6 added c
   |   () [default] draft
-  o  8:c5862ade0278 added b
+  o  8:bd76a775c527 added b
   |   () [default] draft
   | o  1:c7586e2a9264 added a
   |/    () [default] draft
@@ -365,40 +365,40 @@
   $ hg debugobsolete
   b1661037fa25511d0b7ccddf405e336f9d7d3424 7ed0642d644bb9ad93d252dd9ffe7b4729febe48 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'amend', 'user': 'test'}
   b1661037fa25511d0b7ccddf405e336f9d7d3424 da4b96f4a8d610a85b225583138f681d67e275dd 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
-  7ed0642d644bb9ad93d252dd9ffe7b4729febe48 2ec52f302b0f0ef30979124e92f1d9f2a26cedf8 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'evolve', 'user': 'test'}
-  2ec52f302b0f0ef30979124e92f1d9f2a26cedf8 c5862ade02783a99f46082f4f0483c449fc4c3f2 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'evolve', 'user': 'test'}
-  da4b96f4a8d610a85b225583138f681d67e275dd c5862ade02783a99f46082f4f0483c449fc4c3f2 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'evolve', 'user': 'test'}
-  ca1b80f7960aae2306287bab52b4090c59af8c29 81ead2f9fc6156de69d12b7b5df71c34ab8b9c10 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'evolve', 'user': 'test'}
-  c41c793e0ef1ddb463e85ea9491e377d01127ba2 25cb1649b46389f8e6e77c3796f01b37996b8fcd 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'evolve', 'user': 'test'}
-  f220d694b3a605e236b4b34ef97d3cc6959efb89 91939f44a1fe6d865ec791122014971dfff75129 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '73', 'operation': 'amend', 'user': 'test'}
-  f220d694b3a605e236b4b34ef97d3cc6959efb89 7af6be6736c0aebd226820373190e636fe9f16e9 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
-  91939f44a1fe6d865ec791122014971dfff75129 c38f731f5ae01e417ceeea09f046febf4536d356 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'evolve', 'user': 'test'}
-  c38f731f5ae01e417ceeea09f046febf4536d356 3c4c7420a968a3f76d61fa16c3af9abe115f07b6 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'evolve', 'user': 'test'}
-  7af6be6736c0aebd226820373190e636fe9f16e9 3c4c7420a968a3f76d61fa16c3af9abe115f07b6 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '73', 'operation': 'evolve', 'user': 'test'}
-  d84c9e99d55bfa499ab77dabd1fb3035e8f14ba9 98cd38d203030c04c89650c7280a6a71ae2f748c 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'amend', 'user': 'test'}
-  d84c9e99d55bfa499ab77dabd1fb3035e8f14ba9 6c3124aac43f4c0e64155b93ea60e0e10abd6ba1 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '68', 'operation': 'rebase', 'user': 'test'}
-  6c3124aac43f4c0e64155b93ea60e0e10abd6ba1 ec9ec45c397e15dfd9f25a91b6ffa1e17f9b9471 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'amend', 'user': 'test'}
-  98cd38d203030c04c89650c7280a6a71ae2f748c 5ddc0bec0e2650fb56e3b5d24f7c7c3a61401fbe 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'evolve', 'user': 'test'}
-  5ddc0bec0e2650fb56e3b5d24f7c7c3a61401fbe 26dd4974d99f30b9c9b259e22254b29474155d45 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '72', 'operation': 'evolve', 'user': 'test'}
-  ec9ec45c397e15dfd9f25a91b6ffa1e17f9b9471 26dd4974d99f30b9c9b259e22254b29474155d45 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'evolve', 'user': 'test'}
+  7ed0642d644bb9ad93d252dd9ffe7b4729febe48 df708ef51071b9b7932664cb88742483ffa6c0af 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'evolve', 'user': 'test'}
+  df708ef51071b9b7932664cb88742483ffa6c0af bd76a775c52744611afa76b4980e0b46a7a105f5 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'evolve', 'user': 'test'}
+  da4b96f4a8d610a85b225583138f681d67e275dd bd76a775c52744611afa76b4980e0b46a7a105f5 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'evolve', 'user': 'test'}
+  ca1b80f7960aae2306287bab52b4090c59af8c29 905d3f000de6ac0cdca8ed4bd222bf08ddb4b6d4 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'evolve', 'user': 'test'}
+  c41c793e0ef1ddb463e85ea9491e377d01127ba2 44c908a29dde4b2a7fd1fa5714177b99a2423bbb 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'evolve', 'user': 'test'}
+  2eea3a452f0362f367aa8a45ffc2ebec52971c3d f9c46439290cf371c88424caaefc92398d808666 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '73', 'operation': 'amend', 'user': 'test'}
+  2eea3a452f0362f367aa8a45ffc2ebec52971c3d 03d7f147ff4243d7ac83eba7047ab8847da35c91 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
+  f9c46439290cf371c88424caaefc92398d808666 45cdf781a3eac63e762b68047e0beee60a47a805 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'evolve', 'user': 'test'}
+  45cdf781a3eac63e762b68047e0beee60a47a805 60f40a789d85a42549e1e10c27779cfb5d5e1e1c 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'evolve', 'user': 'test'}
+  03d7f147ff4243d7ac83eba7047ab8847da35c91 60f40a789d85a42549e1e10c27779cfb5d5e1e1c 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '73', 'operation': 'evolve', 'user': 'test'}
+  6cba24390b749067bef92c44e0288e6f554bfb37 347339f712becdde80c9ad13d22a497db6086d90 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'amend', 'user': 'test'}
+  6cba24390b749067bef92c44e0288e6f554bfb37 24f8adc447ef80b160e63ae48688e98cb737166f 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '68', 'operation': 'rebase', 'user': 'test'}
+  24f8adc447ef80b160e63ae48688e98cb737166f 7734a6171413c2df9c39102accf4bc21cbc5bd9a 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'amend', 'user': 'test'}
+  347339f712becdde80c9ad13d22a497db6086d90 6f720dea6f607e618f51c0cf1b07f8415de5e23e 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'evolve', 'user': 'test'}
+  6f720dea6f607e618f51c0cf1b07f8415de5e23e a1a5f649aad404acfddaa979465e96581c2ce0fb 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '72', 'operation': 'evolve', 'user': 'test'}
+  7734a6171413c2df9c39102accf4bc21cbc5bd9a a1a5f649aad404acfddaa979465e96581c2ce0fb 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'evolve', 'user': 'test'}
   $ hg obslog -r . --all
-  @    26dd4974d99f (21) added y
-  |\     rewritten(branch, content) from 5ddc0bec0e26 using evolve by test (Thu Jan 01 00:00:00 1970 +0000)
-  | |    amended(content) from ec9ec45c397e using evolve by test (Thu Jan 01 00:00:00 1970 +0000)
+  @    a1a5f649aad4 (21) added y
+  |\     rewritten(branch, content) from 6f720dea6f60 using evolve by test (Thu Jan 01 00:00:00 1970 +0000)
+  | |    amended(content) from 7734a6171413 using evolve by test (Thu Jan 01 00:00:00 1970 +0000)
   | |
-  x |  5ddc0bec0e26 (20) added y
-  | |    rebased(parent) from 98cd38d20303 using evolve by test (Thu Jan 01 00:00:00 1970 +0000)
+  x |  6f720dea6f60 (20) added y
+  | |    rebased(parent) from 347339f712be using evolve by test (Thu Jan 01 00:00:00 1970 +0000)
   | |
-  | x  ec9ec45c397e (19) added y
-  | |    amended(content) from 6c3124aac43f using amend by test (Thu Jan 01 00:00:00 1970 +0000)
+  | x  7734a6171413 (19) added y
+  | |    amended(content) from 24f8adc447ef using amend by test (Thu Jan 01 00:00:00 1970 +0000)
   | |
-  | x  6c3124aac43f (18) added y
-  | |    rewritten(branch, parent) from d84c9e99d55b using rebase by test (Thu Jan 01 00:00:00 1970 +0000)
+  | x  24f8adc447ef (18) added y
+  | |    rewritten(branch, parent) from 6cba24390b74 using rebase by test (Thu Jan 01 00:00:00 1970 +0000)
   | |
-  x |  98cd38d20303 (17) added y
-  |/     amended(content) from d84c9e99d55b using amend by test (Thu Jan 01 00:00:00 1970 +0000)
+  x |  347339f712be (17) added y
+  |/     amended(content) from 6cba24390b74 using amend by test (Thu Jan 01 00:00:00 1970 +0000)
   |
-  x  d84c9e99d55b (16) added y
+  x  6cba24390b74 (16) added y
   
 
 checking that relocated commit is there
@@ -407,11 +407,11 @@
   # User test
   # Date 0 0
   #      Thu Jan 01 00:00:00 1970 +0000
-  # Node ID 5ddc0bec0e2650fb56e3b5d24f7c7c3a61401fbe
-  # Parent  3c4c7420a968a3f76d61fa16c3af9abe115f07b6
+  # Node ID 6f720dea6f607e618f51c0cf1b07f8415de5e23e
+  # Parent  60f40a789d85a42549e1e10c27779cfb5d5e1e1c
   added y
   
-  diff -r 3c4c7420a968 -r 5ddc0bec0e26 y
+  diff -r 60f40a789d85 -r 6f720dea6f60 y
   --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   +++ b/y	Thu Jan 01 00:00:00 1970 +0000
   @@ -0,0 +1,1 @@
@@ -421,15 +421,15 @@
 ----------------------------------------------------------------------
 
   $ hg glog
-  @  21:26dd4974d99f added y
+  @  21:a1a5f649aad4 added y
   |   () [bar] draft
-  o  15:3c4c7420a968 added foo to x
+  o  15:60f40a789d85 added foo to x
   |   () [bar] draft
-  o  10:25cb1649b463 added d
+  o  10:44c908a29dde added d
   |   () [default] draft
-  o  9:81ead2f9fc61 added c
+  o  9:905d3f000de6 added c
   |   () [default] draft
-  o  8:c5862ade0278 added b
+  o  8:bd76a775c527 added b
   |   () [default] draft
   | o  1:c7586e2a9264 added a
   |/    () [default] draft
@@ -442,7 +442,7 @@
   $ echo z > z
   $ hg ci -Aqm "added z"
   $ hg glog -r .
-  @  22:136e58088ce2 added z
+  @  22:e308b18e59ab added z
   |   () [default] draft
   ~
 
@@ -452,30 +452,30 @@
 
   $ hg up 'predecessors(.)' --hidden
   0 files updated, 0 files merged, 1 files removed, 0 files unresolved
-  updated to hidden changeset 136e58088ce2
-  (hidden revision '136e58088ce2' was rewritten as: f4c3594c72e7)
-  working directory parent is obsolete! (136e58088ce2)
-  (use 'hg evolve' to update to its successor: f4c3594c72e7)
+  updated to hidden changeset e308b18e59ab
+  (hidden revision 'e308b18e59ab' was rewritten as: 20885f9c4458)
+  working directory parent is obsolete! (e308b18e59ab)
+  (use 'hg evolve' to update to its successor: 20885f9c4458)
   $ hg rebase -r . -d 'desc("added y")' --config experimental.evolution.allowdivergence=True
-  rebasing 22:136e58088ce2 "added z"
+  rebasing 22:e308b18e59ab "added z"
   2 new content-divergent changesets
   $ echo bar > z
   $ hg amend
 
   $ hg glog
-  @  25:7e87b40e3aa8 added z
+  @  25:85cb29df3b9e added z
   |   () [bar] draft
-  | *  23:f4c3594c72e7 added z
+  | *  23:20885f9c4458 added z
   | |   () [default] draft
-  o |  21:26dd4974d99f added y
+  o |  21:a1a5f649aad4 added y
   | |   () [bar] draft
-  o |  15:3c4c7420a968 added foo to x
+  o |  15:60f40a789d85 added foo to x
   | |   () [bar] draft
-  o |  10:25cb1649b463 added d
+  o |  10:44c908a29dde added d
   | |   () [default] draft
-  o |  9:81ead2f9fc61 added c
+  o |  9:905d3f000de6 added c
   |/    () [default] draft
-  o  8:c5862ade0278 added b
+  o  8:bd76a775c527 added b
   |   () [default] draft
   | o  1:c7586e2a9264 added a
   |/    () [default] draft
@@ -486,7 +486,7 @@
   merge:[23] added z
   with: [25] added z
   base: [22] added z
-  rebasing "divergent" content-divergent changeset f4c3594c72e7 on 26dd4974d99f
+  rebasing "divergent" content-divergent changeset 20885f9c4458 on a1a5f649aad4
   merging y
   warning: conflicts while merging y! (edit, then use 'hg resolve --mark')
   unresolved merge conflicts
@@ -494,16 +494,16 @@
   [240]
 
   $ hg diff
-  diff -r 26dd4974d99f y
+  diff -r a1a5f649aad4 y
   --- a/y	Thu Jan 01 00:00:00 1970 +0000
   +++ b/y	Thu Jan 01 00:00:00 1970 +0000
   @@ -1,1 +1,5 @@
-  +<<<<<<< destination: 26dd4974d99f bar - test: added y
+  +<<<<<<< destination: a1a5f649aad4 bar - test: added y
    watbar
   +=======
   +foo
-  +>>>>>>> evolving:    f4c3594c72e7 - test: added z
-  diff -r 26dd4974d99f z
+  +>>>>>>> evolving:    20885f9c4458 - test: added z
+  diff -r a1a5f649aad4 z
   --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   +++ b/z	Thu Jan 01 00:00:00 1970 +0000
   @@ -0,0 +1,1 @@
@@ -515,7 +515,7 @@
   continue: hg evolve --continue
 
   $ hg evolve --continue
-  evolving 23:f4c3594c72e7 "added z"
+  evolving 23:20885f9c4458 "added z"
   merging y
   warning: conflicts while merging y! (edit, then use 'hg resolve --mark')
   1 files updated, 0 files merged, 0 files removed, 1 files unresolved
@@ -524,16 +524,16 @@
   [240]
 
   $ hg diff
-  diff -r 5049972c0e21 y
+  diff -r 3ad61e93b7b0 y
   --- a/y	Thu Jan 01 00:00:00 1970 +0000
   +++ b/y	Thu Jan 01 00:00:00 1970 +0000
   @@ -1,1 +1,5 @@
-  +<<<<<<< local: 5049972c0e21 - test: added z
+  +<<<<<<< local: 3ad61e93b7b0 - test: added z
    foo
   +=======
   +watbar
-  +>>>>>>> other: 7e87b40e3aa8 bar - test: added z
-  diff -r 5049972c0e21 z
+  +>>>>>>> other: 85cb29df3b9e bar - test: added z
+  diff -r 3ad61e93b7b0 z
   --- a/z	Thu Jan 01 00:00:00 1970 +0000
   +++ b/z	Thu Jan 01 00:00:00 1970 +0000
   @@ -1,1 +1,1 @@
@@ -545,20 +545,20 @@
   (no more unresolved files)
   continue: hg evolve --continue
   $ hg evolve --continue
-  working directory is now at 04eb6e8d253d
+  working directory is now at 9fe0112b059e
 
   $ hg glog
-  @  27:04eb6e8d253d added z
+  @  27:9fe0112b059e added z
   |   () [bar] draft
-  o  21:26dd4974d99f added y
+  o  21:a1a5f649aad4 added y
   |   () [bar] draft
-  o  15:3c4c7420a968 added foo to x
+  o  15:60f40a789d85 added foo to x
   |   () [bar] draft
-  o  10:25cb1649b463 added d
+  o  10:44c908a29dde added d
   |   () [default] draft
-  o  9:81ead2f9fc61 added c
+  o  9:905d3f000de6 added c
   |   () [default] draft
-  o  8:c5862ade0278 added b
+  o  8:bd76a775c527 added b
   |   () [default] draft
   | o  1:c7586e2a9264 added a
   |/    () [default] draft
@@ -571,17 +571,17 @@
   # Date 0 0
   #      Thu Jan 01 00:00:00 1970 +0000
   # Branch bar
-  # Node ID 04eb6e8d253d5f17e0d9b1518678e015c272704e
-  # Parent  26dd4974d99f30b9c9b259e22254b29474155d45
+  # Node ID 9fe0112b059ea3e9b1213e4f07839b957125ffca
+  # Parent  a1a5f649aad404acfddaa979465e96581c2ce0fb
   added z
   
-  diff -r 26dd4974d99f -r 04eb6e8d253d y
+  diff -r a1a5f649aad4 -r 9fe0112b059e y
   --- a/y	Thu Jan 01 00:00:00 1970 +0000
   +++ b/y	Thu Jan 01 00:00:00 1970 +0000
   @@ -1,1 +1,1 @@
   -watbar
   +foo
-  diff -r 26dd4974d99f -r 04eb6e8d253d z
+  diff -r a1a5f649aad4 -r 9fe0112b059e z
   --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   +++ b/z	Thu Jan 01 00:00:00 1970 +0000
   @@ -0,0 +1,1 @@
@@ -590,46 +590,46 @@
   $ hg debugobsolete
   b1661037fa25511d0b7ccddf405e336f9d7d3424 7ed0642d644bb9ad93d252dd9ffe7b4729febe48 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'amend', 'user': 'test'}
   b1661037fa25511d0b7ccddf405e336f9d7d3424 da4b96f4a8d610a85b225583138f681d67e275dd 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
-  7ed0642d644bb9ad93d252dd9ffe7b4729febe48 2ec52f302b0f0ef30979124e92f1d9f2a26cedf8 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'evolve', 'user': 'test'}
-  2ec52f302b0f0ef30979124e92f1d9f2a26cedf8 c5862ade02783a99f46082f4f0483c449fc4c3f2 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'evolve', 'user': 'test'}
-  da4b96f4a8d610a85b225583138f681d67e275dd c5862ade02783a99f46082f4f0483c449fc4c3f2 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'evolve', 'user': 'test'}
-  ca1b80f7960aae2306287bab52b4090c59af8c29 81ead2f9fc6156de69d12b7b5df71c34ab8b9c10 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'evolve', 'user': 'test'}
-  c41c793e0ef1ddb463e85ea9491e377d01127ba2 25cb1649b46389f8e6e77c3796f01b37996b8fcd 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'evolve', 'user': 'test'}
-  f220d694b3a605e236b4b34ef97d3cc6959efb89 91939f44a1fe6d865ec791122014971dfff75129 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '73', 'operation': 'amend', 'user': 'test'}
-  f220d694b3a605e236b4b34ef97d3cc6959efb89 7af6be6736c0aebd226820373190e636fe9f16e9 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
-  91939f44a1fe6d865ec791122014971dfff75129 c38f731f5ae01e417ceeea09f046febf4536d356 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'evolve', 'user': 'test'}
-  c38f731f5ae01e417ceeea09f046febf4536d356 3c4c7420a968a3f76d61fa16c3af9abe115f07b6 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'evolve', 'user': 'test'}
-  7af6be6736c0aebd226820373190e636fe9f16e9 3c4c7420a968a3f76d61fa16c3af9abe115f07b6 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '73', 'operation': 'evolve', 'user': 'test'}
-  d84c9e99d55bfa499ab77dabd1fb3035e8f14ba9 98cd38d203030c04c89650c7280a6a71ae2f748c 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'amend', 'user': 'test'}
-  d84c9e99d55bfa499ab77dabd1fb3035e8f14ba9 6c3124aac43f4c0e64155b93ea60e0e10abd6ba1 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '68', 'operation': 'rebase', 'user': 'test'}
-  6c3124aac43f4c0e64155b93ea60e0e10abd6ba1 ec9ec45c397e15dfd9f25a91b6ffa1e17f9b9471 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'amend', 'user': 'test'}
-  98cd38d203030c04c89650c7280a6a71ae2f748c 5ddc0bec0e2650fb56e3b5d24f7c7c3a61401fbe 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'evolve', 'user': 'test'}
-  5ddc0bec0e2650fb56e3b5d24f7c7c3a61401fbe 26dd4974d99f30b9c9b259e22254b29474155d45 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '72', 'operation': 'evolve', 'user': 'test'}
-  ec9ec45c397e15dfd9f25a91b6ffa1e17f9b9471 26dd4974d99f30b9c9b259e22254b29474155d45 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'evolve', 'user': 'test'}
-  136e58088ce2a46749c73256b02608ca9be0fe09 f4c3594c72e7140404222d25e8827292e5d1a728 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'amend', 'user': 'test'}
-  136e58088ce2a46749c73256b02608ca9be0fe09 da49edc1732932755e2c42d91b6883e6616ff40b 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '68', 'operation': 'rebase', 'user': 'test'}
-  da49edc1732932755e2c42d91b6883e6616ff40b 7e87b40e3aa8d28f0ba07c1cec4f562e57ba7c12 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'amend', 'user': 'test'}
-  f4c3594c72e7140404222d25e8827292e5d1a728 5049972c0e212e0ad051e628b37d162097944b5f 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '12', 'operation': 'evolve', 'user': 'test'}
-  5049972c0e212e0ad051e628b37d162097944b5f 04eb6e8d253d5f17e0d9b1518678e015c272704e 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '72', 'operation': 'evolve', 'user': 'test'}
-  7e87b40e3aa8d28f0ba07c1cec4f562e57ba7c12 04eb6e8d253d5f17e0d9b1518678e015c272704e 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'evolve', 'user': 'test'}
+  7ed0642d644bb9ad93d252dd9ffe7b4729febe48 df708ef51071b9b7932664cb88742483ffa6c0af 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'evolve', 'user': 'test'}
+  df708ef51071b9b7932664cb88742483ffa6c0af bd76a775c52744611afa76b4980e0b46a7a105f5 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'evolve', 'user': 'test'}
+  da4b96f4a8d610a85b225583138f681d67e275dd bd76a775c52744611afa76b4980e0b46a7a105f5 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'evolve', 'user': 'test'}
+  ca1b80f7960aae2306287bab52b4090c59af8c29 905d3f000de6ac0cdca8ed4bd222bf08ddb4b6d4 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'evolve', 'user': 'test'}
+  c41c793e0ef1ddb463e85ea9491e377d01127ba2 44c908a29dde4b2a7fd1fa5714177b99a2423bbb 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'evolve', 'user': 'test'}
+  2eea3a452f0362f367aa8a45ffc2ebec52971c3d f9c46439290cf371c88424caaefc92398d808666 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '73', 'operation': 'amend', 'user': 'test'}
+  2eea3a452f0362f367aa8a45ffc2ebec52971c3d 03d7f147ff4243d7ac83eba7047ab8847da35c91 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
+  f9c46439290cf371c88424caaefc92398d808666 45cdf781a3eac63e762b68047e0beee60a47a805 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'evolve', 'user': 'test'}
+  45cdf781a3eac63e762b68047e0beee60a47a805 60f40a789d85a42549e1e10c27779cfb5d5e1e1c 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'evolve', 'user': 'test'}
+  03d7f147ff4243d7ac83eba7047ab8847da35c91 60f40a789d85a42549e1e10c27779cfb5d5e1e1c 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '73', 'operation': 'evolve', 'user': 'test'}
+  6cba24390b749067bef92c44e0288e6f554bfb37 347339f712becdde80c9ad13d22a497db6086d90 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'amend', 'user': 'test'}
+  6cba24390b749067bef92c44e0288e6f554bfb37 24f8adc447ef80b160e63ae48688e98cb737166f 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '68', 'operation': 'rebase', 'user': 'test'}
+  24f8adc447ef80b160e63ae48688e98cb737166f 7734a6171413c2df9c39102accf4bc21cbc5bd9a 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'amend', 'user': 'test'}
+  347339f712becdde80c9ad13d22a497db6086d90 6f720dea6f607e618f51c0cf1b07f8415de5e23e 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'evolve', 'user': 'test'}
+  6f720dea6f607e618f51c0cf1b07f8415de5e23e a1a5f649aad404acfddaa979465e96581c2ce0fb 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '72', 'operation': 'evolve', 'user': 'test'}
+  7734a6171413c2df9c39102accf4bc21cbc5bd9a a1a5f649aad404acfddaa979465e96581c2ce0fb 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'evolve', 'user': 'test'}
+  e308b18e59abf67245f1d9e19d26578bab7cd9c1 20885f9c44581ef505edf72a1de7c939ed3eb794 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'amend', 'user': 'test'}
+  e308b18e59abf67245f1d9e19d26578bab7cd9c1 29d63ec6339e534af5eff2c8f3f47cfac2f2c863 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '68', 'operation': 'rebase', 'user': 'test'}
+  29d63ec6339e534af5eff2c8f3f47cfac2f2c863 85cb29df3b9e7c6d08ffa7d546639c5360acc92d 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'amend', 'user': 'test'}
+  20885f9c44581ef505edf72a1de7c939ed3eb794 3ad61e93b7b0eb94c634e61fe0570cc016cf2d1b 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '12', 'operation': 'evolve', 'user': 'test'}
+  3ad61e93b7b0eb94c634e61fe0570cc016cf2d1b 9fe0112b059ea3e9b1213e4f07839b957125ffca 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '72', 'operation': 'evolve', 'user': 'test'}
+  85cb29df3b9e7c6d08ffa7d546639c5360acc92d 9fe0112b059ea3e9b1213e4f07839b957125ffca 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'evolve', 'user': 'test'}
   $ hg obslog --all
-  @    04eb6e8d253d (27) added z
-  |\     rewritten(branch, content) from 5049972c0e21 using evolve by test (Thu Jan 01 00:00:00 1970 +0000)
-  | |    amended(content) from 7e87b40e3aa8 using evolve by test (Thu Jan 01 00:00:00 1970 +0000)
+  @    9fe0112b059e (27) added z
+  |\     rewritten(branch, content) from 3ad61e93b7b0 using evolve by test (Thu Jan 01 00:00:00 1970 +0000)
+  | |    amended(content) from 85cb29df3b9e using evolve by test (Thu Jan 01 00:00:00 1970 +0000)
   | |
-  x |  5049972c0e21 (26) added z
-  | |    rewritten(parent, content) from f4c3594c72e7 using evolve by test (Thu Jan 01 00:00:00 1970 +0000)
+  x |  3ad61e93b7b0 (26) added z
+  | |    rewritten(parent, content) from 20885f9c4458 using evolve by test (Thu Jan 01 00:00:00 1970 +0000)
   | |
-  | x  7e87b40e3aa8 (25) added z
-  | |    amended(content) from da49edc17329 using amend by test (Thu Jan 01 00:00:00 1970 +0000)
+  | x  85cb29df3b9e (25) added z
+  | |    amended(content) from 29d63ec6339e using amend by test (Thu Jan 01 00:00:00 1970 +0000)
   | |
-  | x  da49edc17329 (24) added z
-  | |    rewritten(branch, parent) from 136e58088ce2 using rebase by test (Thu Jan 01 00:00:00 1970 +0000)
+  x |  20885f9c4458 (23) added z
+  | |    amended(content) from e308b18e59ab using amend by test (Thu Jan 01 00:00:00 1970 +0000)
   | |
-  x |  f4c3594c72e7 (23) added z
-  |/     amended(content) from 136e58088ce2 using amend by test (Thu Jan 01 00:00:00 1970 +0000)
+  | x  29d63ec6339e (24) added z
+  |/     rewritten(branch, parent) from e308b18e59ab using rebase by test (Thu Jan 01 00:00:00 1970 +0000)
   |
-  x  136e58088ce2 (22) added z
+  x  e308b18e59ab (22) added z
   
 
   $ cd ..
@@ -693,7 +693,7 @@
   0 files updated, 0 files merged, 1 files removed, 0 files unresolved
   1 new orphan changesets
   $ hg glog
-  o  7:cc3d0c6117c7 divergent
+  o  7:412e351c2892 divergent
   |   () [default] draft
   | *  5:88473f9137d1 child
   | |   () [default] draft
@@ -708,9 +708,9 @@
   move:[5] child
   atop:[7] divergent
   $ hg glog
-  o  8:916b4ec3b91f child
+  o  8:b361c3801668 child
   |   () [default] draft
-  o  7:cc3d0c6117c7 divergent
+  o  7:412e351c2892 divergent
   |   () [default] draft
   o  1:33c576d20069 upstream
   |   () [default] draft
@@ -719,22 +719,22 @@
   $ hg debugobsolete
   898ddd4443b3d5520bf48f22f9411d5a0751cf2e befae61385695f1ae4b78b030ad91075b2b523ef 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
   898ddd4443b3d5520bf48f22f9411d5a0751cf2e 4cc21313ecee97ce33265514a0596a192bfa6b3f 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'amend', 'user': 'test'}
-  4cc21313ecee97ce33265514a0596a192bfa6b3f bf4fe3a3afeb14c338094f41a35863921856592f 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '12', 'operation': 'evolve', 'user': 'test'}
-  befae61385695f1ae4b78b030ad91075b2b523ef cc3d0c6117c7400995107497370fa4c2138399cd 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'evolve', 'user': 'test'}
-  bf4fe3a3afeb14c338094f41a35863921856592f cc3d0c6117c7400995107497370fa4c2138399cd 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'evolve', 'user': 'test'}
-  88473f9137d12e90055d30bbb9b78dd786520870 916b4ec3b91fd03826bd4b179051ae3cee633b56 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'evolve', 'user': 'test'}
+  4cc21313ecee97ce33265514a0596a192bfa6b3f 76fca1cf64e34efb00748a6cc50d2d0b411e3039 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '12', 'operation': 'evolve', 'user': 'test'}
+  befae61385695f1ae4b78b030ad91075b2b523ef 412e351c28921f27c0f3ac678e209a9e99d9b76c 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'evolve', 'user': 'test'}
+  76fca1cf64e34efb00748a6cc50d2d0b411e3039 412e351c28921f27c0f3ac678e209a9e99d9b76c 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'evolve', 'user': 'test'}
+  88473f9137d12e90055d30bbb9b78dd786520870 b361c3801668c8ba867a32ecc2a38cfdfb582a7e 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'evolve', 'user': 'test'}
   $ hg obslog -r 'desc("divergent")' --all
-  o    cc3d0c6117c7 (7) divergent
-  |\     amended(content) from befae6138569 using evolve by test (Thu Jan 01 00:00:00 1970 +0000)
-  | |    rewritten from bf4fe3a3afeb using evolve by test (Thu Jan 01 00:00:00 1970 +0000)
+  o    412e351c2892 (7) divergent
+  |\     rewritten from 76fca1cf64e3 using evolve by test (Thu Jan 01 00:00:00 1970 +0000)
+  | |    amended(content) from befae6138569 using evolve by test (Thu Jan 01 00:00:00 1970 +0000)
   | |
-  x |  befae6138569 (3) divergent
+  x |  76fca1cf64e3 (6) divergent
+  | |    rewritten(parent, content) from 4cc21313ecee using evolve by test (Thu Jan 01 00:00:00 1970 +0000)
+  | |
+  | x  befae6138569 (3) divergent
   | |    rebased(parent) from 898ddd4443b3 using rebase by test (Thu Jan 01 00:00:00 1970 +0000)
   | |
-  | x  bf4fe3a3afeb (6) divergent
-  | |    rewritten(parent, content) from 4cc21313ecee using evolve by test (Thu Jan 01 00:00:00 1970 +0000)
-  | |
-  | x  4cc21313ecee (4) divergent
+  x |  4cc21313ecee (4) divergent
   |/     amended(content) from 898ddd4443b3 using amend by test (Thu Jan 01 00:00:00 1970 +0000)
   |
   x  898ddd4443b3 (2) divergent
--- a/tests/test-evolve-content-divergent-stack.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-evolve-content-divergent-stack.t	Fri Dec 09 15:01:59 2022 +0400
@@ -309,23 +309,23 @@
   $ hg evolve -c
   evolving 18:2ecfb60af48a "added c and newfile"
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  working directory is now at 7e8d59a0286a
+  working directory is now at e7933de77142
 
   $ hg log -p -l1
-  changeset:   21:7e8d59a0286a
+  changeset:   21:e7933de77142
   tag:         tip
   parent:      17:5907cbc074a0
   user:        test
   date:        Thu Jan 01 00:00:00 1970 +0000
   summary:     added c and newfile
   
-  diff -r 5907cbc074a0 -r 7e8d59a0286a c
+  diff -r 5907cbc074a0 -r e7933de77142 c
   --- a/c	Thu Jan 01 00:00:00 1970 +0000
   +++ b/c	Thu Jan 01 00:00:00 1970 +0000
   @@ -1,1 +1,1 @@
   -conflict
   +c
-  diff -r 5907cbc074a0 -r 7e8d59a0286a newfile
+  diff -r 5907cbc074a0 -r e7933de77142 newfile
   --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   +++ b/newfile	Thu Jan 01 00:00:00 1970 +0000
   @@ -0,0 +1,1 @@
@@ -478,31 +478,31 @@
   merge:[6] added b
   with: [11] added b
   base: [2] added b
-  rebasing "divergent" content-divergent changeset d5f148423c16 on 7e67dfb7ee31
-  rebasing "other" content-divergent changeset 6eb54b5af3fb on 7e67dfb7ee31
+  rebasing "divergent" content-divergent changeset d5f148423c16 on 4c0b67f978c2
+  rebasing "other" content-divergent changeset 6eb54b5af3fb on 4c0b67f978c2
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
   merge:[7] added c
   with: [12] added c
   base: [3] added c
-  rebasing "divergent" content-divergent changeset 3ce4be6d8e5e on 80cec1b1c90f
-  rebasing "other" content-divergent changeset 8ed612937375 on 80cec1b1c90f
+  rebasing "divergent" content-divergent changeset 3ce4be6d8e5e on c2c8d7bb6505
+  rebasing "other" content-divergent changeset 8ed612937375 on c2c8d7bb6505
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
   merge:[8] added d
   with: [13] added d
   base: [4] added d
-  rebasing "divergent" content-divergent changeset c72d2885eb51 on 7e370616fb2b
-  rebasing "other" content-divergent changeset d45f050514c2 on 7e370616fb2b
+  rebasing "divergent" content-divergent changeset c72d2885eb51 on 2d29aa40ef18
+  rebasing "other" content-divergent changeset d45f050514c2 on 2d29aa40ef18
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  working directory is now at 7e67dfb7ee31
+  working directory is now at 4c0b67f978c2
 
   $ hg glog
-  o  24:469255caf534 added d
+  o  24:4a605b2a329e added d
   |   () [default] draft
-  o  21:7e370616fb2b added c
+  o  21:2d29aa40ef18 added c
   |   () [default] draft
-  o  18:80cec1b1c90f added b
+  o  18:c2c8d7bb6505 added b
   |   () [default] draft
-  @  15:7e67dfb7ee31 watbar to a
+  @  15:4c0b67f978c2 watbar to a
   |   () [default] draft
   o  9:2228e3b74514 add newfile
   |   () [default] draft
@@ -514,7 +514,7 @@
 
   $ hg strip 14: --hidden
   0 files updated, 0 files merged, 1 files removed, 0 files unresolved
-  saved backup bundle to $TESTTMP/stackrepo1/.hg/strip-backup/7e67dfb7ee31-ff5c6a6d-backup.hg
+  saved backup bundle to $TESTTMP/stackrepo1/.hg/strip-backup/b0d57620c872-9e140417-backup.hg
   8 new content-divergent changesets
 
 Prepare repo to have merge conflicts
@@ -527,7 +527,7 @@
   rebasing "divergent" content-divergent changeset 8e222f257bbf on 2228e3b74514
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
   6 new orphan changesets
-  working directory is now at 7e67dfb7ee31
+  working directory is now at 4c0b67f978c2
   $ echo b_conflict > b
   $ hg amend -A
   adding b
@@ -537,7 +537,7 @@
   merge:[6] added b
   with: [11] added b
   base: [2] added b
-  rebasing "divergent" content-divergent changeset d5f148423c16 on c758af982013
+  rebasing "divergent" content-divergent changeset d5f148423c16 on 6b129ddb2c87
   merging b
   warning: conflicts while merging b! (edit, then use 'hg resolve --mark')
   unresolved merge conflicts
@@ -550,7 +550,7 @@
   continue: hg evolve --continue
   $ hg evolve --continue
   evolving 6:d5f148423c16 "added b"
-  rebasing "other" content-divergent changeset 6eb54b5af3fb on c758af982013
+  rebasing "other" content-divergent changeset 6eb54b5af3fb on 6b129ddb2c87
   merging b
   warning: conflicts while merging b! (edit, then use 'hg resolve --mark')
   unresolved merge conflicts
@@ -567,23 +567,23 @@
   merge:[7] added c
   with: [12] added c
   base: [3] added c
-  rebasing "divergent" content-divergent changeset 3ce4be6d8e5e on 1a79fc84e761
-  rebasing "other" content-divergent changeset 8ed612937375 on 1a79fc84e761
+  rebasing "divergent" content-divergent changeset 3ce4be6d8e5e on e55b9e217879
+  rebasing "other" content-divergent changeset 8ed612937375 on e55b9e217879
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
   merge:[8] added d
   with: [13] added d
   base: [4] added d
-  rebasing "divergent" content-divergent changeset c72d2885eb51 on 6c228f1e5409
-  rebasing "other" content-divergent changeset d45f050514c2 on 6c228f1e5409
+  rebasing "divergent" content-divergent changeset c72d2885eb51 on 0e1902cb9cef
+  rebasing "other" content-divergent changeset d45f050514c2 on 0e1902cb9cef
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ hg glog
-  o  25:957008d45543 added d
+  o  25:375c5a89ec21 added d
   |   () [default] draft
-  o  22:6c228f1e5409 added c
+  o  22:0e1902cb9cef added c
   |   () [default] draft
-  o  19:1a79fc84e761 added b
+  o  19:e55b9e217879 added b
   |   () [default] draft
-  @  16:c758af982013 watbar to a
+  @  16:6b129ddb2c87 watbar to a
   |   () [default] draft
   o  9:2228e3b74514 add newfile
   |   () [default] draft
@@ -594,7 +594,7 @@
 --------------------------------------------------------------
   $ hg strip 14: --hidden
   0 files updated, 0 files merged, 2 files removed, 0 files unresolved
-  saved backup bundle to $TESTTMP/stackrepo1/.hg/strip-backup/c758af982013-0af4fee9-backup.hg
+  saved backup bundle to $TESTTMP/stackrepo1/.hg/strip-backup/b0d57620c872-25c1f036-backup.hg
   8 new content-divergent changesets
 
 Insert conflicting changes in between the stack of content-div csets
@@ -635,8 +635,8 @@
   merge:[14] added b
   with: [17] added b
   base: [2] added b
-  rebasing "divergent" content-divergent changeset 2a955e808c53 on 7e67dfb7ee31
-  rebasing "other" content-divergent changeset 509103439e5e on 7e67dfb7ee31
+  rebasing "divergent" content-divergent changeset 2a955e808c53 on 4c0b67f978c2
+  rebasing "other" content-divergent changeset 509103439e5e on 4c0b67f978c2
   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
@@ -736,8 +736,8 @@
   merge:[14] added b
   with: [17] added b
   base: [2] added b
-  rebasing "divergent" content-divergent changeset 2a955e808c53 on 7e67dfb7ee31
-  rebasing "other" content-divergent changeset 509103439e5e on 7e67dfb7ee31
+  rebasing "divergent" content-divergent changeset 2a955e808c53 on 4c0b67f978c2
+  rebasing "other" content-divergent changeset 509103439e5e on 4c0b67f978c2
   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
@@ -751,7 +751,7 @@
   stopped the interrupted evolve
   working directory is now at 509103439e5e
   $ hg log -G
-  o  changeset:   21:7e67dfb7ee31
+  o  changeset:   21:4c0b67f978c2
   |  tag:         tip
   |  parent:      9:2228e3b74514
   |  user:        test
@@ -799,7 +799,7 @@
   +---x  changeset:   10:c04ff147ef79
   | |    user:        test
   | |    date:        Thu Jan 01 00:00:00 1970 +0000
-  | |    obsolete:    rewritten using evolve as 21:7e67dfb7ee31
+  | |    obsolete:    rewritten using evolve as 21:4c0b67f978c2
   | |    summary:     added a
   | |
   o |  changeset:   9:2228e3b74514
@@ -812,7 +812,7 @@
   |/   parent:      0:8fa14d15e168
   |    user:        test
   |    date:        Thu Jan 01 00:00:00 1970 +0000
-  |    obsolete:    rebased using evolve as 21:7e67dfb7ee31
+  |    obsolete:    rebased using evolve as 21:4c0b67f978c2
   |    summary:     watbar to a
   |
   o  changeset:   0:8fa14d15e168
@@ -821,11 +821,11 @@
      summary:     added hgignore
   
   $ hg obslog -r 'desc("watbar to a")' --all
-  o    7e67dfb7ee31 (21) watbar to a
-  |\     rewritten from 186bdc2cdfa2 using evolve by test (Thu Jan 01 00:00:00 1970 +0000)
+  o    4c0b67f978c2 (21) watbar to a
+  |\     rewritten from b0d57620c872 using evolve by test (Thu Jan 01 00:00:00 1970 +0000)
   | |    rewritten(description, content) from c04ff147ef79 using evolve by test (Thu Jan 01 00:00:00 1970 +0000)
   | |
-  x |  186bdc2cdfa2 (20) watbar to a
+  x |  b0d57620c872 (20) watbar to a
   | |    rebased(parent) from 8e222f257bbf using evolve by test (Thu Jan 01 00:00:00 1970 +0000)
   | |
   | x  c04ff147ef79 (10) added a
@@ -857,8 +857,8 @@
   merge:[14] added b
   with: [17] added b
   base: [2] added b
-  rebasing "divergent" content-divergent changeset 2a955e808c53 on 7e67dfb7ee31
-  rebasing "other" content-divergent changeset 509103439e5e on 7e67dfb7ee31
+  rebasing "divergent" content-divergent changeset 2a955e808c53 on 4c0b67f978c2
+  rebasing "other" content-divergent changeset 509103439e5e on 4c0b67f978c2
   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
@@ -874,16 +874,16 @@
   merge:[15] added c
   with: [18] added c
   base: [3] added c
-  rebasing "divergent" content-divergent changeset 48b0f803817a on ddfcba2aac91
-  rebasing "other" content-divergent changeset eaf34afe4df3 on ddfcba2aac91
+  rebasing "divergent" content-divergent changeset 48b0f803817a on 59338f08e6ef
+  rebasing "other" content-divergent changeset eaf34afe4df3 on 59338f08e6ef
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
   merge:[16] added d
   with: [19] added d
   base: [4] added d
-  rebasing "divergent" content-divergent changeset 91c8ccb9c241 on bb396302d792
-  rebasing "other" content-divergent changeset c351be27f199 on bb396302d792
+  rebasing "divergent" content-divergent changeset 91c8ccb9c241 on ef321c27d145
+  rebasing "other" content-divergent changeset c351be27f199 on ef321c27d145
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  working directory is now at ddfcba2aac91
+  working directory is now at 59338f08e6ef
 
   $ hg evolve -l
 
@@ -1018,8 +1018,8 @@
   merge:[4] c
   with: [7] c
   base: [2] c
-  rebasing "divergent" content-divergent changeset fef59171875e on bfba946a2829
-  rebasing "other" content-divergent changeset ef4885dea3da on bfba946a2829
+  rebasing "divergent" content-divergent changeset fef59171875e on 24bad874a3c7
+  rebasing "other" content-divergent changeset ef4885dea3da on 24bad874a3c7
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
 
 Expected result:
@@ -1027,15 +1027,15 @@
 Changeset with description "c" only adds file "c" with content "c".
 
   $ hg glog -l2 -p
-  o  12:a5abd6c7f9d8 c
-  |   () [default] draftdiff -r bfba946a2829 -r a5abd6c7f9d8 c
+  o  12:8a66432f9036 c
+  |   () [default] draftdiff -r 24bad874a3c7 -r 8a66432f9036 c
   |  --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   |  +++ b/c	Thu Jan 01 00:00:00 1970 +0000
   |  @@ -0,0 +1,1 @@
   |  +c
   |
-  o  9:bfba946a2829 b
-  |   () [default] draftdiff -r 980f7dc84c29 -r bfba946a2829 b
+  o  9:24bad874a3c7 b
+  |   () [default] draftdiff -r 980f7dc84c29 -r 24bad874a3c7 b
   ~  --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
      +++ b/b	Thu Jan 01 00:00:00 1970 +0000
      @@ -0,0 +1,1 @@
@@ -1121,16 +1121,16 @@
   merge:[5] added bar and car
   with: [9] added bar and car
   base: [2] added bar and car
-  rebasing "divergent" content-divergent changeset f4ed107810a7 on 3e0693d8f69b
-  rebasing "other" content-divergent changeset 7dd5b9d42ef3 on 3e0693d8f69b
+  rebasing "divergent" content-divergent changeset f4ed107810a7 on eb084588f69b
+  rebasing "other" content-divergent changeset 7dd5b9d42ef3 on eb084588f69b
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
   2 new orphan changesets
-  working directory is now at 3e0693d8f69b
+  working directory is now at eb084588f69b
 
   $ hg glog
-  o  15:5382795441b8 added bar and car
+  o  15:33947326df25 added bar and car
   |   () [default] draft
-  @  12:3e0693d8f69b added foo
+  @  12:eb084588f69b added foo
   |   () [default] draft
   | *  10:9a1f460df8b5 added dar
   | |   () [default] draft
--- a/tests/test-evolve-continue.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-evolve-continue.t	Fri Dec 09 15:01:59 2022 +0400
@@ -41,7 +41,7 @@
 
 Simple case of evolve --continue
 
-  $ hg up ca1b80f7960a
+  $ hg up 'desc("added c")'
   0 files updated, 0 files merged, 1 files removed, 0 files unresolved
   $ echo bar > d
   $ hg add d
@@ -81,7 +81,7 @@
   evolving 4:c41c793e0ef1 "added d"
 
   $ hg glog
-  o  6:2a4e03d422e2 added d
+  o  6:250d8c3c5ad9 added d
   |   () draft
   @  5:cb6a2ab625bb added c
   |   () draft
@@ -95,28 +95,86 @@
   $ hg up
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
 
+Testing hg continue for evolve
+
+  $ hg up 'desc("added b")'
+  0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+  $ echo bar > c
+  $ hg add c
+  $ hg amend
+  2 new orphan changesets
+  $ hg glog
+  @  7:8591ebad2ee8 added b
+  |   () draft
+  | *  6:250d8c3c5ad9 added d
+  | |   () draft orphan
+  | *  5:cb6a2ab625bb added c
+  | |   () draft orphan
+  | x  2:b1661037fa25 added b
+  |/    () draft
+  o  1:c7586e2a9264 added a
+  |   () draft
+  o  0:8fa14d15e168 added hgignore
+      () draft
+
+  $ hg evolve --all
+  move:[5] added c
+  atop:[7] added b
+  merging c (inmemory !)
+  hit merge conflicts; retrying merge in working copy (inmemory !)
+  merging c
+  warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
+  [240]
+
+  $ echo foo > c
+  $ hg resolve -m
+  (no more unresolved files)
+  continue: hg evolve --continue
+
+  $ hg continue
+  evolving 5:cb6a2ab625bb "added c"
+  move:[6] added d
+  atop:[8] added c
+
+  $ hg glog
+  o  9:628919fc6772 added d
+  |   () draft
+  o  8:f8d5006085c0 added c
+  |   () draft
+  @  7:8591ebad2ee8 added b
+  |   () draft
+  o  1:c7586e2a9264 added a
+  |   () draft
+  o  0:8fa14d15e168 added hgignore
+      () draft
+
+  $ hg up
+  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
 Case when conflicts resolution lead to empty wdir in evolve --continue
 
   $ echo foo > e
   $ hg ci -Aqm "added e"
   $ hg prev
   0 files updated, 0 files merged, 1 files removed, 0 files unresolved
-  [6] added d
+  [9] added d
   $ echo bar > e
   $ hg add e
   $ hg amend
   1 new orphan changesets
 
   $ hg glog
-  @  8:00a5c774cc37 added d
+  @  11:7898e026e390 added d
   |   () draft
-  | *  7:ad0a59d83efe added e
+  | *  10:5610cf0a9e66 added e
   | |   () draft orphan
-  | x  6:2a4e03d422e2 added d
+  | x  9:628919fc6772 added d
   |/    () draft
-  o  5:cb6a2ab625bb added c
+  o  8:f8d5006085c0 added c
   |   () draft
-  o  2:b1661037fa25 added b
+  o  7:8591ebad2ee8 added b
   |   () draft
   o  1:c7586e2a9264 added a
   |   () draft
@@ -124,8 +182,8 @@
       () draft
 
   $ hg evolve --update
-  move:[7] added e
-  atop:[8] added d
+  move:[10] added e
+  atop:[11] added d
   merging e (inmemory !)
   hit merge conflicts; retrying merge in working copy (inmemory !)
   merging e
@@ -141,15 +199,15 @@
   $ hg diff
 
   $ hg evolve --continue
-  evolving 7:ad0a59d83efe "added e"
-  evolution of 7:ad0a59d83efe created no changes to commit
+  evolving 10:5610cf0a9e66 "added e"
+  evolution of 10:5610cf0a9e66 created no changes to commit
 
   $ hg glog
-  @  8:00a5c774cc37 added d
+  @  11:7898e026e390 added d
   |   () draft
-  o  5:cb6a2ab625bb added c
+  o  8:f8d5006085c0 added c
   |   () draft
-  o  2:b1661037fa25 added b
+  o  7:8591ebad2ee8 added b
   |   () draft
   o  1:c7586e2a9264 added a
   |   () draft
@@ -158,7 +216,7 @@
 
 Case when there are a lot of revision to continue
 
-  $ hg up c7586e2a9264
+  $ hg up 'desc("added a")'
   0 files updated, 0 files merged, 4 files removed, 0 files unresolved
   $ echo bar > b
   $ hg add b
@@ -166,8 +224,8 @@
   3 new orphan changesets
 
   $ hg evolve --all --update
-  move:[2] added b
-  atop:[9] added a
+  move:[7] added b
+  atop:[12] added a
   merging b (inmemory !)
   hit merge conflicts; retrying merge in working copy (inmemory !)
   merging b
@@ -181,20 +239,20 @@
   (no more unresolved files)
   continue: hg evolve --continue
   $ hg evolve --continue
-  evolving 2:b1661037fa25 "added b"
-  move:[5] added c
-  atop:[10] added b
-  move:[8] added d
-  working directory is now at 6642d2c9176e
+  evolving 7:8591ebad2ee8 "added b"
+  move:[8] added c
+  atop:[13] added b
+  move:[11] added d
+  working directory is now at 0fb68c8390f6
 
   $ hg glog
-  @  12:6642d2c9176e added d
+  @  15:0fb68c8390f6 added d
   |   () draft
-  o  11:95665a2de664 added c
+  o  14:7bf9d72ff3bf added c
   |   () draft
-  o  10:87f748868183 added b
+  o  13:aaa724b65a25 added b
   |   () draft
-  o  9:53b632d203d8 added a
+  o  12:53b632d203d8 added a
   |   () draft
   o  0:8fa14d15e168 added hgignore
       () draft
@@ -205,24 +263,24 @@
   $ for ch in f g h; do echo foo > $ch; hg add $ch; hg ci -m "added "$ch; done;
 
   $ hg glog
-  @  15:09becba8f97d added h
+  @  18:1519cf722575 added h
   |   () draft
-  o  14:5aa7b2bbd944 added g
+  o  17:04c32ddd9b44 added g
   |   () draft
-  o  13:be88f889b6dc added f
+  o  16:29139ab665e3 added f
   |   () draft
-  o  12:6642d2c9176e added d
+  o  15:0fb68c8390f6 added d
   |   () draft
-  o  11:95665a2de664 added c
+  o  14:7bf9d72ff3bf added c
   |   () draft
-  o  10:87f748868183 added b
+  o  13:aaa724b65a25 added b
   |   () draft
-  o  9:53b632d203d8 added a
+  o  12:53b632d203d8 added a
   |   () draft
   o  0:8fa14d15e168 added hgignore
       () draft
 
-  $ hg up 95665a2de664
+  $ hg up 'desc("added c")'
   1 files updated, 0 files merged, 4 files removed, 0 files unresolved
 
   $ echo bar > f
@@ -232,29 +290,29 @@
   4 new orphan changesets
 
   $ hg glog
-  @  16:645135c5caa4 added c
+  @  19:ebc872a542e5 added c
   |   () draft
-  | *  15:09becba8f97d added h
+  | *  18:1519cf722575 added h
   | |   () draft orphan
-  | *  14:5aa7b2bbd944 added g
+  | *  17:04c32ddd9b44 added g
   | |   () draft orphan
-  | *  13:be88f889b6dc added f
+  | *  16:29139ab665e3 added f
   | |   () draft orphan
-  | *  12:6642d2c9176e added d
+  | *  15:0fb68c8390f6 added d
   | |   () draft orphan
-  | x  11:95665a2de664 added c
+  | x  14:7bf9d72ff3bf added c
   |/    () draft
-  o  10:87f748868183 added b
+  o  13:aaa724b65a25 added b
   |   () draft
-  o  9:53b632d203d8 added a
+  o  12:53b632d203d8 added a
   |   () draft
   o  0:8fa14d15e168 added hgignore
       () draft
 
   $ hg evolve --all --update
-  move:[12] added d
-  atop:[16] added c
-  move:[13] added f
+  move:[15] added d
+  atop:[19] added c
+  move:[16] added f
   merging f (inmemory !)
   hit merge conflicts; retrying merge in working copy (inmemory !)
   merging f
@@ -268,10 +326,10 @@
   (no more unresolved files)
   continue: hg evolve --continue
   $ hg evolve --continue
-  evolving 13:be88f889b6dc "added f"
-  move:[14] added g
-  atop:[18] added f
-  move:[15] added h
+  evolving 16:29139ab665e3 "added f"
+  move:[17] added g
+  atop:[21] added f
+  move:[18] added h
   merging h (inmemory !)
   hit merge conflicts; retrying merge in working copy (inmemory !)
   merging h
@@ -285,30 +343,30 @@
   (no more unresolved files)
   continue: hg evolve --continue
   $ hg evolve --continue
-  evolving 15:09becba8f97d "added h"
-  working directory is now at 3ba9d3d1b089
+  evolving 18:1519cf722575 "added h"
+  working directory is now at 0eb2b6434bd7
 
 Make sure, confirmopt is respected while continue
 
   $ hg glog
-  @  20:3ba9d3d1b089 added h
+  @  23:0eb2b6434bd7 added h
   |   () draft
-  o  19:981e615b14ca added g
+  o  22:d4c17c25a1c7 added g
   |   () draft
-  o  18:5794f1a3cbb2 added f
+  o  21:602e4bd1e5aa added f
   |   () draft
-  o  17:e47537da02b3 added d
+  o  20:5cf56d246d18 added d
   |   () draft
-  o  16:645135c5caa4 added c
+  o  19:ebc872a542e5 added c
   |   () draft
-  o  10:87f748868183 added b
+  o  13:aaa724b65a25 added b
   |   () draft
-  o  9:53b632d203d8 added a
+  o  12:53b632d203d8 added a
   |   () draft
   o  0:8fa14d15e168 added hgignore
       () draft
 
-  $ hg up 5794f1a3cbb2
+  $ hg up 'desc("added f")'
   1 files updated, 0 files merged, 1 files removed, 0 files unresolved
   $ echo bar > g
   $ hg add g
@@ -318,8 +376,8 @@
   $ hg evolve --all --update --confirm << EOF
   > y
   > EOF
-  move:[19] added g
-  atop:[21] added f
+  move:[22] added g
+  atop:[24] added f
   perform evolve? [Ny] y
   merging g (inmemory !)
   hit merge conflicts; retrying merge in working copy (inmemory !)
@@ -337,26 +395,26 @@
   $ hg evolve --continue << EOF
   > y
   > EOF
-  evolving 19:981e615b14ca "added g"
-  move:[20] added h
-  atop:[22] added g
+  evolving 22:d4c17c25a1c7 "added g"
+  move:[23] added h
+  atop:[25] added g
   perform evolve? [Ny] y
-  working directory is now at af6bd002a48d
+  working directory is now at cc583f773dc4
 
   $ hg glog
-  @  23:af6bd002a48d added h
+  @  26:cc583f773dc4 added h
   |   () draft
-  o  22:d2c94a8f44bd added g
+  o  25:84772f0dfa79 added g
   |   () draft
-  o  21:9849fa96c885 added f
+  o  24:d074fc123610 added f
   |   () draft
-  o  17:e47537da02b3 added d
+  o  20:5cf56d246d18 added d
   |   () draft
-  o  16:645135c5caa4 added c
+  o  19:ebc872a542e5 added c
   |   () draft
-  o  10:87f748868183 added b
+  o  13:aaa724b65a25 added b
   |   () draft
-  o  9:53b632d203d8 added a
+  o  12:53b632d203d8 added a
   |   () draft
   o  0:8fa14d15e168 added hgignore
       () draft
@@ -370,8 +428,8 @@
   2 new orphan changesets
 
   $ hg next --evolve
-  move:[22] added g
-  atop:[24] added f
+  move:[25] added g
+  atop:[27] added f
   merging g (inmemory !)
   hit merge conflicts; retrying merge in working copy (inmemory !)
   merging g
@@ -384,7 +442,7 @@
   (no more unresolved files)
   continue: hg evolve --continue
   $ hg evolve --continue
-  evolving 22:d2c94a8f44bd "added g"
+  evolving 25:84772f0dfa79 "added g"
 
 Testing that interrupted evolve don't get confused about copies (issue5930):
 ----------------------------------------------------------------------------
--- a/tests/test-evolve-inmemory.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-evolve-inmemory.t	Fri Dec 09 15:01:59 2022 +0400
@@ -103,9 +103,9 @@
   move:[5] E
   atop:[7] D
   $ hg glog
-  o  8:166afca01be8 draft tip
+  o  8:918ab8de4edf draft tip
   |  E
-  o  7:4f84a36487e4 draft
+  o  7:c9677354e977 draft
   |  D
   o  6:a2a0434af50b draft
   |  C
--- a/tests/test-evolve-interrupted.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-evolve-interrupted.t	Fri Dec 09 15:01:59 2022 +0400
@@ -135,7 +135,7 @@
   [40]
   $ hg evolve --continue
   evolving 1:e0486f65907d "banana"
-  working directory is now at bd5ec7dfc2af
+  working directory is now at b10ea0f329d2
   $ cat .hg/evolvestate
   cat: .hg/evolvestate: No such file or directory
   [1]
--- a/tests/test-evolve-noupdate.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-evolve-noupdate.t	Fri Dec 09 15:01:59 2022 +0400
@@ -116,14 +116,14 @@
   atop:[8] added a
   move:[6] added c
   move:[7] added d
-  working directory is now at 12c720cb3782
+  working directory is now at 4a58b1d0c4f3
 
   $ hg glog
-  o  11:a74d9f22ba3f added d
+  o  11:43480a2dfd57 added d
   |   () draft
-  o  10:958f5155e8cd added c
+  o  10:ed864d50e6e4 added c
   |   () draft
-  @  9:12c720cb3782 added b
+  @  9:4a58b1d0c4f3 added b
   |   () draft
   o  8:3d41537b44ca added a
   |   () draft
--- a/tests/test-evolve-order.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-evolve-order.t	Fri Dec 09 15:01:59 2022 +0400
@@ -95,13 +95,13 @@
   atop:[11] asecond
   move:[6] add _c
   move:[7] add _d
-  working directory is now at 739f18ac1d03
+  working directory is now at 225d2cc5d3fc
   $ hg log -G
-  @  14:739f18ac1d03@default(draft) add _d
+  @  14:225d2cc5d3fc@default(draft) add _d
   |
-  o  13:e5960578d158@default(draft) add _c
+  o  13:0fc229278e4d@default(draft) add _c
   |
-  o  12:4ad33fa88946@default(draft) bprime
+  o  12:c3741b9eafae@default(draft) bprime
   |
   o  11:9a584314f3f3@default(draft) asecond
   |
@@ -124,21 +124,21 @@
   1 changesets pruned
   1 new orphan changesets
   $ hg log -G -r "desc(_d)::"
-  @  21:dcf786e878fd@default(draft) add c1second
+  @  21:a329855d0bc1@default(draft) add c1second
   |
-  | *  20:507d52d715f6@default(draft) add c2prime
+  | *  20:072276ece1bf@default(draft) add c2prime
   | |
-  | x  19:c995cb124ddc@default(draft) add c1prime
+  | x  19:f137acd06692@default(draft) add c1prime
   |/
-  | *  18:d096a2437fd0@default(draft) add c4_
+  | *  18:0a1d9b2ce733@default(draft) add c4_
   | |
-  | *  17:cde95c6cba7a@default(draft) add c3_
+  | *  17:e2874f41c56c@default(draft) add c3_
   | |
-  | x  16:e0d9f7a099fe@default(draft) add c2_
+  | x  16:3247c33339fa@default(draft) add c2_
   | |
-  | x  15:43b7c338b1f8@default(draft) add c1_
+  | x  15:df322257c182@default(draft) add c1_
   |/
-  o  14:739f18ac1d03@default(draft) add _d
+  o  14:225d2cc5d3fc@default(draft) add _d
   |
   ~
 
@@ -154,33 +154,33 @@
   1 changesets pruned
 
   $ hg log -G -r "desc(_d)::"
-  @  27:b253ff5b65d1@default(draft) add b3prime
+  @  27:ba4c348b6d5e@default(draft) add b3prime
   |
-  o  26:4acf61f11dfb@default(draft) add b1prime
+  o  26:8fe985f5d0aa@default(draft) add b1prime
   |
-  | *  25:594e1fbbd61f@default(draft) add b4_
+  | *  25:1d9ba2e75c93@default(draft) add b4_
   | |
-  | x  24:be27500cfc76@default(draft) add b3_
+  | x  24:aec6a9657b6c@default(draft) add b3_
   | |
-  | x  23:b54f77dc5831@default(draft) add b2_
+  | x  23:a69b58575918@default(draft) add b2_
   | |
-  | x  22:0e1eba27e9aa@default(draft) add b1_
+  | x  22:3564eb18e448@default(draft) add b1_
   |/
-  | o  21:dcf786e878fd@default(draft) add c1second
+  | o  21:a329855d0bc1@default(draft) add c1second
   |/
-  | *  20:507d52d715f6@default(draft) add c2prime
+  | *  20:072276ece1bf@default(draft) add c2prime
   | |
-  | x  19:c995cb124ddc@default(draft) add c1prime
+  | x  19:f137acd06692@default(draft) add c1prime
   |/
-  | *  18:d096a2437fd0@default(draft) add c4_
+  | *  18:0a1d9b2ce733@default(draft) add c4_
   | |
-  | *  17:cde95c6cba7a@default(draft) add c3_
+  | *  17:e2874f41c56c@default(draft) add c3_
   | |
-  | x  16:e0d9f7a099fe@default(draft) add c2_
+  | x  16:3247c33339fa@default(draft) add c2_
   | |
-  | x  15:43b7c338b1f8@default(draft) add c1_
+  | x  15:df322257c182@default(draft) add c1_
   |/
-  o  14:739f18ac1d03@default(draft) add _d
+  o  14:225d2cc5d3fc@default(draft) add _d
   |
   ~
 
@@ -188,7 +188,7 @@
   $ echo "(desc(_d)::) - desc(c3_)"
   (desc(_d)::) - desc(c3_)
   $ hg evolve --rev "(desc(_d)::) - desc(c3_)"
-  skipping d096a2437fd0, consider including orphan ancestors
+  skipping 0a1d9b2ce733, consider including orphan ancestors
   move:[20] add c2prime
   atop:[21] add c1second
   move:[25] add b4_
@@ -199,23 +199,23 @@
   move:[17] add c3_
   atop:[28] add c2prime
   move:[18] add c4_
-  working directory is now at 35e7b797ace5
+  working directory is now at 4ee8feb52325
   $ hg log -G -r "desc(_d)::"
-  @  31:35e7b797ace5@default(draft) add c4_
+  @  31:4ee8feb52325@default(draft) add c4_
   |
-  o  30:0b9488394e89@default(draft) add c3_
+  o  30:08a530ce67e1@default(draft) add c3_
   |
-  | o  29:ea93190a9cd1@default(draft) add b4_
+  | o  29:4897c8ed7645@default(draft) add b4_
   | |
-  o |  28:881b9c092e53@default(draft) add c2prime
+  o |  28:3abc7618dd5f@default(draft) add c2prime
   | |
-  | o  27:b253ff5b65d1@default(draft) add b3prime
+  | o  27:ba4c348b6d5e@default(draft) add b3prime
   | |
-  | o  26:4acf61f11dfb@default(draft) add b1prime
+  | o  26:8fe985f5d0aa@default(draft) add b1prime
   | |
-  o |  21:dcf786e878fd@default(draft) add c1second
+  o |  21:a329855d0bc1@default(draft) add c1second
   |/
-  o  14:739f18ac1d03@default(draft) add _d
+  o  14:225d2cc5d3fc@default(draft) add _d
   |
   ~
 
@@ -244,4 +244,4 @@
   $ hg evolve --rev "orphan()"
   move:[29] add b4_
   atop:[34] b3second
-  skipping 0b9488394e89: divergent rewriting. can't choose destination
+  skipping 08a530ce67e1: divergent rewriting. can't choose destination
--- a/tests/test-evolve-orphan-merge.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-evolve-orphan-merge.t	Fri Dec 09 15:01:59 2022 +0400
@@ -217,10 +217,10 @@
   continue: hg evolve --continue
   $ hg evolve --continue
   evolving 10:fd41d25a3e90 "foobar to c"
-  working directory is now at c5405d2da7a1
+  working directory is now at 6b3ccba26ce3
 
   $ hg glog
-  @    12:c5405d2da7a1 foobar to c
+  @    12:6b3ccba26ce3 foobar to c
   |\    () draft
   | o  11:31c317b7bdb1 foo to c
   | |   () draft
@@ -230,7 +230,7 @@
       () draft
 
   $ hg parents
-  changeset:   12:c5405d2da7a1
+  changeset:   12:6b3ccba26ce3
   tag:         tip
   parent:      9:d0f84b25d4e3
   parent:      11:31c317b7bdb1
@@ -249,7 +249,7 @@
   $ hg glog
   @  13:928097d0b5b5 foo to c
   |   () draft
-  | *    12:c5405d2da7a1 foobar to c
+  | *    12:6b3ccba26ce3 foobar to c
   | |\    () draft orphan
   +---x  11:31c317b7bdb1 foo to c
   | |     () draft
@@ -273,11 +273,11 @@
   continue: hg evolve --continue
 
   $ hg evolve --continue
-  evolving 12:c5405d2da7a1 "foobar to c"
-  working directory is now at dc1948a6eeab
+  evolving 12:6b3ccba26ce3 "foobar to c"
+  working directory is now at 6feadc8fabd5
 
   $ hg glog
-  @    14:dc1948a6eeab foobar to c
+  @    14:6feadc8fabd5 foobar to c
   |\    () draft
   | o  13:928097d0b5b5 foo to c
   | |   () draft
@@ -289,7 +289,7 @@
 3) When stabilizing other changesets resulted in orphan merge changeset
 -----------------------------------------------------------------------
 
-  $ hg prune -r d0f84b25d4e3 -r 928097d0b5b5 -r dc1948a6eeab
+  $ hg prune -r d0f84b25d4e3 -r 928097d0b5b5 -r 6feadc8fabd5
   0 files updated, 0 files merged, 1 files removed, 0 files unresolved
   working directory is now at 8fa14d15e168
   3 changesets pruned
--- a/tests/test-evolve-phase-divergence.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-evolve-phase-divergence.t	Fri Dec 09 15:01:59 2022 +0400
@@ -756,21 +756,21 @@
   recreate:[14] y to y and foobar to foo
   atop:[12] y to y and foobar to foo
   rebasing to destination parent: 2352021b3785
-  committed as 8c2bb6fb44e9
-  working directory is now at 8c2bb6fb44e9
+  committed as ec66af49a1a6
+  working directory is now at ec66af49a1a6
 
   $ hg exp
   # HG changeset patch
   # User test
   # Date 0 0
   #      Thu Jan 01 00:00:00 1970 +0000
-  # Node ID 8c2bb6fb44e9443c64b3a2a3d061272c8e25e6ce
+  # Node ID ec66af49a1a643ef308fe11697c59c4920d2bd9e
   # Parent  dc88f5aa9bc90a6418899d267d9524205dfb429b
   phase-divergent update to dc88f5aa9bc9:
   
   y to y and foobar to foo
   
-  diff -r dc88f5aa9bc9 -r 8c2bb6fb44e9 y
+  diff -r dc88f5aa9bc9 -r ec66af49a1a6 y
   --- a/y	Thu Jan 01 00:00:00 1970 +0000
   +++ b/y	Thu Jan 01 00:00:00 1970 +0000
   @@ -1,1 +1,1 @@
@@ -778,7 +778,7 @@
   +foo
 
   $ hg glog
-  @  16:8c2bb6fb44e9 phase-divergent update to dc88f5aa9bc9:
+  @  16:ec66af49a1a6 phase-divergent update to dc88f5aa9bc9:
   |   () draft
   o  12:dc88f5aa9bc9 y to y and foobar to foo
   |   () public
@@ -806,7 +806,7 @@
   $ echo l > l
   $ hg ci -Aqm "added l to l"
   $ hg rebase -r . -d .^^^^
-  rebasing 17:f3794e5a91dc tip "added l to l"
+  rebasing 17:c7c3e834e653 tip "added l to l"
   $ echo kl > l
   $ echo foo > x
   $ hg add x
@@ -824,21 +824,21 @@
   b1a0e143e32be800ff6a5c2cd6c77823652c901b 0 {502e737366322886cf628276aa0a2796904453b4} (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'evolve', 'user': 'test'}
   dc88f5aa9bc90a6418899d267d9524205dfb429b 211ab84d1689507465ecf708fea540e9867d5fda 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
   211ab84d1689507465ecf708fea540e9867d5fda 13015a180eee523ba9950f18683762a77f560f3d 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'amend', 'user': 'test'}
-  13015a180eee523ba9950f18683762a77f560f3d 7687d2968b3e2697f955beac2da24ee879950cb9 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'evolve', 'user': 'test'}
-  7687d2968b3e2697f955beac2da24ee879950cb9 8c2bb6fb44e9443c64b3a2a3d061272c8e25e6ce 1 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '13', 'operation': 'evolve', 'user': 'test'}
-  f3794e5a91dc1d4d36fee5c423386b19433a1f48 2bfd56949cf0a3abfbf9881254a88fe07b336ddb 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
-  2bfd56949cf0a3abfbf9881254a88fe07b336ddb 5fd38c0de46ec31f0bb1904b5909802bc4bcb47e 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'amend', 'user': 'test'}
+  13015a180eee523ba9950f18683762a77f560f3d 7c9c658a311a5194f4826f91ae667b151263d192 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'evolve', 'user': 'test'}
+  7c9c658a311a5194f4826f91ae667b151263d192 ec66af49a1a643ef308fe11697c59c4920d2bd9e 1 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '13', 'operation': 'evolve', 'user': 'test'}
+  c7c3e834e6538706672e2b5387a27efda6e0f00f 5c0ff97e7b93a7510a08eaf8ae3821448255963d 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'}
+  5c0ff97e7b93a7510a08eaf8ae3821448255963d 4c2ba1e0fc47842138814c7e5dc64392bdf2d70e 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'amend', 'user': 'test'}
   $ hg obslog -r .
-  @  5fd38c0de46e (19) added l to l
-  |    amended(content) from 2bfd56949cf0 using amend by test (Thu Jan 01 00:00:00 1970 +0000)
+  @  4c2ba1e0fc47 (19) added l to l
+  |    amended(content) from 5c0ff97e7b93 using amend by test (Thu Jan 01 00:00:00 1970 +0000)
   |
-  x  2bfd56949cf0 (18) added l to l
-  |    rebased(parent) from f3794e5a91dc using rebase by test (Thu Jan 01 00:00:00 1970 +0000)
+  x  5c0ff97e7b93 (18) added l to l
+  |    rebased(parent) from c7c3e834e653 using rebase by test (Thu Jan 01 00:00:00 1970 +0000)
   |
-  x  f3794e5a91dc (17) added l to l
+  x  c7c3e834e653 (17) added l to l
   
 
-  $ hg phase -r f3794e5a91dc --public --hidden
+  $ hg phase -r c7c3e834e653 --public --hidden
   1 new phase-divergent changesets
 
 Resolution using `hg evolve --phase-divergent`
@@ -847,7 +847,7 @@
   $ hg evolve --phase-divergent --update
   recreate:[19] added l to l
   atop:[17] added l to l
-  rebasing to destination parent: 8c2bb6fb44e9
+  rebasing to destination parent: ec66af49a1a6
   merging x
   warning: conflicts while merging x! (edit, then use 'hg resolve --mark')
   unresolved merge conflicts
@@ -855,20 +855,20 @@
   [240]
 
   $ hg diff
-  diff -r 8c2bb6fb44e9 l
+  diff -r ec66af49a1a6 l
   --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   +++ b/l	Thu Jan 01 00:00:00 1970 +0000
   @@ -0,0 +1,1 @@
   +kl
-  diff -r 8c2bb6fb44e9 x
+  diff -r ec66af49a1a6 x
   --- a/x	Thu Jan 01 00:00:00 1970 +0000
   +++ b/x	Thu Jan 01 00:00:00 1970 +0000
   @@ -1,1 +1,5 @@
-  +<<<<<<< destination: 8c2bb6fb44e9 - test: phase-divergent update to dc88f5aa9...
+  +<<<<<<< destination: ec66af49a1a6 - test: phase-divergent update to dc88f5aa9...
    x
   +=======
   +foo
-  +>>>>>>> evolving:    5fd38c0de46e - test: added l to l
+  +>>>>>>> evolving:    4c2ba1e0fc47 - test: added l to l
 
   $ echo foo > x
 
@@ -877,16 +877,16 @@
   continue: hg evolve --continue
 
   $ hg evolve --continue
-  evolving 19:5fd38c0de46e "added l to l"
-  committed as e3090241a10c
-  working directory is now at e3090241a10c
+  evolving 19:4c2ba1e0fc47 "added l to l"
+  committed as 4a3e0e3f88ca
+  working directory is now at 4a3e0e3f88ca
 
   $ hg glog
-  @  21:e3090241a10c phase-divergent update to f3794e5a91dc:
+  @  21:4a3e0e3f88ca phase-divergent update to c7c3e834e653:
   |   () draft
-  o  17:f3794e5a91dc added l to l
+  o  17:c7c3e834e653 added l to l
   |   () public
-  o  16:8c2bb6fb44e9 phase-divergent update to dc88f5aa9bc9:
+  o  16:ec66af49a1a6 phase-divergent update to dc88f5aa9bc9:
   |   () public
   o  12:dc88f5aa9bc9 y to y and foobar to foo
   |   () public
@@ -910,19 +910,19 @@
   # User test
   # Date 0 0
   #      Thu Jan 01 00:00:00 1970 +0000
-  # Node ID e3090241a10c320b6132e4673915fd6b19c0de39
-  # Parent  f3794e5a91dc1d4d36fee5c423386b19433a1f48
-  phase-divergent update to f3794e5a91dc:
+  # Node ID 4a3e0e3f88ca7c24f3b9f54abfbb49a314fe4c0b
+  # Parent  c7c3e834e6538706672e2b5387a27efda6e0f00f
+  phase-divergent update to c7c3e834e653:
   
   added l to l
   
-  diff -r f3794e5a91dc -r e3090241a10c l
+  diff -r c7c3e834e653 -r 4a3e0e3f88ca l
   --- a/l	Thu Jan 01 00:00:00 1970 +0000
   +++ b/l	Thu Jan 01 00:00:00 1970 +0000
   @@ -1,1 +1,1 @@
   -l
   +kl
-  diff -r f3794e5a91dc -r e3090241a10c x
+  diff -r c7c3e834e653 -r 4a3e0e3f88ca x
   --- a/x	Thu Jan 01 00:00:00 1970 +0000
   +++ b/x	Thu Jan 01 00:00:00 1970 +0000
   @@ -1,1 +1,1 @@
@@ -933,7 +933,7 @@
 ------------------------------------------------------------------------
 
   $ hg glog -r .
-  @  21:e3090241a10c phase-divergent update to f3794e5a91dc:
+  @  21:4a3e0e3f88ca phase-divergent update to c7c3e834e653:
   |   () draft
   ~
   $ echo f > f
@@ -947,44 +947,44 @@
 
   $ hg evolve --list
 
-  $ hg phase -r 428f7900a969 --public --hidden
+  $ hg phase -r 898734e41932 --public --hidden
   1 new phase-divergent changesets
 
-  $ hg glog -r f3794e5a91dc::
-  @  24:390acb97e50a added f
+  $ hg glog -r c7c3e834e653::
+  @  24:5dfcf4a7c095 added f
   |   () draft
-  | o  23:428f7900a969 added g
+  | o  23:898734e41932 added g
   | |   () public
-  | o  22:21ae52e414e6 added f
+  | o  22:54c60ee8ecb8 added f
   |/    () public
-  o  21:e3090241a10c phase-divergent update to f3794e5a91dc:
+  o  21:4a3e0e3f88ca phase-divergent update to c7c3e834e653:
   |   () public
-  o  17:f3794e5a91dc added l to l
+  o  17:c7c3e834e653 added l to l
   |   () public
   ~
 
   $ hg evolve --list
-  390acb97e50a: added f
-    phase-divergent: 21ae52e414e6 (immutable precursor)
-    phase-divergent: 428f7900a969 (immutable precursor)
+  5dfcf4a7c095: added f
+    phase-divergent: 54c60ee8ecb8 (immutable precursor)
+    phase-divergent: 898734e41932 (immutable precursor)
   
 Resolving phase divergence using `hg evolve`
 
   $ hg evolve --phase-divergent --all
   recreate:[24] added f
   atop:[23] added g
-  rebasing to destination parent: 21ae52e414e6
+  rebasing to destination parent: 54c60ee8ecb8
   no changes to commit
-  working directory is now at e3090241a10c
+  working directory is now at 4a3e0e3f88ca
 
-  $ hg glog -r f3794e5a91dc::
-  o  23:428f7900a969 added g
+  $ hg glog -r c7c3e834e653::
+  o  23:898734e41932 added g
   |   () public
-  o  22:21ae52e414e6 added f
+  o  22:54c60ee8ecb8 added f
   |   () public
-  @  21:e3090241a10c phase-divergent update to f3794e5a91dc:
+  @  21:4a3e0e3f88ca phase-divergent update to c7c3e834e653:
   |   () public
-  o  17:f3794e5a91dc added l to l
+  o  17:c7c3e834e653 added l to l
   |   () public
   ~
 
@@ -1315,13 +1315,13 @@
   recreate:[4] added n
   atop:[1] added m and n
   rebasing to destination parent: d3873e73d99e
-  committed as 88b0dae5369a
-  working directory is now at 88b0dae5369a
+  committed as 0f21d47fe960
+  working directory is now at 0f21d47fe960
 
   $ hg glog --hidden
-  @  7:88b0dae5369a phase-divergent update to a51bce62c219:
+  @  7:0f21d47fe960 phase-divergent update to a51bce62c219:
   |   () draft
-  | x  6:98dad8812511 added n
+  | x  6:302a3ecef922 added n
   | |   () draft
   +---o  5:86419909e017 phase-divergent update to a51bce62c219:
   | |     () draft
@@ -1340,25 +1340,25 @@
   a51bce62c219f024bc0ae0cc0e3957ee77d7cb46 4f25cd9cd2bf15bc83316e91fbcb93489ea15a75 e1154ec0206ac05c3765f7bd1337e3b96db2974f 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '13', 'operation': 'prune', 'user': 'test'}
   e1154ec0206ac05c3765f7bd1337e3b96db2974f 52ca78bb98c71222f8afae28d48ae6cfd44a60c9 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'amend', 'user': 'test'}
   4f25cd9cd2bf15bc83316e91fbcb93489ea15a75 86419909e01787959aa6471aee605c6d604a3e0d 1 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '13', 'operation': 'evolve', 'user': 'test'}
-  52ca78bb98c71222f8afae28d48ae6cfd44a60c9 98dad881251146cd171f53b2a5b7fc3a371f820e 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'evolve', 'user': 'test'}
-  98dad881251146cd171f53b2a5b7fc3a371f820e 88b0dae5369aaa3bceb6c0b647542594e2c72fb7 1 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '13', 'operation': 'evolve', 'user': 'test'}
+  52ca78bb98c71222f8afae28d48ae6cfd44a60c9 302a3ecef922d617073b8e96d3e0f15ab7a6d30d 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'evolve', 'user': 'test'}
+  302a3ecef922d617073b8e96d3e0f15ab7a6d30d 0f21d47fe96059e134fd230d6d1623ff1d541963 1 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '13', 'operation': 'evolve', 'user': 'test'}
   $ hg obslog -r a51bce62c219 --all
-  o  86419909e017 (5) phase-divergent update to a51bce62c219:
-  |    rewritten(description, parent, content) from 4f25cd9cd2bf using evolve by test (Thu Jan 01 00:00:00 1970 +0000)
+  @  0f21d47fe960 (7) phase-divergent update to a51bce62c219:
+  |    rewritten(description, parent, content) from 302a3ecef922 using evolve by test (Thu Jan 01 00:00:00 1970 +0000)
   |
-  | @  88b0dae5369a (7) phase-divergent update to a51bce62c219:
-  | |    rewritten(description, parent, content) from 98dad8812511 using evolve by test (Thu Jan 01 00:00:00 1970 +0000)
+  | o  86419909e017 (5) phase-divergent update to a51bce62c219:
+  | |    rewritten(description, parent, content) from 4f25cd9cd2bf using evolve by test (Thu Jan 01 00:00:00 1970 +0000)
   | |
-  x |  4f25cd9cd2bf (2) added m
+  x |  302a3ecef922 (6) added n
+  | |    rebased(parent) from 52ca78bb98c7 using evolve by test (Thu Jan 01 00:00:00 1970 +0000)
+  | |
+  | x  4f25cd9cd2bf (2) added m
   | |    split(description, parent, content) from a51bce62c219 using prune by test (Thu Jan 01 00:00:00 1970 +0000)
   | |
-  | x  98dad8812511 (6) added n
-  | |    rebased(parent) from 52ca78bb98c7 using evolve by test (Thu Jan 01 00:00:00 1970 +0000)
-  | |
-  | x  52ca78bb98c7 (4) added n
+  x |  52ca78bb98c7 (4) added n
   | |    amended(content) from e1154ec0206a using amend by test (Thu Jan 01 00:00:00 1970 +0000)
   | |
-  | x  e1154ec0206a (3) added n
+  x |  e1154ec0206a (3) added n
   |/     split(description, parent, content) from a51bce62c219 using prune by test (Thu Jan 01 00:00:00 1970 +0000)
   |
   o  a51bce62c219 (1) added m and n
@@ -1383,23 +1383,23 @@
   -n
 
 XXX: not sure this is correct
-  $ hg exp 88b0dae5369a
+  $ hg exp 0f21d47fe960
   # HG changeset patch
   # User test
   # Date 0 0
   #      Thu Jan 01 00:00:00 1970 +0000
-  # Node ID 88b0dae5369aaa3bceb6c0b647542594e2c72fb7
+  # Node ID 0f21d47fe96059e134fd230d6d1623ff1d541963
   # Parent  a51bce62c219f024bc0ae0cc0e3957ee77d7cb46
   phase-divergent update to a51bce62c219:
   
   added n
   
-  diff -r a51bce62c219 -r 88b0dae5369a m
+  diff -r a51bce62c219 -r 0f21d47fe960 m
   --- a/m	Thu Jan 01 00:00:00 1970 +0000
   +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   @@ -1,1 +0,0 @@
   -m
-  diff -r a51bce62c219 -r 88b0dae5369a n
+  diff -r a51bce62c219 -r 0f21d47fe960 n
   --- a/n	Thu Jan 01 00:00:00 1970 +0000
   +++ b/n	Thu Jan 01 00:00:00 1970 +0000
   @@ -1,1 +1,1 @@
--- a/tests/test-evolve-phase.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-evolve-phase.t	Fri Dec 09 15:01:59 2022 +0400
@@ -128,7 +128,7 @@
   evolving 2:13833940840c "c"
 
   $ hg glog
-  o  4 - 3d2080c198e5 c (secret)
+  o  4 - 82e9fa5a553a c (secret)
   |
   @  3 - 87495ea7c9ec b (draft)
   |
--- a/tests/test-evolve-progress.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-evolve-progress.t	Fri Dec 09 15:01:59 2022 +0400
@@ -149,11 +149,11 @@
   obscache is out of date
   move:[6] third
   atop:[11] second
-  hg rebase -r 53c0008d98a0 -d 60a86497fbfe
+  hg rebase -r 53c0008d98a0 -d c8caf623f57b
   evolve: 2/3 changesets (66.67%)
   resolving manifests
    branchmerge: True, force: True, partial: False
-   ancestor: 5f16d91ecde0, local: 60a86497fbfe+, remote: 53c0008d98a0
+   ancestor: 5f16d91ecde0, local: c8caf623f57b+, remote: 53c0008d98a0
    b: remote created -> g
   getting b
   updating: b 1/1 files (100.00%)
@@ -162,11 +162,11 @@
   committing manifest
   committing changelog
   move:[7] fourth
-  hg rebase -r 385376d04062 -d b2de95304e32
+  hg rebase -r 385376d04062 -d 55f7ff45dec4
   evolve: 3/3 changesets (100.00%)
   resolving manifests
    branchmerge: True, force: True, partial: False
-   ancestor: 53c0008d98a0, local: b2de95304e32+, remote: 385376d04062
+   ancestor: 53c0008d98a0, local: 55f7ff45dec4+, remote: 385376d04062
    b: remote is newer -> g
   getting b
   updating: b 1/1 files (100.00%)
@@ -180,7 +180,7 @@
   invalid branch cache (served.hidden): tip differs
   resolving manifests
    branchmerge: False, force: False, partial: False
-   ancestor: c6e6fdb1d046, local: c6e6fdb1d046+, remote: f8d7d38c0a88
+   ancestor: 1edc3bac9e3c, local: 1edc3bac9e3c+, remote: f8d7d38c0a88
    b: other deleted -> r
   removing b
   updating: b 1/2 files (50.00%)
--- a/tests/test-evolve-public-content-divergent-corner-cases.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-evolve-public-content-divergent-corner-cases.t	Fri Dec 09 15:01:59 2022 +0400
@@ -137,14 +137,14 @@
   base: [2] added c
   rebasing "other" content-divergent changeset f5f9b4fc8b77 on c9241b0f2d5b
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  committed as 0941937e8302
-  working directory is now at 0941937e8302
+  committed as a3019c73de83
+  working directory is now at a3019c73de83
 
   $ hg glog -p
-  @  8:0941937e8302 phase-divergent update to c0d7ee6604ea:
+  @  8:a3019c73de83 phase-divergent update to c0d7ee6604ea:
   |   draft
   |
-  |  diff -r c0d7ee6604ea -r 0941937e8302 c
+  |  diff -r c0d7ee6604ea -r a3019c73de83 c
   |  --- a/c	Thu Jan 01 00:00:00 1970 +0000
   |  +++ b/c	Thu Jan 01 00:00:00 1970 +0000
   |  @@ -1,1 +1,2 @@
@@ -432,7 +432,7 @@
   $ hg sum
   parent: 5:93cd84bbdaca 
    added d
-  parent: 6:2af3359250d3 tip (content-divergent)
+  parent: 6:cf77846279b4 tip (content-divergent)
    added c e
   branch: default
   commit: 1 modified, 1 unknown, 1 unresolved (merge)
@@ -447,27 +447,27 @@
   continue: hg evolve --continue
 
   $ hg evolve --continue
-  committed as bb4d94ae1a5a
-  working directory is now at bb4d94ae1a5a
+  committed as 01169b149789
+  working directory is now at 01169b149789
 
   $ hg export
   # HG changeset patch
   # User test
   # Date 0 0
   #      Thu Jan 01 00:00:00 1970 +0000
-  # Node ID bb4d94ae1a5ac031ba524ef30850f32b9b50a560
+  # Node ID 01169b149789f09d81f86d5273e56671ab645590
   # Parent  93cd84bbdacaeb8f881c29a609dbdd30c38cbc57
   phase-divergent update to 93cd84bbdaca:
   
   added c e
   
-  diff -r 93cd84bbdaca -r bb4d94ae1a5a d
+  diff -r 93cd84bbdaca -r 01169b149789 d
   --- a/d	Thu Jan 01 00:00:00 1970 +0000
   +++ b/d	Thu Jan 01 00:00:00 1970 +0000
   @@ -1,1 +1,1 @@
   -dd
   +resolved
-  diff -r 93cd84bbdaca -r bb4d94ae1a5a e
+  diff -r 93cd84bbdaca -r 01169b149789 e
   --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   +++ b/e	Thu Jan 01 00:00:00 1970 +0000
   @@ -0,0 +1,1 @@
--- a/tests/test-evolve-public-content-divergent-discard.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-evolve-public-content-divergent-discard.t	Fri Dec 09 15:01:59 2022 +0400
@@ -397,7 +397,7 @@
   $ hg evolve --continue
   evolving 4:f89a8e2f86ac "added dh"
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  other divergent changeset bc309da55b88 has same content as local e800202333a4 and differs by "description" only, discarding bc309da55b88
+  other divergent changeset 50a1c208f59e has same content as local e800202333a4 and differs by "description" only, discarding 50a1c208f59e
 
   $ hg evolve -l
 
@@ -617,7 +617,7 @@
   continue: hg evolve --continue
 
   $ hg evolve --continue
-  other divergent changeset 09054d1f3c97 has same content as local e800202333a4 and differs by "description" only, discarding 09054d1f3c97
+  other divergent changeset 573a0455bb00 has same content as local e800202333a4 and differs by "description" only, discarding 573a0455bb00
 
   $ hg evolve -l
 
--- a/tests/test-evolve-public-content-divergent-main.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-evolve-public-content-divergent-main.t	Fri Dec 09 15:01:59 2022 +0400
@@ -392,20 +392,20 @@
   $ hg evolve --continue
   evolving 4:f31bcc378766 "added d c e"
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  committed as 4bce4ff71bf9
-  working directory is now at 4bce4ff71bf9
+  committed as e247c56b4c01
+  working directory is now at e247c56b4c01
   $ hg export
   # HG changeset patch
   # User test
   # Date 0 0
   #      Thu Jan 01 00:00:00 1970 +0000
-  # Node ID 4bce4ff71bf901840aebb0aa87716e878938b55e
+  # Node ID e247c56b4c0103b53448551b3e5ff9a8173be791
   # Parent  93cd84bbdacaeb8f881c29a609dbdd30c38cbc57
   phase-divergent update to 93cd84bbdaca:
   
   added d c e
   
-  diff -r 93cd84bbdaca -r 4bce4ff71bf9 e
+  diff -r 93cd84bbdaca -r e247c56b4c01 e
   --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   +++ b/e	Thu Jan 01 00:00:00 1970 +0000
   @@ -0,0 +1,1 @@
@@ -627,7 +627,7 @@
   continue: hg evolve --continue
 
   $ hg evolve --continue
-  committed as ba823b8ff683
+  committed as 704cf6f2d22f
 
   $ hg evolve -l
   $ cd ..
--- a/tests/test-evolve-stop-orphan.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-evolve-stop-orphan.t	Fri Dec 09 15:01:59 2022 +0400
@@ -48,7 +48,7 @@
 
   $ hg evolve --stop
   abort: no interrupted evolve to stop
-  [255]
+  [20]
 
 Testing with wrong combinations of flags
 ========================================
@@ -220,9 +220,9 @@
   continue: hg evolve --continue
   $ hg evolve --continue
   evolving 4:c41c793e0ef1 "added d"
-  working directory is now at 2a4e03d422e2
+  working directory is now at 250d8c3c5ad9
   $ hg glog
-  @  6:2a4e03d422e2 added d
+  @  6:250d8c3c5ad9 added d
   |   () draft
   o  5:cb6a2ab625bb added c
   |   () draft
@@ -243,7 +243,7 @@
   $ hg glog
   @  7:21817cd42526 added hgignore
       () draft
-  *  6:2a4e03d422e2 added d
+  *  6:250d8c3c5ad9 added d
   |   () draft orphan
   *  5:cb6a2ab625bb added c
   |   () draft orphan
@@ -283,7 +283,7 @@
   |   () draft
   @  7:21817cd42526 added hgignore
       () draft
-  *  6:2a4e03d422e2 added d
+  *  6:250d8c3c5ad9 added d
   |   () draft orphan
   *  5:cb6a2ab625bb added c
   |   () draft orphan
@@ -316,9 +316,9 @@
   move:[6] added d
   atop:[10] added c
   $ hg glog
-  o  11:cd0909a30222 added d
+  o  11:4b77e6973234 added d
   |   () draft
-  o  10:cb1dd1086ef6 added c
+  o  10:b4e2f43191a0 added c
   |   () draft
   o  9:aec285328e90 added b
   |   () draft
@@ -340,9 +340,9 @@
   $ hg bookmark b2
 
   $ hg glog
-  o  11:cd0909a30222 added d
+  o  11:4b77e6973234 added d
   |   () draft
-  o  10:cb1dd1086ef6 added c
+  o  10:b4e2f43191a0 added c
   |   (b1) draft
   @  9:aec285328e90 added b
   |   (b2) draft
@@ -361,9 +361,9 @@
   $ hg glog
   @  12:a3cc2042492f added a
   |   () draft
-  | *  11:cd0909a30222 added d
+  | *  11:4b77e6973234 added d
   | |   () draft orphan
-  | *  10:cb1dd1086ef6 added c
+  | *  10:b4e2f43191a0 added c
   | |   (b1) draft orphan
   | *  9:aec285328e90 added b
   | |   (b2) draft orphan
@@ -394,9 +394,9 @@
   |   (b2) draft
   @  12:a3cc2042492f added a
   |   () draft
-  | *  11:cd0909a30222 added d
+  | *  11:4b77e6973234 added d
   | |   () draft orphan
-  | *  10:cb1dd1086ef6 added c
+  | *  10:b4e2f43191a0 added c
   | |   (b1) draft orphan
   | x  9:aec285328e90 added b
   | |   () draft
--- a/tests/test-evolve-topic.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-evolve-topic.t	Fri Dec 09 15:01:59 2022 +0400
@@ -128,9 +128,9 @@
   move:[s3] add eee
   atop:[s2] add ddd
   move:[s4] add fff
-  working directory is now at 070c5573d8f9
+  working directory is now at ad43ddbeead9
   $ hg log -G
-  @  13 - {foo} 070c5573d8f9 add fff (draft)
+  @  13 - {foo} ad43ddbeead9 add fff (draft)
   |
   o  12 - {foo} 42b49017ff90 add eee (draft)
   |
@@ -166,17 +166,17 @@
   move:[7] add hhh
   move:[8] add iii
   move:[9] add jjj
-  working directory is now at 9bf430c106b7
+  working directory is now at fed0f67a2171
   $ hg log -G
-  @  17 - {bar} 9bf430c106b7 add jjj (draft)
+  @  17 - {bar} fed0f67a2171 add jjj (draft)
   |
-  o  16 - {bar} d2dc89c57700 add iii (draft)
+  o  16 - {bar} 94e899639b23 add iii (draft)
   |
-  o  15 - {bar} 20bc4d02aa62 add hhh (draft)
+  o  15 - {bar} 55e5cd2b6cd6 add hhh (draft)
   |
-  o  14 - {bar} 16d6f664b17c add ggg (draft)
+  o  14 - {bar} 56107a7ddeaf add ggg (draft)
   |
-  o  13 - {foo} 070c5573d8f9 add fff (draft)
+  o  13 - {foo} ad43ddbeead9 add fff (draft)
   |
   o  12 - {foo} 42b49017ff90 add eee (draft)
   |
@@ -227,15 +227,15 @@
 Testing when instability is involved
 
   $ hg log -G
-  o  17 - {bar} 9bf430c106b7 add jjj (draft)
+  o  17 - {bar} fed0f67a2171 add jjj (draft)
   |
-  o  16 - {bar} d2dc89c57700 add iii (draft)
+  o  16 - {bar} 94e899639b23 add iii (draft)
   |
-  o  15 - {bar} 20bc4d02aa62 add hhh (draft)
+  o  15 - {bar} 55e5cd2b6cd6 add hhh (draft)
   |
-  o  14 - {bar} 16d6f664b17c add ggg (draft)
+  o  14 - {bar} 56107a7ddeaf add ggg (draft)
   |
-  o  13 - {foo} 070c5573d8f9 add fff (draft)
+  o  13 - {foo} ad43ddbeead9 add fff (draft)
   |
   @  12 - {foo} 42b49017ff90 add eee (draft)
   |
@@ -247,12 +247,12 @@
   |
   o  0 - {} 199cc73e9a0b add aaa (draft)
   
-  $ hg topic -r 070c5573d8f9 bar
+  $ hg topic -r ad43ddbeead9 bar
   4 new orphan changesets
   changed topic on 1 changesets to "bar"
   $ hg log -r 18 -T '{rev}: {join(extras, " ")}\n'
-  18: _rewrite_noise=[0-9a-f]+ amend_source=[0-9a-f]+ branch=default rebase_source=[0-9a-f]+ topic=bar (re)
-  $ hg up 16d6f664b17c
+  18: _rewrite_noise=[0-9a-f]+ branch=default rebase_source=[0-9a-f]+ topic=bar (re)
+  $ hg up 56107a7ddeaf
   switching to topic bar
   2 files updated, 0 files merged, 0 files removed, 0 files unresolved
 
@@ -274,17 +274,17 @@
 ------------------------------------------------------------------------------
 
   $ hg log --graph
-  @  18 - {bar} c80027c7cda1 add fff (draft)
+  @  18 - {bar} 8dde0971132d add fff (draft)
   |
-  | *  17 - {bar} 9bf430c106b7 add jjj (draft)
+  | *  17 - {bar} fed0f67a2171 add jjj (draft)
   | |
-  | *  16 - {bar} d2dc89c57700 add iii (draft)
+  | *  16 - {bar} 94e899639b23 add iii (draft)
   | |
-  | *  15 - {bar} 20bc4d02aa62 add hhh (draft)
+  | *  15 - {bar} 55e5cd2b6cd6 add hhh (draft)
   | |
-  | *  14 - {bar} 16d6f664b17c add ggg (draft)
+  | *  14 - {bar} 56107a7ddeaf add ggg (draft)
   | |
-  | x  13 - {foo} 070c5573d8f9 add fff (draft)
+  | x  13 - {foo} ad43ddbeead9 add fff (draft)
   |/
   o  12 - {foo} 42b49017ff90 add eee (draft)
   |
@@ -303,24 +303,24 @@
 
 When the current topic, obsoleted changesets topic and successor topic are same
 
-  $ hg up 20bc4d02aa62
+  $ hg up 55e5cd2b6cd6
   2 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ echo foobar >> hhh
   $ hg amend
-  $ hg up 20bc4d02aa62
+  $ hg up 55e5cd2b6cd6
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  working directory parent is obsolete! (20bc4d02aa62)
-  (use 'hg evolve' to update to its successor: d834582d9ee3)
+  working directory parent is obsolete! (55e5cd2b6cd6)
+  (use 'hg evolve' to update to its successor: 604c23b08613)
   $ hg log -Gr 14::
-  *  19 - {bar} d834582d9ee3 add hhh (draft)
+  *  19 - {bar} 604c23b08613 add hhh (draft)
   |
-  | *  17 - {bar} 9bf430c106b7 add jjj (draft)
+  | *  17 - {bar} fed0f67a2171 add jjj (draft)
   | |
-  | *  16 - {bar} d2dc89c57700 add iii (draft)
+  | *  16 - {bar} 94e899639b23 add iii (draft)
   | |
-  | @  15 - {bar} 20bc4d02aa62 add hhh (draft)
+  | @  15 - {bar} 55e5cd2b6cd6 add hhh (draft)
   |/
-  *  14 - {bar} 16d6f664b17c add ggg (draft)
+  *  14 - {bar} 56107a7ddeaf add ggg (draft)
   |
   ~
 
@@ -331,33 +331,33 @@
 When the current topic and successors topic are same, but obsolete cset has
 different topic
 
-  $ hg rebase -s d2dc89c57700 -d d834582d9ee3 --config extensions.rebase=
-  rebasing 16:d2dc89c57700 bar "add iii"
+  $ hg rebase -s 94e899639b23 -d 604c23b08613 --config extensions.rebase=
+  rebasing 16:94e899639b23 bar "add iii"
   1 new orphan changesets
-  rebasing 17:9bf430c106b7 bar "add jjj"
+  rebasing 17:fed0f67a2171 bar "add jjj"
   1 new orphan changesets
   $ hg log -Gr 42b49017ff90::
-  *  21 - {bar} 7542e76aba2c add jjj (draft)
+  *  21 - {bar} 573bbc059289 add jjj (draft)
   |
-  *  20 - {bar} 7858bd7e9906 add iii (draft)
+  *  20 - {bar} 8e94e3065186 add iii (draft)
   |
-  *  19 - {bar} d834582d9ee3 add hhh (draft)
+  *  19 - {bar} 604c23b08613 add hhh (draft)
   |
-  | o  18 - {bar} c80027c7cda1 add fff (draft)
+  | o  18 - {bar} 8dde0971132d add fff (draft)
   | |
-  @ |  14 - {bar} 16d6f664b17c add ggg (draft)
+  @ |  14 - {bar} 56107a7ddeaf add ggg (draft)
   | |
-  x |  13 - {foo} 070c5573d8f9 add fff (draft)
+  x |  13 - {foo} ad43ddbeead9 add fff (draft)
   |/
   o  12 - {foo} 42b49017ff90 add eee (draft)
   |
   ~
 
-  $ hg up 070c5573d8f9
+  $ hg up ad43ddbeead9
   switching to topic foo
   0 files updated, 0 files merged, 1 files removed, 0 files unresolved
-  working directory parent is obsolete! (070c5573d8f9)
-  (use 'hg evolve' to update to its successor: c80027c7cda1)
+  working directory parent is obsolete! (ad43ddbeead9)
+  (use 'hg evolve' to update to its successor: 8dde0971132d)
 
   $ hg topic bar
 
@@ -369,7 +369,7 @@
 When current topic and obsolete cset topic are same but successor has different
 one
 
-  $ hg up 070c5573d8f9
+  $ hg up ad43ddbeead9
   switching to topic foo
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ hg prev
@@ -392,17 +392,17 @@
   $ hg ci --amend
   4 new orphan changesets
   $ hg log -G
-  @  26 - {bar} 239dcab64bc0 add fff (draft)
+  @  26 - {bar} 235873f1950b add fff (draft)
   |
-  | *  25 - {bar} e49f8682fb23 add jjj (draft)
+  | *  25 - {bar} ed0b505ff189 add jjj (draft)
   | |
-  | *  24 - {bar} 318094e157e3 add iii (draft)
+  | *  24 - {bar} 50b1b9387d50 add iii (draft)
   | |
-  | *  23 - {bar} aa8b0df2da21 add hhh (draft)
+  | *  23 - {bar} 0d4bb3a72a5b add hhh (draft)
   | |
-  | *  22 - {bar} 310e9f9bceb1 add ggg (draft)
+  | *  22 - {bar} 548702c1d91c add ggg (draft)
   | |
-  | x  18 - {bar} c80027c7cda1 add fff (draft)
+  | x  18 - {bar} 8dde0971132d add fff (draft)
   |/
   o  12 - {foo} 42b49017ff90 add eee (draft)
   |
@@ -428,7 +428,7 @@
   (no more unresolved files)
   continue: hg evolve --continue
   $ hg evolve --continue
-  evolving 23:aa8b0df2da21 "add hhh"
+  evolving 23:0d4bb3a72a5b "add hhh"
   move:[s4] add iii
   atop:[s3] add hhh
   move:[s5] add jjj
@@ -441,13 +441,13 @@
   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: 239dcab64bc0)
+  (hidden revision '6a6b7365c751' was rewritten as: 235873f1950b)
   working directory parent is obsolete! (6a6b7365c751)
-  (use 'hg evolve' to update to its successor: 239dcab64bc0)
+  (use 'hg evolve' to update to its successor: 235873f1950b)
 
 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 239dcab64bc0
+  working directory is now at 235873f1950b
--- a/tests/test-evolve.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-evolve.t	Fri Dec 09 15:01:59 2022 +0400
@@ -400,7 +400,7 @@
 
 phase change turning obsolete changeset public issues a phase divergence warning
 
-  $ hg phase --hidden --public 99833d22b0c6
+  $ hg phase --hidden --public 5c9c8d9c2e4e
   1 new phase-divergent changesets
 
 all solving phase-divergent
@@ -408,7 +408,7 @@
   $ glog
   @  6:47d52a103155@default(draft) another feature that rox
   |
-  | o  5:99833d22b0c6@default(public) another feature (child of ba0ec09b1bab)
+  | o  5:5c9c8d9c2e4e@default(public) another feature (child of ba0ec09b1bab)
   |/
   o  4:ba0ec09b1bab@default(public) a nifty feature
   |
@@ -417,19 +417,19 @@
   $ hg evolve --any --traceback --phase-divergent
   recreate:[6] another feature that rox
   atop:[5] another feature (child of ba0ec09b1bab)
-  committed as aca219761afb
-  working directory is now at aca219761afb
+  committed as acecd63a9288
+  working directory is now at acecd63a9288
   $ glog
-  @  7:aca219761afb@default(draft) phase-divergent update to 99833d22b0c6:
+  @  7:acecd63a9288@default(draft) phase-divergent update to 5c9c8d9c2e4e:
   |
-  o  5:99833d22b0c6@default(public) another feature (child of ba0ec09b1bab)
+  o  5:5c9c8d9c2e4e@default(public) another feature (child of ba0ec09b1bab)
   |
   o  4:ba0ec09b1bab@default(public) a nifty feature
   |
   o  0:e55e0562ee93@default(public) base
   
-  $ hg diff --hidden -r aca219761afb -r 47d52a103155
-  $ hg diff -r aca219761afb^ -r aca219761afb
+  $ hg diff --hidden -r acecd63a9288 -r 47d52a103155
+  $ hg diff -r acecd63a9288^ -r acecd63a9288
   diff --git a/main-file-1 b/main-file-1
   --- a/main-file-1
   +++ b/main-file-1
@@ -443,7 +443,7 @@
   $ hg commit -m 'dansk 2!'
   $ sed -i'' -e s/Three/tre/ main-file-1
   $ hg commit -m 'dansk 3!'
-  $ hg update aca219761afb
+  $ hg update acecd63a9288
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ sed -i'' -e s/Un/Én/ main-file-1
   $ hg commit --amend -m 'dansk!'
@@ -475,17 +475,17 @@
   $ hg evolve -n --config 'command-templates.oneline-summary = custom {rev} {desc}'
   move:custom 8 dansk 2!
   atop:custom 10 dansk!
-  hg rebase -r 569625323d3e -d 9975c016fe7b
-  skipping 8163b3ed62c7, consider including orphan ancestors
+  hg rebase -r bdb9adf2959a -d 74d61108f94b
+  skipping 3db99d6b500c, consider including orphan ancestors
 
 command-templates.oneline-summary is respected when evolving/updating working copy
 
   $ hg co -q 7
-  working directory parent is obsolete! (aca219761afb)
+  working directory parent is obsolete! (acecd63a9288)
   $ hg evolve --no-all --config 'command-templates.oneline-summary = custom {rev} {desc}'
   update:custom 10 dansk!
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  working directory is now at 9975c016fe7b
+  working directory is now at 74d61108f94b
 
   $ hg evolve --all --traceback
   move:[8] dansk 2!
@@ -872,11 +872,11 @@
   2 changesets folded
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ glog
-  @  13:284c0d45770d@default(draft) Folding with custom commit message
+  @  13:90308a3a84bd@default(draft) Folding with custom commit message
   |
-  o  10:9975c016fe7b@default(draft) dansk!
+  o  10:74d61108f94b@default(draft) dansk!
   |
-  o  5:99833d22b0c6@default(public) another feature (child of ba0ec09b1bab)
+  o  5:5c9c8d9c2e4e@default(public) another feature (child of ba0ec09b1bab)
   |
   o  4:ba0ec09b1bab@default(public) a nifty feature
   |
@@ -891,9 +891,9 @@
   2 changesets folded
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ hg qlog
-  14 - 8693d0f277b8 A longer
+  14 - c07a8bc54a51 A longer
                     commit message (draft)
-  5 - 99833d22b0c6 another feature (child of ba0ec09b1bab) (public)
+  5 - 5c9c8d9c2e4e another feature (child of ba0ec09b1bab) (public)
   4 - ba0ec09b1bab a nifty feature (public)
   0 - e55e0562ee93 base (public)
 
@@ -1009,13 +1009,13 @@
   $ ls .hg/bookmarks*
   .hg/bookmarks
   $ glog
-  o  10:d952e93add6f@mybranch(draft) a2
+  o  10:f37ed7a60f43@mybranch(draft) a2
   |
   @  9:9f8b83c2e7f3@default(draft) a1__
   |
-  | *  8:777c26ca5e78@mybranch(draft) a3
+  | *  8:c7661e655801@mybranch(draft) a3
   | |
-  | x  7:eb07e22a0e63@mybranch(draft) a2
+  | x  7:5406c5cfee42@mybranch(draft) a2
   | |
   | x  6:faafc6cea0ba@default(draft) a1_
   |/
@@ -1024,7 +1024,7 @@
 
 Possibility to select what instability to solve first, asking for
 phase-divergent before content-divergent
-  $ hg revert -r d952e93add6f --all
+  $ hg revert -r f37ed7a60f43 --all
   reverting a
   $ hg log -G --template '{rev} [{branch}] {desc|firstline}\n'
   o  10 [mybranch] a2
@@ -1042,7 +1042,7 @@
   $ echo "hello world" > newfile
   $ hg add newfile
   $ hg commit -m "add new file bumped" -o 10
-  $ hg phase --public --hidden d952e93add6f
+  $ hg phase --public --hidden f37ed7a60f43
   1 new phase-divergent changesets
   $ hg log -G
   @  11	: add new file bumped - test
@@ -1081,17 +1081,17 @@
   $ hg evolve -r "desc('add new file bumped')" --phase-divergent
   recreate:[11] add new file bumped
   atop:[10] a2
-  committed as a8bb31d4b7f2
-  working directory is now at a8bb31d4b7f2
+  committed as db294883bd68
+  working directory is now at db294883bd68
   $ hg evolve --any
   move:[8] a3
-  atop:[12] phase-divergent update to d952e93add6f:
+  atop:[12] phase-divergent update to f37ed7a60f43:
   $ glog
-  o  13:b88539ad24d7@default(draft) a3
+  o  13:0210bf7b6518@default(draft) a3
   |
-  @  12:a8bb31d4b7f2@default(draft) phase-divergent update to d952e93add6f:
+  @  12:db294883bd68@default(draft) phase-divergent update to f37ed7a60f43:
   |
-  o  10:d952e93add6f@mybranch(public) a2
+  o  10:f37ed7a60f43@mybranch(public) a2
   |
   o  9:9f8b83c2e7f3@default(public) a1__
   |
@@ -1099,14 +1099,14 @@
   
 
 Check that we can resolve instabilities in a revset with more than one commit
-  $ hg up b88539ad24d7 -C
+  $ hg up 0210bf7b6518 -C
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ mkcommit gg
-  $ hg up b88539ad24d7
+  $ hg up 0210bf7b6518
   0 files updated, 0 files merged, 1 files removed, 0 files unresolved
   $ mkcommit gh
   created new head
-  $ hg up b88539ad24d7
+  $ hg up 0210bf7b6518
   0 files updated, 0 files merged, 1 files removed, 0 files unresolved
   $ printf "newline\nnewline\n" >> a
   $ hg log -G
@@ -1116,7 +1116,7 @@
   |/
   @  13	: a3 - test
   |
-  o  12	: phase-divergent update to d952e93add6f: - test
+  o  12	: phase-divergent update to f37ed7a60f43: - test
   |
   o  10	: a2 - test
   |
@@ -1127,17 +1127,17 @@
   $ hg amend
   2 new orphan changesets
   $ glog
-  @  16:0cf3707e8971@default(draft) a3
+  @  16:5478ae0ce2d9@default(draft) a3
   |
-  | *  15:daa1ff1c7fbd@default(draft) add gh
+  | *  15:fb5702c4d3e6@default(draft) add gh
   | |
-  | | *  14:484fb3cfa7f2@default(draft) add gg
+  | | *  14:148850890f43@default(draft) add gg
   | |/
-  | x  13:b88539ad24d7@default(draft) a3
+  | x  13:0210bf7b6518@default(draft) a3
   |/
-  o  12:a8bb31d4b7f2@default(draft) phase-divergent update to d952e93add6f:
+  o  12:db294883bd68@default(draft) phase-divergent update to f37ed7a60f43:
   |
-  o  10:d952e93add6f@mybranch(public) a2
+  o  10:f37ed7a60f43@mybranch(public) a2
   |
   o  9:9f8b83c2e7f3@default(public) a1__
   |
@@ -1145,29 +1145,29 @@
   
 
 Evolving an empty revset should do nothing
-  $ hg evolve --rev "daa1ff1c7fbd and 484fb3cfa7f2"
+  $ hg evolve --rev "fb5702c4d3e6 and 148850890f43"
   set of specified revisions is empty
   [1]
 
-  $ hg evolve --rev "b88539ad24d7::" --phase-divergent
+  $ hg evolve --rev "0210bf7b6518::" --phase-divergent
   no phasedivergent changesets in specified revisions
   (do you want to use --orphan)
   [2]
-  $ hg evolve --rev "b88539ad24d7::" --orphan
+  $ hg evolve --rev "0210bf7b6518::" --orphan
   move:[14] add gg
   atop:[16] a3
   move:[15] add gh
   atop:[16] a3
   $ glog
-  o  18:0c049e4e5422@default(draft) add gh
+  o  18:5f8a4fc86068@default(draft) add gh
   |
-  | o  17:98e171e2f272@default(draft) add gg
+  | o  17:a38ac764661b@default(draft) add gg
   |/
-  @  16:0cf3707e8971@default(draft) a3
+  @  16:5478ae0ce2d9@default(draft) a3
   |
-  o  12:a8bb31d4b7f2@default(draft) phase-divergent update to d952e93add6f:
+  o  12:db294883bd68@default(draft) phase-divergent update to f37ed7a60f43:
   |
-  o  10:d952e93add6f@mybranch(public) a2
+  o  10:f37ed7a60f43@mybranch(public) a2
   |
   o  9:9f8b83c2e7f3@default(public) a1__
   |
@@ -1204,19 +1204,19 @@
 
   $ hg --hidden up 14
   2 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  updated to hidden changeset 484fb3cfa7f2
-  (hidden revision '484fb3cfa7f2' was rewritten as: 98e171e2f272)
-  working directory parent is obsolete! (484fb3cfa7f2)
+  updated to hidden changeset 148850890f43
+  (hidden revision '148850890f43' was rewritten as: a38ac764661b)
+  working directory parent is obsolete! (148850890f43)
   $ cat >> $HGRCPATH <<EOF
   > [experimental]
   > evolutioncommands=evolve
   > EOF
   $ hg --hidden up 15
   1 files updated, 0 files merged, 1 files removed, 0 files unresolved
-  updated to hidden changeset daa1ff1c7fbd
-  (hidden revision 'daa1ff1c7fbd' was rewritten as: 0c049e4e5422)
-  working directory parent is obsolete! (daa1ff1c7fbd)
-  (use 'hg evolve' to update to its successor: 0c049e4e5422)
+  updated to hidden changeset fb5702c4d3e6
+  (hidden revision 'fb5702c4d3e6' was rewritten as: 5f8a4fc86068)
+  working directory parent is obsolete! (fb5702c4d3e6)
+  (use 'hg evolve' to update to its successor: 5f8a4fc86068)
 
 Restore all of the evolution features
 
@@ -1226,7 +1226,7 @@
   > EOF
 
 Check hg evolve --rev on singled out commit
-  $ hg up 98e171e2f272 -C
+  $ hg up a38ac764661b -C
   2 files updated, 0 files merged, 1 files removed, 0 files unresolved
   $ mkcommit j1
   $ mkcommit j2
@@ -1237,28 +1237,28 @@
   $ hg add j4
   $ hg amend
   2 new orphan changesets
-  $ glog -r "0cf3707e8971::"
-  @  22:274b6cd0c101@default(draft) add j1
+  $ glog -r "5478ae0ce2d9::"
+  @  22:cc75952078c6@default(draft) add j1
   |
-  | *  21:89e4f7e8feb5@default(draft) add j3
+  | *  21:677a629bd09c@default(draft) add j3
   | |
-  | *  20:4cd61236beca@default(draft) add j2
+  | *  20:0208ef487f3a@default(draft) add j2
   | |
-  | x  19:0fd8bfb02de4@default(draft) add j1
+  | x  19:30d3ac01aa58@default(draft) add j1
   |/
-  | o  18:0c049e4e5422@default(draft) add gh
+  | o  18:5f8a4fc86068@default(draft) add gh
   | |
-  o |  17:98e171e2f272@default(draft) add gg
+  o |  17:a38ac764661b@default(draft) add gg
   |/
-  o  16:0cf3707e8971@default(draft) a3
+  o  16:5478ae0ce2d9@default(draft) a3
   |
   ~
 
-  $ hg evolve --rev 89e4f7e8feb5 --any
+  $ hg evolve --rev 677a629bd09c --any
   abort: cannot specify both "--rev" and "--any"
   [255]
-  $ hg evolve --rev 89e4f7e8feb5
-  skipping 89e4f7e8feb5, consider including orphan ancestors
+  $ hg evolve --rev 677a629bd09c
+  skipping 677a629bd09c, consider including orphan ancestors
 
 Check that uncommit respects the allowunstable option
 With only createmarkers we can only uncommit on a head
@@ -1266,38 +1266,38 @@
   > [experimental]
   > evolution=createmarkers, allnewcommands
   > EOF
-  $ hg up 274b6cd0c101^
+  $ hg up cc75952078c6^
   0 files updated, 0 files merged, 2 files removed, 0 files unresolved
   $ hg uncommit --all
   abort: cannot uncommit changeset, as that will orphan 4 descendants
   (see 'hg help evolution.instability')
   [10]
-  $ hg up 274b6cd0c101
+  $ hg up cc75952078c6
   2 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ hg uncommit --all
   new changeset is empty
   (use 'hg prune .' to remove it)
-  $ glog -r "0cf3707e8971::"
-  @  23:0ef9ff75f8e2@default(draft) add j1
+  $ glog -r "5478ae0ce2d9::"
+  @  23:4086309bffa5@default(draft) add j1
   |
-  | *  21:89e4f7e8feb5@default(draft) add j3
+  | *  21:677a629bd09c@default(draft) add j3
   | |
-  | *  20:4cd61236beca@default(draft) add j2
+  | *  20:0208ef487f3a@default(draft) add j2
   | |
-  | x  19:0fd8bfb02de4@default(draft) add j1
+  | x  19:30d3ac01aa58@default(draft) add j1
   |/
-  | o  18:0c049e4e5422@default(draft) add gh
+  | o  18:5f8a4fc86068@default(draft) add gh
   | |
-  o |  17:98e171e2f272@default(draft) add gg
+  o |  17:a38ac764661b@default(draft) add gg
   |/
-  o  16:0cf3707e8971@default(draft) a3
+  o  16:5478ae0ce2d9@default(draft) a3
   |
   ~
 
 Check that prune respects the allowunstable option
   $ hg up -C .
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  $ hg up 0c049e4e5422
+  $ hg up 5f8a4fc86068
   1 files updated, 0 files merged, 1 files removed, 0 files unresolved
   $ hg evolve --all
   nothing to evolve on current working copy parent
@@ -1307,42 +1307,42 @@
   move:[20] add j2
   atop:[23] add j1
   move:[21] add j3
-  $ glog -r "0cf3707e8971::"
-  o  25:0d9203b74542@default(draft) add j3
+  $ glog -r "5478ae0ce2d9::"
+  o  25:bc61f0de3ab8@default(draft) add j3
   |
-  o  24:f1b85956c48c@default(draft) add j2
+  o  24:57c9733eb876@default(draft) add j2
   |
-  o  23:0ef9ff75f8e2@default(draft) add j1
+  o  23:4086309bffa5@default(draft) add j1
   |
-  | @  18:0c049e4e5422@default(draft) add gh
+  | @  18:5f8a4fc86068@default(draft) add gh
   | |
-  o |  17:98e171e2f272@default(draft) add gg
+  o |  17:a38ac764661b@default(draft) add gg
   |/
-  o  16:0cf3707e8971@default(draft) a3
+  o  16:5478ae0ce2d9@default(draft) a3
   |
   ~
-  $ hg up 98e171e2f272
+  $ hg up a38ac764661b
   1 files updated, 0 files merged, 1 files removed, 0 files unresolved
   $ mkcommit c5_
   created new head
-  $ hg prune '0ef9ff75f8e2 + f1b85956c48c'
+  $ hg prune '4086309bffa5 + 57c9733eb876'
   abort: cannot prune changeset, as that will orphan 1 descendants
   (see 'hg help evolution.instability')
   [10]
-  $ hg prune '98e171e2f272::0d9203b74542'
+  $ hg prune 'a38ac764661b::bc61f0de3ab8'
   abort: cannot prune changeset, as that will orphan 1 descendants
   (see 'hg help evolution.instability')
   [10]
-  $ hg prune '0ef9ff75f8e2::'
+  $ hg prune '4086309bffa5::'
   3 changesets pruned
-  $ glog -r "0cf3707e8971::"
-  @  26:4c6f6f6d1976@default(draft) add c5_
+  $ glog -r "5478ae0ce2d9::"
+  @  26:0ea0aab97a68@default(draft) add c5_
   |
-  | o  18:0c049e4e5422@default(draft) add gh
+  | o  18:5f8a4fc86068@default(draft) add gh
   | |
-  o |  17:98e171e2f272@default(draft) add gg
+  o |  17:a38ac764661b@default(draft) add gg
   |/
-  o  16:0cf3707e8971@default(draft) a3
+  o  16:5478ae0ce2d9@default(draft) a3
   |
   ~
 
@@ -1350,24 +1350,24 @@
 
 (most of this has been moved to test-fold.t)
 
-  $ hg up 0cf3707e8971
+  $ hg up 5478ae0ce2d9
   0 files updated, 0 files merged, 2 files removed, 0 files unresolved
   $ mkcommit unstableifparentisfolded
   created new head
-  $ glog -r "0cf3707e8971::"
-  @  27:2d1b55e10be9@default(draft) add unstableifparentisfolded
+  $ glog -r "5478ae0ce2d9::"
+  @  27:a590ee1f960d@default(draft) add unstableifparentisfolded
   |
-  | o  26:4c6f6f6d1976@default(draft) add c5_
+  | o  26:0ea0aab97a68@default(draft) add c5_
   | |
-  +---o  18:0c049e4e5422@default(draft) add gh
+  +---o  18:5f8a4fc86068@default(draft) add gh
   | |
-  | o  17:98e171e2f272@default(draft) add gg
+  | o  17:a38ac764661b@default(draft) add gg
   |/
-  o  16:0cf3707e8971@default(draft) a3
+  o  16:5478ae0ce2d9@default(draft) a3
   |
   ~
 
-  $ hg fold --exact "98e171e2f272::"
+  $ hg fold --exact "a38ac764661b::"
   2 changesets folded
 
 Check that dirstate changes are kept at failure for conflicts (issue4966)
@@ -1391,20 +1391,20 @@
   $ hg add newlyadded
   $ hg commit -m "will cause conflict at evolve"
 
-  $ glog -r "0cf3707e8971::"
-  @  31:5be050657ca5@default(draft) will cause conflict at evolve
+  $ glog -r "5478ae0ce2d9::"
+  @  31:835945a2b5c1@default(draft) will cause conflict at evolve
   |
-  o  30:748126f98ff1@default(draft) will be evolved safely
+  o  30:c4fb0d23465b@default(draft) will be evolved safely
   |
-  o  29:4548f3a8db2c@default(draft) will be amended
+  o  29:45e2cc1499ee@default(draft) will be amended
   |
-  | o  28:92ca6f3984de@default(draft) add gg
+  | o  28:7992c4aad71c@default(draft) add gg
   | |
-  o |  27:2d1b55e10be9@default(draft) add unstableifparentisfolded
+  o |  27:a590ee1f960d@default(draft) add unstableifparentisfolded
   |/
-  | o  18:0c049e4e5422@default(draft) add gh
+  | o  18:5f8a4fc86068@default(draft) add gh
   |/
-  o  16:0cf3707e8971@default(draft) a3
+  o  16:5478ae0ce2d9@default(draft) a3
   |
   ~
 
@@ -1426,17 +1426,17 @@
   [240]
 
   $ glog -r "desc('add unstableifparentisfolded')::" --hidden
-  @  33:b9acdb1af6d5@default(draft) will be evolved safely
+  @  33:bdb2d79645eb@default(draft) will be evolved safely
   |
-  o  32:6ec468e4cb98@default(draft) amended
+  o  32:d788a38aecda@default(draft) amended
   |
-  | %  31:5be050657ca5@default(draft) will cause conflict at evolve
+  | %  31:835945a2b5c1@default(draft) will cause conflict at evolve
   | |
-  | x  30:748126f98ff1@default(draft) will be evolved safely
+  | x  30:c4fb0d23465b@default(draft) will be evolved safely
   | |
-  | x  29:4548f3a8db2c@default(draft) will be amended
+  | x  29:45e2cc1499ee@default(draft) will be amended
   |/
-  o  27:2d1b55e10be9@default(draft) add unstableifparentisfolded
+  o  27:a590ee1f960d@default(draft) add unstableifparentisfolded
   |
   ~
 
--- a/tests/test-extension-isolation.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-extension-isolation.t	Fri Dec 09 15:01:59 2022 +0400
@@ -134,6 +134,7 @@
     _exttopics_heads
     ext-topics-publish=all
     topics
+    topics-namespaces
   $ hg debugcapabilities http://$LOCALIP:$HGPORT/repo-no-ext | egrep 'topics|evoext'
   [1]
 
@@ -148,6 +149,7 @@
     _exttopics_heads
     ext-topics-publish=all
     topics
+    topics-namespaces
   $ hg debugcapabilities http://$LOCALIP:$HGPORT/repo-evo | egrep 'topics|evoext'
     _evoext_getbundle_obscommon
     _evoext_obshashrange_v1
@@ -155,6 +157,7 @@
     _exttopics_heads
     ext-topics-publish=all
     topics
+    topics-namespaces
   $ hg debugcapabilities http://$LOCALIP:$HGPORT/repo-evo | egrep 'topics|evoext'
     _evoext_getbundle_obscommon
     _evoext_obshashrange_v1
--- a/tests/test-fixup.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-fixup.t	Fri Dec 09 15:01:59 2022 +0400
@@ -271,6 +271,43 @@
   1 files updated, 0 files merged, 2 files removed, 0 files unresolved
   working directory is now at fed7e534b3bb
 
+testing continue command
+
+  $ hg up -r 'desc("baz")'
+  3 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ echo 'not foo' > foo
+
+  $ hg fixup -r 'desc("update foo")'
+  merging foo
+  warning: conflicts while merging foo! (edit, then use 'hg resolve --mark')
+  unresolved merge conflicts
+  (see 'hg help evolve.interrupted')
+  [240]
+  $ echo 'bonjour fixed' > foo
+  $ hg resolve --mark foo
+  (no more unresolved files)
+  continue: hg fixup --continue
+
+  $ hg continue
+  evolving 14:6b0b1270d7dd "temporary fixup commit"
+
+  $ hg glog
+  o  16:0dd54868f420 update foo
+  |   () draft
+  | @  14:6b0b1270d7dd temporary fixup commit
+  | |   () secret
+  | o  9:12b5e442244f baz
+  | |   () secret
+  | o  5:2eec5320cfc7 bar
+  |/    (bm) draft
+  o  0:e63c23eaa88a foo
+      () draft
+
+  $ hg evolve
+  update:[16] update foo
+  1 files updated, 0 files merged, 2 files removed, 0 files unresolved
+  working directory is now at 0dd54868f420
+
 amending a descendant of wdp
 
   $ hg up 0
@@ -279,11 +316,11 @@
   $ hg add foobar
   $ hg fixup -r 'desc(baz)'
   $ hg glog
-  o  16:b50fd0850076 baz
+  o  19:b50fd0850076 baz
   |   () secret
-  | @  14:4a9c4d14d447 temporary fixup commit
+  | @  17:4a9c4d14d447 temporary fixup commit
   | |   () draft
-  | | o  13:fed7e534b3bb update foo
+  | | o  16:0dd54868f420 update foo
   | |/    () draft
   o |  5:2eec5320cfc7 bar
   |/    (bm) draft
@@ -291,14 +328,14 @@
       () draft
 
   $ hg evolve
-  update:[16] baz
+  update:[19] baz
   2 files updated, 0 files merged, 0 files removed, 0 files unresolved
   working directory is now at b50fd0850076
 
   $ hg glog
-  @  16:b50fd0850076 baz
+  @  19:b50fd0850076 baz
   |   () secret
-  | o  13:fed7e534b3bb update foo
+  | o  16:0dd54868f420 update foo
   | |   () draft
   o |  5:2eec5320cfc7 bar
   |/    (bm) draft
@@ -323,25 +360,25 @@
 
   $ hg fixup --continue
   abort: no interrupted fixup to continue
-  [255]
+  [20]
 
   $ hg fixup --abort
   abort: no interrupted fixup to abort
-  [255]
+  [20]
 
 testing error cases
 
   $ hg fixup tip --abort
   abort: cannot specify a revision with --abort
-  [255]
+  [10]
 
   $ hg fixup -r tip --continue
   abort: cannot specify a revision with --continue
-  [255]
+  [10]
 
   $ hg fixup
   abort: please specify a revision to fixup
-  [255]
+  [10]
 
   $ hg fixup tip
   nothing changed
@@ -368,7 +405,7 @@
 
   $ hg fixup :10 -r 5
   abort: please specify just one revision
-  [255]
+  [10]
 
   $ cd ..
 
--- a/tests/test-minitopic.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-minitopic.t	Fri Dec 09 15:01:59 2022 +0400
@@ -220,7 +220,7 @@
   $ hg push enabled
   pushing to http://localhost:$HGPORT/
   searching for changes
-  abort: push creates new remote head 82c5842e0472 on branch 'default:topic_A'
+  abort: push creates new remote head 82c5842e0472 on branch 'default//topic_A'
   (merge or see 'hg help push' for details about pushing new heads)
   [20]
   $ hg push disabled
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-namespaces.t	Fri Dec 09 15:01:59 2022 +0400
@@ -0,0 +1,138 @@
+https://www.mercurial-scm.org/wiki/TopicPlan#sub_branches.2C_namespacing_and_representation
+
+  $ . "$TESTDIR/testlib/topic_setup.sh"
+
+  $ hg init repo
+  $ cd repo
+
+  $ hg debug-topic-namespace space-name
+  marked working directory as topic namespace: space-name
+  $ hg debug-topic-namespaces
+  space-name
+
+  $ hg log -r 'wdir()' -T '{topic_namespace}\n'
+  space-name
+
+  $ hg log -r 'wdir()' -T '{fqbn}\n'
+  default//space-name/
+
+  $ hg branches
+
+  $ hg debug-topic-namespace --clear
+  $ hg debug-topic-namespaces
+  default
+
+  $ hg debugtopicnamespace --clear nonsense
+  abort: cannot use --clear when setting a topic namespace
+  [255]
+
+  $ hg branch stable
+  marked working directory as branch stable
+  (branches are permanent and global, did you want a bookmark?)
+  $ hg debug-topic-namespace alice
+  marked working directory as topic namespace: alice
+  $ hg topic feature
+  marked working directory as topic: feature
+  $ echo a > a
+  $ hg ci -qAm a
+
+  $ hg debug-topic-namespaces
+  alice
+
+  $ hg log -r . -T '{rev}: {branch} {topic_namespace} {topic}\n'
+  0: stable alice feature
+
+  $ hg log -r . -T '{rev}: {fqbn}\n'
+  0: stable//alice/feature
+
+  $ hg branches
+  stable//alice/feature          0:69c7dbf6acd1
+
+Updating to a revision with a namespace should activate it
+
+  $ hg up null
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ hg debug-topic-namespace
+  default
+  $ hg topics
+     feature (1 changesets)
+  $ hg up 0
+  switching to topic-namespace alice
+  switching to topic feature
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg debug-topic-namespace
+  alice
+  $ hg topics
+   * feature (1 changesets)
+
+Updating to a topic namespace is not supported
+
+  $ hg up alice
+  abort: unknown revision 'alice'
+  [10]
+
+Revsets
+
+  $ nslog() {
+  >   hg log -T '{rev}: {topic_namespace}\n' -r "$1"
+  > }
+
+  $ nslog 'topicnamespace(:)'
+  0: alice
+  $ nslog 'topicnamespace(all())'
+  0: alice
+  $ nslog 'topicnamespace(topicnamespace("alice"))'
+  0: alice
+  $ nslog 'topicnamespace(wdir())'
+  0: alice
+  $ nslog 'topicnamespace("re:ice$")'
+  0: alice
+  $ nslog 'topicnamespace(nonsense)'
+  abort: unknown revision 'nonsense'
+  [10]
+
+  $ nslog 'topicnamespace("re:nonsense")'
+  $ nslog 'topicnamespace("literal:nonsense")'
+  abort: topic namespace 'nonsense' does not exist
+  [10]
+
+Parsing
+
+  $ hg debugparsefqbn foo/bar//user26/feature -T '[{branch}] <{topic_namespace}> ({topic})\n'
+  [foo/bar] <user26> (feature)
+
+no double slashes means it's a named branch
+  $ hg debug-parse-fqbn foo/bar
+  branch:    foo/bar
+  namespace: default
+  topic:     
+
+Formatting
+
+  $ hg debugformatfqbn -b branch -n namespace -t topic
+  branch//namespace/topic
+
+  $ hg debug-format-fqbn -n namespace
+  //namespace/
+
+  $ hg debug-format-fqbn -b foo/bar -n user26 -t feature
+  foo/bar//user26/feature
+
+default values
+
+  $ hg debug-format-fqbn -b default -n default -t '' --no-short
+  default//default/
+  $ hg debug-format-fqbn -b default -n default -t '' --short
+  default
+
+  $ hg debug-format-fqbn -b default -n namespace -t '' --no-short
+  default//namespace/
+  $ hg debug-format-fqbn -b default -n namespace -t '' --short
+  default//namespace/
+
+  $ hg debug-format-fqbn -b default -n default -t topic --no-short
+  default//default/topic
+  $ hg debug-format-fqbn -b default -n default -t topic --short
+  default//topic
+
+  $ cd ..
--- a/tests/test-next-abort.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-next-abort.t	Fri Dec 09 15:01:59 2022 +0400
@@ -36,10 +36,10 @@
   working directory is now at 1c7f51cf0ef0
   $ hg next --abort
   abort: no interrupted next to abort
-  [255]
+  [20]
   $ hg evolve --abort
   abort: no interrupted evolve to abort
-  [255]
+  [20]
 
   $ hg next --abort --move-bookmark
   abort: cannot specify both --abort and --move-bookmark
--- a/tests/test-pick.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-pick.t	Fri Dec 09 15:01:59 2022 +0400
@@ -1,4 +1,4 @@
-#testcases abortcommand abortflag
+#testcases abortcontinuecommand abortcontinueflag
 Test for the pick command
 
   $ cat >> $HGRCPATH <<EOF
@@ -9,10 +9,11 @@
   > EOF
   $ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH
 
-#if abortflag
+#if abortcontinueflag
   $ cat >> $HGRCPATH <<EOF
   > [alias]
   > abort = pick --abort
+  > continue = pick --continue
   > EOF
 #endif
 
@@ -82,14 +83,19 @@
 
   $ hg pick --continue
   abort: no interrupted pick state exists
-  [255]
+  [20]
+#if abortcontinuecommand
+  $ hg continue
+  abort: no operation in progress
+  [20]
+#endif
 
 Aborting without interrupted pick
 
   $ hg pick --abort
   abort: no interrupted pick state exists
-  [255]
-#if abortcommand
+  [20]
+#if abortcontinuecommand
   $ hg abort
   abort: no operation in progress
   [20]
@@ -205,7 +211,11 @@
   $ hg resolve --all --mark
   (no more unresolved files)
   continue: hg pick --continue
-  $ hg pick --continue
+#if abortcontinuecommand
+  $ hg continue --dry-run
+  pick in progress, will be resumed
+#endif
+  $ hg continue
   $ hg glog
   @  8:44e155eb95c7 add c
   |
@@ -243,7 +253,7 @@
   (no more unresolved files)
   continue: hg pick --continue
 
-  $ hg pick --continue
+  $ hg continue
   note: picking 9:4e04628911f6 created no changes to commit
 
 Testing the abort functionality of hg pick
@@ -264,7 +274,7 @@
   unresolved merge conflicts (see hg help resolve)
   [240]
 
-#if abortcommand
+#if abortcontinuecommand
   $ hg abort --dry-run
   pick in progress, will be aborted
 #endif
@@ -330,7 +340,7 @@
   (no more unresolved files)
   continue: hg pick --continue
 
-  $ hg pick --continue
+  $ hg continue
   $ hg phase -r .
   11: secret
 
@@ -466,7 +476,7 @@
   $ hg resolve -t :other a
   (no more unresolved files)
   continue: hg pick --continue
-  $ hg pick --continue
+  $ hg continue
 
 Demonstrate that b was not forgotten and is definitely included in 4
 
--- a/tests/test-prev-next.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-prev-next.t	Fri Dec 09 15:01:59 2022 +0400
@@ -366,13 +366,13 @@
   got lock after (\d+) seconds (re)
   move:[2] two
   atop:[3] one
-  working directory is now at a7d885c75614
+  working directory is now at ab3a85718ec9
   $ wait
 
 testing next --evolve when working directory is dirty
 
   $ hg log -GT "{rev}:{node|short} {desc|firstline}"
-  @  4:a7d885c75614 two
+  @  4:ab3a85718ec9 two
   |
   o  3:c741983992fc one
   
--- a/tests/test-prune.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-prune.t	Fri Dec 09 15:01:59 2022 +0400
@@ -36,20 +36,20 @@
 ---------------------------------------
 
   $ hg prune --fold --pair
-  abort: can only specify one of pair, fold
-  [255]
+  abort: cannot specify both --pair and --fold
+  [10]
   $ hg prune --fold --biject
-  abort: no revisions specified to prune
-  [255]
+  abort: cannot specify both --biject and --fold
+  [10]
   $ hg prune --split --fold
-  abort: can only specify one of fold, split
-  [255]
+  abort: cannot specify both --fold and --split
+  [10]
   $ hg prune --split --fold --pair
-  abort: can only specify one of pair, fold, split
-  [255]
+  abort: cannot specify both --pair and --fold
+  [10]
   $ hg prune --split --fold --biject
-  abort: can only specify one of fold, split
-  [255]
+  abort: cannot specify both --fold and --split
+  [10]
 
 Check simple case
 ----------------------------
@@ -172,7 +172,7 @@
 
   $ hg prune 'desc("add dd")' -s 'desc("add nD")' -s 'desc("add nC")'
   abort: please add --split if you want to do a split
-  [255]
+  [10]
   $ hg prune 'desc("add dd")' -s 'desc("add nD")' -s 'desc("add nC")' --split
   1 changesets pruned
   $ hg debugobsolete
@@ -201,9 +201,9 @@
 two old, two new (should be denied)
 
   $ hg prune 'desc("add cc")' 'desc("add bb")' -s 'desc("add nD")' -s 'desc("add nC")'
-  abort: Can't use multiple successors for multiple precursors
+  abort: cannot use multiple successors for multiple precursors
   (use --pair to mark a series as a replacement for another)
-  [255]
+  [10]
   $ hg debugobsolete
   9d206ffc875e1bc304590549be293be36821e66c 0 {47d2a3944de8b013de3be9578e8e344ea2e6c097} (Sat Dec 15 00:00:00 1979 +0000) {'ef1': '0', 'operation': 'prune', 'user': 'blah'}
   7c3bad9141dcb46ff89abf5f61856facd56e476c 0 {1f0dee641bb7258c56bd60e93edfa2405381c41e} (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'prune', 'user': 'test'}
@@ -216,7 +216,7 @@
 
   $ hg prune 'desc("add cc")' 'desc("add bb")' -s 'desc("add nB")'
   abort: please add --fold if you want to do a fold
-  [255]
+  [10]
   $ hg prune 'desc("add cc")' 'desc("add bb")' -s 'desc("add nB")' --fold
   2 changesets pruned
   $ hg debugobsolete
@@ -295,7 +295,7 @@
   $ hg prune -B nostrip
   bookmark 'nostrip' deleted
   abort: no revisions specified to prune
-  [255]
+  [10]
   $ hg tag --remove --local a
   $ hg prune -B todelete
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
@@ -488,3 +488,16 @@
   (use 'hg evolve' to update to its parent successor)
 
   $ cd ..
+
+Test that pruning (without any successors) an already pruned
+revision doesn't give false warning about divergence creation:
+
+  $ hg init nofalsewarn
+  $ cd nofalsewarn
+  $ echo a > A
+  $ hg ci -Aqm "added a"
+  $ hg ci --amend -m "added A"
+  $ hg prune 0 --hidden
+  1 changesets pruned
+
+  $ cd ..
--- a/tests/test-push-checkheads-mixed-branch-topic-G1.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-push-checkheads-mixed-branch-topic-G1.t	Fri Dec 09 15:01:59 2022 +0400
@@ -67,13 +67,13 @@
   1 new obsolescence markers
   obsoleted 1 changesets
   $ hg log -G --hidden
-  @  845eeb768064 (draft)[Z]: B1
+  @  845eeb768064 [default//Z] (draft): B1
   |
-  | x  35d2f30a8ba4 (draft)[Z]: B0
+  | x  35d2f30a8ba4 [default//Z] (draft): B0
   | |
-  | o  8aaa48160adc (draft): A0
+  | o  8aaa48160adc [default] (draft): A0
   |/
-  o  1e4be0697311 (public): root
+  o  1e4be0697311 [default] (public): root
   
 
 Actual testing
--- a/tests/test-push-checkheads-mixed-branch-topic-G2.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-push-checkheads-mixed-branch-topic-G2.t	Fri Dec 09 15:01:59 2022 +0400
@@ -78,17 +78,17 @@
   1 new obsolescence markers
   obsoleted 1 changesets
   $ hg log -G --hidden
-  @  0c76bc104656 (draft): C1
+  @  0c76bc104656 [default] (draft): C1
   |
-  o  f6082bc4ffef (draft): A1
+  o  f6082bc4ffef [default] (draft): A1
   |
-  | x  44759c6d327d (draft): C0
+  | x  44759c6d327d [default] (draft): C0
   | |
-  | *  35d2f30a8ba4 (draft)[Z]: B0
+  | *  35d2f30a8ba4 [default//Z] (draft): B0
   | |
-  | x  8aaa48160adc (draft): A0
+  | x  8aaa48160adc [default] (draft): A0
   |/
-  o  1e4be0697311 (public): root
+  o  1e4be0697311 [default] (public): root
   
 
 Actual testing
--- a/tests/test-push-checkheads-mixed-branch-topic-G3.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-push-checkheads-mixed-branch-topic-G3.t	Fri Dec 09 15:01:59 2022 +0400
@@ -73,15 +73,15 @@
   1 new obsolescence markers
   obsoleted 1 changesets
   $ hg log -G --hidden
-  @  dc44c53142f0 (draft): C1
+  @  dc44c53142f0 [default] (draft): C1
   |
-  | x  44759c6d327d (draft): C0
+  | x  44759c6d327d [default] (draft): C0
   | |
-  | o  35d2f30a8ba4 (draft)[Z]: B0
+  | o  35d2f30a8ba4 [default//Z] (draft): B0
   | |
-  | o  8aaa48160adc (draft): A0
+  | o  8aaa48160adc [default] (draft): A0
   |/
-  o  1e4be0697311 (public): root
+  o  1e4be0697311 [default] (public): root
   
 
 Actual testing
--- a/tests/test-push-checkheads-multi-topics-F1.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-push-checkheads-multi-topics-F1.t	Fri Dec 09 15:01:59 2022 +0400
@@ -71,15 +71,15 @@
   1 new obsolescence markers
   obsoleted 1 changesets
   $ hg log -G --hidden
-  @  845eeb768064 (draft)[Z]: B1
+  @  845eeb768064 [default//Z] (draft): B1
   |
-  | x  e1494106e1ca (draft)[Z]: B0
+  | x  e1494106e1ca [default//Z] (draft): B0
   | |
-  | o  f5cd873e2965 (draft)[Y]: A0
+  | o  f5cd873e2965 [default//Y] (draft): A0
   |/
-  | x  8aaa48160adc (draft): A0
+  | x  8aaa48160adc [default] (draft): A0
   |/
-  o  1e4be0697311 (public): root
+  o  1e4be0697311 [default] (public): root
   
 
 Actual testing
--- a/tests/test-push-checkheads-multi-topics-F2.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-push-checkheads-multi-topics-F2.t	Fri Dec 09 15:01:59 2022 +0400
@@ -82,17 +82,17 @@
   1 new obsolescence markers
   obsoleted 1 changesets
   $ hg log -G --hidden
-  @  0e26ba57d799 (draft)[Y]: C1
+  @  0e26ba57d799 [default//Y] (draft): C1
   |
-  o  fb4a34222909 (draft)[Y]: A1
+  o  fb4a34222909 [default//Y] (draft): A1
   |
-  | x  345721b128e8 (draft)[Y]: C0
+  | x  345721b128e8 [default//Y] (draft): C0
   | |
-  | *  e1494106e1ca (draft)[Z]: B0
+  | *  e1494106e1ca [default//Z] (draft): B0
   | |
-  | x  f5cd873e2965 (draft)[Y]: A0
+  | x  f5cd873e2965 [default//Y] (draft): A0
   |/
-  o  1e4be0697311 (public): root
+  o  1e4be0697311 [default] (public): root
   
 
 Actual testing
--- a/tests/test-push-checkheads-multi-topics-F3.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-push-checkheads-multi-topics-F3.t	Fri Dec 09 15:01:59 2022 +0400
@@ -77,15 +77,15 @@
   1 new obsolescence markers
   obsoleted 1 changesets
   $ hg log -G --hidden
-  @  57530ca5eb24 (draft)[Y]: C1
+  @  57530ca5eb24 [default//Y] (draft): C1
   |
-  | x  345721b128e8 (draft)[Y]: C0
+  | x  345721b128e8 [default//Y] (draft): C0
   | |
-  | o  e1494106e1ca (draft)[Z]: B0
+  | o  e1494106e1ca [default//Z] (draft): B0
   | |
-  | o  f5cd873e2965 (draft)[Y]: A0
+  | o  f5cd873e2965 [default//Y] (draft): A0
   |/
-  o  1e4be0697311 (public): root
+  o  1e4be0697311 [default] (public): root
   
 
 Actual testing
@@ -94,7 +94,7 @@
   $ hg push -r 'desc("C1")'
   pushing to $TESTTMP/E1/server
   searching for changes
-  abort: push creates new remote head 57530ca5eb24 on branch 'default:Y'
+  abort: push creates new remote head 57530ca5eb24 on branch 'default//Y'
   (merge or see 'hg help push' for details about pushing new heads)
   [20]
 
--- a/tests/test-push-checkheads-multibranches-E1.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-push-checkheads-multibranches-E1.t	Fri Dec 09 15:01:59 2022 +0400
@@ -68,13 +68,13 @@
   1 new obsolescence markers
   obsoleted 1 changesets
   $ hg log -G --hidden
-  @  c98b855401e7 (draft): B1
+  @  c98b855401e7 [Z] (draft): B1
   |
-  | x  93e5c1321ece (draft): B0
+  | x  93e5c1321ece [Z] (draft): B0
   | |
-  | o  8aaa48160adc (draft): A0
+  | o  8aaa48160adc [default] (draft): A0
   |/
-  o  1e4be0697311 (public): root
+  o  1e4be0697311 [default] (public): root
   
 
 Actual testing
--- a/tests/test-push-checkheads-multibranches-E2.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-push-checkheads-multibranches-E2.t	Fri Dec 09 15:01:59 2022 +0400
@@ -78,17 +78,17 @@
   1 new obsolescence markers
   obsoleted 1 changesets
   $ hg log -G --hidden
-  @  0c76bc104656 (draft): C1
+  @  0c76bc104656 [default] (draft): C1
   |
-  o  f6082bc4ffef (draft): A1
+  o  f6082bc4ffef [default] (draft): A1
   |
-  | x  afc55ba2ce61 (draft): C0
+  | x  afc55ba2ce61 [default] (draft): C0
   | |
-  | *  93e5c1321ece (draft): B0
+  | *  93e5c1321ece [Z] (draft): B0
   | |
-  | x  8aaa48160adc (draft): A0
+  | x  8aaa48160adc [default] (draft): A0
   |/
-  o  1e4be0697311 (public): root
+  o  1e4be0697311 [default] (public): root
   
 
 Actual testing
--- a/tests/test-push-checkheads-multibranches-E3.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-push-checkheads-multibranches-E3.t	Fri Dec 09 15:01:59 2022 +0400
@@ -73,15 +73,15 @@
   1 new obsolescence markers
   obsoleted 1 changesets
   $ hg log -G --hidden
-  @  dc44c53142f0 (draft): C1
+  @  dc44c53142f0 [default] (draft): C1
   |
-  | x  afc55ba2ce61 (draft): C0
+  | x  afc55ba2ce61 [default] (draft): C0
   | |
-  | o  93e5c1321ece (draft): B0
+  | o  93e5c1321ece [Z] (draft): B0
   | |
-  | o  8aaa48160adc (draft): A0
+  | o  8aaa48160adc [default] (draft): A0
   |/
-  o  1e4be0697311 (public): root
+  o  1e4be0697311 [default] (public): root
   
 
 Actual testing
--- a/tests/test-push-checkheads-partial-C1.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-push-checkheads-partial-C1.t	Fri Dec 09 15:01:59 2022 +0400
@@ -61,13 +61,13 @@
   1 new obsolescence markers
   obsoleted 1 changesets
   $ hg log -G --hidden
-  @  25c56d33e4c4 (draft): B1
+  @  25c56d33e4c4 [default] (draft): B1
   |
-  | x  d73caddc5533 (draft): B0
+  | x  d73caddc5533 [default] (draft): B0
   | |
-  | o  8aaa48160adc (draft): A0
+  | o  8aaa48160adc [default] (draft): A0
   |/
-  o  1e4be0697311 (public): root
+  o  1e4be0697311 [default] (public): root
   
 
 
--- a/tests/test-push-checkheads-partial-C2.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-push-checkheads-partial-C2.t	Fri Dec 09 15:01:59 2022 +0400
@@ -64,13 +64,13 @@
   obsoleted 1 changesets
   1 new orphan changesets
   $ hg log -G --hidden
-  @  f6082bc4ffef (draft): A1
+  @  f6082bc4ffef [default] (draft): A1
   |
-  | *  d73caddc5533 (draft): B0
+  | *  d73caddc5533 [default] (draft): B0
   | |
-  | x  8aaa48160adc (draft): A0
+  | x  8aaa48160adc [default] (draft): A0
   |/
-  o  1e4be0697311 (public): root
+  o  1e4be0697311 [default] (public): root
   
 
 Actual testing
--- a/tests/test-push-checkheads-partial-C3.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-push-checkheads-partial-C3.t	Fri Dec 09 15:01:59 2022 +0400
@@ -63,13 +63,13 @@
   1 new obsolescence markers
   obsoleted 1 changesets
   $ hg log -G --hidden
-  @  0f88766e02d6 (draft): C0
+  @  0f88766e02d6 [default] (draft): C0
   |
-  | x  d73caddc5533 (draft): B0
+  | x  d73caddc5533 [default] (draft): B0
   | |
-  | o  8aaa48160adc (draft): A0
+  | o  8aaa48160adc [default] (draft): A0
   |/
-  o  1e4be0697311 (public): root
+  o  1e4be0697311 [default] (public): root
   
 
 Actual testing
--- a/tests/test-push-checkheads-partial-C4.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-push-checkheads-partial-C4.t	Fri Dec 09 15:01:59 2022 +0400
@@ -64,13 +64,13 @@
   obsoleted 1 changesets
   1 new orphan changesets
   $ hg log -G --hidden
-  @  0f88766e02d6 (draft): C0
+  @  0f88766e02d6 [default] (draft): C0
   |
-  | *  d73caddc5533 (draft): B0
+  | *  d73caddc5533 [default] (draft): B0
   | |
-  | x  8aaa48160adc (draft): A0
+  | x  8aaa48160adc [default] (draft): A0
   |/
-  o  1e4be0697311 (public): root
+  o  1e4be0697311 [default] (public): root
   
 
 Actual testing
--- a/tests/test-push-checkheads-pruned-B1.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-push-checkheads-pruned-B1.t	Fri Dec 09 15:01:59 2022 +0400
@@ -52,11 +52,11 @@
   1 new obsolescence markers
   obsoleted 1 changesets
   $ hg log -G --hidden
-  @  74ff5441d343 (draft): B0
+  @  74ff5441d343 [default] (draft): B0
   |
-  | x  8aaa48160adc (draft): A0
+  | x  8aaa48160adc [default] (draft): A0
   |/
-  o  1e4be0697311 (public): root
+  o  1e4be0697311 [default] (public): root
   
 
 Actual testing
--- a/tests/test-push-checkheads-pruned-B2.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-push-checkheads-pruned-B2.t	Fri Dec 09 15:01:59 2022 +0400
@@ -67,13 +67,13 @@
   1 new obsolescence markers
   obsoleted 1 changesets
   $ hg log -G --hidden
-  @  f6082bc4ffef (draft): A1
+  @  f6082bc4ffef [default] (draft): A1
   |
-  | x  d73caddc5533 (draft): B0
+  | x  d73caddc5533 [default] (draft): B0
   | |
-  | x  8aaa48160adc (draft): A0
+  | x  8aaa48160adc [default] (draft): A0
   |/
-  o  1e4be0697311 (public): root
+  o  1e4be0697311 [default] (public): root
   
 
 Actual testing
--- a/tests/test-push-checkheads-pruned-B3.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-push-checkheads-pruned-B3.t	Fri Dec 09 15:01:59 2022 +0400
@@ -67,13 +67,13 @@
   1 new obsolescence markers
   obsoleted 1 changesets
   $ hg log -G --hidden
-  @  25c56d33e4c4 (draft): B1
+  @  25c56d33e4c4 [default] (draft): B1
   |
-  | x  d73caddc5533 (draft): B0
+  | x  d73caddc5533 [default] (draft): B0
   | |
-  | x  8aaa48160adc (draft): A0
+  | x  8aaa48160adc [default] (draft): A0
   |/
-  o  1e4be0697311 (public): root
+  o  1e4be0697311 [default] (public): root
   
 
 Actual testing
--- a/tests/test-push-checkheads-pruned-B4.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-push-checkheads-pruned-B4.t	Fri Dec 09 15:01:59 2022 +0400
@@ -68,13 +68,13 @@
   1 new obsolescence markers
   obsoleted 1 changesets
   $ hg log -G --hidden
-  @  0f88766e02d6 (draft): C0
+  @  0f88766e02d6 [default] (draft): C0
   |
-  | x  d73caddc5533 (draft): B0
+  | x  d73caddc5533 [default] (draft): B0
   | |
-  | x  8aaa48160adc (draft): A0
+  | x  8aaa48160adc [default] (draft): A0
   |/
-  o  1e4be0697311 (public): root
+  o  1e4be0697311 [default] (public): root
   
 
 Actual testing
--- a/tests/test-push-checkheads-pruned-B5.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-push-checkheads-pruned-B5.t	Fri Dec 09 15:01:59 2022 +0400
@@ -74,15 +74,15 @@
   1 new obsolescence markers
   obsoleted 1 changesets
   $ hg log -G --hidden
-  @  25c56d33e4c4 (draft): B1
+  @  25c56d33e4c4 [default] (draft): B1
   |
-  | x  821fb21d0dd2 (draft): C0
+  | x  821fb21d0dd2 [default] (draft): C0
   | |
-  | x  d73caddc5533 (draft): B0
+  | x  d73caddc5533 [default] (draft): B0
   | |
-  | x  8aaa48160adc (draft): A0
+  | x  8aaa48160adc [default] (draft): A0
   |/
-  o  1e4be0697311 (public): root
+  o  1e4be0697311 [default] (public): root
   
 
 Actual testing
--- a/tests/test-push-checkheads-pruned-B6.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-push-checkheads-pruned-B6.t	Fri Dec 09 15:01:59 2022 +0400
@@ -58,13 +58,13 @@
   1 new obsolescence markers
   obsoleted 1 changesets
   $ hg log -G --hidden
-  x  ba93660aff8d (draft): A1
+  x  ba93660aff8d [default] (draft): A1
   |
-  @  74ff5441d343 (draft): B0
+  @  74ff5441d343 [default] (draft): B0
   |
-  | x  8aaa48160adc (draft): A0
+  | x  8aaa48160adc [default] (draft): A0
   |/
-  o  1e4be0697311 (public): root
+  o  1e4be0697311 [default] (public): root
   
 
 Actual testing
--- a/tests/test-push-checkheads-pruned-B7.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-push-checkheads-pruned-B7.t	Fri Dec 09 15:01:59 2022 +0400
@@ -57,13 +57,13 @@
   1 new obsolescence markers
   obsoleted 1 changesets
   $ hg log -G --hidden
-  x  ba93660aff8d (draft): A1
+  x  ba93660aff8d [default] (draft): A1
   |
-  @  74ff5441d343 (draft): B0
+  @  74ff5441d343 [default] (draft): B0
   |
-  | x  8aaa48160adc (draft): A0
+  | x  8aaa48160adc [default] (draft): A0
   |/
-  o  1e4be0697311 (public): root
+  o  1e4be0697311 [default] (public): root
   
 
 Actual testing
--- a/tests/test-push-checkheads-pruned-B8.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-push-checkheads-pruned-B8.t	Fri Dec 09 15:01:59 2022 +0400
@@ -80,17 +80,17 @@
   1 new obsolescence markers
   obsoleted 1 changesets
   $ hg log -G --hidden
-  @  c1f8d089020f (draft): A2
+  @  c1f8d089020f [default] (draft): A2
   |
-  | x  262c8c798096 (draft): B1
+  | x  262c8c798096 [default] (draft): B1
   | |
-  | x  f6082bc4ffef (draft): A1
+  | x  f6082bc4ffef [default] (draft): A1
   |/
-  | x  d73caddc5533 (draft): B0
+  | x  d73caddc5533 [default] (draft): B0
   | |
-  | x  8aaa48160adc (draft): A0
+  | x  8aaa48160adc [default] (draft): A0
   |/
-  o  1e4be0697311 (public): root
+  o  1e4be0697311 [default] (public): root
   
 
 Actual testing
--- a/tests/test-push-checkheads-supersede-A1.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-push-checkheads-supersede-A1.t	Fri Dec 09 15:01:59 2022 +0400
@@ -49,11 +49,11 @@
   1 new obsolescence markers
   obsoleted 1 changesets
   $ hg log -G --hidden
-  @  f6082bc4ffef (draft): A1
+  @  f6082bc4ffef [default] (draft): A1
   |
-  | x  8aaa48160adc (draft): A0
+  | x  8aaa48160adc [default] (draft): A0
   |/
-  o  1e4be0697311 (public): root
+  o  1e4be0697311 [default] (public): root
   
 
 Actual testing
--- a/tests/test-push-checkheads-supersede-A2.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-push-checkheads-supersede-A2.t	Fri Dec 09 15:01:59 2022 +0400
@@ -67,15 +67,15 @@
   1 new obsolescence markers
   obsoleted 1 changesets
   $ hg log -G --hidden
-  @  262c8c798096 (draft): B1
+  @  262c8c798096 [default] (draft): B1
   |
-  o  f6082bc4ffef (draft): A1
+  o  f6082bc4ffef [default] (draft): A1
   |
-  | x  d73caddc5533 (draft): B0
+  | x  d73caddc5533 [default] (draft): B0
   | |
-  | x  8aaa48160adc (draft): A0
+  | x  8aaa48160adc [default] (draft): A0
   |/
-  o  1e4be0697311 (public): root
+  o  1e4be0697311 [default] (public): root
   
 
 Actual testing
--- a/tests/test-push-checkheads-supersede-A3.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-push-checkheads-supersede-A3.t	Fri Dec 09 15:01:59 2022 +0400
@@ -70,15 +70,15 @@
   1 new obsolescence markers
   obsoleted 1 changesets
   $ hg log -G --hidden
-  @  c1c7524e9488 (draft): A1
+  @  c1c7524e9488 [default] (draft): A1
   |
-  o  25c56d33e4c4 (draft): B1
+  o  25c56d33e4c4 [default] (draft): B1
   |
-  | x  d73caddc5533 (draft): B0
+  | x  d73caddc5533 [default] (draft): B0
   | |
-  | x  8aaa48160adc (draft): A0
+  | x  8aaa48160adc [default] (draft): A0
   |/
-  o  1e4be0697311 (public): root
+  o  1e4be0697311 [default] (public): root
   
 
 Actual testing
--- a/tests/test-push-checkheads-supersede-A4.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-push-checkheads-supersede-A4.t	Fri Dec 09 15:01:59 2022 +0400
@@ -52,13 +52,13 @@
   obsoleted 1 changesets
   $ mkcommit B0
   $ hg log -G --hidden
-  @  f40ded968333 (draft): B0
+  @  f40ded968333 [default] (draft): B0
   |
-  o  f6082bc4ffef (draft): A1
+  o  f6082bc4ffef [default] (draft): A1
   |
-  | x  8aaa48160adc (draft): A0
+  | x  8aaa48160adc [default] (draft): A0
   |/
-  o  1e4be0697311 (public): root
+  o  1e4be0697311 [default] (public): root
   
 
 Actual testing
--- a/tests/test-push-checkheads-supersede-A5.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-push-checkheads-supersede-A5.t	Fri Dec 09 15:01:59 2022 +0400
@@ -52,13 +52,13 @@
   1 new obsolescence markers
   obsoleted 1 changesets
   $ hg log -G --hidden
-  @  ba93660aff8d (draft): A1
+  @  ba93660aff8d [default] (draft): A1
   |
-  o  74ff5441d343 (draft): B0
+  o  74ff5441d343 [default] (draft): B0
   |
-  | x  8aaa48160adc (draft): A0
+  | x  8aaa48160adc [default] (draft): A0
   |/
-  o  1e4be0697311 (public): root
+  o  1e4be0697311 [default] (public): root
   
 
 Actual testing
--- a/tests/test-push-checkheads-supersede-A6.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-push-checkheads-supersede-A6.t	Fri Dec 09 15:01:59 2022 +0400
@@ -76,17 +76,17 @@
   1 new obsolescence markers
   obsoleted 1 changesets
   $ hg log -G --hidden
-  @  d70a1f75a020 (draft): B1
+  @  d70a1f75a020 [default] (draft): B1
   |
-  | o  f6082bc4ffef (draft): A1
+  | o  f6082bc4ffef [default] (draft): A1
   | |
-  o |  0f88766e02d6 (draft): C0
+  o |  0f88766e02d6 [default] (draft): C0
   |/
-  | x  d73caddc5533 (draft): B0
+  | x  d73caddc5533 [default] (draft): B0
   | |
-  | x  8aaa48160adc (draft): A0
+  | x  8aaa48160adc [default] (draft): A0
   |/
-  o  1e4be0697311 (public): root
+  o  1e4be0697311 [default] (public): root
   
 
 Actual testing
--- a/tests/test-push-checkheads-supersede-A7.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-push-checkheads-supersede-A7.t	Fri Dec 09 15:01:59 2022 +0400
@@ -76,17 +76,17 @@
   1 new obsolescence markers
   obsoleted 1 changesets
   $ hg log -G --hidden
-  @  25c56d33e4c4 (draft): B1
+  @  25c56d33e4c4 [default] (draft): B1
   |
-  | o  a0802eb7fc1b (draft): A1
+  | o  a0802eb7fc1b [default] (draft): A1
   | |
-  | o  0f88766e02d6 (draft): C0
+  | o  0f88766e02d6 [default] (draft): C0
   |/
-  | x  d73caddc5533 (draft): B0
+  | x  d73caddc5533 [default] (draft): B0
   | |
-  | x  8aaa48160adc (draft): A0
+  | x  8aaa48160adc [default] (draft): A0
   |/
-  o  1e4be0697311 (public): root
+  o  1e4be0697311 [default] (public): root
   
 
 Actual testing
--- a/tests/test-push-checkheads-supersede-A8.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-push-checkheads-supersede-A8.t	Fri Dec 09 15:01:59 2022 +0400
@@ -59,13 +59,13 @@
   1 new obsolescence markers
   obsoleted 1 changesets
   $ hg log -G --hidden
-  @  c1f8d089020f (draft): A2
+  @  c1f8d089020f [default] (draft): A2
   |
-  | x  f6082bc4ffef (draft): A1
+  | x  f6082bc4ffef [default] (draft): A1
   |/
-  | x  8aaa48160adc (draft): A0
+  | x  8aaa48160adc [default] (draft): A0
   |/
-  o  1e4be0697311 (public): root
+  o  1e4be0697311 [default] (public): root
   
 
 Actual testing
--- a/tests/test-push-checkheads-unpushed-D1.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-push-checkheads-unpushed-D1.t	Fri Dec 09 15:01:59 2022 +0400
@@ -56,13 +56,13 @@
   $ mkcommit B0
   created new head
   $ hg log -G --hidden
-  @  74ff5441d343 (draft): B0
+  @  74ff5441d343 [default] (draft): B0
   |
-  | o  f6082bc4ffef (draft): A1
+  | o  f6082bc4ffef [default] (draft): A1
   |/
-  | x  8aaa48160adc (draft): A0
+  | x  8aaa48160adc [default] (draft): A0
   |/
-  o  1e4be0697311 (public): root
+  o  1e4be0697311 [default] (public): root
   
 
 Actual testing
--- a/tests/test-push-checkheads-unpushed-D2.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-push-checkheads-unpushed-D2.t	Fri Dec 09 15:01:59 2022 +0400
@@ -75,15 +75,15 @@
   $ mkcommit C0
   created new head
   $ hg log -G --hidden
-  @  0f88766e02d6 (draft): C0
+  @  0f88766e02d6 [default] (draft): C0
   |
-  | o  f6082bc4ffef (draft): A1
+  | o  f6082bc4ffef [default] (draft): A1
   |/
-  | x  d73caddc5533 (draft): B0
+  | x  d73caddc5533 [default] (draft): B0
   | |
-  | x  8aaa48160adc (draft): A0
+  | x  8aaa48160adc [default] (draft): A0
   |/
-  o  1e4be0697311 (public): root
+  o  1e4be0697311 [default] (public): root
   
 
 Actual testing
--- a/tests/test-push-checkheads-unpushed-D3.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-push-checkheads-unpushed-D3.t	Fri Dec 09 15:01:59 2022 +0400
@@ -74,15 +74,15 @@
   1 new obsolescence markers
   obsoleted 1 changesets
   $ hg log -G --hidden
-  @  25c56d33e4c4 (draft): B1
+  @  25c56d33e4c4 [default] (draft): B1
   |
-  | o  f6082bc4ffef (draft): A1
+  | o  f6082bc4ffef [default] (draft): A1
   |/
-  | x  d73caddc5533 (draft): B0
+  | x  d73caddc5533 [default] (draft): B0
   | |
-  | x  8aaa48160adc (draft): A0
+  | x  8aaa48160adc [default] (draft): A0
   |/
-  o  1e4be0697311 (public): root
+  o  1e4be0697311 [default] (public): root
   
 
 Actual testing
--- a/tests/test-push-checkheads-unpushed-D4.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-push-checkheads-unpushed-D4.t	Fri Dec 09 15:01:59 2022 +0400
@@ -90,17 +90,17 @@
   1 new obsolescence markers
   obsoleted 1 changesets
   $ hg log -G --hidden
-  @  d70a1f75a020 (draft): B1
+  @  d70a1f75a020 [default] (draft): B1
   |
-  | o  f6082bc4ffef (draft): A1
+  | o  f6082bc4ffef [default] (draft): A1
   | |
-  o |  0f88766e02d6 (draft): C0
+  o |  0f88766e02d6 [default] (draft): C0
   |/
-  | x  d73caddc5533 (draft): B0
+  | x  d73caddc5533 [default] (draft): B0
   | |
-  | x  8aaa48160adc (draft): A0
+  | x  8aaa48160adc [default] (draft): A0
   |/
-  o  1e4be0697311 (public): root
+  o  1e4be0697311 [default] (public): root
   
 
 Actual testing (new branch only)
--- a/tests/test-push-checkheads-unpushed-D5.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-push-checkheads-unpushed-D5.t	Fri Dec 09 15:01:59 2022 +0400
@@ -79,17 +79,17 @@
   1 new obsolescence markers
   obsoleted 1 changesets
   $ hg log -G --hidden
-  @  25c56d33e4c4 (draft): B1
+  @  25c56d33e4c4 [default] (draft): B1
   |
-  | o  a0802eb7fc1b (draft): A1
+  | o  a0802eb7fc1b [default] (draft): A1
   | |
-  | o  0f88766e02d6 (draft): C0
+  | o  0f88766e02d6 [default] (draft): C0
   |/
-  | x  d73caddc5533 (draft): B0
+  | x  d73caddc5533 [default] (draft): B0
   | |
-  | x  8aaa48160adc (draft): A0
+  | x  8aaa48160adc [default] (draft): A0
   |/
-  o  1e4be0697311 (public): root
+  o  1e4be0697311 [default] (public): root
   
 
 Actual testing
--- a/tests/test-push-checkheads-unpushed-D6.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-push-checkheads-unpushed-D6.t	Fri Dec 09 15:01:59 2022 +0400
@@ -62,15 +62,15 @@
   1 new obsolescence markers
   obsoleted 1 changesets
   $ hg log -G --hidden
-  @  0f88766e02d6 (draft): C0
+  @  0f88766e02d6 [default] (draft): C0
   |
-  | x  ba93660aff8d (draft): A1
+  | x  ba93660aff8d [default] (draft): A1
   | |
-  | o  74ff5441d343 (draft): B0
+  | o  74ff5441d343 [default] (draft): B0
   |/
-  | x  8aaa48160adc (draft): A0
+  | x  8aaa48160adc [default] (draft): A0
   |/
-  o  1e4be0697311 (public): root
+  o  1e4be0697311 [default] (public): root
   
 
 Actual testing
--- a/tests/test-push-checkheads-unpushed-D7.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-push-checkheads-unpushed-D7.t	Fri Dec 09 15:01:59 2022 +0400
@@ -74,17 +74,17 @@
   1 new obsolescence markers
   obsoleted 1 changesets
   $ hg log -G --hidden
-  @  0f88766e02d6 (draft): C0
+  @  0f88766e02d6 [default] (draft): C0
   |
-  | x  c1f8d089020f (draft): A2
+  | x  c1f8d089020f [default] (draft): A2
   |/
-  | x  ba93660aff8d (draft): A1
+  | x  ba93660aff8d [default] (draft): A1
   | |
-  | o  74ff5441d343 (draft): B0
+  | o  74ff5441d343 [default] (draft): B0
   |/
-  | x  8aaa48160adc (draft): A0
+  | x  8aaa48160adc [default] (draft): A0
   |/
-  o  1e4be0697311 (public): root
+  o  1e4be0697311 [default] (public): root
   
 
 Actual testing
--- a/tests/test-single-head-obsolescence-topic-B1.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-single-head-obsolescence-topic-B1.t	Fri Dec 09 15:01:59 2022 +0400
@@ -84,17 +84,17 @@
   1 new obsolescence markers
   obsoleted 1 changesets
   $ hg log -G --hidden
-  @  f4ed6717fb66 [default:topic-X] (draft): B1
+  @  f4ed6717fb66 [default//topic-X] (draft): B1
   |
-  o  c1340bef453e [default:topic-X] (draft): A1
+  o  c1340bef453e [default//topic-X] (draft): A1
   |
-  | *  618812b710f7 [default:topic-Y] (draft): D0
+  | *  618812b710f7 [default//topic-Y] (draft): D0
   | |
-  | *  d1ad53773db2 [default:topic-Y] (draft): C0
+  | *  d1ad53773db2 [default//topic-Y] (draft): C0
   | |
-  | x  1c1f62b56685 [default:topic-X] (draft): B0
+  | x  1c1f62b56685 [default//topic-X] (draft): B0
   | |
-  | x  5a47a98cd8e5 [default:topic-X] (draft): A0
+  | x  5a47a98cd8e5 [default//topic-X] (draft): A0
   |/
   o  1e4be0697311 [default] (public): root
   
--- a/tests/test-single-head-obsolescence-topic-B2.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-single-head-obsolescence-topic-B2.t	Fri Dec 09 15:01:59 2022 +0400
@@ -83,15 +83,15 @@
   obsoleted 1 changesets
   2 new orphan changesets
   $ hg log -G --hidden
-  @  5a4735b75167 [default:topic-X] (draft): B1
+  @  5a4735b75167 [default//topic-X] (draft): B1
   |
-  | *  02490b2dd1c5 [Z:topic-Y] (draft): D0
+  | *  02490b2dd1c5 [Z//topic-Y] (draft): D0
   | |
-  | *  447ad8382abc [Z:topic-Y] (draft): C0
+  | *  447ad8382abc [Z//topic-Y] (draft): C0
   | |
-  | x  1c1f62b56685 [default:topic-X] (draft): B0
+  | x  1c1f62b56685 [default//topic-X] (draft): B0
   | |
-  | o  5a47a98cd8e5 [default:topic-X] (draft): A0
+  | o  5a47a98cd8e5 [default//topic-X] (draft): A0
   |/
   o  1e4be0697311 [default] (public): root
   
@@ -109,6 +109,6 @@
   adding file changes
   transaction abort!
   rollback completed
-  abort: rejecting multiple heads on branch "default:topic-X"
+  abort: rejecting multiple heads on branch "default//topic-X"
   (2 heads: 5a47a98cd8e5 5a4735b75167)
   [255]
--- a/tests/test-single-head-obsolescence-topic-B3.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-single-head-obsolescence-topic-B3.t	Fri Dec 09 15:01:59 2022 +0400
@@ -86,17 +86,17 @@
   1 new obsolescence markers
   obsoleted 1 changesets
   $ hg log -G --hidden
-  @  9f6e6381b9aa [default:topic-X] (draft): C1
+  @  9f6e6381b9aa [default//topic-X] (draft): C1
   |
-  o  c1340bef453e [default:topic-X] (draft): A1
+  o  c1340bef453e [default//topic-X] (draft): A1
   |
-  | *  850d57e10bfe [default:topic-Y] (draft): D0
+  | *  850d57e10bfe [default//topic-Y] (draft): D0
   | |
-  | x  fcdd583577e8 [default:topic-X] (draft): C0
+  | x  fcdd583577e8 [default//topic-X] (draft): C0
   | |
-  | *  030eec7a0fe2 [default:topic-Y] (draft): B0
+  | *  030eec7a0fe2 [default//topic-Y] (draft): B0
   | |
-  | x  5a47a98cd8e5 [default:topic-X] (draft): A0
+  | x  5a47a98cd8e5 [default//topic-X] (draft): A0
   |/
   o  1e4be0697311 [default] (public): root
   
--- a/tests/test-single-head-obsolescence-topic-B4.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-single-head-obsolescence-topic-B4.t	Fri Dec 09 15:01:59 2022 +0400
@@ -83,15 +83,15 @@
   obsoleted 1 changesets
   1 new orphan changesets
   $ hg log -G --hidden
-  @  b98a8bd4ca39 [default:topic-X] (draft): C1
+  @  b98a8bd4ca39 [default//topic-X] (draft): C1
   |
-  | *  850d57e10bfe [default:topic-Y] (draft): D0
+  | *  850d57e10bfe [default//topic-Y] (draft): D0
   | |
-  | x  fcdd583577e8 [default:topic-X] (draft): C0
+  | x  fcdd583577e8 [default//topic-X] (draft): C0
   | |
-  | o  030eec7a0fe2 [default:topic-Y] (draft): B0
+  | o  030eec7a0fe2 [default//topic-Y] (draft): B0
   |/
-  o  5a47a98cd8e5 [default:topic-X] (draft): A0
+  o  5a47a98cd8e5 [default//topic-X] (draft): A0
   |
   o  1e4be0697311 [default] (public): root
   
--- a/tests/test-single-head-obsolescence-topic-B5.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-single-head-obsolescence-topic-B5.t	Fri Dec 09 15:01:59 2022 +0400
@@ -88,13 +88,13 @@
   |
   o  f6082bc4ffef [default] (draft): A1
   |
-  | *  339fd31549ed [default:topic-Y] (draft): C0
+  | *  339fd31549ed [default//topic-Y] (draft): C0
   | |
-  | x    33b3d4185449 [default:topic-X] (draft): M0
+  | x    33b3d4185449 [default//topic-X] (draft): M0
   | |\
-  +---o  d3826ff42cf7 [default:topic-X] (draft): B0
+  +---o  d3826ff42cf7 [default//topic-X] (draft): B0
   | |
-  | o  5a47a98cd8e5 [default:topic-X] (draft): A0
+  | o  5a47a98cd8e5 [default//topic-X] (draft): A0
   |/
   o  1e4be0697311 [default] (public): root
   
@@ -110,6 +110,6 @@
   no changes found
   transaction abort!
   rollback completed
-  abort: rejecting multiple heads on branch "default:topic-X"
+  abort: rejecting multiple heads on branch "default//topic-X"
   (2 heads: 5a47a98cd8e5 d3826ff42cf7)
   [255]
--- a/tests/test-split.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-split.t	Fri Dec 09 15:01:59 2022 +0400
@@ -431,7 +431,7 @@
   $ hg summary
   parent: 18:26f72cfaf036 tip
    Works on mytopic
-  branch: new-branch:mytopic
+  branch: new-branch//mytopic
   commit: (clean)
   update: (current)
   phases: 9 draft
--- a/tests/test-stabilize-conflict.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-stabilize-conflict.t	Fri Dec 09 15:01:59 2022 +0400
@@ -80,6 +80,11 @@
   atop:[3] babar count up to ten
   merging babar
   working directory is now at 71c18f70c34f
+
+  $ hg log -r . -T '{extras % "{key}={value}\n"}'
+  branch=default
+  rebase_source=694f05b30ab7d4324e469d19af2ee80003a8fb50
+
   $ hg resolve -l
   $ hg log -G
   @  changeset:   4:71c18f70c34f
@@ -167,10 +172,15 @@
   continue: hg evolve --continue
   $ hg evolve --continue
   evolving 4:71c18f70c34f "babar count up to fifteen"
-  working directory is now at 1836b91c6c1d
+  working directory is now at 368da14a3c59
+
+  $ hg log -r . -T '{extras % "{key}={value}\n"}'
+  branch=default
+  rebase_source=71c18f70c34f7a15e293983a89ccd17ae3f444aa
+
   $ hg resolve -l
   $ hg log -G
-  @  changeset:   6:1836b91c6c1d
+  @  changeset:   6:368da14a3c59
   |  tag:         tip
   |  user:        test
   |  date:        Thu Jan 01 00:00:00 1970 +0000
@@ -232,7 +242,7 @@
   |  date:        Thu Jan 01 00:00:00 1970 +0000
   |  summary:     babar count up to ten
   |
-  | %  changeset:   6:1836b91c6c1d
+  | %  changeset:   6:368da14a3c59
   | |  user:        test
   | |  date:        Thu Jan 01 00:00:00 1970 +0000
   | |  instability: orphan
--- a/tests/test-stabilize-order.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-stabilize-order.t	Fri Dec 09 15:01:59 2022 +0400
@@ -81,7 +81,7 @@
   resolving manifests (ondisk !)
   removing b (ondisk !)
   $ glog
-  o  6:81b8bbcd5892@default(draft) addb
+  o  6:bede829dd2d3@default(draft) addb
   |
   @  5:005fe5914f78@default(draft) adda
   |
@@ -100,7 +100,7 @@
   $ hg evolve -v --update
   move:[3] addc
   atop:[6] addb
-  hg rebase -r 7a7552255fb5 -d 81b8bbcd5892
+  hg rebase -r 7a7552255fb5 -d bede829dd2d3
   resolving manifests (ondisk !)
   getting b (ondisk !)
   resolving manifests
@@ -112,7 +112,7 @@
   resolving manifests (inmemory !)
   getting b (inmemory !)
   getting c (inmemory !)
-  working directory is now at 0f691739f917
+  working directory is now at 65095d7d0dd5
   $ hg debugobsolete > successors.new
   $ diff -u successors.old successors.new
   --- successors.old* (glob)
@@ -120,16 +120,16 @@
   @@ -1,3 +1,4 @@
    ef23d6ef94d68dea65d20587dfecc8b33d165617 22619daeed78036f80fbd326b6852519c4f0c25e 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'amend', 'user': 'test'}
    93418d2c0979643ad446f621195e78720edb05b4 005fe5914f78e8bc64c7eba28117b0b1fa210d0d 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'amend', 'user': 'test'}
-   22619daeed78036f80fbd326b6852519c4f0c25e 81b8bbcd5892841efed41433d7a5e9df922396cb 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'evolve', 'user': 'test'}
-  +7a7552255fb5f8bd745e46fba6f0ca633a4dd716 0f691739f91762462bf8ba21f35fdf71fe64310e 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'evolve', 'user': 'test'}
+   22619daeed78036f80fbd326b6852519c4f0c25e bede829dd2d3b2ae9bf198c23432b250dc964458 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'evolve', 'user': 'test'}
+  +7a7552255fb5f8bd745e46fba6f0ca633a4dd716 65095d7d0dd5e4f15503bb7b1f433a5fe9bac052 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'evolve', 'user': 'test'}
   [1]
 
 
 
   $ glog
-  @  7:0f691739f917@default(draft) addc
+  @  7:65095d7d0dd5@default(draft) addc
   |
-  o  6:81b8bbcd5892@default(draft) addb
+  o  6:bede829dd2d3@default(draft) addb
   |
   o  5:005fe5914f78@default(draft) adda
   |
@@ -140,23 +140,23 @@
 
 Test behavior with --any
 
-  $ hg up 81b8bbcd5892
+  $ hg up bede829dd2d3
   0 files updated, 0 files merged, 1 files removed, 0 files unresolved
   $ echo b >> b
   $ hg amend
   1 new orphan changesets
   $ glog
-  @  8:7a68bc4596ea@default(draft) addb
+  @  8:036cf654e942@default(draft) addb
   |
-  | *  7:0f691739f917@default(draft) addc
+  | *  7:65095d7d0dd5@default(draft) addc
   | |
-  | x  6:81b8bbcd5892@default(draft) addb
+  | x  6:bede829dd2d3@default(draft) addb
   |/
   o  5:005fe5914f78@default(draft) adda
   |
   o  0:c471ef929e6a@default(draft) addroot
   
-  $ hg up 0f691739f917
+  $ hg up 65095d7d0dd5
   2 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ hg evolve -v
   nothing to evolve on current working copy parent
@@ -165,7 +165,7 @@
   $ hg evolve --any -v
   move:[7] addc
   atop:[8] addb
-  hg rebase -r 0f691739f917 -d 7a68bc4596ea
+  hg rebase -r 65095d7d0dd5 -d 036cf654e942
   resolving manifests (ondisk !)
   removing c (ondisk !)
   getting b (ondisk !)
@@ -177,11 +177,11 @@
   committing changelog
   resolving manifests (inmemory !)
   getting b (inmemory !)
-  working directory is now at 2256dae6521f
+  working directory is now at e99ecf51c867
   $ glog
-  @  9:2256dae6521f@default(draft) addc
+  @  9:e99ecf51c867@default(draft) addc
   |
-  o  8:7a68bc4596ea@default(draft) addb
+  o  8:036cf654e942@default(draft) addb
   |
   o  5:005fe5914f78@default(draft) adda
   |
@@ -206,33 +206,33 @@
   $ hg commit --amend -m "newmessage"
   2 new orphan changesets
   $ hg log -G
-  @  changeset:   12:f83a0bce03e4
+  @  changeset:   12:49773ccde390
   |  tag:         tip
-  |  parent:      8:7a68bc4596ea
+  |  parent:      8:036cf654e942
   |  user:        test
   |  date:        Thu Jan 01 00:00:00 1970 +0000
   |  summary:     newmessage
   |
-  | *  changeset:   11:fa68011f392e
-  | |  parent:      9:2256dae6521f
+  | *  changeset:   11:a9892777b519
+  | |  parent:      9:e99ecf51c867
   | |  user:        test
   | |  date:        Thu Jan 01 00:00:00 1970 +0000
   | |  instability: orphan
   | |  summary:     secondambiguous
   | |
-  | | *  changeset:   10:bdc003b6eec2
+  | | *  changeset:   10:0b6e26b2472d
   | |/   user:        test
   | |    date:        Thu Jan 01 00:00:00 1970 +0000
   | |    instability: orphan
   | |    summary:     firstambiguous
   | |
-  | x  changeset:   9:2256dae6521f
+  | x  changeset:   9:e99ecf51c867
   |/   user:        test
   |    date:        Thu Jan 01 00:00:00 1970 +0000
-  |    obsolete:    reworded using amend as 12:f83a0bce03e4
+  |    obsolete:    reworded using amend as 12:49773ccde390
   |    summary:     addc
   |
-  o  changeset:   8:7a68bc4596ea
+  o  changeset:   8:036cf654e942
   |  parent:      5:005fe5914f78
   |  user:        test
   |  date:        Thu Jan 01 00:00:00 1970 +0000
--- a/tests/test-topic-flow-publish-bare.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-topic-flow-publish-bare.t	Fri Dec 09 15:01:59 2022 +0400
@@ -350,16 +350,19 @@
   $ hg debugcapabilities $TESTTMP/bare-branch-server | grep topics
     ext-topics-publish=auto
     topics
+    topics-namespaces
   $ hg debugcapabilities ssh://user@dummy/bare-branch-server | grep topics
     _exttopics_heads
     ext-topics-publish=auto
     topics
+    topics-namespaces
   $ hg serve -R ../bare-branch-server -p $HGPORT -d --pid-file hg.pid
   $ cat hg.pid >> $DAEMON_PIDS
   $ hg debugcapabilities http://localhost:$HGPORT | grep topics
     _exttopics_heads
     ext-topics-publish=auto
     topics
+    topics-namespaces
   $ killdaemons.py
 
 Trying to push changeset without topic (would publish them)
--- a/tests/test-topic-flow-single-head.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-topic-flow-single-head.t	Fri Dec 09 15:01:59 2022 +0400
@@ -146,7 +146,7 @@
   adding file changes
   transaction abort!
   rollback completed
-  abort: 2 heads on "default:bar"
+  abort: 2 heads on "default//bar"
   (5194f5dcd542, 48a01453c1c5)
   [255]
 
--- a/tests/test-topic-fold.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-topic-fold.t	Fri Dec 09 15:01:59 2022 +0400
@@ -49,7 +49,7 @@
   $ hg summary
   parent: 3:ba602426356f tip
    folded
-  branch: default:myfeature
+  branch: default//myfeature
   commit: (clean)
   update: (current)
   phases: 2 draft
--- a/tests/test-topic-mode.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-topic-mode.t	Fri Dec 09 15:01:59 2022 +0400
@@ -1,14 +1,15 @@
   $ . "$TESTDIR/testlib/topic_setup.sh"
 
+  $ cat <<EOF >> $HGRCPATH
+  > [phases]
+  > publish = false
+  > EOF
+
 Testing the config knob to forbid untopiced commit
 ======================================================
 
   $ hg init $TESTTMP/untopic-commit
   $ cd $TESTTMP/untopic-commit
-  $ cat <<EOF >> .hg/hgrc
-  > [phases]
-  > publish=false
-  > EOF
   $ cat <<EOF >> $HGRCPATH
   > [experimental]
   > topic-mode = enforce
@@ -40,10 +41,6 @@
 
   $ hg init $TESTTMP/untopic-warn-commit
   $ cd $TESTTMP/untopic-warn-commit
-  $ cat <<EOF >> .hg/hgrc
-  > [phases]
-  > publish=false
-  > EOF
   $ cat <<EOF >> $HGRCPATH
   > [experimental]
   > topic-mode = warning
@@ -91,10 +88,6 @@
 
   $ hg init $TESTTMP/test-untopic-merge-commit
   $ cd $TESTTMP/test-untopic-merge-commit
-  $ cat <<EOF >> .hg/hgrc
-  > [phases]
-  > publish=false
-  > EOF
   $ cat <<EOF >> $HGRCPATH
   > [experimental]
   > topic-mode = enforce
@@ -155,10 +148,6 @@
 
   $ hg init $TESTTMP/test-untopic-merge-commit-abort
   $ cd $TESTTMP/test-untopic-merge-commit-abort
-  $ cat <<EOF >> .hg/hgrc
-  > [phases]
-  > publish=false
-  > EOF
   $ cat <<EOF >> $HGRCPATH
   > [experimental]
   > topic-mode = enforce-all
@@ -212,10 +201,6 @@
 
   $ hg init $TESTTMP/test-untopic-random
   $ cd $TESTTMP/test-untopic-random
-  $ cat <<EOF >> .hg/hgrc
-  > [phases]
-  > publish=false
-  > EOF
   $ cat <<EOF >> $HGRCPATH
   > [experimental]
   > topic-mode = random
@@ -228,7 +213,7 @@
   $ touch A
   $ hg add A
   $ hg commit -m "Add A" --config devel.randomseed=42
-  active topic 'palatial-antelope' grew its first changeset
+  active topic 'panoramic-antelope' grew its first changeset
   (see 'hg help topics' for more information)
 
   $ hg up -r "desc(ROOT)"
@@ -256,8 +241,8 @@
   |  date:        Thu Jan 01 00:00:00 1970 +0000
   |  summary:     Add B
   |
-  | o  changeset:   1:d502ab6d9d91
-  |/   topic:       palatial-antelope
+  | o  changeset:   1:d4b548f35972
+  |/   topic:       panoramic-antelope
   |    user:        test
   |    date:        Thu Jan 01 00:00:00 1970 +0000
   |    summary:     Add A
@@ -267,19 +252,16 @@
      date:        Thu Jan 01 00:00:00 1970 +0000
      summary:     ROOT
   
-  $ hg merge palatial-antelope
+  $ hg merge panoramic-antelope
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   (branch merge, don't forget to commit)
   $ hg ci -m 'merge'
+
 Testing the config knob to use a random topic for untopic commit (even for merge)
 =================================================================================
 
   $ hg init $TESTTMP/test-untopic-random-all
   $ cd $TESTTMP/test-untopic-random-all
-  $ cat <<EOF >> .hg/hgrc
-  > [phases]
-  > publish=false
-  > EOF
   $ cat <<EOF >> $HGRCPATH
   > [experimental]
   > topic-mode = random-all
@@ -292,7 +274,7 @@
   $ touch A
   $ hg add A
   $ hg commit -m "Add A" --config devel.randomseed=42
-  active topic 'palatial-antelope' grew its first changeset
+  active topic 'panoramic-antelope' grew its first changeset
   (see 'hg help topics' for more information)
 
   $ hg up -r "desc(ROOT)"
@@ -320,8 +302,8 @@
   |  date:        Thu Jan 01 00:00:00 1970 +0000
   |  summary:     Add B
   |
-  | o  changeset:   1:d502ab6d9d91
-  |/   topic:       palatial-antelope
+  | o  changeset:   1:d4b548f35972
+  |/   topic:       panoramic-antelope
   |    user:        test
   |    date:        Thu Jan 01 00:00:00 1970 +0000
   |    summary:     Add A
@@ -331,7 +313,7 @@
      date:        Thu Jan 01 00:00:00 1970 +0000
      summary:     ROOT
   
-  $ hg merge palatial-antelope
+  $ hg merge panoramic-antelope
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   (branch merge, don't forget to commit)
   $ hg ci -m 'merge'  --config devel.randomseed=1337
--- a/tests/test-topic-push.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-topic-push.t	Fri Dec 09 15:01:59 2022 +0400
@@ -47,12 +47,12 @@
   $ hg add aaa
   $ hg commit -m 'CA'
   $ hg outgoing -G
-  comparing with $TESTTMP/main (glob)
+  comparing with $TESTTMP/main
   searching for changes
   @  0 default  draft CA
   
   $ hg push
-  pushing to $TESTTMP/main (glob)
+  pushing to $TESTTMP/main
   searching for changes
   adding changesets
   adding manifests
@@ -72,25 +72,25 @@
   created new head
   (consider using topic for lightweight branches. See 'hg help topic')
   $ hg outgoing -G
-  comparing with $TESTTMP/main (glob)
+  comparing with $TESTTMP/main
   searching for changes
   @  2 default  draft CC
   
   o  1 default  draft CB
   
   $ hg push
-  pushing to $TESTTMP/main (glob)
+  pushing to $TESTTMP/main
   searching for changes
   abort: push creates new remote head 9fe81b7f425d
   (merge or see 'hg help push' for details about pushing new heads)
   [20]
   $ hg outgoing -r 'desc(CB)' -G
-  comparing with $TESTTMP/main (glob)
+  comparing with $TESTTMP/main
   searching for changes
   o  1 default  draft CB
   
   $ hg push -r 'desc(CB)'
-  pushing to $TESTTMP/main (glob)
+  pushing to $TESTTMP/main
   searching for changes
   adding changesets
   adding manifests
@@ -99,23 +99,23 @@
 
 Pushing a new branch
 
-  $ hg branch mountain
-  marked working directory as branch mountain
+  $ hg branch double//slash
+  marked working directory as branch double//slash
   (branches are permanent and global, did you want a bookmark?)
   $ hg commit --amend
   $ hg outgoing -G
-  comparing with $TESTTMP/main (glob)
+  comparing with $TESTTMP/main
   searching for changes
-  @  3 mountain  draft CC
+  @  3 double//slash  draft CC
   
   $ hg push
-  pushing to $TESTTMP/main (glob)
+  pushing to $TESTTMP/main
   searching for changes
-  abort: push creates new remote branches: mountain
+  abort: push creates new remote branches: double//slash//
   (use 'hg push --new-branch' to create new remote branches)
   [20]
   $ hg push --new-branch
-  pushing to $TESTTMP/main (glob)
+  pushing to $TESTTMP/main
   searching for changes
   adding changesets
   adding manifests
@@ -126,7 +126,7 @@
 Including on non-publishing
 
   $ hg push --new-branch draft
-  pushing to $TESTTMP/draft (glob)
+  pushing to $TESTTMP/draft
   searching for changes
   adding changesets
   adding manifests
@@ -152,7 +152,7 @@
   $ hg log -G # keep track of phase because I saw some strange bug during developement
   @  4 default babar draft CD
   |
-  | o  3 mountain  public CC
+  | o  3 double//slash  public CC
   |/
   | o  1 default  public CB
   |/
@@ -162,7 +162,7 @@
 Pushing a new topic to a non publishing server should not be seen as a new head
 
   $ hg push draft
-  pushing to $TESTTMP/draft (glob)
+  pushing to $TESTTMP/draft
   searching for changes
   adding changesets
   adding manifests
@@ -171,7 +171,7 @@
   $ hg log -G
   @  4 default babar draft CD
   |
-  | o  3 mountain  public CC
+  | o  3 double//slash  public CC
   |/
   | o  1 default  public CB
   |/
@@ -182,7 +182,7 @@
   $ hg log -G -R $TESTTMP/draft
   o  3 default babar draft CD
   |
-  | o  2 mountain  public CC
+  | o  2 double//slash  public CC
   |/
   | o  1 default  public CB
   |/
@@ -202,7 +202,7 @@
   | |
   | o  4 default babar draft CD
   | |
-  | | o  3 mountain  public CC
+  | | o  3 double//slash  public CC
   | |/
   o |  1 default  public CB
   |/
@@ -240,7 +240,7 @@
   |
   o  3 default babar draft CD
   |
-  | o  2 mountain  public CC
+  | o  2 double//slash  public CC
   |/
   | o  1 default  public CB
   |/
@@ -252,7 +252,7 @@
 Pushing a new topic to a publishing server should be seen as a new head
 
   $ hg push
-  pushing to $TESTTMP/main (glob)
+  pushing to $TESTTMP/main
   searching for changes
   abort: push creates new remote head 67f579af159d
   (merge or see 'hg help push' for details about pushing new heads)
@@ -260,7 +260,7 @@
   $ hg log -G
   @  4 default babar draft CD
   |
-  | o  3 mountain  public CC
+  | o  3 double//slash  public CC
   |/
   | o  1 default  public CB
   |/
@@ -284,7 +284,7 @@
   |
   | o  4 default babar draft CD
   |/
-  | o  3 mountain  public CC
+  | o  3 double//slash  public CC
   |/
   | o  1 default  public CB
   |/
@@ -308,7 +308,7 @@
   |
   | o  4 default babar draft CD
   |/
-  | o  3 mountain  public CC
+  | o  3 double//slash  public CC
   |/
   | o  1 default  public CB
   |/
@@ -330,7 +330,7 @@
   |
   | o  4 default babar draft CD
   |/
-  | o  3 mountain  public CC
+  | o  3 double//slash  public CC
   |/
   | o  1 default  public CB
   |/
@@ -350,7 +350,7 @@
   |
   | o  4 default babar draft CD
   |/
-  | o  3 mountain  public CC
+  | o  3 double//slash  public CC
   |/
   | o  1 default  public CB
   |/
@@ -374,7 +374,7 @@
   | |
   | | o  4 default babar draft CD
   | |/
-  | | o  3 mountain  public CC
+  | | o  3 double//slash  public CC
   | |/
   o |  1 default  public CB
   |/
@@ -382,9 +382,9 @@
   
 
   $ hg push draft
-  pushing to $TESTTMP/draft (glob)
+  pushing to $TESTTMP/draft
   searching for changes
-  abort: push creates new remote head f0bc62a661be on branch 'default:babar'
+  abort: push creates new remote head f0bc62a661be on branch 'default//babar'
   (merge or see 'hg help push' for details about pushing new heads)
   [20]
 
@@ -416,7 +416,7 @@
   | |/
   | | o  4 default babar draft CD
   | |/
-  | | o  3 mountain  public CC
+  | | o  3 double//slash  public CC
   | |/
   o |  1 default  public CB
   |/
@@ -426,7 +426,7 @@
 Reject when pushing to draft
 
   $ hg push draft -r .
-  pushing to $TESTTMP/draft (glob)
+  pushing to $TESTTMP/draft
   searching for changes
   abort: push creates new remote head 4937c4cad39e
   (merge or see 'hg help push' for details about pushing new heads)
@@ -435,7 +435,7 @@
 Reject when pushing to publishing
 
   $ hg push -r .
-  pushing to $TESTTMP/main (glob)
+  pushing to $TESTTMP/main
   searching for changes
   adding changesets
   adding manifests
@@ -509,4 +509,4 @@
   searching for changes
   no changes found
   abort: push creates new heads on branch 'default': bbd9d6199b88
-  [255]
+  [20]
--- a/tests/test-topic-stack-data.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-topic-stack-data.t	Fri Dec 09 15:01:59 2022 +0400
@@ -111,7 +111,7 @@
   $ hg summary
   parent: 21:3e54b49a3113 tip
    add foo_b
-  branch: lake:foo
+  branch: lake//foo
   commit: (clean)
   update: (current)
   phases: 22 draft
--- a/tests/test-topic-stack.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-topic-stack.t	Fri Dec 09 15:01:59 2022 +0400
@@ -313,7 +313,7 @@
   $ hg summary
   parent: 3:e629654d7050 
    c_d
-  branch: default:foo
+  branch: default//foo
   commit: (clean)
   update: 2 new changesets (update)
   phases: 4 draft
--- a/tests/test-topic-tutorial.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-topic-tutorial.t	Fri Dec 09 15:01:59 2022 +0400
@@ -108,7 +108,7 @@
   $ hg summary
   parent: 0:38da43f0a2ea tip
    Shopping list
-  branch: default:food
+  branch: default//food
   commit: (new branch)
   update: (current)
   topic:  food
--- a/tests/test-topic.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-topic.t	Fri Dec 09 15:01:59 2022 +0400
@@ -254,13 +254,16 @@
   [1]
   $ hg topics --current somerandomtopic
   abort: cannot use --current when setting a topic
-  [255]
+  [10]
   $ hg topics --current --clear
   abort: cannot use --current and --clear
-  [255]
+  [10]
   $ hg topics --clear somerandomtopic
   abort: cannot use --clear when setting a topic
-  [255]
+  [10]
+  $ hg topics --list --clear
+  abort: cannot specify both --list and --clear
+  [10]
 
 Trying some invalid topicnames
 
@@ -277,18 +280,18 @@
   abort: cannot use an integer as a name
   [10]
   $ hg topic '   '
-  abort: topic name cannot consist entirely of whitespaces
-  [255]
+  abort: topic names cannot consist entirely of whitespace
+  [10]
 
   $ hg topic 'a12#45'
   abort: invalid topic name: 'a12#45'
   (topic names can only consist of alphanumeric, '-' '_' and '.' characters)
-  [255]
+  [10]
 
   $ hg topic 'foo bar'
   abort: invalid topic name: 'foo bar'
   (topic names can only consist of alphanumeric, '-' '_' and '.' characters)
-  [255]
+  [10]
 
 this is trying to list topic names
   $ hg topic ''
@@ -296,7 +299,7 @@
   $ hg topic '*12 B23'
   abort: invalid topic name: '*12 B23'
   (topic names can only consist of alphanumeric, '-' '_' and '.' characters)
-  [255]
+  [10]
 
 Test commit flag and help text
 
@@ -317,6 +320,24 @@
   $ hg topic
    * topicflag (0 changesets)
 
+Non-ascii topic name
+
+  $ hg --encoding utf-8 topic æ
+  $ hg topics
+   * \xc3\xa6 (0 changesets) (esc)
+  $ hg --encoding latin1 topics
+   * \xc3\xa6 (0 changesets) (esc)
+
+  $ hg --encoding utf-8 topic ©
+  abort: invalid topic name: '\xc2\xa9' (esc)
+  (topic names can only consist of alphanumeric, '-' '_' and '.' characters)
+  [10]
+
+  $ hg --encoding latin1 topic æ
+  abort: invalid topic name: '\xc3\xa6' (esc)
+  (topic names can only consist of alphanumeric, '-' '_' and '.' characters)
+  [10]
+
 Make a topic
 
   $ hg topic narf
@@ -581,11 +602,11 @@
      fran  (1 changesets)
    * narf  (2 changesets)
      query (2 changesets)
-  $ hg debugnamecomplete # branch:topic here is a buggy side effect
+  $ hg debugnamecomplete
   default
-  default:fran
-  default:narf
-  default:query
+  default//fran
+  default//narf
+  default//query
   fran
   narf
   query
@@ -1136,7 +1157,7 @@
 
   $ hg topics --age random
   abort: cannot use --age while setting a topic
-  [255]
+  [10]
   $ cd ..
 
 Test that topics doesn't confuse branchheads checking logic
--- a/tests/test-unstability-resolution-result.t	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/test-unstability-resolution-result.t	Fri Dec 09 15:01:59 2022 +0400
@@ -108,7 +108,7 @@
   continue: hg evolve --continue
   $ hg evolve --continue
   evolving 4:3655f0f50885 "newer a"
-  working directory is now at 1cf0aacfd363
+  working directory is now at 99ec7503cf5a
 
 Stabilize phase-divergent changesets with a different parent
 ============================================================
@@ -116,7 +116,7 @@
 (the same-parent case is handled in test-evolve.t)
 
   $ glog
-  @  6:1cf0aacfd363@default(draft) bk:[] newer a
+  @  6:99ec7503cf5a@default(draft) bk:[] newer a
   |
   o  5:66719795a494@default(draft) bk:[changea] changea
   |
@@ -136,8 +136,8 @@
 
 Get a successors of 8 on it
 
-  $ hg pick 1cf0aacfd363
-  picking 6:1cf0aacfd363 "newer a"
+  $ hg pick 99ec7503cf5a
+  picking 6:99ec7503cf5a "newer a"
 
 Add real change to the successors
 
@@ -146,14 +146,14 @@
 
 Make precursors public
 
-  $ hg phase --hidden --public 1cf0aacfd363
+  $ hg phase --hidden --public 99ec7503cf5a
   1 new phase-divergent changesets
   $ glog
-  @  9:99c21c89bcef@default(draft) bk:[] newer a
+  @  9:998db519ac88@default(draft) bk:[] newer a
   |
   o  7:7bc2f5967f5e@default(draft) bk:[] add c
   |
-  | o  6:1cf0aacfd363@default(public) bk:[] newer a
+  | o  6:99ec7503cf5a@default(public) bk:[] newer a
   |/
   o  5:66719795a494@default(public) bk:[changea] changea
   |
@@ -165,10 +165,10 @@
   $ hg evolve --any --dry-run --phase-divergent
   recreate:[9] newer a
   atop:[6] newer a
-  hg rebase --rev 99c21c89bcef --dest 66719795a494;
-  hg update 1cf0aacfd363;
-  hg revert --all --rev 99c21c89bcef;
-  hg commit --message "phase-divergent update to 99c21c89bcef"
+  hg rebase --rev 998db519ac88 --dest 66719795a494;
+  hg update 99ec7503cf5a;
+  hg revert --all --rev 998db519ac88;
+  hg commit --message "phase-divergent update to 998db519ac88"
   $ hg evolve --any --confirm --phase-divergent
   recreate:[9] newer a
   atop:[6] newer a
@@ -180,14 +180,14 @@
   atop:[6] newer a
   perform evolve? [Ny] y
   rebasing to destination parent: 66719795a494
-  committed as 8fc63fe1f297
-  working directory is now at 8fc63fe1f297
+  committed as 1e688a4b6db8
+  working directory is now at 1e688a4b6db8
   $ glog
-  @  11:8fc63fe1f297@default(draft) bk:[] phase-divergent update to 1cf0aacfd363:
+  @  11:1e688a4b6db8@default(draft) bk:[] phase-divergent update to 99ec7503cf5a:
   |
   | o  7:7bc2f5967f5e@default(draft) bk:[] add c
   | |
-  o |  6:1cf0aacfd363@default(public) bk:[] newer a
+  o |  6:99ec7503cf5a@default(public) bk:[] newer a
   |/
   o  5:66719795a494@default(public) bk:[changea] changea
   |
@@ -198,13 +198,13 @@
   # User test
   # Date 0 0
   #      Thu Jan 01 00:00:00 1970 +0000
-  # Node ID 8fc63fe1f297f356d1156bbbbe865b9911efad74
-  # Parent  1cf0aacfd36310b18e403e1594871187e0364a82
-  phase-divergent update to 1cf0aacfd363:
+  # Node ID 1e688a4b6db81db9b647e9045aff0fcbc5c32b8d
+  # Parent  99ec7503cf5a2cd545f41792129becc4172e9e9d
+  phase-divergent update to 99ec7503cf5a:
   
   newer a
   
-  diff -r 1cf0aacfd363 -r 8fc63fe1f297 a
+  diff -r 99ec7503cf5a -r 1e688a4b6db8 a
   --- a/a	Thu Jan 01 00:00:00 1970 +0000
   +++ b/a	Thu Jan 01 00:00:00 1970 +0000
   @@ -1,3 +1,4 @@
--- a/tests/testlib/push-checkheads-util.sh	Fri Dec 09 14:57:14 2022 +0400
+++ b/tests/testlib/push-checkheads-util.sh	Fri Dec 09 15:01:59 2022 +0400
@@ -4,17 +4,16 @@
 
 cat >> $HGRCPATH <<EOF
 [ui]
-# simpler log output
-logtemplate ="{node|short} ({phase}){if(topic, "[{topic}]")}: {desc}\n"
+logtemplate = "{node|short} [{if(topic, fqbn, branch)}] ({phase}): {desc}\n"
 
 [phases]
 # non publishing server
-publish=False
+publish = False
 
 [extensions]
 # we need to strip some changeset for some test cases
-strip=
-evolve=
+strip =
+evolve =
 EOF
 
 setuprepos() {
@@ -31,9 +30,5 @@
         echo >> "server/.hg/hgrc" "[experimental]"
         echo >> "server/.hg/hgrc" "# enforce a single name per branch"
         echo >> "server/.hg/hgrc" "single-head-per-branch = yes"
-
-        echo >> "client/.hg/hgrc" "[ui]"
-        echo >> "client/.hg/hgrc" "# simpler log output"
-        printf >> "client/.hg/hgrc" "%s" 'logtemplate = "{node|short} [{branch}{if(topic, ":{topic}")}] ({phase}): {desc}\n"'
     fi
 }