branching: merge stable into default for 6.9 cycle
authorRaphaël Gomès <rgomes@octobus.net>
Mon, 08 Jul 2024 17:56:54 +0200
changeset 51666 8e3f6b5bf720
parent 51651 cf294cb90b2b (current diff)
parent 51665 b8fe591d7ab8 (diff)
child 51669 32a1c9226dd9
branching: merge stable into default for 6.9 cycle
--- a/.hgsigs	Mon Jun 24 13:15:46 2024 +0200
+++ b/.hgsigs	Mon Jul 08 17:56:54 2024 +0200
@@ -263,3 +263,4 @@
 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
+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
--- a/.hgtags	Mon Jun 24 13:15:46 2024 +0200
+++ b/.hgtags	Mon Jul 08 17:56:54 2024 +0200
@@ -279,3 +279,4 @@
 028dc3f92dbd0f93bb78f9848c94ba5eecd72e71 6.7.3
 a1a011d4b148955975cb40d619d285fdd4ee8713 6.7.4
 6454c117c6a4003f07d8f4281dd90038955123e4 6.8rc0
+11f41248595b6dd7e0fbb434ecbf75c418785a4c 6.8
--- a/contrib/chg/hgclient.c	Mon Jun 24 13:15:46 2024 +0200
+++ b/contrib/chg/hgclient.c	Mon Jul 08 17:56:54 2024 +0200
@@ -7,6 +7,11 @@
  * GNU General Public License version 2 or any later version.
  */
 
+#if defined(__sun) && !defined(_XOPEN_SOURCE)
+/* msg_control is used */
+#define _XOPEN_SOURCE 600
+#endif
+
 #include <arpa/inet.h> /* for ntohl(), htonl() */
 #include <assert.h>
 #include <ctype.h>
@@ -26,6 +31,10 @@
 #include "procutil.h"
 #include "util.h"
 
+#ifndef O_DIRECTORY
+#define O_DIRECTORY O_RDONLY
+#endif
+
 enum {
 	CAP_GETENCODING = 0x0001,
 	CAP_RUNCOMMAND = 0x0002,
--- a/contrib/import-checker.py	Mon Jun 24 13:15:46 2024 +0200
+++ b/contrib/import-checker.py	Mon Jul 08 17:56:54 2024 +0200
@@ -237,6 +237,8 @@
         yield m
     for m in ['cffi']:
         yield m
+    yield 'distutils'  # in Python < 3.12
+    yield 'distutils.version'  # in Python < 3.12
     stdlib_prefixes = {sys.prefix, sys.exec_prefix}
     # We need to supplement the list of prefixes for the search to work
     # when run from within a virtualenv.
--- a/mercurial/branchmap.py	Mon Jun 24 13:15:46 2024 +0200
+++ b/mercurial/branchmap.py	Mon Jul 08 17:56:54 2024 +0200
@@ -1213,11 +1213,12 @@
 
         if self._names:
             try:
-                if repo.ui.configbool(b'storage', b'revbranchcache.mmap'):
-                    with repo.cachevfs(_rbcrevs) as fp:
+                usemmap = repo.ui.configbool(b'storage', b'revbranchcache.mmap')
+                with repo.cachevfs(_rbcrevs) as fp:
+                    if usemmap and repo.cachevfs.is_mmap_safe(_rbcrevs):
                         data = util.buffer(util.mmapread(fp))
-                else:
-                    data = repo.cachevfs.read(_rbcrevs)
+                    else:
+                        data = fp.read()
                 self._rbcrevs = rbcrevs(data)
             except (IOError, OSError) as inst:
                 repo.ui.debug(
--- a/mercurial/bundle2.py	Mon Jun 24 13:15:46 2024 +0200
+++ b/mercurial/bundle2.py	Mon Jul 08 17:56:54 2024 +0200
@@ -1788,7 +1788,7 @@
         addpartrevbranchcache(repo, bundler, outgoing)
 
     if opts.get(b'obsolescence', False):
-        obsmarkers = repo.obsstore.relevantmarkers(nodes=outgoing.missing)
+        obsmarkers = repo.obsstore.relevantmarkers(outgoing.missing)
         buildobsmarkerspart(
             bundler,
             obsmarkers,
--- a/mercurial/configitems.toml	Mon Jun 24 13:15:46 2024 +0200
+++ b/mercurial/configitems.toml	Mon Jul 08 17:56:54 2024 +0200
@@ -2147,7 +2147,7 @@
 [[items]]
 section = "storage"
 name = "revbranchcache.mmap"
-default = true
+default = false
 
 [[items]]
 section = "storage"
--- a/mercurial/exchange.py	Mon Jun 24 13:15:46 2024 +0200
+++ b/mercurial/exchange.py	Mon Jul 08 17:56:54 2024 +0200
@@ -703,8 +703,8 @@
     repo = pushop.repo
     # very naive computation, that can be quite expensive on big repo.
     # However: evolution is currently slow on them anyway.
-    revs = repo.revs(b'::%ln', pushop.futureheads)
-    pushop.outobsmarkers = pushop.repo.obsstore.relevantmarkers(revs=revs)
+    nodes = (c.node() for c in repo.set(b'::%ln', pushop.futureheads))
+    pushop.outobsmarkers = pushop.repo.obsstore.relevantmarkers(nodes)
 
 
 @pushdiscovery(b'bookmarks')
@@ -2605,8 +2605,8 @@
     if kwargs.get('obsmarkers', False):
         if heads is None:
             heads = repo.heads()
-        revs = repo.revs(b'::%ln', heads)
-        markers = repo.obsstore.relevantmarkers(revs=revs)
+        subset = [c.node() for c in repo.set(b'::%ln', heads)]
+        markers = repo.obsstore.relevantmarkers(subset)
         markers = obsutil.sortedmarkers(markers)
         bundle2.buildobsmarkerspart(bundler, markers)
 
--- a/mercurial/obsolete.py	Mon Jun 24 13:15:46 2024 +0200
+++ b/mercurial/obsolete.py	Mon Jul 08 17:56:54 2024 +0200
@@ -771,11 +771,10 @@
             _addchildren(self.children, markers)
         _checkinvalidmarkers(self.repo, markers)
 
-    def relevantmarkers(self, nodes=None, revs=None):
-        """return a set of all obsolescence markers relevant to a set of
-        nodes or revisions.
+    def relevantmarkers(self, nodes):
+        """return a set of all obsolescence markers relevant to a set of nodes.
 
-        "relevant" to a set of nodes or revisions mean:
+        "relevant" to a set of nodes mean:
 
         - marker that use this changeset as successor
         - prune marker of direct children on this changeset
@@ -783,21 +782,8 @@
           markers
 
         It is a set so you cannot rely on order."""
-        if nodes is None:
-            nodes = set()
-        if revs is None:
-            revs = set()
 
-        get_rev = self.repo.unfiltered().changelog.index.get_rev
-        pendingnodes = set()
-        for marker in self._all:
-            for node in (marker[0],) + marker[1] + (marker[5] or ()):
-                if node in nodes:
-                    pendingnodes.add(node)
-                elif revs:
-                    rev = get_rev(node)
-                    if rev is not None and rev in revs:
-                        pendingnodes.add(node)
+        pendingnodes = set(nodes)
         seenmarkers = set()
         seennodes = set(pendingnodes)
         precursorsmarkers = self.predecessors
--- a/mercurial/obsutil.py	Mon Jun 24 13:15:46 2024 +0200
+++ b/mercurial/obsutil.py	Mon Jul 08 17:56:54 2024 +0200
@@ -108,7 +108,7 @@
     elif exclusive:
         rawmarkers = exclusivemarkers(repo, nodes)
     else:
-        rawmarkers = repo.obsstore.relevantmarkers(nodes=nodes)
+        rawmarkers = repo.obsstore.relevantmarkers(nodes)
 
     for markerdata in rawmarkers:
         yield marker(repo, markerdata)
--- a/mercurial/revlog.py	Mon Jun 24 13:15:46 2024 +0200
+++ b/mercurial/revlog.py	Mon Jul 08 17:56:54 2024 +0200
@@ -1460,7 +1460,10 @@
             with self.opener(filepath) as fp:
                 if mmap_threshold is not None:
                     file_size = self.opener.fstat(fp).st_size
-                    if file_size >= mmap_threshold:
+                    if (
+                        file_size >= mmap_threshold
+                        and self.opener.is_mmap_safe(filepath)
+                    ):
                         if size is not None:
                             # avoid potentiel mmap crash
                             size = min(file_size, size)
--- a/mercurial/revlogutils/nodemap.py	Mon Jun 24 13:15:46 2024 +0200
+++ b/mercurial/revlogutils/nodemap.py	Mon Jul 08 17:56:54 2024 +0200
@@ -74,7 +74,7 @@
     test_race_hook_1()
     try:
         with revlog.opener(filename) as fd:
-            if use_mmap:
+            if use_mmap and revlog.opener.is_mmap_safe(filename):
                 try:
                     data = util.buffer(util.mmapread(fd, data_length))
                 except ValueError:
@@ -205,7 +205,7 @@
                 fd.seek(target_docket.data_length)
                 fd.write(data)
                 if feed_data:
-                    if use_mmap:
+                    if use_mmap and revlog.opener.is_mmap_safe(datafile):
                         fd.flush()
                         new_data = util.buffer(util.mmapread(fd, new_length))
                     else:
@@ -238,11 +238,11 @@
         with revlog.opener(datafile, b'w+') as fd:
             fd.write(data)
             if feed_data:
-                if use_mmap:
-                    new_data = data
-                else:
+                if use_mmap and revlog.opener.is_mmap_safe(datafile):
                     fd.flush()
                     new_data = util.buffer(util.mmapread(fd, len(data)))
+                else:
+                    new_data = data
         target_docket.data_length = len(data)
     target_docket.tip_rev = revlog.tiprev()
     target_docket.tip_node = revlog.node(target_docket.tip_rev)
--- a/mercurial/util.py	Mon Jun 24 13:15:46 2024 +0200
+++ b/mercurial/util.py	Mon Jul 08 17:56:54 2024 +0200
@@ -441,6 +441,13 @@
 
 
 def mmapread(fp, size=None):
+    """Read a file content using mmap
+
+    The responsability of checking the file system is mmap safe is the
+    responsability of the caller.
+
+    In some case, a normal string might be returned.
+    """
     if size == 0:
         # size of 0 to mmap.mmap() means "all data"
         # rather than "zero bytes", so special case that.
--- a/mercurial/vfs.py	Mon Jun 24 13:15:46 2024 +0200
+++ b/mercurial/vfs.py	Mon Jul 08 17:56:54 2024 +0200
@@ -189,6 +189,35 @@
     def lstat(self, path: Optional[bytes] = None):
         return os.lstat(self.join(path))
 
+    def is_mmap_safe(self, path: Optional[bytes] = None) -> bool:
+        """return True if it is safe to read a file content as mmap
+
+        This focus on the file system aspect of such safety, the application
+        logic around that file is not taken into account, so caller need to
+        make sure the file won't be truncated in a way that will create SIGBUS
+        on access.
+
+
+        The initial motivation for this logic is that if mmap is used on NFS
+        and somebody deletes the mapped file (e.g. by renaming on top of it),
+        then you get SIGBUS, which can be pretty disruptive: we get core dump
+        reports, and the process terminates without writing to the blackbox.
+
+        Instead in this situation we prefer to read the file normally.
+        The risk of ESTALE in the middle of the read remains, but it's
+        smaller because we read sooner and the error should be reported
+        just as any other error.
+
+        Note that python standard library does not offer the necessary function
+        to detect the file stem bits. So this detection rely on compiled bits
+        and is not available in pure python.
+        """
+        # XXX Since we already assume a vfs to address a consistent file system
+        # in other location, we could determine the fstype once for the root
+        # and cache that value.
+        fstype = util.getfstype(self.join(path))
+        return fstype is not None and fstype != b'nfs'
+
     def listdir(self, path: Optional[bytes] = None):
         return os.listdir(self.join(path))
 
--- a/relnotes/6.8	Mon Jun 24 13:15:46 2024 +0200
+++ b/relnotes/6.8	Mon Jul 08 17:56:54 2024 +0200
@@ -1,6 +1,4 @@
-= Mercurial 6.8rc0 =
-
-/!\ This is a tentative release, any and all notes below are subject to change or removal.
+= Mercurial 6.8 =
 
 As usual, a *lot* of patches don't make it to this list.
 
@@ -32,8 +30,6 @@
  * tags-cache: skip the filternode step if we are not going to use it
  * tags-cache: directly operate on rev-num warming hgtagsfnodescache
  * tags-cache: directly perform a monimal walk for hgtagsfnodescache warming
- * exchange: improve computation of relevant markers for large repos
-
 
 == New Experimental Features ==
 
@@ -43,9 +39,9 @@
     * branchcache: add a "pure topological head" fast path
     * branchcache: allow to detect "pure topological case" for branchmap
 
-
 == Bug Fixes ==
 
+ * rust: use `cpython` 0.7.2 crate to add support for Python 3.12
  * perf-stream-locked-section: actually use v1 generation when requested
  * perf-stream-locked-section: fix the call to the v3 generator
  * perf-stream-locked-section: advertise the right version key in the help
@@ -62,6 +58,8 @@
  * hgrc: search XDG_CONFIG_HOME on mac
  * clonebundles: add missing newline to legacy response
  * narrow: add a test for linkrev computation done during widen
+ * Multiple fixes to guard against mmap issues
+ * portability: fix build on Solaris-derived systemd
 
 == Backwards Compatibility Changes ==
 
--- a/rust/Cargo.lock	Mon Jun 24 13:15:46 2024 +0200
+++ b/rust/Cargo.lock	Mon Jul 08 17:56:54 2024 +0200
@@ -236,9 +236,9 @@
 
 [[package]]
 name = "cpython"
-version = "0.7.1"
+version = "0.7.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3052106c29da7390237bc2310c1928335733b286287754ea85e6093d2495280e"
+checksum = "43b398a2c65baaf5892f10bb69b52508bf7a993380cc4ecd3785aaebb5c79389"
 dependencies = [
  "libc",
  "num-traits",
@@ -912,9 +912,9 @@
 
 [[package]]
 name = "python3-sys"
-version = "0.7.1"
+version = "0.7.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "49f8b50d72fb3015735aa403eebf19bbd72c093bfeeae24ee798be5f2f1aab52"
+checksum = "0f53ef6740367a09718d2cd21ba15b0d7972342a38e554736bcee7773e45c9f5"
 dependencies = [
  "libc",
  "regex",
--- a/tests/test-revlog-mmapindex.t	Mon Jun 24 13:15:46 2024 +0200
+++ b/tests/test-revlog-mmapindex.t	Mon Jul 08 17:56:54 2024 +0200
@@ -37,7 +37,7 @@
 
 mmap index which is now more than 4k long
   $ hg log -l 5 -T '{rev}\n' --config experimental.mmapindexthreshold=4k
-  mmapping $TESTTMP/a/.hg/store/00changelog.i
+  mmapping $TESTTMP/a/.hg/store/00changelog.i (no-pure !)
   mmapping $TESTTMP/a/.hg/store/00changelog-????????.nd (glob) (rust !)
   100
   99