branching: merge stable into default
authorRaphaël Gomès <rgomes@octobus.net>
Mon, 03 May 2021 18:55:19 +0200
changeset 47057 7431f5ab0d2a
parent 47043 12450fbea288 (current diff)
parent 47056 067f2c53fb24 (diff)
child 47060 fde5bb5d1acf
branching: merge stable into default
hgext/git/dirstate.py
hgext/git/gitlog.py
hgext/git/index.py
hgext/phabricator.py
mercurial/hg.py
--- a/.hgsigs	Fri Apr 30 02:11:58 2021 +0200
+++ b/.hgsigs	Mon May 03 18:55:19 2021 +0200
@@ -208,3 +208,5 @@
 9da65e3cf3706ff41e08b311381c588440c27baf 0 iQJJBAABCgAzFiEEgY2HzRrBgMOUyG5jOjPeRg2ew58FAmAHEb4VHDc4OTVwdWxraXRAZ21haWwuY29tAAoJEDoz3kYNnsOfMJ0P/0A0L7tLfx03TWyz7VLPs9t3ojqGjFCaZAGPyS0Wtkpw0fhllYzf4WjFyGGsM1Re8fY7iakSoU3hzHID9svxH1CZ2qneaWHyXc166gFEhvOUmySQMRN26HnRG2Spc+gc/SMLUcAavzMiHukffD+IF0sDwQyTxwei40dc2T2whlqlIJ5r3VvV9KJVWotupKyH4XcWC5qr5tQvoc4jUnP+oyRtmv9sr9yqoC0nI6SALK61USfe6wl/g1vDDmwz3mE75LsVAJjPYVQzceMSAKqSnS2eB1xSdrs8AGB+VbG7aBAAlYo2kiQGYWnriXNJK5b6fwqbiyhMsyxShg/uFUnWeO52/0/tt7/2sHhXs7+IBM8nW/DSr1QbHaJ+p874zmJGsNT3FC370YioSuaqwTBFMvh37qi95bwqxGUYCoTr6nahfiXdUO3PC3OHCH/gXFmisKx2Lq7X1DIZZRqbKr0gPdksLJqk1zRrB++KGq5KEUsLFdQq4BePxleQy9thGzujBp1kqb9s/9eWlNfDVTVtL1n8jujoK66EwgknN9m66xMuLGRmCclMZ9NwVmfP9jumD0jz+YYrIZC2EoRGyftmNhlZahwDwgtQ70FSxNr/r+bSgMcUPdplkwh6c+UZGJpFyaKvJQfHcm6wuShKbrccSai4e6BU43J/yvbAVH0+1wus
 0e2e7300f4302b02412b0b734717697049494c4c 0 iQJJBAABCgAzFiEEgY2HzRrBgMOUyG5jOjPeRg2ew58FAmAZlogVHDc4OTVwdWxraXRAZ21haWwuY29tAAoJEDoz3kYNnsOfalsQAJjgyWsRM1Dty8MYagJiC3lDqqeUkIkdMB569d0NKaiarwL/vxPS7nx+ELNw0stWKDhgTjZlgUvkjqZEZgR4C4mdAbZYO1gWVc03eOeHMJB46oEIXv27pZYkQZ1SwDfVDfoCKExGExRw/cfoALXX6PvB7B0Az35ZcStCIgHn0ltTeJDge1XUCs8+10x2pjYBZssQ8ZVRhP3WeVZovX5CglrHW+9Uo09dJIIW7lmIgK2LLT0nsgeRTfb0YX7BiDATVAJgUQxf6MD2Sxt/oaWejL3zICKV5Cs+MaNElhpCD1YoVOe2DpASk60IHPZCmaOyCZCyBL9Yn2xxO9oDTVXJidwyKcvjCOaz4X6c5jdkgm0TaKlqfbY8LiUsQet0zzbQT7g+8jHv31wkjnxOMkbvHZZGoQLZTjS9M5NeWkvW8FzO9QLpp/sFJRCsNzjEzJWZCiAPKv51/4j7tNWOZLsKbYmjjQn9MoYZOrsFz4zjHYxz7Wi46JHMNzsHwi5iVreKXp1UGTQYhRZnKKb7g6zS3w3nI1KrGPfEnMf/EqRycLJV9HEoQTGo4T36DBFO7Wvyp6xwsnPGBki78ib5kUWwwSJiBsyx956nblY4wZaC8TiCueVqu0OfHpR4TGNuIkzS7ODNNRpcH65KNulIMRfB4kMLkvBVA27lDhc+XnDevi5q
 d5d9177c0045d206db575bae6daa98e2cb2fe5bc 0 iQJJBAABCgAzFiEEgY2HzRrBgMOUyG5jOjPeRg2ew58FAmBHDE4VHDc4OTVwdWxraXRAZ21haWwuY29tAAoJEDoz3kYNnsOfo20P/2eaVVY+VgaHktRHpJKJsC8tc8brHXfwPTijTzWl/2d4rZ1QwvyYFycl8LwtHeVdjvbDf61YIX2BiucX+rG11x21LyPPgD90pQ0VdRgoGXgVZX27exkvS5DUhqXnVnbey5dH3pFAPtYsC3jHsoo8NyNDrn2nXdvzzABArljIVyjnG5JokPiEH3dQSY78HlJR451HlrWEmRgL9PlzHGDRmpkdypKiV8o58386uqCz5zfugA9aC/JYheNA40xM3PV24GbJ/dtMqztzOh6MVxFWV5+krK2hXBXk/p8eE1SYDoO5tqZAmSgKmBJZ5zas4zRBoJb51BiLM0cBaxmBiqZ+sv9IHknoyEMisc4+0O6z7JKqLiZetVbvNVOkCP/CbKyik+evbZnQB6JhgOSCjfcLD5ZFl8GiRiz84ZT3ges5RTyVcE6jJNUV+nwmNdW2qLQP9JydInKNwTrEgZcrJDv6i+lu519p8+zcOgIF1J+CO8qQaq3+j5MA4Dttat3anWOQNIzbx4yuG75NezVN3jnRGmoSGwg1YLseqjQCBlpJrBWTD1SsuWpgbKx4EiELDN+PcDovxB2pYa+NzFfv0ZFcnWuLpr6KjCgzBkTK5KfmTqu7I+eM29g+2JvmCao+kk8MVyVmV9H2f5xRvuhrEBmDNlLb7uOhJW3a7EvZG6g9EfW9
+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
--- a/.hgtags	Fri Apr 30 02:11:58 2021 +0200
+++ b/.hgtags	Mon May 03 18:55:19 2021 +0200
@@ -221,3 +221,5 @@
 9da65e3cf3706ff41e08b311381c588440c27baf 5.7rc0
 0e2e7300f4302b02412b0b734717697049494c4c 5.7
 d5d9177c0045d206db575bae6daa98e2cb2fe5bc 5.7.1
+f67b8946bb1b6cfa8328dbf8d6a9128b69ccdcb4 5.8rc0
+8d2b62d716b095507effaa8d56f87cd27ba659ab 5.8rc1
--- a/hgext/git/dirstate.py	Fri Apr 30 02:11:58 2021 +0200
+++ b/hgext/git/dirstate.py	Mon May 03 18:55:19 2021 +0200
@@ -63,7 +63,7 @@
         pygit2.GIT_STATUS_WT_RENAMED: b'a',
         pygit2.GIT_STATUS_WT_TYPECHANGE: b'n',
         pygit2.GIT_STATUS_WT_UNREADABLE: b'?',
-        pygit2.GIT_STATUS_INDEX_MODIFIED | pygit2.GIT_STATUS_WT_MODIFIED: 'm',
+        pygit2.GIT_STATUS_INDEX_MODIFIED | pygit2.GIT_STATUS_WT_MODIFIED: b'm',
     }
 
 
--- a/hgext/git/gitlog.py	Fri Apr 30 02:11:58 2021 +0200
+++ b/hgext/git/gitlog.py	Mon May 03 18:55:19 2021 +0200
@@ -65,7 +65,8 @@
 
     def hasnode(self, n):
         t = self._db.execute(
-            'SELECT node FROM changelog WHERE node = ?', (n,)
+            'SELECT node FROM changelog WHERE node = ?',
+            (pycompat.sysstr(n),),
         ).fetchone()
         return t is not None
 
@@ -144,7 +145,7 @@
 
     def revs(self, start=0, stop=None):
         if stop is None:
-            stop = self.tip()
+            stop = self.tiprev()
         t = self._db.execute(
             'SELECT rev FROM changelog '
             'WHERE rev >= ? AND rev <= ? '
@@ -156,8 +157,11 @@
     def tiprev(self):
         t = self._db.execute(
             'SELECT rev FROM changelog ' 'ORDER BY REV DESC ' 'LIMIT 1'
-        )
-        return next(t)
+        ).fetchone()
+
+        if t is not None:
+            return t[0]
+        return -1
 
     def _partialmatch(self, id):
         if sha1nodeconstants.wdirhex.startswith(id):
@@ -165,7 +169,8 @@
         candidates = [
             bin(x[0])
             for x in self._db.execute(
-                'SELECT node FROM changelog WHERE node LIKE ?', (id + b'%',)
+                'SELECT node FROM changelog WHERE node LIKE ?',
+                (pycompat.sysstr(id + b'%'),),
             )
         ]
         if sha1nodeconstants.nullhex.startswith(id):
@@ -213,10 +218,11 @@
             n = self.node(nodeorrev)
         else:
             n = nodeorrev
+        extra = {b'branch': b'default'}
         # handle looking up nullid
         if n == sha1nodeconstants.nullid:
             return hgchangelog._changelogrevision(
-                extra={}, manifest=sha1nodeconstants.nullid
+                extra=extra, manifest=sha1nodeconstants.nullid
             )
         hn = gitutil.togitnode(n)
         # We've got a real commit!
@@ -233,7 +239,7 @@
             for r in self._db.execute(
                 'SELECT filename FROM changedfiles '
                 'WHERE node = ? and filenode = ?',
-                (hn, sha1nodeconstants.nullhex),
+                (hn, gitutil.nullgit),
             )
         ]
         c = self.gitrepo[hn]
@@ -247,7 +253,7 @@
             filesremoved=filesremoved,
             description=c.message.encode('utf8'),
             # TODO do we want to handle extra? how?
-            extra={b'branch': b'default'},
+            extra=extra,
         )
 
     def ancestors(self, revs, stoprev=0, inclusive=False):
--- a/hgext/git/index.py	Fri Apr 30 02:11:58 2021 +0200
+++ b/hgext/git/index.py	Mon May 03 18:55:19 2021 +0200
@@ -278,7 +278,7 @@
     for pos, commit in enumerate(walker):
         if prog is not None:
             prog.update(pos)
-        p1 = p2 = sha1nodeconstants.nullhex
+        p1 = p2 = gitutil.nullgit
         if len(commit.parents) > 2:
             raise error.ProgrammingError(
                 (
--- a/hgext/phabricator.py	Fri Apr 30 02:11:58 2021 +0200
+++ b/hgext/phabricator.py	Mon May 03 18:55:19 2021 +0200
@@ -403,7 +403,7 @@
 def callconduit(ui, name, params):
     """call Conduit API, params is a dict. return json.loads result, or None"""
     host, token = readurltoken(ui)
-    url, authinfo = util.url(b'/'.join([host, b'api', name])).authinfo()
+    url, authinfo = urlutil.url(b'/'.join([host, b'api', name])).authinfo()
     ui.debug(b'Conduit Call: %s %s\n' % (url, pycompat.byterepr(params)))
     params = params.copy()
     params[b'__conduit__'] = {
--- a/mercurial/dirstateguard.py	Fri Apr 30 02:11:58 2021 +0200
+++ b/mercurial/dirstateguard.py	Mon May 03 18:55:19 2021 +0200
@@ -7,11 +7,13 @@
 
 from __future__ import absolute_import
 
+import os
 from .i18n import _
 
 from . import (
     error,
     narrowspec,
+    requirements,
     util,
 )
 
@@ -34,13 +36,22 @@
         self._repo = repo
         self._active = False
         self._closed = False
-        self._backupname = b'dirstate.backup.%s.%d' % (name, id(self))
-        self._narrowspecbackupname = b'narrowspec.backup.%s.%d' % (
-            name,
-            id(self),
-        )
+
+        def getname(prefix):
+            fd, fname = repo.vfs.mkstemp(prefix=prefix)
+            os.close(fd)
+            return fname
+
+        self._backupname = getname(b'dirstate.backup.%s.' % name)
         repo.dirstate.savebackup(repo.currenttransaction(), self._backupname)
-        narrowspec.savewcbackup(repo, self._narrowspecbackupname)
+        # Don't make this the empty string, things may join it with stuff and
+        # blindly try to unlink it, which could be bad.
+        self._narrowspecbackupname = None
+        if requirements.NARROW_REQUIREMENT in repo.requirements:
+            self._narrowspecbackupname = getname(
+                b'narrowspec.backup.%s.' % name
+            )
+            narrowspec.savewcbackup(repo, self._narrowspecbackupname)
         self._active = True
 
     def __del__(self):
@@ -62,12 +73,14 @@
         self._repo.dirstate.clearbackup(
             self._repo.currenttransaction(), self._backupname
         )
-        narrowspec.clearwcbackup(self._repo, self._narrowspecbackupname)
+        if self._narrowspecbackupname:
+            narrowspec.clearwcbackup(self._repo, self._narrowspecbackupname)
         self._active = False
         self._closed = True
 
     def _abort(self):
-        narrowspec.restorewcbackup(self._repo, self._narrowspecbackupname)
+        if self._narrowspecbackupname:
+            narrowspec.restorewcbackup(self._repo, self._narrowspecbackupname)
         self._repo.dirstate.restorebackup(
             self._repo.currenttransaction(), self._backupname
         )
--- a/mercurial/extensions.py	Fri Apr 30 02:11:58 2021 +0200
+++ b/mercurial/extensions.py	Mon May 03 18:55:19 2021 +0200
@@ -930,7 +930,11 @@
 def moduleversion(module):
     '''return version information from given module as a string'''
     if util.safehasattr(module, b'getversion') and callable(module.getversion):
-        version = module.getversion()
+        try:
+            version = module.getversion()
+        except Exception:
+            version = b'unknown'
+
     elif util.safehasattr(module, b'__version__'):
         version = module.__version__
     else:
--- a/mercurial/hg.py	Fri Apr 30 02:11:58 2021 +0200
+++ b/mercurial/hg.py	Mon May 03 18:55:19 2021 +0200
@@ -1273,7 +1273,7 @@
     srcs = urlutil.get_pull_paths(repo, ui, [source], opts.get(b'branch'))
     srcs = list(srcs)
     if len(srcs) != 1:
-        msg = _('for now, incoming supports only a single source, %d provided')
+        msg = _(b'for now, incoming supports only a single source, %d provided')
         msg %= len(srcs)
         raise error.Abort(msg)
     source, branches = srcs[0]
--- a/mercurial/mail.py	Fri Apr 30 02:11:58 2021 +0200
+++ b/mercurial/mail.py	Mon May 03 18:55:19 2021 +0200
@@ -220,6 +220,7 @@
 
 def _mbox(mbox, sender, recipients, msg):
     '''write mails to mbox'''
+    # TODO: use python mbox library for proper locking
     with open(mbox, b'ab+') as fp:
         # Should be time.asctime(), but Windows prints 2-characters day
         # of month instead of one. Make them print the same thing.
--- a/mercurial/repoview.py	Fri Apr 30 02:11:58 2021 +0200
+++ b/mercurial/repoview.py	Mon May 03 18:55:19 2021 +0200
@@ -464,18 +464,24 @@
         return delattr(self._unfilteredrepo, attr)
 
 
-# Python <3.4 easily leaks types via __mro__. See
-# https://bugs.python.org/issue17950. We cache dynamically created types
-# so they won't be leaked on every invocation of repo.filtered().
+# Dynamically created classes introduce memory cycles via __mro__. See
+# https://bugs.python.org/issue17950.
+# This need of the garbage collector can turn into memory leak in
+# Python <3.4, which is the first version released with PEP 442.
 _filteredrepotypes = weakref.WeakKeyDictionary()
 
 
 def newtype(base):
     """Create a new type with the repoview mixin and the given base class"""
-    if base not in _filteredrepotypes:
+    ref = _filteredrepotypes.get(base)
+    if ref is not None:
+        cls = ref()
+        if cls is not None:
+            return cls
 
-        class filteredrepo(repoview, base):
-            pass
+    class filteredrepo(repoview, base):
+        pass
 
-        _filteredrepotypes[base] = filteredrepo
-    return _filteredrepotypes[base]
+    _filteredrepotypes[base] = weakref.ref(filteredrepo)
+    # do not reread from weakref to be 100% sure not to return None
+    return filteredrepo
--- a/mercurial/upgrade_utils/actions.py	Fri Apr 30 02:11:58 2021 +0200
+++ b/mercurial/upgrade_utils/actions.py	Mon May 03 18:55:19 2021 +0200
@@ -5,15 +5,13 @@
 # This software may be used and distributed according to the terms of the
 # GNU General Public License version 2 or any later version.
 
-# See https://github.com/google/pytype/issues/860
-# pytype: skip-file
-
 from __future__ import absolute_import
 
 from ..i18n import _
 from .. import (
     error,
     localrepo,
+    pycompat,
     requirements,
     revlog,
     util,
@@ -21,6 +19,13 @@
 
 from ..utils import compression
 
+if pycompat.TYPE_CHECKING:
+    from typing import (
+        List,
+        Type,
+    )
+
+
 # list of requirements that request a clone of all revlog if added/removed
 RECLONES_REQUIREMENTS = {
     requirements.GENERALDELTA_REQUIREMENT,
@@ -110,7 +115,7 @@
         return hash(self.name)
 
 
-allformatvariant = []
+allformatvariant = []  # type: List[Type['formatvariant']]
 
 
 def registerformatvariant(cls):
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/relnotes/5.8	Mon May 03 18:55:19 2021 +0200
@@ -0,0 +1,68 @@
+== New Features ==
+ 
+ * `hg purge` is now a core command using `--confirm` by default.
+ 
+ * The `rev-branch-cache` is now updated incrementally whenever changesets
+   are added.
+
+ * The new options `experimental.bundlecompthreads` and
+   `experimental.bundlecompthreads.<engine>` can be used to instruct
+   the compression engines for bundle operations to use multiple threads
+   for compression. The default is single threaded operation. Currently
+   only supported for zstd.
+
+== Default Format Change ==
+
+These changes affects newly created repositories (or new clone) done with
+Mercurial 5.8.
+
+  * The `ZSTD` compression will now be used by default for new repositories
+    when available. This compression format was introduced in Mercurial 5.0,
+    released in May 2019. See `hg help config.format.revlog-compression` for
+    details.
+
+  * Mercurial installation built with the Rust parts will now use the
+    "persistent nodemap" feature by default. This feature was introduced in
+    Mercurial 5.4 (May 2020). However Mercurial instalation built without the
+    fast Rust implementation will refuse to interract with them by default.
+    This restriction can be lifted through configuration.
+
+    See `hg help config.format.use-persistent-nodemap` for details
+
+== New Experimental Features ==
+
+ * There's a new `diff.merge` config option to show the changes
+    relative to an automerge for merge changesets. This makes it
+    easier to detect and review manual changes performed in merge
+    changesets. It is supported by `hg diff --change`, `hg log -p`
+    `hg incoming -p`, and `hg outgoing -p` so far.
+
+
+== Bug Fixes ==
+
+ * gracefully recover from inconsistent persistent-nodemap data from disk.
+
+
+== Backwards Compatibility Changes ==
+
+ * In normal repositories, the first parent of a changeset is not null,
+   unless both parents are null (like the first changeset). Some legacy
+   repositories violate this condition. The revlog code will now
+   silentely swap the parents if this condition is tested. This can
+   change the output of `hg log` when explicitly asking for first or
+   second parent. The changesets "nodeid" are not affected.
+
+
+== Internal API Changes ==
+
+ * `changelog.branchinfo` is deprecated and will be removed after 5.8.
+   It is superseded by `changelogrevision.branchinfo`.
+
+ * Callbacks for revlog.addgroup and the changelog._nodeduplicatecallback hook
+   now get a revision number as argument instead of a node.
+
+ * revlog.addrevision returns the revision number instead of the node.
+
+ * `nodes.nullid` and related constants are being phased out as part of
+   the deprecation of SHA1. Repository instances and related classes
+   provide access via `nodeconstants` and in some cases `nullid` attributes.
--- a/relnotes/next	Fri Apr 30 02:11:58 2021 +0200
+++ b/relnotes/next	Mon May 03 18:55:19 2021 +0200
@@ -1,49 +1,21 @@
 == New Features ==
  
- * `hg purge` is now a core command using `--confirm` by default.
- 
- * The `rev-branch-cache` is now updated incrementally whenever changesets
-   are added.
+
+== Default Format Change ==
 
- * The new options `experimental.bundlecompthreads` and
-   `experimental.bundlecompthreads.<engine>` can be used to instruct
-   the compression engines for bundle operations to use multiple threads
-   for compression. The default is single threaded operation. Currently
-   only supported for zstd.
+These changes affects newly created repositories (or new clone) done with
+Mercurial 5.8.
+
 
 == New Experimental Features ==
 
- * There's a new `diff.merge` config option to show the changes
-    relative to an automerge for merge changesets. This makes it
-    easier to detect and review manual changes performed in merge
-    changesets. It is supported by `hg diff --change`, `hg log -p`
-    `hg incoming -p`, and `hg outgoing -p` so far.
-
 
 == Bug Fixes ==
 
 
-
 == Backwards Compatibility Changes ==
 
- * In normal repositories, the first parent of a changeset is not null,
-   unless both parents are null (like the first changeset). Some legacy
-   repositories violate this condition. The revlog code will now
-   silentely swap the parents if this condition is tested. This can
-   change the output of `hg log` when explicitly asking for first or
-   second parent.
-
 
 == Internal API Changes ==
 
- * `changelog.branchinfo` is deprecated and will be removed after 5.8.
-   It is superseded by `changelogrevision.branchinfo`.
 
- * Callbacks for revlog.addgroup and the changelog._nodeduplicatecallback hook
-   now get a revision number as argument instead of a node.
-
- * revlog.addrevision returns the revision number instead of the node.
-
- * `nodes.nullid` and related constants are being phased out as part of
-   the deprecation of SHA1. Repository instances and related classes
-   provide access via `nodeconstants` and in some cases `nullid` attributes.
--- a/setup.py	Fri Apr 30 02:11:58 2021 +0200
+++ b/setup.py	Mon May 03 18:55:19 2021 +0200
@@ -437,6 +437,10 @@
             version = '%(latesttag)s+hg%(latesttagdistance)s.%(node).12s' % kw
     else:
         version = '0+hg' + kw.get('node', '')[:12]
+elif os.path.exists('mercurial/__version__.py'):
+    with open('mercurial/__version__.py') as f:
+        data = f.read()
+    version = re.search('version = b"(.*)"', data).group(1)
 
 if version:
     versionb = version
--- a/tests/run-tests.py	Fri Apr 30 02:11:58 2021 +0200
+++ b/tests/run-tests.py	Mon May 03 18:55:19 2021 +0200
@@ -326,7 +326,7 @@
 
 default_defaults = {
     'jobs': ('HGTEST_JOBS', multiprocessing.cpu_count()),
-    'timeout': ('HGTEST_TIMEOUT', 180),
+    'timeout': ('HGTEST_TIMEOUT', 360),
     'slowtimeout': ('HGTEST_SLOWTIMEOUT', 1500),
     'port': ('HGTEST_PORT', 20059),
     'shell': ('HGTEST_SHELL', 'sh'),
--- a/tests/test-git-interop.t	Fri Apr 30 02:11:58 2021 +0200
+++ b/tests/test-git-interop.t	Mon May 03 18:55:19 2021 +0200
@@ -7,6 +7,7 @@
   > GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"; export GIT_COMMITTER_NAME
   > GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"; export GIT_COMMITTER_EMAIL
   > GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"; export GIT_COMMITTER_DATE
+  > HGUSER="test <test@example.org>"; export HGUSER
   > count=10
   > gitcommit() {
   >    GIT_AUTHOR_DATE="2007-01-01 00:00:$count +0000";
@@ -49,6 +50,22 @@
   > log-index-cache-miss = yes
   > EOF
 
+Test some edge cases around a commitless repo first
+  $ mkdir empty
+  $ cd empty
+  $ git init
+  Initialized empty Git repository in $TESTTMP/empty/.git/
+  $ hg init --git
+  $ hg heads
+  [1]
+  $ hg tip
+  changeset:   -1:000000000000
+  tag:         tip
+  user:        
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  
+  $ cd ..
+
 Make a new repo with git:
   $ mkdir foo
   $ cd foo
@@ -67,6 +84,7 @@
   On branch master
   Untracked files:
     (use "git add <file>..." to include in what will be committed)
+   (?)
   	gamma
   
   nothing added to commit but untracked files present (use "git add" to track)
@@ -134,6 +152,7 @@
   On branch master
   Untracked files:
     (use "git add <file>..." to include in what will be committed)
+   (?)
   	gamma
   
   nothing added to commit but untracked files present (use "git add" to track)
@@ -153,7 +172,9 @@
   $ git status
   On branch master
   Changes to be committed:
-    (use "git restore --staged <file>..." to unstage)
+    (use "git restore --staged <file>..." to unstage) (?)
+    (use "git reset HEAD <file>..." to unstage) (?)
+   (?)
   	new file:   gamma
   
 
@@ -165,6 +186,7 @@
   On branch master
   Untracked files:
     (use "git add <file>..." to include in what will be committed)
+   (?)
   	gamma
   
   nothing added to commit but untracked files present (use "git add" to track)
@@ -175,7 +197,7 @@
 hg log FILE
 
   $ echo a >> alpha
-  $ hg ci -m 'more alpha' --traceback --date '1583522787 18000'
+  $ hg ci -m 'more alpha' --traceback --date '1583558723 18000'
   $ echo b >> beta
   $ hg ci -m 'more beta'
   heads mismatch, rebuilding dagcache
@@ -184,16 +206,16 @@
   heads mismatch, rebuilding dagcache
   $ hg log -G alpha
   heads mismatch, rebuilding dagcache
-  @  changeset:   4:6626247b7dc8
+  @  changeset:   4:cf6ddf5d9b8a
   :  bookmark:    master
   :  tag:         tip
-  :  user:        test <test>
+  :  user:        test <test@example.org>
   :  date:        Thu Jan 01 00:00:00 1970 +0000
   :  summary:     even more alpha
   :
-  o  changeset:   2:a1983dd7fb19
-  :  user:        test <test>
-  :  date:        Fri Mar 06 14:26:27 2020 -0500
+  o  changeset:   2:5b2c80b027ce
+  :  user:        test <test@example.org>
+  :  date:        Sat Mar 07 00:25:23 2020 -0500
   :  summary:     more alpha
   :
   o  changeset:   0:c5864c9d16fb
@@ -202,8 +224,8 @@
      summary:     Add alpha
   
   $ hg log -G beta
-  o  changeset:   3:d8ee22687733
-  :  user:        test <test>
+  o  changeset:   3:980d4f79a9c6
+  :  user:        test <test@example.org>
   :  date:        Thu Jan 01 00:00:00 1970 +0000
   :  summary:     more beta
   :
@@ -214,7 +236,7 @@
   
 
   $ hg log -r "children(3d9be8deba43)" -T"{node|short} {children}\n"
-  a1983dd7fb19 3:d8ee22687733
+  5b2c80b027ce 3:980d4f79a9c6
 
 hg annotate
 
@@ -258,13 +280,29 @@
 node|shortest works correctly
   $ hg log -T '{node}\n' | sort
   3d9be8deba43482be2c81a4cb4be1f10d85fa8bc
-  6626247b7dc8f231b183b8a4761c89139baca2ad
-  a1983dd7fb19cbd83ad5a1c2fc8bf3d775dea12f
-  ae1ab744f95bfd5b07cf573baef98a778058537b
+  5b2c80b027ce4250f88957326c199a2dc48dad60
+  980d4f79a9c617d60d0fe1fb383753c4a61bea8e
+  c1a41c49866ecc9c5411be932653e5b430961dd5
   c5864c9d16fb3431fe2c175ff84dc6accdbb2c18
-  d8ee22687733a1991813560b15128cd9734f4b48
-  $ hg log -r ae1ab744f95bfd5b07cf573baef98a778058537b --template "{shortest(node,1)}\n"
-  ae
+  cf6ddf5d9b8a120bf90020342bcf7a96d0167279
+  $ hg log -r c1a41c49866ecc9c5411be932653e5b430961dd5 --template "{shortest(node,1)}\n"
+  c1
+
+This covers gitlog._partialmatch()
+  $ hg log -r c
+  abort: ambiguous revision identifier: c
+  [10]
+  $ hg log -r c1
+  changeset:   5:c1a41c49866e
+  bookmark:    master
+  tag:         tip
+  user:        test <test@example.org>
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     Introduce file a/mu
+  
+  $ hg log -r dead
+  abort: unknown revision 'dead'
+  [255]
 
 This coveres changelog.findmissing()
   $ hg merge --preview 3d9be8deba43
@@ -320,14 +358,14 @@
 
   $ hg ex -r .
   # HG changeset patch
-  # User test <test>
+  # User test <test@example.org>
   # Date 0 0
   #      Thu Jan 01 00:00:00 1970 +0000
-  # Node ID 80adc61cf57e99f6a412d83fee6239d1556cefcf
-  # Parent  ae1ab744f95bfd5b07cf573baef98a778058537b
+  # Node ID 6024eda7986da123aa6797dd4603bd399d49bf5c
+  # Parent  c1a41c49866ecc9c5411be932653e5b430961dd5
   test interactive commit
   
-  diff -r ae1ab744f95b -r 80adc61cf57e alpha
+  diff -r c1a41c49866e -r 6024eda7986d alpha
   --- a/alpha	Thu Jan 01 00:00:00 1970 +0000
   +++ b/alpha	Thu Jan 01 00:00:00 1970 +0000
   @@ -1,3 +1,4 @@
@@ -336,8 +374,8 @@
    a
   +bar
   $ git show
-  commit 80adc61cf57e99f6a412d83fee6239d1556cefcf
-  Author: test <test>
+  commit 6024eda7986da123aa6797dd4603bd399d49bf5c
+  Author: test <test@example.org>
   Date:   Thu Jan 1 00:00:00 1970 +0000
   
       test interactive commit
@@ -358,3 +396,30 @@
   $ hg rm beta
   $ hg ci -m 'remove beta'
 
+This covers changelog.tiprev() (issue6510)
+  $ hg log -r '(.^^):'
+  heads mismatch, rebuilding dagcache
+  changeset:   5:c1a41c49866e
+  user:        test <test@example.org>
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     Introduce file a/mu
+  
+  changeset:   6:6024eda7986d
+  user:        test <test@example.org>
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     test interactive commit
+  
+  changeset:   7:1a0fee76bfc4
+  bookmark:    master
+  tag:         tip
+  user:        test <test@example.org>
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     remove beta
+  
+This covers changelog.headrevs() with a non-None arg
+  $ hg log -r 'heads(.)' -Tcompact
+  7[tip][master]   1a0fee76bfc4   1970-01-01 00:00 +0000   test
+    remove beta
+  
+
+
--- a/tests/test-transaction-rollback-on-sigpipe.t	Fri Apr 30 02:11:58 2021 +0200
+++ b/tests/test-transaction-rollback-on-sigpipe.t	Mon May 03 18:55:19 2021 +0200
@@ -22,14 +22,14 @@
 
   $ killable_pipe=`pwd`/killable_pipe.sh
   $ script $killable_pipe <<EOF
-  > #!/bin/bash
+  > #!/usr/bin/env bash
   > echo \$\$ >> $pidfile
   > exec cat
   > EOF
 
   $ remotecmd=`pwd`/remotecmd.sh
   $ script $remotecmd <<EOF
-  > #!/bin/bash
+  > #!/usr/bin/env bash
   > hg "\$@" 1> >($killable_pipe) 2> >($killable_pipe >&2)
   > EOF
 
@@ -38,7 +38,7 @@
 
   $ hook_script=`pwd`/pretxnchangegroup.sh
   $ script $hook_script <<EOF
-  > #!/bin/bash
+  > #!/usr/bin/env bash
   > for pid in \$(cat $pidfile) ; do
   >   kill \$pid
   >   while kill -0 \$pid 2>/dev/null ; do