infinitepush: drop the extension
authorPierre-Yves David <pierre-yves.david@octobus.net>
Fri, 21 Jul 2023 03:56:28 +0200
changeset 50803 609a3b8058c3
parent 50802 cf0502231d56
child 50806 337bc83c1275
infinitepush: drop the extension The writing have been on the wall for a long time.
contrib/check-pytype.sh
contrib/python3-whitelist
hgext/infinitepush/README
hgext/infinitepush/__init__.py
hgext/infinitepush/bundleparts.py
hgext/infinitepush/common.py
hgext/infinitepush/fileindexapi.py
hgext/infinitepush/indexapi.py
hgext/infinitepush/schema.sql
hgext/infinitepush/sqlindexapi.py
hgext/infinitepush/store.py
hgext/lfs/wrapper.py
i18n/ja.po
i18n/pt_BR.po
relnotes/next
setup.py
tests/library-infinitepush.sh
tests/test-check-py3-compat.t
tests/test-infinitepush-bundlestore.t
tests/test-infinitepush-ci.t
tests/test-infinitepush.t
--- a/contrib/check-pytype.sh	Fri Jun 23 13:27:09 2023 +0200
+++ b/contrib/check-pytype.sh	Fri Jul 21 03:56:28 2023 +0200
@@ -26,7 +26,6 @@
 # hgext/githelp.py              # [attribute-error] [wrong-arg-types]
 # hgext/hgk.py                  # [attribute-error]
 # hgext/histedit.py             # [attribute-error], [wrong-arg-types]
-# hgext/infinitepush            # using bytes for str literal; scheduled for removal
 # hgext/keyword.py              # [attribute-error]
 # hgext/largefiles/storefactory.py  # [attribute-error]
 # hgext/lfs/__init__.py         # [attribute-error]
@@ -88,7 +87,6 @@
     -x hgext/githelp.py \
     -x hgext/hgk.py \
     -x hgext/histedit.py \
-    -x hgext/infinitepush \
     -x hgext/keyword.py \
     -x hgext/largefiles/storefactory.py \
     -x hgext/lfs/__init__.py \
--- a/contrib/python3-whitelist	Fri Jun 23 13:27:09 2023 +0200
+++ b/contrib/python3-whitelist	Fri Jul 21 03:56:28 2023 +0200
@@ -337,9 +337,6 @@
 test-import.t
 test-imports-checker.t
 test-incoming-outgoing.t
-test-infinitepush-bundlestore.t
-test-infinitepush-ci.t
-test-infinitepush.t
 test-inherit-mode.t
 test-init.t
 test-install.t
--- a/hgext/infinitepush/README	Fri Jun 23 13:27:09 2023 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,23 +0,0 @@
-## What is it?
-
-This extension adds ability to save certain pushes to a remote blob store
-as bundles and to serve commits from remote blob store.
-The revisions are stored on disk or in everstore.
-The metadata are stored in sql or on disk.
-
-## Config options
-
-infinitepush.branchpattern: pattern to detect a scratchbranch, example
-                            're:scratch/.+'
-
-infinitepush.indextype: disk or sql for the metadata
-infinitepush.reponame: only relevant for sql metadata backend, reponame to put in
-                       sql
-
-infinitepush.indexpath: only relevant for ondisk metadata backend, the path to
-                        store the index on disk. If not set will be under .hg
-                        in a folder named filebundlestore
-
-infinitepush.storepath: only relevant for ondisk metadata backend, the path to
-                        store the bundles. If not set, it will be
-                        .hg/filebundlestore
--- a/hgext/infinitepush/__init__.py	Fri Jun 23 13:27:09 2023 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1413 +0,0 @@
-# Infinite push
-#
-# Copyright 2016 Facebook, Inc.
-#
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2 or any later version.
-""" store some pushes in a remote blob store on the server (EXPERIMENTAL)
-
-IMPORTANT: if you use this extension, please contact
-mercurial-devel@mercurial-scm.org ASAP. This extension is believed to
-be unused and barring learning of users of this functionality, we will
-delete this code at the end of 2020.
-
-    [infinitepush]
-    # Server-side and client-side option. Pattern of the infinitepush bookmark
-    branchpattern = PATTERN
-
-    # Server or client
-    server = False
-
-    # Server-side option. Possible values: 'disk' or 'sql'. Fails if not set
-    indextype = disk
-
-    # Server-side option. Used only if indextype=sql.
-    # Format: 'IP:PORT:DB_NAME:USER:PASSWORD'
-    sqlhost = IP:PORT:DB_NAME:USER:PASSWORD
-
-    # Server-side option. Used only if indextype=disk.
-    # Filesystem path to the index store
-    indexpath = PATH
-
-    # Server-side option. Possible values: 'disk' or 'external'
-    # Fails if not set
-    storetype = disk
-
-    # Server-side option.
-    # Path to the binary that will save bundle to the bundlestore
-    # Formatted cmd line will be passed to it (see `put_args`)
-    put_binary = put
-
-    # Serser-side option. Used only if storetype=external.
-    # Format cmd-line string for put binary. Placeholder: {filename}
-    put_args = {filename}
-
-    # Server-side option.
-    # Path to the binary that get bundle from the bundlestore.
-    # Formatted cmd line will be passed to it (see `get_args`)
-    get_binary = get
-
-    # Serser-side option. Used only if storetype=external.
-    # Format cmd-line string for get binary. Placeholders: {filename} {handle}
-    get_args = {filename} {handle}
-
-    # Server-side option
-    logfile = FIlE
-
-    # Server-side option
-    loglevel = DEBUG
-
-    # Server-side option. Used only if indextype=sql.
-    # Sets mysql wait_timeout option.
-    waittimeout = 300
-
-    # Server-side option. Used only if indextype=sql.
-    # Sets mysql innodb_lock_wait_timeout option.
-    locktimeout = 120
-
-    # Server-side option. Used only if indextype=sql.
-    # Name of the repository
-    reponame = ''
-
-    # Client-side option. Used by --list-remote option. List of remote scratch
-    # patterns to list if no patterns are specified.
-    defaultremotepatterns = ['*']
-
-    # Instructs infinitepush to forward all received bundle2 parts to the
-    # bundle for storage. Defaults to False.
-    storeallparts = True
-
-    # routes each incoming push to the bundlestore. defaults to False
-    pushtobundlestore = True
-
-    [remotenames]
-    # Client-side option
-    # This option should be set only if remotenames extension is enabled.
-    # Whether remote bookmarks are tracked by remotenames extension.
-    bookmarks = True
-"""
-
-
-import collections
-import contextlib
-import functools
-import logging
-import os
-import random
-import re
-import socket
-import subprocess
-import time
-
-from mercurial.node import (
-    bin,
-    hex,
-)
-
-from mercurial.i18n import _
-
-from mercurial.pycompat import (
-    getattr,
-    open,
-)
-
-from mercurial.utils import (
-    procutil,
-    stringutil,
-    urlutil,
-)
-
-from mercurial import (
-    bundle2,
-    changegroup,
-    commands,
-    discovery,
-    encoding,
-    error,
-    exchange,
-    extensions,
-    hg,
-    localrepo,
-    phases,
-    pushkey,
-    pycompat,
-    registrar,
-    util,
-    wireprototypes,
-    wireprotov1peer,
-    wireprotov1server,
-)
-
-from . import (
-    bundleparts,
-    common,
-)
-
-# Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
-# extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
-# be specifying the version(s) of Mercurial they are tested with, or
-# leave the attribute unspecified.
-testedwith = b'ships-with-hg-core'
-
-configtable = {}
-configitem = registrar.configitem(configtable)
-
-configitem(
-    b'infinitepush',
-    b'deprecation-message',
-    default=True,
-)
-
-configitem(
-    b'infinitepush',
-    b'deprecation-abort',
-    default=True,
-)
-
-configitem(
-    b'infinitepush',
-    b'server',
-    default=False,
-)
-configitem(
-    b'infinitepush',
-    b'storetype',
-    default=b'',
-)
-configitem(
-    b'infinitepush',
-    b'indextype',
-    default=b'',
-)
-configitem(
-    b'infinitepush',
-    b'indexpath',
-    default=b'',
-)
-configitem(
-    b'infinitepush',
-    b'storeallparts',
-    default=False,
-)
-configitem(
-    b'infinitepush',
-    b'reponame',
-    default=b'',
-)
-configitem(
-    b'scratchbranch',
-    b'storepath',
-    default=b'',
-)
-configitem(
-    b'infinitepush',
-    b'branchpattern',
-    default=b'',
-)
-configitem(
-    b'infinitepush',
-    b'pushtobundlestore',
-    default=False,
-)
-configitem(
-    b'experimental',
-    b'server-bundlestore-bookmark',
-    default=b'',
-)
-configitem(
-    b'experimental',
-    b'infinitepush-scratchpush',
-    default=False,
-)
-
-experimental = b'experimental'
-configbookmark = b'server-bundlestore-bookmark'
-configscratchpush = b'infinitepush-scratchpush'
-
-scratchbranchparttype = bundleparts.scratchbranchparttype
-revsetpredicate = registrar.revsetpredicate()
-templatekeyword = registrar.templatekeyword()
-_scratchbranchmatcher = lambda x: False
-_maybehash = re.compile('^[a-f0-9]+$').search
-
-
-def _buildexternalbundlestore(ui):
-    put_args = ui.configlist(b'infinitepush', b'put_args', [])
-    put_binary = ui.config(b'infinitepush', b'put_binary')
-    if not put_binary:
-        raise error.Abort(b'put binary is not specified')
-    get_args = ui.configlist(b'infinitepush', b'get_args', [])
-    get_binary = ui.config(b'infinitepush', b'get_binary')
-    if not get_binary:
-        raise error.Abort(b'get binary is not specified')
-    from . import store
-
-    return store.externalbundlestore(put_binary, put_args, get_binary, get_args)
-
-
-def _buildsqlindex(ui):
-    sqlhost = ui.config(b'infinitepush', b'sqlhost')
-    if not sqlhost:
-        raise error.Abort(_(b'please set infinitepush.sqlhost'))
-    host, port, db, user, password = sqlhost.split(b':')
-    reponame = ui.config(b'infinitepush', b'reponame')
-    if not reponame:
-        raise error.Abort(_(b'please set infinitepush.reponame'))
-
-    logfile = ui.config(b'infinitepush', b'logfile', b'')
-    waittimeout = ui.configint(b'infinitepush', b'waittimeout', 300)
-    locktimeout = ui.configint(b'infinitepush', b'locktimeout', 120)
-    from . import sqlindexapi
-
-    return sqlindexapi.sqlindexapi(
-        reponame,
-        host,
-        port,
-        db,
-        user,
-        password,
-        logfile,
-        _getloglevel(ui),
-        waittimeout=waittimeout,
-        locktimeout=locktimeout,
-    )
-
-
-def _getloglevel(ui):
-    loglevel = ui.config(b'infinitepush', b'loglevel', b'DEBUG')
-    numeric_loglevel = getattr(logging, loglevel.upper(), None)
-    if not isinstance(numeric_loglevel, int):
-        raise error.Abort(_(b'invalid log level %s') % loglevel)
-    return numeric_loglevel
-
-
-def _tryhoist(ui, remotebookmark):
-    """returns a bookmarks with hoisted part removed
-
-    Remotenames extension has a 'hoist' config that allows to use remote
-    bookmarks without specifying remote path. For example, 'hg update master'
-    works as well as 'hg update remote/master'. We want to allow the same in
-    infinitepush.
-    """
-
-    if common.isremotebooksenabled(ui):
-        hoist = ui.config(b'remotenames', b'hoistedpeer') + b'/'
-        if remotebookmark.startswith(hoist):
-            return remotebookmark[len(hoist) :]
-    return remotebookmark
-
-
-class bundlestore:
-    def __init__(self, repo):
-        self._repo = repo
-        storetype = self._repo.ui.config(b'infinitepush', b'storetype')
-        if storetype == b'disk':
-            from . import store
-
-            self.store = store.filebundlestore(self._repo.ui, self._repo)
-        elif storetype == b'external':
-            self.store = _buildexternalbundlestore(self._repo.ui)
-        else:
-            raise error.Abort(
-                _(b'unknown infinitepush store type specified %s') % storetype
-            )
-
-        indextype = self._repo.ui.config(b'infinitepush', b'indextype')
-        if indextype == b'disk':
-            from . import fileindexapi
-
-            self.index = fileindexapi.fileindexapi(self._repo)
-        elif indextype == b'sql':
-            self.index = _buildsqlindex(self._repo.ui)
-        else:
-            raise error.Abort(
-                _(b'unknown infinitepush index type specified %s') % indextype
-            )
-
-
-def _isserver(ui):
-    return ui.configbool(b'infinitepush', b'server')
-
-
-WARNING_MSG = b"""IMPORTANT: if you use this extension, please contact
-mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-unused and barring learning of users of this functionality, we drop this
-extension in Mercurial 6.6.
-"""
-
-
-def reposetup(ui, repo):
-    if ui.configbool(b'infinitepush', b'deprecation-message'):
-        ui.write_err(WARNING_MSG)
-    if ui.configbool(b'infinitepush', b'deprecation-abort'):
-        msg = b"USING EXTENSION INFINITE PUSH DESPITE PENDING DROP"
-        hint = b"contact mercurial-devel@mercurial-scm.org"
-        raise error.Abort(msg, hint=hint)
-    if _isserver(ui) and repo.local():
-        repo.bundlestore = bundlestore(repo)
-
-
-def extsetup(ui):
-    commonsetup(ui)
-    if _isserver(ui):
-        serverextsetup(ui)
-    else:
-        clientextsetup(ui)
-
-
-def uipopulate(ui):
-    if not ui.hasconfig(b"experimental", b"changegroup3"):
-        ui.setconfig(b"experimental", b"changegroup3", False, b"infinitepush")
-
-
-def commonsetup(ui):
-    wireprotov1server.commands[b'listkeyspatterns'] = (
-        wireprotolistkeyspatterns,
-        b'namespace patterns',
-    )
-    scratchbranchpat = ui.config(b'infinitepush', b'branchpattern')
-    if scratchbranchpat:
-        global _scratchbranchmatcher
-        kind, pat, _scratchbranchmatcher = stringutil.stringmatcher(
-            scratchbranchpat
-        )
-
-
-def serverextsetup(ui):
-    origpushkeyhandler = bundle2.parthandlermapping[b'pushkey']
-
-    def newpushkeyhandler(*args, **kwargs):
-        bundle2pushkey(origpushkeyhandler, *args, **kwargs)
-
-    newpushkeyhandler.params = origpushkeyhandler.params
-    bundle2.parthandlermapping[b'pushkey'] = newpushkeyhandler
-
-    orighandlephasehandler = bundle2.parthandlermapping[b'phase-heads']
-    newphaseheadshandler = lambda *args, **kwargs: bundle2handlephases(
-        orighandlephasehandler, *args, **kwargs
-    )
-    newphaseheadshandler.params = orighandlephasehandler.params
-    bundle2.parthandlermapping[b'phase-heads'] = newphaseheadshandler
-
-    extensions.wrapfunction(
-        localrepo.localrepository, 'listkeys', localrepolistkeys
-    )
-    wireprotov1server.commands[b'lookup'] = (
-        _lookupwrap(wireprotov1server.commands[b'lookup'][0]),
-        b'key',
-    )
-    extensions.wrapfunction(exchange, 'getbundlechunks', getbundlechunks)
-
-    extensions.wrapfunction(bundle2, 'processparts', processparts)
-
-
-def clientextsetup(ui):
-    entry = extensions.wrapcommand(commands.table, b'push', _push)
-
-    entry[1].append(
-        (
-            b'',
-            b'bundle-store',
-            None,
-            _(b'force push to go to bundle store (EXPERIMENTAL)'),
-        )
-    )
-
-    extensions.wrapcommand(commands.table, b'pull', _pull)
-
-    extensions.wrapfunction(discovery, 'checkheads', _checkheads)
-
-    wireprotov1peer.wirepeer.listkeyspatterns = listkeyspatterns
-
-    partorder = exchange.b2partsgenorder
-    index = partorder.index(b'changeset')
-    partorder.insert(
-        index, partorder.pop(partorder.index(scratchbranchparttype))
-    )
-
-
-def _checkheads(orig, pushop):
-    if pushop.ui.configbool(experimental, configscratchpush, False):
-        return
-    return orig(pushop)
-
-
-def wireprotolistkeyspatterns(repo, proto, namespace, patterns):
-    patterns = wireprototypes.decodelist(patterns)
-    d = repo.listkeys(encoding.tolocal(namespace), patterns).items()
-    return pushkey.encodekeys(d)
-
-
-def localrepolistkeys(orig, self, namespace, patterns=None):
-    if namespace == b'bookmarks' and patterns:
-        index = self.bundlestore.index
-        results = {}
-        bookmarks = orig(self, namespace)
-        for pattern in patterns:
-            results.update(index.getbookmarks(pattern))
-            if pattern.endswith(b'*'):
-                pattern = b're:^' + pattern[:-1] + b'.*'
-            kind, pat, matcher = stringutil.stringmatcher(pattern)
-            for bookmark, node in bookmarks.items():
-                if matcher(bookmark):
-                    results[bookmark] = node
-        return results
-    else:
-        return orig(self, namespace)
-
-
-@wireprotov1peer.batchable
-def listkeyspatterns(self, namespace, patterns):
-    if not self.capable(b'pushkey'):
-        return {}, None
-    self.ui.debug(b'preparing listkeys for "%s"\n' % namespace)
-
-    def decode(d):
-        self.ui.debug(
-            b'received listkey for "%s": %i bytes\n' % (namespace, len(d))
-        )
-        return pushkey.decodekeys(d)
-
-    return {
-        b'namespace': encoding.fromlocal(namespace),
-        b'patterns': wireprototypes.encodelist(patterns),
-    }, decode
-
-
-def _readbundlerevs(bundlerepo):
-    return list(bundlerepo.revs(b'bundle()'))
-
-
-def _includefilelogstobundle(bundlecaps, bundlerepo, bundlerevs, ui):
-    """Tells remotefilelog to include all changed files to the changegroup
-
-    By default remotefilelog doesn't include file content to the changegroup.
-    But we need to include it if we are fetching from bundlestore.
-    """
-    changedfiles = set()
-    cl = bundlerepo.changelog
-    for r in bundlerevs:
-        # [3] means changed files
-        changedfiles.update(cl.read(r)[3])
-    if not changedfiles:
-        return bundlecaps
-
-    changedfiles = b'\0'.join(changedfiles)
-    newcaps = []
-    appended = False
-    for cap in bundlecaps or []:
-        if cap.startswith(b'excludepattern='):
-            newcaps.append(b'\0'.join((cap, changedfiles)))
-            appended = True
-        else:
-            newcaps.append(cap)
-    if not appended:
-        # Not found excludepattern cap. Just append it
-        newcaps.append(b'excludepattern=' + changedfiles)
-
-    return newcaps
-
-
-def _rebundle(bundlerepo, bundleroots, unknownhead):
-    """
-    Bundle may include more revision then user requested. For example,
-    if user asks for revision but bundle also consists its descendants.
-    This function will filter out all revision that user is not requested.
-    """
-    parts = []
-
-    version = b'02'
-    outgoing = discovery.outgoing(
-        bundlerepo, commonheads=bundleroots, ancestorsof=[unknownhead]
-    )
-    cgstream = changegroup.makestream(bundlerepo, outgoing, version, b'pull')
-    cgstream = util.chunkbuffer(cgstream).read()
-    cgpart = bundle2.bundlepart(b'changegroup', data=cgstream)
-    cgpart.addparam(b'version', version)
-    parts.append(cgpart)
-
-    return parts
-
-
-def _getbundleroots(oldrepo, bundlerepo, bundlerevs):
-    cl = bundlerepo.changelog
-    bundleroots = []
-    for rev in bundlerevs:
-        node = cl.node(rev)
-        parents = cl.parents(node)
-        for parent in parents:
-            # include all revs that exist in the main repo
-            # to make sure that bundle may apply client-side
-            if parent in oldrepo:
-                bundleroots.append(parent)
-    return bundleroots
-
-
-def _needsrebundling(head, bundlerepo):
-    bundleheads = list(bundlerepo.revs(b'heads(bundle())'))
-    return not (
-        len(bundleheads) == 1 and bundlerepo[bundleheads[0]].node() == head
-    )
-
-
-def _generateoutputparts(head, bundlerepo, bundleroots, bundlefile):
-    """generates bundle that will be send to the user
-
-    returns tuple with raw bundle string and bundle type
-    """
-    parts = []
-    if not _needsrebundling(head, bundlerepo):
-        with util.posixfile(bundlefile, b"rb") as f:
-            unbundler = exchange.readbundle(bundlerepo.ui, f, bundlefile)
-            if isinstance(unbundler, changegroup.cg1unpacker):
-                part = bundle2.bundlepart(
-                    b'changegroup', data=unbundler._stream.read()
-                )
-                part.addparam(b'version', b'01')
-                parts.append(part)
-            elif isinstance(unbundler, bundle2.unbundle20):
-                haschangegroup = False
-                for part in unbundler.iterparts():
-                    if part.type == b'changegroup':
-                        haschangegroup = True
-                    newpart = bundle2.bundlepart(part.type, data=part.read())
-                    for key, value in part.params.items():
-                        newpart.addparam(key, value)
-                    parts.append(newpart)
-
-                if not haschangegroup:
-                    raise error.Abort(
-                        b'unexpected bundle without changegroup part, '
-                        + b'head: %s' % hex(head),
-                        hint=b'report to administrator',
-                    )
-            else:
-                raise error.Abort(b'unknown bundle type')
-    else:
-        parts = _rebundle(bundlerepo, bundleroots, head)
-
-    return parts
-
-
-def getbundlechunks(orig, repo, source, heads=None, bundlecaps=None, **kwargs):
-    heads = heads or []
-    # newheads are parents of roots of scratch bundles that were requested
-    newphases = {}
-    scratchbundles = []
-    newheads = []
-    scratchheads = []
-    nodestobundle = {}
-    allbundlestocleanup = []
-    try:
-        for head in heads:
-            if not repo.changelog.index.has_node(head):
-                if head not in nodestobundle:
-                    newbundlefile = common.downloadbundle(repo, head)
-                    bundlepath = b"bundle:%s+%s" % (repo.root, newbundlefile)
-                    bundlerepo = hg.repository(repo.ui, bundlepath)
-
-                    allbundlestocleanup.append((bundlerepo, newbundlefile))
-                    bundlerevs = set(_readbundlerevs(bundlerepo))
-                    bundlecaps = _includefilelogstobundle(
-                        bundlecaps, bundlerepo, bundlerevs, repo.ui
-                    )
-                    cl = bundlerepo.changelog
-                    bundleroots = _getbundleroots(repo, bundlerepo, bundlerevs)
-                    for rev in bundlerevs:
-                        node = cl.node(rev)
-                        newphases[hex(node)] = str(phases.draft)
-                        nodestobundle[node] = (
-                            bundlerepo,
-                            bundleroots,
-                            newbundlefile,
-                        )
-
-                scratchbundles.append(
-                    _generateoutputparts(head, *nodestobundle[head])
-                )
-                newheads.extend(bundleroots)
-                scratchheads.append(head)
-    finally:
-        for bundlerepo, bundlefile in allbundlestocleanup:
-            bundlerepo.close()
-            try:
-                os.unlink(bundlefile)
-            except (IOError, OSError):
-                # if we can't cleanup the file then just ignore the error,
-                # no need to fail
-                pass
-
-    pullfrombundlestore = bool(scratchbundles)
-    wrappedchangegrouppart = False
-    wrappedlistkeys = False
-    oldchangegrouppart = exchange.getbundle2partsmapping[b'changegroup']
-    try:
-
-        def _changegrouppart(bundler, *args, **kwargs):
-            # Order is important here. First add non-scratch part
-            # and only then add parts with scratch bundles because
-            # non-scratch part contains parents of roots of scratch bundles.
-            result = oldchangegrouppart(bundler, *args, **kwargs)
-            for bundle in scratchbundles:
-                for part in bundle:
-                    bundler.addpart(part)
-            return result
-
-        exchange.getbundle2partsmapping[b'changegroup'] = _changegrouppart
-        wrappedchangegrouppart = True
-
-        def _listkeys(orig, self, namespace):
-            origvalues = orig(self, namespace)
-            if namespace == b'phases' and pullfrombundlestore:
-                if origvalues.get(b'publishing') == b'True':
-                    # Make repo non-publishing to preserve draft phase
-                    del origvalues[b'publishing']
-                origvalues.update(newphases)
-            return origvalues
-
-        extensions.wrapfunction(
-            localrepo.localrepository, 'listkeys', _listkeys
-        )
-        wrappedlistkeys = True
-        heads = list((set(newheads) | set(heads)) - set(scratchheads))
-        result = orig(
-            repo, source, heads=heads, bundlecaps=bundlecaps, **kwargs
-        )
-    finally:
-        if wrappedchangegrouppart:
-            exchange.getbundle2partsmapping[b'changegroup'] = oldchangegrouppart
-        if wrappedlistkeys:
-            extensions.unwrapfunction(
-                localrepo.localrepository, 'listkeys', _listkeys
-            )
-    return result
-
-
-def _lookupwrap(orig):
-    def _lookup(repo, proto, key):
-        localkey = encoding.tolocal(key)
-
-        if isinstance(localkey, str) and _scratchbranchmatcher(localkey):
-            scratchnode = repo.bundlestore.index.getnode(localkey)
-            if scratchnode:
-                return b"%d %s\n" % (1, scratchnode)
-            else:
-                return b"%d %s\n" % (
-                    0,
-                    b'scratch branch %s not found' % localkey,
-                )
-        else:
-            try:
-                r = hex(repo.lookup(localkey))
-                return b"%d %s\n" % (1, r)
-            except Exception as inst:
-                if repo.bundlestore.index.getbundle(localkey):
-                    return b"%d %s\n" % (1, localkey)
-                else:
-                    r = stringutil.forcebytestr(inst)
-                    return b"%d %s\n" % (0, r)
-
-    return _lookup
-
-
-def _pull(orig, ui, repo, source=b"default", **opts):
-    opts = pycompat.byteskwargs(opts)
-    # Copy paste from `pull` command
-    path = urlutil.get_unique_pull_path_obj(
-        b"infinite-push's pull",
-        ui,
-        source,
-    )
-
-    scratchbookmarks = {}
-    unfi = repo.unfiltered()
-    unknownnodes = []
-    for rev in opts.get(b'rev', []):
-        if rev not in unfi:
-            unknownnodes.append(rev)
-    if opts.get(b'bookmark'):
-        bookmarks = []
-        revs = opts.get(b'rev') or []
-        for bookmark in opts.get(b'bookmark'):
-            if _scratchbranchmatcher(bookmark):
-                # rev is not known yet
-                # it will be fetched with listkeyspatterns next
-                scratchbookmarks[bookmark] = b'REVTOFETCH'
-            else:
-                bookmarks.append(bookmark)
-
-        if scratchbookmarks:
-            other = hg.peer(repo, opts, path)
-            try:
-                fetchedbookmarks = other.listkeyspatterns(
-                    b'bookmarks', patterns=scratchbookmarks
-                )
-                for bookmark in scratchbookmarks:
-                    if bookmark not in fetchedbookmarks:
-                        raise error.Abort(
-                            b'remote bookmark %s not found!' % bookmark
-                        )
-                    scratchbookmarks[bookmark] = fetchedbookmarks[bookmark]
-                    revs.append(fetchedbookmarks[bookmark])
-            finally:
-                other.close()
-        opts[b'bookmark'] = bookmarks
-        opts[b'rev'] = revs
-
-    if scratchbookmarks or unknownnodes:
-        # Set anyincoming to True
-        extensions.wrapfunction(
-            discovery, 'findcommonincoming', _findcommonincoming
-        )
-    try:
-        # Remote scratch bookmarks will be deleted because remotenames doesn't
-        # know about them. Let's save it before pull and restore after
-        remotescratchbookmarks = _readscratchremotebookmarks(ui, repo, path.loc)
-        result = orig(ui, repo, path.loc, **pycompat.strkwargs(opts))
-        # TODO(stash): race condition is possible
-        # if scratch bookmarks was updated right after orig.
-        # But that's unlikely and shouldn't be harmful.
-        if common.isremotebooksenabled(ui):
-            remotescratchbookmarks.update(scratchbookmarks)
-            _saveremotebookmarks(repo, remotescratchbookmarks, path.loc)
-        else:
-            _savelocalbookmarks(repo, scratchbookmarks)
-        return result
-    finally:
-        if scratchbookmarks:
-            extensions.unwrapfunction(discovery, 'findcommonincoming')
-
-
-def _readscratchremotebookmarks(ui, repo, other):
-    if common.isremotebooksenabled(ui):
-        remotenamesext = extensions.find(b'remotenames')
-        remotepath = remotenamesext.activepath(repo.ui, other)
-        result = {}
-        # Let's refresh remotenames to make sure we have it up to date
-        # Seems that `repo.names['remotebookmarks']` may return stale bookmarks
-        # and it results in deleting scratch bookmarks. Our best guess how to
-        # fix it is to use `clearnames()`
-        repo._remotenames.clearnames()
-        for remotebookmark in repo.names[b'remotebookmarks'].listnames(repo):
-            path, bookname = remotenamesext.splitremotename(remotebookmark)
-            if path == remotepath and _scratchbranchmatcher(bookname):
-                nodes = repo.names[b'remotebookmarks'].nodes(
-                    repo, remotebookmark
-                )
-                if nodes:
-                    result[bookname] = hex(nodes[0])
-        return result
-    else:
-        return {}
-
-
-def _saveremotebookmarks(repo, newbookmarks, remote):
-    remotenamesext = extensions.find(b'remotenames')
-    remotepath = remotenamesext.activepath(repo.ui, remote)
-    branches = collections.defaultdict(list)
-    bookmarks = {}
-    remotenames = remotenamesext.readremotenames(repo)
-    for hexnode, nametype, remote, rname in remotenames:
-        if remote != remotepath:
-            continue
-        if nametype == b'bookmarks':
-            if rname in newbookmarks:
-                # It's possible if we have a normal bookmark that matches
-                # scratch branch pattern. In this case just use the current
-                # bookmark node
-                del newbookmarks[rname]
-            bookmarks[rname] = hexnode
-        elif nametype == b'branches':
-            # saveremotenames expects 20 byte binary nodes for branches
-            branches[rname].append(bin(hexnode))
-
-    for bookmark, hexnode in newbookmarks.items():
-        bookmarks[bookmark] = hexnode
-    remotenamesext.saveremotenames(repo, remotepath, branches, bookmarks)
-
-
-def _savelocalbookmarks(repo, bookmarks):
-    if not bookmarks:
-        return
-    with repo.wlock(), repo.lock(), repo.transaction(b'bookmark') as tr:
-        changes = []
-        for scratchbook, node in bookmarks.items():
-            changectx = repo[node]
-            changes.append((scratchbook, changectx.node()))
-        repo._bookmarks.applychanges(repo, tr, changes)
-
-
-def _findcommonincoming(orig, *args, **kwargs):
-    common, inc, remoteheads = orig(*args, **kwargs)
-    return common, True, remoteheads
-
-
-def _push(orig, ui, repo, *dests, **opts):
-    opts = pycompat.byteskwargs(opts)
-    bookmark = opts.get(b'bookmark')
-    # we only support pushing one infinitepush bookmark at once
-    if len(bookmark) == 1:
-        bookmark = bookmark[0]
-    else:
-        bookmark = b''
-
-    oldphasemove = None
-    overrides = {(experimental, configbookmark): bookmark}
-
-    with ui.configoverride(overrides, b'infinitepush'):
-        scratchpush = opts.get(b'bundle_store')
-        if _scratchbranchmatcher(bookmark):
-            scratchpush = True
-            # bundle2 can be sent back after push (for example, bundle2
-            # containing `pushkey` part to update bookmarks)
-            ui.setconfig(experimental, b'bundle2.pushback', True)
-
-        if scratchpush:
-            # this is an infinitepush, we don't want the bookmark to be applied
-            # rather that should be stored in the bundlestore
-            opts[b'bookmark'] = []
-            ui.setconfig(experimental, configscratchpush, True)
-            oldphasemove = extensions.wrapfunction(
-                exchange, '_localphasemove', _phasemove
-            )
-
-        paths = list(urlutil.get_push_paths(repo, ui, dests))
-        if len(paths) > 1:
-            msg = _(b'cannot push to multiple path with infinitepush')
-            raise error.Abort(msg)
-
-        path = paths[0]
-        destpath = path.loc
-        # Remote scratch bookmarks will be deleted because remotenames doesn't
-        # know about them. Let's save it before push and restore after
-        remotescratchbookmarks = _readscratchremotebookmarks(ui, repo, destpath)
-        result = orig(ui, repo, *dests, **pycompat.strkwargs(opts))
-        if common.isremotebooksenabled(ui):
-            if bookmark and scratchpush:
-                other = hg.peer(repo, opts, path)
-                try:
-                    fetchedbookmarks = other.listkeyspatterns(
-                        b'bookmarks', patterns=[bookmark]
-                    )
-                    remotescratchbookmarks.update(fetchedbookmarks)
-                finally:
-                    other.close()
-            _saveremotebookmarks(repo, remotescratchbookmarks, destpath)
-    if oldphasemove:
-        exchange._localphasemove = oldphasemove
-    return result
-
-
-def _deleteinfinitepushbookmarks(ui, repo, path, names):
-    """Prune remote names by removing the bookmarks we don't want anymore,
-    then writing the result back to disk
-    """
-    remotenamesext = extensions.find(b'remotenames')
-
-    # remotename format is:
-    # (node, nametype ("branches" or "bookmarks"), remote, name)
-    nametype_idx = 1
-    remote_idx = 2
-    name_idx = 3
-    remotenames = [
-        remotename
-        for remotename in remotenamesext.readremotenames(repo)
-        if remotename[remote_idx] == path
-    ]
-    remote_bm_names = [
-        remotename[name_idx]
-        for remotename in remotenames
-        if remotename[nametype_idx] == b"bookmarks"
-    ]
-
-    for name in names:
-        if name not in remote_bm_names:
-            raise error.Abort(
-                _(
-                    b"infinitepush bookmark '{}' does not exist "
-                    b"in path '{}'"
-                ).format(name, path)
-            )
-
-    bookmarks = {}
-    branches = collections.defaultdict(list)
-    for node, nametype, remote, name in remotenames:
-        if nametype == b"bookmarks" and name not in names:
-            bookmarks[name] = node
-        elif nametype == b"branches":
-            # saveremotenames wants binary nodes for branches
-            branches[name].append(bin(node))
-
-    remotenamesext.saveremotenames(repo, path, branches, bookmarks)
-
-
-def _phasemove(orig, pushop, nodes, phase=phases.public):
-    """prevent commits from being marked public
-
-    Since these are going to a scratch branch, they aren't really being
-    published."""
-
-    if phase != phases.public:
-        orig(pushop, nodes, phase)
-
-
-@exchange.b2partsgenerator(scratchbranchparttype)
-def partgen(pushop, bundler):
-    bookmark = pushop.ui.config(experimental, configbookmark)
-    scratchpush = pushop.ui.configbool(experimental, configscratchpush)
-    if b'changesets' in pushop.stepsdone or not scratchpush:
-        return
-
-    if scratchbranchparttype not in bundle2.bundle2caps(pushop.remote):
-        return
-
-    pushop.stepsdone.add(b'changesets')
-    if not pushop.outgoing.missing:
-        pushop.ui.status(_(b'no changes found\n'))
-        pushop.cgresult = 0
-        return
-
-    # This parameter tells the server that the following bundle is an
-    # infinitepush. This let's it switch the part processing to our infinitepush
-    # code path.
-    bundler.addparam(b"infinitepush", b"True")
-
-    scratchparts = bundleparts.getscratchbranchparts(
-        pushop.repo, pushop.remote, pushop.outgoing, pushop.ui, bookmark
-    )
-
-    for scratchpart in scratchparts:
-        bundler.addpart(scratchpart)
-
-    def handlereply(op):
-        # server either succeeds or aborts; no code to read
-        pushop.cgresult = 1
-
-    return handlereply
-
-
-bundle2.capabilities[bundleparts.scratchbranchparttype] = ()
-
-
-def _getrevs(bundle, oldnode, force, bookmark):
-    b'extracts and validates the revs to be imported'
-    revs = [bundle[r] for r in bundle.revs(b'sort(bundle())')]
-
-    # new bookmark
-    if oldnode is None:
-        return revs
-
-    # Fast forward update
-    if oldnode in bundle and list(bundle.set(b'bundle() & %s::', oldnode)):
-        return revs
-
-    return revs
-
-
-@contextlib.contextmanager
-def logservicecall(logger, service, **kwargs):
-    start = time.time()
-    logger(service, eventtype=b'start', **kwargs)
-    try:
-        yield
-        logger(
-            service,
-            eventtype=b'success',
-            elapsedms=(time.time() - start) * 1000,
-            **kwargs
-        )
-    except Exception as e:
-        logger(
-            service,
-            eventtype=b'failure',
-            elapsedms=(time.time() - start) * 1000,
-            errormsg=stringutil.forcebytestr(e),
-            **kwargs
-        )
-        raise
-
-
-def _getorcreateinfinitepushlogger(op):
-    logger = op.records[b'infinitepushlogger']
-    if not logger:
-        ui = op.repo.ui
-        try:
-            username = procutil.getuser()
-        except Exception:
-            username = b'unknown'
-        # Generate random request id to be able to find all logged entries
-        # for the same request. Since requestid is pseudo-generated it may
-        # not be unique, but we assume that (hostname, username, requestid)
-        # is unique.
-        random.seed()
-        requestid = random.randint(0, 2000000000)
-        hostname = socket.gethostname()
-        logger = functools.partial(
-            ui.log,
-            b'infinitepush',
-            user=username,
-            requestid=requestid,
-            hostname=hostname,
-            reponame=ui.config(b'infinitepush', b'reponame'),
-        )
-        op.records.add(b'infinitepushlogger', logger)
-    else:
-        logger = logger[0]
-    return logger
-
-
-def storetobundlestore(orig, repo, op, unbundler):
-    """stores the incoming bundle coming from push command to the bundlestore
-    instead of applying on the revlogs"""
-
-    repo.ui.status(_(b"storing changesets on the bundlestore\n"))
-    bundler = bundle2.bundle20(repo.ui)
-
-    # processing each part and storing it in bundler
-    with bundle2.partiterator(repo, op, unbundler) as parts:
-        for part in parts:
-            bundlepart = None
-            if part.type == b'replycaps':
-                # This configures the current operation to allow reply parts.
-                bundle2._processpart(op, part)
-            else:
-                bundlepart = bundle2.bundlepart(part.type, data=part.read())
-                for key, value in part.params.items():
-                    bundlepart.addparam(key, value)
-
-                # Certain parts require a response
-                if part.type in (b'pushkey', b'changegroup'):
-                    if op.reply is not None:
-                        rpart = op.reply.newpart(b'reply:%s' % part.type)
-                        rpart.addparam(
-                            b'in-reply-to', b'%d' % part.id, mandatory=False
-                        )
-                        rpart.addparam(b'return', b'1', mandatory=False)
-
-            op.records.add(
-                part.type,
-                {
-                    b'return': 1,
-                },
-            )
-            if bundlepart:
-                bundler.addpart(bundlepart)
-
-    # storing the bundle in the bundlestore
-    buf = util.chunkbuffer(bundler.getchunks())
-    fd, bundlefile = pycompat.mkstemp()
-    try:
-        try:
-            fp = os.fdopen(fd, 'wb')
-            fp.write(buf.read())
-        finally:
-            fp.close()
-        storebundle(op, {}, bundlefile)
-    finally:
-        try:
-            os.unlink(bundlefile)
-        except Exception:
-            # we would rather see the original exception
-            pass
-
-
-def processparts(orig, repo, op, unbundler):
-
-    # make sure we don't wrap processparts in case of `hg unbundle`
-    if op.source == b'unbundle':
-        return orig(repo, op, unbundler)
-
-    # this server routes each push to bundle store
-    if repo.ui.configbool(b'infinitepush', b'pushtobundlestore'):
-        return storetobundlestore(orig, repo, op, unbundler)
-
-    if unbundler.params.get(b'infinitepush') != b'True':
-        return orig(repo, op, unbundler)
-
-    handleallparts = repo.ui.configbool(b'infinitepush', b'storeallparts')
-
-    bundler = bundle2.bundle20(repo.ui)
-    cgparams = None
-    with bundle2.partiterator(repo, op, unbundler) as parts:
-        for part in parts:
-            bundlepart = None
-            if part.type == b'replycaps':
-                # This configures the current operation to allow reply parts.
-                bundle2._processpart(op, part)
-            elif part.type == bundleparts.scratchbranchparttype:
-                # Scratch branch parts need to be converted to normal
-                # changegroup parts, and the extra parameters stored for later
-                # when we upload to the store. Eventually those parameters will
-                # be put on the actual bundle instead of this part, then we can
-                # send a vanilla changegroup instead of the scratchbranch part.
-                cgversion = part.params.get(b'cgversion', b'01')
-                bundlepart = bundle2.bundlepart(
-                    b'changegroup', data=part.read()
-                )
-                bundlepart.addparam(b'version', cgversion)
-                cgparams = part.params
-
-                # If we're not dumping all parts into the new bundle, we need to
-                # alert the future pushkey and phase-heads handler to skip
-                # the part.
-                if not handleallparts:
-                    op.records.add(
-                        scratchbranchparttype + b'_skippushkey', True
-                    )
-                    op.records.add(
-                        scratchbranchparttype + b'_skipphaseheads', True
-                    )
-            else:
-                if handleallparts:
-                    # Ideally we would not process any parts, and instead just
-                    # forward them to the bundle for storage, but since this
-                    # differs from previous behavior, we need to put it behind a
-                    # config flag for incremental rollout.
-                    bundlepart = bundle2.bundlepart(part.type, data=part.read())
-                    for key, value in part.params.items():
-                        bundlepart.addparam(key, value)
-
-                    # Certain parts require a response
-                    if part.type == b'pushkey':
-                        if op.reply is not None:
-                            rpart = op.reply.newpart(b'reply:pushkey')
-                            rpart.addparam(
-                                b'in-reply-to', str(part.id), mandatory=False
-                            )
-                            rpart.addparam(b'return', b'1', mandatory=False)
-                else:
-                    bundle2._processpart(op, part)
-
-            if handleallparts:
-                op.records.add(
-                    part.type,
-                    {
-                        b'return': 1,
-                    },
-                )
-            if bundlepart:
-                bundler.addpart(bundlepart)
-
-    # If commits were sent, store them
-    if cgparams:
-        buf = util.chunkbuffer(bundler.getchunks())
-        fd, bundlefile = pycompat.mkstemp()
-        try:
-            try:
-                fp = os.fdopen(fd, 'wb')
-                fp.write(buf.read())
-            finally:
-                fp.close()
-            storebundle(op, cgparams, bundlefile)
-        finally:
-            try:
-                os.unlink(bundlefile)
-            except Exception:
-                # we would rather see the original exception
-                pass
-
-
-def storebundle(op, params, bundlefile):
-    log = _getorcreateinfinitepushlogger(op)
-    parthandlerstart = time.time()
-    log(scratchbranchparttype, eventtype=b'start')
-    index = op.repo.bundlestore.index
-    store = op.repo.bundlestore.store
-    op.records.add(scratchbranchparttype + b'_skippushkey', True)
-
-    bundle = None
-    try:  # guards bundle
-        bundlepath = b"bundle:%s+%s" % (op.repo.root, bundlefile)
-        bundle = hg.repository(op.repo.ui, bundlepath)
-
-        bookmark = params.get(b'bookmark')
-        bookprevnode = params.get(b'bookprevnode', b'')
-        force = params.get(b'force')
-
-        if bookmark:
-            oldnode = index.getnode(bookmark)
-        else:
-            oldnode = None
-        bundleheads = bundle.revs(b'heads(bundle())')
-        if bookmark and len(bundleheads) > 1:
-            raise error.Abort(
-                _(b'cannot push more than one head to a scratch branch')
-            )
-
-        revs = _getrevs(bundle, oldnode, force, bookmark)
-
-        # Notify the user of what is being pushed
-        plural = b's' if len(revs) > 1 else b''
-        op.repo.ui.warn(_(b"pushing %d commit%s:\n") % (len(revs), plural))
-        maxoutput = 10
-        for i in range(0, min(len(revs), maxoutput)):
-            firstline = bundle[revs[i]].description().split(b'\n')[0][:50]
-            op.repo.ui.warn(b"    %s  %s\n" % (revs[i], firstline))
-
-        if len(revs) > maxoutput + 1:
-            op.repo.ui.warn(b"    ...\n")
-            firstline = bundle[revs[-1]].description().split(b'\n')[0][:50]
-            op.repo.ui.warn(b"    %s  %s\n" % (revs[-1], firstline))
-
-        nodesctx = [bundle[rev] for rev in revs]
-        inindex = lambda rev: bool(index.getbundle(bundle[rev].hex()))
-        if bundleheads:
-            newheadscount = sum(not inindex(rev) for rev in bundleheads)
-        else:
-            newheadscount = 0
-        # If there's a bookmark specified, there should be only one head,
-        # so we choose the last node, which will be that head.
-        # If a bug or malicious client allows there to be a bookmark
-        # with multiple heads, we will place the bookmark on the last head.
-        bookmarknode = nodesctx[-1].hex() if nodesctx else None
-        key = None
-        if newheadscount:
-            with open(bundlefile, b'rb') as f:
-                bundledata = f.read()
-                with logservicecall(
-                    log, b'bundlestore', bundlesize=len(bundledata)
-                ):
-                    bundlesizelimit = 100 * 1024 * 1024  # 100 MB
-                    if len(bundledata) > bundlesizelimit:
-                        error_msg = (
-                            b'bundle is too big: %d bytes. '
-                            + b'max allowed size is 100 MB'
-                        )
-                        raise error.Abort(error_msg % (len(bundledata),))
-                    key = store.write(bundledata)
-
-        with logservicecall(log, b'index', newheadscount=newheadscount), index:
-            if key:
-                index.addbundle(key, nodesctx)
-            if bookmark:
-                index.addbookmark(bookmark, bookmarknode)
-                _maybeaddpushbackpart(
-                    op, bookmark, bookmarknode, bookprevnode, params
-                )
-        log(
-            scratchbranchparttype,
-            eventtype=b'success',
-            elapsedms=(time.time() - parthandlerstart) * 1000,
-        )
-
-    except Exception as e:
-        log(
-            scratchbranchparttype,
-            eventtype=b'failure',
-            elapsedms=(time.time() - parthandlerstart) * 1000,
-            errormsg=stringutil.forcebytestr(e),
-        )
-        raise
-    finally:
-        if bundle:
-            bundle.close()
-
-
-@bundle2.parthandler(
-    scratchbranchparttype,
-    (
-        b'bookmark',
-        b'bookprevnode',
-        b'force',
-        b'pushbackbookmarks',
-        b'cgversion',
-    ),
-)
-def bundle2scratchbranch(op, part):
-    '''unbundle a bundle2 part containing a changegroup to store'''
-
-    bundler = bundle2.bundle20(op.repo.ui)
-    cgversion = part.params.get(b'cgversion', b'01')
-    cgpart = bundle2.bundlepart(b'changegroup', data=part.read())
-    cgpart.addparam(b'version', cgversion)
-    bundler.addpart(cgpart)
-    buf = util.chunkbuffer(bundler.getchunks())
-
-    fd, bundlefile = pycompat.mkstemp()
-    try:
-        try:
-            fp = os.fdopen(fd, 'wb')
-            fp.write(buf.read())
-        finally:
-            fp.close()
-        storebundle(op, part.params, bundlefile)
-    finally:
-        try:
-            os.unlink(bundlefile)
-        except FileNotFoundError:
-            pass
-
-    return 1
-
-
-def _maybeaddpushbackpart(op, bookmark, newnode, oldnode, params):
-    if params.get(b'pushbackbookmarks'):
-        if op.reply and b'pushback' in op.reply.capabilities:
-            params = {
-                b'namespace': b'bookmarks',
-                b'key': bookmark,
-                b'new': newnode,
-                b'old': oldnode,
-            }
-            op.reply.newpart(b'pushkey', mandatoryparams=params.items())
-
-
-def bundle2pushkey(orig, op, part):
-    """Wrapper of bundle2.handlepushkey()
-
-    The only goal is to skip calling the original function if flag is set.
-    It's set if infinitepush push is happening.
-    """
-    if op.records[scratchbranchparttype + b'_skippushkey']:
-        if op.reply is not None:
-            rpart = op.reply.newpart(b'reply:pushkey')
-            rpart.addparam(b'in-reply-to', str(part.id), mandatory=False)
-            rpart.addparam(b'return', b'1', mandatory=False)
-        return 1
-
-    return orig(op, part)
-
-
-def bundle2handlephases(orig, op, part):
-    """Wrapper of bundle2.handlephases()
-
-    The only goal is to skip calling the original function if flag is set.
-    It's set if infinitepush push is happening.
-    """
-
-    if op.records[scratchbranchparttype + b'_skipphaseheads']:
-        return
-
-    return orig(op, part)
-
-
-def _asyncsavemetadata(root, nodes):
-    """starts a separate process that fills metadata for the nodes
-
-    This function creates a separate process and doesn't wait for it's
-    completion. This was done to avoid slowing down pushes
-    """
-
-    maxnodes = 50
-    if len(nodes) > maxnodes:
-        return
-    nodesargs = []
-    for node in nodes:
-        nodesargs.append(b'--node')
-        nodesargs.append(node)
-    with open(os.devnull, b'w+b') as devnull:
-        cmdline = [
-            util.hgexecutable(),
-            b'debugfillinfinitepushmetadata',
-            b'-R',
-            root,
-        ] + nodesargs
-        # Process will run in background. We don't care about the return code
-        subprocess.Popen(
-            pycompat.rapply(procutil.tonativestr, cmdline),
-            close_fds=True,
-            shell=False,
-            stdin=devnull,
-            stdout=devnull,
-            stderr=devnull,
-        )
--- a/hgext/infinitepush/bundleparts.py	Fri Jun 23 13:27:09 2023 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,126 +0,0 @@
-# Copyright 2017 Facebook, Inc.
-#
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2 or any later version.
-
-
-from mercurial.i18n import _
-from mercurial.node import hex
-
-from mercurial import (
-    bundle2,
-    changegroup,
-    error,
-    extensions,
-    revsetlang,
-    util,
-)
-
-from . import common
-
-isremotebooksenabled = common.isremotebooksenabled
-
-scratchbranchparttype = b'b2x:infinitepush'
-
-
-def getscratchbranchparts(repo, peer, outgoing, ui, bookmark):
-    if not outgoing.missing:
-        raise error.Abort(_(b'no commits to push'))
-
-    if scratchbranchparttype not in bundle2.bundle2caps(peer):
-        raise error.Abort(
-            _(b'no server support for %r') % scratchbranchparttype
-        )
-
-    _validaterevset(
-        repo, revsetlang.formatspec(b'%ln', outgoing.missing), bookmark
-    )
-
-    supportedversions = changegroup.supportedoutgoingversions(repo)
-    # Explicitly avoid using '01' changegroup version in infinitepush to
-    # support general delta
-    supportedversions.discard(b'01')
-    cgversion = min(supportedversions)
-    _handlelfs(repo, outgoing.missing)
-    cg = changegroup.makestream(repo, outgoing, cgversion, b'push')
-
-    params = {}
-    params[b'cgversion'] = cgversion
-    if bookmark:
-        params[b'bookmark'] = bookmark
-        # 'prevbooknode' is necessary for pushkey reply part
-        params[b'bookprevnode'] = b''
-        bookmarks = repo._bookmarks
-        if bookmark in bookmarks:
-            params[b'bookprevnode'] = hex(bookmarks[bookmark])
-
-    # Do not send pushback bundle2 part with bookmarks if remotenames extension
-    # is enabled. It will be handled manually in `_push()`
-    if not isremotebooksenabled(ui):
-        params[b'pushbackbookmarks'] = b'1'
-
-    parts = []
-
-    # .upper() marks this as a mandatory part: server will abort if there's no
-    #  handler
-    parts.append(
-        bundle2.bundlepart(
-            scratchbranchparttype.upper(),
-            advisoryparams=params.items(),
-            data=cg,
-        )
-    )
-
-    return parts
-
-
-def _validaterevset(repo, revset, bookmark):
-    """Abort if the revs to be pushed aren't valid for a scratch branch."""
-    if not repo.revs(revset):
-        raise error.Abort(_(b'nothing to push'))
-    if bookmark:
-        # Allow bundle with many heads only if no bookmark is specified
-        heads = repo.revs(b'heads(%r)', revset)
-        if len(heads) > 1:
-            raise error.Abort(
-                _(b'cannot push more than one head to a scratch branch')
-            )
-
-
-def _handlelfs(repo, missing):
-    """Special case if lfs is enabled
-
-    If lfs is enabled then we need to call prepush hook
-    to make sure large files are uploaded to lfs
-    """
-    try:
-        lfsmod = extensions.find(b'lfs')
-        lfsmod.wrapper.uploadblobsfromrevs(repo, missing)
-    except KeyError:
-        # Ignore if lfs extension is not enabled
-        return
-
-
-class copiedpart:
-    """a copy of unbundlepart content that can be consumed later"""
-
-    def __init__(self, part):
-        # copy "public properties"
-        self.type = part.type
-        self.id = part.id
-        self.mandatory = part.mandatory
-        self.mandatoryparams = part.mandatoryparams
-        self.advisoryparams = part.advisoryparams
-        self.params = part.params
-        self.mandatorykeys = part.mandatorykeys
-        # copy the buffer
-        self._io = util.stringio(part.read())
-
-    def consume(self):
-        return
-
-    def read(self, size=None):
-        if size is None:
-            return self._io.read()
-        else:
-            return self._io.read(size)
--- a/hgext/infinitepush/common.py	Fri Jun 23 13:27:09 2023 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
-# Copyright 2017 Facebook, Inc.
-#
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2 or any later version.
-
-
-import os
-
-from mercurial.node import hex
-
-from mercurial import (
-    error,
-    extensions,
-    pycompat,
-)
-
-
-def isremotebooksenabled(ui):
-    return b'remotenames' in extensions._extensions and ui.configbool(
-        b'remotenames', b'bookmarks'
-    )
-
-
-def downloadbundle(repo, unknownbinhead):
-    index = repo.bundlestore.index
-    store = repo.bundlestore.store
-    bundleid = index.getbundle(hex(unknownbinhead))
-    if bundleid is None:
-        raise error.Abort(b'%s head is not known' % hex(unknownbinhead))
-    bundleraw = store.read(bundleid)
-    return _makebundlefromraw(bundleraw)
-
-
-def _makebundlefromraw(data):
-    fp = None
-    fd, bundlefile = pycompat.mkstemp()
-    try:  # guards bundlefile
-        try:  # guards fp
-            fp = os.fdopen(fd, 'wb')
-            fp.write(data)
-        finally:
-            fp.close()
-    except Exception:
-        try:
-            os.unlink(bundlefile)
-        except Exception:
-            # we would rather see the original exception
-            pass
-        raise
-
-    return bundlefile
--- a/hgext/infinitepush/fileindexapi.py	Fri Jun 23 13:27:09 2023 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,110 +0,0 @@
-# Infinite push
-#
-# Copyright 2016 Facebook, Inc.
-#
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2 or any later version.
-"""
-    [infinitepush]
-    # Server-side option. Used only if indextype=disk.
-    # Filesystem path to the index store
-    indexpath = PATH
-"""
-
-
-import os
-
-from mercurial import util
-
-from mercurial.utils import stringutil
-
-from . import indexapi
-
-
-class fileindexapi(indexapi.indexapi):
-    def __init__(self, repo):
-        super(fileindexapi, self).__init__()
-        self._repo = repo
-        root = repo.ui.config(b'infinitepush', b'indexpath')
-        if not root:
-            root = os.path.join(b'scratchbranches', b'index')
-
-        self._nodemap = os.path.join(root, b'nodemap')
-        self._bookmarkmap = os.path.join(root, b'bookmarkmap')
-        self._metadatamap = os.path.join(root, b'nodemetadatamap')
-        self._lock = None
-
-    def __enter__(self):
-        self._lock = self._repo.wlock()
-        return self
-
-    def __exit__(self, exc_type, exc_val, exc_tb):
-        if self._lock:
-            self._lock.__exit__(exc_type, exc_val, exc_tb)
-
-    def addbundle(self, bundleid, nodesctx):
-        for node in nodesctx:
-            nodepath = os.path.join(self._nodemap, node.hex())
-            self._write(nodepath, bundleid)
-
-    def addbookmark(self, bookmark, node):
-        bookmarkpath = os.path.join(self._bookmarkmap, bookmark)
-        self._write(bookmarkpath, node)
-
-    def addmanybookmarks(self, bookmarks):
-        for bookmark, node in bookmarks.items():
-            self.addbookmark(bookmark, node)
-
-    def deletebookmarks(self, patterns):
-        for pattern in patterns:
-            for bookmark, _ in self._listbookmarks(pattern):
-                bookmarkpath = os.path.join(self._bookmarkmap, bookmark)
-                self._delete(bookmarkpath)
-
-    def getbundle(self, node):
-        nodepath = os.path.join(self._nodemap, node)
-        return self._read(nodepath)
-
-    def getnode(self, bookmark):
-        bookmarkpath = os.path.join(self._bookmarkmap, bookmark)
-        return self._read(bookmarkpath)
-
-    def getbookmarks(self, query):
-        return dict(self._listbookmarks(query))
-
-    def saveoptionaljsonmetadata(self, node, jsonmetadata):
-        vfs = self._repo.vfs
-        vfs.write(os.path.join(self._metadatamap, node), jsonmetadata)
-
-    def _listbookmarks(self, pattern):
-        if pattern.endswith(b'*'):
-            pattern = b're:^' + pattern[:-1] + b'.*'
-        kind, pat, matcher = stringutil.stringmatcher(pattern)
-        prefixlen = len(self._bookmarkmap) + 1
-        for dirpath, _, books in self._repo.vfs.walk(self._bookmarkmap):
-            for book in books:
-                bookmark = os.path.join(dirpath, book)[prefixlen:]
-                bookmark = util.pconvert(bookmark)
-                if not matcher(bookmark):
-                    continue
-                yield bookmark, self._read(os.path.join(dirpath, book))
-
-    def _write(self, path, value):
-        vfs = self._repo.vfs
-        dirname = vfs.dirname(path)
-        if not vfs.exists(dirname):
-            vfs.makedirs(dirname)
-
-        vfs.write(path, value)
-
-    def _read(self, path):
-        vfs = self._repo.vfs
-        if not vfs.exists(path):
-            return None
-        return vfs.read(path)
-
-    def _delete(self, path):
-        vfs = self._repo.vfs
-        if not vfs.exists(path):
-            return
-        return vfs.unlink(path)
--- a/hgext/infinitepush/indexapi.py	Fri Jun 23 13:27:09 2023 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-# Infinite push
-#
-# Copyright 2016 Facebook, Inc.
-#
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2 or any later version.
-
-
-class indexapi:
-    """Class that manages access to infinitepush index.
-
-    This class is a context manager and all write operations (like
-    deletebookmarks, addbookmark etc) should use `with` statement:
-
-      with index:
-          index.deletebookmarks(...)
-          ...
-    """
-
-    def __init__(self):
-        """Initializes the metadata store connection."""
-
-    def close(self):
-        """Cleans up the metadata store connection."""
-
-    def __enter__(self):
-        return self
-
-    def __exit__(self, exc_type, exc_val, exc_tb):
-        pass
-
-    def addbundle(self, bundleid, nodesctx):
-        """Takes a bundleid and a list of node contexts for each node
-        in that bundle and records that."""
-        raise NotImplementedError()
-
-    def addbookmark(self, bookmark, node):
-        """Takes a bookmark name and hash, and records mapping in the metadata
-        store."""
-        raise NotImplementedError()
-
-    def addmanybookmarks(self, bookmarks):
-        """Takes a dict with mapping from bookmark to hash and records mapping
-        in the metadata store."""
-        raise NotImplementedError()
-
-    def deletebookmarks(self, patterns):
-        """Accepts list of bookmarks and deletes them."""
-        raise NotImplementedError()
-
-    def getbundle(self, node):
-        """Returns the bundleid for the bundle that contains the given node."""
-        raise NotImplementedError()
-
-    def getnode(self, bookmark):
-        """Returns the node for the given bookmark. None if it doesn't exist."""
-        raise NotImplementedError()
-
-    def getbookmarks(self, query):
-        """Returns bookmarks that match the query"""
-        raise NotImplementedError()
-
-    def saveoptionaljsonmetadata(self, node, jsonmetadata):
-        """Saves optional metadata for a given node"""
-        raise NotImplementedError()
-
-
-class indexexception(Exception):
-    pass
--- a/hgext/infinitepush/schema.sql	Fri Jun 23 13:27:09 2023 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-CREATE TABLE `bookmarkstonode` (
-  `node` varbinary(64) NOT NULL,
-  `bookmark` varbinary(512) NOT NULL,
-  `reponame` varbinary(255) NOT NULL,
-  PRIMARY KEY (`reponame`,`bookmark`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-
-CREATE TABLE `bundles` (
-  `bundle` varbinary(512) NOT NULL,
-  `reponame` varbinary(255) NOT NULL,
-  PRIMARY KEY (`bundle`,`reponame`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-
-CREATE TABLE `nodestobundle` (
-  `node` varbinary(64) NOT NULL,
-  `bundle` varbinary(512) NOT NULL,
-  `reponame` varbinary(255) NOT NULL,
-  PRIMARY KEY (`node`,`reponame`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-
-CREATE TABLE `nodesmetadata` (
-  `node` varbinary(64) NOT NULL,
-  `message` mediumblob NOT NULL,
-  `p1` varbinary(64) NOT NULL,
-  `p2` varbinary(64) DEFAULT NULL,
-  `author` varbinary(255) NOT NULL,
-  `committer` varbinary(255) DEFAULT NULL,
-  `author_date` bigint(20) NOT NULL,
-  `committer_date` bigint(20) DEFAULT NULL,
-  `reponame` varbinary(255) NOT NULL,
-  `optional_json_metadata` mediumblob,
-  PRIMARY KEY (`reponame`,`node`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--- a/hgext/infinitepush/sqlindexapi.py	Fri Jun 23 13:27:09 2023 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,295 +0,0 @@
-# Infinite push
-#
-# Copyright 2016 Facebook, Inc.
-#
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2 or any later version.
-
-
-import logging
-import os
-import time
-
-import warnings
-import mysql.connector
-
-from . import indexapi
-
-
-def _convertbookmarkpattern(pattern):
-    pattern = pattern.replace(b'_', b'\\_')
-    pattern = pattern.replace(b'%', b'\\%')
-    if pattern.endswith(b'*'):
-        pattern = pattern[:-1] + b'%'
-    return pattern
-
-
-class sqlindexapi(indexapi.indexapi):
-    """
-    Sql backend for infinitepush index. See schema.sql
-    """
-
-    def __init__(
-        self,
-        reponame,
-        host,
-        port,
-        database,
-        user,
-        password,
-        logfile,
-        loglevel,
-        waittimeout=300,
-        locktimeout=120,
-    ):
-        super(sqlindexapi, self).__init__()
-        self.reponame = reponame
-        self.sqlargs = {
-            b'host': host,
-            b'port': port,
-            b'database': database,
-            b'user': user,
-            b'password': password,
-        }
-        self.sqlconn = None
-        self.sqlcursor = None
-        if not logfile:
-            logfile = os.devnull
-        logging.basicConfig(filename=logfile)
-        self.log = logging.getLogger()
-        self.log.setLevel(loglevel)
-        self._connected = False
-        self._waittimeout = waittimeout
-        self._locktimeout = locktimeout
-
-    def sqlconnect(self):
-        if self.sqlconn:
-            raise indexapi.indexexception(b"SQL connection already open")
-        if self.sqlcursor:
-            raise indexapi.indexexception(
-                b"SQL cursor already open without connection"
-            )
-        retry = 3
-        while True:
-            try:
-                self.sqlconn = mysql.connector.connect(**self.sqlargs)
-
-                # Code is copy-pasted from hgsql. Bug fixes need to be
-                # back-ported!
-                # The default behavior is to return byte arrays, when we
-                # need strings. This custom convert returns strings.
-                self.sqlconn.set_converter_class(CustomConverter)
-                self.sqlconn.autocommit = False
-                break
-            except mysql.connector.errors.Error:
-                # mysql can be flakey occasionally, so do some minimal
-                # retrying.
-                retry -= 1
-                if retry == 0:
-                    raise
-                time.sleep(0.2)
-
-        waittimeout = self.sqlconn.converter.escape(b'%s' % self._waittimeout)
-
-        self.sqlcursor = self.sqlconn.cursor()
-        self.sqlcursor.execute(b"SET wait_timeout=%s" % waittimeout)
-        self.sqlcursor.execute(
-            b"SET innodb_lock_wait_timeout=%s" % self._locktimeout
-        )
-        self._connected = True
-
-    def close(self):
-        """Cleans up the metadata store connection."""
-        with warnings.catch_warnings():
-            warnings.simplefilter(b"ignore")
-            self.sqlcursor.close()
-            self.sqlconn.close()
-        self.sqlcursor = None
-        self.sqlconn = None
-
-    def __enter__(self):
-        if not self._connected:
-            self.sqlconnect()
-        return self
-
-    def __exit__(self, exc_type, exc_val, exc_tb):
-        if exc_type is None:
-            self.sqlconn.commit()
-        else:
-            self.sqlconn.rollback()
-
-    def addbundle(self, bundleid, nodesctx):
-        if not self._connected:
-            self.sqlconnect()
-        self.log.info(b"ADD BUNDLE %r %r" % (self.reponame, bundleid))
-        self.sqlcursor.execute(
-            b"INSERT INTO bundles(bundle, reponame) VALUES (%s, %s)",
-            params=(bundleid, self.reponame),
-        )
-        for ctx in nodesctx:
-            self.sqlcursor.execute(
-                b"INSERT INTO nodestobundle(node, bundle, reponame) "
-                b"VALUES (%s, %s, %s) ON DUPLICATE KEY UPDATE "
-                b"bundle=VALUES(bundle)",
-                params=(ctx.hex(), bundleid, self.reponame),
-            )
-
-            extra = ctx.extra()
-            author_name = ctx.user()
-            committer_name = extra.get(b'committer', ctx.user())
-            author_date = int(ctx.date()[0])
-            committer_date = int(extra.get(b'committer_date', author_date))
-            self.sqlcursor.execute(
-                b"INSERT IGNORE INTO nodesmetadata(node, message, p1, p2, "
-                b"author, committer, author_date, committer_date, "
-                b"reponame) VALUES "
-                b"(%s, %s, %s, %s, %s, %s, %s, %s, %s)",
-                params=(
-                    ctx.hex(),
-                    ctx.description(),
-                    ctx.p1().hex(),
-                    ctx.p2().hex(),
-                    author_name,
-                    committer_name,
-                    author_date,
-                    committer_date,
-                    self.reponame,
-                ),
-            )
-
-    def addbookmark(self, bookmark, node):
-        """Takes a bookmark name and hash, and records mapping in the metadata
-        store."""
-        if not self._connected:
-            self.sqlconnect()
-        self.log.info(
-            b"ADD BOOKMARKS %r bookmark: %r node: %r"
-            % (self.reponame, bookmark, node)
-        )
-        self.sqlcursor.execute(
-            b"INSERT INTO bookmarkstonode(bookmark, node, reponame) "
-            b"VALUES (%s, %s, %s) ON DUPLICATE KEY UPDATE node=VALUES(node)",
-            params=(bookmark, node, self.reponame),
-        )
-
-    def addmanybookmarks(self, bookmarks):
-        if not self._connected:
-            self.sqlconnect()
-        args = []
-        values = []
-        for bookmark, node in bookmarks.items():
-            args.append(b'(%s, %s, %s)')
-            values.extend((bookmark, node, self.reponame))
-        args = b','.join(args)
-
-        self.sqlcursor.execute(
-            b"INSERT INTO bookmarkstonode(bookmark, node, reponame) "
-            b"VALUES %s ON DUPLICATE KEY UPDATE node=VALUES(node)" % args,
-            params=values,
-        )
-
-    def deletebookmarks(self, patterns):
-        """Accepts list of bookmark patterns and deletes them.
-        If `commit` is set then bookmark will actually be deleted. Otherwise
-        deletion will be delayed until the end of transaction.
-        """
-        if not self._connected:
-            self.sqlconnect()
-        self.log.info(b"DELETE BOOKMARKS: %s" % patterns)
-        for pattern in patterns:
-            pattern = _convertbookmarkpattern(pattern)
-            self.sqlcursor.execute(
-                b"DELETE from bookmarkstonode WHERE bookmark LIKE (%s) "
-                b"and reponame = %s",
-                params=(pattern, self.reponame),
-            )
-
-    def getbundle(self, node):
-        """Returns the bundleid for the bundle that contains the given node."""
-        if not self._connected:
-            self.sqlconnect()
-        self.log.info(b"GET BUNDLE %r %r" % (self.reponame, node))
-        self.sqlcursor.execute(
-            b"SELECT bundle from nodestobundle "
-            b"WHERE node = %s AND reponame = %s",
-            params=(node, self.reponame),
-        )
-        result = self.sqlcursor.fetchall()
-        if len(result) != 1 or len(result[0]) != 1:
-            self.log.info(b"No matching node")
-            return None
-        bundle = result[0][0]
-        self.log.info(b"Found bundle %r" % bundle)
-        return bundle
-
-    def getnode(self, bookmark):
-        """Returns the node for the given bookmark. None if it doesn't exist."""
-        if not self._connected:
-            self.sqlconnect()
-        self.log.info(
-            b"GET NODE reponame: %r bookmark: %r" % (self.reponame, bookmark)
-        )
-        self.sqlcursor.execute(
-            b"SELECT node from bookmarkstonode WHERE "
-            b"bookmark = %s AND reponame = %s",
-            params=(bookmark, self.reponame),
-        )
-        result = self.sqlcursor.fetchall()
-        if len(result) != 1 or len(result[0]) != 1:
-            self.log.info(b"No matching bookmark")
-            return None
-        node = result[0][0]
-        self.log.info(b"Found node %r" % node)
-        return node
-
-    def getbookmarks(self, query):
-        if not self._connected:
-            self.sqlconnect()
-        self.log.info(
-            b"QUERY BOOKMARKS reponame: %r query: %r" % (self.reponame, query)
-        )
-        query = _convertbookmarkpattern(query)
-        self.sqlcursor.execute(
-            b"SELECT bookmark, node from bookmarkstonode WHERE "
-            b"reponame = %s AND bookmark LIKE %s",
-            params=(self.reponame, query),
-        )
-        result = self.sqlcursor.fetchall()
-        bookmarks = {}
-        for row in result:
-            if len(row) != 2:
-                self.log.info(b"Bad row returned: %s" % row)
-                continue
-            bookmarks[row[0]] = row[1]
-        return bookmarks
-
-    def saveoptionaljsonmetadata(self, node, jsonmetadata):
-        if not self._connected:
-            self.sqlconnect()
-        self.log.info(
-            (
-                b"INSERT METADATA, QUERY BOOKMARKS reponame: %r "
-                + b"node: %r, jsonmetadata: %s"
-            )
-            % (self.reponame, node, jsonmetadata)
-        )
-
-        self.sqlcursor.execute(
-            b"UPDATE nodesmetadata SET optional_json_metadata=%s WHERE "
-            b"reponame=%s AND node=%s",
-            params=(jsonmetadata, self.reponame, node),
-        )
-
-
-class CustomConverter(mysql.connector.conversion.MySQLConverter):
-    """Ensure that all values being returned are returned as python string
-    (versus the default byte arrays)."""
-
-    def _STRING_to_python(self, value, dsc=None):
-        return str(value)
-
-    def _VAR_STRING_to_python(self, value, dsc=None):
-        return str(value)
-
-    def _BLOB_to_python(self, value, dsc=None):
-        return str(value)
--- a/hgext/infinitepush/store.py	Fri Jun 23 13:27:09 2023 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,194 +0,0 @@
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2 or any later version.
-
-# based on bundleheads extension by Gregory Szorc <gps@mozilla.com>
-
-
-import abc
-import os
-import subprocess
-
-from mercurial.node import hex
-from mercurial.pycompat import open
-from mercurial import pycompat
-from mercurial.utils import (
-    hashutil,
-    procutil,
-)
-
-
-class BundleWriteException(Exception):
-    pass
-
-
-class BundleReadException(Exception):
-    pass
-
-
-class abstractbundlestore:  # pytype: disable=ignored-metaclass
-    """Defines the interface for bundle stores.
-
-    A bundle store is an entity that stores raw bundle data. It is a simple
-    key-value store. However, the keys are chosen by the store. The keys can
-    be any Python object understood by the corresponding bundle index (see
-    ``abstractbundleindex`` below).
-    """
-
-    __metaclass__ = abc.ABCMeta
-
-    @abc.abstractmethod
-    def write(self, data):
-        """Write bundle data to the store.
-
-        This function receives the raw data to be written as a str.
-        Throws BundleWriteException
-        The key of the written data MUST be returned.
-        """
-
-    @abc.abstractmethod
-    def read(self, key):
-        """Obtain bundle data for a key.
-
-        Returns None if the bundle isn't known.
-        Throws BundleReadException
-        The returned object should be a file object supporting read()
-        and close().
-        """
-
-
-class filebundlestore:
-    """bundle store in filesystem
-
-    meant for storing bundles somewhere on disk and on network filesystems
-    """
-
-    def __init__(self, ui, repo):
-        self.ui = ui
-        self.repo = repo
-        self.storepath = ui.configpath(b'scratchbranch', b'storepath')
-        if not self.storepath:
-            self.storepath = self.repo.vfs.join(
-                b"scratchbranches", b"filebundlestore"
-            )
-        if not os.path.exists(self.storepath):
-            os.makedirs(self.storepath)
-
-    def _dirpath(self, hashvalue):
-        """First two bytes of the hash are the name of the upper
-        level directory, next two bytes are the name of the
-        next level directory"""
-        return os.path.join(self.storepath, hashvalue[0:2], hashvalue[2:4])
-
-    def _filepath(self, filename):
-        return os.path.join(self._dirpath(filename), filename)
-
-    def write(self, data):
-        filename = hex(hashutil.sha1(data).digest())
-        dirpath = self._dirpath(filename)
-
-        if not os.path.exists(dirpath):
-            os.makedirs(dirpath)
-
-        with open(self._filepath(filename), b'wb') as f:
-            f.write(data)
-
-        return filename
-
-    def read(self, key):
-        try:
-            with open(self._filepath(key), b'rb') as f:
-                return f.read()
-        except IOError:
-            return None
-
-
-def format_placeholders_args(args, filename=None, handle=None):
-    """Formats `args` with Infinitepush replacements.
-
-    Hack to get `str.format()`-ed strings working in a BC way with
-    bytes.
-    """
-    formatted_args = []
-    for arg in args:
-        if filename and arg == b'{filename}':
-            formatted_args.append(filename)
-        elif handle and arg == b'{handle}':
-            formatted_args.append(handle)
-        else:
-            formatted_args.append(arg)
-    return formatted_args
-
-
-class externalbundlestore(abstractbundlestore):
-    def __init__(self, put_binary, put_args, get_binary, get_args):
-        """
-        `put_binary` - path to binary file which uploads bundle to external
-            storage and prints key to stdout
-        `put_args` - format string with additional args to `put_binary`
-                     {filename} replacement field can be used.
-        `get_binary` - path to binary file which accepts filename and key
-            (in that order), downloads bundle from store and saves it to file
-        `get_args` - format string with additional args to `get_binary`.
-                     {filename} and {handle} replacement field can be used.
-        """
-
-        self.put_args = put_args
-        self.get_args = get_args
-        self.put_binary = put_binary
-        self.get_binary = get_binary
-
-    def _call_binary(self, args):
-        p = subprocess.Popen(
-            pycompat.rapply(procutil.tonativestr, args),
-            stdout=subprocess.PIPE,
-            stderr=subprocess.PIPE,
-            close_fds=True,
-        )
-        stdout, stderr = p.communicate()
-        returncode = p.returncode
-        return returncode, stdout, stderr
-
-    def write(self, data):
-        # Won't work on windows because you can't open file second time without
-        # closing it
-        # TODO: rewrite without str.format() and replace NamedTemporaryFile()
-        # with pycompat.namedtempfile()
-        with pycompat.namedtempfile() as temp:
-            temp.write(data)
-            temp.flush()
-            temp.seek(0)
-            formatted_args = format_placeholders_args(
-                self.put_args, filename=temp.name
-            )
-            returncode, stdout, stderr = self._call_binary(
-                [self.put_binary] + formatted_args
-            )
-
-            if returncode != 0:
-                raise BundleWriteException(
-                    b'Failed to upload to external store: %s' % stderr
-                )
-            stdout_lines = stdout.splitlines()
-            if len(stdout_lines) == 1:
-                return stdout_lines[0]
-            else:
-                raise BundleWriteException(
-                    b'Bad output from %s: %s' % (self.put_binary, stdout)
-                )
-
-    def read(self, handle):
-        # Won't work on windows because you can't open file second time without
-        # closing it
-        with pycompat.namedtempfile() as temp:
-            formatted_args = format_placeholders_args(
-                self.get_args, filename=temp.name, handle=handle
-            )
-            returncode, stdout, stderr = self._call_binary(
-                [self.get_binary] + formatted_args
-            )
-
-            if returncode != 0:
-                raise BundleReadException(
-                    b'Failed to download from external store: %s' % stderr
-                )
-            return temp.read()
--- a/hgext/lfs/wrapper.py	Fri Jun 23 13:27:09 2023 +0200
+++ b/hgext/lfs/wrapper.py	Fri Jul 21 03:56:28 2023 +0200
@@ -383,10 +383,7 @@
 
 
 def uploadblobsfromrevs(repo, revs):
-    """upload lfs blobs introduced by revs
-
-    Note: also used by other extensions e. g. infinitepush. avoid renaming.
-    """
+    """upload lfs blobs introduced by revs"""
     if _canskipupload(repo):
         return
     pointers = extractpointers(repo, revs)
--- a/i18n/ja.po	Fri Jun 23 13:27:09 2023 +0200
+++ b/i18n/ja.po	Fri Jul 21 03:56:28 2023 +0200
@@ -5875,13 +5875,6 @@
 msgstr "共有元情報を相対パスで保持 (実験的実装)"
 
 msgid ""
-"    [infinitepush]\n"
-"    # Server-side and client-side option. Pattern of the infinitepush "
-"bookmark\n"
-"    branchpattern = PATTERN"
-msgstr ""
-
-msgid ""
 "    # Server or client\n"
 "    server = False"
 msgstr ""
@@ -5973,12 +5966,6 @@
 msgstr ""
 
 msgid ""
-"    # Instructs infinitepush to forward all received bundle2 parts to the\n"
-"    # bundle for storage. Defaults to False.\n"
-"    storeallparts = True"
-msgstr ""
-
-msgid ""
 "    # routes each incoming push to the bundlestore. defaults to False\n"
 "    pushtobundlestore = True"
 msgstr ""
@@ -5991,24 +5978,10 @@
 "    bookmarks = True\n"
 msgstr ""
 
-msgid "please set infinitepush.sqlhost"
-msgstr ""
-
-msgid "please set infinitepush.reponame"
-msgstr ""
-
 #, fuzzy, python-format
 msgid "invalid log level %s"
 msgstr "不正なローカルアドレス: %s"
 
-#, fuzzy, python-format
-msgid "unknown infinitepush store type specified %s"
-msgstr "--type に未知のバンドル種別が指定されました"
-
-#, fuzzy, python-format
-msgid "unknown infinitepush index type specified %s"
-msgstr "--type に未知のバンドル種別が指定されました"
-
 #, fuzzy
 msgid "force push to go to bundle store (EXPERIMENTAL)"
 msgstr "表示対象リビジョン"
@@ -6019,10 +5992,6 @@
 msgid "see 'hg help config.paths'"
 msgstr "詳細は 'hg help config.paths' 参照"
 
-#, fuzzy
-msgid "infinitepush bookmark '{}' does not exist in path '{}'"
-msgstr "ブックマーク '%s' は存在しません"
-
 msgid "no changes found\n"
 msgstr "差分はありません\n"
 
--- a/i18n/pt_BR.po	Fri Jun 23 13:27:09 2023 +0200
+++ b/i18n/pt_BR.po	Fri Jul 21 03:56:28 2023 +0200
@@ -5940,12 +5940,6 @@
 msgstr ""
 
 msgid ""
-"    [infinitepush]\n"
-"    # Server-side and client-side option. Pattern of the infinitepush bookmark\n"
-"    branchpattern = PATTERN"
-msgstr ""
-
-msgid ""
 "    # Server or client\n"
 "    server = False"
 msgstr ""
@@ -6034,12 +6028,6 @@
 msgstr ""
 
 msgid ""
-"    # Instructs infinitepush to forward all received bundle2 parts to the\n"
-"    # bundle for storage. Defaults to False.\n"
-"    storeallparts = True"
-msgstr ""
-
-msgid ""
 "    # routes each incoming push to the bundlestore. defaults to False\n"
 "    pushtobundlestore = True"
 msgstr ""
@@ -6052,24 +6040,10 @@
 "    bookmarks = True\n"
 msgstr ""
 
-msgid "please set infinitepush.sqlhost"
-msgstr ""
-
-msgid "please set infinitepush.reponame"
-msgstr ""
-
 #, python-format
 msgid "invalid log level %s"
 msgstr ""
 
-#, python-format
-msgid "unknown infinitepush store type specified %s"
-msgstr ""
-
-#, python-format
-msgid "unknown infinitepush index type specified %s"
-msgstr ""
-
 msgid "force push to go to bundle store (EXPERIMENTAL)"
 msgstr ""
 
@@ -6079,9 +6053,6 @@
 msgid "see 'hg help config.paths'"
 msgstr "veja 'hg help config.paths'"
 
-msgid "infinitepush bookmark '{}' does not exist in path '{}'"
-msgstr ""
-
 msgid "no changes found\n"
 msgstr "nenhuma alteração encontrada\n"
 
--- a/relnotes/next	Fri Jun 23 13:27:09 2023 +0200
+++ b/relnotes/next	Fri Jul 21 03:56:28 2023 +0200
@@ -13,6 +13,8 @@
 
 == Backwards Compatibility Changes ==
 
+* remove the experimental infinite push extension
+
 == Internal API Changes ==
 
 == Miscellaneous ==
--- a/setup.py	Fri Jun 23 13:27:09 2023 +0200
+++ b/setup.py	Fri Jul 21 03:56:28 2023 +0200
@@ -1321,7 +1321,6 @@
     'hgext.git',
     'hgext.highlight',
     'hgext.hooklib',
-    'hgext.infinitepush',
     'hgext.largefiles',
     'hgext.lfs',
     'hgext.narrow',
--- a/tests/library-infinitepush.sh	Fri Jun 23 13:27:09 2023 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-scratchnodes() {
-  for node in `find ../repo/.hg/scratchbranches/index/nodemap/* | sort`; do
-     echo ${node##*/} `cat $node`
-  done
-}
-
-scratchbookmarks() {
-  for bookmark in `find ../repo/.hg/scratchbranches/index/bookmarkmap/* -type f | sort`; do
-     echo "${bookmark##*/bookmarkmap/} `cat $bookmark`"
-  done
-}
-
-setupcommon() {
-  cat >> $HGRCPATH << EOF
-[extensions]
-infinitepush=
-[infinitepush]
-branchpattern=re:scratch/.*
-deprecation-abort=no
-deprecation-message=yes
-
-EOF
-}
-
-setupserver() {
-cat >> .hg/hgrc << EOF
-[infinitepush]
-server=yes
-indextype=disk
-storetype=disk
-reponame=babar
-EOF
-}
--- a/tests/test-check-py3-compat.t	Fri Jun 23 13:27:09 2023 +0200
+++ b/tests/test-check-py3-compat.t	Fri Jul 21 03:56:28 2023 +0200
@@ -10,7 +10,6 @@
   > | sed 's|\\|/|g' | xargs "$PYTHON" contrib/check-py3-compat.py \
   > | sed 's/[0-9][0-9]*)$/*)/'
   hgext/convert/transport.py: error importing: <*Error> No module named 'svn.client' (error at transport.py:*) (glob) (?)
-  hgext/infinitepush/sqlindexapi.py: error importing: <*Error> No module named 'mysql' (error at sqlindexapi.py:*) (glob) (?)
   mercurial/scmwindows.py: error importing: <ValueError> _type_ 'v' not supported (error at win32.py:*) (no-windows !)
   mercurial/win32.py: error importing: <ValueError> _type_ 'v' not supported (error at win32.py:*) (no-windows !)
   mercurial/windows.py: error importing: <*Error> No module named 'msvcrt' (error at windows.py:*) (glob) (no-windows !)
--- a/tests/test-infinitepush-bundlestore.t	Fri Jun 23 13:27:09 2023 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,755 +0,0 @@
-#require no-reposimplestore no-chg
-
-XXX-CHG this test hangs if `hg` is really `chg`. This was hidden by the use of
-`alias hg=chg` by run-tests.py. With such alias removed, this test is revealed
-buggy. This need to be resolved sooner than later.
-
-
-Testing infinipush extension and the confi options provided by it
-
-Create an ondisk bundlestore in .hg/scratchbranches
-  $ . "$TESTDIR/library-infinitepush.sh"
-  $ cp $HGRCPATH $TESTTMP/defaulthgrc
-  $ setupcommon
-  $ mkcommit() {
-  >    echo "$1" > "$1"
-  >    hg add "$1"
-  >    hg ci -m "$1"
-  > }
-  $ hg init repo
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  $ cd repo
-
-Check that we can send a scratch on the server and it does not show there in
-the history but is stored on disk
-  $ setupserver
-  $ cd ..
-  $ hg clone ssh://user@dummy/repo client -q
-  remote: IMPORTANT: if you use this extension, please contact
-  remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  remote: unused and barring learning of users of this functionality, we drop this
-  remote: extension in Mercurial 6.6.
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  $ cd client
-  $ mkcommit initialcommit
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  $ hg push -r .
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  pushing to ssh://user@dummy/repo
-  remote: IMPORTANT: if you use this extension, please contact
-  remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  remote: unused and barring learning of users of this functionality, we drop this
-  remote: extension in Mercurial 6.6.
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  searching for changes
-  remote: adding changesets
-  remote: adding manifests
-  remote: adding file changes
-  remote: added 1 changesets with 1 changes to 1 files
-  $ mkcommit scratchcommit
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  $ hg push -r . -B scratch/mybranch
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  pushing to ssh://user@dummy/repo
-  remote: IMPORTANT: if you use this extension, please contact
-  remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  remote: unused and barring learning of users of this functionality, we drop this
-  remote: extension in Mercurial 6.6.
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  searching for changes
-  remote: IMPORTANT: if you use this extension, please contact
-  remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  remote: unused and barring learning of users of this functionality, we drop this
-  remote: extension in Mercurial 6.6.
-  remote: pushing 1 commit:
-  remote:     20759b6926ce  scratchcommit
-  $ hg log -G
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  @  changeset:   1:20759b6926ce
-  |  bookmark:    scratch/mybranch
-  |  tag:         tip
-  |  user:        test
-  |  date:        Thu Jan 01 00:00:00 1970 +0000
-  |  summary:     scratchcommit
-  |
-  o  changeset:   0:67145f466344
-     user:        test
-     date:        Thu Jan 01 00:00:00 1970 +0000
-     summary:     initialcommit
-  
-  $ hg log -G -R ../repo
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  o  changeset:   0:67145f466344
-     tag:         tip
-     user:        test
-     date:        Thu Jan 01 00:00:00 1970 +0000
-     summary:     initialcommit
-  
-  $ find ../repo/.hg/scratchbranches | sort
-  ../repo/.hg/scratchbranches
-  ../repo/.hg/scratchbranches/filebundlestore
-  ../repo/.hg/scratchbranches/filebundlestore/b9
-  ../repo/.hg/scratchbranches/filebundlestore/b9/e1
-  ../repo/.hg/scratchbranches/filebundlestore/b9/e1/b9e1ee5f93fb6d7c42496fc176c09839639dd9cc
-  ../repo/.hg/scratchbranches/index
-  ../repo/.hg/scratchbranches/index/bookmarkmap
-  ../repo/.hg/scratchbranches/index/bookmarkmap/scratch
-  ../repo/.hg/scratchbranches/index/bookmarkmap/scratch/mybranch
-  ../repo/.hg/scratchbranches/index/nodemap
-  ../repo/.hg/scratchbranches/index/nodemap/20759b6926ce827d5a8c73eb1fa9726d6f7defb2
-
-From another client we can get the scratchbranch if we ask for it explicitely
-
-  $ cd ..
-  $ hg clone ssh://user@dummy/repo client2 -q
-  remote: IMPORTANT: if you use this extension, please contact
-  remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  remote: unused and barring learning of users of this functionality, we drop this
-  remote: extension in Mercurial 6.6.
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  $ cd client2
-  $ hg pull -B scratch/mybranch --traceback
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  remote: IMPORTANT: if you use this extension, please contact
-  remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  remote: unused and barring learning of users of this functionality, we drop this
-  remote: extension in Mercurial 6.6.
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  pulling from ssh://user@dummy/repo
-  remote: IMPORTANT: if you use this extension, please contact
-  remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  remote: unused and barring learning of users of this functionality, we drop this
-  remote: extension in Mercurial 6.6.
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  searching for changes
-  remote: IMPORTANT: if you use this extension, please contact
-  remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  remote: unused and barring learning of users of this functionality, we drop this
-  remote: extension in Mercurial 6.6.
-  adding changesets
-  adding manifests
-  adding file changes
-  added 1 changesets with 1 changes to 1 files
-  new changesets 20759b6926ce (1 drafts)
-  (run 'hg update' to get a working copy)
-  $ hg log -G
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  o  changeset:   1:20759b6926ce
-  |  bookmark:    scratch/mybranch
-  |  tag:         tip
-  |  user:        test
-  |  date:        Thu Jan 01 00:00:00 1970 +0000
-  |  summary:     scratchcommit
-  |
-  @  changeset:   0:67145f466344
-     user:        test
-     date:        Thu Jan 01 00:00:00 1970 +0000
-     summary:     initialcommit
-  
-  $ cd ..
-
-Push to non-scratch bookmark
-
-  $ cd client
-  $ hg up 0
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
-  $ mkcommit newcommit
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  created new head
-  $ hg push -r .
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  pushing to ssh://user@dummy/repo
-  remote: IMPORTANT: if you use this extension, please contact
-  remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  remote: unused and barring learning of users of this functionality, we drop this
-  remote: extension in Mercurial 6.6.
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  searching for changes
-  remote: adding changesets
-  remote: adding manifests
-  remote: adding file changes
-  remote: added 1 changesets with 1 changes to 1 files
-  $ hg log -G -T '{desc} {phase} {bookmarks}'
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  @  newcommit public
-  |
-  | o  scratchcommit draft scratch/mybranch
-  |/
-  o  initialcommit public
-  
-
-Push to scratch branch
-  $ cd ../client2
-  $ hg up -q scratch/mybranch
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  $ mkcommit 'new scratch commit'
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  $ hg push -r . -B scratch/mybranch
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  pushing to ssh://user@dummy/repo
-  remote: IMPORTANT: if you use this extension, please contact
-  remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  remote: unused and barring learning of users of this functionality, we drop this
-  remote: extension in Mercurial 6.6.
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  searching for changes
-  remote: IMPORTANT: if you use this extension, please contact
-  remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  remote: unused and barring learning of users of this functionality, we drop this
-  remote: extension in Mercurial 6.6.
-  remote: pushing 2 commits:
-  remote:     20759b6926ce  scratchcommit
-  remote:     1de1d7d92f89  new scratch commit
-  $ hg log -G -T '{desc} {phase} {bookmarks}'
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  @  new scratch commit draft scratch/mybranch
-  |
-  o  scratchcommit draft
-  |
-  o  initialcommit public
-  
-  $ scratchnodes
-  1de1d7d92f8965260391d0513fe8a8d5973d3042 bed63daed3beba97fff2e819a148cf415c217a85
-  20759b6926ce827d5a8c73eb1fa9726d6f7defb2 bed63daed3beba97fff2e819a148cf415c217a85
-
-  $ scratchbookmarks
-  scratch/mybranch 1de1d7d92f8965260391d0513fe8a8d5973d3042
-
-Push scratch bookmark with no new revs
-  $ hg push -r . -B scratch/anotherbranch
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  pushing to ssh://user@dummy/repo
-  remote: IMPORTANT: if you use this extension, please contact
-  remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  remote: unused and barring learning of users of this functionality, we drop this
-  remote: extension in Mercurial 6.6.
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  searching for changes
-  remote: IMPORTANT: if you use this extension, please contact
-  remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  remote: unused and barring learning of users of this functionality, we drop this
-  remote: extension in Mercurial 6.6.
-  remote: pushing 2 commits:
-  remote:     20759b6926ce  scratchcommit
-  remote:     1de1d7d92f89  new scratch commit
-  $ hg log -G -T '{desc} {phase} {bookmarks}'
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  @  new scratch commit draft scratch/anotherbranch scratch/mybranch
-  |
-  o  scratchcommit draft
-  |
-  o  initialcommit public
-  
-  $ scratchbookmarks
-  scratch/anotherbranch 1de1d7d92f8965260391d0513fe8a8d5973d3042
-  scratch/mybranch 1de1d7d92f8965260391d0513fe8a8d5973d3042
-
-Pull scratch and non-scratch bookmark at the same time
-
-  $ hg -R ../repo book newbook
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  $ cd ../client
-  $ hg pull -B newbook -B scratch/mybranch --traceback
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  remote: IMPORTANT: if you use this extension, please contact
-  remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  remote: unused and barring learning of users of this functionality, we drop this
-  remote: extension in Mercurial 6.6.
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  pulling from ssh://user@dummy/repo
-  remote: IMPORTANT: if you use this extension, please contact
-  remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  remote: unused and barring learning of users of this functionality, we drop this
-  remote: extension in Mercurial 6.6.
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  searching for changes
-  remote: IMPORTANT: if you use this extension, please contact
-  remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  remote: unused and barring learning of users of this functionality, we drop this
-  remote: extension in Mercurial 6.6.
-  adding changesets
-  adding manifests
-  adding file changes
-  adding remote bookmark newbook
-  added 1 changesets with 1 changes to 2 files
-  new changesets 1de1d7d92f89 (1 drafts)
-  (run 'hg update' to get a working copy)
-  $ hg log -G -T '{desc} {phase} {bookmarks}'
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  o  new scratch commit draft scratch/mybranch
-  |
-  | @  newcommit public
-  | |
-  o |  scratchcommit draft
-  |/
-  o  initialcommit public
-  
-
-Push scratch revision without bookmark with --bundle-store
-
-  $ hg up -q tip
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  $ mkcommit scratchcommitnobook
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  $ hg log -G -T '{desc} {phase} {bookmarks}'
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  @  scratchcommitnobook draft
-  |
-  o  new scratch commit draft scratch/mybranch
-  |
-  | o  newcommit public
-  | |
-  o |  scratchcommit draft
-  |/
-  o  initialcommit public
-  
-  $ hg push -r . --bundle-store
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  pushing to ssh://user@dummy/repo
-  remote: IMPORTANT: if you use this extension, please contact
-  remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  remote: unused and barring learning of users of this functionality, we drop this
-  remote: extension in Mercurial 6.6.
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  searching for changes
-  remote: IMPORTANT: if you use this extension, please contact
-  remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  remote: unused and barring learning of users of this functionality, we drop this
-  remote: extension in Mercurial 6.6.
-  remote: pushing 3 commits:
-  remote:     20759b6926ce  scratchcommit
-  remote:     1de1d7d92f89  new scratch commit
-  remote:     2b5d271c7e0d  scratchcommitnobook
-  $ hg -R ../repo log -G -T '{desc} {phase}'
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  o  newcommit public
-  |
-  o  initialcommit public
-  
-
-  $ scratchnodes
-  1de1d7d92f8965260391d0513fe8a8d5973d3042 66fa08ff107451320512817bed42b7f467a1bec3
-  20759b6926ce827d5a8c73eb1fa9726d6f7defb2 66fa08ff107451320512817bed42b7f467a1bec3
-  2b5d271c7e0d25d811359a314d413ebcc75c9524 66fa08ff107451320512817bed42b7f467a1bec3
-
-Test with pushrebase
-  $ mkcommit scratchcommitwithpushrebase
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  $ hg push -r . -B scratch/mybranch
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  pushing to ssh://user@dummy/repo
-  remote: IMPORTANT: if you use this extension, please contact
-  remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  remote: unused and barring learning of users of this functionality, we drop this
-  remote: extension in Mercurial 6.6.
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  searching for changes
-  remote: IMPORTANT: if you use this extension, please contact
-  remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  remote: unused and barring learning of users of this functionality, we drop this
-  remote: extension in Mercurial 6.6.
-  remote: pushing 4 commits:
-  remote:     20759b6926ce  scratchcommit
-  remote:     1de1d7d92f89  new scratch commit
-  remote:     2b5d271c7e0d  scratchcommitnobook
-  remote:     d8c4f54ab678  scratchcommitwithpushrebase
-  $ hg -R ../repo log -G -T '{desc} {phase}'
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  o  newcommit public
-  |
-  o  initialcommit public
-  
-  $ scratchnodes
-  1de1d7d92f8965260391d0513fe8a8d5973d3042 e3cb2ac50f9e1e6a5ead3217fc21236c84af4397
-  20759b6926ce827d5a8c73eb1fa9726d6f7defb2 e3cb2ac50f9e1e6a5ead3217fc21236c84af4397
-  2b5d271c7e0d25d811359a314d413ebcc75c9524 e3cb2ac50f9e1e6a5ead3217fc21236c84af4397
-  d8c4f54ab678fd67cb90bb3f272a2dc6513a59a7 e3cb2ac50f9e1e6a5ead3217fc21236c84af4397
-
-Change the order of pushrebase and infinitepush
-  $ mkcommit scratchcommitwithpushrebase2
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  $ hg push -r . -B scratch/mybranch
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  pushing to ssh://user@dummy/repo
-  remote: IMPORTANT: if you use this extension, please contact
-  remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  remote: unused and barring learning of users of this functionality, we drop this
-  remote: extension in Mercurial 6.6.
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  searching for changes
-  remote: IMPORTANT: if you use this extension, please contact
-  remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  remote: unused and barring learning of users of this functionality, we drop this
-  remote: extension in Mercurial 6.6.
-  remote: pushing 5 commits:
-  remote:     20759b6926ce  scratchcommit
-  remote:     1de1d7d92f89  new scratch commit
-  remote:     2b5d271c7e0d  scratchcommitnobook
-  remote:     d8c4f54ab678  scratchcommitwithpushrebase
-  remote:     6c10d49fe927  scratchcommitwithpushrebase2
-  $ hg -R ../repo log -G -T '{desc} {phase}'
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  o  newcommit public
-  |
-  o  initialcommit public
-  
-  $ scratchnodes
-  1de1d7d92f8965260391d0513fe8a8d5973d3042 cd0586065eaf8b483698518f5fc32531e36fd8e0
-  20759b6926ce827d5a8c73eb1fa9726d6f7defb2 cd0586065eaf8b483698518f5fc32531e36fd8e0
-  2b5d271c7e0d25d811359a314d413ebcc75c9524 cd0586065eaf8b483698518f5fc32531e36fd8e0
-  6c10d49fe92751666c40263f96721b918170d3da cd0586065eaf8b483698518f5fc32531e36fd8e0
-  d8c4f54ab678fd67cb90bb3f272a2dc6513a59a7 cd0586065eaf8b483698518f5fc32531e36fd8e0
-
-Non-fastforward scratch bookmark push
-
-  $ hg log -GT "{rev}:{node} {desc}\n"
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  @  6:6c10d49fe92751666c40263f96721b918170d3da scratchcommitwithpushrebase2
-  |
-  o  5:d8c4f54ab678fd67cb90bb3f272a2dc6513a59a7 scratchcommitwithpushrebase
-  |
-  o  4:2b5d271c7e0d25d811359a314d413ebcc75c9524 scratchcommitnobook
-  |
-  o  3:1de1d7d92f8965260391d0513fe8a8d5973d3042 new scratch commit
-  |
-  | o  2:91894e11e8255bf41aa5434b7b98e8b2aa2786eb newcommit
-  | |
-  o |  1:20759b6926ce827d5a8c73eb1fa9726d6f7defb2 scratchcommit
-  |/
-  o  0:67145f4663446a9580364f70034fea6e21293b6f initialcommit
-  
-  $ hg up 6c10d49fe927
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  $ echo 1 > amend
-  $ hg add amend
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  $ hg ci --amend -m 'scratch amended commit'
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  saved backup bundle to $TESTTMP/client/.hg/strip-backup/6c10d49fe927-c99ffec5-amend.hg
-  $ hg log -G -T '{desc} {phase} {bookmarks}'
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  @  scratch amended commit draft scratch/mybranch
-  |
-  o  scratchcommitwithpushrebase draft
-  |
-  o  scratchcommitnobook draft
-  |
-  o  new scratch commit draft
-  |
-  | o  newcommit public
-  | |
-  o |  scratchcommit draft
-  |/
-  o  initialcommit public
-  
-
-  $ scratchbookmarks
-  scratch/anotherbranch 1de1d7d92f8965260391d0513fe8a8d5973d3042
-  scratch/mybranch 6c10d49fe92751666c40263f96721b918170d3da
-  $ hg push -r . -B scratch/mybranch
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  pushing to ssh://user@dummy/repo
-  remote: IMPORTANT: if you use this extension, please contact
-  remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  remote: unused and barring learning of users of this functionality, we drop this
-  remote: extension in Mercurial 6.6.
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  searching for changes
-  remote: IMPORTANT: if you use this extension, please contact
-  remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  remote: unused and barring learning of users of this functionality, we drop this
-  remote: extension in Mercurial 6.6.
-  remote: pushing 5 commits:
-  remote:     20759b6926ce  scratchcommit
-  remote:     1de1d7d92f89  new scratch commit
-  remote:     2b5d271c7e0d  scratchcommitnobook
-  remote:     d8c4f54ab678  scratchcommitwithpushrebase
-  remote:     8872775dd97a  scratch amended commit
-  $ scratchbookmarks
-  scratch/anotherbranch 1de1d7d92f8965260391d0513fe8a8d5973d3042
-  scratch/mybranch 8872775dd97a750e1533dc1fbbca665644b32547
-  $ hg log -G -T '{desc} {phase} {bookmarks}'
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  @  scratch amended commit draft scratch/mybranch
-  |
-  o  scratchcommitwithpushrebase draft
-  |
-  o  scratchcommitnobook draft
-  |
-  o  new scratch commit draft
-  |
-  | o  newcommit public
-  | |
-  o |  scratchcommit draft
-  |/
-  o  initialcommit public
-  
-Check that push path is not ignored. Add new path to the hgrc
-  $ cat >> .hg/hgrc << EOF
-  > [paths]
-  > peer=ssh://user@dummy/client2
-  > EOF
-
-Checkout last non-scrath commit
-  $ hg up 91894e11e8255
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  1 files updated, 0 files merged, 6 files removed, 0 files unresolved
-  $ mkcommit peercommit
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-Use --force because this push creates new head
-  $ hg push peer -r . -f
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  pushing to ssh://user@dummy/client2
-  remote: IMPORTANT: if you use this extension, please contact
-  remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  remote: unused and barring learning of users of this functionality, we drop this
-  remote: extension in Mercurial 6.6.
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  searching for changes
-  remote: adding changesets
-  remote: adding manifests
-  remote: adding file changes
-  remote: added 2 changesets with 2 changes to 2 files (+1 heads)
-  $ hg -R ../repo log -G -T '{desc} {phase} {bookmarks}'
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  o  newcommit public
-  |
-  o  initialcommit public
-  
-  $ hg -R ../client2 log -G -T '{desc} {phase} {bookmarks}'
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  o  peercommit public
-  |
-  o  newcommit public
-  |
-  | @  new scratch commit draft scratch/anotherbranch scratch/mybranch
-  | |
-  | o  scratchcommit draft
-  |/
-  o  initialcommit public
-  
--- a/tests/test-infinitepush-ci.t	Fri Jun 23 13:27:09 2023 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,579 +0,0 @@
-#require no-reposimplestore
-
-Testing the case when there is no infinitepush extension present on the client
-side and the server routes each push to bundlestore. This case is very much
-similar to CI use case.
-
-Setup
------
-
-  $ . "$TESTDIR/library-infinitepush.sh"
-  $ cat >> $HGRCPATH <<EOF
-  > [alias]
-  > glog = log -GT "{rev}:{node|short} {desc}\n{phase}"
-  > EOF
-  $ cp $HGRCPATH $TESTTMP/defaulthgrc
-  $ hg init repo
-  $ cd repo
-  $ setupserver
-  $ echo "pushtobundlestore = True" >> .hg/hgrc
-  $ echo "[extensions]" >> .hg/hgrc
-  $ echo "infinitepush=" >> .hg/hgrc
-  $ echo "[infinitepush]" >> .hg/hgrc
-  $ echo "deprecation-abort=no" >> .hg/hgrc
-  $ echo initialcommit > initialcommit
-  $ hg ci -Aqm "initialcommit"
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  IMPORTANT: if you use this extension, please contact (chg !)
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be (chg !)
-  unused and barring learning of users of this functionality, we drop this (chg !)
-  extension in Mercurial 6.6. (chg !)
-  $ hg phase --public .
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-
-  $ cd ..
-  $ hg clone repo client -q
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  $ hg clone repo client2 -q
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  $ hg clone ssh://user@dummy/repo client3 -q
-  remote: IMPORTANT: if you use this extension, please contact
-  remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  remote: unused and barring learning of users of this functionality, we drop this
-  remote: extension in Mercurial 6.6.
-  $ cd client
-
-Pushing a new commit from the client to the server
------------------------------------------------------
-
-  $ echo foobar > a
-  $ hg ci -Aqm "added a"
-  $ hg glog
-  @  1:6cb0989601f1 added a
-  |  draft
-  o  0:67145f466344 initialcommit
-     public
-
-  $ hg push
-  pushing to $TESTTMP/repo
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  searching for changes
-  storing changesets on the bundlestore
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  pushing 1 commit:
-      6cb0989601f1  added a
-
-  $ scratchnodes
-  6cb0989601f1fb5805238edfb16f3606713d9a0b 3b414252ff8acab801318445d88ff48faf4a28c3
-
-Understanding how data is stored on the bundlestore in server
--------------------------------------------------------------
-
-There are two things, filebundlestore and index
-  $ ls ../repo/.hg/scratchbranches
-  filebundlestore
-  index
-
-filebundlestore stores the bundles
-  $ ls ../repo/.hg/scratchbranches/filebundlestore/3b/41/
-  3b414252ff8acab801318445d88ff48faf4a28c3
-
-index/nodemap stores a map of node id and file in which bundle is stored in filebundlestore
-  $ ls ../repo/.hg/scratchbranches/index/
-  nodemap
-  $ ls ../repo/.hg/scratchbranches/index/nodemap/
-  6cb0989601f1fb5805238edfb16f3606713d9a0b
-
-  $ cd ../repo
-
-Checking that the commit was not applied to revlog on the server
-------------------------------------------------------------------
-
-  $ hg glog
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  @  0:67145f466344 initialcommit
-     public
-
-Applying the changeset from the bundlestore
---------------------------------------------
-
-  $ hg unbundle .hg/scratchbranches/filebundlestore/3b/41/3b414252ff8acab801318445d88ff48faf4a28c3
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  adding changesets
-  adding manifests
-  adding file changes
-  added 1 changesets with 1 changes to 1 files
-  new changesets 6cb0989601f1
-  (run 'hg update' to get a working copy)
-
-  $ hg glog
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  o  1:6cb0989601f1 added a
-  |  public
-  @  0:67145f466344 initialcommit
-     public
-
-Pushing more changesets from the local repo
---------------------------------------------
-
-  $ cd ../client
-  $ echo b > b
-  $ hg ci -Aqm "added b"
-  $ echo c > c
-  $ hg ci -Aqm "added c"
-  $ hg glog
-  @  3:bf8a6e3011b3 added c
-  |  draft
-  o  2:eaba929e866c added b
-  |  draft
-  o  1:6cb0989601f1 added a
-  |  public
-  o  0:67145f466344 initialcommit
-     public
-
-  $ hg push
-  pushing to $TESTTMP/repo
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  searching for changes
-  storing changesets on the bundlestore
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  pushing 2 commits:
-      eaba929e866c  added b
-      bf8a6e3011b3  added c
-
-Checking that changesets are not applied on the server
-------------------------------------------------------
-
-  $ hg glog -R ../repo
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  o  1:6cb0989601f1 added a
-  |  public
-  @  0:67145f466344 initialcommit
-     public
-
-Both of the new changesets are stored in a single bundle-file
-  $ scratchnodes
-  6cb0989601f1fb5805238edfb16f3606713d9a0b 3b414252ff8acab801318445d88ff48faf4a28c3
-  bf8a6e3011b345146bbbedbcb1ebd4837571492a 239585f5e61f0c09ce7106bdc1097bff731738f4
-  eaba929e866c59bc9a6aada5a9dd2f6990db83c0 239585f5e61f0c09ce7106bdc1097bff731738f4
-
-Pushing more changesets to the server
--------------------------------------
-
-  $ echo d > d
-  $ hg ci -Aqm "added d"
-  $ echo e > e
-  $ hg ci -Aqm "added e"
-
-XXX: we should have pushed only the parts which are not in bundlestore
-  $ hg push
-  pushing to $TESTTMP/repo
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  searching for changes
-  storing changesets on the bundlestore
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  pushing 4 commits:
-      eaba929e866c  added b
-      bf8a6e3011b3  added c
-      1bb96358eda2  added d
-      b4e4bce66051  added e
-
-Sneak peek into the bundlestore at the server
-  $ scratchnodes
-  1bb96358eda285b536c6d1c66846a7cdb2336cea 98fbae0016662521b0007da1b7bc349cd3caacd1
-  6cb0989601f1fb5805238edfb16f3606713d9a0b 3b414252ff8acab801318445d88ff48faf4a28c3
-  b4e4bce660512ad3e71189e14588a70ac8e31fef 98fbae0016662521b0007da1b7bc349cd3caacd1
-  bf8a6e3011b345146bbbedbcb1ebd4837571492a 98fbae0016662521b0007da1b7bc349cd3caacd1
-  eaba929e866c59bc9a6aada5a9dd2f6990db83c0 98fbae0016662521b0007da1b7bc349cd3caacd1
-
-Checking if `hg pull` pulls something or `hg incoming` shows something
------------------------------------------------------------------------
-
-  $ hg incoming
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  comparing with $TESTTMP/repo
-  searching for changes
-  no changes found
-  [1]
-
-  $ hg pull
-  pulling from $TESTTMP/repo
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  searching for changes
-  no changes found
-
-Pulling from second client which is a localpeer to test `hg pull -r <rev>`
---------------------------------------------------------------------------
-
-Pulling the revision which is applied
-
-  $ cd ../client2
-  $ hg pull -r 6cb0989601f1
-  pulling from $TESTTMP/repo
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  searching for changes
-  adding changesets
-  adding manifests
-  adding file changes
-  added 1 changesets with 1 changes to 1 files
-  new changesets 6cb0989601f1
-  (run 'hg update' to get a working copy)
-  $ hg glog
-  o  1:6cb0989601f1 added a
-  |  public
-  @  0:67145f466344 initialcommit
-     public
-
-Pulling the revision which is in bundlestore
-XXX: we should support pulling revisions from a local peers bundlestore without
-client side wrapping
-
-  $ hg pull -r b4e4bce660512ad3e71189e14588a70ac8e31fef
-  pulling from $TESTTMP/repo
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  abort: unknown revision 'b4e4bce660512ad3e71189e14588a70ac8e31fef'
-  [10]
-  $ hg glog
-  o  1:6cb0989601f1 added a
-  |  public
-  @  0:67145f466344 initialcommit
-     public
-
-  $ cd ../client
-
-Pulling from third client which is not a localpeer
----------------------------------------------------
-
-Pulling the revision which is applied
-
-  $ cd ../client3
-  $ hg pull -r 6cb0989601f1
-  pulling from ssh://user@dummy/repo
-  remote: IMPORTANT: if you use this extension, please contact
-  remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  remote: unused and barring learning of users of this functionality, we drop this
-  remote: extension in Mercurial 6.6.
-  searching for changes
-  adding changesets
-  adding manifests
-  adding file changes
-  added 1 changesets with 1 changes to 1 files
-  new changesets 6cb0989601f1
-  (run 'hg update' to get a working copy)
-  $ hg glog
-  o  1:6cb0989601f1 added a
-  |  public
-  @  0:67145f466344 initialcommit
-     public
-
-Pulling the revision which is in bundlestore
-
-Trying to specify short hash
-XXX: we should support this
-  $ hg pull -r b4e4bce660512
-  pulling from ssh://user@dummy/repo
-  remote: IMPORTANT: if you use this extension, please contact
-  remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  remote: unused and barring learning of users of this functionality, we drop this
-  remote: extension in Mercurial 6.6.
-  abort: unknown revision 'b4e4bce660512'
-  [255]
-
-XXX: we should show better message when the pull is happening from bundlestore
-  $ hg pull -r b4e4bce660512ad3e71189e14588a70ac8e31fef
-  pulling from ssh://user@dummy/repo
-  remote: IMPORTANT: if you use this extension, please contact
-  remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  remote: unused and barring learning of users of this functionality, we drop this
-  remote: extension in Mercurial 6.6.
-  searching for changes
-  remote: IMPORTANT: if you use this extension, please contact
-  remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  remote: unused and barring learning of users of this functionality, we drop this
-  remote: extension in Mercurial 6.6.
-  adding changesets
-  adding manifests
-  adding file changes
-  added 4 changesets with 4 changes to 4 files
-  new changesets eaba929e866c:b4e4bce66051
-  (run 'hg update' to get a working copy)
-  $ hg glog
-  o  5:b4e4bce66051 added e
-  |  public
-  o  4:1bb96358eda2 added d
-  |  public
-  o  3:bf8a6e3011b3 added c
-  |  public
-  o  2:eaba929e866c added b
-  |  public
-  o  1:6cb0989601f1 added a
-  |  public
-  @  0:67145f466344 initialcommit
-     public
-
-  $ cd ../client
-
-Checking storage of phase information with the bundle on bundlestore
----------------------------------------------------------------------
-
-creating a draft commit
-  $ cat >> $HGRCPATH <<EOF
-  > [phases]
-  > publish = False
-  > EOF
-  $ echo f > f
-  $ hg ci -Aqm "added f"
-  $ hg glog -r '.^::'
-  @  6:9b42578d4447 added f
-  |  draft
-  o  5:b4e4bce66051 added e
-  |  public
-  ~
-
-  $ hg push
-  pushing to $TESTTMP/repo
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  searching for changes
-  storing changesets on the bundlestore
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  pushing 5 commits:
-      eaba929e866c  added b
-      bf8a6e3011b3  added c
-      1bb96358eda2  added d
-      b4e4bce66051  added e
-      9b42578d4447  added f
-
-XXX: the phase of 9b42578d4447 should not be changed here
-  $ hg glog -r .
-  @  6:9b42578d4447 added f
-  |  public
-  ~
-
-applying the bundle on the server to check preservation of phase-information
-
-  $ cd ../repo
-  $ scratchnodes
-  1bb96358eda285b536c6d1c66846a7cdb2336cea 280a46a259a268f0e740c81c5a7751bdbfaec85f
-  6cb0989601f1fb5805238edfb16f3606713d9a0b 3b414252ff8acab801318445d88ff48faf4a28c3
-  9b42578d44473575994109161430d65dd147d16d 280a46a259a268f0e740c81c5a7751bdbfaec85f
-  b4e4bce660512ad3e71189e14588a70ac8e31fef 280a46a259a268f0e740c81c5a7751bdbfaec85f
-  bf8a6e3011b345146bbbedbcb1ebd4837571492a 280a46a259a268f0e740c81c5a7751bdbfaec85f
-  eaba929e866c59bc9a6aada5a9dd2f6990db83c0 280a46a259a268f0e740c81c5a7751bdbfaec85f
-
-  $ hg unbundle .hg/scratchbranches/filebundlestore/28/0a/280a46a259a268f0e740c81c5a7751bdbfaec85f
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  adding changesets
-  adding manifests
-  adding file changes
-  added 5 changesets with 5 changes to 5 files
-  new changesets eaba929e866c:9b42578d4447 (1 drafts)
-  (run 'hg update' to get a working copy)
-
-  $ hg glog
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  o  6:9b42578d4447 added f
-  |  draft
-  o  5:b4e4bce66051 added e
-  |  public
-  o  4:1bb96358eda2 added d
-  |  public
-  o  3:bf8a6e3011b3 added c
-  |  public
-  o  2:eaba929e866c added b
-  |  public
-  o  1:6cb0989601f1 added a
-  |  public
-  @  0:67145f466344 initialcommit
-     public
-
-Checking storage of obsmarkers in the bundlestore
---------------------------------------------------
-
-enabling obsmarkers and rebase extension
-
-  $ cat >> $HGRCPATH << EOF
-  > [experimental]
-  > evolution = all
-  > [extensions]
-  > rebase =
-  > EOF
-
-  $ cd ../client
-
-  $ hg phase -r . --draft --force
-  $ hg rebase -r 6 -d 3
-  rebasing 6:9b42578d4447 tip "added f"
-
-  $ hg glog
-  @  7:99949238d9ac added f
-  |  draft
-  | o  5:b4e4bce66051 added e
-  | |  public
-  | o  4:1bb96358eda2 added d
-  |/   public
-  o  3:bf8a6e3011b3 added c
-  |  public
-  o  2:eaba929e866c added b
-  |  public
-  o  1:6cb0989601f1 added a
-  |  public
-  o  0:67145f466344 initialcommit
-     public
-
-  $ hg push -f
-  pushing to $TESTTMP/repo
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  searching for changes
-  storing changesets on the bundlestore
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  pushing 1 commit:
-      99949238d9ac  added f
-
-XXX: the phase should not have changed here
-  $ hg glog -r .
-  @  7:99949238d9ac added f
-  |  public
-  ~
-
-Unbundling on server to see obsmarkers being applied
-
-  $ cd ../repo
-
-  $ scratchnodes
-  1bb96358eda285b536c6d1c66846a7cdb2336cea 280a46a259a268f0e740c81c5a7751bdbfaec85f
-  6cb0989601f1fb5805238edfb16f3606713d9a0b 3b414252ff8acab801318445d88ff48faf4a28c3
-  99949238d9ac7f2424a33a46dface6f866afd059 090a24fe63f31d3b4bee714447f835c8c362ff57
-  9b42578d44473575994109161430d65dd147d16d 280a46a259a268f0e740c81c5a7751bdbfaec85f
-  b4e4bce660512ad3e71189e14588a70ac8e31fef 280a46a259a268f0e740c81c5a7751bdbfaec85f
-  bf8a6e3011b345146bbbedbcb1ebd4837571492a 280a46a259a268f0e740c81c5a7751bdbfaec85f
-  eaba929e866c59bc9a6aada5a9dd2f6990db83c0 280a46a259a268f0e740c81c5a7751bdbfaec85f
-
-  $ hg glog
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  IMPORTANT: if you use this extension, please contact (chg !)
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be (chg !)
-  unused and barring learning of users of this functionality, we drop this (chg !)
-  extension in Mercurial 6.6. (chg !)
-  o  6:9b42578d4447 added f
-  |  draft
-  o  5:b4e4bce66051 added e
-  |  public
-  o  4:1bb96358eda2 added d
-  |  public
-  o  3:bf8a6e3011b3 added c
-  |  public
-  o  2:eaba929e866c added b
-  |  public
-  o  1:6cb0989601f1 added a
-  |  public
-  @  0:67145f466344 initialcommit
-     public
-
-  $ hg unbundle .hg/scratchbranches/filebundlestore/09/0a/090a24fe63f31d3b4bee714447f835c8c362ff57
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  adding changesets
-  adding manifests
-  adding file changes
-  added 1 changesets with 0 changes to 1 files (+1 heads)
-  1 new obsolescence markers
-  obsoleted 1 changesets
-  new changesets 99949238d9ac (1 drafts)
-  (run 'hg heads' to see heads, 'hg merge' to merge)
-
-  $ hg glog
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  o  7:99949238d9ac added f
-  |  draft
-  | o  5:b4e4bce66051 added e
-  | |  public
-  | o  4:1bb96358eda2 added d
-  |/   public
-  o  3:bf8a6e3011b3 added c
-  |  public
-  o  2:eaba929e866c added b
-  |  public
-  o  1:6cb0989601f1 added a
-  |  public
-  @  0:67145f466344 initialcommit
-     public
--- a/tests/test-infinitepush.t	Fri Jun 23 13:27:09 2023 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,472 +0,0 @@
-#require no-reposimplestore no-chg
-
-XXX-CHG this test hangs if `hg` is really `chg`. This was hidden by the use of
-`alias hg=chg` by run-tests.py. With such alias removed, this test is revealed
-buggy. This need to be resolved sooner than later.
-
-
-Testing infinipush extension and the confi options provided by it
-
-Setup
-
-  $ . "$TESTDIR/library-infinitepush.sh"
-  $ cp $HGRCPATH $TESTTMP/defaulthgrc
-  $ setupcommon
-  $ hg init repo
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  $ cd repo
-  $ setupserver
-  $ echo initialcommit > initialcommit
-  $ hg ci -Aqm "initialcommit"
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  $ hg phase --public .
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-
-  $ cd ..
-  $ hg clone ssh://user@dummy/repo client -q
-  remote: IMPORTANT: if you use this extension, please contact
-  remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  remote: unused and barring learning of users of this functionality, we drop this
-  remote: extension in Mercurial 6.6.
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-
-Create two heads. Push first head alone, then two heads together. Make sure that
-multihead push works.
-  $ cd client
-  $ echo multihead1 > multihead1
-  $ hg add multihead1
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  $ hg ci -m "multihead1"
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  $ hg up null
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  0 files updated, 0 files merged, 2 files removed, 0 files unresolved
-  $ echo multihead2 > multihead2
-  $ hg ci -Am "multihead2"
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  adding multihead2
-  created new head
-  $ hg push -r . --bundle-store
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  pushing to ssh://user@dummy/repo
-  remote: IMPORTANT: if you use this extension, please contact
-  remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  remote: unused and barring learning of users of this functionality, we drop this
-  remote: extension in Mercurial 6.6.
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  searching for changes
-  remote: IMPORTANT: if you use this extension, please contact
-  remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  remote: unused and barring learning of users of this functionality, we drop this
-  remote: extension in Mercurial 6.6.
-  remote: pushing 1 commit:
-  remote:     ee4802bf6864  multihead2
-  $ hg push -r '1:2' --bundle-store
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  pushing to ssh://user@dummy/repo
-  remote: IMPORTANT: if you use this extension, please contact
-  remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  remote: unused and barring learning of users of this functionality, we drop this
-  remote: extension in Mercurial 6.6.
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  searching for changes
-  remote: IMPORTANT: if you use this extension, please contact
-  remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  remote: unused and barring learning of users of this functionality, we drop this
-  remote: extension in Mercurial 6.6.
-  remote: pushing 2 commits:
-  remote:     bc22f9a30a82  multihead1
-  remote:     ee4802bf6864  multihead2
-  $ scratchnodes
-  bc22f9a30a821118244deacbd732e394ed0b686c de1b7d132ba98f0172cd974e3e69dfa80faa335c
-  ee4802bf6864326a6b3dcfff5a03abc2a0a69b8f de1b7d132ba98f0172cd974e3e69dfa80faa335c
-
-Create two new scratch bookmarks
-  $ hg up 0
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  1 files updated, 0 files merged, 1 files removed, 0 files unresolved
-  $ echo scratchfirstpart > scratchfirstpart
-  $ hg ci -Am "scratchfirstpart"
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  adding scratchfirstpart
-  created new head
-  $ hg push -r . -B scratch/firstpart
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  pushing to ssh://user@dummy/repo
-  remote: IMPORTANT: if you use this extension, please contact
-  remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  remote: unused and barring learning of users of this functionality, we drop this
-  remote: extension in Mercurial 6.6.
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  searching for changes
-  remote: IMPORTANT: if you use this extension, please contact
-  remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  remote: unused and barring learning of users of this functionality, we drop this
-  remote: extension in Mercurial 6.6.
-  remote: pushing 1 commit:
-  remote:     176993b87e39  scratchfirstpart
-  $ hg up 0
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
-  $ echo scratchsecondpart > scratchsecondpart
-  $ hg ci -Am "scratchsecondpart"
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  adding scratchsecondpart
-  created new head
-  $ hg push -r . -B scratch/secondpart
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  pushing to ssh://user@dummy/repo
-  remote: IMPORTANT: if you use this extension, please contact
-  remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  remote: unused and barring learning of users of this functionality, we drop this
-  remote: extension in Mercurial 6.6.
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  searching for changes
-  remote: IMPORTANT: if you use this extension, please contact
-  remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  remote: unused and barring learning of users of this functionality, we drop this
-  remote: extension in Mercurial 6.6.
-  remote: pushing 1 commit:
-  remote:     8db3891c220e  scratchsecondpart
-
-Pull two bookmarks from the second client
-  $ cd ..
-  $ hg clone ssh://user@dummy/repo client2 -q
-  remote: IMPORTANT: if you use this extension, please contact
-  remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  remote: unused and barring learning of users of this functionality, we drop this
-  remote: extension in Mercurial 6.6.
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  $ cd client2
-  $ hg pull -B scratch/firstpart -B scratch/secondpart
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  remote: IMPORTANT: if you use this extension, please contact
-  remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  remote: unused and barring learning of users of this functionality, we drop this
-  remote: extension in Mercurial 6.6.
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  pulling from ssh://user@dummy/repo
-  remote: IMPORTANT: if you use this extension, please contact
-  remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  remote: unused and barring learning of users of this functionality, we drop this
-  remote: extension in Mercurial 6.6.
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  searching for changes
-  remote: IMPORTANT: if you use this extension, please contact
-  remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  remote: unused and barring learning of users of this functionality, we drop this
-  remote: extension in Mercurial 6.6.
-  remote: IMPORTANT: if you use this extension, please contact
-  remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  remote: unused and barring learning of users of this functionality, we drop this
-  remote: extension in Mercurial 6.6.
-  adding changesets
-  adding manifests
-  adding file changes
-  adding changesets
-  adding manifests
-  adding file changes
-  added 2 changesets with 2 changes to 2 files (+1 heads)
-  new changesets * (glob)
-  (run 'hg heads' to see heads, 'hg merge' to merge)
-  $ hg log -r scratch/secondpart -T '{node}'
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  8db3891c220e216f6da214e8254bd4371f55efca (no-eol)
-  $ hg log -r scratch/firstpart -T '{node}'
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  176993b87e39bd88d66a2cccadabe33f0b346339 (no-eol)
-Make two commits to the scratch branch
-
-  $ echo testpullbycommithash1 > testpullbycommithash1
-  $ hg ci -Am "testpullbycommithash1"
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  adding testpullbycommithash1
-  created new head
-  $ hg log -r '.' -T '{node}\n' > ../testpullbycommithash1
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  $ echo testpullbycommithash2 > testpullbycommithash2
-  $ hg ci -Aqm "testpullbycommithash2"
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  $ hg push -r . -B scratch/mybranch -q
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  remote: IMPORTANT: if you use this extension, please contact
-  remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  remote: unused and barring learning of users of this functionality, we drop this
-  remote: extension in Mercurial 6.6.
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-
-Create third client and pull by commit hash.
-Make sure testpullbycommithash2 has not fetched
-  $ cd ..
-  $ hg clone ssh://user@dummy/repo client3 -q
-  remote: IMPORTANT: if you use this extension, please contact
-  remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  remote: unused and barring learning of users of this functionality, we drop this
-  remote: extension in Mercurial 6.6.
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  $ cd client3
-  $ hg pull -r `cat ../testpullbycommithash1`
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  pulling from ssh://user@dummy/repo
-  remote: IMPORTANT: if you use this extension, please contact
-  remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  remote: unused and barring learning of users of this functionality, we drop this
-  remote: extension in Mercurial 6.6.
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  searching for changes
-  remote: IMPORTANT: if you use this extension, please contact
-  remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  remote: unused and barring learning of users of this functionality, we drop this
-  remote: extension in Mercurial 6.6.
-  adding changesets
-  adding manifests
-  adding file changes
-  added 1 changesets with 1 changes to 1 files
-  new changesets 33910bfe6ffe (1 drafts)
-  (run 'hg update' to get a working copy)
-  $ hg log -G -T '{desc} {phase} {bookmarks}'
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  o  testpullbycommithash1 draft
-  |
-  @  initialcommit public
-  
-Make public commit in the repo and pull it.
-Make sure phase on the client is public.
-  $ cd ../repo
-  $ echo publiccommit > publiccommit
-  $ hg ci -Aqm "publiccommit"
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  $ hg phase --public .
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  $ cd ../client3
-  $ hg pull
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  pulling from ssh://user@dummy/repo
-  remote: IMPORTANT: if you use this extension, please contact
-  remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  remote: unused and barring learning of users of this functionality, we drop this
-  remote: extension in Mercurial 6.6.
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  searching for changes
-  adding changesets
-  adding manifests
-  adding file changes
-  added 1 changesets with 1 changes to 1 files (+1 heads)
-  new changesets a79b6597f322
-  (run 'hg heads' to see heads, 'hg merge' to merge)
-  $ hg log -G -T '{desc} {phase} {bookmarks} {node|short}'
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  o  publiccommit public  a79b6597f322
-  |
-  | o  testpullbycommithash1 draft  33910bfe6ffe
-  |/
-  @  initialcommit public  67145f466344
-  
-  $ hg up a79b6597f322
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  $ echo scratchontopofpublic > scratchontopofpublic
-  $ hg ci -Aqm "scratchontopofpublic"
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  $ hg push -r . -B scratch/scratchontopofpublic
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  pushing to ssh://user@dummy/repo
-  remote: IMPORTANT: if you use this extension, please contact
-  remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  remote: unused and barring learning of users of this functionality, we drop this
-  remote: extension in Mercurial 6.6.
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  searching for changes
-  remote: IMPORTANT: if you use this extension, please contact
-  remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  remote: unused and barring learning of users of this functionality, we drop this
-  remote: extension in Mercurial 6.6.
-  remote: pushing 1 commit:
-  remote:     c70aee6da07d  scratchontopofpublic
-  $ cd ../client2
-  $ hg pull -B scratch/scratchontopofpublic
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  remote: IMPORTANT: if you use this extension, please contact
-  remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  remote: unused and barring learning of users of this functionality, we drop this
-  remote: extension in Mercurial 6.6.
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  pulling from ssh://user@dummy/repo
-  remote: IMPORTANT: if you use this extension, please contact
-  remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  remote: unused and barring learning of users of this functionality, we drop this
-  remote: extension in Mercurial 6.6.
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  searching for changes
-  remote: IMPORTANT: if you use this extension, please contact
-  remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  remote: unused and barring learning of users of this functionality, we drop this
-  remote: extension in Mercurial 6.6.
-  adding changesets
-  adding manifests
-  adding file changes
-  adding changesets
-  adding manifests
-  adding file changes
-  added 2 changesets with 2 changes to 2 files (+1 heads)
-  new changesets a79b6597f322:c70aee6da07d (1 drafts)
-  (run 'hg heads .' to see heads, 'hg merge' to merge)
-  $ hg log -r scratch/scratchontopofpublic -T '{phase}'
-  IMPORTANT: if you use this extension, please contact
-  mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
-  unused and barring learning of users of this functionality, we drop this
-  extension in Mercurial 6.6.
-  draft (no-eol)