changeset 6921:4b843ae726de mercurial-4.9

test-compat: merge mercurial-5.0 into mercurial-4.9
author Anton Shestakov <av6@dwimlabs.net>
date Fri, 25 Oct 2024 18:14:41 +0400
parents e885fc210015 (current diff) df546ef8d75f (diff)
children f4f5ae0bfc29
files
diffstat 22 files changed, 464 insertions(+), 341 deletions(-) [+]
line wrap: on
line diff
--- a/.gitlab-ci.yml	Thu Jun 27 09:47:05 2024 +0400
+++ b/.gitlab-ci.yml	Fri Oct 25 18:14:41 2024 +0400
@@ -1,6 +1,6 @@
 .prepare_hg: &prepare_hg
     - hg pull -R /ci/repos/mercurial/ https://repo.mercurial-scm.org/hg
-    - hg_branch=${HG_BRANCH:-$(tests/testlib/map-hg-rev.sh "$(hg identify --branch)")}
+    - hg_branch=${HG_BRANCH:-$(tests/testlib/map-hg-rev.sh $CI_COMMIT_HG_BRANCH)}
     - hg -R /ci/repos/mercurial/ update "$hg_branch"
     - hg_rev=$(hg log -R /ci/repos/mercurial/ -r . -T '{node}')
     - echo testing with mercurial branch="$hg_branch", revision="$hg_rev"
@@ -24,6 +24,7 @@
     image: registry.heptapod.net/mercurial/ci-images/$PY-hgext3rd
     before_script:
         - (cd tests; ls -1 test-check-*.t > /tmp/check-tests.txt)
+        - (cd tests; ls -1 test-check-sdist.t test-doctest.py > /tmp/compat-blacklist.txt)
     script:
         - *prepare_hg
         - ($PYTHON --version)
@@ -34,14 +35,15 @@
     variables:
         PY: py2
         PYTHON: prlimit --nofile=1024:1024 python2
-        RUNTEST_ARGS: "--test-list /tmp/check-tests.txt"
+        RUNTEST_ARGS: "--test-list /tmp/check-tests.txt --blacklist /tmp/compat-blacklist.txt"
+        CI_CLEVER_CLOUD_FLAVOR: S
 
 tests-py2-cext:
     <<: *runtests
     variables:
         PY: py2
         PYTHON: prlimit --nofile=1024:1024 python2
-        RUNTEST_ARGS: "--blacklist /tmp/check-tests.txt"
+        RUNTEST_ARGS: "--blacklist /tmp/check-tests.txt --blacklist /tmp/compat-blacklist.txt"
         TEST_HGMODULEPOLICY: "c"
 
 tests-py2-pure:
@@ -49,5 +51,5 @@
     variables:
         PY: py2
         PYTHON: prlimit --nofile=1024:1024 python2
-        RUNTEST_ARGS: "--pure --blacklist /tmp/check-tests.txt"
+        RUNTEST_ARGS: "--pure --blacklist /tmp/check-tests.txt --blacklist /tmp/compat-blacklist.txt"
         TEST_HGMODULEPOLICY: "py"
--- a/.hgtags	Thu Jun 27 09:47:05 2024 +0400
+++ b/.hgtags	Fri Oct 25 18:14:41 2024 +0400
@@ -110,3 +110,4 @@
 369e248b6312cc3b0777033a4632f2c9e18a0897 11.1.1
 c31c6638381080bc5905fad37545610fde3b98bc 11.1.2
 2d2da4f7742a0da2c2fbd5a95c48937720eeafd4 11.1.3
+ed7c98393e060210689f0b94d79e8b990403b6a9 11.1.4
--- a/CHANGELOG	Thu Jun 27 09:47:05 2024 +0400
+++ b/CHANGELOG	Fri Oct 25 18:14:41 2024 +0400
@@ -1,7 +1,24 @@
 Changelog
 =========
 
-11.1.4 - in progress
+11.1.5 - in progress
+--------------------
+
+  * compatibility with Mercurial 6.9
+
+  * evolve: check that the evolved revisions are indeed in the repo during
+    abort, fixes an issue when trying to access them during cleanup step
+
+  * docs: update installation instructions due to PEP 668
+  * docs: minor edits and fixes in evolve and topic tutorials
+
+  * tests: more tests related to Python packaging
+
+topic (1.1.5)
+
+  * compatibility with Mercurial 6.9
+
+11.1.4 -- 2024-06-28
 --------------------
 
   * compatibility with Mercurial 6.8
--- a/README.rst	Thu Jun 27 09:47:05 2024 +0400
+++ b/README.rst	Fri Oct 25 18:14:41 2024 +0400
@@ -26,7 +26,7 @@
 * improves performance of obsolescence marker exchange and discovery during
   push and pull.
 
-.. _`changeset evolution`: https://www.mercurial-scm.org/wiki/ChangesetEvolution
+.. _`changeset evolution`: https://wiki.mercurial-scm.org/ChangesetEvolution
 
 Documentation
 -------------
@@ -48,44 +48,101 @@
 
     $ pip install --user hg-evolve
 
-Then enable it in your hgrc::
+Note: some distributions have adopted PEP 668 and made using ``pip install
+--user`` more difficult than it should be. One of the cleanest ways around this
+issue is to install both Mercurial and this extension in a separate virtual
+environment. If you don't want to manage the virtual environment manually, you
+can use Pipx.
+
+Using Pipx
+----------
+
+Its documentation explains that "pipx is made specifically for application
+installation", and the idea is that for every application it can create and
+maintain a separate virtual environment and make all executables available on a
+single path (e.g. ~/.local/bin/ on Linux, check ``pipx ensurepath``).
+
+To create a virtual environment for hg and install evolve::
+
+    $ pipx install mercurial
+    $ pipx inject mercurial hg-evolve
+    # or pipx runpip mercurial install hg-evolve
+
+Note: it's recommended to use ``inject`` command to install evolve, but
+sometimes ``runpip`` could be used. On some setups ``inject`` might require
+specifying the full path to the extension in the configuration file, while
+``runpip`` might not.
+
+Using Your Package Manager
+--------------------------
+
+Sometimes your distribution's package manager might have the newest (or recent
+enough) version of the extension. For example, both `Debian`_ and `Ubuntu`_
+currently have a package called ``mercurial-evolve``.  Similarly, other
+distributions might have it packaged, possibly under a slightly different name.
+Try searching your package manager's database or see `this Repology page`_.
+
+.. _`Debian`: https://packages.debian.org/search?keywords=mercurial-evolve&searchon=names&exact=1&suite=all&section=all
+.. _`Ubuntu`: https://packages.ubuntu.com/search?keywords=mercurial-evolve&searchon=names&exact=1&suite=all&section=all
+.. _`this Repology page`: https://repology.org/project/mercurial-evolve/related
+
+From Source
+-----------
+
+To obtain a local version from source::
+
+    $ hg clone https://repo.mercurial-scm.org/evolve
+
+There's no need to compile anything or run ``make``.
+
+This method keeps the extension in its own repo, and you can use it by
+specifying the full path to the ``hgext3rd/evolve/``.
+
+Alternatively, you can install it::
+
+    $ cd evolve
+    # optionally `hg update <target revision>`
+    $ pip install --user .
+
+This should avoid the need to specify the full path to the extension.
+
+Enabling the Extension
+----------------------
+
+After installing the extension, you need to enable it before you can use it.
+
+To do that, edit your hgrc::
 
     $ hg config --edit # add these two lines:
     [extensions]
     evolve =
 
-From Source
------------
-
-To install a local version from source::
-
-    $ hg clone https://www.mercurial-scm.org/repo/evolve/
-    $ cd evolve
-    # optionally `hg update <target revision>`
-    $ pip install --user .
-
-Then enable it in your hgrc::
-
-    $ hg config --edit # add these two lines:
-    [extensions]
-    evolve =
-
-It's also possible to use evolve without installing it, in which case you will
-need to provide the full path to ``hgext3rd/evolve/``, for example::
+If you didn't install the extension or Mercurial can't find it on one of the
+default paths, you need to specify the full path to ``hgext3rd/evolve/``::
 
     [extensions]
     evolve = ~/evolve/hgext3rd/evolve
 
+Similarly, if you want to enable topic extension, do this::
+
+    $ hg config --edit
+    [extensions]
+    topic =
+    # or
+    topic = ~/evolve/hgext3rd/topic
+
 Pitfalls
 --------
 
 If you get ``"failed to import extension evolve: No module named 'evolve'"``
 error, there are a couple of things to check:
 
-* make sure you gave pip the correct package name (it's hg-evolve),
+* make sure you gave pip/pipx the correct package name (it's ``hg-evolve``),
 
 * make sure evolve is installed for the same version of Python that you use for
-  running Mercurial (``hg debuginstall | grep Python``).
+  running Mercurial (``hg debuginstall | grep Python``),
+
+* try specifying the full path to the ``hgext3rd/evolve/`` directory.
 
 Extension Purpose
 =================
@@ -110,7 +167,7 @@
 Mercurial announced official `support for Python 3`_ starting with its 5.2
 release. Since 9.3.0, evolve has official support for Python 3.6+.
 
-.. _`support for Python 3`: https://www.mercurial-scm.org/wiki/Python3
+.. _`support for Python 3`: https://wiki.mercurial-scm.org/Python3
 
 Python 2 Support
 ================
@@ -146,7 +203,7 @@
 
 For guidelines on the patch description, see the `official Mercurial guideline`_.
 
-.. _`official Mercurial guideline`: https://mercurial-scm.org/wiki/ContributingChanges#Patch_descriptions
+.. _`official Mercurial guideline`: https://wiki.mercurial-scm.org/ContributingChanges#Patch_descriptions
 
 Please don't forget to update and run the tests when you fix a bug or add a
 feature. To run the tests, you need a working copy of Mercurial, say in
--- a/debian/changelog	Thu Jun 27 09:47:05 2024 +0400
+++ b/debian/changelog	Fri Oct 25 18:14:41 2024 +0400
@@ -1,3 +1,9 @@
+mercurial-evolve (11.1.4-1) unstable; urgency=medium
+
+  * new upstream release
+
+ -- Anton Shestakov <av6@dwimlabs.net>  Fri, 28 Jun 2024 17:01:09 +0400
+
 mercurial-evolve (11.1.3-1) unstable; urgency=medium
 
   * new upstream release
--- a/hgext3rd/evolve/evolvecmd.py	Thu Jun 27 09:47:05 2024 +0400
+++ b/hgext3rd/evolve/evolvecmd.py	Fri Oct 25 18:14:41 2024 +0400
@@ -1897,10 +1897,10 @@
         cleanup = True
         startnode = evolvestate[b'startnode']
         for old, new in evolvestate[b'replacements'].items():
-            if new:
+            if new and new in repo:
                 evolvedctx.append(repo[new])
         for temp in evolvestate[b'temprevs']:
-            if temp:
+            if temp and temp in repo:
                 evolvedctx.append(repo[temp])
         evolvedrevs = [c.rev() for c in evolvedctx]
 
--- a/hgext3rd/evolve/metadata.py	Thu Jun 27 09:47:05 2024 +0400
+++ b/hgext3rd/evolve/metadata.py	Fri Oct 25 18:14:41 2024 +0400
@@ -5,7 +5,7 @@
 # This software may be used and distributed according to the terms of the
 # GNU General Public License version 2 or any later version.
 
-__version__ = b'11.1.4.dev0'
-testedwith = b'4.9 5.0 5.1 5.2 5.3 5.4 5.5 5.6 5.7 5.8 5.9 6.0 6.1 6.2 6.3 6.4 6.5 6.6 6.7 6.8'
+__version__ = b'11.1.5.dev0'
+testedwith = b'4.9 5.0 5.1 5.2 5.3 5.4 5.5 5.6 5.7 5.8 5.9 6.0 6.1 6.2 6.3 6.4 6.5 6.6 6.7 6.8 6.9'
 minimumhgversion = b'4.9'
 buglink = b'https://bz.mercurial-scm.org/'
--- a/hgext3rd/topic/__init__.py	Thu Jun 27 09:47:05 2024 +0400
+++ b/hgext3rd/topic/__init__.py	Fri Oct 25 18:14:41 2024 +0400
@@ -238,9 +238,9 @@
               b'log.topic': b'green_background',
               }
 
-__version__ = b'1.1.4.dev0'
+__version__ = b'1.1.5.dev0'
 
-testedwith = b'4.9 5.0 5.1 5.2 5.3 5.4 5.5 5.6 5.7 5.8 5.9 6.0 6.1 6.2 6.3 6.4 6.5 6.6 6.7 6.8'
+testedwith = b'4.9 5.0 5.1 5.2 5.3 5.4 5.5 5.6 5.7 5.8 5.9 6.0 6.1 6.2 6.3 6.4 6.5 6.6 6.7 6.8 6.9'
 minimumhgversion = b'4.9'
 buglink = b'https://bz.mercurial-scm.org/'
 
--- a/hgext3rd/topic/discovery.py	Thu Jun 27 09:47:05 2024 +0400
+++ b/hgext3rd/topic/discovery.py	Fri Oct 25 18:14:41 2024 +0400
@@ -6,7 +6,6 @@
 
 from mercurial.i18n import _
 from mercurial import (
-    branchmap,
     bundle2,
     discovery,
     encoding,
@@ -24,6 +23,12 @@
     compat,
 )
 
+try:
+    from mercurial.branching.rev_cache import revbranchcache
+except ImportError:
+    # hg <= 6.8 (f0e07efc199f)
+    from mercurial.branchmap import revbranchcache
+
 urlreq = util.urlreq
 
 @contextlib.contextmanager
@@ -391,10 +396,10 @@
     extensions.wrapfunction(wireprotov1server, '_capabilities', wireprotocaps)
     wirepeer.branchmaptns = wirepeer.branchmap
     wireprotov1server.wireprotocommand(b'branchmaptns', permission=b'pull')(wireprotobranchmaptns)
-    extensions.wrapfunction(branchmap.revbranchcache, 'branchinfo', wrapbranchinfo)
+    extensions.wrapfunction(revbranchcache, 'branchinfo', wrapbranchinfo)
     # branchinfo method can get replaced by _branchinfo method directly when
     # on-disk revbranchcache is not available, see revbranchcache.__init__()
-    extensions.wrapfunction(branchmap.revbranchcache, '_branchinfo', wrapslowbranchinfo)
+    extensions.wrapfunction(revbranchcache, '_branchinfo', wrapslowbranchinfo)
     # we need a proper wrap b2 part stuff
     extensions.wrapfunction(bundle2, 'handlecheckheads', handlecheckheads)
     bundle2.handlecheckheads.params = frozenset()
--- a/setup.py	Thu Jun 27 09:47:05 2024 +0400
+++ b/setup.py	Fri Oct 25 18:14:41 2024 +0400
@@ -40,6 +40,7 @@
     url='https://www.mercurial-scm.org/doc/evolution/',
     description='Flexible evolution of Mercurial history.',
     long_description=open(join(dirname(__file__), 'README.rst')).read(),
+    long_description_content_type='text/x-rst',
     keywords='hg mercurial',
     license='GPLv2+',
     packages=py_packages,
--- a/tests/hghaveaddon.py	Thu Jun 27 09:47:05 2024 +0400
+++ b/tests/hghaveaddon.py	Fri Oct 25 18:14:41 2024 +0400
@@ -29,6 +29,11 @@
     return hghave.matchoutput('check-manifest --version 2>&1',
                               br'check-manifest version')
 
+@hghave.check("twine", "twine utility for publishing Python packages")
+def has_twine():
+    return hghave.matchoutput('twine --help 2>&1',
+                              br'usage: twine .*\bcheck\b')
+
 @hghave.check("default-cg3", "changegroup3 by default")
 def has_default_changegroup3():
     from mercurial import configitems
--- a/tests/test-check-commit.t	Thu Jun 27 09:47:05 2024 +0400
+++ b/tests/test-check-commit.t	Fri Oct 25 18:14:41 2024 +0400
@@ -5,25 +5,33 @@
 
   $ exit 80
 
+  $ . "$RUNTESTDIR/helpers-testrepo.sh"
+
 Enable obsolescence to avoid the warning issue when obsmarkers are found
 
   $ cat << EOF >> $HGRCPATH
   > [experimental]
   > evolution = all
-  > [diff]
-  > git = yes
   > EOF
 
 Go back in the hg repo
 
   $ cd $TESTDIR/..
 
-  $ for node in `hg log --rev 'not public() and ::. and not desc("# no-check-commit")' --template '{node|short}\n'`; do
-  >    hg export $node | ${RUNTESTDIR}/../contrib/check-commit > ${TESTTMP}/check-commit.out
-  >    if [ $? -ne 0 ]; then
-  >        echo "Revision $node does not comply with rules"
-  >        echo '------------------------------------------------------'
-  >        cat ${TESTTMP}/check-commit.out
-  >        echo
-  >   fi
-  > done
+  $ REVSET='not public() and ::. and not desc("# no-check-commit")'
+
+  $ mkdir "$TESTTMP/p"
+  $ REVS=`testrepohg log -r "$REVSET" -T.`
+  $ if [ -n "$REVS" ] ; then
+  >   testrepohg export --git -o "$TESTTMP/p/%n-%h" -r "$REVSET"
+  >   for f in `ls "$TESTTMP/p"`; do
+  >      "$RUNTESTDIR/../contrib/check-commit" < "$TESTTMP/p/$f" > "$TESTTMP/check-commit.out"
+  >      if [ $? -ne 0 ]; then
+  >          node="${f##*-}"
+  >          echo "Revision $node does not comply with rules"
+  >          echo '------------------------------------------------------'
+  >          cat ${TESTTMP}/check-commit.out
+  >          echo
+  >     fi
+  >   done
+  > fi
--- a/tests/test-check-flake8.t	Thu Jun 27 09:47:05 2024 +0400
+++ b/tests/test-check-flake8.t	Fri Oct 25 18:14:41 2024 +0400
@@ -1,12 +1,14 @@
 #require test-repo flake8
 
+  $ . "$RUNTESTDIR/helpers-testrepo.sh"
+
 Copied from Mercurial core (60ee2593a270)
 
   $ cd "`dirname "$TESTDIR"`"
 
 run flake8 on all tracked files ending in .py or with a python shebang
 
-  $ hg files -0 'set:(**.py or grep("^#!.*python")) - removed()' \
+  $ testrepohg files -0 'set:(**.py or grep("^#!.*python")) - removed()' \
   > -X hgext3rd/evolve/thirdparty \
   > 2>/dev/null \
   > | xargs -0 "$PYTHON" -m flake8
--- a/tests/test-check-pyflakes.t	Thu Jun 27 09:47:05 2024 +0400
+++ b/tests/test-check-pyflakes.t	Fri Oct 25 18:14:41 2024 +0400
@@ -1,12 +1,14 @@
 #require test-repo pyflakes
 
+  $ . "$RUNTESTDIR/helpers-testrepo.sh"
+
 Copied from Mercurial core (60ee2593a270)
 
   $ cd "`dirname "$TESTDIR"`"
 
 run pyflakes on all tracked files ending in .py or with a python shebang
 
-  $ hg files -0 'set:(**.py or grep("^#!.*python")) - removed()' \
+  $ testrepohg files -0 'set:(**.py or grep("^#!.*python")) - removed()' \
   > -X hgext3rd/evolve/thirdparty \
   > 2>/dev/null \
   > | xargs -0 "$PYTHON" -m pyflakes 2>/dev/null
--- a/tests/test-check-sdist.t	Thu Jun 27 09:47:05 2024 +0400
+++ b/tests/test-check-sdist.t	Fri Oct 25 18:14:41 2024 +0400
@@ -11,16 +11,17 @@
 
 #if test-repo
 
-  $ hg archive "$TESTTMP"/hg-evolve
+  $ . "$RUNTESTDIR/helpers-testrepo.sh"
+  $ testrepohg archive "$TESTTMP"/hg-evolve
   $ cd "$TESTTMP"/hg-evolve
 
 #endif
 
   $ "$PYTHON" setup.py sdist --dist-dir "$TESTTMP"/dist > /dev/null
-  */dist.py:*: UserWarning: Unknown distribution option: 'python_requires' (glob)
-    warnings.warn(msg)
-  warning: sdist: standard file not found: should have one of README, README.txt (?)
-   (?)
+  */dist.py:*: UserWarning: Unknown distribution option: 'long_description_content_type' (glob) (?)
+    warnings.warn(msg) (?)
+  */dist.py:*: UserWarning: Unknown distribution option: 'python_requires' (glob) (?)
+    warnings.warn(msg) (?)
   warning: no previously-included files found matching 'docs/tutorial/.netlify'
   warning: no previously-included files found matching '.gitlab-ci.yml'
   warning: no previously-included files found matching '.hg-format-source'
@@ -30,35 +31,40 @@
   no previously-included directories found matching '.gitlab'
   $ cd "$TESTTMP"/dist
 
-  $ find hg-evolve-*.tar.gz -size +800000c
-  hg-evolve-*.tar.gz (glob)
+  $ find hg?evolve-*.tar.gz -size +800000c
+  hg?evolve-*.tar.gz (glob)
 
-  $ tar -tzf hg-evolve-*.tar.gz | sed 's|^hg-evolve-[^/]*/||' | sort > files
-  $ egrep '^tests/test-.*\.(t|py)$' files > test-files
-  $ egrep -v '^tests/test-.*\.(t|py)$' files > other-files
-  $ wc -l other-files
-  148 other-files
-  $ wc -l test-files
-  ??? test-files (glob)
-  $ fgrep debian files
+  $ tar -tzf hg?evolve-*.tar.gz | sed 's|^hg.evolve-[^/]*/||' | sort > ../files
+  $ grep -E '^tests/test-.*\.(t|py)$' ../files > ../test-files
+  $ grep -E -v '^tests/test-.*\.(t|py)$' ../files > ../other-files
+  $ wc -l ../other-files
+  ??? ../other-files (glob)
+  $ wc -l ../test-files
+  ??? ../test-files (glob)
+  $ grep -F debian ../files
   tests/test-check-debian.t
-  $ fgrep __init__.py files
+  $ grep -F __init__.py ../files
   hgext3rd/__init__.py
   hgext3rd/evolve/__init__.py
   hgext3rd/evolve/thirdparty/__init__.py
   hgext3rd/topic/__init__.py
-  $ fgrep common.sh files
+  $ grep -F common.sh ../files
   docs/tutorial/testlib/common.sh
   tests/testlib/common.sh
-  $ fgrep README files
+  $ grep -F README ../files
   README.rst
   docs/README
   docs/tutorial/README.rst
   hgext3rd/topic/README
 
-  $ egrep '(gitlab|contrib|hack|format-source)' files
+  $ grep -E '(gitlab|contrib|hack|format-source)' ../files
+  [1]
+  $ grep -F legacy.py ../files
+  [1]
+  $ grep -F netlify ../files
   [1]
-  $ fgrep legacy.py files
-  [1]
-  $ fgrep netlify files
-  [1]
+
+#if twine
+  $ twine --no-color check *
+  Checking hg?evolve-*.tar.gz: PASSED (glob)
+#endif
--- a/tests/test-check-tag.t	Thu Jun 27 09:47:05 2024 +0400
+++ b/tests/test-check-tag.t	Fri Oct 25 18:14:41 2024 +0400
@@ -2,38 +2,35 @@
 
 Enable obsolescence to avoid the warning issue when obsmarkers are found
 
-  $ cat << EOF >> $HGRCPATH
-  > [experimental]
-  > evolution = all
-  > EOF
+  $ . "$RUNTESTDIR/helpers-testrepo.sh"
 
   $ cd "$TESTDIR"/..
 
 Checking all non-public tagged revisions up to the current commit, see our
 release checklist for more ideas
 
-  $ for node in `hg log --rev 'tag() and ::. and not public() and not desc("# no-check-commit")' --template '{node|short}\n'`; do
-  >   tags=`hg log --rev $node --template '{tags}\n'`
+  $ for node in `testrepohg log --rev 'tag() and ::. and not public() and not desc("# no-check-commit")' --template '{node|short}\n'`; do
+  >   tags=`testrepohg log --rev $node --template '{tags}\n'`
   >   if echo "$tags" | grep -q ' '; then
   >     echo "Revision $node is tagged multiple times: $tags"
   >   fi
-  >   branch=`hg log --rev $node --template '{branch}\n'`
+  >   branch=`testrepohg log --rev $node --template '{branch}\n'`
   >   if [ "$branch" != "stable" ]; then
   >     echo "Revision $node is not on stable branch: $branch"
   >   fi
   >   # Here we skip:
   >   # - pullbundle because it usually has no changes (so no version bump)
-  >   if hg grep --rev $node '^__version__ = .*\.dev' hgext3rd/evolve/ hgext3rd/topic/; then
+  >   if testrepohg grep --rev $node '^__version__ = .*\.dev' hgext3rd/evolve/ hgext3rd/topic/; then
   >     echo "Versions should not end with .dev at tagged revision $node"
   >   fi
-  >   entry=`hg cat --rev $node CHANGELOG | fgrep "$tags"`
+  >   entry=`testrepohg cat --rev $node CHANGELOG | grep -F "$tags"`
   >   if [ -z "$entry" ]; then
   >     echo "Revision $node has no CHANGELOG entry for $tags"
   >   fi
-  >   if echo "$entry" | egrep -vq ' -- [0-9]{4}-[0-9]{2}-[0-9]{2}'; then
+  >   if echo "$entry" | grep -E -vq ' -- [0-9]{4}-[0-9]{2}-[0-9]{2}'; then
   >     echo "CHANGELOG entry for $tags should have a date in YYYY-MM-DD format: $entry"
   >   fi
-  >   entry=`hg cat --rev $node debian/changelog | fgrep "$tags"`
+  >   entry=`testrepohg cat --rev $node debian/changelog | grep -F "$tags"`
   >   if [ -z "$entry" ]; then
   >     echo "Revision $node has no debian/changelog entry for $tags"
   >   fi
--- a/tests/test-doctest.py	Thu Jun 27 09:47:05 2024 +0400
+++ b/tests/test-doctest.py	Fri Oct 25 18:14:41 2024 +0400
@@ -67,11 +67,15 @@
 if not os.path.isdir(os.path.join(cwd, ".hg")):
     sys.exit(0)
 
-files = subprocess.check_output(
-    "hg files --print0 \"%s\"" % fileset,
-    shell=True,
-    cwd=cwd,
-).split(b'\0')
+files_cmd = 'hg files --print0 "%s"' % fileset
+
+# we prefer system hg for reading the repository, unless we're on python2
+# because then we assume that system hg is too old (this is not always true,
+# but it's an easy check and works well enough for us)
+if ispy3 and 'HGTEST_RESTOREENV':
+    files_cmd = '. $HGTEST_RESTOREENV; ' + files_cmd
+
+files = subprocess.check_output(files_cmd, shell=True, cwd=cwd).split(b'\0')
 
 if sys.version_info[0] >= 3:
     cwd = os.fsencode(cwd)
--- a/tests/test-extension-isolation.t	Thu Jun 27 09:47:05 2024 +0400
+++ b/tests/test-extension-isolation.t	Fri Oct 25 18:14:41 2024 +0400
@@ -117,34 +117,34 @@
 Check evolve isolation
 -----------------------
 
-  $ hg debugcapabilities http://$LOCALIP:$HGPORT/repo-no-ext | egrep 'topics|evoext'
+  $ hg debugcapabilities http://$LOCALIP:$HGPORT/repo-no-ext | grep -E 'topics|evoext'
   [1]
-  $ hg debugcapabilities http://$LOCALIP:$HGPORT/repo-evo | egrep 'topics|evoext'
+  $ hg debugcapabilities http://$LOCALIP:$HGPORT/repo-evo | grep -E 'topics|evoext'
     _evoext_getbundle_obscommon
     _evoext_obshashrange_v1
-  $ hg debugcapabilities http://$LOCALIP:$HGPORT/repo-no-ext | egrep 'topics|evoext'
+  $ hg debugcapabilities http://$LOCALIP:$HGPORT/repo-no-ext | grep -E 'topics|evoext'
   [1]
 
 Check topic isolation
 ---------------------
 
-  $ hg debugcapabilities http://$LOCALIP:$HGPORT/repo-no-ext | egrep 'topics|evoext'
+  $ hg debugcapabilities http://$LOCALIP:$HGPORT/repo-no-ext | grep -E 'topics|evoext'
   [1]
-  $ hg debugcapabilities http://$LOCALIP:$HGPORT/repo-topic | egrep 'topics|evoext'
+  $ hg debugcapabilities http://$LOCALIP:$HGPORT/repo-topic | grep -E 'topics|evoext'
     _exttopics_heads
     ext-topics-publish=all
     ext-topics-tns-heads
     topics
     topics-namespaces
-  $ hg debugcapabilities http://$LOCALIP:$HGPORT/repo-no-ext | egrep 'topics|evoext'
+  $ hg debugcapabilities http://$LOCALIP:$HGPORT/repo-no-ext | grep -E 'topics|evoext'
   [1]
 
 Check coupled isolation
 -----------------------
 
-  $ hg debugcapabilities http://$LOCALIP:$HGPORT/repo-no-ext | egrep 'topics|evoext'
+  $ hg debugcapabilities http://$LOCALIP:$HGPORT/repo-no-ext | grep -E 'topics|evoext'
   [1]
-  $ hg debugcapabilities http://$LOCALIP:$HGPORT/repo-both | egrep 'topics|evoext'
+  $ hg debugcapabilities http://$LOCALIP:$HGPORT/repo-both | grep -E 'topics|evoext'
     _evoext_getbundle_obscommon
     _evoext_obshashrange_v1
     _exttopics_heads
@@ -152,19 +152,19 @@
     ext-topics-tns-heads
     topics
     topics-namespaces
-  $ hg debugcapabilities http://$LOCALIP:$HGPORT/repo-evo | egrep 'topics|evoext'
+  $ hg debugcapabilities http://$LOCALIP:$HGPORT/repo-evo | grep -E 'topics|evoext'
     _evoext_getbundle_obscommon
     _evoext_obshashrange_v1
-  $ hg debugcapabilities http://$LOCALIP:$HGPORT/repo-topic | egrep 'topics|evoext'
+  $ hg debugcapabilities http://$LOCALIP:$HGPORT/repo-topic | grep -E 'topics|evoext'
     _exttopics_heads
     ext-topics-publish=all
     ext-topics-tns-heads
     topics
     topics-namespaces
-  $ hg debugcapabilities http://$LOCALIP:$HGPORT/repo-evo | egrep 'topics|evoext'
+  $ hg debugcapabilities http://$LOCALIP:$HGPORT/repo-evo | grep -E 'topics|evoext'
     _evoext_getbundle_obscommon
     _evoext_obshashrange_v1
-  $ hg debugcapabilities http://$LOCALIP:$HGPORT/repo-no-ext | egrep 'topics|evoext'
+  $ hg debugcapabilities http://$LOCALIP:$HGPORT/repo-no-ext | grep -E 'topics|evoext'
   [1]
 
 Final cleanup
--- a/tests/test-topic-issue6841.t	Thu Jun 27 09:47:05 2024 +0400
+++ b/tests/test-topic-issue6841.t	Fri Oct 25 18:14:41 2024 +0400
@@ -43,8 +43,7 @@
 
 on-disk caches are using bare branch names only
 
-  $ f -H .hg/cache/rbc-names-v1
-  .hg/cache/rbc-names-v1:
+  $ f -Hq .hg/cache/rbc-names-v?
   0000: 64 65 66 61 75 6c 74                            |default|
   $ grep topic-foo .hg/cache/*
   [1]
--- a/tests/test-topic-tutorial.t	Thu Jun 27 09:47:05 2024 +0400
+++ b/tests/test-topic-tutorial.t	Fri Oct 25 18:14:41 2024 +0400
@@ -6,12 +6,12 @@
 
 .. Various setup
 
-  $ . "$TESTDIR/testlib/topic_setup.sh"
+  $ . "$TESTDIR/testlib/common.sh" #rest-ignore
   $ cat >> $HGRCPATH << EOF
-  > [experimental]
-  > evolution=all
   > [extensions]
-  > evolve=
+  > evolve =
+  > rebase =
+  > topic =
   > EOF
 
   $ hg init server
@@ -20,7 +20,7 @@
 
   $ cat >> .hg/hgrc << EOF
   > [ui]
-  > user= Shopping Master
+  > user = Shopping Master
   > EOF
 
   $ cat >> shopping << EOF
@@ -43,7 +43,7 @@
   $ cd client
   $ cat >> .hg/hgrc << EOF
   > [ui]
-  > user= Tutorial User
+  > user = Tutorial User
   > EOF
 #if docgraph-ext
   $ . "$TESTDIR/testlib/docgraph_setup.sh" #rest-ignore
@@ -100,7 +100,7 @@
   marked working directory as topic: food
 
 Much like a named branch, our topic is active but it does not contain any
-changeset yet:
+changesets yet:
 
   $ hg topics
    * food (0 changesets)
@@ -147,7 +147,7 @@
 
   $ cat >> shopping << EOF
   > Egg
-  > Suggar
+  > Sugar
   > Vinegar
   > Oil
   > EOF
@@ -157,7 +157,7 @@
   (see 'hg help topics' for more information)
 
   $ hg log --graph --rev 'topic("food")'
-  @  changeset:   1:13900241408b
+  @  changeset:   1:9e90e00c084b
   |  tag:         tip
   ~  topic:       food
      user:        test
@@ -198,14 +198,14 @@
   $ hg commit -m "adding fruits"
 
   $ hg log --graph --rev 'topic("food")'
-  @  changeset:   2:287de11b401f
+  @  changeset:   2:a25aaa6b9385
   |  tag:         tip
   |  topic:       food
   |  user:        test
   |  date:        Thu Jan 01 00:00:00 1970 +0000
   |  summary:     adding fruits
   |
-  o  changeset:   1:13900241408b
+  o  changeset:   1:9e90e00c084b
   |  topic:       food
   ~  user:        test
      date:        Thu Jan 01 00:00:00 1970 +0000
@@ -268,14 +268,14 @@
 changeset of default without a topic:
 
   $ hg log --graph
-  o  changeset:   2:287de11b401f
+  o  changeset:   2:a25aaa6b9385
   |  tag:         tip
   |  topic:       food
   |  user:        test
   |  date:        Thu Jan 01 00:00:00 1970 +0000
   |  summary:     adding fruits
   |
-  o  changeset:   1:13900241408b
+  o  changeset:   1:9e90e00c084b
   |  topic:       food
   |  user:        test
   |  date:        Thu Jan 01 00:00:00 1970 +0000
@@ -395,13 +395,13 @@
   |  date:        Thu Jan 01 00:00:00 1970 +0000
   |  summary:     Adding clothes
   |
-  | o  changeset:   2:287de11b401f
+  | o  changeset:   2:a25aaa6b9385
   | |  topic:       food
   | |  user:        test
   | |  date:        Thu Jan 01 00:00:00 1970 +0000
   | |  summary:     adding fruits
   | |
-  | @  changeset:   1:13900241408b
+  | @  changeset:   1:9e90e00c084b
   |/   topic:       food
   |    user:        test
   |    date:        Thu Jan 01 00:00:00 1970 +0000
@@ -488,21 +488,21 @@
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
 
   $ hg rebase
-  rebasing 1:13900241408b "adding condiments" (food)
+  rebasing 1:9e90e00c084b "adding condiments" (food)
   merging shopping
   switching to topic food
-  rebasing 2:287de11b401f "adding fruits" (food)
+  rebasing 2:a25aaa6b9385 "adding fruits" (food)
   merging shopping
 
   $ hg log --graph
-  @  changeset:   5:2d50db8b5b4c
+  @  changeset:   5:fec062fcfcfa
   |  tag:         tip
   |  topic:       food
   |  user:        test
   |  date:        Thu Jan 01 00:00:00 1970 +0000
   |  summary:     adding fruits
   |
-  o  changeset:   4:4011b46eeb33
+  o  changeset:   4:d3a1ea2a0337
   |  topic:       food
   |  user:        test
   |  date:        Thu Jan 01 00:00:00 1970 +0000
@@ -580,9 +580,9 @@
 There exists a template keyword named "topic" which can be used
 
   $ hg log -GT "{rev}:{node|short} {topic}\n {desc}"
-  @  5:2d50db8b5b4c food
+  @  5:fec062fcfcfa food
   |   adding fruits
-  o  4:4011b46eeb33 food
+  o  4:d3a1ea2a0337 food
   |   adding condiments
   o  3:6104862e8b84
   |   Adding clothes
@@ -618,13 +618,13 @@
   s0^ adding fruits (base current)
 
   $ hg log --graph
-  @  changeset:   5:2d50db8b5b4c
+  @  changeset:   5:fec062fcfcfa
   |  tag:         tip
   |  user:        test
   |  date:        Thu Jan 01 00:00:00 1970 +0000
   |  summary:     adding fruits
   |
-  o  changeset:   4:4011b46eeb33
+  o  changeset:   4:d3a1ea2a0337
   |  user:        test
   |  date:        Thu Jan 01 00:00:00 1970 +0000
   |  summary:     adding condiments
@@ -713,7 +713,7 @@
 Keep working within topics
 ==========================
 
-Making sure all your new local commit are made within a topic will help you
+Making sure all your new local commits are made within a topic will help you
 organize your work. It is possible to ensure this through the Mercurial
 configuration.
 
@@ -724,10 +724,10 @@
   > topic-mode = enforce
   > EOF
 
-You can also use `hg config --edit` to update your mercurial configuration.
+You can also use `hg config --edit` to update your Mercurial configuration.
 
 
-Once enforcement is turned on. New local commit will be denied if no topic is active.
+Once enforcement is turned on, new local commits will be denied if no topic is active.
 
   $ echo sickle >> shopping
   $ hg commit -m 'Adding sickle'
@@ -764,7 +764,7 @@
   $ echo drill >> shopping
   $ hg commit -m 'Adding drill'
 
-But we are not sure we will actually go to the hardware store, so in the
+But we are not sure if we will actually go to the hardware store, so in the
 meantime, we want to extend the list with drinks. We go back to the official
 default branch and start a new topic:
 
@@ -815,7 +815,7 @@
   nothing to rebase
   [1]
 
-We simulate independant contributions to the repo with this
+We simulate independent contributions to the repo with this
 activity:
 
   $ cd ../server
@@ -832,7 +832,7 @@
   $ hg commit -m 'add a pair of shoes'
   $ cd ../client
 
-Let's discover what other people did contribute:
+Let's discover what other people have contributed:
 
   $ hg pull
   pulling from $TESTTMP/server (glob)
@@ -841,62 +841,62 @@
   adding manifests
   adding file changes
   added 2 changesets with 2 changes to 1 files (+1 heads)
-  new changesets f2d6cacc6115:fbff9bc37a43
+  new changesets bbfb218049cd:033bfcc0ecb0
   (run 'hg heads' to see heads)
 
 There are new changes! We can simply use ``hg rebase`` to update our
 changeset on top of the latest:
 
   $ hg log -G
-  o  changeset:   12:fbff9bc37a43
+  o  changeset:   12:033bfcc0ecb0
   |  tag:         tip
   |  user:        test
   |  date:        Thu Jan 01 00:00:00 1970 +0000
   |  summary:     add a pair of shoes
   |
-  o  changeset:   11:f2d6cacc6115
-  |  parent:      5:2d50db8b5b4c
+  o  changeset:   11:bbfb218049cd
+  |  parent:      5:fec062fcfcfa
   |  user:        test
   |  date:        Thu Jan 01 00:00:00 1970 +0000
   |  summary:     add a coat
   |
-  | o  changeset:   10:70dfa201ed73
+  | o  changeset:   10:0b8a99ba9213
   | |  topic:       drinks
   | |  user:        test
   | |  date:        Thu Jan 01 00:00:00 1970 +0000
   | |  summary:     Adding orange juice
   | |
-  | o  changeset:   9:8dfa45bd5e0c
+  | o  changeset:   9:213e97c6cd8a
   |/   topic:       drinks
-  |    parent:      5:2d50db8b5b4c
+  |    parent:      5:fec062fcfcfa
   |    user:        test
   |    date:        Thu Jan 01 00:00:00 1970 +0000
   |    summary:     Adding apple juice
   |
-  | @  changeset:   8:34255b455dac
+  | @  changeset:   8:9ef4e4f40a79
   | |  topic:       tools
   | |  user:        test
   | |  date:        Thu Jan 01 00:00:00 1970 +0000
   | |  summary:     Adding drill
   | |
-  | o  changeset:   7:cffff85af537
+  | o  changeset:   7:c1d9846a234f
   | |  topic:       tools
   | |  user:        test
   | |  date:        Thu Jan 01 00:00:00 1970 +0000
   | |  summary:     Adding saw
   | |
-  | o  changeset:   6:183984ef46d1
+  | o  changeset:   6:6d6f38ff45f0
   |/   topic:       tools
   |    user:        test
   |    date:        Thu Jan 01 00:00:00 1970 +0000
   |    summary:     Adding hammer
   |
-  o  changeset:   5:2d50db8b5b4c
+  o  changeset:   5:fec062fcfcfa
   |  user:        test
   |  date:        Thu Jan 01 00:00:00 1970 +0000
   |  summary:     adding fruits
   |
-  o  changeset:   4:4011b46eeb33
+  o  changeset:   4:d3a1ea2a0337
   |  user:        test
   |  date:        Thu Jan 01 00:00:00 1970 +0000
   |  summary:     adding condiments
@@ -1055,49 +1055,49 @@
 #endif
 
   $ hg rebase
-  rebasing 6:183984ef46d1 "Adding hammer" (tools)
+  rebasing 6:6d6f38ff45f0 "Adding hammer" (tools)
   merging shopping
   switching to topic tools
-  rebasing 7:cffff85af537 "Adding saw" (tools)
+  rebasing 7:c1d9846a234f "Adding saw" (tools)
   merging shopping
-  rebasing 8:34255b455dac "Adding drill" (tools)
+  rebasing 8:9ef4e4f40a79 "Adding drill" (tools)
   merging shopping
 
-But what about the other topic? You can use 'hg topics --verbose' to see
+But what about the other topic? You can use ``hg topics --verbose`` to see
 information about all the topics:
 
   $ hg topics --verbose
      drinks (on branch: default, 2 changesets, 2 behind)
    * tools  (on branch: default, 3 changesets)
 
-The "2 behind" is telling you that there are 2 new changesets over the base of the topic.
+The "2 behind" is telling you that there are 2 new changesets on top of the base of the topic.
 
 Pushing that topic would create a new head, and therefore will be prevented:
 
   $ hg push --rev drinks
   pushing to $TESTTMP/server (glob)
   searching for changes
-  abort: push creates new remote head 70dfa201ed73!
+  abort: push creates new remote head 0b8a99ba9213!
   (merge or see 'hg help push' for details about pushing new heads)
   [255]
 
 
 Even after a rebase, pushing all active topics at the same time would publish
-them to the default branch, and then mercurial would complain about the
+them to the default branch, and then Mercurial would complain about the
 multiple *public* heads it would create on that branch:
 
   $ hg rebase -b drinks
-  rebasing 9:8dfa45bd5e0c "Adding apple juice" (drinks)
+  rebasing 9:213e97c6cd8a "Adding apple juice" (drinks)
   merging shopping
   switching to topic drinks
-  rebasing 10:70dfa201ed73 "Adding orange juice" (drinks)
+  rebasing 10:0b8a99ba9213 "Adding orange juice" (drinks)
   merging shopping
   switching to topic tools
 
   $ hg push
   pushing to $TESTTMP/server (glob)
   searching for changes
-  abort: push creates new remote head 4cd7c1591a67!
+  abort: push creates new remote head 56656c6d1153!
   (merge or see 'hg help push' for details about pushing new heads)
   [255]
 
@@ -1113,7 +1113,7 @@
   added 2 changesets with 2 changes to 1 files
   2 new obsolescence markers
 
-The published topic has now faded out, and the other is now marked as
+The published topic has now faded out, and the other is now marked as being
 "behind":
 
   $ hg topics --verbose
@@ -1133,7 +1133,7 @@
 Navigating within your stack
 ----------------------------
 
-As we saw before `stack` displays changesets on your current topic in a clean way:
+As we saw before ``stack`` displays changesets on your current topic in a clean way:
 
   $ hg topics --verbose
    * tools (on branch: default, 3 changesets, 2 behind)
@@ -1146,9 +1146,9 @@
   s1: Adding hammer
   s0^ add a pair of shoes (base)
 
-You can navigate in your current stack with `previous` and `next`.
+You can navigate in your current stack with ``previous`` and ``next``.
 
-`previous` will bring you back to the parent of the topic head.
+``previous`` will bring you back to the parent of the topic head.
 
   $ hg previous
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
@@ -1162,7 +1162,7 @@
   s1: Adding hammer
   s0^ add a pair of shoes (base)
 
-`next` will move you forward to the topic head.
+``next`` will move you forward to the topic head.
 
   $ hg next
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
@@ -1176,7 +1176,7 @@
   s1: Adding hammer
   s0^ add a pair of shoes (base)
 
-You can also directly jump to a changeset within your stack with the revset `t#`.
+You can also directly jump to a changeset within your stack with the revset ``s<number>``.
 
   $ hg update s1
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
@@ -1209,47 +1209,47 @@
 it shows too many things:
 
   $ hg log -G -r "s0::"
-  @  changeset:   18:b7509bd417f8
+  @  changeset:   18:2c1a47a5c075
   |  tag:         tip
   |  topic:       tools
-  |  parent:      12:fbff9bc37a43
+  |  parent:      12:033bfcc0ecb0
   |  user:        test
   |  date:        Thu Jan 01 00:00:00 1970 +0000
   |  summary:     Adding hammer to the shopping list
   |
-  | o  changeset:   17:4cd7c1591a67
+  | o  changeset:   17:9dc8cec494f3
   | |  user:        test
   | |  date:        Thu Jan 01 00:00:00 1970 +0000
   | |  summary:     Adding orange juice
   | |
-  | o  changeset:   16:20759cb47ff8
-  |/   parent:      12:fbff9bc37a43
+  | o  changeset:   16:9dfd6068e8e7
+  |/   parent:      12:033bfcc0ecb0
   |    user:        test
   |    date:        Thu Jan 01 00:00:00 1970 +0000
   |    summary:     Adding apple juice
   |
-  | *  changeset:   15:bb1e6254f532
+  | *  changeset:   15:56656c6d1153
   | |  topic:       tools
   | |  user:        test
   | |  date:        Thu Jan 01 00:00:00 1970 +0000
   | |  instability: orphan
   | |  summary:     Adding drill
   | |
-  | *  changeset:   14:d4f97f32f8a1
+  | *  changeset:   14:a0ec1a6dcdce
   | |  topic:       tools
   | |  user:        test
   | |  date:        Thu Jan 01 00:00:00 1970 +0000
   | |  instability: orphan
   | |  summary:     Adding saw
   | |
-  | x  changeset:   13:a8ab3599d53d
+  | x  changeset:   13:dcb888ba1623
   |/   topic:       tools
   |    user:        test
   |    date:        Thu Jan 01 00:00:00 1970 +0000
-  |    obsolete:    reworded using amend as 18:b7509bd417f8
+  |    obsolete:    reworded using amend as 18:2c1a47a5c075
   |    summary:     Adding hammer
   |
-  o  changeset:   12:fbff9bc37a43
+  o  changeset:   12:033bfcc0ecb0
   |  user:        test
   ~  date:        Thu Jan 01 00:00:00 1970 +0000
      summary:     add a pair of shoes
@@ -1364,14 +1364,14 @@
   s1@ Adding hammer to the shopping list (current)
   s0^ add a pair of shoes (base)
 
-It's easy to stabilize the situation, `next` has an `--evolve` option.  It will
-do the necessary relocation of `s2` and `s3` over the new `s1` without having
-to do that rebase by hand.:
+It's easy to stabilize the situation, ``next`` has an ``--evolve`` option
+(turned on by default nowadays). It will do the necessary relocation of `s2`
+and `s3` over the new `s1` without having to do that rebase by hand:
 
   $ hg next --evolve
   move:[s2] Adding saw
   atop:[s1] Adding hammer to the shopping list
-  working directory is now at d5c51ee5762a
+  working directory is now at 7537e3a3cbca
 
   $ hg stack
   ### topic: tools
@@ -1386,7 +1386,7 @@
   $ hg next --evolve
   move:[s3] Adding drill
   atop:[s2] Adding saw
-  working directory is now at bae3758e46bf
+  working directory is now at 9d65331e0dc1
 
   $ hg stack
   ### topic: tools
@@ -1396,41 +1396,41 @@
   s1: Adding hammer to the shopping list
   s0^ add a pair of shoes (base)
 
-Let's take a look at `hg log` once again:
+Let's take a look at ``hg log`` once again:
 
   $ hg log -G -r "s0::"
-  @  changeset:   20:bae3758e46bf
+  @  changeset:   20:9d65331e0dc1
   |  tag:         tip
   |  topic:       tools
   |  user:        test
   |  date:        Thu Jan 01 00:00:00 1970 +0000
   |  summary:     Adding drill
   |
-  o  changeset:   19:d5c51ee5762a
+  o  changeset:   19:7537e3a3cbca
   |  topic:       tools
   |  user:        test
   |  date:        Thu Jan 01 00:00:00 1970 +0000
   |  summary:     Adding saw
   |
-  o  changeset:   18:b7509bd417f8
+  o  changeset:   18:2c1a47a5c075
   |  topic:       tools
-  |  parent:      12:fbff9bc37a43
+  |  parent:      12:033bfcc0ecb0
   |  user:        test
   |  date:        Thu Jan 01 00:00:00 1970 +0000
   |  summary:     Adding hammer to the shopping list
   |
-  | o  changeset:   17:4cd7c1591a67
+  | o  changeset:   17:9dc8cec494f3
   | |  user:        test
   | |  date:        Thu Jan 01 00:00:00 1970 +0000
   | |  summary:     Adding orange juice
   | |
-  | o  changeset:   16:20759cb47ff8
-  |/   parent:      12:fbff9bc37a43
+  | o  changeset:   16:9dfd6068e8e7
+  |/   parent:      12:033bfcc0ecb0
   |    user:        test
   |    date:        Thu Jan 01 00:00:00 1970 +0000
   |    summary:     Adding apple juice
   |
-  o  changeset:   12:fbff9bc37a43
+  o  changeset:   12:033bfcc0ecb0
   |  user:        test
   ~  date:        Thu Jan 01 00:00:00 1970 +0000
      summary:     add a pair of shoes
@@ -1548,61 +1548,61 @@
 completely linear history so it's what we will do.
 
   $ hg log -G
-  @  changeset:   21:f936c6da9d61
+  @  changeset:   21:69ad92f8ff49
   |  tag:         tip
   |  topic:       tools
-  |  parent:      18:b7509bd417f8
+  |  parent:      18:2c1a47a5c075
   |  user:        test
   |  date:        Thu Jan 01 00:00:00 1970 +0000
   |  summary:     Adding nails
   |
-  | o  changeset:   20:bae3758e46bf
+  | o  changeset:   20:9d65331e0dc1
   | |  topic:       tools
   | |  user:        test
   | |  date:        Thu Jan 01 00:00:00 1970 +0000
   | |  summary:     Adding drill
   | |
-  | o  changeset:   19:d5c51ee5762a
+  | o  changeset:   19:7537e3a3cbca
   |/   topic:       tools
   |    user:        test
   |    date:        Thu Jan 01 00:00:00 1970 +0000
   |    summary:     Adding saw
   |
-  o  changeset:   18:b7509bd417f8
+  o  changeset:   18:2c1a47a5c075
   |  topic:       tools
-  |  parent:      12:fbff9bc37a43
+  |  parent:      12:033bfcc0ecb0
   |  user:        test
   |  date:        Thu Jan 01 00:00:00 1970 +0000
   |  summary:     Adding hammer to the shopping list
   |
-  | o  changeset:   17:4cd7c1591a67
+  | o  changeset:   17:9dc8cec494f3
   | |  user:        test
   | |  date:        Thu Jan 01 00:00:00 1970 +0000
   | |  summary:     Adding orange juice
   | |
-  | o  changeset:   16:20759cb47ff8
-  |/   parent:      12:fbff9bc37a43
+  | o  changeset:   16:9dfd6068e8e7
+  |/   parent:      12:033bfcc0ecb0
   |    user:        test
   |    date:        Thu Jan 01 00:00:00 1970 +0000
   |    summary:     Adding apple juice
   |
-  o  changeset:   12:fbff9bc37a43
+  o  changeset:   12:033bfcc0ecb0
   |  user:        test
   |  date:        Thu Jan 01 00:00:00 1970 +0000
   |  summary:     add a pair of shoes
   |
-  o  changeset:   11:f2d6cacc6115
-  |  parent:      5:2d50db8b5b4c
+  o  changeset:   11:bbfb218049cd
+  |  parent:      5:fec062fcfcfa
   |  user:        test
   |  date:        Thu Jan 01 00:00:00 1970 +0000
   |  summary:     add a coat
   |
-  o  changeset:   5:2d50db8b5b4c
+  o  changeset:   5:fec062fcfcfa
   |  user:        test
   |  date:        Thu Jan 01 00:00:00 1970 +0000
   |  summary:     adding fruits
   |
-  o  changeset:   4:4011b46eeb33
+  o  changeset:   4:d3a1ea2a0337
   |  user:        test
   |  date:        Thu Jan 01 00:00:00 1970 +0000
   |  summary:     adding condiments
@@ -1777,9 +1777,9 @@
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
 
   $ hg rebase
-  rebasing 19:d5c51ee5762a "Adding saw" (tools)
+  rebasing 19:7537e3a3cbca "Adding saw" (tools)
   merging shopping
-  rebasing 20:bae3758e46bf "Adding drill" (tools)
+  rebasing 20:9d65331e0dc1 "Adding drill" (tools)
   merging shopping
 
   $ hg stack
@@ -1832,7 +1832,7 @@
   8 new obsolescence markers
 
 Pushing the new topic branch to a non-publishing server did not require
---force. As long as new heads are on their own topic, Mercurial will not
+``--force``. As long as new heads are on their own topic, Mercurial will not
 complain about them.
 
 From another client, we will get them with their topic:
@@ -1847,7 +1847,7 @@
   adding file changes
   added 4 changesets with 4 changes to 1 files (+1 heads)
   8 new obsolescence markers
-  new changesets b7509bd417f8:2d084ac00115 (4 drafts)
+  new changesets 2c1a47a5c075:bbb9e269a01a (4 drafts)
   (run 'hg heads' to see heads)
 
   $ hg topics --verbose
@@ -1891,7 +1891,7 @@
   adding manifests
   adding file changes
   added 1 changesets with 1 changes to 1 files
-  new changesets 0d409663a1fd (1 drafts)
+  new changesets 71d37f5c73ed (1 drafts)
   (run 'hg update' to get a working copy)
 
   $ hg update
--- a/tests/test-tutorial.t	Thu Jun 27 09:47:05 2024 +0400
+++ b/tests/test-tutorial.t	Fri Oct 25 18:14:41 2024 +0400
@@ -1,3 +1,6 @@
+===============
+Evolve Tutorial
+===============
 
 Initial setup
 -------------
@@ -99,11 +102,11 @@
   adding file changes
   added 1 changesets with 1 changes to 1 files
 
-Later I add additional item to my list
+Later I add additional items to my list
 
   $ cat >> shopping << EOF
   > Egg
-  > Suggar
+  > Sugar
   > Vinegar
   > Oil
   > EOF
@@ -115,12 +118,12 @@
   > EOF
   $ hg commit -m "adding fruit"
 
-This history is very linear
+The history is completely linear so far
 
   $ hg log -G
-  @  d85de4546133 (draft): adding fruit
+  @  4296f0622469 (draft): adding fruit
   |
-  o  4d5dc8187023 (draft): adding condiment
+  o  63ae8c44f4b6 (draft): adding condiment
   |
   o  7e82d3f3c2cb (public): Monthy Python Shopping list
   
@@ -170,22 +173,22 @@
       }
 #endif
 
-But a typo was made in Babanas!
+But a typo was made in Bananas!
 
   $ hg export tip
   # HG changeset patch
   # User test
   # Date 0 0
   #      Thu Jan 01 00:00:00 1970 +0000
-  # Node ID d85de4546133030c82d257bbcdd9b1b416d0c31c
-  # Parent  4d5dc81870237d492284826e21840b2ca00e26d1
+  # Node ID 4296f0622469c1527d5dc020cf72bd7732c44c64
+  # Parent  63ae8c44f4b6274d5580b4eea41a87623301c3e9
   adding fruit
   
   diff --git a/shopping b/shopping
   --- a/shopping
   +++ b/shopping
   @@ -9,3 +9,6 @@
-   Suggar
+   Sugar
    Vinegar
    Oil
   +Bananos
@@ -193,12 +196,12 @@
   +Apple
 
 The faulty changeset is in the "draft" phase because it has not been exchanged with
-the outside. The first one has been exchanged and is "public" (immutable).
+the outside yet. The first one has been exchanged and is "public" (immutable).
 
   $ hg log -G
-  @  d85de4546133 (draft): adding fruit
+  @  4296f0622469 (draft): adding fruit
   |
-  o  4d5dc8187023 (draft): adding condiment
+  o  63ae8c44f4b6 (draft): adding condiment
   |
   o  7e82d3f3c2cb (public): Monthy Python Shopping list
   
@@ -249,7 +252,7 @@
       }
 #endif
 
-Hopefully. I can use `hg commit --amend` to rewrite my faulty changeset!
+Luckily, I can use `hg commit --amend` to rewrite my faulty changeset!
 
   $ sed -i'' -e s/Bananos/Banana/ shopping
   $ hg diff
@@ -257,7 +260,7 @@
   --- a/shopping
   +++ b/shopping
   @@ -9,6 +9,6 @@
-   Suggar
+   Sugar
    Vinegar
    Oil
   -Bananos
@@ -266,12 +269,12 @@
    Apple
   $ hg commit --amend
 
-A new changeset with the right diff replace the wrong one.
+A new changeset with the correct changes replaces the old one.
 
   $ hg log -G
-  @  9d0363b81950 (draft): adding fruit
+  @  6445b365ad1c (draft): adding fruit
   |
-  o  4d5dc8187023 (draft): adding condiment
+  o  63ae8c44f4b6 (draft): adding condiment
   |
   o  7e82d3f3c2cb (public): Monthy Python Shopping list
   
@@ -326,15 +329,15 @@
   # User test
   # Date 0 0
   #      Thu Jan 01 00:00:00 1970 +0000
-  # Node ID 9d0363b81950646bc6ad1ec5de8b8197ea586541
-  # Parent  4d5dc81870237d492284826e21840b2ca00e26d1
+  # Node ID 6445b365ad1c4905e7a120e45242d9f4b51ec48f
+  # Parent  63ae8c44f4b6274d5580b4eea41a87623301c3e9
   adding fruit
   
   diff --git a/shopping b/shopping
   --- a/shopping
   +++ b/shopping
   @@ -9,3 +9,6 @@
-   Suggar
+   Sugar
    Vinegar
    Oil
   +Banana
@@ -344,7 +347,7 @@
 Getting rid of branchy history
 ----------------------------------
 
-While I was working on my list. Someone made a change remotely.
+While I was working on my list, someone made a change remotely.
 
   $ cd ../remote
   $ hg up -q
@@ -369,9 +372,9 @@
   $ hg log -G
   o  9ca060c80d74 (public): SPAM
   |
-  | @  9d0363b81950 (draft): adding fruit
+  | @  6445b365ad1c (draft): adding fruit
   | |
-  | o  4d5dc8187023 (draft): adding condiment
+  | o  63ae8c44f4b6 (draft): adding condiment
   |/
   o  7e82d3f3c2cb (public): Monthy Python Shopping list
   
@@ -437,19 +440,19 @@
 Instead of merging my head with the new one. I'm going to rebase my work
 
   $ hg diff
-  $ hg rebase --dest 9ca060c80d74 --source 4d5dc8187023
-  rebasing 1:4d5dc8187023 "adding condiment"
+  $ hg rebase --dest 9ca060c80d74 --source 63ae8c44f4b6
+  rebasing 1:63ae8c44f4b6 "adding condiment"
   merging shopping
-  rebasing 3:9d0363b81950 "adding fruit"
+  rebasing 3:6445b365ad1c "adding fruit"
   merging shopping
 
 
 My local work is now rebased on the remote one.
 
   $ hg log -G
-  @  41aff6a42b75 (draft): adding fruit
+  @  d300c8f961ce (draft): adding fruit
   |
-  o  dfd3a2d7691e (draft): adding condiment
+  o  723e5a43d6d9 (draft): adding condiment
   |
   o  9ca060c80d74 (public): SPAM
   |
@@ -526,31 +529,31 @@
   > EOF
   $ hg ci -m 'transport'
   $ hg log -G
-  @  1125e39fbf21 (draft): transport
+  @  7f938a07ecb2 (draft): transport
   |
-  o  41aff6a42b75 (draft): adding fruit
+  o  d300c8f961ce (draft): adding fruit
   |
-  o  dfd3a2d7691e (draft): adding condiment
+  o  723e5a43d6d9 (draft): adding condiment
   |
   o  9ca060c80d74 (public): SPAM
   |
   o  7e82d3f3c2cb (public): Monthy Python Shopping list
   
 
-I have a new commit but I realize that don't want it. (Transport shop list does
-not fit well in my standard shopping list)
+I have a new commit but I realize that don't want it. (Transport shopping list
+does not fit well in my standard shopping list)
 
   $ hg prune . # "." is for working directory parent
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  working directory is now at 41aff6a42b75
+  working directory is now at d300c8f961ce
   1 changesets pruned
 
 The silly changeset is gone.
 
   $ hg log -G
-  @  41aff6a42b75 (draft): adding fruit
+  @  d300c8f961ce (draft): adding fruit
   |
-  o  dfd3a2d7691e (draft): adding condiment
+  o  723e5a43d6d9 (draft): adding condiment
   |
   o  9ca060c80d74 (public): SPAM
   |
@@ -629,18 +632,18 @@
   > Towel
   > Soap
   > EOF
-  $ hg ci -m 'bathroom stuff' -q # XXX remove the -q
+  $ hg ci -m 'bathroom stuff'
 
   $ sed -i'' -e 's/Spam/Spam Spam Spam/g' shopping
   $ hg ci -m 'SPAM SPAM'
   $ hg log -G
-  @  fac207dec9f5 (draft): SPAM SPAM
+  @  1c877d31b53f (draft): SPAM SPAM
   |
-  o  10b8aeaa8cc8 (draft): bathroom stuff
+  o  d1928babc208 (draft): bathroom stuff
   |
-  o  41aff6a42b75 (draft): adding fruit
+  o  d300c8f961ce (draft): adding fruit
   |
-  o  dfd3a2d7691e (draft): adding condiment
+  o  723e5a43d6d9 (draft): adding condiment
   |
   o  9ca060c80d74 (public): SPAM
   |
@@ -649,27 +652,27 @@
 
 .. note:: We can't amend changeset 7e82d3f3c2cb or 9ca060c80d74 as they are immutable.
 
- I now want to push to remote all my changes except the bathroom one, which I'm
- not totally happy with yet. To be able to push "SPAM SPAM" I need a version of
- "SPAM SPAM" which is not a child of "bathroom stuff"
+I now want to push to remote all my changes except the bathroom one, which I'm
+not totally happy with yet. To be able to push "SPAM SPAM" I need a version of
+"SPAM SPAM" which is not a child of "bathroom stuff".
 
-You can use the 'grab' alias for that.
+You can use the 'grab' command for that.
 
-.. note: grab is an alias for `hg rebase --dest . --rev <target>; hg up <there>`
+.. note:: `grab` is an alias for `hg rebase --dest . --rev <target>; hg up <result>`
 
-  $ hg up 'p1(10b8aeaa8cc8)' # going on "bathroom stuff" parent
+  $ hg up 'p1(d1928babc208)' # going on "bathroom stuff" parent
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  $ hg pick fac207dec9f5 # moving "SPAM SPAM" to the working directory parent
-  picking 9:fac207dec9f5 "SPAM SPAM"
+  $ hg pick 1c877d31b53f # moving "SPAM SPAM" to the working directory parent
+  picking 9:1c877d31b53f "SPAM SPAM"
   merging shopping
   $ hg log -G
-  @  57e9caedbcb8 (draft): SPAM SPAM
+  @  501b33037995 (draft): SPAM SPAM
   |
-  | o  10b8aeaa8cc8 (draft): bathroom stuff
+  | o  d1928babc208 (draft): bathroom stuff
   |/
-  o  41aff6a42b75 (draft): adding fruit
+  o  d300c8f961ce (draft): adding fruit
   |
-  o  dfd3a2d7691e (draft): adding condiment
+  o  723e5a43d6d9 (draft): adding condiment
   |
   o  9ca060c80d74 (public): SPAM
   |
@@ -758,7 +761,7 @@
       }
 #endif
 
-We have a new SPAM SPAM version without the bathroom stuff
+We have a new version of "SPAM SPAM" without the bathroom stuff
 
   $ grep Spam shopping  # enough spam
   Spam Spam Spam Spam Spam Spam Spam Spam Spam
@@ -769,8 +772,8 @@
   # User test
   # Date 0 0
   #      Thu Jan 01 00:00:00 1970 +0000
-  # Node ID 57e9caedbcb8575a01c128db9d1bcbd624ef2115
-  # Parent  41aff6a42b7578ec7ec3cb2041633f1ca43cca96
+  # Node ID 501b330379955b6bf194dc99504a477b1f2d3f89
+  # Parent  d300c8f961ceefede93601dbe478c701e2ff5995
   SPAM SPAM
   
   diff --git a/shopping b/shopping
@@ -783,10 +786,10 @@
    Albatross
    Rat (rather a lot)
 
-To make sure I do not push unready changeset by mistake I set the "bathroom
-stuff" changeset in the secret phase.
+To make sure I do not push unfinished changeset by mistake I move the "bathroom
+stuff" changeset to the secret phase.
 
-  $ hg phase --force --secret 10b8aeaa8cc8
+  $ hg phase --force --secret d1928babc208
 
 we can now push our change:
 
@@ -799,20 +802,20 @@
   added 3 changesets with 3 changes to 1 files
   5 new obsolescence markers
 
-for simplicity sake we get the bathroom change in line again
+for simplicity's sake we get the bathroom change in line again
 
-  $ hg pick 10b8aeaa8cc8
-  picking 8:10b8aeaa8cc8 "bathroom stuff"
+  $ hg pick d1928babc208
+  picking 8:d1928babc208 "bathroom stuff"
   merging shopping
   $ hg phase --draft .
   $ hg log -G
-  @  4710c0968793 (draft): bathroom stuff
+  @  39b19dc3d1e4 (draft): bathroom stuff
   |
-  o  57e9caedbcb8 (public): SPAM SPAM
+  o  501b33037995 (public): SPAM SPAM
   |
-  o  41aff6a42b75 (public): adding fruit
+  o  d300c8f961ce (public): adding fruit
   |
-  o  dfd3a2d7691e (public): adding condiment
+  o  723e5a43d6d9 (public): adding condiment
   |
   o  9ca060c80d74 (public): SPAM
   |
@@ -905,7 +908,7 @@
 ------------------
 
 This part is not written yet, but you can use either the `histedit` extension
-of the `uncommit` command to splitting a change.
+or the `uncommit` command to split a change.
 
   $ hg help uncommit
   hg uncommit [OPTION]... [FILE]...
@@ -998,8 +1001,8 @@
   $ hg -R ../local/ showconfig phases
   [1]
 
-The localrepo does not have any specific configuration for `phases.publish`. It
-is ``true`` by default.
+The local repo does not have any specific configuration for `phases.publish`.
+It is ``true`` by default.
 
   $ hg pull local
   pulling from $TESTTMP/local (glob)
@@ -1009,16 +1012,16 @@
   adding file changes
   added 1 changesets with 1 changes to 1 files
   1 new obsolescence markers
-  new changesets 4710c0968793
+  new changesets 39b19dc3d1e4
   (run 'hg update' to get a working copy)
   $ hg log -G
-  o  4710c0968793 (public): bathroom stuff
+  o  39b19dc3d1e4 (public): bathroom stuff
   |
-  o  57e9caedbcb8 (public): SPAM SPAM
+  o  501b33037995 (public): SPAM SPAM
   |
-  o  41aff6a42b75 (public): adding fruit
+  o  d300c8f961ce (public): adding fruit
   |
-  o  dfd3a2d7691e (public): adding condiment
+  o  723e5a43d6d9 (public): adding condiment
   |
   @  9ca060c80d74 (public): SPAM
   |
@@ -1027,16 +1030,16 @@
 
 We do not want to publish the "bathroom changeset". Let's rollback the last transaction.
 
-.. Warning: Rollback is actually a dangerous kind of internal command that is deprecated and should not be exposed to user. Please forget you read about it until someone fix this tutorial.
+.. warning:: `rollback` is actually a dangerous kind of internal command that is deprecated and should not be exposed to user. Please forget you read about it until someone fix this tutorial.
 
   $ hg rollback
   repository tip rolled back to revision 4 (undo pull)
   $ hg log -G
-  o  57e9caedbcb8 (public): SPAM SPAM
+  o  501b33037995 (public): SPAM SPAM
   |
-  o  41aff6a42b75 (public): adding fruit
+  o  d300c8f961ce (public): adding fruit
   |
-  o  dfd3a2d7691e (public): adding condiment
+  o  723e5a43d6d9 (public): adding condiment
   |
   @  9ca060c80d74 (public): SPAM
   |
@@ -1065,16 +1068,16 @@
   adding file changes
   added 1 changesets with 1 changes to 1 files
   1 new obsolescence markers
-  new changesets 4710c0968793 (1 drafts)
+  new changesets 39b19dc3d1e4 (1 drafts)
   (run 'hg update' to get a working copy)
   $ hg log -G
-  o  4710c0968793 (draft): bathroom stuff
+  o  39b19dc3d1e4 (draft): bathroom stuff
   |
-  o  57e9caedbcb8 (public): SPAM SPAM
+  o  501b33037995 (public): SPAM SPAM
   |
-  o  41aff6a42b75 (public): adding fruit
+  o  d300c8f961ce (public): adding fruit
   |
-  o  dfd3a2d7691e (public): adding condiment
+  o  723e5a43d6d9 (public): adding condiment
   |
   @  9ca060c80d74 (public): SPAM
   |
@@ -1086,7 +1089,7 @@
 
 Remotely someone add a new changeset on top of the mutable "bathroom" on.
 
-  $ hg up 4710c0968793 -q
+  $ hg up 39b19dc3d1e4 -q
   $ cat >> shopping << EOF
   > Giraffe
   > Rhino
@@ -1098,17 +1101,17 @@
 But at the same time, locally, this same "bathroom changeset" was updated.
 
   $ cd ../local
-  $ hg up 4710c0968793 -q
+  $ hg up 39b19dc3d1e4 -q
   $ sed -i'' -e 's/... More bathroom stuff to come/Bath Robe/' shopping
   $ hg commit --amend
   $ hg log -G
-  @  682004e81e71 (draft): bathroom stuff
+  @  5486682f4225 (draft): bathroom stuff
   |
-  o  57e9caedbcb8 (public): SPAM SPAM
+  o  501b33037995 (public): SPAM SPAM
   |
-  o  41aff6a42b75 (public): adding fruit
+  o  d300c8f961ce (public): adding fruit
   |
-  o  dfd3a2d7691e (public): adding condiment
+  o  723e5a43d6d9 (public): adding condiment
   |
   o  9ca060c80d74 (public): SPAM
   |
@@ -1207,24 +1210,24 @@
   adding file changes
   added 1 changesets with 1 changes to 1 files
   1 new orphan changesets
-  new changesets e4e4fa805d92 (1 drafts)
+  new changesets 0609f95eccab (1 drafts)
   (run 'hg update' to get a working copy)
 
 The new changeset "animal" is based on an old changeset of "bathroom". You can
 see both version showing up in the log.
 
   $ hg log -G
-  *  e4e4fa805d92 (draft): animals
+  *  0609f95eccab (draft): animals
   |
-  | @  682004e81e71 (draft): bathroom stuff
+  | @  5486682f4225 (draft): bathroom stuff
   | |
-  x |  4710c0968793 (draft): bathroom stuff
+  x |  39b19dc3d1e4 (draft): bathroom stuff
   |/
-  o  57e9caedbcb8 (public): SPAM SPAM
+  o  501b33037995 (public): SPAM SPAM
   |
-  o  41aff6a42b75 (public): adding fruit
+  o  d300c8f961ce (public): adding fruit
   |
-  o  dfd3a2d7691e (public): adding condiment
+  o  723e5a43d6d9 (public): adding condiment
   |
   o  9ca060c80d74 (public): SPAM
   |
@@ -1342,10 +1345,10 @@
       }
 #endif
 
-The older version 75954b8cd933 never ceased to exist in the local repo. It was
+The older version 39b19dc3d1e4 never ceased to exist in the local repo. It was
 just hidden and excluded from pull and push.
 
-.. note:: In hgview there is a nice dotted relation highlighting a44c85f957d3 as a new version of 75954b8cd933. this is not yet ported to ``hg log -G``.
+.. note:: In hgview there is a nice dotted relation highlighting 5486682f4225 as a new version of 39b19dc3d1e4. This is not yet ported to ``hg log -G``.
 
 There is now an **unstable** changeset in this history. Mercurial will refuse to
 share it with the outside:
@@ -1353,20 +1356,20 @@
   $ hg push other
   pushing to $TESTTMP/other (glob)
   searching for changes
-  abort: push includes orphan changeset: e4e4fa805d92!
+  abort: push includes orphan changeset: 0609f95eccab!
   (use 'hg evolve' to get a stable history or --force to ignore warnings)
   [255]
  
 
-To resolve this unstable state, you need to rebase bf1b0d202029 onto
-a44c85f957d3. The `hg evolve` command will do this for you.
+To resolve this unstable state, you need to rebase 0609f95eccab onto
+5486682f4225. The `hg evolve` command will do this for you.
 
 It has a --dry-run option to only suggest the next move.
 
   $ hg evolve --dry-run
   move:[13] animals
   atop:[12] bathroom stuff
-  hg rebase -r e4e4fa805d92 -d 682004e81e71
+  hg rebase -r 0609f95eccab -d 5486682f4225
 
 Let's do it
 
@@ -1378,15 +1381,15 @@
 The old version of bathroom is hidden again.
 
   $ hg log -G
-  o  2a2b36e14660 (draft): animals
+  o  3266db1117c9 (draft): animals
   |
-  @  682004e81e71 (draft): bathroom stuff
+  @  5486682f4225 (draft): bathroom stuff
   |
-  o  57e9caedbcb8 (public): SPAM SPAM
+  o  501b33037995 (public): SPAM SPAM
   |
-  o  41aff6a42b75 (public): adding fruit
+  o  d300c8f961ce (public): adding fruit
   |
-  o  dfd3a2d7691e (public): adding condiment
+  o  723e5a43d6d9 (public): adding condiment
   |
   o  9ca060c80d74 (public): SPAM
   |
@@ -1516,13 +1519,13 @@
 Now let's see where we are, and update to the successor.
 
   $ hg parents
-  e4e4fa805d92 (draft): animals
-  working directory parent is obsolete! (e4e4fa805d92)
-  (use 'hg evolve' to update to its successor: 2a2b36e14660)
+  0609f95eccab (draft): animals
+  working directory parent is obsolete! (0609f95eccab)
+  (use 'hg evolve' to update to its successor: 3266db1117c9)
   $ hg evolve
   update:[8] animals
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  working directory is now at 2a2b36e14660
+  working directory is now at 3266db1117c9
 
 Relocating unstable change after prune
 ----------------------------------------------
@@ -1542,20 +1545,20 @@
   adding manifests
   adding file changes
   added 1 changesets with 1 changes to 1 files
-  new changesets fc41faf45288 (1 drafts)
+  new changesets fff8c3d068b6 (1 drafts)
   (run 'hg update' to get a working copy)
   $ hg log -G
-  o  fc41faf45288 (draft): SPAM SPAM SPAM
+  o  fff8c3d068b6 (draft): SPAM SPAM SPAM
   |
-  @  2a2b36e14660 (draft): animals
+  @  3266db1117c9 (draft): animals
   |
-  o  682004e81e71 (draft): bathroom stuff
+  o  5486682f4225 (draft): bathroom stuff
   |
-  o  57e9caedbcb8 (public): SPAM SPAM
+  o  501b33037995 (public): SPAM SPAM
   |
-  o  41aff6a42b75 (public): adding fruit
+  o  d300c8f961ce (public): adding fruit
   |
-  o  dfd3a2d7691e (public): adding condiment
+  o  723e5a43d6d9 (public): adding condiment
   |
   o  9ca060c80d74 (public): SPAM
   |
@@ -1670,9 +1673,9 @@
 
 In the mean time I noticed you can't buy animals in a super market and I prune the animal changeset:
 
-  $ hg prune 2a2b36e14660
+  $ hg prune 3266db1117c9
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  working directory is now at 682004e81e71
+  working directory is now at 5486682f4225
   1 changesets pruned
   1 new orphan changesets
 
@@ -1681,17 +1684,17 @@
 is neither dead or obsolete. My repository is in an unstable state again.
 
   $ hg log -G
-  *  fc41faf45288 (draft): SPAM SPAM SPAM
+  *  fff8c3d068b6 (draft): SPAM SPAM SPAM
   |
-  x  2a2b36e14660 (draft): animals
+  x  3266db1117c9 (draft): animals
   |
-  @  682004e81e71 (draft): bathroom stuff
+  @  5486682f4225 (draft): bathroom stuff
   |
-  o  57e9caedbcb8 (public): SPAM SPAM
+  o  501b33037995 (public): SPAM SPAM
   |
-  o  41aff6a42b75 (public): adding fruit
+  o  d300c8f961ce (public): adding fruit
   |
-  o  dfd3a2d7691e (public): adding condiment
+  o  723e5a43d6d9 (public): adding condiment
   |
   o  9ca060c80d74 (public): SPAM
   |
@@ -1805,7 +1808,7 @@
 #endif
 
   $ hg log -r "orphan()"
-  fc41faf45288 (draft): SPAM SPAM SPAM
+  fff8c3d068b6 (draft): SPAM SPAM SPAM
 
 #if docgraph-ext
   $ hg docgraph -r "orphan()" --sphinx-directive --rankdir LR #rest-ignore
@@ -1836,18 +1839,18 @@
   move:[15] SPAM SPAM SPAM
   atop:[12] bathroom stuff
   merging shopping
-  working directory is now at e6cfcb672150
+  working directory is now at c33e56ec23a8
 
   $ hg log -G
-  @  e6cfcb672150 (draft): SPAM SPAM SPAM
+  @  c33e56ec23a8 (draft): SPAM SPAM SPAM
   |
-  o  682004e81e71 (draft): bathroom stuff
+  o  5486682f4225 (draft): bathroom stuff
   |
-  o  57e9caedbcb8 (public): SPAM SPAM
+  o  501b33037995 (public): SPAM SPAM
   |
-  o  41aff6a42b75 (public): adding fruit
+  o  d300c8f961ce (public): adding fruit
   |
-  o  dfd3a2d7691e (public): adding condiment
+  o  723e5a43d6d9 (public): adding condiment
   |
   o  9ca060c80d74 (public): SPAM
   |
--- a/tests/test-version-install.t	Thu Jun 27 09:47:05 2024 +0400
+++ b/tests/test-version-install.t	Fri Oct 25 18:14:41 2024 +0400
@@ -18,7 +18,15 @@
     evolve  external  * (glob)
 
 Test install
-TODO: fix warning
-  $ "$PYTHON" "$TESTDIR/../setup.py" install --root "$TESTTMP/installtest" > /dev/null
-  */distutils/dist.py:*: UserWarning: Unknown distribution option: 'python_requires' (glob)
-    warnings.warn(msg)
+(pip on python2 doesn't have --root-user-action flag, so we ignore the warning manually)
+
+  $ "$PYTHON" -m pip install "$TESTDIR/.." --root="$TESTTMP/installtest" --quiet
+  WARNING: Running pip as the 'root' user * (glob) (?)
+
+Test that evolve can be loaded from the above path
+
+  $ echo "evolve=$(find $TESTTMP -path '*/hgext3rd/evolve')" >> $HGRCPATH
+  $ hg debugconfig extensions.evolve
+  */installtest/*/python*/hgext3rd/evolve (glob)
+  $ hg help evolve | head -1
+  hg evolve [OPTIONS]...