changeset 45803:84eb4c833c41

merge with stable
author Augie Fackler <augie@google.com>
date Mon, 02 Nov 2020 14:39:43 -0500
parents ff7e0ca666e8 (diff) f59c5d9f56b8 (current diff)
children 6991f3014311
files relnotes/5.6 relnotes/next
diffstat 121 files changed, 1851 insertions(+), 1228 deletions(-) [+]
line wrap: on
line diff
--- a/hgext/clonebundles.py	Mon Nov 02 14:26:19 2020 -0500
+++ b/hgext/clonebundles.py	Mon Nov 02 14:39:43 2020 -0500
@@ -205,6 +205,7 @@
 from __future__ import absolute_import
 
 from mercurial import (
+    bundlecaches,
     extensions,
     wireprotov1server,
 )
@@ -218,7 +219,7 @@
     # Only advertise if a manifest exists. This does add some I/O to requests.
     # But this should be cheaper than a wasted network round trip due to
     # missing file.
-    if repo.vfs.exists(b'clonebundles.manifest'):
+    if repo.vfs.exists(bundlecaches.CB_MANIFEST_FILE):
         caps.append(b'clonebundles')
 
     return caps
--- a/hgext/convert/hg.py	Mon Nov 02 14:26:19 2020 -0500
+++ b/hgext/convert/hg.py	Mon Nov 02 14:39:43 2020 -0500
@@ -398,7 +398,7 @@
                     ctx = self.repo[node]
                     if ctx.phase() < phases.draft:
                         phases.registernew(
-                            self.repo, tr, phases.draft, [ctx.node()]
+                            self.repo, tr, phases.draft, [ctx.rev()]
                         )
 
             text = b"(octopus merge fixup)\n"
--- a/hgext/eol.py	Mon Nov 02 14:26:19 2020 -0500
+++ b/hgext/eol.py	Mon Nov 02 14:39:43 2020 -0500
@@ -280,7 +280,7 @@
                 b"warning: ignoring .hgeol file due to parse error "
                 b"at %s: %s\n"
             )
-            % (inst.args[1], inst.args[0])
+            % (inst.location, inst.message)
         )
     return None
 
--- a/hgext/histedit.py	Mon Nov 02 14:26:19 2020 -0500
+++ b/hgext/histedit.py	Mon Nov 02 14:39:43 2020 -0500
@@ -525,11 +525,8 @@
         """
         ctx = self.repo[self.node]
         ui = self.repo.ui
-        summary = (
-            cmdutil.rendertemplate(
-                ctx, ui.config(b'histedit', b'summary-template')
-            )
-            or b''
+        summary = cmdutil.rendertemplate(
+            ctx, ui.config(b'histedit', b'summary-template')
         )
         summary = summary.splitlines()[0]
         line = b'%s %s %s' % (self.verb, ctx, summary)
@@ -1152,11 +1149,8 @@
 
     @util.propertycache
     def desc(self):
-        summary = (
-            cmdutil.rendertemplate(
-                self.ctx, self.ui.config(b'histedit', b'summary-template')
-            )
-            or b''
+        summary = cmdutil.rendertemplate(
+            self.ctx, self.ui.config(b'histedit', b'summary-template')
         )
         if summary:
             return summary
--- a/hgext/lfs/__init__.py	Mon Nov 02 14:26:19 2020 -0500
+++ b/hgext/lfs/__init__.py	Mon Nov 02 14:39:43 2020 -0500
@@ -127,10 +127,10 @@
 from mercurial.i18n import _
 
 from mercurial import (
+    bundlecaches,
     config,
     context,
     error,
-    exchange,
     extensions,
     exthelper,
     filelog,
@@ -351,7 +351,7 @@
     # Make bundle choose changegroup3 instead of changegroup2. This affects
     # "hg bundle" command. Note: it does not cover all bundle formats like
     # "packed1". Using "packed1" with lfs will likely cause trouble.
-    exchange._bundlespeccontentopts[b"v2"][b"cg.version"] = b"03"
+    bundlecaches._bundlespeccontentopts[b"v2"][b"cg.version"] = b"03"
 
 
 @eh.filesetpredicate(b'lfs()')
--- a/hgext/phabricator.py	Mon Nov 02 14:26:19 2020 -0500
+++ b/hgext/phabricator.py	Mon Nov 02 14:39:43 2020 -0500
@@ -141,9 +141,7 @@
     b'phabricator.action.created': b'green',
     b'phabricator.action.skipped': b'magenta',
     b'phabricator.action.updated': b'magenta',
-    b'phabricator.desc': b'',
     b'phabricator.drev': b'bold',
-    b'phabricator.node': b'',
     b'phabricator.status.abandoned': b'magenta dim',
     b'phabricator.status.accepted': b'green bold',
     b'phabricator.status.closed': b'green',
@@ -1220,9 +1218,8 @@
         b'phabricator.action.%s' % action,
     )
     drevdesc = ui.label(b'D%d' % newrevid, b'phabricator.drev')
-    nodedesc = ui.label(bytes(ctx), b'phabricator.node')
-    desc = ui.label(ctx.description().split(b'\n')[0], b'phabricator.desc')
-    ui.write(_(b'%s - %s - %s: %s\n') % (drevdesc, actiondesc, nodedesc, desc))
+    summary = cmdutil.format_changeset_summary(ui, ctx, b'phabsend')
+    ui.write(_(b'%s - %s - %s\n') % (drevdesc, actiondesc, summary))
 
 
 def _amend_diff_properties(unfi, drevid, newnodes, diff):
@@ -1642,7 +1639,6 @@
     ui = repo.ui
     for rev in revs:
         ctx = repo[rev]
-        desc = ctx.description().splitlines()[0]
         oldnode, olddiff, drevid = oldmap.get(ctx.node(), (None, None, None))
         if drevid:
             drevdesc = ui.label(b'D%d' % drevid, b'phabricator.drev')
@@ -1650,11 +1646,10 @@
             drevdesc = ui.label(_(b'NEW'), b'phabricator.drev')
 
         ui.write(
-            _(b'%s - %s: %s\n')
+            _(b'%s - %s\n')
             % (
                 drevdesc,
-                ui.label(bytes(ctx), b'phabricator.node'),
-                ui.label(desc, b'phabricator.desc'),
+                cmdutil.format_changeset_summary(ui, ctx, b'phabsend'),
             )
         )
 
--- a/hgext/rebase.py	Mon Nov 02 14:26:19 2020 -0500
+++ b/hgext/rebase.py	Mon Nov 02 14:39:43 2020 -0500
@@ -146,20 +146,9 @@
 
 def _ctxdesc(ctx):
     """short description for a context"""
-    desc = b'%d:%s "%s"' % (
-        ctx.rev(),
-        ctx,
-        ctx.description().split(b'\n', 1)[0],
+    return cmdutil.format_changeset_summary(
+        ctx.repo().ui, ctx, command=b'rebase'
     )
-    repo = ctx.repo()
-    names = []
-    for nsname, ns in pycompat.iteritems(repo.names):
-        if nsname == b'branches':
-            continue
-        names.extend(ns.names(repo, ctx.node()))
-    if names:
-        desc += b' (%s)' % b' '.join(names)
-    return desc
 
 
 class rebaseruntime(object):
@@ -526,6 +515,21 @@
         ctx = repo[rev]
         if commitmsg is None:
             commitmsg = ctx.description()
+
+        # Skip replacement if collapsing, as that degenerates to p1 for all
+        # nodes.
+        if not self.collapsef:
+            cl = repo.changelog
+            commitmsg = rewriteutil.update_hash_refs(
+                repo,
+                commitmsg,
+                {
+                    cl.node(oldrev): [cl.node(newrev)]
+                    for oldrev, newrev in self.state.items()
+                    if newrev != revtodo
+                },
+            )
+
         date = self.date
         if date is None:
             date = ctx.date()
--- a/hgext/split.py	Mon Nov 02 14:26:19 2020 -0500
+++ b/hgext/split.py	Mon Nov 02 14:39:43 2020 -0500
@@ -143,8 +143,8 @@
                 b'HG: Splitting %s. So far it has been split into:\n'
             ) % short(ctx.node())
             for c in committed:
-                firstline = c.description().split(b'\n', 1)[0]
-                header += _(b'HG: - %s: %s\n') % (short(c.node()), firstline)
+                summary = cmdutil.format_changeset_summary(ui, c, b'split')
+                header += _(b'HG: - %s\n') % summary
             header += _(
                 b'HG: Write commit message for the next split changeset.\n'
             )
--- a/hgext/sqlitestore.py	Mon Nov 02 14:26:19 2020 -0500
+++ b/hgext/sqlitestore.py	Mon Nov 02 14:39:43 2020 -0500
@@ -674,9 +674,10 @@
         linkmapper,
         transaction,
         addrevisioncb=None,
+        duplicaterevisioncb=None,
         maybemissingparents=False,
     ):
-        nodes = []
+        empty = True
 
         for node, p1, p2, linknode, deltabase, delta, wireflags in deltas:
             storeflags = 0
@@ -715,8 +716,6 @@
 
             linkrev = linkmapper(linknode)
 
-            nodes.append(node)
-
             if node in self._revisions:
                 # Possibly reset parents to make them proper.
                 entry = self._revisions[node]
@@ -741,6 +740,9 @@
                         (self._nodetorev[p1], entry.flags, entry.rid),
                     )
 
+                if duplicaterevisioncb:
+                    duplicaterevisioncb(self, node)
+                empty = False
                 continue
 
             if deltabase == nullid:
@@ -763,8 +765,9 @@
 
             if addrevisioncb:
                 addrevisioncb(self, node)
+            empty = False
 
-        return nodes
+        return not empty
 
     def censorrevision(self, tr, censornode, tombstone=b''):
         tombstone = storageutil.packmeta({b'censored': tombstone}, b'')
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial/bundlecaches.py	Mon Nov 02 14:39:43 2020 -0500
@@ -0,0 +1,424 @@
+# bundlecaches.py - utility to deal with pre-computed bundle for servers
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2 or any later version.
+
+from .i18n import _
+
+from .thirdparty import attr
+
+from . import (
+    error,
+    sslutil,
+    util,
+)
+from .utils import stringutil
+
+urlreq = util.urlreq
+
+CB_MANIFEST_FILE = b'clonebundles.manifest'
+
+
+@attr.s
+class bundlespec(object):
+    compression = attr.ib()
+    wirecompression = attr.ib()
+    version = attr.ib()
+    wireversion = attr.ib()
+    params = attr.ib()
+    contentopts = attr.ib()
+
+
+# Maps bundle version human names to changegroup versions.
+_bundlespeccgversions = {
+    b'v1': b'01',
+    b'v2': b'02',
+    b'packed1': b's1',
+    b'bundle2': b'02',  # legacy
+}
+
+# Maps bundle version with content opts to choose which part to bundle
+_bundlespeccontentopts = {
+    b'v1': {
+        b'changegroup': True,
+        b'cg.version': b'01',
+        b'obsolescence': False,
+        b'phases': False,
+        b'tagsfnodescache': False,
+        b'revbranchcache': False,
+    },
+    b'v2': {
+        b'changegroup': True,
+        b'cg.version': b'02',
+        b'obsolescence': False,
+        b'phases': False,
+        b'tagsfnodescache': True,
+        b'revbranchcache': True,
+    },
+    b'packed1': {b'cg.version': b's1'},
+}
+_bundlespeccontentopts[b'bundle2'] = _bundlespeccontentopts[b'v2']
+
+_bundlespecvariants = {
+    b"streamv2": {
+        b"changegroup": False,
+        b"streamv2": True,
+        b"tagsfnodescache": False,
+        b"revbranchcache": False,
+    }
+}
+
+# Compression engines allowed in version 1. THIS SHOULD NEVER CHANGE.
+_bundlespecv1compengines = {b'gzip', b'bzip2', b'none'}
+
+
+def parsebundlespec(repo, spec, strict=True):
+    """Parse a bundle string specification into parts.
+
+    Bundle specifications denote a well-defined bundle/exchange format.
+    The content of a given specification should not change over time in
+    order to ensure that bundles produced by a newer version of Mercurial are
+    readable from an older version.
+
+    The string currently has the form:
+
+       <compression>-<type>[;<parameter0>[;<parameter1>]]
+
+    Where <compression> is one of the supported compression formats
+    and <type> is (currently) a version string. A ";" can follow the type and
+    all text afterwards is interpreted as URI encoded, ";" delimited key=value
+    pairs.
+
+    If ``strict`` is True (the default) <compression> is required. Otherwise,
+    it is optional.
+
+    Returns a bundlespec object of (compression, version, parameters).
+    Compression will be ``None`` if not in strict mode and a compression isn't
+    defined.
+
+    An ``InvalidBundleSpecification`` is raised when the specification is
+    not syntactically well formed.
+
+    An ``UnsupportedBundleSpecification`` is raised when the compression or
+    bundle type/version is not recognized.
+
+    Note: this function will likely eventually return a more complex data
+    structure, including bundle2 part information.
+    """
+
+    def parseparams(s):
+        if b';' not in s:
+            return s, {}
+
+        params = {}
+        version, paramstr = s.split(b';', 1)
+
+        for p in paramstr.split(b';'):
+            if b'=' not in p:
+                raise error.InvalidBundleSpecification(
+                    _(
+                        b'invalid bundle specification: '
+                        b'missing "=" in parameter: %s'
+                    )
+                    % p
+                )
+
+            key, value = p.split(b'=', 1)
+            key = urlreq.unquote(key)
+            value = urlreq.unquote(value)
+            params[key] = value
+
+        return version, params
+
+    if strict and b'-' not in spec:
+        raise error.InvalidBundleSpecification(
+            _(
+                b'invalid bundle specification; '
+                b'must be prefixed with compression: %s'
+            )
+            % spec
+        )
+
+    if b'-' in spec:
+        compression, version = spec.split(b'-', 1)
+
+        if compression not in util.compengines.supportedbundlenames:
+            raise error.UnsupportedBundleSpecification(
+                _(b'%s compression is not supported') % compression
+            )
+
+        version, params = parseparams(version)
+
+        if version not in _bundlespeccgversions:
+            raise error.UnsupportedBundleSpecification(
+                _(b'%s is not a recognized bundle version') % version
+            )
+    else:
+        # Value could be just the compression or just the version, in which
+        # case some defaults are assumed (but only when not in strict mode).
+        assert not strict
+
+        spec, params = parseparams(spec)
+
+        if spec in util.compengines.supportedbundlenames:
+            compression = spec
+            version = b'v1'
+            # Generaldelta repos require v2.
+            if b'generaldelta' in repo.requirements:
+                version = b'v2'
+            # Modern compression engines require v2.
+            if compression not in _bundlespecv1compengines:
+                version = b'v2'
+        elif spec in _bundlespeccgversions:
+            if spec == b'packed1':
+                compression = b'none'
+            else:
+                compression = b'bzip2'
+            version = spec
+        else:
+            raise error.UnsupportedBundleSpecification(
+                _(b'%s is not a recognized bundle specification') % spec
+            )
+
+    # Bundle version 1 only supports a known set of compression engines.
+    if version == b'v1' and compression not in _bundlespecv1compengines:
+        raise error.UnsupportedBundleSpecification(
+            _(b'compression engine %s is not supported on v1 bundles')
+            % compression
+        )
+
+    # The specification for packed1 can optionally declare the data formats
+    # required to apply it. If we see this metadata, compare against what the
+    # repo supports and error if the bundle isn't compatible.
+    if version == b'packed1' and b'requirements' in params:
+        requirements = set(params[b'requirements'].split(b','))
+        missingreqs = requirements - repo.supportedformats
+        if missingreqs:
+            raise error.UnsupportedBundleSpecification(
+                _(b'missing support for repository features: %s')
+                % b', '.join(sorted(missingreqs))
+            )
+
+    # Compute contentopts based on the version
+    contentopts = _bundlespeccontentopts.get(version, {}).copy()
+
+    # Process the variants
+    if b"stream" in params and params[b"stream"] == b"v2":
+        variant = _bundlespecvariants[b"streamv2"]
+        contentopts.update(variant)
+
+    engine = util.compengines.forbundlename(compression)
+    compression, wirecompression = engine.bundletype()
+    wireversion = _bundlespeccgversions[version]
+
+    return bundlespec(
+        compression, wirecompression, version, wireversion, params, contentopts
+    )
+
+
+def parseclonebundlesmanifest(repo, s):
+    """Parses the raw text of a clone bundles manifest.
+
+    Returns a list of dicts. The dicts have a ``URL`` key corresponding
+    to the URL and other keys are the attributes for the entry.
+    """
+    m = []
+    for line in s.splitlines():
+        fields = line.split()
+        if not fields:
+            continue
+        attrs = {b'URL': fields[0]}
+        for rawattr in fields[1:]:
+            key, value = rawattr.split(b'=', 1)
+            key = util.urlreq.unquote(key)
+            value = util.urlreq.unquote(value)
+            attrs[key] = value
+
+            # Parse BUNDLESPEC into components. This makes client-side
+            # preferences easier to specify since you can prefer a single
+            # component of the BUNDLESPEC.
+            if key == b'BUNDLESPEC':
+                try:
+                    bundlespec = parsebundlespec(repo, value)
+                    attrs[b'COMPRESSION'] = bundlespec.compression
+                    attrs[b'VERSION'] = bundlespec.version
+                except error.InvalidBundleSpecification:
+                    pass
+                except error.UnsupportedBundleSpecification:
+                    pass
+
+        m.append(attrs)
+
+    return m
+
+
+def isstreamclonespec(bundlespec):
+    # Stream clone v1
+    if bundlespec.wirecompression == b'UN' and bundlespec.wireversion == b's1':
+        return True
+
+    # Stream clone v2
+    if (
+        bundlespec.wirecompression == b'UN'
+        and bundlespec.wireversion == b'02'
+        and bundlespec.contentopts.get(b'streamv2')
+    ):
+        return True
+
+    return False
+
+
+def filterclonebundleentries(repo, entries, streamclonerequested=False):
+    """Remove incompatible clone bundle manifest entries.
+
+    Accepts a list of entries parsed with ``parseclonebundlesmanifest``
+    and returns a new list consisting of only the entries that this client
+    should be able to apply.
+
+    There is no guarantee we'll be able to apply all returned entries because
+    the metadata we use to filter on may be missing or wrong.
+    """
+    newentries = []
+    for entry in entries:
+        spec = entry.get(b'BUNDLESPEC')
+        if spec:
+            try:
+                bundlespec = parsebundlespec(repo, spec, strict=True)
+
+                # If a stream clone was requested, filter out non-streamclone
+                # entries.
+                if streamclonerequested and not isstreamclonespec(bundlespec):
+                    repo.ui.debug(
+                        b'filtering %s because not a stream clone\n'
+                        % entry[b'URL']
+                    )
+                    continue
+
+            except error.InvalidBundleSpecification as e:
+                repo.ui.debug(stringutil.forcebytestr(e) + b'\n')
+                continue
+            except error.UnsupportedBundleSpecification as e:
+                repo.ui.debug(
+                    b'filtering %s because unsupported bundle '
+                    b'spec: %s\n' % (entry[b'URL'], stringutil.forcebytestr(e))
+                )
+                continue
+        # If we don't have a spec and requested a stream clone, we don't know
+        # what the entry is so don't attempt to apply it.
+        elif streamclonerequested:
+            repo.ui.debug(
+                b'filtering %s because cannot determine if a stream '
+                b'clone bundle\n' % entry[b'URL']
+            )
+            continue
+
+        if b'REQUIRESNI' in entry and not sslutil.hassni:
+            repo.ui.debug(
+                b'filtering %s because SNI not supported\n' % entry[b'URL']
+            )
+            continue
+
+        if b'REQUIREDRAM' in entry:
+            try:
+                requiredram = util.sizetoint(entry[b'REQUIREDRAM'])
+            except error.ParseError:
+                repo.ui.debug(
+                    b'filtering %s due to a bad REQUIREDRAM attribute\n'
+                    % entry[b'URL']
+                )
+                continue
+            actualram = repo.ui.estimatememory()
+            if actualram is not None and actualram * 0.66 < requiredram:
+                repo.ui.debug(
+                    b'filtering %s as it needs more than 2/3 of system memory\n'
+                    % entry[b'URL']
+                )
+                continue
+
+        newentries.append(entry)
+
+    return newentries
+
+
+class clonebundleentry(object):
+    """Represents an item in a clone bundles manifest.
+
+    This rich class is needed to support sorting since sorted() in Python 3
+    doesn't support ``cmp`` and our comparison is complex enough that ``key=``
+    won't work.
+    """
+
+    def __init__(self, value, prefers):
+        self.value = value
+        self.prefers = prefers
+
+    def _cmp(self, other):
+        for prefkey, prefvalue in self.prefers:
+            avalue = self.value.get(prefkey)
+            bvalue = other.value.get(prefkey)
+
+            # Special case for b missing attribute and a matches exactly.
+            if avalue is not None and bvalue is None and avalue == prefvalue:
+                return -1
+
+            # Special case for a missing attribute and b matches exactly.
+            if bvalue is not None and avalue is None and bvalue == prefvalue:
+                return 1
+
+            # We can't compare unless attribute present on both.
+            if avalue is None or bvalue is None:
+                continue
+
+            # Same values should fall back to next attribute.
+            if avalue == bvalue:
+                continue
+
+            # Exact matches come first.
+            if avalue == prefvalue:
+                return -1
+            if bvalue == prefvalue:
+                return 1
+
+            # Fall back to next attribute.
+            continue
+
+        # If we got here we couldn't sort by attributes and prefers. Fall
+        # back to index order.
+        return 0
+
+    def __lt__(self, other):
+        return self._cmp(other) < 0
+
+    def __gt__(self, other):
+        return self._cmp(other) > 0
+
+    def __eq__(self, other):
+        return self._cmp(other) == 0
+
+    def __le__(self, other):
+        return self._cmp(other) <= 0
+
+    def __ge__(self, other):
+        return self._cmp(other) >= 0
+
+    def __ne__(self, other):
+        return self._cmp(other) != 0
+
+
+def sortclonebundleentries(ui, entries):
+    prefers = ui.configlist(b'ui', b'clonebundleprefers')
+    if not prefers:
+        return list(entries)
+
+    def _split(p):
+        if b'=' not in p:
+            hint = _(b"each comma separated item should be key=value pairs")
+            raise error.Abort(
+                _(b"invalid ui.clonebundleprefers item: %s") % p, hint=hint
+            )
+        return p.split(b'=', 1)
+
+    prefers = [_split(p) for p in prefers]
+
+    items = sorted(clonebundleentry(v, prefers) for v in entries)
+    return [i.value for i in items]
--- a/mercurial/changegroup.py	Mon Nov 02 14:26:19 2020 -0500
+++ b/mercurial/changegroup.py	Mon Nov 02 14:39:43 2020 -0500
@@ -316,20 +316,29 @@
             self.callback = progress.increment
 
             efilesset = set()
+            cgnodes = []
+
+            def ondupchangelog(cl, node):
+                if cl.rev(node) < clstart:
+                    cgnodes.append(node)
 
             def onchangelog(cl, node):
                 efilesset.update(cl.readfiles(node))
 
             self.changelogheader()
             deltas = self.deltaiter()
-            cgnodes = cl.addgroup(deltas, csmap, trp, addrevisioncb=onchangelog)
-            efiles = len(efilesset)
-
-            if not cgnodes:
+            if not cl.addgroup(
+                deltas,
+                csmap,
+                trp,
+                addrevisioncb=onchangelog,
+                duplicaterevisioncb=ondupchangelog,
+            ):
                 repo.ui.develwarn(
                     b'applied empty changelog from changegroup',
                     config=b'warn-empty-changegroup',
                 )
+            efiles = len(efilesset)
             clend = len(cl)
             changesets = clend - clstart
             progress.complete()
@@ -356,7 +365,7 @@
                 for cset in pycompat.xrange(clstart, clend):
                     mfnode = cl.changelogrevision(cset).manifest
                     mfest = ml[mfnode].readdelta()
-                    # store file cgnodes we must see
+                    # store file nodes we must see
                     for f, n in pycompat.iteritems(mfest):
                         needfiles.setdefault(f, set()).add(n)
 
@@ -414,7 +423,7 @@
                     **pycompat.strkwargs(hookargs)
                 )
 
-            added = [cl.node(r) for r in pycompat.xrange(clstart, clend)]
+            added = pycompat.xrange(clstart, clend)
             phaseall = None
             if srctype in (b'push', b'serve'):
                 # Old servers can not push the boundary themselves.
@@ -436,7 +445,8 @@
             if added:
                 phases.registernew(repo, tr, targetphase, added)
             if phaseall is not None:
-                phases.advanceboundary(repo, tr, phaseall, cgnodes)
+                phases.advanceboundary(repo, tr, phaseall, cgnodes, revs=added)
+                cgnodes = []
 
             if changesets > 0:
 
@@ -449,9 +459,9 @@
 
                     repo.hook(b"changegroup", **pycompat.strkwargs(hookargs))
 
-                    for n in added:
+                    for rev in added:
                         args = hookargs.copy()
-                        args[b'node'] = hex(n)
+                        args[b'node'] = hex(cl.node(rev))
                         del args[b'node_last']
                         repo.hook(b"incoming", **pycompat.strkwargs(args))
 
--- a/mercurial/cmdutil.py	Mon Nov 02 14:26:19 2020 -0500
+++ b/mercurial/cmdutil.py	Mon Nov 02 14:39:43 2020 -0500
@@ -1210,6 +1210,30 @@
     return t.renderdefault(mapping)
 
 
+def format_changeset_summary(ui, ctx, command=None, default_spec=None):
+    """Format a changeset summary (one line)."""
+    spec = None
+    if command:
+        spec = ui.config(
+            b'command-templates', b'oneline-summary.%s' % command, None
+        )
+    if not spec:
+        spec = ui.config(b'command-templates', b'oneline-summary')
+    if not spec:
+        spec = default_spec
+    if not spec:
+        spec = (
+            b'{separate(" ", '
+            b'label("oneline-summary.changeset", "{rev}:{node|short}")'
+            b', '
+            b'join(filter(namespaces % "{ifeq(namespace, "branches", "", join(names % "{label("oneline-summary.{namespace}", name)}", " "))}"), " ")'
+            b')} '
+            b'"{label("oneline-summary.desc", desc|firstline)}"'
+        )
+    text = rendertemplate(ctx, spec)
+    return text.split(b'\n')[0]
+
+
 def _buildfntemplate(pat, total=None, seqno=None, revwidth=None, pathname=None):
     r"""Convert old-style filename format string to template string
 
--- a/mercurial/commands.py	Mon Nov 02 14:26:19 2020 -0500
+++ b/mercurial/commands.py	Mon Nov 02 14:39:43 2020 -0500
@@ -26,6 +26,7 @@
     archival,
     bookmarks,
     bundle2,
+    bundlecaches,
     changegroup,
     cmdutil,
     copies,
@@ -1542,7 +1543,9 @@
 
     bundletype = opts.get(b'type', b'bzip2').lower()
     try:
-        bundlespec = exchange.parsebundlespec(repo, bundletype, strict=False)
+        bundlespec = bundlecaches.parsebundlespec(
+            repo, bundletype, strict=False
+        )
     except error.UnsupportedBundleSpecification as e:
         raise error.Abort(
             pycompat.bytestr(e),
@@ -2013,8 +2016,7 @@
 
     opts = pycompat.byteskwargs(opts)
     if opts.get(b'subrepos'):
-        if opts.get(b'amend'):
-            raise error.Abort(_(b'cannot amend with --subrepos'))
+        cmdutil.check_incompatible_arguments(opts, b'subrepos', [b'amend'])
         # Let --subrepos on the command line override config setting.
         ui.setconfig(b'ui', b'commitsubrepos', True, b'commit')
 
@@ -2138,6 +2140,7 @@
             None,
             _(b'edit shared source repository config (EXPERIMENTAL)'),
         ),
+        (b'', b'non-shared', None, _(b'edit non shared config (EXPERIMENTAL)')),
         (b'g', b'global', None, _(b'edit global config')),
     ]
     + formatteropts,
@@ -2168,6 +2171,9 @@
 
     .. container:: verbose
 
+      --non-shared flag is used to edit `.hg/hgrc-not-shared` config file.
+      This file is not shared across shares when in share-safe mode.
+
       Template:
 
       The following keywords are supported. See also :hg:`help templates`.
@@ -2185,7 +2191,7 @@
     """
 
     opts = pycompat.byteskwargs(opts)
-    editopts = (b'edit', b'local', b'global', b'shared')
+    editopts = (b'edit', b'local', b'global', b'shared', b'non_shared')
     if any(opts.get(o) for o in editopts):
         cmdutil.check_at_most_one_arg(opts, *editopts[1:])
         if opts.get(b'local'):
@@ -2207,6 +2213,8 @@
                         )
                     )
             paths = [vfsmod.vfs(repo.sharedpath).join(b'hgrc')]
+        elif opts.get(b'non_shared'):
+            paths = [repo.vfs.join(b'hgrc-not-shared')]
         else:
             paths = rcutil.userrcpath()
 
@@ -2341,7 +2349,7 @@
     ]
     + walkopts
     + dryrunopts,
-    _(b'[OPTION]... SOURCE... DEST'),
+    _(b'[OPTION]... (SOURCE... DEST | --forget DEST...)'),
     helpcategory=command.CATEGORY_FILE_CONTENTS,
 )
 def copy(ui, repo, *pats, **opts):
@@ -4564,7 +4572,7 @@
 
     See :hg:`help templates` for more about pre-packaged styles and
     specifying custom templates. The default template used by the log
-    command can be customized via the ``ui.logtemplate`` configuration
+    command can be customized via the ``command-templates.log`` configuration
     setting.
 
     Returns 0 on success.
--- a/mercurial/commit.py	Mon Nov 02 14:26:19 2020 -0500
+++ b/mercurial/commit.py	Mon Nov 02 14:39:43 2020 -0500
@@ -112,7 +112,7 @@
             # be compliant anyway
             #
             # if minimal phase was 0 we don't need to retract anything
-            phases.registernew(repo, tr, targetphase, [n])
+            phases.registernew(repo, tr, targetphase, [repo[n].rev()])
         return n
 
 
--- a/mercurial/config.py	Mon Nov 02 14:26:19 2020 -0500
+++ b/mercurial/config.py	Mon Nov 02 14:39:43 2020 -0500
@@ -200,7 +200,10 @@
                 self._unset.append((section, name))
                 continue
 
-            raise error.ParseError(l.rstrip(), (b"%s:%d" % (src, line)))
+            message = l.rstrip()
+            if l.startswith(b' '):
+                message = b"unexpected leading whitespace: %s" % message
+            raise error.ParseError(message, (b"%s:%d" % (src, line)))
 
     def read(self, path, fp=None, sections=None, remap=None):
         if not fp:
--- a/mercurial/configitems.py	Mon Nov 02 14:26:19 2020 -0500
+++ b/mercurial/configitems.py	Mon Nov 02 14:39:43 2020 -0500
@@ -223,6 +223,43 @@
 coreconfigitem(
     b'color', b'pagermode', default=dynamicdefault,
 )
+coreconfigitem(
+    b'command-templates',
+    b'graphnode',
+    default=None,
+    alias=[(b'ui', b'graphnodetemplate')],
+)
+coreconfigitem(
+    b'command-templates', b'log', default=None, alias=[(b'ui', b'logtemplate')],
+)
+coreconfigitem(
+    b'command-templates',
+    b'mergemarker',
+    default=(
+        b'{node|short} '
+        b'{ifeq(tags, "tip", "", '
+        b'ifeq(tags, "", "", "{tags} "))}'
+        b'{if(bookmarks, "{bookmarks} ")}'
+        b'{ifeq(branch, "default", "", "{branch} ")}'
+        b'- {author|user}: {desc|firstline}'
+    ),
+    alias=[(b'ui', b'mergemarkertemplate')],
+)
+coreconfigitem(
+    b'command-templates',
+    b'pre-merge-tool-output',
+    default=None,
+    alias=[(b'ui', b'pre-merge-tool-output-template')],
+)
+coreconfigitem(
+    b'command-templates', b'oneline-summary', default=None,
+)
+coreconfigitem(
+    b'command-templates',
+    b'oneline-summary.*',
+    default=dynamicdefault,
+    generic=True,
+)
 _registerdiffopts(section=b'commands', configprefix=b'commit.interactive.')
 coreconfigitem(
     b'commands', b'commit.post-status', default=False,
@@ -939,7 +976,7 @@
 coreconfigitem(
     b'merge-tools',
     br'.*\.mergemarkertemplate$',
-    default=dynamicdefault,  # take from ui.mergemarkertemplate
+    default=dynamicdefault,  # take from command-templates.mergemarker
     generic=True,
     priority=-1,
 )
@@ -1288,9 +1325,6 @@
     b'ui', b'formatted', default=None,
 )
 coreconfigitem(
-    b'ui', b'graphnodetemplate', default=None,
-)
-coreconfigitem(
     b'ui', b'interactive', default=None,
 )
 coreconfigitem(
@@ -1306,27 +1340,12 @@
     b'ui', b'logblockedtimes', default=False,
 )
 coreconfigitem(
-    b'ui', b'logtemplate', default=None,
-)
-coreconfigitem(
     b'ui', b'merge', default=None,
 )
 coreconfigitem(
     b'ui', b'mergemarkers', default=b'basic',
 )
 coreconfigitem(
-    b'ui',
-    b'mergemarkertemplate',
-    default=(
-        b'{node|short} '
-        b'{ifeq(tags, "tip", "", '
-        b'ifeq(tags, "", "", "{tags} "))}'
-        b'{if(bookmarks, "{bookmarks} ")}'
-        b'{ifeq(branch, "default", "", "{branch} ")}'
-        b'- {author|user}: {desc|firstline}'
-    ),
-)
-coreconfigitem(
     b'ui', b'message-output', default=b'stdio',
 )
 coreconfigitem(
@@ -1342,9 +1361,6 @@
     b'ui', b'patch', default=None,
 )
 coreconfigitem(
-    b'ui', b'pre-merge-tool-output-template', default=None,
-)
-coreconfigitem(
     b'ui', b'portablefilenames', default=b'warn',
 )
 coreconfigitem(
--- a/mercurial/copies.py	Mon Nov 02 14:26:19 2020 -0500
+++ b/mercurial/copies.py	Mon Nov 02 14:39:43 2020 -0500
@@ -400,7 +400,10 @@
             elif changes is not None and dest in changes.merged:
                 minor[dest] = value
             elif not isancestor(new_tt, other_tt):
-                minor[dest] = value
+                if value[1] is not None:
+                    minor[dest] = value
+                elif isancestor(other_tt, new_tt):
+                    minor[dest] = value
 
 
 def _revinfo_getter_extra(repo):
--- a/mercurial/dispatch.py	Mon Nov 02 14:26:19 2020 -0500
+++ b/mercurial/dispatch.py	Mon Nov 02 14:39:43 2020 -0500
@@ -36,13 +36,16 @@
     help,
     hg,
     hook,
+    localrepo,
     profiling,
     pycompat,
     rcutil,
     registrar,
+    requirements as requirementsmod,
     scmutil,
     ui as uimod,
     util,
+    vfs,
 )
 
 from .utils import (
@@ -243,15 +246,13 @@
     if isinstance(inst, error.UnknownIdentifier):
         # make sure to check fileset first, as revset can invoke fileset
         similar = _getsimilar(inst.symbols, inst.function)
-    if len(inst.args) > 1:
+    if inst.location is not None:
         write(
             _(b"hg: parse error at %s: %s\n")
-            % (pycompat.bytestr(inst.args[1]), inst.args[0])
+            % (pycompat.bytestr(inst.location), inst.message)
         )
-        if inst.args[0].startswith(b' '):
-            write(_(b"unexpected leading whitespace\n"))
     else:
-        write(_(b"hg: parse error: %s\n") % inst.args[0])
+        write(_(b"hg: parse error: %s\n") % inst.message)
         _reportsimilar(write, similar)
     if inst.hint:
         write(_(b"(%s)\n") % inst.hint)
@@ -941,6 +942,29 @@
     return ret
 
 
+def _readsharedsourceconfig(ui, path):
+    """if the current repository is shared one, this tries to read
+    .hg/hgrc of shared source if we are in share-safe mode
+
+    Config read is loaded into the ui object passed
+
+    This should be called before reading .hg/hgrc or the main repo
+    as that overrides config set in shared source"""
+    try:
+        with open(os.path.join(path, b".hg", b"requires"), "rb") as fp:
+            requirements = set(fp.read().splitlines())
+            if not (
+                requirementsmod.SHARESAFE_REQUIREMENT in requirements
+                and requirementsmod.SHARED_REQUIREMENT in requirements
+            ):
+                return
+            hgvfs = vfs.vfs(os.path.join(path, b".hg"))
+            sharedvfs = localrepo._getsharedvfs(hgvfs, requirements)
+            ui.readconfig(sharedvfs.join(b"hgrc"), path)
+    except IOError:
+        pass
+
+
 def _getlocal(ui, rpath, wd=None):
     """Return (path, local ui object) for the given target path.
 
@@ -961,13 +985,17 @@
     else:
         lui = ui.copy()
         if rcutil.use_repo_hgrc():
+            _readsharedsourceconfig(lui, path)
             lui.readconfig(os.path.join(path, b".hg", b"hgrc"), path)
+            lui.readconfig(os.path.join(path, b".hg", b"hgrc-not-shared"), path)
 
     if rpath:
         path = lui.expandpath(rpath)
         lui = ui.copy()
         if rcutil.use_repo_hgrc():
+            _readsharedsourceconfig(lui, path)
             lui.readconfig(os.path.join(path, b".hg", b"hgrc"), path)
+            lui.readconfig(os.path.join(path, b".hg", b"hgrc-not-shared"), path)
 
     return path, lui
 
--- a/mercurial/error.py	Mon Nov 02 14:26:19 2020 -0500
+++ b/mercurial/error.py	Mon Nov 02 14:39:43 2020 -0500
@@ -48,7 +48,7 @@
 
 
 class RevlogError(StorageError):
-    __bytes__ = _tobytes
+    pass
 
 
 class SidedataHashError(RevlogError):
@@ -224,6 +224,17 @@
 class ParseError(Hint, Exception):
     """Raised when parsing config files and {rev,file}sets (msg[, pos])"""
 
+    def __init__(self, message, location=None, hint=None):
+        self.message = message
+        self.location = location
+        self.hint = hint
+        # Pass the message and possibly location into the Exception constructor
+        # to help code that looks for exc.args.
+        if location is not None:
+            Exception.__init__(self, message, location)
+        else:
+            Exception.__init__(self, message)
+
     __bytes__ = _tobytes
 
 
--- a/mercurial/exchange.py	Mon Nov 02 14:26:19 2020 -0500
+++ b/mercurial/exchange.py	Mon Nov 02 14:39:43 2020 -0500
@@ -16,10 +16,10 @@
     nullid,
     nullrev,
 )
-from .thirdparty import attr
 from . import (
     bookmarks as bookmod,
     bundle2,
+    bundlecaches,
     changegroup,
     discovery,
     error,
@@ -34,7 +34,6 @@
     pycompat,
     requirements,
     scmutil,
-    sslutil,
     streamclone,
     url as urlmod,
     util,
@@ -50,202 +49,6 @@
 
 _NARROWACL_SECTION = b'narrowacl'
 
-# Maps bundle version human names to changegroup versions.
-_bundlespeccgversions = {
-    b'v1': b'01',
-    b'v2': b'02',
-    b'packed1': b's1',
-    b'bundle2': b'02',  # legacy
-}
-
-# Maps bundle version with content opts to choose which part to bundle
-_bundlespeccontentopts = {
-    b'v1': {
-        b'changegroup': True,
-        b'cg.version': b'01',
-        b'obsolescence': False,
-        b'phases': False,
-        b'tagsfnodescache': False,
-        b'revbranchcache': False,
-    },
-    b'v2': {
-        b'changegroup': True,
-        b'cg.version': b'02',
-        b'obsolescence': False,
-        b'phases': False,
-        b'tagsfnodescache': True,
-        b'revbranchcache': True,
-    },
-    b'packed1': {b'cg.version': b's1'},
-}
-_bundlespeccontentopts[b'bundle2'] = _bundlespeccontentopts[b'v2']
-
-_bundlespecvariants = {
-    b"streamv2": {
-        b"changegroup": False,
-        b"streamv2": True,
-        b"tagsfnodescache": False,
-        b"revbranchcache": False,
-    }
-}
-
-# Compression engines allowed in version 1. THIS SHOULD NEVER CHANGE.
-_bundlespecv1compengines = {b'gzip', b'bzip2', b'none'}
-
-
-@attr.s
-class bundlespec(object):
-    compression = attr.ib()
-    wirecompression = attr.ib()
-    version = attr.ib()
-    wireversion = attr.ib()
-    params = attr.ib()
-    contentopts = attr.ib()
-
-
-def parsebundlespec(repo, spec, strict=True):
-    """Parse a bundle string specification into parts.
-
-    Bundle specifications denote a well-defined bundle/exchange format.
-    The content of a given specification should not change over time in
-    order to ensure that bundles produced by a newer version of Mercurial are
-    readable from an older version.
-
-    The string currently has the form:
-
-       <compression>-<type>[;<parameter0>[;<parameter1>]]
-
-    Where <compression> is one of the supported compression formats
-    and <type> is (currently) a version string. A ";" can follow the type and
-    all text afterwards is interpreted as URI encoded, ";" delimited key=value
-    pairs.
-
-    If ``strict`` is True (the default) <compression> is required. Otherwise,
-    it is optional.
-
-    Returns a bundlespec object of (compression, version, parameters).
-    Compression will be ``None`` if not in strict mode and a compression isn't
-    defined.
-
-    An ``InvalidBundleSpecification`` is raised when the specification is
-    not syntactically well formed.
-
-    An ``UnsupportedBundleSpecification`` is raised when the compression or
-    bundle type/version is not recognized.
-
-    Note: this function will likely eventually return a more complex data
-    structure, including bundle2 part information.
-    """
-
-    def parseparams(s):
-        if b';' not in s:
-            return s, {}
-
-        params = {}
-        version, paramstr = s.split(b';', 1)
-
-        for p in paramstr.split(b';'):
-            if b'=' not in p:
-                raise error.InvalidBundleSpecification(
-                    _(
-                        b'invalid bundle specification: '
-                        b'missing "=" in parameter: %s'
-                    )
-                    % p
-                )
-
-            key, value = p.split(b'=', 1)
-            key = urlreq.unquote(key)
-            value = urlreq.unquote(value)
-            params[key] = value
-
-        return version, params
-
-    if strict and b'-' not in spec:
-        raise error.InvalidBundleSpecification(
-            _(
-                b'invalid bundle specification; '
-                b'must be prefixed with compression: %s'
-            )
-            % spec
-        )
-
-    if b'-' in spec:
-        compression, version = spec.split(b'-', 1)
-
-        if compression not in util.compengines.supportedbundlenames:
-            raise error.UnsupportedBundleSpecification(
-                _(b'%s compression is not supported') % compression
-            )
-
-        version, params = parseparams(version)
-
-        if version not in _bundlespeccgversions:
-            raise error.UnsupportedBundleSpecification(
-                _(b'%s is not a recognized bundle version') % version
-            )
-    else:
-        # Value could be just the compression or just the version, in which
-        # case some defaults are assumed (but only when not in strict mode).
-        assert not strict
-
-        spec, params = parseparams(spec)
-
-        if spec in util.compengines.supportedbundlenames:
-            compression = spec
-            version = b'v1'
-            # Generaldelta repos require v2.
-            if b'generaldelta' in repo.requirements:
-                version = b'v2'
-            # Modern compression engines require v2.
-            if compression not in _bundlespecv1compengines:
-                version = b'v2'
-        elif spec in _bundlespeccgversions:
-            if spec == b'packed1':
-                compression = b'none'
-            else:
-                compression = b'bzip2'
-            version = spec
-        else:
-            raise error.UnsupportedBundleSpecification(
-                _(b'%s is not a recognized bundle specification') % spec
-            )
-
-    # Bundle version 1 only supports a known set of compression engines.
-    if version == b'v1' and compression not in _bundlespecv1compengines:
-        raise error.UnsupportedBundleSpecification(
-            _(b'compression engine %s is not supported on v1 bundles')
-            % compression
-        )
-
-    # The specification for packed1 can optionally declare the data formats
-    # required to apply it. If we see this metadata, compare against what the
-    # repo supports and error if the bundle isn't compatible.
-    if version == b'packed1' and b'requirements' in params:
-        requirements = set(params[b'requirements'].split(b','))
-        missingreqs = requirements - repo.supportedformats
-        if missingreqs:
-            raise error.UnsupportedBundleSpecification(
-                _(b'missing support for repository features: %s')
-                % b', '.join(sorted(missingreqs))
-            )
-
-    # Compute contentopts based on the version
-    contentopts = _bundlespeccontentopts.get(version, {}).copy()
-
-    # Process the variants
-    if b"stream" in params and params[b"stream"] == b"v2":
-        variant = _bundlespecvariants[b"streamv2"]
-        contentopts.update(variant)
-
-    engine = util.compengines.forbundlename(compression)
-    compression, wirecompression = engine.bundletype()
-    wireversion = _bundlespeccgversions[version]
-
-    return bundlespec(
-        compression, wirecompression, version, wireversion, params, contentopts
-    )
-
 
 def readbundle(ui, fh, fname, vfs=None):
     header = changegroup.readexactly(fh, 4)
@@ -2867,7 +2670,7 @@
     # attempt.
     pullop.clonebundleattempted = True
 
-    entries = parseclonebundlesmanifest(repo, res)
+    entries = bundlecaches.parseclonebundlesmanifest(repo, res)
     if not entries:
         repo.ui.note(
             _(
@@ -2877,7 +2680,7 @@
         )
         return
 
-    entries = filterclonebundleentries(
+    entries = bundlecaches.filterclonebundleentries(
         repo, entries, streamclonerequested=pullop.streamclonerequested
     )
 
@@ -2898,7 +2701,7 @@
         )
         return
 
-    entries = sortclonebundleentries(repo.ui, entries)
+    entries = bundlecaches.sortclonebundleentries(repo.ui, entries)
 
     url = entries[0][b'URL']
     repo.ui.status(_(b'applying clone bundle from %s\n') % url)
@@ -2923,214 +2726,6 @@
         )
 
 
-def parseclonebundlesmanifest(repo, s):
-    """Parses the raw text of a clone bundles manifest.
-
-    Returns a list of dicts. The dicts have a ``URL`` key corresponding
-    to the URL and other keys are the attributes for the entry.
-    """
-    m = []
-    for line in s.splitlines():
-        fields = line.split()
-        if not fields:
-            continue
-        attrs = {b'URL': fields[0]}
-        for rawattr in fields[1:]:
-            key, value = rawattr.split(b'=', 1)
-            key = urlreq.unquote(key)
-            value = urlreq.unquote(value)
-            attrs[key] = value
-
-            # Parse BUNDLESPEC into components. This makes client-side
-            # preferences easier to specify since you can prefer a single
-            # component of the BUNDLESPEC.
-            if key == b'BUNDLESPEC':
-                try:
-                    bundlespec = parsebundlespec(repo, value)
-                    attrs[b'COMPRESSION'] = bundlespec.compression
-                    attrs[b'VERSION'] = bundlespec.version
-                except error.InvalidBundleSpecification:
-                    pass
-                except error.UnsupportedBundleSpecification:
-                    pass
-
-        m.append(attrs)
-
-    return m
-
-
-def isstreamclonespec(bundlespec):
-    # Stream clone v1
-    if bundlespec.wirecompression == b'UN' and bundlespec.wireversion == b's1':
-        return True
-
-    # Stream clone v2
-    if (
-        bundlespec.wirecompression == b'UN'
-        and bundlespec.wireversion == b'02'
-        and bundlespec.contentopts.get(b'streamv2')
-    ):
-        return True
-
-    return False
-
-
-def filterclonebundleentries(repo, entries, streamclonerequested=False):
-    """Remove incompatible clone bundle manifest entries.
-
-    Accepts a list of entries parsed with ``parseclonebundlesmanifest``
-    and returns a new list consisting of only the entries that this client
-    should be able to apply.
-
-    There is no guarantee we'll be able to apply all returned entries because
-    the metadata we use to filter on may be missing or wrong.
-    """
-    newentries = []
-    for entry in entries:
-        spec = entry.get(b'BUNDLESPEC')
-        if spec:
-            try:
-                bundlespec = parsebundlespec(repo, spec, strict=True)
-
-                # If a stream clone was requested, filter out non-streamclone
-                # entries.
-                if streamclonerequested and not isstreamclonespec(bundlespec):
-                    repo.ui.debug(
-                        b'filtering %s because not a stream clone\n'
-                        % entry[b'URL']
-                    )
-                    continue
-
-            except error.InvalidBundleSpecification as e:
-                repo.ui.debug(stringutil.forcebytestr(e) + b'\n')
-                continue
-            except error.UnsupportedBundleSpecification as e:
-                repo.ui.debug(
-                    b'filtering %s because unsupported bundle '
-                    b'spec: %s\n' % (entry[b'URL'], stringutil.forcebytestr(e))
-                )
-                continue
-        # If we don't have a spec and requested a stream clone, we don't know
-        # what the entry is so don't attempt to apply it.
-        elif streamclonerequested:
-            repo.ui.debug(
-                b'filtering %s because cannot determine if a stream '
-                b'clone bundle\n' % entry[b'URL']
-            )
-            continue
-
-        if b'REQUIRESNI' in entry and not sslutil.hassni:
-            repo.ui.debug(
-                b'filtering %s because SNI not supported\n' % entry[b'URL']
-            )
-            continue
-
-        if b'REQUIREDRAM' in entry:
-            try:
-                requiredram = util.sizetoint(entry[b'REQUIREDRAM'])
-            except error.ParseError:
-                repo.ui.debug(
-                    b'filtering %s due to a bad REQUIREDRAM attribute\n'
-                    % entry[b'URL']
-                )
-                continue
-            actualram = repo.ui.estimatememory()
-            if actualram is not None and actualram * 0.66 < requiredram:
-                repo.ui.debug(
-                    b'filtering %s as it needs more than 2/3 of system memory\n'
-                    % entry[b'URL']
-                )
-                continue
-
-        newentries.append(entry)
-
-    return newentries
-
-
-class clonebundleentry(object):
-    """Represents an item in a clone bundles manifest.
-
-    This rich class is needed to support sorting since sorted() in Python 3
-    doesn't support ``cmp`` and our comparison is complex enough that ``key=``
-    won't work.
-    """
-
-    def __init__(self, value, prefers):
-        self.value = value
-        self.prefers = prefers
-
-    def _cmp(self, other):
-        for prefkey, prefvalue in self.prefers:
-            avalue = self.value.get(prefkey)
-            bvalue = other.value.get(prefkey)
-
-            # Special case for b missing attribute and a matches exactly.
-            if avalue is not None and bvalue is None and avalue == prefvalue:
-                return -1
-
-            # Special case for a missing attribute and b matches exactly.
-            if bvalue is not None and avalue is None and bvalue == prefvalue:
-                return 1
-
-            # We can't compare unless attribute present on both.
-            if avalue is None or bvalue is None:
-                continue
-
-            # Same values should fall back to next attribute.
-            if avalue == bvalue:
-                continue
-
-            # Exact matches come first.
-            if avalue == prefvalue:
-                return -1
-            if bvalue == prefvalue:
-                return 1
-
-            # Fall back to next attribute.
-            continue
-
-        # If we got here we couldn't sort by attributes and prefers. Fall
-        # back to index order.
-        return 0
-
-    def __lt__(self, other):
-        return self._cmp(other) < 0
-
-    def __gt__(self, other):
-        return self._cmp(other) > 0
-
-    def __eq__(self, other):
-        return self._cmp(other) == 0
-
-    def __le__(self, other):
-        return self._cmp(other) <= 0
-
-    def __ge__(self, other):
-        return self._cmp(other) >= 0
-
-    def __ne__(self, other):
-        return self._cmp(other) != 0
-
-
-def sortclonebundleentries(ui, entries):
-    prefers = ui.configlist(b'ui', b'clonebundleprefers')
-    if not prefers:
-        return list(entries)
-
-    def _split(p):
-        if b'=' not in p:
-            hint = _(b"each comma separated item should be key=value pairs")
-            raise error.Abort(
-                _(b"invalid ui.clonebundleprefers item: %s") % p, hint=hint
-            )
-        return p.split(b'=', 1)
-
-    prefers = [_split(p) for p in prefers]
-
-    items = sorted(clonebundleentry(v, prefers) for v in entries)
-    return [i.value for i in items]
-
-
 def trypullbundlefromurl(ui, repo, url):
     """Attempt to apply a bundle from a URL."""
     with repo.lock(), repo.transaction(b'bundleurl') as tr:
--- a/mercurial/exchangev2.py	Mon Nov 02 14:26:19 2020 -0500
+++ b/mercurial/exchangev2.py	Mon Nov 02 14:39:43 2020 -0500
@@ -79,7 +79,9 @@
     # Ensure all new changesets are draft by default. If the repo is
     # publishing, the phase will be adjusted by the loop below.
     if csetres[b'added']:
-        phases.registernew(repo, tr, phases.draft, csetres[b'added'])
+        phases.registernew(
+            repo, tr, phases.draft, [repo[n].rev() for n in csetres[b'added']]
+        )
 
     # And adjust the phase of all changesets accordingly.
     for phasenumber, phase in phases.phasenames.items():
@@ -343,16 +345,21 @@
     )
 
     manifestnodes = {}
+    added = []
 
     def linkrev(node):
         repo.ui.debug(b'add changeset %s\n' % short(node))
         # Linkrev for changelog is always self.
         return len(cl)
 
+    def ondupchangeset(cl, node):
+        added.append(node)
+
     def onchangeset(cl, node):
         progress.increment()
 
         revision = cl.changelogrevision(node)
+        added.append(node)
 
         # We need to preserve the mapping of changelog revision to node
         # so we can set the linkrev accordingly when manifests are added.
@@ -403,8 +410,12 @@
                 0,
             )
 
-    added = cl.addgroup(
-        iterrevisions(), linkrev, weakref.proxy(tr), addrevisioncb=onchangeset
+    cl.addgroup(
+        iterrevisions(),
+        linkrev,
+        weakref.proxy(tr),
+        addrevisioncb=onchangeset,
+        duplicaterevisioncb=ondupchangeset,
     )
 
     progress.complete()
@@ -516,12 +527,15 @@
             # Chomp off header object.
             next(objs)
 
-            added.extend(
-                rootmanifest.addgroup(
-                    iterrevisions(objs, progress),
-                    linkrevs.__getitem__,
-                    weakref.proxy(tr),
-                )
+            def onchangeset(cl, node):
+                added.append(node)
+
+            rootmanifest.addgroup(
+                iterrevisions(objs, progress),
+                linkrevs.__getitem__,
+                weakref.proxy(tr),
+                addrevisioncb=onchangeset,
+                duplicaterevisioncb=onchangeset,
             )
 
     progress.complete()
--- a/mercurial/filelog.py	Mon Nov 02 14:26:19 2020 -0500
+++ b/mercurial/filelog.py	Mon Nov 02 14:39:43 2020 -0500
@@ -139,6 +139,7 @@
         linkmapper,
         transaction,
         addrevisioncb=None,
+        duplicaterevisioncb=None,
         maybemissingparents=False,
     ):
         if maybemissingparents:
@@ -150,7 +151,11 @@
             )
 
         return self._revlog.addgroup(
-            deltas, linkmapper, transaction, addrevisioncb=addrevisioncb
+            deltas,
+            linkmapper,
+            transaction,
+            addrevisioncb=addrevisioncb,
+            duplicaterevisioncb=duplicaterevisioncb,
         )
 
     def getstrippoint(self, minlink):
--- a/mercurial/filemerge.py	Mon Nov 02 14:26:19 2020 -0500
+++ b/mercurial/filemerge.py	Mon Nov 02 14:39:43 2020 -0500
@@ -643,7 +643,7 @@
 
 
 def _describemerge(ui, repo, mynode, fcl, fcb, fco, env, toolpath, args):
-    tmpl = ui.config(b'ui', b'pre-merge-tool-output-template')
+    tmpl = ui.config(b'command-templates', b'pre-merge-tool-output')
     if not tmpl:
         return
 
@@ -831,7 +831,7 @@
     ca = fca.changectx()
 
     ui = repo.ui
-    template = ui.config(b'ui', b'mergemarkertemplate')
+    template = ui.config(b'command-templates', b'mergemarker')
     if tool is not None:
         template = _toolstr(ui, tool, b'mergemarkertemplate', template)
     template = templater.unquotestring(template)
@@ -1100,7 +1100,7 @@
             labeltool = None
             if markerstyle != b'basic':
                 # respect 'tool's mergemarkertemplate (which defaults to
-                # ui.mergemarkertemplate)
+                # command-templates.mergemarker)
                 labeltool = tool
             if internalmarkerstyle != b'basic' or markerstyle != b'basic':
                 premergelabels = _formatlabels(
--- a/mercurial/helptext/config.txt	Mon Nov 02 14:26:19 2020 -0500
+++ b/mercurial/helptext/config.txt	Mon Nov 02 14:39:43 2020 -0500
@@ -1549,11 +1549,11 @@
   (default: ``basic``)
 
 ``mergemarkertemplate``
-  This setting can be used to override ``mergemarkertemplate`` from the ``[ui]``
-  section on a per-tool basis; this applies to the ``$label``-prefixed variables
-  and to the conflict markers that are generated if ``premerge`` is ``keep` or
-  ``keep-merge3``. See the corresponding variable in ``[ui]`` for more
-  information.
+  This setting can be used to override ``mergemarker`` from the
+  ``[command-templates]`` section on a per-tool basis; this applies to the
+  ``$label``-prefixed variables and to the conflict markers that are generated
+  if ``premerge`` is ``keep` or ``keep-merge3``. See the corresponding variable
+  in ``[ui]`` for more information.
 
 .. container:: windows
 
@@ -2334,8 +2334,7 @@
     UTF-8. (default: ISO-8859-1)
 
 ``graphnodetemplate``
-    The template used to print changeset nodes in an ASCII revision graph.
-    (default: ``{graphnode}``)
+    (DEPRECATED) Use ``command-templates.graphnode`` instead.
 
 ``ignore``
     A file to read per-user ignore patterns from. This file should be
@@ -2363,7 +2362,7 @@
     (default: 10000000)
 
 ``logtemplate``
-    Template string for commands that print changesets.
+    (DEPRECATED) Use ``command-templates.log`` instead.
 
 ``merge``
     The conflict resolution program to use during a manual merge.
@@ -2371,29 +2370,14 @@
     For configuring merge tools see the ``[merge-tools]`` section.
 
 ``mergemarkers``
-    Sets the merge conflict marker label styling. The ``detailed``
-    style uses the ``mergemarkertemplate`` setting to style the labels.
+    Sets the merge conflict marker label styling. The ``detailed`` style
+    uses the ``command-templates.mergemarker`` setting to style the labels.
     The ``basic`` style just uses 'local' and 'other' as the marker label.
     One of ``basic`` or ``detailed``.
     (default: ``basic``)
 
 ``mergemarkertemplate``
-    The template used to print the commit description next to each conflict
-    marker during merge conflicts. See :hg:`help templates` for the template
-    format.
-
-    Defaults to showing the hash, tags, branches, bookmarks, author, and
-    the first line of the commit description.
-
-    If you use non-ASCII characters in names for tags, branches, bookmarks,
-    authors, and/or commit descriptions, you must pay attention to encodings of
-    managed files. At template expansion, non-ASCII characters use the encoding
-    specified by the ``--encoding`` global option, ``HGENCODING`` or other
-    environment variables that govern your locale. If the encoding of the merge
-    markers is different from the encoding of the merged files,
-    serious problems may occur.
-
-    Can be overridden per-merge-tool, see the ``[merge-tools]`` section.
+    (DEPRECATED) Use ``command-templates.mergemarker`` instead.
 
 ``message-output``
     Where to write status and error messages. (default: ``stdio``)
@@ -2456,14 +2440,7 @@
       On Windows, this configuration option is ignored and the command aborted.
 
 ``pre-merge-tool-output-template``
-    A template that is printed before executing an external merge tool. This can
-    be used to print out additional context that might be useful to have during
-    the conflict resolution, such as the description of the various commits
-    involved or bookmarks/tags.
-
-    Additional information is available in the ``local`, ``base``, and ``other``
-    dicts. For example: ``{local.label}``, ``{base.name}``, or
-    ``{other.islink}``.
+    (DEPRECATED) Use ``command-template.pre-merge-tool-output`` instead.
 
 ``quiet``
     Reduce the amount of output printed.
@@ -2561,6 +2538,47 @@
     Increase the amount of output printed. (default: False)
 
 
+``command-templates``
+---------------------
+
+Templates used for customizing the output of commands.
+
+``graphnode``
+    The template used to print changeset nodes in an ASCII revision graph.
+    (default: ``{graphnode}``)
+
+``log``
+    Template string for commands that print changesets.
+
+``mergemarker``
+    The template used to print the commit description next to each conflict
+    marker during merge conflicts. See :hg:`help templates` for the template
+    format.
+
+    Defaults to showing the hash, tags, branches, bookmarks, author, and
+    the first line of the commit description.
+
+    If you use non-ASCII characters in names for tags, branches, bookmarks,
+    authors, and/or commit descriptions, you must pay attention to encodings of
+    managed files. At template expansion, non-ASCII characters use the encoding
+    specified by the ``--encoding`` global option, ``HGENCODING`` or other
+    environment variables that govern your locale. If the encoding of the merge
+    markers is different from the encoding of the merged files,
+    serious problems may occur.
+
+    Can be overridden per-merge-tool, see the ``[merge-tools]`` section.
+
+``pre-merge-tool-output``
+    A template that is printed before executing an external merge tool. This can
+    be used to print out additional context that might be useful to have during
+    the conflict resolution, such as the description of the various commits
+    involved or bookmarks/tags.
+
+    Additional information is available in the ``local`, ``base``, and ``other``
+    dicts. For example: ``{local.label}``, ``{base.name}``, or
+    ``{other.islink}``.
+
+
 ``web``
 -------
 
--- a/mercurial/interfaces/repository.py	Mon Nov 02 14:26:19 2020 -0500
+++ b/mercurial/interfaces/repository.py	Mon Nov 02 14:39:43 2020 -0500
@@ -756,6 +756,7 @@
         linkmapper,
         transaction,
         addrevisioncb=None,
+        duplicaterevisioncb=None,
         maybemissingparents=False,
     ):
         """Process a series of deltas for storage.
@@ -1247,7 +1248,13 @@
         See the documentation for ``ifiledata`` for more.
         """
 
-    def addgroup(deltas, linkmapper, transaction, addrevisioncb=None):
+    def addgroup(
+        deltas,
+        linkmapper,
+        transaction,
+        addrevisioncb=None,
+        duplicaterevisioncb=None,
+    ):
         """Process a series of deltas for storage.
 
         See the documentation in ``ifilemutation`` for more.
--- a/mercurial/localrepo.py	Mon Nov 02 14:26:19 2020 -0500
+++ b/mercurial/localrepo.py	Mon Nov 02 14:39:43 2020 -0500
@@ -31,6 +31,7 @@
     bookmarks,
     branchmap,
     bundle2,
+    bundlecaches,
     changegroup,
     color,
     commit,
@@ -299,7 +300,7 @@
         return self._caps
 
     def clonebundles(self):
-        return self._repo.tryread(b'clonebundles.manifest')
+        return self._repo.tryread(bundlecaches.CB_MANIFEST_FILE)
 
     def debugwireargs(self, one, two, three=None, four=None, five=None):
         """Used to test argument passing over the wire"""
@@ -715,18 +716,28 @@
     if not rcutil.use_repo_hgrc():
         return False
 
+    ret = False
     # first load config from shared source if we has to
     if requirementsmod.SHARESAFE_REQUIREMENT in requirements and sharedvfs:
         try:
             ui.readconfig(sharedvfs.join(b'hgrc'), root=sharedvfs.base)
+            ret = True
         except IOError:
             pass
 
     try:
         ui.readconfig(hgvfs.join(b'hgrc'), root=wdirvfs.base)
-        return True
+        ret = True
     except IOError:
-        return False
+        pass
+
+    try:
+        ui.readconfig(hgvfs.join(b'hgrc-not-shared'), root=wdirvfs.base)
+        ret = True
+    except IOError:
+        pass
+
+    return ret
 
 
 def afterhgrcload(ui, wdirvfs, hgvfs, requirements):
--- a/mercurial/logcmdutil.py	Mon Nov 02 14:26:19 2020 -0500
+++ b/mercurial/logcmdutil.py	Mon Nov 02 14:39:43 2020 -0500
@@ -623,7 +623,7 @@
 
     # ui settings
     if not tmpl and not style:  # template are stronger than style
-        tmpl = ui.config(b'ui', b'logtemplate')
+        tmpl = ui.config(b'command-templates', b'log')
         if tmpl:
             return formatter.literal_templatespec(templater.unquotestring(tmpl))
         else:
@@ -656,7 +656,7 @@
     Display format will be the first non-empty hit of:
     1. option 'template'
     2. option 'style'
-    3. [ui] setting 'logtemplate'
+    3. [command-templates] setting 'log'
     4. [ui] setting 'style'
     If all of these values are either the unset or the empty string,
     regular display via changesetprinter() is done.
@@ -1111,7 +1111,7 @@
 
 
 def _graphnodeformatter(ui, displayer):
-    spec = ui.config(b'ui', b'graphnodetemplate')
+    spec = ui.config(b'command-templates', b'graphnode')
     if not spec:
         return templatekw.getgraphnode  # fast path for "{graphnode}"
 
--- a/mercurial/manifest.py	Mon Nov 02 14:26:19 2020 -0500
+++ b/mercurial/manifest.py	Mon Nov 02 14:39:43 2020 -0500
@@ -1832,9 +1832,20 @@
             deltamode=deltamode,
         )
 
-    def addgroup(self, deltas, linkmapper, transaction, addrevisioncb=None):
+    def addgroup(
+        self,
+        deltas,
+        linkmapper,
+        transaction,
+        addrevisioncb=None,
+        duplicaterevisioncb=None,
+    ):
         return self._revlog.addgroup(
-            deltas, linkmapper, transaction, addrevisioncb=addrevisioncb
+            deltas,
+            linkmapper,
+            transaction,
+            addrevisioncb=addrevisioncb,
+            duplicaterevisioncb=duplicaterevisioncb,
         )
 
     def rawsize(self, rev):
--- a/mercurial/parser.py	Mon Nov 02 14:26:19 2020 -0500
+++ b/mercurial/parser.py	Mon Nov 02 14:39:43 2020 -0500
@@ -408,10 +408,10 @@
 def parseerrordetail(inst):
     """Compose error message from specified ParseError object
     """
-    if len(inst.args) > 1:
-        return _(b'at %d: %s') % (inst.args[1], inst.args[0])
+    if inst.location is not None:
+        return _(b'at %d: %s') % (inst.location, inst.message)
     else:
-        return inst.args[0]
+        return inst.message
 
 
 class alias(object):
--- a/mercurial/phases.py	Mon Nov 02 14:26:19 2020 -0500
+++ b/mercurial/phases.py	Mon Nov 02 14:39:43 2020 -0500
@@ -510,21 +510,20 @@
         tr.addfilegenerator(b'phase', (b'phaseroots',), self._write)
         tr.hookargs[b'phases_moved'] = b'1'
 
-    def registernew(self, repo, tr, targetphase, nodes):
+    def registernew(self, repo, tr, targetphase, revs):
         repo = repo.unfiltered()
-        self._retractboundary(repo, tr, targetphase, nodes)
+        self._retractboundary(repo, tr, targetphase, [], revs=revs)
         if tr is not None and b'phases' in tr.changes:
             phasetracking = tr.changes[b'phases']
-            torev = repo.changelog.rev
             phase = self.phase
-            revs = [torev(node) for node in nodes]
-            revs.sort()
-            for rev in revs:
+            for rev in sorted(revs):
                 revphase = phase(repo, rev)
                 _trackphasechange(phasetracking, rev, None, revphase)
         repo.invalidatevolatilesets()
 
-    def advanceboundary(self, repo, tr, targetphase, nodes, dryrun=None):
+    def advanceboundary(
+        self, repo, tr, targetphase, nodes, revs=None, dryrun=None
+    ):
         """Set all 'nodes' to phase 'targetphase'
 
         Nodes with a phase lower than 'targetphase' are not affected.
@@ -535,26 +534,27 @@
         """
         # Be careful to preserve shallow-copied values: do not update
         # phaseroots values, replace them.
+        if revs is None:
+            revs = []
         if tr is None:
             phasetracking = None
         else:
             phasetracking = tr.changes.get(b'phases')
 
         repo = repo.unfiltered()
+        revs = [repo[n].rev() for n in nodes] + [r for r in revs]
 
         changes = set()  # set of revisions to be changed
         delroots = []  # set of root deleted by this path
         for phase in (phase for phase in allphases if phase > targetphase):
             # filter nodes that are not in a compatible phase already
-            nodes = [
-                n for n in nodes if self.phase(repo, repo[n].rev()) >= phase
-            ]
-            if not nodes:
+            revs = [rev for rev in revs if self.phase(repo, rev) >= phase]
+            if not revs:
                 break  # no roots to move anymore
 
             olds = self.phaseroots[phase]
 
-            affected = repo.revs(b'%ln::%ln', olds, nodes)
+            affected = repo.revs(b'%ln::%ld', olds, revs)
             changes.update(affected)
             if dryrun:
                 continue
@@ -611,9 +611,11 @@
                     _trackphasechange(phasetracking, r, phase, targetphase)
         repo.invalidatevolatilesets()
 
-    def _retractboundary(self, repo, tr, targetphase, nodes):
+    def _retractboundary(self, repo, tr, targetphase, nodes, revs=None):
         # Be careful to preserve shallow-copied values: do not update
         # phaseroots values, replace them.
+        if revs is None:
+            revs = []
         if targetphase in (archived, internal) and not supportinternal(repo):
             name = phasenames[targetphase]
             msg = b'this repository does not support the %s phase' % name
@@ -624,7 +626,7 @@
         tonode = repo.changelog.node
         currentroots = {torev(node) for node in self.phaseroots[targetphase]}
         finalroots = oldroots = set(currentroots)
-        newroots = [torev(node) for node in nodes]
+        newroots = [torev(node) for node in nodes] + [r for r in revs]
         newroots = [
             rev for rev in newroots if self.phase(repo, rev) < targetphase
         ]
@@ -679,7 +681,7 @@
         self.invalidate()
 
 
-def advanceboundary(repo, tr, targetphase, nodes, dryrun=None):
+def advanceboundary(repo, tr, targetphase, nodes, revs=None, dryrun=None):
     """Add nodes to a phase changing other nodes phases if necessary.
 
     This function move boundary *forward* this means that all nodes
@@ -691,9 +693,11 @@
 
     Returns a set of revs whose phase is changed or should be changed
     """
+    if revs is None:
+        revs = []
     phcache = repo._phasecache.copy()
     changes = phcache.advanceboundary(
-        repo, tr, targetphase, nodes, dryrun=dryrun
+        repo, tr, targetphase, nodes, revs=revs, dryrun=dryrun
     )
     if not dryrun:
         repo._phasecache.replace(phcache)
@@ -713,14 +717,14 @@
     repo._phasecache.replace(phcache)
 
 
-def registernew(repo, tr, targetphase, nodes):
+def registernew(repo, tr, targetphase, revs):
     """register a new revision and its phase
 
     Code adding revisions to the repository should use this function to
     set new changeset in their target phase (or higher).
     """
     phcache = repo._phasecache.copy()
-    phcache.registernew(repo, tr, targetphase, nodes)
+    phcache.registernew(repo, tr, targetphase, revs)
     repo._phasecache.replace(phcache)
 
 
--- a/mercurial/revlog.py	Mon Nov 02 14:26:19 2020 -0500
+++ b/mercurial/revlog.py	Mon Nov 02 14:39:43 2020 -0500
@@ -668,7 +668,7 @@
         if not self._chunkcache:
             self._chunkclear()
         # revnum -> (chain-length, sum-delta-length)
-        self._chaininfocache = {}
+        self._chaininfocache = util.lrucachedict(500)
         # revlog header -> revlog compressor
         self._decompressors = {}
 
@@ -2368,7 +2368,14 @@
             self._enforceinlinesize(transaction, ifh)
         nodemaputil.setup_persistent_nodemap(transaction, self)
 
-    def addgroup(self, deltas, linkmapper, transaction, addrevisioncb=None):
+    def addgroup(
+        self,
+        deltas,
+        linkmapper,
+        transaction,
+        addrevisioncb=None,
+        duplicaterevisioncb=None,
+    ):
         """
         add a delta group
 
@@ -2383,8 +2390,6 @@
         if self._writinghandles:
             raise error.ProgrammingError(b'cannot nest addgroup() calls')
 
-        nodes = []
-
         r = len(self)
         end = 0
         if r:
@@ -2405,6 +2410,7 @@
             ifh.flush()
 
         self._writinghandles = (ifh, dfh)
+        empty = True
 
         try:
             deltacomputer = deltautil.deltacomputer(self)
@@ -2414,11 +2420,12 @@
                 link = linkmapper(linknode)
                 flags = flags or REVIDX_DEFAULT_FLAGS
 
-                nodes.append(node)
-
                 if self.index.has_node(node):
+                    # this can happen if two branches make the same change
                     self._nodeduplicatecallback(transaction, node)
-                    # this can happen if two branches make the same change
+                    if duplicaterevisioncb:
+                        duplicaterevisioncb(self, node)
+                    empty = False
                     continue
 
                 for p in (p1, p2):
@@ -2472,6 +2479,7 @@
 
                 if addrevisioncb:
                     addrevisioncb(self, node)
+                empty = False
 
                 if not dfh and not self._inline:
                     # addrevision switched from inline to conventional
@@ -2486,8 +2494,7 @@
             if dfh:
                 dfh.close()
             ifh.close()
-
-        return nodes
+        return not empty
 
     def iscensored(self, rev):
         """Check if a file revision is censored."""
@@ -2550,7 +2557,7 @@
 
         # then reset internal state in memory to forget those revisions
         self._revisioncache = None
-        self._chaininfocache = {}
+        self._chaininfocache = util.lrucachedict(500)
         self._chunkclear()
 
         del self.index[rev:-1]
--- a/mercurial/revsetlang.py	Mon Nov 02 14:26:19 2020 -0500
+++ b/mercurial/revsetlang.py	Mon Nov 02 14:39:43 2020 -0500
@@ -642,8 +642,8 @@
     try:
         return _parsewith(spec, lookup=lookup)
     except error.ParseError as inst:
-        if len(inst.args) > 1:  # has location
-            loc = inst.args[1]
+        if inst.location is not None:
+            loc = inst.location
             # Remove newlines -- spaces are equivalent whitespace.
             spec = spec.replace(b'\n', b' ')
             # We want the caret to point to the place in the template that
--- a/mercurial/tags.py	Mon Nov 02 14:26:19 2020 -0500
+++ b/mercurial/tags.py	Mon Nov 02 14:39:43 2020 -0500
@@ -759,7 +759,7 @@
         properprefix = node[0:4]
 
         # Validate and return existing entry.
-        if record != _fnodesmissingrec:
+        if record != _fnodesmissingrec and len(record) == _fnodesrecsize:
             fileprefix = record[0:4]
 
             if fileprefix == properprefix:
--- a/mercurial/templater.py	Mon Nov 02 14:26:19 2020 -0500
+++ b/mercurial/templater.py	Mon Nov 02 14:39:43 2020 -0500
@@ -312,9 +312,9 @@
 
 
 def _addparseerrorhint(inst, tmpl):
-    if len(inst.args) <= 1:
-        return  # no location
-    loc = inst.args[1]
+    if inst.location is None:
+        return
+    loc = inst.location
     # Offset the caret location by the number of newlines before the
     # location of the error, since we will replace one-char newlines
     # with the two-char literal r'\n'.
--- a/mercurial/testing/storage.py	Mon Nov 02 14:26:19 2020 -0500
+++ b/mercurial/testing/storage.py	Mon Nov 02 14:39:43 2020 -0500
@@ -1117,7 +1117,22 @@
             return 0
 
         with self._maketransactionfn() as tr:
-            nodes = f.addgroup([], None, tr, addrevisioncb=cb)
+            nodes = []
+
+            def onchangeset(cl, node):
+                nodes.append(node)
+                cb(cl, node)
+
+            def ondupchangeset(cl, node):
+                nodes.append(node)
+
+            f.addgroup(
+                [],
+                None,
+                tr,
+                addrevisioncb=onchangeset,
+                duplicaterevisioncb=ondupchangeset,
+            )
 
         self.assertEqual(nodes, [])
         self.assertEqual(callbackargs, [])
@@ -1136,7 +1151,22 @@
         ]
 
         with self._maketransactionfn() as tr:
-            nodes = f.addgroup(deltas, linkmapper, tr, addrevisioncb=cb)
+            nodes = []
+
+            def onchangeset(cl, node):
+                nodes.append(node)
+                cb(cl, node)
+
+            def ondupchangeset(cl, node):
+                nodes.append(node)
+
+            f.addgroup(
+                deltas,
+                linkmapper,
+                tr,
+                addrevisioncb=onchangeset,
+                duplicaterevisioncb=ondupchangeset,
+            )
 
         self.assertEqual(
             nodes,
@@ -1175,7 +1205,19 @@
             deltas.append((nodes[i], nullid, nullid, nullid, nullid, delta, 0))
 
         with self._maketransactionfn() as tr:
-            self.assertEqual(f.addgroup(deltas, lambda x: 0, tr), nodes)
+            newnodes = []
+
+            def onchangeset(cl, node):
+                newnodes.append(node)
+
+            f.addgroup(
+                deltas,
+                lambda x: 0,
+                tr,
+                addrevisioncb=onchangeset,
+                duplicaterevisioncb=onchangeset,
+            )
+            self.assertEqual(newnodes, nodes)
 
         self.assertEqual(len(f), len(deltas))
         self.assertEqual(list(f.revs()), [0, 1, 2])
--- a/mercurial/ui.py	Mon Nov 02 14:26:19 2020 -0500
+++ b/mercurial/ui.py	Mon Nov 02 14:39:43 2020 -0500
@@ -507,6 +507,8 @@
                 del cfg[b'defaults'][k]
             for k, v in cfg.items(b'commands'):
                 del cfg[b'commands'][k]
+            for k, v in cfg.items(b'command-templates'):
+                del cfg[b'command-templates'][k]
         # Don't remove aliases from the configuration if in the exceptionlist
         if self.plain(b'alias'):
             for k, v in cfg.items(b'alias'):
--- a/mercurial/unionrepo.py	Mon Nov 02 14:26:19 2020 -0500
+++ b/mercurial/unionrepo.py	Mon Nov 02 14:39:43 2020 -0500
@@ -129,6 +129,7 @@
         linkmapper,
         transaction,
         addrevisioncb=None,
+        duplicaterevisioncb=None,
         maybemissingparents=False,
     ):
         raise NotImplementedError
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mercurial/utils/memorytop.py	Mon Nov 02 14:39:43 2020 -0500
@@ -0,0 +1,44 @@
+# memorytop requires Python 3.4
+#
+# Usage: set PYTHONTRACEMALLOC=n in the environment of the hg invocation,
+# where n>= is the number of frames to show in the backtrace. Put calls to
+# memorytop in strategic places to show the current memory use by allocation
+# site.
+
+import gc
+import tracemalloc
+
+
+def memorytop(limit=10):
+    gc.collect()
+    snapshot = tracemalloc.take_snapshot()
+
+    snapshot = snapshot.filter_traces(
+        (
+            tracemalloc.Filter(False, "<frozen importlib._bootstrap>"),
+            tracemalloc.Filter(False, "<frozen importlib._bootstrap_external>"),
+            tracemalloc.Filter(False, "<unknown>"),
+        )
+    )
+    stats = snapshot.statistics('traceback')
+
+    total = sum(stat.size for stat in stats)
+    print("\nTotal allocated size: %.1f KiB\n" % (total / 1024))
+    print("Lines with the biggest net allocations")
+    for index, stat in enumerate(stats[:limit], 1):
+        print(
+            "#%d: %d objects using %.1f KiB"
+            % (index, stat.count, stat.size / 1024)
+        )
+        for line in stat.traceback.format(most_recent_first=True):
+            print('    ', line)
+
+    other = stats[limit:]
+    if other:
+        size = sum(stat.size for stat in other)
+        count = sum(stat.count for stat in other)
+        print(
+            "%s other: %d objects using %.1f KiB"
+            % (len(other), count, size / 1024)
+        )
+    print()
--- a/mercurial/utils/procutil.py	Mon Nov 02 14:26:19 2020 -0500
+++ b/mercurial/utils/procutil.py	Mon Nov 02 14:39:43 2020 -0500
@@ -635,21 +635,35 @@
         stderr=None,
         ensurestart=True,
         record_wait=None,
+        stdin_bytes=None,
     ):
         '''Spawn a command without waiting for it to finish.'''
         # we can't use close_fds *and* redirect stdin. I'm not sure that we
         # need to because the detached process has no console connection.
-        p = subprocess.Popen(
-            tonativestr(script),
-            shell=shell,
-            env=tonativeenv(env),
-            close_fds=True,
-            creationflags=_creationflags,
-            stdout=stdout,
-            stderr=stderr,
-        )
-        if record_wait is not None:
-            record_wait(p.wait)
+
+        try:
+            stdin = None
+            if stdin_bytes is not None:
+                stdin = pycompat.unnamedtempfile()
+                stdin.write(stdin_bytes)
+                stdin.flush()
+                stdin.seek(0)
+
+            p = subprocess.Popen(
+                tonativestr(script),
+                shell=shell,
+                env=tonativeenv(env),
+                close_fds=True,
+                creationflags=_creationflags,
+                stdin=stdin,
+                stdout=stdout,
+                stderr=stderr,
+            )
+            if record_wait is not None:
+                record_wait(p.wait)
+        finally:
+            if stdin is not None:
+                stdin.close()
 
 
 else:
@@ -662,6 +676,7 @@
         stderr=None,
         ensurestart=True,
         record_wait=None,
+        stdin_bytes=None,
     ):
         '''Spawn a command without waiting for it to finish.
 
@@ -722,15 +737,21 @@
             if record_wait is None:
                 # Start a new session
                 os.setsid()
+            # connect stdin to devnull to make sure the subprocess can't
+            # muck up that stream for mercurial.
+            if stdin_bytes is None:
+                stdin = open(os.devnull, b'r')
+            else:
+                stdin = pycompat.unnamedtempfile()
+                stdin.write(stdin_bytes)
+                stdin.flush()
+                stdin.seek(0)
 
-            stdin = open(os.devnull, b'r')
             if stdout is None:
                 stdout = open(os.devnull, b'w')
             if stderr is None:
                 stderr = open(os.devnull, b'w')
 
-            # connect stdin to devnull to make sure the subprocess can't
-            # muck up that stream for mercurial.
             p = subprocess.Popen(
                 cmd,
                 shell=shell,
@@ -754,5 +775,6 @@
         finally:
             # mission accomplished, this child needs to exit and not
             # continue the hg process here.
+            stdin.close()
             if record_wait is None:
                 os._exit(returncode)
--- a/mercurial/wireprotov1server.py	Mon Nov 02 14:26:19 2020 -0500
+++ b/mercurial/wireprotov1server.py	Mon Nov 02 14:39:43 2020 -0500
@@ -19,6 +19,7 @@
 
 from . import (
     bundle2,
+    bundlecaches,
     changegroup as changegroupmod,
     discovery,
     encoding,
@@ -272,7 +273,7 @@
     data center given the client's IP address.
     """
     return wireprototypes.bytesresponse(
-        repo.vfs.tryread(b'clonebundles.manifest')
+        repo.vfs.tryread(bundlecaches.CB_MANIFEST_FILE)
     )
 
 
@@ -387,8 +388,8 @@
     manifest = repo.vfs.tryread(b'pullbundles.manifest')
     if not manifest:
         return None
-    res = exchange.parseclonebundlesmanifest(repo, manifest)
-    res = exchange.filterclonebundleentries(repo, res)
+    res = bundlecaches.parseclonebundlesmanifest(repo, manifest)
+    res = bundlecaches.filterclonebundleentries(repo, res)
     if not res:
         return None
     cl = repo.unfiltered().changelog
--- a/relnotes/5.6	Mon Nov 02 14:26:19 2020 -0500
+++ b/relnotes/5.6	Mon Nov 02 14:39:43 2020 -0500
@@ -8,6 +8,9 @@
  * New revset predicate `diffcontains(pattern)` for filtering revisions
    in the same way as `hg grep --diff pattern`.
 
+ * The memory footprint per changeset and per file during pull/unbundle
+   operations has been significantly reduced.
+
 
 == New Experimental Features ==
 
@@ -27,3 +30,15 @@
    the higher-level functions available in the same module cover your
    use cases.
 
+ * `phases.registernew` now takes a set of revisions instead of a list
+   of nodes. `phases.advanceboundary` takes an optional set of revisions
+   in addition to the list of nodes. The corresponeding members of the
+   `phasecache` class follow this change.
+
+ * The `addgroup` member of `revlog` classes no longer keeps a list of
+   all found nodes. It now returns True iff a node was found in the group.
+   An optional callback for duplicated nodes can be used by callers to keep
+   track of all nodes themselve.
+
+ * The `_chaininfocache` of `revlog` classes has been changed from a dict
+   to a LRU cache.
--- a/relnotes/next	Mon Nov 02 14:26:19 2020 -0500
+++ b/relnotes/next	Mon Nov 02 14:39:43 2020 -0500
@@ -1,6 +1,9 @@
 == New Features ==
 
 
+ * The memory footprint per changeset and per file during pull/unbundle
+   operations has been significantly reduced.
+
 
 == New Experimental Features ==
 
@@ -17,3 +20,15 @@
 == Internal API Changes ==
 
 
+ * `phases.registernew` now takes a set of revisions instead of a list
+   of nodes. `phases.advanceboundary` takes an optional set of revisions
+   in addition to the list of nodes. The corresponeding members of the
+   `phasecache` class follow this change.
+
+ * The `addgroup` member of `revlog` classes no longer keeps a list of
+   all found nodes. It now returns True iff a node was found in the group.
+   An optional callback for duplicated nodes can be used by callers to keep
+   track of all nodes themselve.
+
+ * The `_chaininfocache` of `revlog` classes has been changed from a dict
+   to a LRU cache.
--- a/rust/hg-core/src/dirstate/dirstate_tree/node.rs	Mon Nov 02 14:26:19 2020 -0500
+++ b/rust/hg-core/src/dirstate/dirstate_tree/node.rs	Mon Nov 02 14:39:43 2020 -0500
@@ -60,43 +60,46 @@
         // Are we're modifying the current file ? Is the the end of the path ?
         let is_current_file = tail.is_empty() && head.is_empty();
 
-        if let NodeKind::File(file) = &mut self.kind {
-            if is_current_file {
-                let new = Self {
-                    kind: NodeKind::File(File {
-                        entry: new_entry,
-                        ..file.clone()
-                    }),
-                };
-                return InsertResult {
-                    did_insert: false,
-                    old_entry: Some(std::mem::replace(self, new)),
-                };
-            } else {
-                match file.entry.state {
-                    // Only replace the current file with a directory if it's
-                    // marked as `Removed`
-                    EntryState::Removed => {
-                        self.kind = NodeKind::Directory(Directory {
-                            was_file: Some(Box::from(file.clone())),
-                            children: Default::default(),
-                        })
-                    }
-                    _ => {
-                        return Node::insert_in_file(
-                            file, new_entry, head, tail,
-                        )
-                    }
+        // Potentially Replace the current file with a directory if it's marked
+        // as `Removed`
+        if !is_current_file {
+            if let NodeKind::File(file) = &mut self.kind {
+                if file.entry.state == EntryState::Removed {
+                    self.kind = NodeKind::Directory(Directory {
+                        was_file: Some(Box::from(file.clone())),
+                        children: Default::default(),
+                    })
                 }
             }
         }
-
         match &mut self.kind {
             NodeKind::Directory(directory) => {
                 Node::insert_in_directory(directory, new_entry, head, tail)
             }
-            NodeKind::File(_) => {
-                unreachable!("The file case has already been handled")
+            NodeKind::File(file) => {
+                if is_current_file {
+                    let new = Self {
+                        kind: NodeKind::File(File {
+                            entry: new_entry,
+                            ..file.clone()
+                        }),
+                    };
+                    InsertResult {
+                        did_insert: false,
+                        old_entry: Some(std::mem::replace(self, new)),
+                    }
+                } else {
+                    match file.entry.state {
+                        EntryState::Removed => {
+                            unreachable!("Removed file turning into a directory was dealt with earlier")
+                        }
+                        _ => {
+                            Node::insert_in_file(
+                                file, new_entry, head, tail,
+                            )
+                        }
+                    }
+                }
             }
         }
     }
--- a/tests/flagprocessorext.py	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/flagprocessorext.py	Mon Nov 02 14:39:43 2020 -0500
@@ -6,8 +6,8 @@
 import zlib
 
 from mercurial import (
+    bundlecaches,
     changegroup,
-    exchange,
     extensions,
     revlog,
     util,
@@ -134,8 +134,8 @@
     revlog.REVIDX_FLAGS_ORDER.extend(flags)
 
     # Teach exchange to use changegroup 3
-    for k in exchange._bundlespeccontentopts.keys():
-        exchange._bundlespeccontentopts[k][b"cg.version"] = b"03"
+    for k in bundlecaches._bundlespeccontentopts.keys():
+        bundlecaches._bundlespeccontentopts[k][b"cg.version"] = b"03"
 
     # Register flag processors for each extension
     flagutil.addflagprocessor(
--- a/tests/simplestorerepo.py	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/simplestorerepo.py	Mon Nov 02 14:39:43 2020 -0500
@@ -532,6 +532,7 @@
         linkmapper,
         transaction,
         addrevisioncb=None,
+        duplicaterevisioncb=None,
         maybemissingparents=False,
     ):
         if maybemissingparents:
@@ -539,7 +540,7 @@
                 _('simple store does not support missing parents ' 'write mode')
             )
 
-        nodes = []
+        empty = True
 
         transaction.addbackup(self._indexpath)
 
@@ -547,9 +548,10 @@
             linkrev = linkmapper(linknode)
             flags = flags or revlog.REVIDX_DEFAULT_FLAGS
 
-            nodes.append(node)
-
             if node in self._indexbynode:
+                if duplicaterevisioncb:
+                    duplicaterevisioncb(self, node)
+                empty = False
                 continue
 
             # Need to resolve the fulltext from the delta base.
@@ -564,7 +566,8 @@
 
             if addrevisioncb:
                 addrevisioncb(self, node)
-        return nodes
+            empty = False
+        return not empty
 
     def _headrevs(self):
         # Assume all revisions are heads by default.
--- a/tests/test-absorb-unfinished.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-absorb-unfinished.t	Mon Nov 02 14:39:43 2020 -0500
@@ -17,7 +17,7 @@
   $ hg commit -Aqm "foo 2"
 
   $ hg --config extensions.rebase= rebase -r 1 -d 0
-  rebasing 1:c3b6dc0e177a "foo 2" (tip)
+  rebasing 1:c3b6dc0e177a tip "foo 2"
   merging foo.whole
   warning: conflicts while merging foo.whole! (edit, then use 'hg resolve --mark')
   unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
--- a/tests/test-amend.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-amend.t	Mon Nov 02 14:39:43 2020 -0500
@@ -403,10 +403,10 @@
   $ hg init $TESTTMP/repo5
   $ cd $TESTTMP/repo5
   $ cat <<'EOF' >> .hg/hgrc
-  > [ui]
-  > logtemplate = 'user:        {user}
-  >                date:        {date|date}
-  >                summary:     {desc|firstline}\n'
+  > [command-templates]
+  > log = 'user:        {user}
+  >        date:        {date|date}
+  >        summary:     {desc|firstline}\n'
   > EOF
 
   $ echo a>a
--- a/tests/test-audit-path.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-audit-path.t	Mon Nov 02 14:39:43 2020 -0500
@@ -177,7 +177,7 @@
 
   $ hg up -qC 2
   $ hg rebase -s 2 -d 1 --config extensions.rebase=
-  rebasing 2:e73c21d6b244 "file a/poisoned" (tip)
+  rebasing 2:e73c21d6b244 tip "file a/poisoned"
   abort: path 'a/poisoned' traverses symbolic link 'a'
   [255]
   $ ls ../merge-symlink-out
--- a/tests/test-bookmarks-pushpull.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-bookmarks-pushpull.t	Mon Nov 02 14:39:43 2020 -0500
@@ -10,8 +10,8 @@
 #require serve
 
   $ cat << EOF >> $HGRCPATH
-  > [ui]
-  > logtemplate={rev}:{node|short} {desc|firstline}
+  > [command-templates]
+  > log={rev}:{node|short} {desc|firstline}
   > [phases]
   > publish=False
   > [experimental]
--- a/tests/test-bookmarks-rebase.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-bookmarks-rebase.t	Mon Nov 02 14:39:43 2020 -0500
@@ -37,7 +37,7 @@
 rebase
 
   $ hg rebase -s two -d one
-  rebasing 3:2ae46b1d99a7 "3" (two tip)
+  rebasing 3:2ae46b1d99a7 two tip "3"
   saved backup bundle to $TESTTMP/.hg/strip-backup/2ae46b1d99a7-e6b057bc-rebase.hg
 
   $ hg log
@@ -77,7 +77,7 @@
   created new head
   $ hg bookmark three
   $ hg rebase -s three -d two
-  rebasing 4:dd7c838e8362 "4" (three tip)
+  rebasing 4:dd7c838e8362 three tip "4"
   merging d
   warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
   unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
@@ -92,7 +92,7 @@
 after aborted rebase, restoring a bookmark that has been removed should not fail
 
   $ hg rebase -s three -d two
-  rebasing 4:dd7c838e8362 "4" (three tip)
+  rebasing 4:dd7c838e8362 three tip "4"
   merging d
   warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
   unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
--- a/tests/test-bundle2-exchange.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-bundle2-exchange.t	Mon Nov 02 14:39:43 2020 -0500
@@ -30,7 +30,8 @@
   > bundle2-output-capture=True
   > [ui]
   > ssh="$PYTHON" "$TESTDIR/dummyssh"
-  > logtemplate={rev}:{node|short} {phase} {author} {bookmarks} {desc|firstline}
+  > [command-templates]
+  > log={rev}:{node|short} {phase} {author} {bookmarks} {desc|firstline}
   > [web]
   > push_ssl = false
   > allow_push = *
--- a/tests/test-bundle2-format.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-bundle2-format.t	Mon Nov 02 14:39:43 2020 -0500
@@ -235,7 +235,8 @@
   > evolution.createmarkers=True
   > [ui]
   > ssh="$PYTHON" "$TESTDIR/dummyssh"
-  > logtemplate={rev}:{node|short} {phase} {author} {bookmarks} {desc|firstline}
+  > [command-templates]
+  > log={rev}:{node|short} {phase} {author} {bookmarks} {desc|firstline}
   > [web]
   > push_ssl = false
   > allow_push = *
--- a/tests/test-bundle2-multiple-changegroups.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-bundle2-multiple-changegroups.t	Mon Nov 02 14:39:43 2020 -0500
@@ -34,8 +34,8 @@
   > EOF
 
   $ cat >> $HGRCPATH << EOF
-  > [ui]
-  > logtemplate={rev}:{node|short} {phase} {author} {bookmarks} {desc|firstline}
+  > [command-templates]
+  > log={rev}:{node|short} {phase} {author} {bookmarks} {desc|firstline}
   > EOF
 
 Start with a simple repository with a single commit
--- a/tests/test-bundle2-remote-changegroup.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-bundle2-remote-changegroup.t	Mon Nov 02 14:39:43 2020 -0500
@@ -96,7 +96,8 @@
   $ cat >> $HGRCPATH << EOF
   > [ui]
   > ssh="$PYTHON" "$TESTDIR/dummyssh"
-  > logtemplate={rev}:{node|short} {phase} {author} {bookmarks} {desc|firstline}
+  > [command-templates]
+  > log={rev}:{node|short} {phase} {author} {bookmarks} {desc|firstline}
   > EOF
 
   $ hg init repo
--- a/tests/test-commandserver.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-commandserver.t	Mon Nov 02 14:39:43 2020 -0500
@@ -982,8 +982,8 @@
   $ cd repo3
 
   $ cat <<EOF >> $HGRCPATH
-  > [ui]
-  > logtemplate = {rev} {desc|firstline} ({files})\n
+  > [command-templates]
+  > log = {rev} {desc|firstline} ({files})\n
   > 
   > [extensions]
   > failafterfinalize = $TESTTMP/failafterfinalize.py
--- a/tests/test-completion.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-completion.t	Mon Nov 02 14:39:43 2020 -0500
@@ -259,7 +259,7 @@
   cat: output, rev, decode, include, exclude, template
   clone: noupdate, updaterev, rev, branch, pull, uncompressed, stream, ssh, remotecmd, insecure
   commit: addremove, close-branch, amend, secret, edit, force-close-branch, interactive, include, exclude, message, logfile, date, user, subrepos
-  config: untrusted, edit, local, shared, global, template
+  config: untrusted, edit, local, shared, non-shared, global, template
   continue: dry-run
   copy: forget, after, at-rev, force, include, exclude, dry-run
   debugancestor: 
--- a/tests/test-config.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-config.t	Mon Nov 02 14:39:43 2020 -0500
@@ -25,8 +25,7 @@
   >  key=value
   > EOF
   $ hg showconfig
-  hg: parse error at $TESTTMP/.hg/hgrc:1:  key=value
-  unexpected leading whitespace
+  hg: parse error at $TESTTMP/.hg/hgrc:1: unexpected leading whitespace:  key=value
   [255]
 
   $ cat > .hg/hgrc << EOF
@@ -34,8 +33,7 @@
   > key=value
   > EOF
   $ hg showconfig
-  hg: parse error at $TESTTMP/.hg/hgrc:1:  [section]
-  unexpected leading whitespace
+  hg: parse error at $TESTTMP/.hg/hgrc:1: unexpected leading whitespace:  [section]
   [255]
 
 Reset hgrc
--- a/tests/test-conflict.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-conflict.t	Mon Nov 02 14:39:43 2020 -0500
@@ -102,6 +102,35 @@
 
   $ hg up -q --clean .
   $ cat <<EOF >> .hg/hgrc
+  > [command-templates]
+  > mergemarker = '{author} {rev}'
+  > EOF
+
+  $ hg merge 1
+  merging a
+  warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
+  0 files updated, 0 files merged, 0 files removed, 1 files unresolved
+  use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
+  [1]
+
+  $ cat a
+  Small Mathematical Series.
+  1
+  2
+  3
+  <<<<<<< working copy: test 2
+  6
+  8
+  =======
+  4
+  5
+  >>>>>>> merge rev:    test 1
+  Hop we are done.
+
+Verify custom conflict markers with legacy config name
+
+  $ hg up -q --clean .
+  $ cat <<EOF >> .hg/hgrc
   > [ui]
   > mergemarkertemplate = '{author} {rev}'
   > EOF
@@ -131,8 +160,8 @@
 
   $ hg up -q --clean .
   $ cat >> .hg/hgrc <<EOF
-  > [ui]
-  > mergemarkertemplate={author} {rev}\nfoo\nbar\nbaz
+  > [command-templates]
+  > mergemarker={author} {rev}\nfoo\nbar\nbaz
   > EOF
 
   $ hg -q merge 1
@@ -170,8 +199,8 @@
   $ hg --encoding utf-8 commit --logfile logfile
 
   $ cat >> .hg/hgrc <<EOF
-  > [ui]
-  > mergemarkertemplate={desc|firstline}
+  > [command-templates]
+  > mergemarker={desc|firstline}
   > EOF
 
   $ hg -q --encoding utf-8 merge 1
--- a/tests/test-copies-chain-merge.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-copies-chain-merge.t	Mon Nov 02 14:39:43 2020 -0500
@@ -17,8 +17,8 @@
   $ cat << EOF >> $HGRCPATH
   > [diff]
   > git=yes
-  > [ui]
-  > logtemplate={rev} {desc}\n
+  > [command-templates]
+  > log={rev} {desc}\n
   > EOF
 
 #if compatibility
@@ -585,6 +585,50 @@
 
   $ hg up null --quiet
 
+Merging a branch where a rename was deleted with a branch where the same file was renamed
+------------------------------------------------------------------------------------------
+
+Create a "conflicting" merge where `d` get removed on one branch before its
+rename information actually conflict with the other branch.
+
+(the copy information from the branch that was not deleted should win).
+
+  $ hg up 'desc("i-0")'
+  3 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg mv b d
+  $ hg ci -m "h-1: b -(move)-> d"
+  created new head
+
+  $ hg up 'desc("c-1")'
+  1 files updated, 0 files merged, 2 files removed, 0 files unresolved
+  $ hg merge 'desc("h-1")'
+  1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  $ hg ci -m "mCH-delete-before-conflict-m-0"
+
+  $ hg up 'desc("h-1")'
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg merge 'desc("c-1")'
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  $ hg ci -m "mHC-delete-before-conflict-m-0"
+  created new head
+  $ hg log -G --rev '::(desc("mCH-delete-before-conflict-m")+desc("mHC-delete-before-conflict-m"))'
+  @    36 mHC-delete-before-conflict-m-0
+  |\
+  +---o  35 mCH-delete-before-conflict-m-0
+  | |/
+  | o  34 h-1: b -(move)-> d
+  | |
+  o |  6 c-1 delete d
+  | |
+  o |  2 i-2: c -move-> d
+  | |
+  o |  1 i-1: a -move-> c
+  |/
+  o  0 i-0 initial commit: a b h
+  
+
 
 Test that sidedata computations during upgrades are correct
 ===========================================================
@@ -801,6 +845,20 @@
    entry-0014 size 14
     '\x00\x00\x00\x01\x10\x00\x00\x00\x01\x00\x00\x00\x00d'
   salvaged   : d, ;
+  ##### revision 34 #####
+  1 sidedata entries
+   entry-0014 size 24
+    '\x00\x00\x00\x02\x0c\x00\x00\x00\x01\x00\x00\x00\x00\x06\x00\x00\x00\x02\x00\x00\x00\x00bd'
+  removed    : b, ;
+  added    p1: d, b;
+  ##### revision 35 #####
+  1 sidedata entries
+   entry-0014 size 4
+    '\x00\x00\x00\x00'
+  ##### revision 36 #####
+  1 sidedata entries
+   entry-0014 size 4
+    '\x00\x00\x00\x00'
 
 #endif
 
@@ -1003,29 +1061,15 @@
 
 Log output should not include a merge commit as it did not happen
 
-#if no-changeset
-  $ hg log -Gfr 'desc("mBDm-0")' d
-  o  8 d-2 re-add d
-  |
-  ~
-#else
   $ hg log -Gfr 'desc("mBDm-0")' d
   o  8 d-2 re-add d
   |
   ~
-#endif
 
-#if no-changeset
   $ hg log -Gfr 'desc("mDBm-0")' d
   o  8 d-2 re-add d
   |
   ~
-#else
-  $ hg log -Gfr 'desc("mDBm-0")' d
-  o  8 d-2 re-add d
-  |
-  ~
-#endif
 
   $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mBDm-0")'
   M b
@@ -1228,6 +1272,7 @@
   o  0 i-0 initial commit: a b h
   
 #else
+BROKEN: `hg log --follow <file>` relies on filelog metadata to work
   $ hg log -Gfr 'desc("mBFm-0")' d
   o  22 f-2: rename i -> d
   |
@@ -1243,6 +1288,7 @@
   o  0 i-0 initial commit: a b h
   
 #else
+BROKEN: `hg log --follow <file>` relies on filelog metadata to work
   $ hg log -Gfr 'desc("mFBm-0")' d
   o  22 f-2: rename i -> d
   |
@@ -1312,6 +1358,7 @@
   o  0 i-0 initial commit: a b h
   
 #else
+BROKEN: `hg log --follow <file>` relies on filelog metadata to work
   $ hg log -Gfr 'desc("mDGm-0")' d
   o    26 mDGm-0 simple merge - one way
   |\
@@ -1340,6 +1387,7 @@
   o  0 i-0 initial commit: a b h
   
 #else
+BROKEN: `hg log --follow <file>` relies on filelog metadata to work
   $ hg log -Gfr 'desc("mDGm-0")' d
   o    26 mDGm-0 simple merge - one way
   |\
@@ -1432,6 +1480,7 @@
   o  0 i-0 initial commit: a b h
   
 #else
+BROKEN: `hg log --follow <file>` relies on filelog metadata to work
   $ hg log -Gfr 'desc("mFGm-0")' d
   o    28 mFGm-0 simple merge - one way
   |\
@@ -1461,6 +1510,7 @@
   o  0 i-0 initial commit: a b h
   
 #else
+BROKEN: `hg log --follow <file>` relies on filelog metadata to work
   $ hg log -Gfr 'desc("mGFm-0")' d
   o    29 mGFm-0 simple merge - the other way
   |\
@@ -1566,3 +1616,51 @@
   A d
   $ hg status --copies --rev 'desc("b-1")' --rev 'desc("mCB-revert-m-0")'
   $ hg status --copies --rev 'desc("b-1")' --rev 'desc("mBC-revert-m-0")'
+
+
+Merging a branch where a rename was deleted with a branch where the same file was renamed
+------------------------------------------------------------------------------------------
+
+Create a "conflicting" merge where `d` get removed on one branch before its
+rename information actually conflict with the other branch.
+
+(the copy information from the branch that was not deleted should win).
+
+  $ hg log -G --rev '::(desc("mCH-delete-before-conflict-m")+desc("mHC-delete-before-conflict-m"))'
+  @    36 mHC-delete-before-conflict-m-0
+  |\
+  +---o  35 mCH-delete-before-conflict-m-0
+  | |/
+  | o  34 h-1: b -(move)-> d
+  | |
+  o |  6 c-1 delete d
+  | |
+  o |  2 i-2: c -move-> d
+  | |
+  o |  1 i-1: a -move-> c
+  |/
+  o  0 i-0 initial commit: a b h
+  
+
+  $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mCH-delete-before-conflict-m")'
+  A d
+    b (no-compatibility no-changeset !)
+  R a
+  R b
+  $ hg status --copies --rev 'desc("i-0")' --rev 'desc("mHC-delete-before-conflict-m")'
+  A d
+    b
+  R a
+  R b
+  $ hg status --copies --rev 'desc("c-1")' --rev 'desc("mCH-delete-before-conflict-m")'
+  A d
+    b
+  R b
+  $ hg status --copies --rev 'desc("c-1")' --rev 'desc("mHC-delete-before-conflict-m")'
+  A d
+    b
+  R b
+  $ hg status --copies --rev 'desc("h-1")' --rev 'desc("mCH-delete-before-conflict-m")'
+  R a
+  $ hg status --copies --rev 'desc("h-1")' --rev 'desc("mHC-delete-before-conflict-m")'
+  R a
--- a/tests/test-copies-in-changeset.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-copies-in-changeset.t	Mon Nov 02 14:39:43 2020 -0500
@@ -344,7 +344,7 @@
   $ hg mv a b
   $ hg ci -qm 'rename a to b'
   $ hg rebase -d 1 --config rebase.experimental.inmemory=yes
-  rebasing 2:* "rename a to b" (tip) (glob)
+  rebasing 2:* tip "rename a to b" (glob)
   merging a and b to b
   saved backup bundle to $TESTTMP/rebase-rename/.hg/strip-backup/*-*-rebase.hg (glob)
   $ hg st --change . --copies
--- a/tests/test-copies.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-copies.t	Mon Nov 02 14:39:43 2020 -0500
@@ -502,7 +502,7 @@
   $ hg debugpathcopies 2 4
   x -> z (no-filelog !)
   $ hg debugpathcopies 0 4
-  x -> z (filelog !)
+  x -> z (no-changeset no-compatibility !)
   $ hg debugpathcopies 1 5
   $ hg debugpathcopies 2 5
   x -> z (no-filelog !)
@@ -625,8 +625,8 @@
      a
 
   $ hg rebase -r . -d 2 -t :other
-  rebasing 5:5018b1509e94 "added willconflict and d" (tip) (no-changeset !)
-  rebasing 5:af8d273bf580 "added willconflict and d" (tip) (changeset !)
+  rebasing 5:5018b1509e94 tip "added willconflict and d" (no-changeset !)
+  rebasing 5:af8d273bf580 tip "added willconflict and d" (changeset !)
 
   $ hg up 3 -q
   $ hg l --hidden
--- a/tests/test-copy-move-merge.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-copy-move-merge.t	Mon Nov 02 14:39:43 2020 -0500
@@ -137,7 +137,7 @@
 
   $ hg up -qC 2
   $ hg rebase --keep -d 1 -b 2 --config extensions.rebase=
-  rebasing 2:add3f11052fa "other" (tip)
+  rebasing 2:add3f11052fa tip "other"
   merging b and a to b
   merging c and a to c
 
@@ -156,7 +156,7 @@
   $ hg rebase --keep -d 1 -b 2 --config extensions.rebase= --config experimental.copytrace=off --config ui.interactive=True << EOF
   > c
   > EOF
-  rebasing 2:add3f11052fa "other" (tip)
+  rebasing 2:add3f11052fa tip "other"
   file 'a' was deleted in local [dest] but was modified in other [source].
   You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
   What do you want to do? c
@@ -238,7 +238,7 @@
 file is copied from `0:a`, so the file history of the `3:b` should trace directly to `0:a`.
 
   $ hg rebase -d 2 -s 3 --config extensions.rebase= --config experimental.copytrace=off
-  rebasing 3:47e1a9e6273b "copy a->b (2)" (tip)
+  rebasing 3:47e1a9e6273b tip "copy a->b (2)"
   saved backup bundle to $TESTTMP/copydisable3/.hg/strip-backup/47e1a9e6273b-2d099c59-rebase.hg
 
   $ hg log -G -f b
--- a/tests/test-copytrace-heuristics.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-copytrace-heuristics.t	Mon Nov 02 14:39:43 2020 -0500
@@ -54,7 +54,7 @@
      desc: initial
 
   $ hg rebase -s . -d 1
-  rebasing 2:557f403c0afd "mod a, mod dir/file.txt" (tip)
+  rebasing 2:557f403c0afd tip "mod a, mod dir/file.txt"
   merging b and a to b
   merging dir2/file.txt and dir/file.txt to dir2/file.txt
   saved backup bundle to $TESTTMP/repo/.hg/strip-backup/557f403c0afd-9926eeff-rebase.hg
@@ -87,7 +87,7 @@
      desc: initial
 
   $ hg rebase -s . -d 1
-  rebasing 2:d526312210b9 "mode a" (tip)
+  rebasing 2:d526312210b9 tip "mode a"
   file 'a' was deleted in local [dest] but was modified in other [source].
   You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
   What do you want to do? u
@@ -126,7 +126,7 @@
      desc: initial
 
   $ hg rebase -s . -d 2
-  rebasing 3:9d5cf99c3d9f "mod a" (tip)
+  rebasing 3:9d5cf99c3d9f tip "mod a"
   merging b and a to b
   saved backup bundle to $TESTTMP/repo/.hg/strip-backup/9d5cf99c3d9f-f02358cc-rebase.hg
   $ cd ..
@@ -161,7 +161,7 @@
      desc: initial
 
   $ hg rebase -s . -d 0
-  rebasing 3:fbe97126b396 "mod b" (tip)
+  rebasing 3:fbe97126b396 tip "mod b"
   merging a and b to a
   saved backup bundle to $TESTTMP/repo/.hg/strip-backup/fbe97126b396-cf5452a1-rebase.hg
   $ cd ..
@@ -198,7 +198,7 @@
      desc: initial
 
   $ hg rebase -s . -d 2
-  rebasing 3:6b2f4cece40f "mod dir/a" (tip)
+  rebasing 3:6b2f4cece40f tip "mod dir/a"
   merging dir/b and dir/a to dir/b
   saved backup bundle to $TESTTMP/repo/.hg/strip-backup/6b2f4cece40f-503efe60-rebase.hg
   $ cd ..
@@ -243,7 +243,7 @@
 With small limit
 
   $ hg rebase -s 2 -d 1 --config experimental.copytrace.movecandidateslimit=0
-  rebasing 2:ef716627c70b "mod a" (tip)
+  rebasing 2:ef716627c70b tip "mod a"
   skipping copytracing for 'a', more candidates than the limit: 7
   file 'a' was deleted in local [dest] but was modified in other [source].
   You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
@@ -257,7 +257,7 @@
 With default limit which is 100
 
   $ hg rebase -s 2 -d 1
-  rebasing 2:ef716627c70b "mod a" (tip)
+  rebasing 2:ef716627c70b tip "mod a"
   merging foo and a to foo
   saved backup bundle to $TESTTMP/repo/.hg/strip-backup/ef716627c70b-24681561-rebase.hg
 
@@ -323,7 +323,7 @@
      desc: initial
 
   $ hg rebase -s . -d 1
-  rebasing 2:a33d80b6e352 "mv dir/ dir2/" (tip)
+  rebasing 2:a33d80b6e352 tip "mv dir/ dir2/"
   merging dir/a and dir2/a to dir2/a
   saved backup bundle to $TESTTMP/repo/.hg/strip-backup/a33d80b6e352-fecb9ada-rebase.hg
   $ cd ..
@@ -358,7 +358,7 @@
   o  rev: 0
      desc: initial
   $ hg rebase -s . -d 2
-  rebasing 3:d41316942216 "mod a" (tip)
+  rebasing 3:d41316942216 tip "mod a"
   merging c and a to c
   saved backup bundle to $TESTTMP/repo/.hg/strip-backup/d41316942216-2b5949bc-rebase.hg
 
@@ -431,7 +431,7 @@
      desc: initial
 
   $ hg rebase -s . -d 2
-  rebasing 3:ef716627c70b "mod a" (tip)
+  rebasing 3:ef716627c70b tip "mod a"
   merging b and a to b
   saved backup bundle to $TESTTMP/repo/.hg/strip-backup/ef716627c70b-24681561-rebase.hg
   $ ls -A
@@ -504,7 +504,7 @@
      desc: initial
 
   $ hg rebase -s . -d 1
-  rebasing 2:ef716627c70b "mod a" (tip)
+  rebasing 2:ef716627c70b tip "mod a"
   merging b and a to b
   merging c and a to c
   saved backup bundle to $TESTTMP/repo/repo/.hg/strip-backup/ef716627c70b-24681561-rebase.hg
@@ -631,7 +631,7 @@
      desc: initial
 
   $ hg rebase -s . -d 1 --config experimental.copytrace.sourcecommitlimit=100
-  rebasing 2:6207d2d318e7 "mod a" (tip)
+  rebasing 2:6207d2d318e7 tip "mod a"
   merging dir2/b and dir1/a to dir2/b
   saved backup bundle to $TESTTMP/repo/repo/.hg/strip-backup/6207d2d318e7-1c9779ad-rebase.hg
   $ cat dir2/b
@@ -669,7 +669,7 @@
      desc: initial
 
   $ hg rebase -s . -d 1 --config experimental.copytrace.sourcecommitlimit=100
-  rebasing 2:e8919e7df8d0 "mv dir1 dir2" (tip)
+  rebasing 2:e8919e7df8d0 tip "mv dir1 dir2"
   saved backup bundle to $TESTTMP/repo/repo/.hg/strip-backup/e8919e7df8d0-f62fab62-rebase.hg
   $ ls dir2
   a
--- a/tests/test-dirstate-nonnormalset.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-dirstate-nonnormalset.t	Mon Nov 02 14:39:43 2020 -0500
@@ -1,6 +1,6 @@
   $ cat >> $HGRCPATH << EOF
-  > [ui]
-  > logtemplate="{rev}:{node|short} ({phase}) [{tags} {bookmarks}] {desc|firstline}\n"
+  > [command-templates]
+  > log="{rev}:{node|short} ({phase}) [{tags} {bookmarks}] {desc|firstline}\n"
   > [extensions]
   > dirstateparanoidcheck = $TESTDIR/../contrib/dirstatenonnormalcheck.py
   > [experimental]
--- a/tests/test-dirstate-race.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-dirstate-race.t	Mon Nov 02 14:39:43 2020 -0500
@@ -225,7 +225,7 @@
   > EOF
 
   $ hg rebase -s . -d 3 --tool test
-  rebasing 4:b08445fd6b2a "c4" (tip)
+  rebasing 4:b08445fd6b2a tip "c4"
   merging a
   custom merge tool
   custom merge tool end
--- a/tests/test-fix.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-fix.t	Mon Nov 02 14:39:43 2020 -0500
@@ -865,7 +865,7 @@
   $ hg commit -Aqm "foo 2"
 
   $ hg --config extensions.rebase= rebase -r 1 -d 0
-  rebasing 1:c3b6dc0e177a "foo 2" (tip)
+  rebasing 1:c3b6dc0e177a tip "foo 2"
   merging foo.whole
   warning: conflicts while merging foo.whole! (edit, then use 'hg resolve --mark')
   unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
--- a/tests/test-glog-beautifygraph.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-glog-beautifygraph.t	Mon Nov 02 14:39:43 2020 -0500
@@ -2534,7 +2534,7 @@
 
 node template with changesetprinter:
 
-  $ hg log -Gqr 5:7 --config ui.graphnodetemplate='"{rev}"'
+  $ hg log -Gqr 5:7 --config command-templates.graphnode='"{rev}"'
   7  7:9febbb9c8b2e
   \xe2\x94\x82 (esc)
   6    6:9feeac35a70a
@@ -2547,7 +2547,7 @@
 node template with changesettemplater (shared cache variable):
 
   $ hg log -Gr 5:7 -T '{latesttag % "{rev} {tag}+{distance}"}\n' \
-  > --config ui.graphnodetemplate='{ifeq(latesttagdistance, 0, "#", graphnode)}'
+  > --config command-templates.graphnode='{ifeq(latesttagdistance, 0, "#", graphnode)}'
   \xe2\x97\x8b  7 foo-bar+1 (esc)
   \xe2\x94\x82 (esc)
   #    6 foo-bar+0
@@ -2560,7 +2560,7 @@
 label() should just work in node template:
 
   $ hg log -Gqr 7 --config extensions.color= --color=debug \
-  > --config ui.graphnodetemplate='{label("branch.{branch}", rev)}'
+  > --config command-templates.graphnode='{label("branch.{branch}", rev)}'
   [branch.default\xe2\x94\x827]  [log.node|7:9febbb9c8b2e] (esc)
   \xe2\x94\x82 (esc)
   \xe2\x95\xa7 (esc)
@@ -3084,8 +3084,8 @@
   $ hg init multiroots
   $ cd multiroots
   $ cat <<EOF > .hg/hgrc
-  > [ui]
-  > logtemplate = '{rev} {desc}\n\n'
+  > [command-templates]
+  > log = '{rev} {desc}\n\n'
   > EOF
 
   $ touch foo
--- a/tests/test-glog-topological.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-glog-topological.t	Mon Nov 02 14:39:43 2020 -0500
@@ -1,8 +1,8 @@
 This test file aims at test topological iteration and the various configuration it can has.
 
   $ cat >> $HGRCPATH << EOF
-  > [ui]
-  > logtemplate={rev}\n
+  > [command-templates]
+  > log={rev}\n
   > EOF
 
 On this simple example, all topological branch are displayed in turn until we
--- a/tests/test-glog.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-glog.t	Mon Nov 02 14:39:43 2020 -0500
@@ -2384,6 +2384,18 @@
 
 node template with changesetprinter:
 
+  $ hg log -Gqr 5:7 --config command-templates.graphnode='"{rev}"'
+  7  7:9febbb9c8b2e
+  |
+  6    6:9feeac35a70a
+  |\
+  | ~
+  5  5:99b31f1c2782
+  |
+  ~
+
+node template with changesetprinter (legacy config):
+
   $ hg log -Gqr 5:7 --config ui.graphnodetemplate='"{rev}"'
   7  7:9febbb9c8b2e
   |
@@ -2397,7 +2409,7 @@
 node template with changesettemplater (shared cache variable):
 
   $ hg log -Gr 5:7 -T '{latesttag % "{rev} {tag}+{distance}"}\n' \
-  > --config ui.graphnodetemplate='{ifeq(latesttagdistance, 0, "#", graphnode)}'
+  > --config command-templates.graphnode='{ifeq(latesttagdistance, 0, "#", graphnode)}'
   o  7 foo-bar+1
   |
   #    6 foo-bar+0
@@ -2410,7 +2422,7 @@
 label() should just work in node template:
 
   $ hg log -Gqr 7 --config extensions.color= --color=debug \
-  > --config ui.graphnodetemplate='{label("branch.{branch}", rev)}'
+  > --config command-templates.graphnode='{label("branch.{branch}", rev)}'
   [branch.default|7]  [log.node|7:9febbb9c8b2e]
   |
   ~
@@ -3420,8 +3432,8 @@
   $ hg init multiroots
   $ cd multiroots
   $ cat <<EOF > .hg/hgrc
-  > [ui]
-  > logtemplate = '{rev} {desc}\n\n'
+  > [command-templates]
+  > log = '{rev} {desc}\n\n'
   > EOF
 
   $ touch foo
--- a/tests/test-grep.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-grep.t	Mon Nov 02 14:39:43 2020 -0500
@@ -851,8 +851,8 @@
   $ cd follow
 
   $ cat <<'EOF' >> .hg/hgrc
-  > [ui]
-  > logtemplate = '{rev}: {join(files % "{status} {path}", ", ")}\n'
+  > [command-templates]
+  > log = '{rev}: {join(files % "{status} {path}", ", ")}\n'
   > EOF
 
   $ for f in add0 add0-mod1 add0-rm1 add0-mod2 add0-rm2 add0-mod3 add0-mod4 add0-rm4; do
--- a/tests/test-hgrc.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-hgrc.t	Mon Nov 02 14:39:43 2020 -0500
@@ -68,8 +68,7 @@
   $ echo '[foo]' > $HGRC
   $ echo '  x = y' >> $HGRC
   $ hg version
-  hg: parse error at $TESTTMP/hgrc:2:   x = y
-  unexpected leading whitespace
+  hg: parse error at $TESTTMP/hgrc:2: unexpected leading whitespace:   x = y
   [255]
 
   $ "$PYTHON" -c "from __future__ import print_function; print('[foo]\nbar = a\n b\n c \n  de\n fg \nbaz = bif cb \n')" \
--- a/tests/test-histedit-merge-tools.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-histedit-merge-tools.t	Mon Nov 02 14:39:43 2020 -0500
@@ -12,8 +12,6 @@
   > [extensions]
   > histedit=
   > mockmakedate = $TESTDIR/mockmakedate.py
-  > [ui]
-  > pre-merge-tool-output-template='pre-merge message for {node}\n'
   > EOF
 
 Merge conflict
@@ -21,6 +19,11 @@
 
   $ hg init r
   $ cd r
+  $ cat >> .hg/hgrc <<EOF
+  > [command-templates]
+  > pre-merge-tool-output='pre-merge message for {node}\n'
+  > EOF
+
   $ echo foo > file
   $ hg add file
   $ hg ci -m "First" -d "1 0"
@@ -55,3 +58,26 @@
   merging file
   pre-merge message for b90fa2e91a6d11013945a5f684be45b84a8ca6ec
   7181f42b8fca: skipping changeset (no changes)
+  $ hg histedit --abort
+  abort: no histedit in progress
+  [255]
+  $ cd ..
+
+Test legacy config name
+
+  $ hg init r2
+  $ cd r2
+  $ echo foo > file
+  $ hg add file
+  $ hg ci -m "First"
+  $ echo bar > file
+  $ hg ci -m "Second"
+  $ echo conflict > file
+  $ hg co -m 0 --config ui.merge=false \
+  > --config ui.pre-merge-tool-output-template='legacy config: {node}\n'
+  merging file
+  legacy config: 889c9c4d58bd4ce74815efd04a01e0f2bf6765a7
+  merging file failed!
+  0 files updated, 0 files merged, 0 files removed, 1 files unresolved
+  use 'hg resolve' to retry unresolved file merges
+  [1]
--- a/tests/test-histedit-obsolete.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-histedit-obsolete.t	Mon Nov 02 14:39:43 2020 -0500
@@ -293,8 +293,8 @@
 -------------------------------------------
 
   $ cat >> $HGRCPATH << EOF
-  > [ui]
-  > logtemplate= {rev}:{node|short} ({phase}) {desc|firstline}\n
+  > [command-templates]
+  > log = {rev}:{node|short} ({phase}) {desc|firstline}\n
   > EOF
 
   $ hg ph -pv '.^'
--- a/tests/test-infinitepush-ci.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-infinitepush-ci.t	Mon Nov 02 14:39:43 2020 -0500
@@ -356,7 +356,7 @@
 
   $ hg phase -r . --draft --force
   $ hg rebase -r 6 -d 3
-  rebasing 6:9b42578d4447 "added f" (tip)
+  rebasing 6:9b42578d4447 tip "added f"
 
   $ hg glog
   @  7:99949238d9ac added f
--- a/tests/test-largefiles-update.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-largefiles-update.t	Mon Nov 02 14:39:43 2020 -0500
@@ -307,7 +307,7 @@
 
   $ hg rebase -s 1 -d 2 --keep
   rebasing 1:72518492caa6 "#1"
-  rebasing 4:07d6153b5c04 "#4" (tip)
+  rebasing 4:07d6153b5c04 tip "#4"
 
   $ hg status -A large1
   large1: $ENOENT$
--- a/tests/test-log.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-log.t	Mon Nov 02 14:39:43 2020 -0500
@@ -450,6 +450,16 @@
   a
   
   
+Respects ui.logtemplate and command-templates.log configs (the latter takes
+precedence)
+
+  $ hg log -r 0 --config ui.logtemplate="foo {rev}\n"
+  foo 0
+  $ hg log -r 0 --config command-templates.log="bar {rev}\n"
+  bar 0
+  $ hg log -r 0 --config ui.logtemplate="foo {rev}\n" \
+  > --config command-templates.log="bar {rev}\n"
+  bar 0
 
 
 -f and multiple filelog heads
@@ -1122,8 +1132,8 @@
   $ hg init follow-dup
   $ cd follow-dup
   $ cat <<EOF >> .hg/hgrc
-  > [ui]
-  > logtemplate = '=== {rev}: {desc}\n'
+  > [command-templates]
+  > log = '=== {rev}: {desc}\n'
   > [diff]
   > nodates = True
   > EOF
--- a/tests/test-narrow-copies.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-narrow-copies.t	Mon Nov 02 14:39:43 2020 -0500
@@ -70,5 +70,5 @@
   $ echo new > inside/f5
   $ hg ci -Aqm 'add inside/f5'
   $ hg --config extensions.rebase= rebase -d 'public()' -r .
-  rebasing 6:610b60178c28 "add inside/f5" (tip)
+  rebasing 6:610b60178c28 tip "add inside/f5"
   saved backup bundle to $TESTTMP/narrow/.hg/strip-backup/610b60178c28-65716a78-rebase.hg
--- a/tests/test-narrow-rebase.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-narrow-rebase.t	Mon Nov 02 14:39:43 2020 -0500
@@ -61,7 +61,7 @@
   $ echo modified > inside/f2
   $ hg ci -qm 'modify inside/f2'
   $ hg rebase -d 'desc("modify inside/f1")'
-  rebasing 5:c2f36d04e05d "modify inside/f2" (tip)
+  rebasing 5:c2f36d04e05d tip "modify inside/f2"
   saved backup bundle to $TESTTMP/narrow/.hg/strip-backup/*-rebase.hg (glob)
 
 Can rebase onto conflicting changes inside narrow spec
@@ -70,14 +70,14 @@
   $ echo conflicting > inside/f1
   $ hg ci -qm 'conflicting inside/f1'
   $ hg rebase -d 'desc("modify inside/f1")' 2>&1 | egrep -v '(warning:|incomplete!)'
-  rebasing 6:cdce97fbf653 "conflicting inside/f1" (tip)
+  rebasing 6:cdce97fbf653 tip "conflicting inside/f1"
   merging inside/f1
   unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
   $ echo modified3 > inside/f1
   $ hg resolve -m 2>&1 | grep -v continue:
   (no more unresolved files)
   $ hg continue
-  rebasing 6:cdce97fbf653 "conflicting inside/f1" (tip)
+  rebasing 6:cdce97fbf653 tip "conflicting inside/f1"
   saved backup bundle to $TESTTMP/narrow/.hg/strip-backup/*-rebase.hg (glob)
 
 Can rebase onto non-conflicting changes outside narrow spec
@@ -86,7 +86,7 @@
   $ echo modified > inside/f2
   $ hg ci -qm 'modify inside/f2'
   $ hg rebase -d 'desc("modify outside/f1")'
-  rebasing 7:c2f36d04e05d "modify inside/f2" (tip)
+  rebasing 7:c2f36d04e05d tip "modify inside/f2"
   saved backup bundle to $TESTTMP/narrow/.hg/strip-backup/*-rebase.hg (glob)
 
 Rebase interrupts on conflicting changes outside narrow spec
--- a/tests/test-obsmarker-template.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-obsmarker-template.t	Mon Nov 02 14:39:43 2020 -0500
@@ -122,7 +122,7 @@
   o  ea207398892e
   
 
-  $ hg log -G --config ui.logtemplate=
+  $ hg log -G --config command-templates.log=
   o  changeset:   3:d004c8f274b9
   |  tag:         tip
   |  parent:      0:ea207398892e
--- a/tests/test-obsmarkers-effectflag.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-obsmarkers-effectflag.t	Mon Nov 02 14:39:43 2020 -0500
@@ -76,7 +76,7 @@
   $ mkcommit C0
   $ mkcommit D0
   $ hg rebase -r . -d 'desc(B0)'
-  rebasing 10:c85eff83a034 "D0" (tip)
+  rebasing 10:c85eff83a034 tip "D0"
 
 check result
 
--- a/tests/test-obsolete-bundle-strip.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-obsolete-bundle-strip.t	Mon Nov 02 14:39:43 2020 -0500
@@ -9,9 +9,9 @@
 ------------
 
   $ cat >> $HGRCPATH <<EOF
-  > [ui]
+  > [command-templates]
   > # simpler log output
-  > logtemplate = "{node|short}: {desc}\n"
+  > log = "{node|short}: {desc}\n"
   > 
   > [experimental]
   > # enable evolution
--- a/tests/test-obsolete-checkheads.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-obsolete-checkheads.t	Mon Nov 02 14:39:43 2020 -0500
@@ -3,8 +3,8 @@
   > [phases]
   > # public changeset are not obsolete
   > publish=false
-  > [ui]
-  > logtemplate='{node|short} ({phase}) {desc|firstline}\n'
+  > [command-templates]
+  > log='{node|short} ({phase}) {desc|firstline}\n'
   > [experimental]
   > evolution.createmarkers=True
   > EOF
--- a/tests/test-obsolete-distributed.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-obsolete-distributed.t	Mon Nov 02 14:39:43 2020 -0500
@@ -16,8 +16,8 @@
   > evolution = all
   > [phases]
   > publish = False
-  > [ui]
-  > logtemplate= {rev}:{node|short} {desc}{if(obsfate, " [{join(obsfate, "; ")}]")}\n
+  > [command-templates]
+  > log = {rev}:{node|short} {desc}{if(obsfate, " [{join(obsfate, "; ")}]")}\n
   > EOF
 
 Check distributed chain building
--- a/tests/test-phabricator.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-phabricator.t	Mon Nov 02 14:39:43 2020 -0500
@@ -101,7 +101,7 @@
   $ hg ci --addremove -m 'create alpha for phabricator test €'
   adding alpha
   $ hg phabsend -r . --test-vcr "$VCR/phabsend-create-alpha.json"
-  D7915 - created - d386117f30e6: create alpha for phabricator test \xe2\x82\xac (esc)
+  D7915 - created - 0:d386117f30e6 tip "create alpha for phabricator test \xe2\x82\xac" (esc)
   new commits: ['347bf67801e5']
   saved backup bundle to $TESTTMP/repo/.hg/strip-backup/d386117f30e6-24ffe649-phabsend.hg
   $ echo more >> alpha
@@ -112,8 +112,8 @@
   adding beta
   $ hg phabsend -r ".^::" --test-vcr "$VCR/phabsend-update-alpha-create-beta.json"
   c44b38f24a45 mapped to old nodes []
-  D7915 - updated - c44b38f24a45: create alpha for phabricator test \xe2\x82\xac (esc)
-  D7916 - created - 9e6901f21d5b: create beta for phabricator test
+  D7915 - updated - 0:c44b38f24a45 "create alpha for phabricator test \xe2\x82\xac" (esc)
+  D7916 - created - 1:9e6901f21d5b tip "create beta for phabricator test"
   new commits: ['a692622e6937']
   saved backup bundle to $TESTTMP/repo/.hg/strip-backup/9e6901f21d5b-1fcd4f0e-phabsend.hg
   $ unset HGENCODING
@@ -127,8 +127,8 @@
   $ echo 'draft change' > alpha
   $ hg ci -m 'create draft change for phabricator testing'
   $ hg phabsend --amend -r '.^::' --test-vcr "$VCR/phabsend-create-public.json"
-  D7917 - created - 7b4185ab5d16: create public change for phabricator testing
-  D7918 - created - 251c1c333fc6: create draft change for phabricator testing
+  D7917 - created - 2:7b4185ab5d16 "create public change for phabricator testing"
+  D7918 - created - 3:251c1c333fc6 tip "create draft change for phabricator testing"
   warning: not updating public commit 2:7b4185ab5d16
   new commits: ['3244dc4a3334']
   saved backup bundle to $TESTTMP/repo/.hg/strip-backup/251c1c333fc6-41cb7c3b-phabsend.hg
@@ -175,7 +175,7 @@
   $ hg ci --addremove -m "create comment for phabricator test"
   adding comment
   $ hg phabsend -r . -m "For default branch" --test-vcr "$VCR/phabsend-comment-created.json"
-  D7919 - created - d5dddca9023d: create comment for phabricator test
+  D7919 - created - 4:d5dddca9023d tip "create comment for phabricator test"
   new commits: ['f7db812bbe1d']
   saved backup bundle to $TESTTMP/repo/.hg/strip-backup/d5dddca9023d-adf673ba-phabsend.hg
   $ echo comment2 >> comment
@@ -183,12 +183,12 @@
   saved backup bundle to $TESTTMP/repo/.hg/strip-backup/f7db812bbe1d-8fcded77-amend.hg
   $ hg phabsend -r . -m "Address review comments" --test-vcr "$VCR/phabsend-comment-updated.json"
   1849d7828727 mapped to old nodes []
-  D7919 - updated - 1849d7828727: create comment for phabricator test
+  D7919 - updated - 4:1849d7828727 tip "create comment for phabricator test"
 
 Phabsending a skipped commit:
   $ hg phabsend --no-amend -r . --test-vcr "$VCR/phabsend-skipped.json"
   1849d7828727 mapped to old nodes ['1849d7828727']
-  D7919 - skipped - 1849d7828727: create comment for phabricator test
+  D7919 - skipped - 4:1849d7828727 tip "create comment for phabricator test"
 
 Phabsend doesn't create an instability when restacking existing revisions on top
 of new revisions.
@@ -210,7 +210,7 @@
   $ echo "mod2" > file1.txt
   $ hg ci -m 'modified 2'
   $ hg phabsend -r . --test-vcr "$VCR/phabsend-add-parent-setup.json"
-  D8433 - created - 5d3959e20d1d: modified 2
+  D8433 - created - 2:5d3959e20d1d tip "modified 2"
   new commits: ['2b4aa8a88d61']
   $ hg log -G -T compact
   @  3[tip]:1   2b4aa8a88d61   1970-01-01 00:00 +0000   test
@@ -231,8 +231,8 @@
   $ hg up -q 3
   $ hg phabsend -r ".^ + ." --test-vcr "$VCR/phabsend-add-parent.json"
   2b4aa8a88d61 mapped to old nodes ['2b4aa8a88d61']
-  D8434 - created - d549263bcb2d: modified 1
-  D8433 - updated - 2b4aa8a88d61: modified 2
+  D8434 - created - 1:d549263bcb2d "modified 1"
+  D8433 - updated - 3:2b4aa8a88d61 "modified 2"
   new commits: ['876a60d024de']
   new commits: ['0c6523cb1d0f']
   restabilizing 1eda4bf55021 as d2c78c3a3e01
@@ -313,9 +313,9 @@
   $ hg phabsend -r 5::tip --test-vcr "$VCR/phabsend-no-restack-orphan.json"
   876a60d024de mapped to old nodes ['876a60d024de']
   0c6523cb1d0f mapped to old nodes ['0c6523cb1d0f']
-  D8434 - updated - 876a60d024de: modified 1
-  D8433 - updated - 0c6523cb1d0f: modified 2
-  D8435 - created - 082be6c94150: modified A
+  D8434 - updated - 5:876a60d024de "modified 1"
+  D8433 - updated - 6:0c6523cb1d0f "modified 2"
+  D8435 - created - 10:082be6c94150 tip "modified A"
   new commits: ['b5913193c805']
   not restabilizing unchanged d2c78c3a3e01
   $ hg log -G
@@ -374,10 +374,10 @@
   $ hg ci -m 'remove binary'
   $ hg phabsend -r .~2:: --test-vcr "$VCR/phabsend-binary.json"
   uploading bin@aa24a81f55de
-  D8007 - created - aa24a81f55de: add binary
+  D8007 - created - 5:aa24a81f55de "add binary"
   uploading bin@d8d62a881b54
-  D8008 - created - d8d62a881b54: modify binary
-  D8009 - created - af55645b2e29: remove binary
+  D8008 - created - 6:d8d62a881b54 "modify binary"
+  D8009 - created - 7:af55645b2e29 tip "remove binary"
   new commits: ['b8139fbb4a57']
   new commits: ['c88ce4c2d2ad']
   new commits: ['75dbbc901145']
@@ -421,14 +421,14 @@
 
   $ hg phabsend -r .~4:: --test-vcr "$VCR/phabsend-binary-renames.json"
   uploading bin2@f42f9195e00c
-  D8128 - created - f42f9195e00c: add another binary
-  D8129 - created - 834ab31d80ae: moved binary
-  D8130 - created - 494b750e5194: copied binary
+  D8128 - created - 8:f42f9195e00c "add another binary"
+  D8129 - created - 9:834ab31d80ae "moved binary"
+  D8130 - created - 10:494b750e5194 "copied binary"
   uploading bin2_moved_again@25f766b50cc2
-  D8131 - created - 25f766b50cc2: move+mod copied binary
+  D8131 - created - 11:25f766b50cc2 "move+mod copied binary"
   uploading bin2_moved_copied@1b87b363a5e4
   uploading bin2_moved@1b87b363a5e4
-  D8132 - created - 1b87b363a5e4: copy+mod moved binary
+  D8132 - created - 12:1b87b363a5e4 tip "copy+mod moved binary"
   new commits: ['90437c20312a']
   new commits: ['f391f4da4c61']
   new commits: ['da86a9f3268c']
@@ -662,9 +662,9 @@
 
   $ hg phase -r tip --public
   $ hg phabsend --fold -r 1:: --test-vcr "$VCR/phabsend-fold-immutable.json"
-  D8386 - created - a959a3f69d8d: one: first commit to review
-  D8386 - created - 24a4438154ba: two: second commit to review
-  D8386 - created - d235829e802c: 3: a commit with no detailed message
+  D8386 - created - 1:a959a3f69d8d "one: first commit to review"
+  D8386 - created - 2:24a4438154ba "two: second commit to review"
+  D8386 - created - 3:d235829e802c tip "3: a commit with no detailed message"
   warning: not updating public commit 1:a959a3f69d8d
   warning: not updating public commit 2:24a4438154ba
   warning: not updating public commit 3:d235829e802c
@@ -676,13 +676,13 @@
 
   $ echo y | hg phabsend --fold --confirm -r 1:: \
   >          --test-vcr "$VCR/phabsend-fold-initial.json"
-  NEW - a959a3f69d8d: one: first commit to review
-  NEW - 24a4438154ba: two: second commit to review
-  NEW - d235829e802c: 3: a commit with no detailed message
+  NEW - 1:a959a3f69d8d "one: first commit to review"
+  NEW - 2:24a4438154ba "two: second commit to review"
+  NEW - 3:d235829e802c tip "3: a commit with no detailed message"
   Send the above changes to https://phab.mercurial-scm.org/ (Y/n)? y
-  D8387 - created - a959a3f69d8d: one: first commit to review
-  D8387 - created - 24a4438154ba: two: second commit to review
-  D8387 - created - d235829e802c: 3: a commit with no detailed message
+  D8387 - created - 1:a959a3f69d8d "one: first commit to review"
+  D8387 - created - 2:24a4438154ba "two: second commit to review"
+  D8387 - created - 3:d235829e802c tip "3: a commit with no detailed message"
   updating local commit list for D8387
   new commits: ['602c4e738243', '832553266fe8', '921f8265efbd']
   saved backup bundle to $TESTTMP/folded/.hg/strip-backup/a959a3f69d8d-a4a24136-phabsend.hg
@@ -728,7 +728,7 @@
   obsolete feature not enabled but 1 markers found!
   1 files updated, 0 files merged, 1 files removed, 0 files unresolved
   $ hg rebase --config experimental.evolution=all --config extensions.rebase=
-  note: not rebasing 2:832553266fe8 "two: second commit to review", already in destination as 4:0124e5474c88 "two: second commit to review" (tip)
+  note: not rebasing 2:832553266fe8 "two: second commit to review", already in destination as 4:0124e5474c88 tip "two: second commit to review"
   rebasing 3:921f8265efbd "3: a commit with no detailed message"
 
 When commits have changed locally, the local commit list on Phabricator is
@@ -740,13 +740,13 @@
   602c4e738243 mapped to old nodes ['602c4e738243']
   0124e5474c88 mapped to old nodes ['832553266fe8']
   e4edb1fe3565 mapped to old nodes ['921f8265efbd']
-  D8387 - 602c4e738243: one: first commit to review
-  D8387 - 0124e5474c88: two: second commit to review
-  D8387 - e4edb1fe3565: 3: a commit with no detailed message
+  D8387 - 1:602c4e738243 "one: first commit to review"
+  D8387 - 4:0124e5474c88 "two: second commit to review"
+  D8387 - 5:e4edb1fe3565 tip "3: a commit with no detailed message"
   Send the above changes to https://phab.mercurial-scm.org/ (Y/n)? y
-  D8387 - updated - 602c4e738243: one: first commit to review
-  D8387 - updated - 0124e5474c88: two: second commit to review
-  D8387 - updated - e4edb1fe3565: 3: a commit with no detailed message
+  D8387 - updated - 1:602c4e738243 "one: first commit to review"
+  D8387 - updated - 4:0124e5474c88 "two: second commit to review"
+  D8387 - updated - 5:e4edb1fe3565 tip "3: a commit with no detailed message"
   obsolete feature not enabled but 2 markers found! (?)
   updating local commit list for D8387
   new commits: ['602c4e738243', '0124e5474c88', 'e4edb1fe3565']
@@ -772,9 +772,9 @@
   602c4e738243 mapped to old nodes ['602c4e738243']
   0124e5474c88 mapped to old nodes ['0124e5474c88']
   e4edb1fe3565 mapped to old nodes ['e4edb1fe3565']
-  D8387 - updated - 602c4e738243: one: first commit to review
-  D8387 - updated - 0124e5474c88: two: second commit to review
-  D8387 - updated - e4edb1fe3565: 3: a commit with no detailed message
+  D8387 - updated - 1:602c4e738243 "one: first commit to review"
+  D8387 - updated - 4:0124e5474c88 "two: second commit to review"
+  D8387 - updated - 5:e4edb1fe3565 tip "3: a commit with no detailed message"
   obsolete feature not enabled but 2 markers found! (?)
   local commit list for D8387 is already up-to-date
   $ hg log -Tcompact
@@ -801,10 +801,10 @@
   602c4e738243 mapped to old nodes ['602c4e738243']
   0124e5474c88 mapped to old nodes ['0124e5474c88']
   e4edb1fe3565 mapped to old nodes ['e4edb1fe3565']
-  D8387 - updated - 602c4e738243: one: first commit to review
-  D8387 - updated - 0124e5474c88: two: second commit to review
-  D8387 - updated - e4edb1fe3565: 3: a commit with no detailed message
-  D8387 - created - 94aaae213b23: four: extend the fold range
+  D8387 - updated - 1:602c4e738243 "one: first commit to review"
+  D8387 - updated - 4:0124e5474c88 "two: second commit to review"
+  D8387 - updated - 5:e4edb1fe3565 "3: a commit with no detailed message"
+  D8387 - created - 6:94aaae213b23 tip "four: extend the fold range"
   updating local commit list for D8387
   new commits: ['602c4e738243', '0124e5474c88', 'e4edb1fe3565', '51a04fea8707']
   $ hg log -r . -T '{desc}\n'
@@ -832,11 +832,11 @@
   0124e5474c88 mapped to old nodes ['0124e5474c88']
   e4edb1fe3565 mapped to old nodes ['e4edb1fe3565']
   51a04fea8707 mapped to old nodes ['51a04fea8707']
-  D8388 - created - 98d480e0d494: added file
-  D8388 - updated - 602c4e738243: one: first commit to review
-  D8388 - updated - 0124e5474c88: two: second commit to review
-  D8388 - updated - e4edb1fe3565: 3: a commit with no detailed message
-  D8388 - updated - 51a04fea8707: four: extend the fold range
+  D8388 - created - 0:98d480e0d494 "added file"
+  D8388 - updated - 1:602c4e738243 "one: first commit to review"
+  D8388 - updated - 4:0124e5474c88 "two: second commit to review"
+  D8388 - updated - 5:e4edb1fe3565 "3: a commit with no detailed message"
+  D8388 - updated - 7:51a04fea8707 tip "four: extend the fold range"
   updating local commit list for D8388
   new commits: ['15e9b14b4b4c', '6320b7d714cf', '3ee132d41dbc', '30682b960804', 'ac7db67f0991']
 
@@ -925,12 +925,12 @@
   30682b960804 mapped to old nodes ['30682b960804']
   6bc15dc99efd mapped to old nodes ['ac7db67f0991']
   b50946d5e490 mapped to old nodes ['ac7db67f0991']
-  D8388 - updated - 15e9b14b4b4c: added file
-  D8388 - updated - 6320b7d714cf: one: first commit to review
-  D8388 - updated - 3ee132d41dbc: two: second commit to review
-  D8388 - updated - 30682b960804: 3: a commit with no detailed message
-  D8388 - updated - 6bc15dc99efd: four: extend the fold range
-  D8388 - updated - b50946d5e490: four: extend the fold range
+  D8388 - updated - 8:15e9b14b4b4c "added file"
+  D8388 - updated - 9:6320b7d714cf "one: first commit to review"
+  D8388 - updated - 10:3ee132d41dbc "two: second commit to review"
+  D8388 - updated - 11:30682b960804 "3: a commit with no detailed message"
+  D8388 - updated - 14:6bc15dc99efd "four: extend the fold range"
+  D8388 - updated - 15:b50946d5e490 tip "four: extend the fold range"
   updating local commit list for D8388
   new commits: ['15e9b14b4b4c', '6320b7d714cf', '3ee132d41dbc', '30682b960804', '6bc15dc99efd', 'b50946d5e490']
 
@@ -939,7 +939,7 @@
   $ hg --config experimental.evolution=all --config extensions.rebase= \
   >    rebase -r '.^' -r . -d '.^^' --collapse -l log.txt
   rebasing 14:6bc15dc99efd "four: extend the fold range"
-  rebasing 15:b50946d5e490 "four: extend the fold range" (tip)
+  rebasing 15:b50946d5e490 tip "four: extend the fold range"
 
   $ hg phabsend --fold -r 8:: --test-vcr "$VCR/phabsend-fold-fold-end.json" \
   >             --config experimental.evolution=all
@@ -948,11 +948,11 @@
   3ee132d41dbc mapped to old nodes ['3ee132d41dbc']
   30682b960804 mapped to old nodes ['30682b960804']
   e919cdf3d4fe mapped to old nodes ['6bc15dc99efd', 'b50946d5e490']
-  D8388 - updated - 15e9b14b4b4c: added file
-  D8388 - updated - 6320b7d714cf: one: first commit to review
-  D8388 - updated - 3ee132d41dbc: two: second commit to review
-  D8388 - updated - 30682b960804: 3: a commit with no detailed message
-  D8388 - updated - e919cdf3d4fe: four: extend the fold range
+  D8388 - updated - 8:15e9b14b4b4c "added file"
+  D8388 - updated - 9:6320b7d714cf "one: first commit to review"
+  D8388 - updated - 10:3ee132d41dbc "two: second commit to review"
+  D8388 - updated - 11:30682b960804 "3: a commit with no detailed message"
+  D8388 - updated - 16:e919cdf3d4fe tip "four: extend the fold range"
   updating local commit list for D8388
   new commits: ['15e9b14b4b4c', '6320b7d714cf', '3ee132d41dbc', '30682b960804', 'e919cdf3d4fe']
 
@@ -987,8 +987,8 @@
   $ hg ci -m 'c2874a398f7e is my parent (generate test for phabsend)'
 
   $ hg phabsend -r 17::18  --test-vcr "$VCR/phabsend-hash-fixes.json"
-  D8945 - created - 133c1c6c6449: base review (generate test for phabsend)
-  D8946 - created - c2874a398f7e: 133c1c6c6449 is my parent (generate test for phabsend)
+  D8945 - created - 17:133c1c6c6449 "base review (generate test for phabsend)"
+  D8946 - created - 18:c2874a398f7e "133c1c6c6449 is my parent (generate test for phabsend)"
   new commits: ['f444f060f4d6']
   new commits: ['9c9290f945b1']
   restabilizing 1528c12fa2e4 as b28b20212bd4
--- a/tests/test-rebase-abort.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-rebase-abort.t	Mon Nov 02 14:39:43 2020 -0500
@@ -78,7 +78,7 @@
 
   $ hg rebase -s 3 -d 2
   rebasing 3:3163e20567cc "L1"
-  rebasing 4:46f0b057b5c0 "L2" (tip)
+  rebasing 4:46f0b057b5c0 tip "L2"
   merging common
   warning: conflicts while merging common! (edit, then use 'hg resolve --mark')
   unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
@@ -145,7 +145,7 @@
 
   $ hg rebase -s 3 -d 2
   rebasing 3:3163e20567cc "L1"
-  rebasing 4:46f0b057b5c0 "L2" (tip)
+  rebasing 4:46f0b057b5c0 tip "L2"
   merging common
   warning: conflicts while merging common! (edit, then use 'hg resolve --mark')
   unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
@@ -215,7 +215,7 @@
   $ hg rebase -b 4 -d 2
   rebasing 3:a6484957d6b9 "B bis"
   note: not rebasing 3:a6484957d6b9 "B bis", its destination already has all its changes
-  rebasing 4:145842775fec "C1" (tip)
+  rebasing 4:145842775fec tip "C1"
   merging c
   warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
   unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
@@ -274,7 +274,7 @@
   
 
   $ hg rebase -d master -r foo
-  rebasing 3:6c0f977a22d8 "C" (foo tip)
+  rebasing 3:6c0f977a22d8 foo tip "C"
   merging c
   warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
   unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
@@ -314,7 +314,7 @@
   created new head
 
   $ hg rebase -d @ -b foo --tool=internal:fail
-  rebasing 2:070cf4580bb5 "b2" (foo tip)
+  rebasing 2:070cf4580bb5 foo tip "b2"
   unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
   [1]
 
--- a/tests/test-rebase-base-flag.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-rebase-base-flag.t	Mon Nov 02 14:39:43 2020 -0500
@@ -36,9 +36,9 @@
   >   |
   >   R
   > EOS
-  rebasing 3:d6003a550c2c "C" (C)
-  rebasing 5:4526cf523425 "D" (D)
-  rebasing 6:b296604d9846 "E" (E tip)
+  rebasing 3:d6003a550c2c C "C"
+  rebasing 5:4526cf523425 D "D"
+  rebasing 6:b296604d9846 E tip "E"
   o  6: 4870f5e7df37 E
   |
   | o  5: dc999528138a D
@@ -66,9 +66,9 @@
   >   |
   >   R
   > EOS
-  rebasing 2:c1e6b162678d "B" (B)
-  rebasing 3:d6003a550c2c "C" (C)
-  rebasing 6:54c8f00cb91c "E" (E tip)
+  rebasing 2:c1e6b162678d B "B"
+  rebasing 3:d6003a550c2c C "C"
+  rebasing 6:54c8f00cb91c E tip "E"
   o    6: 00598421b616 E
   |\
   | o  5: 6b3e11729672 C
@@ -94,8 +94,8 @@
   >   |
   >   R
   > EOS
-  rebasing 2:c1e6b162678d "B" (B)
-  rebasing 5:54c8f00cb91c "E" (E tip)
+  rebasing 2:c1e6b162678d B "B"
+  rebasing 5:54c8f00cb91c E tip "E"
   o    5: e583bf3ff54c E
   |\
   | o  4: 85260910e847 B
@@ -119,9 +119,9 @@
   >   |
   >   R
   > EOS
-  rebasing 2:c1e6b162678d "B" (B)
-  rebasing 3:d6003a550c2c "C" (C)
-  rebasing 5:54c8f00cb91c "E" (E tip)
+  rebasing 2:c1e6b162678d B "B"
+  rebasing 3:d6003a550c2c C "C"
+  rebasing 5:54c8f00cb91c E tip "E"
   o    5: 00598421b616 E
   |\
   | o  4: 6b3e11729672 C
@@ -167,12 +167,12 @@
   >   |
   >   R
   > EOS
-  rebasing 3:a113dbaa660a "B1" (B1)
-  rebasing 5:06ce7b1cc8c2 "B2" (B2)
-  rebasing 6:0ac98cce32d3 "C1" (C1)
-  rebasing 8:781512f5e33d "C2" (C2)
-  rebasing 9:428d8c18f641 "E1" (E1)
-  rebasing 11:e1bf82f6b6df "E2" (E2)
+  rebasing 3:a113dbaa660a B1 "B1"
+  rebasing 5:06ce7b1cc8c2 B2 "B2"
+  rebasing 6:0ac98cce32d3 C1 "C1"
+  rebasing 8:781512f5e33d C2 "C2"
+  rebasing 9:428d8c18f641 E1 "E1"
+  rebasing 11:e1bf82f6b6df E2 "E2"
   o  12: e4a37b6fdbd2 E2
   |
   o  11: 9675bea983df E1
@@ -210,19 +210,19 @@
   >  \|/  |/  |/
   >   A   A   A
   > EOS
-  rebasing 2:dc0947a82db8 "C" (C)
-  rebasing 8:4e4f9194f9f1 "D" (D)
-  rebasing 9:03ca77807e91 "E" (E)
-  rebasing 10:afc707c82df0 "F" (F)
-  rebasing 13:690dfff91e9e "G" (G)
-  rebasing 14:2893b886bb10 "H" (H)
-  rebasing 3:08ebfeb61bac "I" (I)
-  rebasing 4:a0a5005cec67 "J" (J)
-  rebasing 5:83780307a7e8 "K" (K)
-  rebasing 6:e131637a1cb6 "L" (L)
-  rebasing 11:d1f6d0c3c7e4 "M" (M)
-  rebasing 12:7aaec6f81888 "N" (N)
-  rebasing 15:325bc8f1760d "P" (P tip)
+  rebasing 2:dc0947a82db8 C "C"
+  rebasing 8:4e4f9194f9f1 D "D"
+  rebasing 9:03ca77807e91 E "E"
+  rebasing 10:afc707c82df0 F "F"
+  rebasing 13:690dfff91e9e G "G"
+  rebasing 14:2893b886bb10 H "H"
+  rebasing 3:08ebfeb61bac I "I"
+  rebasing 4:a0a5005cec67 J "J"
+  rebasing 5:83780307a7e8 K "K"
+  rebasing 6:e131637a1cb6 L "L"
+  rebasing 11:d1f6d0c3c7e4 M "M"
+  rebasing 12:7aaec6f81888 N "N"
+  rebasing 15:325bc8f1760d P tip "P"
   o    15: 6ef6a0ea3b18 P
   |\
   | o    14: 20ba3610a7e5 N
@@ -268,13 +268,13 @@
   > |
   > M0
   > EOF
-  rebasing 4:8817fae53c94 "C0" (C0)
-  rebasing 6:06ca5dfe3b5b "B2" (B2)
-  rebasing 7:73508237b032 "C1" (C1)
-  rebasing 9:fdb955e2faed "A2" (A2)
-  rebasing 11:4e449bd1a643 "A3" (A3)
-  rebasing 10:0a33b0519128 "B1" (B1)
-  rebasing 12:209327807c3a "B3" (B3 tip)
+  rebasing 4:8817fae53c94 C0 "C0"
+  rebasing 6:06ca5dfe3b5b B2 "B2"
+  rebasing 7:73508237b032 C1 "C1"
+  rebasing 9:fdb955e2faed A2 "A2"
+  rebasing 11:4e449bd1a643 A3 "A3"
+  rebasing 10:0a33b0519128 B1 "B1"
+  rebasing 12:209327807c3a B3 tip "B3"
   o    12: ceb984566332 B3
   |\
   | o  11: 19d93caac497 B1
@@ -318,8 +318,8 @@
   >  \|\|
   >   C A
   > EOF
-  rebasing 2:112478962961 "B" (B)
-  rebasing 3:b70f76719894 "D" (D)
+  rebasing 2:112478962961 B "B"
+  rebasing 3:b70f76719894 D "D"
   o  4: 511efad7bf13 D
   |
   | o  3: 25c4e279af62 B
@@ -349,8 +349,8 @@
   >  \|\|
   >   A C
   > EOF
-  rebasing 2:f675d5a1c6a4 "B" (B)
-  rebasing 5:f68696fe6af8 "E" (E tip)
+  rebasing 2:f675d5a1c6a4 B "B"
+  rebasing 5:f68696fe6af8 E tip "E"
   o    5: f6e6f5081554 E
   |\
   | o    4: 30cabcba27be B
@@ -370,8 +370,8 @@
   >  \|\|\
   >   A C A
   > EOF
-  rebasing 2:f675d5a1c6a4 "B" (B)
-  rebasing 3:c2a779e13b56 "D" (D)
+  rebasing 2:f675d5a1c6a4 B "B"
+  rebasing 3:c2a779e13b56 D "D"
   o    4: 5eecd056b5f8 D
   |\
   +---o  3: 30cabcba27be B
--- a/tests/test-rebase-bookmarks.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-rebase-bookmarks.t	Mon Nov 02 14:39:43 2020 -0500
@@ -75,7 +75,7 @@
   o  0: 1994f17a630e 'A' bookmarks: Y@diverge
   
   $ hg rebase -s Y -d 3
-  rebasing 2:49cb3485fa0c "C" (Y Z)
+  rebasing 2:49cb3485fa0c Y Z "C"
   saved backup bundle to $TESTTMP/a1/.hg/strip-backup/49cb3485fa0c-126f3e97-rebase.hg
 
   $ hg tglog
@@ -97,7 +97,7 @@
   $ hg book W@diverge
 
   $ hg rebase -s W -d .
-  rebasing 3:41acb9dca9eb "D" (W tip)
+  rebasing 3:41acb9dca9eb W tip "D"
   saved backup bundle to $TESTTMP/a4/.hg/strip-backup/41acb9dca9eb-b35a6a63-rebase.hg
 
   $ hg bookmarks
@@ -115,8 +115,8 @@
   $ hg up -q Z
 
   $ hg rebase -s 1 -d 3
-  rebasing 1:6c81ed0049f8 "B" (X)
-  rebasing 2:49cb3485fa0c "C" (Y Z)
+  rebasing 1:6c81ed0049f8 X "B"
+  rebasing 2:49cb3485fa0c Y Z "C"
   saved backup bundle to $TESTTMP/a2/.hg/strip-backup/6c81ed0049f8-a687065f-rebase.hg
 
   $ hg tglog
@@ -138,8 +138,8 @@
   $ hg up -q X
 
   $ hg rebase -d W
-  rebasing 1:6c81ed0049f8 "B" (X)
-  rebasing 2:49cb3485fa0c "C" (Y Z)
+  rebasing 1:6c81ed0049f8 X "B"
+  rebasing 2:49cb3485fa0c Y Z "C"
   saved backup bundle to $TESTTMP/a3/.hg/strip-backup/6c81ed0049f8-a687065f-rebase.hg
 
   $ hg tglog
@@ -169,7 +169,7 @@
   $ hg up 3
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ hg rebase --dest 4
-  rebasing 3:3d5fa227f4b5 "C" (Y Z)
+  rebasing 3:3d5fa227f4b5 Y Z "C"
   merging c
   warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
   unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
@@ -179,7 +179,7 @@
   (no more unresolved files)
   continue: hg rebase --continue
   $ hg rebase --continue
-  rebasing 3:3d5fa227f4b5 "C" (Y Z)
+  rebasing 3:3d5fa227f4b5 Y Z "C"
   saved backup bundle to $TESTTMP/a3/.hg/strip-backup/3d5fa227f4b5-c6ea2371-rebase.hg
   $ hg tglog
   @  4: 45c0f0ec1203 'C' bookmarks: Y Z
@@ -209,7 +209,7 @@
   $ hg rebase -r '"bisect"^^::"bisect"^' -r bisect -d Z
   rebasing 5:345c90f326a4 "bisect"
   rebasing 6:f677a2907404 "bisect2"
-  rebasing 7:325c16001345 "bisect3" (bisect tip)
+  rebasing 7:325c16001345 bisect tip "bisect3"
   saved backup bundle to $TESTTMP/a3/.hg/strip-backup/345c90f326a4-b4840586-rebase.hg
 
 Bookmark and working parent get moved even if --keep is set (issue5682)
@@ -232,7 +232,7 @@
   o  0: 426bada5c675 'A' bookmarks: A
   
   $ hg rebase -r B -d C --keep
-  rebasing 1:112478962961 "B" (B)
+  rebasing 1:112478962961 B "B"
   $ hg tglog
   @  3: 9769fc65c4c5 'B' bookmarks: B
   |
--- a/tests/test-rebase-cache.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-rebase-cache.t	Mon Nov 02 14:39:43 2020 -0500
@@ -165,7 +165,7 @@
   o  0: 'A'
   
   $ hg rebase -s 8 -d 6
-  rebasing 8:4666b71e8e32 "F" (tip)
+  rebasing 8:4666b71e8e32 tip "F"
   saved backup bundle to $TESTTMP/a2/.hg/strip-backup/4666b71e8e32-fc1c4e96-rebase.hg
 
   $ hg branches
@@ -232,7 +232,7 @@
   $ hg rebase -s 7 -d 6
   rebasing 7:653b9feb4616 "branch3"
   note: not rebasing 7:653b9feb4616 "branch3", its destination already has all its changes
-  rebasing 8:4666b71e8e32 "F" (tip)
+  rebasing 8:4666b71e8e32 tip "F"
   saved backup bundle to $TESTTMP/a3/.hg/strip-backup/653b9feb4616-3c88de16-rebase.hg
 
   $ hg branches
@@ -478,6 +478,6 @@
   $ HGEDITOR="sh $TESTTMP/checkeditform.sh" hg rebase --dest 7 --source 5 -e
   rebasing 5:361a99976cc9 "F"
   HGEDITFORM=rebase.merge
-  rebasing 8:326cfedc031c "I" (tip)
+  rebasing 8:326cfedc031c tip "I"
   HGEDITFORM=rebase.normal
   saved backup bundle to $TESTTMP/a3/c4/.hg/strip-backup/361a99976cc9-35e980d0-rebase.hg
--- a/tests/test-rebase-check-restore.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-rebase-check-restore.t	Mon Nov 02 14:39:43 2020 -0500
@@ -123,7 +123,7 @@
   o  0:draft 'A'
   
   $ hg rebase -s 5 -d 4 --keepbranches
-  rebasing 5:01e6ebbd8272 "F" (tip)
+  rebasing 5:01e6ebbd8272 tip "F"
   merging A
   warning: conflicts while merging A! (edit, then use 'hg resolve --mark')
   unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
@@ -137,7 +137,7 @@
   (no more unresolved files)
   continue: hg rebase --continue
   $ hg rebase --continue
-  rebasing 5:01e6ebbd8272 "F" (tip)
+  rebasing 5:01e6ebbd8272 tip "F"
   saved backup bundle to $TESTTMP/a2/.hg/strip-backup/01e6ebbd8272-6fd3a015-rebase.hg
 
   $ hg tglog
--- a/tests/test-rebase-collapse.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-rebase-collapse.t	Mon Nov 02 14:39:43 2020 -0500
@@ -35,9 +35,9 @@
   > echo "edited manually" >> \$1
   > EOF
   $ HGEDITOR="sh $TESTTMP/editor.sh" hg rebase --collapse --keepbranches -e --source B --dest F
-  rebasing 1:112478962961 "B" (B)
-  rebasing 3:26805aba1e60 "C" (C)
-  rebasing 5:f585351a92f8 "D" (D tip)
+  rebasing 1:112478962961 B "B"
+  rebasing 3:26805aba1e60 C "C"
+  rebasing 5:f585351a92f8 D tip "D"
   ==== before editing
   Collapsed revision
   * B
@@ -96,8 +96,8 @@
 
   $ hg phase --force --secret D
   $ hg rebase --source B --collapse --dest F
-  rebasing 1:112478962961 "B" (B)
-  rebasing 3:4e4f9194f9f1 "D" (D)
+  rebasing 1:112478962961 B "B"
+  rebasing 3:4e4f9194f9f1 D "D"
   saved backup bundle to $TESTTMP/linearized-merge/.hg/strip-backup/112478962961-e389075b-rebase.hg
 
   $ hg tglog
@@ -141,8 +141,8 @@
   > true
   > EOF
   $ HGEDITOR="sh $TESTTMP/checkeditform.sh" hg rebase --source B --collapse -m 'custom message' -e --dest D
-  rebasing 1:112478962961 "B" (B)
-  rebasing 3:26805aba1e60 "C" (C tip)
+  rebasing 1:112478962961 B "B"
+  rebasing 3:26805aba1e60 C tip "C"
   HGEDITFORM=rebase.collapse
   saved backup bundle to $TESTTMP/message/.hg/strip-backup/112478962961-f4131707-rebase.hg
 
@@ -185,9 +185,9 @@
 Rebase and collapse - E onto H:
 
   $ hg rebase -s E --dest H --collapse # root (E) is not a merge
-  rebasing 5:49cb92066bfd "E" (E)
-  rebasing 6:11abe3fb10b8 "F" (F)
-  rebasing 7:64e264db77f0 "G" (G tip)
+  rebasing 5:49cb92066bfd E "E"
+  rebasing 6:11abe3fb10b8 F "F"
+  rebasing 7:64e264db77f0 G tip "G"
   saved backup bundle to $TESTTMP/multiple-external-parents/.hg/strip-backup/49cb92066bfd-ee8a8a79-rebase.hg
 
   $ hg tglog
@@ -287,7 +287,7 @@
   > EOF
 
   $ hg rebase -s F --dest I --collapse # root (F) is not a merge
-  rebasing 6:c82b08f646f1 "F" (F)
+  rebasing 6:c82b08f646f1 F "F"
   file 'E' was deleted in local [dest] but was modified in other [source].
   You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
   What do you want to do? u
@@ -299,9 +299,9 @@
   (no more unresolved files)
   continue: hg rebase --continue
   $ hg rebase -c
-  rebasing 6:c82b08f646f1 "F" (F)
-  rebasing 7:a6db7fa104e1 "G" (G)
-  rebasing 8:e1d201b72d91 "H" (H tip)
+  rebasing 6:c82b08f646f1 F "F"
+  rebasing 7:a6db7fa104e1 G "G"
+  rebasing 8:e1d201b72d91 H tip "H"
   saved backup bundle to $TESTTMP/external-parent/.hg/strip-backup/c82b08f646f1-f2721fbf-rebase.hg
 
   $ hg tglog
@@ -347,8 +347,8 @@
   > A
   > EOF
   $ hg rebase --collapse -r 'B+C' -d D
-  rebasing 1:fc2b737bb2e5 "B" (B)
-  rebasing 2:dc0947a82db8 "C" (C)
+  rebasing 1:fc2b737bb2e5 B "B"
+  rebasing 2:dc0947a82db8 C "C"
   saved backup bundle to $TESTTMP/multiple-bases/.hg/strip-backup/dc0947a82db8-b0c1a7ea-rebase.hg
   $ hg tglog
   o  2: 2127ae44d291 'Collapsed revision
@@ -424,10 +424,10 @@
 
 
   $ hg rebase -s B --collapse --dest F
-  rebasing 1:112478962961 "B" (B)
-  rebasing 3:26805aba1e60 "C" (C)
-  rebasing 4:be0ef73c17ad "D" (D)
-  rebasing 5:02c4367d6973 "E" (E tip)
+  rebasing 1:112478962961 B "B"
+  rebasing 3:26805aba1e60 C "C"
+  rebasing 4:be0ef73c17ad D "D"
+  rebasing 5:02c4367d6973 E tip "E"
   saved backup bundle to $TESTTMP/internal-merge/.hg/strip-backup/112478962961-1dfb057b-rebase.hg
 
   $ hg tglog
@@ -514,7 +514,7 @@
   merging a and d to d
   merging b and e to e
   merging c and f to f
-  rebasing 3:338e84e2e558 "move2" (tip)
+  rebasing 3:338e84e2e558 tip "move2"
   merging f and c to c
   merging e and g to g
   saved backup bundle to $TESTTMP/copies/.hg/strip-backup/6e7340ee38c0-ef8ef003-rebase.hg
@@ -557,7 +557,7 @@
 
   $ hg rebase --collapse -b . -d 0
   rebasing 1:1352765a01d4 "change"
-  rebasing 2:64b456429f67 "Collapsed revision" (tip)
+  rebasing 2:64b456429f67 tip "Collapsed revision"
   saved backup bundle to $TESTTMP/copies/.hg/strip-backup/1352765a01d4-45a352ea-rebase.hg
   $ hg st --change tip --copies
   M a
@@ -631,7 +631,7 @@
   $ hg book foo
   $ hg rebase -d 0 -r "1::2" --collapse -m collapsed
   rebasing 1:6d8d9f24eec3 "a"
-  rebasing 2:1cc73eca5ecc "b" (foo tip)
+  rebasing 2:1cc73eca5ecc foo tip "b"
   saved backup bundle to $TESTTMP/collapseaddremove/.hg/strip-backup/6d8d9f24eec3-77d3b6e2-rebase.hg
   $ hg log -G --template "{rev}: '{desc}' {bookmarks}"
   @  1: 'collapsed' foo
@@ -655,7 +655,7 @@
   > A
   > EOF
   $ hg rebase --collapse -m "new message" -b B -d C
-  rebasing 1:81e5401e4d37 "B" (B)
+  rebasing 1:81e5401e4d37 B "B"
   merging A
   warning: conflicts while merging A! (edit, then use 'hg resolve --mark')
   unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
@@ -665,7 +665,7 @@
   (no more unresolved files)
   continue: hg rebase --continue
   $ hg rebase --continue
-  rebasing 1:81e5401e4d37 "B" (B)
+  rebasing 1:81e5401e4d37 B "B"
   saved backup bundle to $TESTTMP/collapse_remember_message/.hg/strip-backup/81e5401e4d37-96c3dd30-rebase.hg
   $ hg log
   changeset:   2:17186933e123
@@ -702,7 +702,7 @@
   > A
   > EOF
   $ hg rebase --collapse -t internal:merge3 -s B -d D
-  rebasing 1:f899f3910ce7 "B" (B)
+  rebasing 1:f899f3910ce7 B "B"
   merging A
   warning: conflicts while merging A! (edit, then use 'hg resolve --mark')
   unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
@@ -729,8 +729,8 @@
   (no more unresolved files)
   continue: hg rebase --continue
   $ hg rebase --continue
-  rebasing 1:f899f3910ce7 "B" (B)
-  rebasing 3:63668d570d21 "C" (C tip)
+  rebasing 1:f899f3910ce7 B "B"
+  rebasing 3:63668d570d21 C tip "C"
   merging A
   warning: conflicts while merging A! (edit, then use 'hg resolve --mark')
   unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
@@ -757,8 +757,8 @@
   (no more unresolved files)
   continue: hg rebase --continue
   $ HGEDITOR=false hg rebase --continue --config ui.interactive=1
-  already rebased 1:f899f3910ce7 "B" (B) as 82b8abf9c185
-  rebasing 3:63668d570d21 "C" (C tip)
+  already rebased 1:f899f3910ce7 B "B" as 82b8abf9c185
+  rebasing 3:63668d570d21 C tip "C"
   abort: edit failed: false exited with status 1
   [255]
   $ hg tglog
@@ -771,6 +771,6 @@
   o  0: 4a2df7238c3b 'A'
   
   $ hg rebase --continue
-  already rebased 1:f899f3910ce7 "B" (B) as 82b8abf9c185
-  already rebased 3:63668d570d21 "C" (C tip) as 82b8abf9c185
+  already rebased 1:f899f3910ce7 B "B" as 82b8abf9c185
+  already rebased 3:63668d570d21 C tip "C" as 82b8abf9c185
   saved backup bundle to $TESTTMP/aborted-editor/.hg/strip-backup/f899f3910ce7-7cab5e15-rebase.hg
--- a/tests/test-rebase-conflicts.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-rebase-conflicts.t	Mon Nov 02 14:39:43 2020 -0500
@@ -100,7 +100,7 @@
   $ hg rebase --continue
   already rebased 3:3163e20567cc "L1" as 3e046f2ecedb
   rebasing 4:46f0b057b5c0 "L2"
-  rebasing 5:8029388f38dc "L3" (mybook)
+  rebasing 5:8029388f38dc mybook "L3"
   saved backup bundle to $TESTTMP/a/.hg/strip-backup/3163e20567cc-5ca4656e-rebase.hg
 
   $ hg tglog
@@ -261,7 +261,7 @@
   updating the branch cache
   rebased as 19c888675e13
   rebase status stored
-  rebasing 10:2f2496ddf49d "merge" (tip)
+  rebasing 10:2f2496ddf49d tip "merge"
    future parents are 11 and 7
    already in destination
    merge against 10:2f2496ddf49d
@@ -341,7 +341,7 @@
   $ echo c >> a
   $ hg commit -q -m 'abc'
   $ hg rebase -s 7bc217434fc1 -d ab --keep
-  rebasing 13:7bc217434fc1 "abc" (tip)
+  rebasing 13:7bc217434fc1 tip "abc"
   merging a
   warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
   unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
@@ -361,7 +361,7 @@
   rebase aborted
   $ hg up -q -C 7bc217434fc1
   $ hg rebase -s . -d ab --keep -t internal:merge3
-  rebasing 13:7bc217434fc1 "abc" (tip)
+  rebasing 13:7bc217434fc1 tip "abc"
   merging a
   warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
   unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
@@ -399,7 +399,7 @@
   $ echo 3 > B
   $ hg commit --amend -m E -A B -q
   $ hg rebase -r B+D -d . --config experimental.evolution=true
-  rebasing 1:112478962961 "B" (B)
+  rebasing 1:112478962961 B "B"
   merging B
   warning: conflicts while merging B! (edit, then use 'hg resolve --mark')
   unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
@@ -410,8 +410,8 @@
   (no more unresolved files)
   continue: hg rebase --continue
   $ hg rebase --continue --config experimental.evolution=none
-  rebasing 1:112478962961 "B" (B)
-  rebasing 3:f585351a92f8 "D" (D)
+  rebasing 1:112478962961 B "B"
+  rebasing 3:f585351a92f8 D "D"
   warning: orphaned descendants detected, not stripping 112478962961
   saved backup bundle to $TESTTMP/b/.hg/strip-backup/f585351a92f8-e536a9e4-rebase.hg
 
@@ -448,10 +448,10 @@
   $ hg co F
   5 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ hg rebase -d B
-  rebasing 2:dc0947a82db8 "C" (C)
-  rebasing 3:e7b3f00ed42e "D" (D)
-  rebasing 4:03ca77807e91 "E" (E)
-  rebasing 5:9a6b91dc2044 "F" (F tip)
+  rebasing 2:dc0947a82db8 C "C"
+  rebasing 3:e7b3f00ed42e D "D"
+  rebasing 4:03ca77807e91 E "E"
+  rebasing 5:9a6b91dc2044 F tip "F"
   merging conflict
   warning: conflicts while merging conflict! (edit, then use 'hg resolve --mark')
   unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
@@ -480,10 +480,10 @@
   (no more unresolved files)
   continue: hg rebase --continue
   $ hg rebase -c
-  already rebased 2:dc0947a82db8 "C" (C) as 0199610c343e
-  already rebased 3:e7b3f00ed42e "D" (D) as f0dd538aaa63
-  already rebased 4:03ca77807e91 "E" (E) as cbf25af8347d
-  rebasing 5:9a6b91dc2044 "F" (F)
+  already rebased 2:dc0947a82db8 C "C" as 0199610c343e
+  already rebased 3:e7b3f00ed42e D "D" as f0dd538aaa63
+  already rebased 4:03ca77807e91 E "E" as cbf25af8347d
+  rebasing 5:9a6b91dc2044 F "F"
   saved backup bundle to $TESTTMP/conflict-in-merge/.hg/strip-backup/dc0947a82db8-ca7e7d5b-rebase.hg
   $ hg tglog
   @    5:draft 'F'
--- a/tests/test-rebase-dest.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-rebase-dest.t	Mon Nov 02 14:39:43 2020 -0500
@@ -20,15 +20,15 @@
   (use: hg rebase -d REV)
   [255]
   $ hg rebase -d 1
-  rebasing 2:5db65b93a12b "cc" (tip)
+  rebasing 2:5db65b93a12b tip "cc"
   saved backup bundle to $TESTTMP/repo/.hg/strip-backup/5db65b93a12b-4fb789ec-rebase.hg
   $ hg rebase -d 0 -r . -q
   $ HGPLAIN=1 hg rebase
-  rebasing 2:889b0bc6a730 "cc" (tip)
+  rebasing 2:889b0bc6a730 tip "cc"
   saved backup bundle to $TESTTMP/repo/.hg/strip-backup/889b0bc6a730-41ec4f81-rebase.hg
   $ hg rebase -d 0 -r . -q
   $ hg --config commands.rebase.requiredest=False rebase
-  rebasing 2:279de9495438 "cc" (tip)
+  rebasing 2:279de9495438 tip "cc"
   saved backup bundle to $TESTTMP/repo/.hg/strip-backup/279de9495438-ab0a5128-rebase.hg
 
 Requiring dest should not break continue or other rebase options
@@ -45,7 +45,7 @@
   o  0 aa
   
   $ hg rebase -d 2
-  rebasing 3:0537f6b50def "dc" (tip)
+  rebasing 3:0537f6b50def tip "dc"
   merging c
   warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
   unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
@@ -55,7 +55,7 @@
   (no more unresolved files)
   continue: hg rebase --continue
   $ hg rebase --continue
-  rebasing 3:0537f6b50def "dc" (tip)
+  rebasing 3:0537f6b50def tip "dc"
   saved backup bundle to $TESTTMP/repo/.hg/strip-backup/0537f6b50def-be4c7386-rebase.hg
 
   $ cd ..
@@ -171,9 +171,9 @@
   > | |
   > A B
   > EOS
-  already rebased 0:426bada5c675 "A" (A)
-  already rebased 2:dc0947a82db8 "C" (C)
-  rebasing 3:004dc1679908 "D" (D tip)
+  already rebased 0:426bada5c675 A "A"
+  already rebased 2:dc0947a82db8 C "C"
+  rebasing 3:004dc1679908 D tip "D"
   o  4: d8d8601abd5e D
   
   o  2: dc0947a82db8 C
@@ -227,10 +227,10 @@
   > |  |
   > A  D
   > EOS
-  rebasing 2:112478962961 "B" (B)
-  rebasing 4:26805aba1e60 "C" (C)
-  rebasing 3:cd488e83d208 "E" (E)
-  rebasing 5:0069ba24938a "F" (F tip)
+  rebasing 2:112478962961 B "B"
+  rebasing 4:26805aba1e60 C "C"
+  rebasing 3:cd488e83d208 E "E"
+  rebasing 5:0069ba24938a F tip "F"
   o  9: d150ff263fc8 F
   |
   o  8: 66f30a1a2eab E
@@ -254,8 +254,8 @@
   > |\|
   > A D
   > EOS
-  rebasing 3:a4256619d830 "B" (B)
-  rebasing 6:8e139e245220 "C" (C tip)
+  rebasing 3:a4256619d830 B "B"
+  rebasing 6:8e139e245220 C tip "C"
   o    8: d7d1169e9b1c C
   |\
   | o    7: 2ed0c8546285 B
@@ -283,9 +283,9 @@
   >   |/
   >   A
   > EOS
-  rebasing 4:33441538d4aa "F" (F)
-  rebasing 6:cf43ad9da869 "G" (G)
-  rebasing 7:eef94f3b5f03 "H" (H tip)
+  rebasing 4:33441538d4aa F "F"
+  rebasing 6:cf43ad9da869 G "G"
+  rebasing 7:eef94f3b5f03 H tip "H"
   o  10: b3d84c6666cf H
   |
   | o  5: f585351a92f8 D
@@ -309,8 +309,8 @@
   >  \|/
   >   A
   > EOS
-  rebasing 2:dc0947a82db8 "C" (C)
-  rebasing 1:112478962961 "B" (B)
+  rebasing 2:dc0947a82db8 C "C"
+  rebasing 1:112478962961 B "B"
   o  5: 5fe9935d5222 B
   |
   o  4: 12d20731b9e0 C
@@ -352,11 +352,11 @@
   >  \|/
   >   A
   > EOS
-  already rebased 1:112478962961 "B" (B)
-  already rebased 2:dc0947a82db8 "C" (C)
-  already rebased 3:b18e25de2cf5 "D" (D)
-  already rebased 4:312782b8f06e "E" (E)
-  already rebased 5:ad6717a6a58e "F" (F tip)
+  already rebased 1:112478962961 B "B"
+  already rebased 2:dc0947a82db8 C "C"
+  already rebased 3:b18e25de2cf5 D "D"
+  already rebased 4:312782b8f06e E "E"
+  already rebased 5:ad6717a6a58e F tip "F"
   o  5: ad6717a6a58e F
   |
   o  3: b18e25de2cf5 D
@@ -380,17 +380,17 @@
   >  \| |
   >   A H
   > EOS
-  rebasing 4:701514e1408d "I" (I)
-  rebasing 0:426bada5c675 "A" (A)
-  rebasing 1:e7050b6e5048 "H" (H)
-  rebasing 5:26805aba1e60 "C" (C)
-  rebasing 7:cf89f86b485b "J" (J)
-  rebasing 2:112478962961 "B" (B)
-  rebasing 3:7fb047a69f22 "E" (E)
-  rebasing 8:f585351a92f8 "D" (D)
-  rebasing 10:ae41898d7875 "K" (K tip)
-  rebasing 9:711f53bbef0b "G" (G)
-  rebasing 6:64a8289d2492 "F" (F)
+  rebasing 4:701514e1408d I "I"
+  rebasing 0:426bada5c675 A "A"
+  rebasing 1:e7050b6e5048 H "H"
+  rebasing 5:26805aba1e60 C "C"
+  rebasing 7:cf89f86b485b J "J"
+  rebasing 2:112478962961 B "B"
+  rebasing 3:7fb047a69f22 E "E"
+  rebasing 8:f585351a92f8 D "D"
+  rebasing 10:ae41898d7875 K tip "K"
+  rebasing 9:711f53bbef0b G "G"
+  rebasing 6:64a8289d2492 F "F"
   o  21: 3735afb3713a F
   |
   o  20: 07698142d7a7 G
@@ -433,12 +433,12 @@
   >      A
   > EOF
   6 new orphan changesets
-  rebasing 16:5c432343bf59 "J" (J tip)
-  rebasing 3:26805aba1e60 "C" (C)
-  rebasing 6:f585351a92f8 "D" (D)
-  rebasing 10:ffebc37c5d0b "E3" (E3)
-  rebasing 13:fb184bcfeee8 "F2" (F2)
-  rebasing 11:dc838ab4c0da "G" (G)
+  rebasing 16:5c432343bf59 J tip "J"
+  rebasing 3:26805aba1e60 C "C"
+  rebasing 6:f585351a92f8 D "D"
+  rebasing 10:ffebc37c5d0b E3 "E3"
+  rebasing 13:fb184bcfeee8 F2 "F2"
+  rebasing 11:dc838ab4c0da G "G"
   o  22: 174f63d574a8 G
   |
   o  21: c9d9fbe76705 F2
--- a/tests/test-rebase-detach.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-rebase-detach.t	Mon Nov 02 14:39:43 2020 -0500
@@ -24,7 +24,7 @@
   $ hg phase --force --secret D
 
   $ hg rebase -s D -d B
-  rebasing 3:e7b3f00ed42e "D" (D tip)
+  rebasing 3:e7b3f00ed42e D tip "D"
   saved backup bundle to $TESTTMP/a1/.hg/strip-backup/e7b3f00ed42e-6f368371-rebase.hg
 
   $ hg log -G --template "{rev}:{phase} '{desc}' {branches}\n"
@@ -60,8 +60,8 @@
   > EOF
 
   $ hg rebase -s D -d B
-  rebasing 3:e7b3f00ed42e "D" (D)
-  rebasing 4:69a34c08022a "E" (E tip)
+  rebasing 3:e7b3f00ed42e D "D"
+  rebasing 4:69a34c08022a E tip "E"
   saved backup bundle to $TESTTMP/a2/.hg/strip-backup/e7b3f00ed42e-a2ec7cea-rebase.hg
 
   $ hg tglog
@@ -97,8 +97,8 @@
   > EOF
 
   $ hg rebase -s C -d B
-  rebasing 2:dc0947a82db8 "C" (C)
-  rebasing 3:e7b3f00ed42e "D" (D tip)
+  rebasing 2:dc0947a82db8 C "C"
+  rebasing 3:e7b3f00ed42e D tip "D"
   saved backup bundle to $TESTTMP/a3/.hg/strip-backup/dc0947a82db8-b8481714-rebase.hg
 
   $ hg tglog
@@ -136,8 +136,8 @@
   $ hg phase --force --secret E
 
   $ hg rebase --collapse -s D -d B
-  rebasing 3:e7b3f00ed42e "D" (D)
-  rebasing 4:69a34c08022a "E" (E tip)
+  rebasing 3:e7b3f00ed42e D "D"
+  rebasing 4:69a34c08022a E tip "E"
   saved backup bundle to $TESTTMP/a4/.hg/strip-backup/e7b3f00ed42e-a2ec7cea-rebase.hg
 
   $ hg  log -G --template "{rev}:{phase} '{desc}' {branches}\n"
@@ -173,9 +173,9 @@
   > EOF
 
   $ hg rebase -s C -d B
-  rebasing 2:dc0947a82db8 "C" (C)
-  rebasing 3:e7b3f00ed42e "D" (D)
-  rebasing 4:69a34c08022a "E" (E tip)
+  rebasing 2:dc0947a82db8 C "C"
+  rebasing 3:e7b3f00ed42e D "D"
+  rebasing 4:69a34c08022a E tip "E"
   saved backup bundle to $TESTTMP/a5/.hg/strip-backup/dc0947a82db8-3eefec98-rebase.hg
 
   $ hg tglog
@@ -191,7 +191,7 @@
   
   $ hg rebase -d 1 -s 3
   rebasing 3:e9153d36a1af "D"
-  rebasing 4:e3d0c70d606d "E" (tip)
+  rebasing 4:e3d0c70d606d tip "E"
   saved backup bundle to $TESTTMP/a5/.hg/strip-backup/e9153d36a1af-db7388ed-rebase.hg
   $ hg tglog
   o  4: 2c24e540eccd 'E'
@@ -248,9 +248,9 @@
   o  0: 426bada5c675 'A'
   
   $ hg rebase -s I -d H --collapse --config ui.merge=internal:other
-  rebasing 5:b92d164ad3cb "I" (I)
+  rebasing 5:b92d164ad3cb I "I"
   rebasing 6:0cfbc7e8faaf "Merge"
-  rebasing 7:c6aaf0d259c0 "J" (tip)
+  rebasing 7:c6aaf0d259c0 tip "J"
   saved backup bundle to $TESTTMP/a6/.hg/strip-backup/b92d164ad3cb-88fd7ab7-rebase.hg
 
   $ hg tglog
@@ -294,7 +294,7 @@
   adding B
   $ hg phase --force --secret .
   $ hg rebase -s . -d B --config ui.merge=internal:merge
-  rebasing 3:17b4880d2402 "B2" (tip)
+  rebasing 3:17b4880d2402 tip "B2"
   merging B
   warning: conflicts while merging B! (edit, then use 'hg resolve --mark')
   unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
@@ -303,8 +303,8 @@
   (no more unresolved files)
   continue: hg rebase --continue
   $ hg rebase -c
-  rebasing 3:17b4880d2402 "B2" (tip)
-  note: not rebasing 3:17b4880d2402 "B2" (tip), its destination already has all its changes
+  rebasing 3:17b4880d2402 tip "B2"
+  note: not rebasing 3:17b4880d2402 tip "B2", its destination already has all its changes
   saved backup bundle to $TESTTMP/a7/.hg/strip-backup/17b4880d2402-1ae1f6cc-rebase.hg
   $ hg  log -G --template "{rev}:{phase} '{desc}' {branches}\n"
   o  2:draft 'C'
--- a/tests/test-rebase-empty-successor.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-rebase-empty-successor.t	Mon Nov 02 14:39:43 2020 -0500
@@ -24,15 +24,15 @@
 
   $ hg rebase -s 2 -d 1 --config rewrite.empty-successor=skip --dry-run
   starting dry-run rebase; repository will not be changed
-  rebasing 2:6e2aad5e0f3c "b2" (tip)
-  note: not rebasing 2:6e2aad5e0f3c "b2" (tip), its destination already has all its changes
+  rebasing 2:6e2aad5e0f3c tip "b2"
+  note: not rebasing 2:6e2aad5e0f3c tip "b2", its destination already has all its changes
   dry-run rebase completed successfully; run without -n/--dry-run to perform this rebase
 
 With rewrite.empty-successor=keep, b2 will be recreated although it became empty.
 
   $ hg rebase -s 2 -d 1 --config rewrite.empty-successor=keep
-  rebasing 2:6e2aad5e0f3c "b2" (tip)
-  note: created empty successor for 2:6e2aad5e0f3c "b2" (tip), its destination already has all its changes
+  rebasing 2:6e2aad5e0f3c tip "b2"
+  note: created empty successor for 2:6e2aad5e0f3c tip "b2", its destination already has all its changes
   saved backup bundle to $TESTTMP/.hg/strip-backup/6e2aad5e0f3c-7d7c8801-rebase.hg
 
   $ hg tglog
--- a/tests/test-rebase-emptycommit.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-rebase-emptycommit.t	Mon Nov 02 14:39:43 2020 -0500
@@ -50,10 +50,10 @@
 With --keep, bookmark should move
 
   $ hg rebase -r 3+4 -d E --keep
-  rebasing 3:e7b3f00ed42e "D" (BOOK-D)
-  note: not rebasing 3:e7b3f00ed42e "D" (BOOK-D), its destination already has all its changes
-  rebasing 4:69a34c08022a "E" (BOOK-E)
-  note: not rebasing 4:69a34c08022a "E" (BOOK-E), its destination already has all its changes
+  rebasing 3:e7b3f00ed42e BOOK-D "D"
+  note: not rebasing 3:e7b3f00ed42e BOOK-D "D", its destination already has all its changes
+  rebasing 4:69a34c08022a BOOK-E "E"
+  note: not rebasing 4:69a34c08022a BOOK-E "E", its destination already has all its changes
   $ hg log -G -T '{rev} {desc} {bookmarks}'
   o  7 E BOOK-D BOOK-E
   |
@@ -82,12 +82,12 @@
 "BOOK-D", and "BOOK-E" include changes introduced by "C".
 
   $ hg rebase -s 2 -d E
-  rebasing 2:dc0947a82db8 "C" (BOOK-C C)
-  rebasing 3:e7b3f00ed42e "D" (BOOK-D)
-  note: not rebasing 3:e7b3f00ed42e "D" (BOOK-D), its destination already has all its changes
-  rebasing 4:69a34c08022a "E" (BOOK-E)
-  note: not rebasing 4:69a34c08022a "E" (BOOK-E), its destination already has all its changes
-  rebasing 5:6b2aeab91270 "F" (BOOK-F F)
+  rebasing 2:dc0947a82db8 BOOK-C C "C"
+  rebasing 3:e7b3f00ed42e BOOK-D "D"
+  note: not rebasing 3:e7b3f00ed42e BOOK-D "D", its destination already has all its changes
+  rebasing 4:69a34c08022a BOOK-E "E"
+  note: not rebasing 4:69a34c08022a BOOK-E "E", its destination already has all its changes
+  rebasing 5:6b2aeab91270 BOOK-F F "F"
   saved backup bundle to $TESTTMP/non-merge/.hg/strip-backup/dc0947a82db8-52bb4973-rebase.hg
   $ hg log -G -T '{rev} {desc} {bookmarks}'
   o  5 F BOOK-F
@@ -139,12 +139,12 @@
   $ hg branch foo -q
 
   $ hg rebase -r '(A::)-(B::)-A' -d H --keepbranches
-  rebasing 2:dc0947a82db8 "C" (BOOK-C)
-  note: not rebasing 2:dc0947a82db8 "C" (BOOK-C), its destination already has all its changes
-  rebasing 3:b18e25de2cf5 "D" (BOOK-D)
-  note: not rebasing 3:b18e25de2cf5 "D" (BOOK-D), its destination already has all its changes
-  rebasing 4:86a1f6686812 "E" (BOOK-E E)
-  note: not rebasing 4:86a1f6686812 "E" (BOOK-E E), its destination already has all its changes
+  rebasing 2:dc0947a82db8 BOOK-C "C"
+  note: not rebasing 2:dc0947a82db8 BOOK-C "C", its destination already has all its changes
+  rebasing 3:b18e25de2cf5 BOOK-D "D"
+  note: not rebasing 3:b18e25de2cf5 BOOK-D "D", its destination already has all its changes
+  rebasing 4:86a1f6686812 BOOK-E E "E"
+  note: not rebasing 4:86a1f6686812 BOOK-E E "E", its destination already has all its changes
   saved backup bundle to $TESTTMP/merge1/.hg/strip-backup/b18e25de2cf5-1fd0a4ba-rebase.hg
   $ hg update null -q
 
@@ -189,13 +189,13 @@
   > EOS
 
   $ hg rebase -r '(A::)-(B::)-A' -d H
-  rebasing 2:dc0947a82db8 "C" (BOOK-C)
-  note: not rebasing 2:dc0947a82db8 "C" (BOOK-C), its destination already has all its changes
-  rebasing 3:b18e25de2cf5 "D" (BOOK-D D)
-  rebasing 4:03ca77807e91 "E" (BOOK-E E)
-  rebasing 5:ad6717a6a58e "F" (BOOK-F)
-  note: not rebasing 5:ad6717a6a58e "F" (BOOK-F), its destination already has all its changes
-  rebasing 6:c58e8bdac1f4 "G" (BOOK-G G)
+  rebasing 2:dc0947a82db8 BOOK-C "C"
+  note: not rebasing 2:dc0947a82db8 BOOK-C "C", its destination already has all its changes
+  rebasing 3:b18e25de2cf5 BOOK-D D "D"
+  rebasing 4:03ca77807e91 BOOK-E E "E"
+  rebasing 5:ad6717a6a58e BOOK-F "F"
+  note: not rebasing 5:ad6717a6a58e BOOK-F "F", its destination already has all its changes
+  rebasing 6:c58e8bdac1f4 BOOK-G G "G"
   saved backup bundle to $TESTTMP/merge2/.hg/strip-backup/b18e25de2cf5-2d487005-rebase.hg
 
   $ hg log -G -T '{rev} {desc} {bookmarks}'
--- a/tests/test-rebase-inmemory.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-rebase-inmemory.t	Mon Nov 02 14:39:43 2020 -0500
@@ -42,7 +42,7 @@
   b (no-eol)
   $ hg rebase --debug -r b -d c | grep rebasing
   rebasing in memory
-  rebasing 2:db0e82a16a62 "b" (b)
+  rebasing 2:db0e82a16a62 b "b"
   $ hg tglog
   o  3: ca58782ad1e4 'b'
   |
@@ -102,7 +102,7 @@
   somefile (no-eol)
   $ hg rebase --debug -s b -d a | grep rebasing
   rebasing in memory
-  rebasing 2:db0e82a16a62 "b" (b)
+  rebasing 2:db0e82a16a62 b "b"
   $ hg tglog
   o  3: fc055c3b4d33 'b'
   |
@@ -118,7 +118,7 @@
   b (no-eol)
   $ hg rebase --debug -s 1 -d 3 | grep rebasing
   rebasing in memory
-  rebasing 1:02952614a83d "d" (d)
+  rebasing 1:02952614a83d d "d"
   rebasing 2:f56b71190a8f "c"
   $ hg tglog
   o  3: 753feb6fd12a 'c'
@@ -149,7 +149,7 @@
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ hg rebase -r 3 -d 0 --debug | grep rebasing
   rebasing in memory
-  rebasing 3:753feb6fd12a "c" (tip)
+  rebasing 3:753feb6fd12a tip "c"
   $ hg tglog
   @  3: 844a7de3e617 'c'
   |
@@ -179,7 +179,7 @@
   o  0: b173517d0057 'a'
   
   $ hg rebase -r . -d 2
-  rebasing 4:daf7dfc139cb "a/a" (tip)
+  rebasing 4:daf7dfc139cb tip "a/a"
   saved backup bundle to $TESTTMP/repo2/.hg/strip-backup/daf7dfc139cb-fdbfcf4f-rebase.hg
 
   $ hg tglog
@@ -220,7 +220,7 @@
   o  0: b173517d0057 'a'
   
   $ hg rebase -r . -d 5
-  rebasing 7:855e9797387e "added a back!" (tip)
+  rebasing 7:855e9797387e tip "added a back!"
   saved backup bundle to $TESTTMP/repo2/.hg/strip-backup/855e9797387e-81ee4c5d-rebase.hg
 
   $ hg tglog
@@ -246,7 +246,7 @@
   $ hg ci -m 'c/subdir/file.txt'
   $ hg rebase -r . -d 3 -n
   starting dry-run rebase; repository will not be changed
-  rebasing 8:e147e6e3c490 "c/subdir/file.txt" (tip)
+  rebasing 8:e147e6e3c490 tip "c/subdir/file.txt"
   abort: error: 'c/subdir/file.txt' conflicts with file 'c' in 3.
   [255]
 FIXME: shouldn't need this, but when we hit path conflicts in dryrun mode, we
@@ -709,7 +709,7 @@
   $ hg ci -qAm 'add +x to foo.txt'
 issue5960: this was raising an AttributeError exception
   $ hg rebase -r . -d 1
-  rebasing 2:539b93e77479 "add +x to foo.txt" (tip)
+  rebasing 2:539b93e77479 tip "add +x to foo.txt"
   saved backup bundle to $TESTTMP/no_exception/.hg/strip-backup/*.hg (glob)
   $ hg diff -c tip
   diff --git a/foo.txt b/foo.txt
@@ -772,7 +772,7 @@
   $ hg mv a b
   $ hg ci -qm 'rename a to b'
   $ hg rebase -d 1
-  rebasing 2:b977edf6f839 "rename a to b" (tip)
+  rebasing 2:b977edf6f839 tip "rename a to b"
   merging a and b to b
   saved backup bundle to $TESTTMP/rebase-rename/.hg/strip-backup/b977edf6f839-0864f570-rebase.hg
   $ hg st --copies --change .
@@ -793,7 +793,7 @@
   $ hg mv a b
   $ hg ci -qm 'rename a to b'
   $ hg rebase -d 1
-  rebasing 2:b977edf6f839 "rename a to b" (tip)
+  rebasing 2:b977edf6f839 tip "rename a to b"
   merging a and b to b
   saved backup bundle to $TESTTMP/rebase-rename-empty/.hg/strip-backup/b977edf6f839-0864f570-rebase.hg
   $ hg st --copies --change .
@@ -813,7 +813,7 @@
   $ echo a2 > a
   $ hg ci -qm 'modify a'
   $ hg rebase -r . -d 1 --collapse
-  rebasing 2:41c4ea50d4cf "modify a" (tip)
+  rebasing 2:41c4ea50d4cf tip "modify a"
   merging b and a to b
   saved backup bundle to $TESTTMP/rebase-rename-collapse/.hg/strip-backup/41c4ea50d4cf-b90b7994-rebase.hg
   $ cd ..
@@ -850,7 +850,7 @@
   created new head
 
   $ hg rebase -r . -d 1 --config ui.merge=internal:merge3
-  rebasing 2:fb62b706688e "add b to foo" (tip)
+  rebasing 2:fb62b706688e tip "add b to foo"
   merging foo
   hit merge conflicts; rebasing that commit again in the working copy
   merging foo
@@ -943,7 +943,7 @@
   $ hg rebase -s 2 -d 3
   rebasing 2:0194f1db184a "b"
   note: not rebasing 2:0194f1db184a "b", its destination already has all its changes
-  rebasing 4:59c8292117b1 "merge" (tip)
+  rebasing 4:59c8292117b1 tip "merge"
   saved backup bundle to $TESTTMP/keep_merge/.hg/strip-backup/0194f1db184a-aee31d03-rebase.hg
   $ hg tglog
   o    3: 506e2454484b 'merge'
@@ -969,6 +969,6 @@
   $ echo bar > test; hg add test; hg ci -m c
   created new head
   $ hg rebase -d 2 -d 1 --tool :local
-  rebasing 2:ca2749322ee5 "c" (tip)
-  note: not rebasing 2:ca2749322ee5 "c" (tip), its destination already has all its changes
+  rebasing 2:ca2749322ee5 tip "c"
+  note: not rebasing 2:ca2749322ee5 tip "c", its destination already has all its changes
   saved backup bundle to $TESTTMP/nofilechanges/.hg/strip-backup/ca2749322ee5-6dc7e94b-rebase.hg
--- a/tests/test-rebase-interruptions.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-rebase-interruptions.t	Mon Nov 02 14:39:43 2020 -0500
@@ -348,7 +348,7 @@
   $ hg rebase --source 2 --dest 5 --tool internal:other --config 'hooks.precommit=hg status | grep "M A"'
   rebasing 2:965c486023db "C"
   M A
-  rebasing 6:a0b2430ebfb8 "F" (tip)
+  rebasing 6:a0b2430ebfb8 tip "F"
   abort: precommit hook exited with status 1
   [255]
   $ hg tglogp
@@ -397,7 +397,7 @@
   >     --config 'hooks.tonative.pretxncommit=True' --config 'hooks.pretxncommit=hg log -r $HG_NODE | grep "summary:     C"'
   rebasing 2:965c486023db "C"
   summary:     C
-  rebasing 6:a0b2430ebfb8 "F" (tip)
+  rebasing 6:a0b2430ebfb8 tip "F"
   transaction abort!
   rollback completed
   abort: pretxncommit hook exited with status 1
@@ -447,7 +447,7 @@
   $ hg rebase --source 2 --dest 5 --tool internal:other --config 'hooks.pretxnclose=hg log -r tip | grep "summary:     C"'
   rebasing 2:965c486023db "C"
   summary:     C
-  rebasing 6:a0b2430ebfb8 "F" (tip)
+  rebasing 6:a0b2430ebfb8 tip "F"
   transaction abort!
   rollback completed
   abort: pretxnclose hook exited with status 1
@@ -522,7 +522,7 @@
 Now try again with --collapse
   $ hg unbundle -q .hg/strip-backup/fdaca8533b86-7fd70513-rebase.hg
   $ hg rebase -s 2 -d 1 --noninteractive --collapse
-  rebasing 2:fdaca8533b86 "b" (tip)
+  rebasing 2:fdaca8533b86 tip "b"
   merging a
   warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
   unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
@@ -533,7 +533,7 @@
   (no more unresolved files)
   continue: hg rebase --continue
   $ hg rebase --continue
-  rebasing 2:fdaca8533b86 "b" (tip)
+  rebasing 2:fdaca8533b86 tip "b"
   saved backup bundle to $TESTTMP/repo/.hg/strip-backup/fdaca8533b86-7fd70513-rebase.hg
   $ hg resolve --list
   $ test -d .hg/merge
--- a/tests/test-rebase-legacy.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-rebase-legacy.t	Mon Nov 02 14:39:43 2020 -0500
@@ -58,11 +58,11 @@
 #endif
 
   $ hg continue
-  rebasing 4:c1e6b162678d "B" (B)
-  rebasing 8:6f7a236de685 "D" (D)
-  rebasing 2:de008c61a447 "E" (E)
-  rebasing 7:d2fa1c02b240 "G" (G)
-  rebasing 9:6582e6951a9c "H" (H tip)
+  rebasing 4:c1e6b162678d B "B"
+  rebasing 8:6f7a236de685 D "D"
+  rebasing 2:de008c61a447 E "E"
+  rebasing 7:d2fa1c02b240 G "G"
+  rebasing 9:6582e6951a9c H tip "H"
   warning: orphaned descendants detected, not stripping c1e6b162678d, de008c61a447
   saved backup bundle to $TESTTMP/.hg/strip-backup/6f7a236de685-9880a3dc-rebase.hg
 
--- a/tests/test-rebase-mq-skip.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-rebase-mq-skip.t	Mon Nov 02 14:39:43 2020 -0500
@@ -57,7 +57,7 @@
   $ hg up -q -C qtip
 
   $ hg rebase -v
-  rebasing 2:13a46ce44f60 "P0" (p0.patch qbase)
+  rebasing 2:13a46ce44f60 p0.patch qbase "P0"
   resolving manifests
   removing p0
   getting r1
@@ -67,9 +67,9 @@
   p0
   committing manifest
   committing changelog
-  rebasing 3:148775c71080 "P1" (p1.patch qtip)
+  rebasing 3:148775c71080 p1.patch qtip "P1"
   resolving manifests
-  note: not rebasing 3:148775c71080 "P1" (p1.patch qtip), its destination already has all its changes
+  note: not rebasing 3:148775c71080 p1.patch qtip "P1", its destination already has all its changes
   rebase merging completed
   updating mq patch p0.patch to 5:9ecc820b1737
   $TESTTMP/a/.hg/patches/p0.patch
@@ -149,12 +149,12 @@
   $ hg up -q qtip
 
   $ HGMERGE=internal:fail hg rebase
-  rebasing 1:b4bffa6e4776 "r1" (qbase r1)
-  note: not rebasing 1:b4bffa6e4776 "r1" (qbase r1), its destination already has all its changes
-  rebasing 2:c0fd129beb01 "r2" (r2)
-  rebasing 3:6ff5b8feed8e "r3" (r3)
-  note: not rebasing 3:6ff5b8feed8e "r3" (r3), its destination already has all its changes
-  rebasing 4:094320fec554 "r4" (r4)
+  rebasing 1:b4bffa6e4776 qbase r1 "r1"
+  note: not rebasing 1:b4bffa6e4776 qbase r1 "r1", its destination already has all its changes
+  rebasing 2:c0fd129beb01 r2 "r2"
+  rebasing 3:6ff5b8feed8e r3 "r3"
+  note: not rebasing 3:6ff5b8feed8e r3 "r3", its destination already has all its changes
+  rebasing 4:094320fec554 r4 "r4"
   unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
   [1]
 
@@ -163,14 +163,14 @@
   continue: hg rebase --continue
 
   $ hg continue
-  already rebased 1:b4bffa6e4776 "r1" (qbase r1) as 057f55ff8f44
-  already rebased 2:c0fd129beb01 "r2" (r2) as 1660ab13ce9a
-  already rebased 3:6ff5b8feed8e "r3" (r3) as 1660ab13ce9a
-  rebasing 4:094320fec554 "r4" (r4)
-  note: not rebasing 4:094320fec554 "r4" (r4), its destination already has all its changes
-  rebasing 5:681a378595ba "r5" (r5)
-  rebasing 6:512a1f24768b "r6" (qtip r6)
-  note: not rebasing 6:512a1f24768b "r6" (qtip r6), its destination already has all its changes
+  already rebased 1:b4bffa6e4776 qbase r1 "r1" as 057f55ff8f44
+  already rebased 2:c0fd129beb01 r2 "r2" as 1660ab13ce9a
+  already rebased 3:6ff5b8feed8e r3 "r3" as 1660ab13ce9a
+  rebasing 4:094320fec554 r4 "r4"
+  note: not rebasing 4:094320fec554 r4 "r4", its destination already has all its changes
+  rebasing 5:681a378595ba r5 "r5"
+  rebasing 6:512a1f24768b qtip r6 "r6"
+  note: not rebasing 6:512a1f24768b qtip r6 "r6", its destination already has all its changes
   saved backup bundle to $TESTTMP/b/.hg/strip-backup/b4bffa6e4776-b9bfb84d-rebase.hg
 
   $ hg tglog
--- a/tests/test-rebase-mq.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-rebase-mq.t	Mon Nov 02 14:39:43 2020 -0500
@@ -59,7 +59,7 @@
 Rebase - generate a conflict:
 
   $ hg rebase -s 2 -d 1
-  rebasing 2:3504f44bffc0 "P0" (f.patch qbase)
+  rebasing 2:3504f44bffc0 f.patch qbase "P0"
   merging f
   warning: conflicts while merging f! (edit, then use 'hg resolve --mark')
   unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
@@ -72,8 +72,8 @@
   (no more unresolved files)
   continue: hg rebase --continue
   $ hg rebase -c
-  rebasing 2:3504f44bffc0 "P0" (f.patch qbase)
-  rebasing 3:929394423cd3 "P1" (f2.patch qtip tip)
+  rebasing 2:3504f44bffc0 f.patch qbase "P0"
+  rebasing 3:929394423cd3 f2.patch qtip tip "P1"
   merging f
   warning: conflicts while merging f! (edit, then use 'hg resolve --mark')
   unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
@@ -86,8 +86,8 @@
   (no more unresolved files)
   continue: hg rebase --continue
   $ hg rebase -c
-  already rebased 2:3504f44bffc0 "P0" (f.patch qbase) as ebe9914c0d1c
-  rebasing 3:929394423cd3 "P1" (f2.patch qtip)
+  already rebased 2:3504f44bffc0 f.patch qbase "P0" as ebe9914c0d1c
+  rebasing 3:929394423cd3 f2.patch qtip "P1"
   saved backup bundle to $TESTTMP/a/.hg/strip-backup/3504f44bffc0-30595b40-rebase.hg
 
   $ hg tglog
@@ -203,8 +203,8 @@
 Rebase the applied mq patches:
 
   $ hg rebase -s 2 -d 1
-  rebasing 2:0c587ffcb480 "P0 (git)" (f_git.patch qbase)
-  rebasing 3:c7f18665e4bc "P1" (f.patch qtip tip)
+  rebasing 2:0c587ffcb480 f_git.patch qbase "P0 (git)"
+  rebasing 3:c7f18665e4bc f.patch qtip tip "P1"
   saved backup bundle to $TESTTMP/a/.hg/strip-backup/0c587ffcb480-0ea5695f-rebase.hg
 
   $ hg qci -m 'save patch state'
@@ -337,7 +337,7 @@
   foo
   $ [ -f .hg/patches/empty-important ]
   $ hg -q rebase -d 2
-  note: not rebasing 1:0aaf4c3af7eb "important commit message" (empty-important qbase), its destination already has all its changes
+  note: not rebasing 1:0aaf4c3af7eb empty-important qbase "important commit message", its destination already has all its changes
   $ hg qseries
   guarded
   bar
--- a/tests/test-rebase-named-branches.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-rebase-named-branches.t	Mon Nov 02 14:39:43 2020 -0500
@@ -72,7 +72,7 @@
   rebasing 5:24b6387c8c8c "F"
   rebasing 6:eea13746799a "G"
   rebasing 7:02de42196ebe "H"
-  rebasing 9:cb039b7cae8e "dev-two named branch" (tip)
+  rebasing 9:cb039b7cae8e tip "dev-two named branch"
   saved backup bundle to $TESTTMP/a1/.hg/strip-backup/24b6387c8c8c-24cb8001-rebase.hg
 
   $ hg tglog
@@ -101,7 +101,7 @@
   rebasing 6:24de4aff8e28 "F"
   rebasing 7:4b988a958030 "G"
   rebasing 8:31d0e4ba75e6 "H"
-  rebasing 9:9e70cd31750f "dev-two named branch" (tip)
+  rebasing 9:9e70cd31750f tip "dev-two named branch"
   saved backup bundle to $TESTTMP/a1/.hg/strip-backup/643fc9128048-c4ee9ef5-rebase.hg
 
   $ hg tglog
@@ -190,7 +190,7 @@
   rebasing 6:679f28760620 "F"
   rebasing 7:549f007a9f5f "G"
   rebasing 8:12b2bc666e20 "H"
-  rebasing 9:71325f8bc082 "dev-two named branch" (tip)
+  rebasing 9:71325f8bc082 tip "dev-two named branch"
   saved backup bundle to $TESTTMP/a1/.hg/strip-backup/643fc9128048-6cdd1a52-rebase.hg
 
   $ hg tglog
@@ -253,7 +253,7 @@
   rebasing 6:3944801ae4ea "dev-two named branch"
   rebasing 7:3bdb949809d9 "B"
   rebasing 8:a0d543090fa4 "C"
-  rebasing 9:e9f862ce8bad "D" (tip)
+  rebasing 9:e9f862ce8bad tip "D"
   saved backup bundle to $TESTTMP/a1/.hg/strip-backup/3944801ae4ea-fb46ed74-rebase.hg
 
   $ hg tglog
@@ -344,7 +344,7 @@
 
   $ hg rebase -s tip -d 4 --dry-run
   starting dry-run rebase; repository will not be changed
-  rebasing 11:be1dea60f2a6 "D" (tip)
+  rebasing 11:be1dea60f2a6 tip "D"
   dry-run rebase completed successfully; run without -n/--dry-run to perform this rebase
   $ hg diff
   diff -r 2b586e70108d A
@@ -360,7 +360,7 @@
   $ echo A-mod > A
   $ echo n | hg rebase -s tip -d 4 --confirm --config ui.interactive=True
   starting in-memory rebase
-  rebasing 11:be1dea60f2a6 "D" (tip)
+  rebasing 11:be1dea60f2a6 tip "D"
   rebase completed successfully
   apply changes (yn)? n
   $ hg diff
@@ -374,7 +374,7 @@
   $ echo A-mod > A
   $ hg rebase -s tip -d 4 --confirm
   starting in-memory rebase
-  rebasing 11:be1dea60f2a6 "D" (tip)
+  rebasing 11:be1dea60f2a6 tip "D"
   rebase completed successfully
   apply changes (yn)? y
   saved backup bundle to $TESTTMP/a1/.hg/strip-backup/be1dea60f2a6-ca6d2dac-rebase.hg
@@ -527,8 +527,8 @@
   marked working directory as branch x
   $ hg rebase -r 3:: -d .
   rebasing 3:76abc1c6f8c7 "b1"
-  rebasing 4:8427af5d86f2 "c2 closed" (tip)
-  note: not rebasing 4:8427af5d86f2 "c2 closed" (tip), its destination already has all its changes
+  rebasing 4:8427af5d86f2 tip "c2 closed"
+  note: not rebasing 4:8427af5d86f2 tip "c2 closed", its destination already has all its changes
   saved backup bundle to $TESTTMP/case2/.hg/strip-backup/76abc1c6f8c7-cd698d13-rebase.hg
   $ hg tglog
   o  3: 117b0ed08075 'b1' x
--- a/tests/test-rebase-newancestor.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-rebase-newancestor.t	Mon Nov 02 14:39:43 2020 -0500
@@ -251,7 +251,7 @@
   $ echo 'other change while merging future "rebase ancestors"' > other
   $ hg ci -Aqm 'merge rebase ancestors'
   $ hg rebase -d 5 -v
-  rebasing 6:4c5f12f25ebe "merge rebase ancestors" (tip)
+  rebasing 6:4c5f12f25ebe tip "merge rebase ancestors"
   resolving manifests
   removing other
   resolving manifests
@@ -310,9 +310,9 @@
   > R
   > EOS
   $ hg rebase -r D+E+F -d Z
-  rebasing 5:5f2c926dfecf "D" (D)
-  rebasing 6:b296604d9846 "E" (E)
-  rebasing 7:caa9781e507d "F" (F tip)
+  rebasing 5:5f2c926dfecf D "D"
+  rebasing 6:b296604d9846 E "E"
+  rebasing 7:caa9781e507d F tip "F"
   abort: rebasing 7:caa9781e507d will include unwanted changes from 4:d6003a550c2c or 3:c1e6b162678d
   [255]
 
@@ -330,9 +330,9 @@
   > R
   > EOS
   $ hg rebase -r B+C+D -d Z
-  rebasing 3:c1e6b162678d "B" (B)
-  rebasing 4:d6003a550c2c "C" (C)
-  rebasing 5:c8f78076273e "D" (D tip)
+  rebasing 3:c1e6b162678d B "B"
+  rebasing 4:d6003a550c2c C "C"
+  rebasing 5:c8f78076273e D tip "D"
   saved backup bundle to $TESTTMP/dual-merge-base2/.hg/strip-backup/d6003a550c2c-6f1424b6-rebase.hg
   $ hg manifest -r 'desc(D)'
   B
@@ -352,8 +352,8 @@
   > B C Z
   > EOS
   $ hg rebase -r D+F -d Z
-  rebasing 3:004dc1679908 "D" (D)
-  rebasing 5:4be4cbf6f206 "F" (F tip)
+  rebasing 3:004dc1679908 D "D"
+  rebasing 5:4be4cbf6f206 F tip "F"
   saved backup bundle to $TESTTMP/chosen-merge-base1/.hg/strip-backup/004dc1679908-06a66a3c-rebase.hg
   $ hg manifest -r 'desc(F)'
   C
@@ -373,8 +373,8 @@
   > B C Z
   > EOS
   $ hg rebase -r E+F -d Z
-  rebasing 4:974e4943c210 "E" (E)
-  rebasing 5:4be4cbf6f206 "F" (F tip)
+  rebasing 4:974e4943c210 E "E"
+  rebasing 5:4be4cbf6f206 F tip "F"
   saved backup bundle to $TESTTMP/chosen-merge-base2/.hg/strip-backup/974e4943c210-b2874da5-rebase.hg
   $ hg manifest -r 'desc(F)'
   B
--- a/tests/test-rebase-obsolete.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-rebase-obsolete.t	Mon Nov 02 14:39:43 2020 -0500
@@ -5,8 +5,8 @@
 Enable obsolete
 
   $ cat >> $HGRCPATH << EOF
-  > [ui]
-  > logtemplate= {rev}:{node|short} {desc|firstline}{if(obsolete,' ({obsfate})')}
+  > [command-templates]
+  > log= {rev}:{node|short} {desc|firstline}{if(obsolete,' ({obsfate})')}
   > [experimental]
   > evolution.createmarkers=True
   > evolution.allowunstable=True
@@ -210,7 +210,7 @@
   
   $ hg rebase --source 'desc(B)' --dest 'tip' --config experimental.rebaseskipobsolete=True
   rebasing 8:8877864f1edb "B"
-  note: not rebasing 9:08483444fef9 "D", already in destination as 11:4596109a6a43 "D" (tip)
+  note: not rebasing 9:08483444fef9 "D", already in destination as 11:4596109a6a43 tip "D"
   rebasing 10:5ae4c968c6ac "C"
   $ hg debugobsolete
   42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 0 {cd010b8cd998f3981a5a8115f94f8da4ab506089} (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'rebase', 'user': 'test'}
@@ -258,7 +258,7 @@
   grafting 11:4596109a6a43 "D"
   $ hg up -qr 'desc(E)'
   $ hg rebase -s tip -d .
-  rebasing 14:9e36056a46e3 "D" (tip)
+  rebasing 14:9e36056a46e3 tip "D"
   $ hg log --style default --debug -r tip
   changeset:   15:627d4614809036ba22b9e7cb31638ddc06ab99ab
   tag:         tip
@@ -518,7 +518,7 @@
   $ hg rebase --dest 4 --rev '7+11+9'
   rebasing 9:cf44d2f5a9f4 "D"
   rebasing 7:02de42196ebe "H"
-  rebasing 11:0d8f238b634c "C" (tip)
+  rebasing 11:0d8f238b634c tip "C"
   $ hg log -G
   o  14:1e8370e38cca C
   |
@@ -556,9 +556,9 @@
   > EOF
 
   $ hg rebase -d G -r 'B + D + F'
-  rebasing 1:112478962961 "B" (B)
-  rebasing 2:b18e25de2cf5 "D" (D)
-  rebasing 6:f15c3adaf214 "F" (F tip)
+  rebasing 1:112478962961 B "B"
+  rebasing 2:b18e25de2cf5 D "D"
+  rebasing 6:f15c3adaf214 F tip "F"
   abort: cannot rebase 6:f15c3adaf214 without moving at least one of its parents
   [255]
 
@@ -612,7 +612,7 @@
   $ hg rebase --dest 6 --rev '((desc(H) + desc(D))::) - desc(M)'
   rebasing 3:32af7686d403 "D"
   rebasing 7:02de42196ebe "H"
-  rebasing 9:4bde274eefcf "I" (tip)
+  rebasing 9:4bde274eefcf tip "I"
   1 new orphan changesets
   $ hg log -G
   @  12:acd174b7ab39 I
@@ -656,7 +656,7 @@
 
   $ hg rebase --rev .~1::. --dest 'max(desc(D))' --traceback --config experimental.rebaseskipobsolete=off
   rebasing 9:4bde274eefcf "I"
-  rebasing 13:06edfc82198f "J" (tip)
+  rebasing 13:06edfc82198f tip "J"
   2 new content-divergent changesets
   $ hg log -G
   @  15:5ae8a643467b J
@@ -787,7 +787,7 @@
 
   $ hg rebase -d 'desc(B2)'
   note: not rebasing 1:a8b11f55fb19 "B0", already in destination as 3:261e70097290 "B2"
-  rebasing 4:212cb178bcbb "C" (tip)
+  rebasing 4:212cb178bcbb tip "C"
 
 Even when the chain include missing node
 
@@ -816,7 +816,7 @@
 
   $ hg rebase -d 'desc(B2)'
   note: not rebasing 1:a8b11f55fb19 "B0", already in destination as 2:261e70097290 "B2"
-  rebasing 5:1a79b7535141 "D" (tip)
+  rebasing 5:1a79b7535141 tip "D"
   $ hg up 4
   1 files updated, 0 files merged, 1 files removed, 0 files unresolved
   $ echo "O" > O
@@ -845,7 +845,7 @@
   $ hg rebase -d 6 -r "4::"
   rebasing 4:ff2c4d47b71d "C"
   note: not rebasing 7:360bbaa7d3ce "O", it has no successor
-  rebasing 8:8d47583e023f "P" (tip)
+  rebasing 8:8d47583e023f tip "P"
 
 If all the changeset to be rebased are obsolete and present in the destination, we
 should display a friendly error message
@@ -885,7 +885,7 @@
   o  0:4a2df7238c3b A
   
   $ hg rebase -r . -d 10
-  note: not rebasing 11:f44da1f4954c "nonrelevant" (tip), it has no successor
+  note: not rebasing 11:f44da1f4954c tip "nonrelevant", it has no successor
 
 If a rebase is going to create divergence, it should abort
 
@@ -970,7 +970,7 @@
 
   $ hg rebase -s 10 -d 12 --config experimental.evolution.allowdivergence=True
   rebasing 10:121d9e3bc4c6 "P"
-  rebasing 14:73568ab6879d "bar foo" (tip)
+  rebasing 14:73568ab6879d tip "bar foo"
   2 new content-divergent changesets
   $ hg summary
   parent: 16:61bd55f69bc4 tip
@@ -1041,7 +1041,7 @@
   $ hg rebase --continue
   rebasing 19:b82fb57ea638 "willconflict second version"
   note: not rebasing 20:8b31da3c4919 "dummy change", already in destination as 18:601db7a18f51 "dummy change successor"
-  rebasing 21:7bdc8a87673d "dummy change" (tip)
+  rebasing 21:7bdc8a87673d tip "dummy change"
   $ cd ..
 
 Divergence cases due to obsolete changesets
@@ -1096,11 +1096,11 @@
 consequence f (descendant of d) is left behind.
 
   $ hg rebase -b 'e' -d 'x'
-  rebasing 1:488e1b7e7341 "b" (b)
-  rebasing 3:a82ac2b38757 "c" (c)
-  rebasing 5:027ad6c5830d "d'" (d')
-  rebasing 6:d60ebfa0f1cb "e" (e)
-  note: not rebasing 4:76be324c128b "d" (d) and its descendants as this would cause divergence
+  rebasing 1:488e1b7e7341 b "b"
+  rebasing 3:a82ac2b38757 c "c"
+  rebasing 5:027ad6c5830d d' "d'"
+  rebasing 6:d60ebfa0f1cb e "e"
+  note: not rebasing 4:76be324c128b d "d" and its descendants as this would cause divergence
   $ hg log -G -r 'a'::
   o  11:eb6d63fc4ed5 e
   |
@@ -1154,9 +1154,9 @@
   (to force the rebase please set experimental.evolution.allowdivergence=True)
   [255]
   $ hg rebase --config experimental.evolution.allowdivergence=true -r 'c'::'f' -d 'x'
-  rebasing 3:a82ac2b38757 "c" (c)
-  rebasing 4:76be324c128b "d" (d)
-  rebasing 7:1143e9adc121 "f" (f tip)
+  rebasing 3:a82ac2b38757 c "c"
+  rebasing 4:76be324c128b d "d"
+  rebasing 7:1143e9adc121 f tip "f"
   1 new orphan changesets
   2 new content-divergent changesets
   $ hg log -G -r 'a':: -T instabilities
@@ -1187,9 +1187,9 @@
 (Not skipping obsoletes means that divergence is allowed.)
 
   $ hg rebase --config experimental.rebaseskipobsolete=false -r 'c'::'f' -d 'x'
-  rebasing 3:a82ac2b38757 "c" (c)
-  rebasing 4:76be324c128b "d" (d)
-  rebasing 7:1143e9adc121 "f" (f tip)
+  rebasing 3:a82ac2b38757 c "c"
+  rebasing 4:76be324c128b d "d"
+  rebasing 7:1143e9adc121 f tip "f"
   1 new orphan changesets
   2 new content-divergent changesets
 
@@ -1231,12 +1231,12 @@
   o  0:b173517d0057 a
   
   $ hg rebase -b 'f' -d 'x'
-  rebasing 1:488e1b7e7341 "b" (b)
-  rebasing 3:a82ac2b38757 "c" (c)
-  rebasing 5:63324dc512ea "e'" (e')
-  rebasing 7:3ffec603ab53 "f" (f)
-  rebasing 4:76be324c128b "d" (d)
-  note: not rebasing 6:e36fae928aec "e" (e) and its descendants as this would cause divergence
+  rebasing 1:488e1b7e7341 b "b"
+  rebasing 3:a82ac2b38757 c "c"
+  rebasing 5:63324dc512ea e' "e'"
+  rebasing 7:3ffec603ab53 f "f"
+  rebasing 4:76be324c128b d "d"
+  note: not rebasing 6:e36fae928aec e "e" and its descendants as this would cause divergence
   $ hg log -G -r 'a':
   o  13:a1707a5b7c2c d
   |
@@ -1294,7 +1294,7 @@
   o  0:b173517d0057 a
   
   $ hg rebase -d 0 -r 2
-  rebasing 2:a82ac2b38757 "c" (c)
+  rebasing 2:a82ac2b38757 c "c"
   $ hg log -G -r 'a': --hidden
   o  5:69ad416a4a26 c
   |
@@ -1325,8 +1325,8 @@
   1 new orphan changesets
 
   $ hg rebase -d B -s D
-  note: not rebasing 2:b18e25de2cf5 "D" (D), already in destination as 1:112478962961 "B" (B)
-  rebasing 4:66f1a38021c9 "F" (F tip)
+  note: not rebasing 2:b18e25de2cf5 D "D", already in destination as 1:112478962961 B "B"
+  rebasing 4:66f1a38021c9 F tip "F"
   $ hg log -G
   o    5:50e9d60b99c6 F
   |\
@@ -1357,8 +1357,8 @@
   1 new orphan changesets
 
   $ hg rebase -d B -s E
-  note: not rebasing 3:7fb047a69f22 "E" (E), already in destination as 1:112478962961 "B" (B)
-  rebasing 4:66f1a38021c9 "F" (F tip)
+  note: not rebasing 3:7fb047a69f22 E "E", already in destination as 1:112478962961 B "B"
+  rebasing 4:66f1a38021c9 F tip "F"
   $ hg log -G
   o    5:aae1787dacee F
   |\
@@ -1389,8 +1389,8 @@
   1 new orphan changesets
 
   $ hg rebase -d C -s D
-  note: not rebasing 2:b18e25de2cf5 "D" (D), already in destination as 1:112478962961 "B" (B)
-  rebasing 5:66f1a38021c9 "F" (F tip)
+  note: not rebasing 2:b18e25de2cf5 D "D", already in destination as 1:112478962961 B "B"
+  rebasing 5:66f1a38021c9 F tip "F"
 
   $ hg log -G
   o    6:0913febf6439 F
@@ -1424,8 +1424,8 @@
   1 new orphan changesets
 
   $ hg rebase -d C -s E
-  note: not rebasing 3:7fb047a69f22 "E" (E), already in destination as 1:112478962961 "B" (B)
-  rebasing 5:66f1a38021c9 "F" (F tip)
+  note: not rebasing 3:7fb047a69f22 E "E", already in destination as 1:112478962961 B "B"
+  rebasing 5:66f1a38021c9 F tip "F"
   $ hg log -G
   o    6:c6ab0cc6d220 F
   |\
@@ -1458,10 +1458,10 @@
   1 new orphan changesets
 
   $ hg rebase -d C -b F
-  rebasing 2:b18e25de2cf5 "D" (D)
-  note: not rebasing 3:7fb047a69f22 "E" (E), already in destination as 1:112478962961 "B" (B)
-  rebasing 5:66f1a38021c9 "F" (F tip)
-  note: not rebasing 5:66f1a38021c9 "F" (F tip), its destination already has all its changes
+  rebasing 2:b18e25de2cf5 D "D"
+  note: not rebasing 3:7fb047a69f22 E "E", already in destination as 1:112478962961 B "B"
+  rebasing 5:66f1a38021c9 F tip "F"
+  note: not rebasing 5:66f1a38021c9 F tip "F", its destination already has all its changes
   $ hg log -G
   o  6:8f47515dda15 D
   |
@@ -1494,10 +1494,10 @@
   1 new orphan changesets
 
   $ hg rebase -d C -b F
-  note: not rebasing 2:b18e25de2cf5 "D" (D), already in destination as 1:112478962961 "B" (B)
-  rebasing 3:7fb047a69f22 "E" (E)
-  rebasing 5:66f1a38021c9 "F" (F tip)
-  note: not rebasing 5:66f1a38021c9 "F" (F tip), its destination already has all its changes
+  note: not rebasing 2:b18e25de2cf5 D "D", already in destination as 1:112478962961 B "B"
+  rebasing 3:7fb047a69f22 E "E"
+  rebasing 5:66f1a38021c9 F tip "F"
+  note: not rebasing 5:66f1a38021c9 F tip "F", its destination already has all its changes
 
   $ hg log -G
   o  6:533690786a86 E
@@ -1531,8 +1531,8 @@
   > EOF
 
   $ hg rebase -d D -s B
-  rebasing 1:112478962961 "B" (B)
-  note: not rebasing 3:26805aba1e60 "C" (C) and its descendants as this would cause divergence
+  rebasing 1:112478962961 B "B"
+  note: not rebasing 3:26805aba1e60 C "C" and its descendants as this would cause divergence
 
   $ cd ..
 
@@ -1581,9 +1581,9 @@
   > EOS
   1 new orphan changesets
   $ hg rebase -r A+B+E -d F
-  note: not rebasing 4:a3d17304151f "A" (A), already in destination as 0:96cc3511f894 "C" (C)
-  note: not rebasing 5:b23a2cc00842 "B" (B), already in destination as 1:058c1e1fb10a "D" (D)
-  rebasing 7:dac5d11c5a7d "E" (E tip)
+  note: not rebasing 4:a3d17304151f A "A", already in destination as 0:96cc3511f894 C "C"
+  note: not rebasing 5:b23a2cc00842 B "B", already in destination as 1:058c1e1fb10a D "D"
+  rebasing 7:dac5d11c5a7d E tip "E"
   abort: rebasing 7:dac5d11c5a7d will include unwanted changes from 3:59c792af609c, 5:b23a2cc00842 or 2:ba2b7fa7166d, 4:a3d17304151f
   [255]
   $ cd ..
@@ -1600,9 +1600,9 @@
   > EOS
   1 new orphan changesets
   $ hg rebase -r A+B+D -d Z
-  note: not rebasing 0:426bada5c675 "A" (A), already in destination as 2:96cc3511f894 "C" (C)
-  rebasing 1:fc2b737bb2e5 "B" (B)
-  rebasing 3:b8ed089c80ad "D" (D)
+  note: not rebasing 0:426bada5c675 A "A", already in destination as 2:96cc3511f894 C "C"
+  rebasing 1:fc2b737bb2e5 B "B"
+  rebasing 3:b8ed089c80ad D "D"
 
   $ rm .hg/localtags
   $ hg log -G
@@ -1631,9 +1631,9 @@
   > EOS
   1 new orphan changesets
   $ hg rebase -r B+A+D -d Z
-  rebasing 0:426bada5c675 "A" (A)
-  note: not rebasing 1:fc2b737bb2e5 "B" (B), already in destination as 2:96cc3511f894 "C" (C)
-  rebasing 3:b8ed089c80ad "D" (D)
+  rebasing 0:426bada5c675 A "A"
+  note: not rebasing 1:fc2b737bb2e5 B "B", already in destination as 2:96cc3511f894 C "C"
+  rebasing 3:b8ed089c80ad D "D"
 
   $ rm .hg/localtags
   $ hg log -G
@@ -1669,7 +1669,7 @@
   adding b
   created new head
   $ hg rebase -r 2 -d 1
-  rebasing 2:1e9a3c00cbe9 "b" (tip)
+  rebasing 2:1e9a3c00cbe9 tip "b"
   $ hg log -r .  # working dir is at rev 3 (successor of 2)
   3:be1832deae9a b (no-eol)
   $ hg book -r 2 mybook --hidden  # rev 2 has a bookmark on it now
@@ -1679,7 +1679,7 @@
   0 files updated, 0 files merged, 1 files removed, 0 files unresolved
   2:1e9a3c00cbe9 b (rewritten using rebase as 3:be1832deae9a) (no-eol)
   $ hg rebase -r 2 -d 3 --config experimental.evolution.track-operation=1
-  note: not rebasing 2:1e9a3c00cbe9 "b" (mybook), already in destination as 3:be1832deae9a "b" (tip)
+  note: not rebasing 2:1e9a3c00cbe9 mybook "b", already in destination as 3:be1832deae9a tip "b"
 Check that working directory and bookmark was updated to rev 3 although rev 2
 was skipped
   $ hg log -r .
@@ -1706,8 +1706,8 @@
   $ hg update D1 -q
   $ hg bookmark book -i
   $ hg rebase -r B+D1 -d E
-  rebasing 1:112478962961 "B" (B)
-  note: not rebasing 5:15ecf15e0114 "D1" (book D1 tip), already in destination as 2:0807738e0be9 "D2" (D2)
+  rebasing 1:112478962961 B "B"
+  note: not rebasing 5:15ecf15e0114 book D1 tip "D1", already in destination as 2:0807738e0be9 D2 "D2"
   1 new orphan changesets
   $ hg log -G -T '{desc} {bookmarks}'
   @  B book
@@ -1819,7 +1819,7 @@
   continue: hg rebase --continue
   $ hg rebase --continue
   rebasing 1:2ec65233581b "B"
-  rebasing 3:7829726be4dc "C" (tip)
+  rebasing 3:7829726be4dc tip "C"
   $ hg log -G
   @  5:1964d5d5b547 C
   |
@@ -2112,9 +2112,9 @@
   o  0: 1994f17a630e 'A' bookmarks:
   
   $ hg rebase -s 1 -d 5
-  rebasing 1:6c81ed0049f8 "B" (X)
-  rebasing 2:49cb3485fa0c "C" (Y)
-  rebasing 3:67a385d4e6f2 "D" (Z)
+  rebasing 1:6c81ed0049f8 X "B"
+  rebasing 2:49cb3485fa0c Y "C"
+  rebasing 3:67a385d4e6f2 Z "D"
   merging d
   warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
   unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
--- a/tests/test-rebase-parameters.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-rebase-parameters.t	Mon Nov 02 14:39:43 2020 -0500
@@ -451,8 +451,8 @@
   $ cd b1
 
   $ hg rebase -s 2 -d 1 --tool internal:local
-  rebasing 2:e4e3f3546619 "c2b" (tip)
-  note: not rebasing 2:e4e3f3546619 "c2b" (tip), its destination already has all its changes
+  rebasing 2:e4e3f3546619 tip "c2b"
+  note: not rebasing 2:e4e3f3546619 tip "c2b", its destination already has all its changes
   saved backup bundle to $TESTTMP/b1/.hg/strip-backup/e4e3f3546619-b0841178-rebase.hg
 
   $ hg cat c2
@@ -465,7 +465,7 @@
   $ cd b2
 
   $ hg rebase -s 2 -d 1 --tool internal:other
-  rebasing 2:e4e3f3546619 "c2b" (tip)
+  rebasing 2:e4e3f3546619 tip "c2b"
   saved backup bundle to $TESTTMP/b2/.hg/strip-backup/e4e3f3546619-b0841178-rebase.hg
 
   $ hg cat c2
@@ -478,7 +478,7 @@
   $ cd b3
 
   $ hg rebase -s 2 -d 1 --tool internal:fail
-  rebasing 2:e4e3f3546619 "c2b" (tip)
+  rebasing 2:e4e3f3546619 tip "c2b"
   unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
   [1]
 
@@ -502,8 +502,8 @@
   (continue: hg rebase --continue)
   [255]
   $ hg rebase -c --tool internal:fail
-  rebasing 2:e4e3f3546619 "c2b" (tip)
-  note: not rebasing 2:e4e3f3546619 "c2b" (tip), its destination already has all its changes
+  rebasing 2:e4e3f3546619 tip "c2b"
+  note: not rebasing 2:e4e3f3546619 tip "c2b", its destination already has all its changes
   saved backup bundle to $TESTTMP/b3/.hg/strip-backup/e4e3f3546619-b0841178-rebase.hg
 
   $ hg rebase -i
--- a/tests/test-rebase-partial.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-rebase-partial.t	Mon Nov 02 14:39:43 2020 -0500
@@ -35,8 +35,8 @@
   > |/
   > A
   > EOF
-  rebasing 2:b18e25de2cf5 "D" (D)
-  already rebased 3:26805aba1e60 "C" (C tip)
+  rebasing 2:b18e25de2cf5 D "D"
+  already rebased 3:26805aba1e60 C tip "C"
   o  4: fe3b4c6498fa D
   |
   | o  3: 26805aba1e60 C
@@ -56,8 +56,8 @@
   > |/
   > A
   > EOF
-  rebasing 2:b18e25de2cf5 "D" (D)
-  rebasing 3:26805aba1e60 "C" (C tip)
+  rebasing 2:b18e25de2cf5 D "D"
+  rebasing 3:26805aba1e60 C tip "C"
   o  4: a2493f4ace65 Collapsed revision
   |  * D
   |  * C
@@ -81,7 +81,7 @@
   > A
   > EOF
   $ hg rebase -r C+D -d B
-  rebasing 2:ef8c0fe0897b "D" (D)
+  rebasing 2:ef8c0fe0897b D "D"
   merging file
   warning: conflicts while merging file! (edit, then use 'hg resolve --mark')
   unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
@@ -111,8 +111,8 @@
   > |
   > A
   > EOF
-  already rebased 1:112478962961 "B" (B)
-  rebasing 3:f585351a92f8 "D" (D tip)
+  already rebased 1:112478962961 B "B"
+  rebasing 3:f585351a92f8 D tip "D"
   o  4: 1e6da8103bc7 D
   |
   | x  3: f585351a92f8 D
--- a/tests/test-rebase-rename.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-rebase-rename.t	Mon Nov 02 14:39:43 2020 -0500
@@ -60,7 +60,7 @@
 Rebase the revision containing the rename:
 
   $ hg rebase -s 3 -d 2
-  rebasing 3:73a3ee40125d "rename A" (tip)
+  rebasing 3:73a3ee40125d tip "rename A"
   saved backup bundle to $TESTTMP/a/.hg/strip-backup/73a3ee40125d-1d78ebcf-rebase.hg
 
   $ hg tglog
@@ -134,8 +134,8 @@
   o  0: 1994f17a630e 'A'
   
   $ hg rebase -s 5 -d 4
-  rebasing 5:af8ad1f97097 "E" (tip)
-  note: not rebasing 5:af8ad1f97097 "E" (tip), its destination already has all its changes
+  rebasing 5:af8ad1f97097 tip "E"
+  note: not rebasing 5:af8ad1f97097 tip "E", its destination already has all its changes
   saved backup bundle to $TESTTMP/a/.hg/strip-backup/af8ad1f97097-c3e90708-rebase.hg
   $ hg tglog
   @  4: 60f545c27784 'E'
@@ -207,7 +207,7 @@
 Rebase the revision containing the copy:
 
   $ hg rebase -s 3 -d 2
-  rebasing 3:0a8162ff18a8 "copy A" (tip)
+  rebasing 3:0a8162ff18a8 tip "copy A"
   saved backup bundle to $TESTTMP/b/.hg/strip-backup/0a8162ff18a8-dd06302a-rebase.hg
 
   $ hg tglog
@@ -291,7 +291,7 @@
   
 
   $ hg rebase -s 4 -d 3
-  rebasing 4:b918d683b091 "Another unrelated change" (tip)
+  rebasing 4:b918d683b091 tip "Another unrelated change"
   saved backup bundle to $TESTTMP/repo/.hg/strip-backup/b918d683b091-3024bc57-rebase.hg
 
   $ hg diff --stat -c .
@@ -312,14 +312,14 @@
   $ hg commit --message "File b created as copy of a and modified"
   $ hg copy b c
   $ echo c > c
-  $ hg commit --message "File c created as copy of b and modified"
+  $ hg commit --message "File c created as copy of b and modified" ##
   $ hg copy c d
   $ echo d > d
-  $ hg commit --message "File d created as copy of c and modified"
+  $ hg commit --message "File d created as copy of c and modified (child of 327f772bc074)"
 
 Note that there are four entries in the log for d
   $ hg tglog --follow d
-  @  3: 421b7e82bb85 'File d created as copy of c and modified'
+  @  3: 6be224292cfa 'File d created as copy of c and modified (child of 327f772bc074)'
   |
   o  2: 327f772bc074 'File c created as copy of b and modified'
   |
@@ -342,14 +342,14 @@
   $ hg rebase --source 1 --dest 4
   rebasing 1:79d255d24ad2 "File b created as copy of a and modified"
   rebasing 2:327f772bc074 "File c created as copy of b and modified"
-  rebasing 3:421b7e82bb85 "File d created as copy of c and modified"
-  saved backup bundle to $TESTTMP/copy-gets-preserved/.hg/strip-backup/79d255d24ad2-a2265555-rebase.hg
+  rebasing 3:6be224292cfa "File d created as copy of c and modified (child of 327f772bc074)"
+  saved backup bundle to $TESTTMP/copy-gets-preserved/.hg/strip-backup/79d255d24ad2-a3e674e3-rebase.hg
   $ hg update 4
   3 files updated, 0 files merged, 0 files removed, 0 files unresolved
 
 There should still be four entries in the log for d
   $ hg tglog --follow d
-  @  4: dbb9ba033561 'File d created as copy of c and modified'
+  @  4: afbdde3a60d5 'File d created as copy of c and modified (child of af74b229bc02)'
   |
   o  3: af74b229bc02 'File c created as copy of b and modified'
   |
@@ -368,9 +368,9 @@
   rebasing 2:68bf06433839 "File b created as copy of a and modified"
   rebasing 3:af74b229bc02 "File c created as copy of b and modified"
   merging b and c to c
-  rebasing 4:dbb9ba033561 "File d created as copy of c and modified"
+  rebasing 4:afbdde3a60d5 "File d created as copy of c and modified (child of af74b229bc02)"
   merging c and d to d
-  saved backup bundle to $TESTTMP/copy-gets-preserved/.hg/strip-backup/68bf06433839-dde37595-rebase.hg
+  saved backup bundle to $TESTTMP/copy-gets-preserved/.hg/strip-backup/68bf06433839-29d5057f-rebase.hg
   $ hg co tip
   3 files updated, 0 files merged, 0 files removed, 0 files unresolved
 
@@ -378,11 +378,24 @@
 copy of 'a'.
 
   $ hg tglog --follow d
-  @  3: 5a46b94210e5 'Collapsed revision
+  @  3: 75708a266e56 'Collapsed revision
   :  * File b created as copy of a and modified
   :  * File c created as copy of b and modified
-  :  * File d created as copy of c and modified'
+  :  * File d created as copy of c and modified (child of af74b229bc02)'
   o  0: b220cd6d2326 'File a created'
   
+  $ hg log -G -Tcompact
+  @  3[tip]   75708a266e56   1970-01-01 00:00 +0000   test
+  |    Collapsed revision
+  |
+  o  2   15258cf0cf10   1970-01-01 00:00 +0000   test
+  |    unrelated commit is unrelated
+  |
+  o  1   1d689898494b   1970-01-01 00:00 +0000   test
+  |    Unrelated file created
+  |
+  o  0   b220cd6d2326   1970-01-01 00:00 +0000   test
+       File a created
+  
 
   $ cd ..
--- a/tests/test-rebase-scenario-global.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-rebase-scenario-global.t	Mon Nov 02 14:39:43 2020 -0500
@@ -170,7 +170,7 @@
   rebasing 5:24b6387c8c8c "F"
   rebasing 6:eea13746799a "G"
   note: not rebasing 6:eea13746799a "G", its destination already has all its changes
-  rebasing 7:02de42196ebe "H" (tip)
+  rebasing 7:02de42196ebe tip "H"
   saved backup bundle to $TESTTMP/a4/.hg/strip-backup/24b6387c8c8c-c3fe765d-rebase.hg
 
   $ hg tglog
@@ -228,7 +228,7 @@
   $ hg rebase -s 5 -d 1
   rebasing 5:24b6387c8c8c "F"
   rebasing 6:eea13746799a "G"
-  rebasing 7:02de42196ebe "H" (tip)
+  rebasing 7:02de42196ebe tip "H"
   saved backup bundle to $TESTTMP/a6/.hg/strip-backup/24b6387c8c8c-c3fe765d-rebase.hg
 
   $ hg tglog
@@ -339,32 +339,32 @@
 
   $ hg rebase -d 5 -b 6 --keep
   rebasing 6:e1c4361dd923 "C"
-  rebasing 7:c9659aac0000 "D" (tip)
+  rebasing 7:c9659aac0000 tip "D"
 
 Check rebasing mutable changeset
 Source phase greater or equal to destination phase: new changeset get the phase of source:
   $ hg id -n
   5
   $ hg rebase -s9 -d0
-  rebasing 9:2b23e52411f4 "D" (tip)
+  rebasing 9:2b23e52411f4 tip "D"
   saved backup bundle to $TESTTMP/a7/.hg/strip-backup/2b23e52411f4-f942decf-rebase.hg
   $ hg id -n # check we updated back to parent
   5
   $ hg log --template "{phase}\n" -r 9
   draft
   $ hg rebase -s9 -d1
-  rebasing 9:2cb10d0cfc6c "D" (tip)
+  rebasing 9:2cb10d0cfc6c tip "D"
   saved backup bundle to $TESTTMP/a7/.hg/strip-backup/2cb10d0cfc6c-ddb0f256-rebase.hg
   $ hg log --template "{phase}\n" -r 9
   draft
   $ hg phase --force --secret 9
   $ hg rebase -s9 -d0
-  rebasing 9:c5b12b67163a "D" (tip)
+  rebasing 9:c5b12b67163a tip "D"
   saved backup bundle to $TESTTMP/a7/.hg/strip-backup/c5b12b67163a-4e372053-rebase.hg
   $ hg log --template "{phase}\n" -r 9
   secret
   $ hg rebase -s9 -d1
-  rebasing 9:2a0524f868ac "D" (tip)
+  rebasing 9:2a0524f868ac tip "D"
   saved backup bundle to $TESTTMP/a7/.hg/strip-backup/2a0524f868ac-cefd8574-rebase.hg
   $ hg log --template "{phase}\n" -r 9
   secret
@@ -461,7 +461,7 @@
   rebasing 3:ffd453c31098 "D"
   rebasing 6:3d8a618087a7 "G"
   rebasing 7:72434a4e60b0 "H"
-  rebasing 8:479ddb54a924 "I" (tip)
+  rebasing 8:479ddb54a924 tip "I"
   $ hg tglog
   o  13: 9bf1d9358a90 'I'
   |
@@ -506,7 +506,7 @@
   rebasing 3:ffd453c31098 "D"
   rebasing 6:3d8a618087a7 "G"
   rebasing 7:72434a4e60b0 "H"
-  rebasing 8:479ddb54a924 "I" (tip)
+  rebasing 8:479ddb54a924 tip "I"
   $ hg tglog
   o  12: 9d7da0053b1c 'I'
   |
@@ -632,7 +632,7 @@
   $ hg rebase -r '6::' -d 2
   rebasing 6:3d8a618087a7 "G"
   rebasing 7:72434a4e60b0 "H"
-  rebasing 8:479ddb54a924 "I" (tip)
+  rebasing 8:479ddb54a924 tip "I"
   saved backup bundle to $TESTTMP/ah5/.hg/strip-backup/3d8a618087a7-b4f73f31-rebase.hg
   $ hg tglog
   o  8: fcb52e68a694 'I'
@@ -667,7 +667,7 @@
   rebasing 5:41bfcc75ed73 "F"
   rebasing 6:3d8a618087a7 "G"
   rebasing 7:72434a4e60b0 "H"
-  rebasing 8:479ddb54a924 "I" (tip)
+  rebasing 8:479ddb54a924 tip "I"
   saved backup bundle to $TESTTMP/ah6/.hg/strip-backup/3d8a618087a7-aae93a24-rebase.hg
   $ hg tglog
   o  8: 9136df9a87cf 'I'
@@ -736,7 +736,7 @@
 
   $ hg rebase --dest 'desc(G)' --rev 'desc(K) + desc(I)'
   rebasing 8:e7ec4e813ba6 "I"
-  rebasing 10:23a4ace37988 "K" (tip)
+  rebasing 10:23a4ace37988 tip "K"
   saved backup bundle to $TESTTMP/a8/.hg/strip-backup/23a4ace37988-b06984b3-rebase.hg
   $ hg log --rev 'children(desc(G))'
   changeset:   9:adb617877056
@@ -803,7 +803,7 @@
   rebasing 2:779a07b1b7a0 "first source commit"
   current directory was removed (rmcwd !)
   (consider changing to repo root: $TESTTMP/cwd-vanish) (rmcwd !)
-  rebasing 3:a7d6f3a00bf3 "second source with subdir" (tip)
+  rebasing 3:a7d6f3a00bf3 tip "second source with subdir"
   saved backup bundle to $TESTTMP/cwd-vanish/.hg/strip-backup/779a07b1b7a0-853e0073-rebase.hg
 
 Get back to the root of cwd-vanish. Note that even though `cd ..`
@@ -979,7 +979,7 @@
   > EOS
 
   $ hg rebase -s C -d B
-  rebasing 2:dc0947a82db8 "C" (C tip)
+  rebasing 2:dc0947a82db8 C tip "C"
 
   $ [ -f .hg/rebasestate ] && echo 'WRONG: rebasestate should not exist'
   [1]
--- a/tests/test-rebase-templates.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-rebase-templates.t	Mon Nov 02 14:39:43 2020 -0500
@@ -82,3 +82,42 @@
   o  0:18d04c59bb5d Added a
   
 
+Respects command-templates.oneline-summary
+
+  $ hg rebase -r 7 -d 8 -n --config command-templates.oneline-summary='rev: {rev}'
+  starting dry-run rebase; repository will not be changed
+  rebasing rev: 7
+  note: not rebasing rev: 7, its destination already has all its changes
+  dry-run rebase completed successfully; run without -n/--dry-run to perform this rebase
+
+
+command-templates.oneline-summary.rebase overrides
+
+  $ hg rebase -r 7 -d 8 -n \
+  > --config command-templates.oneline-summary='global: {rev}' \
+  > --config command-templates.oneline-summary.rebase='override: {rev}'
+  starting dry-run rebase; repository will not be changed
+  rebasing override: 7
+  note: not rebasing override: 7, its destination already has all its changes
+  dry-run rebase completed successfully; run without -n/--dry-run to perform this rebase
+
+
+check namespaces and coloring (labels)
+
+  $ hg tag -l -r 7 my-tag
+  $ hg rebase -r 7 -d 8 -n
+  starting dry-run rebase; repository will not be changed
+  rebasing 7:f48cd65c6dc3 my-tag "Added b"
+  note: not rebasing 7:f48cd65c6dc3 my-tag "Added b", its destination already has all its changes
+  dry-run rebase completed successfully; run without -n/--dry-run to perform this rebase
+  $ hg bookmark -r 7 my-bookmark
+  $ hg rebase -r 7 -d 8 -n
+  starting dry-run rebase; repository will not be changed
+  rebasing 7:f48cd65c6dc3 my-bookmark my-tag "Added b"
+  note: not rebasing 7:f48cd65c6dc3 my-bookmark my-tag "Added b", its destination already has all its changes
+  dry-run rebase completed successfully; run without -n/--dry-run to perform this rebase
+  $ hg rebase -r 7 -d 8 -n --color=debug
+  [ ui.status|starting dry-run rebase; repository will not be changed]
+  [ ui.status|rebasing [oneline-summary.changeset|7:f48cd65c6dc3] [oneline-summary.bookmarks|my-bookmark] [oneline-summary.tags|my-tag] "[oneline-summary.desc|Added b]"]
+  [ ui.warning|note: not rebasing [oneline-summary.changeset|7:f48cd65c6dc3] [oneline-summary.bookmarks|my-bookmark] [oneline-summary.tags|my-tag] "[oneline-summary.desc|Added b]", its destination already has all its changes]
+  [ ui.status|dry-run rebase completed successfully; run without -n/--dry-run to perform this rebase]
--- a/tests/test-rebase-transaction.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-rebase-transaction.t	Mon Nov 02 14:39:43 2020 -0500
@@ -103,8 +103,8 @@
   >   A
   > EOF
   $ hg rebase --collapse -b D -d Z
-  rebasing 1:112478962961 "B" (B)
-  rebasing 3:c26739dbe603 "C" (C)
+  rebasing 1:112478962961 B "B"
+  rebasing 3:c26739dbe603 C "C"
   merging conflict
   warning: conflicts while merging conflict! (edit, then use 'hg resolve --mark')
   unresolved conflicts (see 'hg resolve', then 'hg rebase --continue')
@@ -132,9 +132,9 @@
   (no more unresolved files)
   continue: hg rebase --continue
   $ hg continue
-  already rebased 1:112478962961 "B" (B) as 79bc8f4973ce
-  rebasing 3:c26739dbe603 "C" (C)
-  rebasing 5:d24bb333861c "D" (D tip)
+  already rebased 1:112478962961 B "B" as 79bc8f4973ce
+  rebasing 3:c26739dbe603 C "C"
+  rebasing 5:d24bb333861c D tip "D"
   saved backup bundle to $TESTTMP/collapse-conflict/.hg/strip-backup/112478962961-b5b34645-rebase.hg
   $ hg tglog
   o  3: Collapsed revision
@@ -165,9 +165,9 @@
   >   A
   > EOF
   $ HGEDITOR=false hg --config ui.interactive=1 rebase --collapse -b D -d Z
-  rebasing 1:112478962961 "B" (B)
-  rebasing 3:26805aba1e60 "C" (C)
-  rebasing 5:f585351a92f8 "D" (D tip)
+  rebasing 1:112478962961 B "B"
+  rebasing 3:26805aba1e60 C "C"
+  rebasing 5:f585351a92f8 D tip "D"
   transaction abort!
   rollback completed
   abort: edit failed: false exited with status 1
@@ -186,9 +186,9 @@
   o  0: A
   
   $ hg continue
-  rebasing 1:112478962961 "B" (B)
-  rebasing 3:26805aba1e60 "C" (C)
-  rebasing 5:f585351a92f8 "D" (D tip)
+  rebasing 1:112478962961 B "B"
+  rebasing 3:26805aba1e60 C "C"
+  rebasing 5:f585351a92f8 D tip "D"
   saved backup bundle to $TESTTMP/collapse-cancel-editor/.hg/strip-backup/112478962961-cb2a9b47-rebase.hg
   $ hg tglog
   o  3: Collapsed revision
--- a/tests/test-remotefilelog-bgprefetch.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-remotefilelog-bgprefetch.t	Mon Nov 02 14:39:43 2020 -0500
@@ -229,7 +229,7 @@
 .. flaky, the core the test is checked when checking the cache dir, so
 .. hopefully this flakyness is not hiding any actual bug.
   $ hg rebase -s temporary -d foo
-  rebasing 3:d9cf06e3b5b6 "b" (temporary tip)
+  rebasing 3:d9cf06e3b5b6 temporary tip "b"
   saved backup bundle to $TESTTMP/shallow/.hg/strip-backup/d9cf06e3b5b6-e5c3dc63-rebase.hg
   ? files fetched over ? fetches - (? misses, 0.00% hit ratio) over *s (glob)
   $ find $CACHEDIR -type f | sort
--- a/tests/test-remotefilelog-linknodes.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-remotefilelog-linknodes.t	Mon Nov 02 14:39:43 2020 -0500
@@ -32,7 +32,7 @@
   b292c1e3311f
 
   $ hg rebase -d 1
-  rebasing 2:0632994590a8 "xx" (tip)
+  rebasing 2:0632994590a8 tip "xx"
   saved backup bundle to $TESTTMP/shallow/.hg/strip-backup/0632994590a8-0bc786d8-rebase.hg (glob)
   $ hg log -f x --template "{node|short}\n"
   81deab2073bc
@@ -41,14 +41,14 @@
 # Rebase back, log -f still works
 
   $ hg rebase -d 0 -r 2
-  rebasing 2:81deab2073bc "xx" (tip)
+  rebasing 2:81deab2073bc tip "xx"
   saved backup bundle to $TESTTMP/shallow/.hg/strip-backup/81deab2073bc-80cb4fda-rebase.hg (glob)
   $ hg log -f x --template "{node|short}\n"
   b3fca10fb42d
   b292c1e3311f
 
   $ hg rebase -d 1 -r 2
-  rebasing 2:b3fca10fb42d "xx" (tip)
+  rebasing 2:b3fca10fb42d tip "xx"
   saved backup bundle to $TESTTMP/shallow/.hg/strip-backup/b3fca10fb42d-da73a0c7-rebase.hg (glob)
 
   $ cd ..
--- a/tests/test-remotefilelog-sparse.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-remotefilelog-sparse.t	Mon Nov 02 14:39:43 2020 -0500
@@ -99,4 +99,4 @@
   $ hg prefetch -r '. + .^' -I x -I z
   4 files fetched over 1 fetches - (4 misses, 0.00% hit ratio) over * (glob)
   $ hg rebase -d 2 --keep
-  rebasing 1:876b1317060d "x2" (foo)
+  rebasing 1:876b1317060d foo "x2"
--- a/tests/test-revset-legacy-lookup.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-revset-legacy-lookup.t	Mon Nov 02 14:39:43 2020 -0500
@@ -1,7 +1,7 @@
 
   $ cat >> $HGRCPATH << EOF
-  > [ui]
-  > logtemplate="{rev}:{node|short} {desc} [{tags}]\n"
+  > [command-templates]
+  > log="{rev}:{node|short} {desc} [{tags}]\n"
   > EOF
 
   $ hg init legacy-lookup
--- a/tests/test-share-safe.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-share-safe.t	Mon Nov 02 14:39:43 2020 -0500
@@ -81,6 +81,36 @@
   $ hg showconfig ui.curses
   true
 
+Test that extensions of source repository are also loaded
+
+  $ hg debugextensions
+  share
+  $ hg extdiff -p echo
+  hg: unknown command 'extdiff'
+  'extdiff' is provided by the following extension:
+  
+      extdiff       command to allow external programs to compare revisions
+  
+  (use 'hg help extensions' for information on enabling extensions)
+  [255]
+
+  $ echo "[extensions]" >> ../source/.hg/hgrc
+  $ echo "extdiff=" >> ../source/.hg/hgrc
+
+  $ hg debugextensions -R ../source
+  extdiff
+  share
+  $ hg extdiff -R ../source -p echo
+
+BROKEN: the command below will not work if config of shared source is not loaded
+on dispatch but debugextensions says that extension
+is loaded
+  $ hg debugextensions
+  extdiff
+  share
+
+  $ hg extdiff -p echo
+
 However, local .hg/hgrc should override the config set by share source
 
   $ echo "[ui]" >> .hg/hgrc
@@ -92,6 +122,8 @@
   $ HGEDITOR=cat hg config --shared
   [ui]
   curses=true
+  [extensions]
+  extdiff=
 
   $ HGEDITOR=cat hg config --local
   [ui]
@@ -221,6 +253,25 @@
   date:        Thu Jan 01 00:00:00 1970 +0000
   summary:     added c
   
+
+Testing that nonsharedrc is loaded for source and not shared
+
+  $ cd ../source
+  $ touch .hg/hgrc-not-shared
+  $ echo "[ui]" >> .hg/hgrc-not-shared
+  $ echo "traceback=true" >> .hg/hgrc-not-shared
+
+  $ hg showconfig ui.traceback
+  true
+
+  $ HGEDITOR=cat hg config --non-shared
+  [ui]
+  traceback=true
+
+  $ cd ../shared1
+  $ hg showconfig ui.traceback
+  [1]
+
 Unsharing works
 
   $ hg unshare
--- a/tests/test-shelve2.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-shelve2.t	Mon Nov 02 14:39:43 2020 -0500
@@ -54,7 +54,7 @@
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
 
   $ hg rebase -d 6c103be8f4e4 --config extensions.rebase=
-  rebasing 2:323bfa07f744 "xyz"( \(tip\))? (re)
+  rebasing 2:323bfa07f744( tip)? "xyz" (re)
   merging x
   saved backup bundle to \$TESTTMP/shelverebase/.hg/strip-backup/323bfa07f744-(78114325|7ae538ef)-rebase.hg (re)
   $ hg unshelve
--- a/tests/test-sparse.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-sparse.t	Mon Nov 02 14:39:43 2020 -0500
@@ -196,7 +196,7 @@
 Verify rebase temporarily includes excluded files
 
   $ hg rebase -d 1 -r 2 --config extensions.rebase=
-  rebasing 2:b91df4f39e75 "edit hide" (tip)
+  rebasing 2:b91df4f39e75 tip "edit hide"
   temporarily included 2 file(s) in the sparse checkout for merging
   merging hide
   warning: conflicts while merging hide! (edit, then use 'hg resolve --mark')
@@ -279,7 +279,7 @@
 
   $ hg commit -Aqm "add show2"
   $ hg rebase -d 1 --config extensions.rebase=
-  rebasing 2:bdde55290160 "add show2" (tip)
+  rebasing 2:bdde55290160 tip "add show2"
   saved backup bundle to $TESTTMP/myrepo/.hg/strip-backup/bdde55290160-216ed9c6-rebase.hg
 
 Verify log --sparse only shows commits that affect the sparse checkout
--- a/tests/test-split.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-split.t	Mon Nov 02 14:39:43 2020 -0500
@@ -216,7 +216,7 @@
   (enter ? for help) [Ynesfdaq?] y
   
   EDITOR: HG: Splitting 1df0d5c5a3ab. So far it has been split into:
-  EDITOR: HG: - e704349bd21b: split 1
+  EDITOR: HG: - 2:e704349bd21b tip "split 1"
   EDITOR: HG: Write commit message for the next split changeset.
   EDITOR: a2
   EDITOR: 
@@ -239,8 +239,8 @@
   (enter ? for help) [Ynesfdaq?] y
   
   EDITOR: HG: Splitting 1df0d5c5a3ab. So far it has been split into:
-  EDITOR: HG: - e704349bd21b: split 1
-  EDITOR: HG: - a09ad58faae3: split 2
+  EDITOR: HG: - 2:e704349bd21b tip "split 1"
+  EDITOR: HG: - 3:a09ad58faae3 "split 2"
   EDITOR: HG: Write commit message for the next split changeset.
   EDITOR: a2
   EDITOR: 
@@ -368,9 +368,9 @@
   $ cp -R . ../d
 
   $ runsplit -r 1 | grep rebasing
-  rebasing 2:b5c5ea414030 "d1" (d1)
-  rebasing 3:f4a0a8d004cc "d2" (d2)
-  rebasing 4:777940761eba "d3" (d3)
+  rebasing 2:b5c5ea414030 d1 "d1"
+  rebasing 3:f4a0a8d004cc d2 "d2"
+  rebasing 4:777940761eba d3 "d3"
 #if obsstore-off
   $ hg bookmark
      d1                        4:c4b449ef030e
@@ -661,7 +661,7 @@
   (enter ? for help) [Ynesfdaq?] f
   
   EDITOR: HG: Splitting dd3c45017cbf. So far it has been split into:
-  EDITOR: HG: - f205aea1c624: split 1
+  EDITOR: HG: - 2:f205aea1c624 tip "split 1"
   EDITOR: HG: Write commit message for the next split changeset.
   EDITOR: splitme
   EDITOR: 
@@ -718,7 +718,7 @@
   (enter ? for help) [Ynesfdaq?] f
   
   EDITOR: HG: Splitting 904c80b40a4a. So far it has been split into:
-  EDITOR: HG: - ffecf40fa954: split 1
+  EDITOR: HG: - 2:ffecf40fa954 tip "split 1"
   EDITOR: HG: Write commit message for the next split changeset.
   EDITOR: splitme
   EDITOR: 
@@ -843,7 +843,7 @@
   (enter ? for help) [Ynesfdaq?] a
   
   EDITOR: HG: Splitting 8c42fa635116. So far it has been split into:
-  EDITOR: HG: - 478be2a70c27: split1, keeping only the numbered lines
+  EDITOR: HG: - 2:478be2a70c27 tip "split1, keeping only the numbered lines"
   EDITOR: HG: Write commit message for the next split changeset.
   EDITOR: move and modify
   EDITOR: 
@@ -941,7 +941,7 @@
   (enter ? for help) [Ynesfdaq?] a
   
   EDITOR: HG: Splitting 41c861dfa61e. So far it has been split into:
-  EDITOR: HG: - 4b19e06610eb: split1, keeping "file" and only the numbered lines in file2
+  EDITOR: HG: - 2:4b19e06610eb tip "split1, keeping "file" and only the numbered lines in file2"
   EDITOR: HG: Write commit message for the next split changeset.
   EDITOR: copy file->file2, modify both
   EDITOR: 
--- a/tests/test-template-map.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-template-map.t	Mon Nov 02 14:39:43 2020 -0500
@@ -48,8 +48,9 @@
 
 Make sure user/global hgrc does not affect tests
 
+  $ echo '[command-templates]' > .hg/hgrc
+  $ echo 'log =' >> .hg/hgrc
   $ echo '[ui]' > .hg/hgrc
-  $ echo 'logtemplate =' >> .hg/hgrc
   $ echo 'style =' >> .hg/hgrc
 
 Add some simple styles to settings
--- a/tests/test-treediscovery.t	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/test-treediscovery.t	Mon Nov 02 14:39:43 2020 -0500
@@ -3,8 +3,8 @@
   $ CAP="getbundle bundle2"
   $ . "$TESTDIR/notcapable"
   $ cat >> $HGRCPATH <<EOF
-  > [ui]
-  > logtemplate="{rev} {node|short}: {desc} {branches}\n"
+  > [command-templates]
+  > log="{rev} {node|short}: {desc} {branches}\n"
   > EOF
 
 Setup HTTP server control:
--- a/tests/testlib/exchange-obsmarker-util.sh	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/testlib/exchange-obsmarker-util.sh	Mon Nov 02 14:39:43 2020 -0500
@@ -14,9 +14,9 @@
 push_ssl = false
 allow_push = *
 
-[ui]
+[command-templates]
 # simpler log output
-logtemplate ="{node|short} ({phase}): {desc}\n"
+log ="{node|short} ({phase}): {desc}\n"
 
 [phases]
 # non publishing server
--- a/tests/testlib/push-checkheads-util.sh	Mon Nov 02 14:26:19 2020 -0500
+++ b/tests/testlib/push-checkheads-util.sh	Mon Nov 02 14:39:43 2020 -0500
@@ -1,9 +1,9 @@
 # setup config and various utility to test new heads checks on push
 
 cat >> $HGRCPATH <<EOF
-[ui]
+[command-templates]
 # simpler log output
-logtemplate ="{node|short} ({phase}): {desc}\n"
+log ="{node|short} ({phase}): {desc}\n"
 
 [phases]
 # non publishing server