changeset 51834:454feddab720

brancing: merge stable into default
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Fri, 06 Sep 2024 02:12:19 +0200
parents 4eccb65e444f (current diff) 6388fd855f66 (diff)
children 6cc18075f82a
files hgext/histedit.py hgext/largefiles/overrides.py hgext/zeroconf/Zeroconf.py mercurial/hgweb/webcommands.py mercurial/keepalive.py mercurial/merge.py mercurial/metadata.py mercurial/patch.py mercurial/posix.py mercurial/statprof.py setup.py
diffstat 22 files changed, 73 insertions(+), 52 deletions(-) [+]
line wrap: on
line diff
--- a/hgext/highlight/__init__.py	Wed Aug 28 23:25:26 2024 +0200
+++ b/hgext/highlight/__init__.py	Fri Sep 06 02:12:19 2024 +0200
@@ -105,4 +105,4 @@
     )
     extensions.wrapfunction(webcommands, 'annotate', annotate_highlight)
     webcommands.highlightcss = generate_css
-    webcommands.__all__.append(b'highlightcss')
+    webcommands.__all__.append('highlightcss')
--- a/hgext/histedit.py	Wed Aug 28 23:25:26 2024 +0200
+++ b/hgext/histedit.py	Fri Sep 06 02:12:19 2024 +0200
@@ -1716,7 +1716,7 @@
             ch = encoding.strtolocal(stdscr.getkey())
 
 
-def _chistedit(ui, repo, freeargs, opts):
+def _chistedit(ui, repo, state, freeargs, opts):
     """interactively edit changeset history via a curses interface
 
     Provides a ncurses interface to histedit. Press ? in chistedit mode
@@ -1776,7 +1776,7 @@
                 for r in rules:
                     fp.write(r)
                 opts[b'commands'] = fp.name
-            return _texthistedit(ui, repo, freeargs, opts)
+            return _texthistedit(ui, repo, state, freeargs, opts)
     except KeyboardInterrupt:
         pass
     return -1
@@ -1915,20 +1915,20 @@
     """
     opts = pycompat.byteskwargs(opts)
 
-    # kludge: _chistedit only works for starting an edit, not aborting
-    # or continuing, so fall back to regular _texthistedit for those
-    # operations.
-    if ui.interface(b'histedit') == b'curses' and _getgoal(opts) == goalnew:
-        return _chistedit(ui, repo, freeargs, opts)
-    return _texthistedit(ui, repo, freeargs, opts)
-
-
-def _texthistedit(ui, repo, freeargs, opts):
     state = histeditstate(repo)
     with repo.wlock() as wlock, repo.lock() as lock:
         state.wlock = wlock
         state.lock = lock
-        _histedit(ui, repo, state, freeargs, opts)
+        # kludge: _chistedit only works for starting an edit, not aborting
+        # or continuing, so fall back to regular _texthistedit for those
+        # operations.
+        if ui.interface(b'histedit') == b'curses' and _getgoal(opts) == goalnew:
+            return _chistedit(ui, repo, state, freeargs, opts)
+        return _texthistedit(ui, repo, state, freeargs, opts)
+
+
+def _texthistedit(ui, repo, state, freeargs, opts):
+    _histedit(ui, repo, state, freeargs, opts)
 
 
 goalcontinue = b'continue'
--- a/hgext/largefiles/overrides.py	Wed Aug 28 23:25:26 2024 +0200
+++ b/hgext/largefiles/overrides.py	Fri Sep 06 02:12:19 2024 +0200
@@ -49,6 +49,8 @@
     actions as upgrade_actions,
 )
 
+from mercurial.utils import urlutil
+
 from . import (
     lfcommands,
     lfutil,
@@ -1139,7 +1141,10 @@
     d = dest
     if d is None:
         d = hg.defaultdest(source)
-    if opts.get('all_largefiles') and not hg.islocal(d):
+    if opts.get('all_largefiles') and urlutil.url(d).scheme not in (
+        b'file',
+        None,
+    ):
         raise error.Abort(
             _(b'--all-largefiles is incompatible with non-local destination %s')
             % d
--- a/hgext/zeroconf/Zeroconf.py	Wed Aug 28 23:25:26 2024 +0200
+++ b/hgext/zeroconf/Zeroconf.py	Fri Sep 06 02:12:19 2024 +0200
@@ -89,7 +89,7 @@
 
 from mercurial import pycompat
 
-__all__ = [b"Zeroconf", b"ServiceInfo", b"ServiceBrowser"]
+__all__ = ["Zeroconf", "ServiceInfo", "ServiceBrowser"]
 
 # hook for threads
 
--- a/mercurial/cffi/bdiff.py	Wed Aug 28 23:25:26 2024 +0200
+++ b/mercurial/cffi/bdiff.py	Fri Sep 06 02:12:19 2024 +0200
@@ -21,11 +21,11 @@
 
 
 def blocks(sa: bytes, sb: bytes) -> List[Tuple[int, int, int, int]]:
-    a = ffi.new(b"struct bdiff_line**")
-    b = ffi.new(b"struct bdiff_line**")
-    ac = ffi.new(b"char[]", str(sa))
-    bc = ffi.new(b"char[]", str(sb))
-    l = ffi.new(b"struct bdiff_hunk*")
+    a = ffi.new("struct bdiff_line**")
+    b = ffi.new("struct bdiff_line**")
+    ac = ffi.new("char[]", bytes(sa))
+    bc = ffi.new("char[]", bytes(sb))
+    l = ffi.new("struct bdiff_hunk*")
     try:
         an = lib.bdiff_splitlines(ac, len(sa), a)
         bn = lib.bdiff_splitlines(bc, len(sb), b)
@@ -49,11 +49,11 @@
 
 
 def bdiff(sa: bytes, sb: bytes) -> bytes:
-    a = ffi.new(b"struct bdiff_line**")
-    b = ffi.new(b"struct bdiff_line**")
-    ac = ffi.new(b"char[]", str(sa))
-    bc = ffi.new(b"char[]", str(sb))
-    l = ffi.new(b"struct bdiff_hunk*")
+    a = ffi.new("struct bdiff_line**")
+    b = ffi.new("struct bdiff_line**")
+    ac = ffi.new("char[]", bytes(sa))
+    bc = ffi.new("char[]", bytes(sb))
+    l = ffi.new("struct bdiff_hunk*")
     try:
         an = lib.bdiff_splitlines(ac, len(sa), a)
         bn = lib.bdiff_splitlines(bc, len(sb), b)
@@ -76,7 +76,7 @@
                         lgt,
                     )
                 )
-                rl.append(str(ffi.buffer((b[0] + lb).l, lgt)))
+                rl.append(bytes(ffi.buffer((b[0] + lb).l, lgt)))
             la = h.a2
             lb = h.b2
             h = h.next
--- a/mercurial/cffi/mpatch.py	Wed Aug 28 23:25:26 2024 +0200
+++ b/mercurial/cffi/mpatch.py	Fri Sep 06 02:12:19 2024 +0200
@@ -19,8 +19,8 @@
 @ffi.def_extern()
 def cffi_get_next_item(arg, pos):
     all, bins = ffi.from_handle(arg)
-    container = ffi.new(b"struct mpatch_flist*[1]")
-    to_pass = ffi.new(b"char[]", str(bins[pos]))
+    container = ffi.new("struct mpatch_flist*[1]")
+    to_pass = ffi.new("char[]", bytes(bins[pos]))
     all.append(to_pass)
     r = lib.mpatch_decode(to_pass, len(to_pass) - 1, container)
     if r < 0:
@@ -41,7 +41,7 @@
     if outlen < 0:
         lib.mpatch_lfree(patch)
         raise mpatchError(b"inconsistency detected")
-    buf = ffi.new(b"char[]", outlen)
+    buf = ffi.new("char[]", outlen)
     if lib.mpatch_apply(buf, text, len(text), patch) < 0:
         lib.mpatch_lfree(patch)
         raise mpatchError(b"error applying patches")
--- a/mercurial/cffi/osutil.py	Wed Aug 28 23:25:26 2024 +0200
+++ b/mercurial/cffi/osutil.py	Fri Sep 06 02:12:19 2024 +0200
@@ -39,8 +39,8 @@
             self.st_mtime = st_mtime
             self.st_size = st_size
 
-    tv_sec_ofs = ffi.offsetof(b"struct timespec", b"tv_sec")
-    buf = ffi.new(b"char[]", listdir_batch_size)
+    tv_sec_ofs = ffi.offsetof("struct timespec", "tv_sec")
+    buf = ffi.new("char[]", listdir_batch_size)
 
     def listdirinternal(dfd, req, stat, skip):
         ret = []
@@ -50,16 +50,16 @@
                 break
             if r == -1:
                 raise OSError(ffi.errno, os.strerror(ffi.errno))
-            cur = ffi.cast(b"val_attrs_t*", buf)
+            cur = ffi.cast("val_attrs_t*", buf)
             for i in range(r):
                 lgt = cur.length
-                assert lgt == ffi.cast(b'uint32_t*', cur)[0]
+                assert lgt == ffi.cast('uint32_t*', cur)[0]
                 ofs = cur.name_info.attr_dataoffset
                 str_lgt = cur.name_info.attr_length
-                base_ofs = ffi.offsetof(b'val_attrs_t', b'name_info')
+                base_ofs = ffi.offsetof('val_attrs_t', 'name_info')
                 name = bytes(
                     ffi.buffer(
-                        ffi.cast(b"char*", cur) + base_ofs + ofs, str_lgt - 1
+                        ffi.cast("char*", cur) + base_ofs + ofs, str_lgt - 1
                     )
                 )
                 tp = attrkinds[cur.obj_type]
@@ -84,12 +84,12 @@
                 else:
                     ret.append((name, tp))
                 cur = ffi.cast(
-                    b"val_attrs_t*", int(ffi.cast(b"intptr_t", cur)) + lgt
+                    "val_attrs_t*", int(ffi.cast("intptr_t", cur)) + lgt
                 )
         return ret
 
     def listdir(path, stat=False, skip=None):
-        req = ffi.new(b"struct attrlist*")
+        req = ffi.new("struct attrlist*")
         req.bitmapcount = lib.ATTR_BIT_MAP_COUNT
         req.commonattr = (
             lib.ATTR_CMN_RETURNED_ATTRS
--- a/mercurial/hgweb/hgweb_mod.py	Wed Aug 28 23:25:26 2024 +0200
+++ b/mercurial/hgweb/hgweb_mod.py	Fri Sep 06 02:12:19 2024 +0200
@@ -464,7 +464,7 @@
 
                 res.headers[b'ETag'] = tag
 
-            if cmd not in webcommands.__all__:
+            if pycompat.sysstr(cmd) not in webcommands.__all__:
                 msg = b'no such method: %s' % cmd
                 raise ErrorResponse(HTTP_BAD_REQUEST, msg)
             else:
--- a/mercurial/hgweb/webcommands.py	Wed Aug 28 23:25:26 2024 +0200
+++ b/mercurial/hgweb/webcommands.py	Fri Sep 06 02:12:19 2024 +0200
@@ -72,7 +72,7 @@
         self.name = name
 
     def __call__(self, func):
-        __all__.append(self.name)
+        __all__.append(pycompat.sysstr(self.name))
         commands[self.name] = func
         return func
 
--- a/mercurial/keepalive.py	Wed Aug 28 23:25:26 2024 +0200
+++ b/mercurial/keepalive.py	Fri Sep 06 02:12:19 2024 +0200
@@ -687,6 +687,6 @@
         N = int(sys.argv[1])
         url = sys.argv[2]
     except (IndexError, ValueError):
-        print(b"%s <integer> <url>" % sys.argv[0])
+        print("%s <integer> <url>" % sys.argv[0])
     else:
         test(url, N)
--- a/mercurial/lsprof.py	Wed Aug 28 23:25:26 2024 +0200
+++ b/mercurial/lsprof.py	Fri Sep 06 02:12:19 2024 +0200
@@ -6,7 +6,7 @@
 # PyPy doesn't expose profiler_entry from the module.
 profiler_entry = getattr(_lsprof, 'profiler_entry', None)
 
-__all__ = [b'profile', b'Stats']
+__all__ = ['profile', 'Stats']
 
 
 def profile(f, *args, **kwds):
--- a/mercurial/merge.py	Wed Aug 28 23:25:26 2024 +0200
+++ b/mercurial/merge.py	Fri Sep 06 02:12:19 2024 +0200
@@ -528,7 +528,7 @@
     """
     # We mutate the items in the dict during iteration, so iterate
     # over a copy.
-    for f, action in mresult.filemap():
+    for f, action in list(mresult.filemap()):
         if narrowmatch(f):
             pass
         elif not branchmerge:
@@ -669,7 +669,7 @@
         return sum(len(self._actionmapping[a]) for a in actions)
 
     def filemap(self, sort=False):
-        if sorted:
+        if sort:
             for key, val in sorted(self._filemapping.items()):
                 yield key, val
         else:
--- a/mercurial/metadata.py	Wed Aug 28 23:25:26 2024 +0200
+++ b/mercurial/metadata.py	Fri Sep 06 02:12:19 2024 +0200
@@ -243,7 +243,7 @@
         return _process_linear(p1, ctx)
     elif p1.rev() == nullrev and p2.rev() != nullrev:
         # In the wild, one can encounter changeset where p1 is null but p2 is not
-        return _process_linear(p1, ctx, parent=2)
+        return _process_linear(p2, ctx, parent=2)
     elif p1.rev() == p2.rev():
         # In the wild, one can encounter such "non-merge"
         return _process_linear(p1, ctx)
--- a/mercurial/patch.py	Wed Aug 28 23:25:26 2024 +0200
+++ b/mercurial/patch.py	Fri Sep 06 02:12:19 2024 +0200
@@ -122,7 +122,7 @@
         if not m.is_multipart():
             yield msgfp(m)
         else:
-            ok_types = (b'text/plain', b'text/x-diff', b'text/x-patch')
+            ok_types = ('text/plain', 'text/x-diff', 'text/x-patch')
             for part in m.walk():
                 ct = part.get_content_type()
                 if ct not in ok_types:
--- a/mercurial/posix.py	Wed Aug 28 23:25:26 2024 +0200
+++ b/mercurial/posix.py	Fri Sep 06 02:12:19 2024 +0200
@@ -23,6 +23,7 @@
 from typing import (
     Any,
     AnyStr,
+    Callable,
     Iterable,
     Iterator,
     List,
@@ -552,7 +553,7 @@
         return False
 
 
-_needsshellquote: Optional[Match[bytes]] = None
+_needsshellquote: Optional[Callable[[bytes], Optional[Match[bytes]]]] = None
 
 
 def shellquote(s: bytes) -> bytes:
--- a/mercurial/statprof.py	Wed Aug 28 23:25:26 2024 +0200
+++ b/mercurial/statprof.py	Fri Sep 06 02:12:19 2024 +0200
@@ -126,7 +126,7 @@
 defaultdict = collections.defaultdict
 contextmanager = contextlib.contextmanager
 
-__all__ = [b'start', b'stop', b'reset', b'display', b'profile']
+__all__ = ['start', 'stop', 'reset', 'display', 'profile']
 
 skips = {
     "util.py:check",
--- a/rust/Cargo.lock	Wed Aug 28 23:25:26 2024 +0200
+++ b/rust/Cargo.lock	Fri Sep 06 02:12:19 2024 +0200
@@ -734,9 +734,9 @@
 
 [[package]]
 name = "libc"
-version = "0.2.137"
+version = "0.2.155"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89"
+checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
 
 [[package]]
 name = "libm"
@@ -1178,6 +1178,7 @@
  "hg-core",
  "home",
  "lazy_static",
+ "libc",
  "log",
  "logging_timer",
  "rayon",
--- a/rust/rhg/Cargo.toml	Wed Aug 28 23:25:26 2024 +0200
+++ b/rust/rhg/Cargo.toml	Fri Sep 06 02:12:19 2024 +0200
@@ -24,3 +24,4 @@
 whoami = "1.4"
 which = "4.3.0"
 rayon = "1.7.0"
+libc = "0.2.155"
--- a/rust/rhg/src/commands/status.rs	Wed Aug 28 23:25:26 2024 +0200
+++ b/rust/rhg/src/commands/status.rs	Fri Sep 06 02:12:19 2024 +0200
@@ -611,7 +611,11 @@
             log::info!("not writing dirstate from `status`: lock is held")
         }
         Err(LockError::Other(HgError::IoError { error, .. }))
-            if error.kind() == io::ErrorKind::PermissionDenied =>
+            if error.kind() == io::ErrorKind::PermissionDenied
+                || match error.raw_os_error() {
+                    None => false,
+                    Some(errno) => libc::EROFS == errno,
+                } =>
         {
             // `hg status` on a read-only repository is fine
         }
--- a/setup.py	Wed Aug 28 23:25:26 2024 +0200
+++ b/setup.py	Fri Sep 06 02:12:19 2024 +0200
@@ -1660,7 +1660,11 @@
     # Allow compiler/linker flags to be added to Visual Studio builds.  Passing
     # extra_link_args to distutils.extensions.Extension() doesn't have any
     # effect.
-    from distutils import msvccompiler
+    try:
+        # setuptools < 65.0
+        from distutils import msvccompiler
+    except ImportError:
+        from distutils import _msvccompiler as msvccompiler
 
     msvccompilerclass = msvccompiler.MSVCCompiler
 
--- a/tests/hgweberror.py	Wed Aug 28 23:25:26 2024 +0200
+++ b/tests/hgweberror.py	Fri Sep 06 02:12:19 2024 +0200
@@ -20,4 +20,4 @@
 
 def extsetup(ui):
     setattr(webcommands, 'raiseerror', raiseerror)
-    webcommands.__all__.append(b'raiseerror')
+    webcommands.__all__.append('raiseerror')
--- a/tests/test-largefiles.t	Wed Aug 28 23:25:26 2024 +0200
+++ b/tests/test-largefiles.t	Fri Sep 06 02:12:19 2024 +0200
@@ -1076,6 +1076,11 @@
   abort: --all-largefiles is incompatible with non-local destination ssh://localhost/a
   [255]
 
+  $ touch existing_destination
+  $ hg clone --all-largefiles a existing_destination
+  abort: destination 'existing_destination' already exists
+  [10]
+
 Test pulling with --all-largefiles flag.  Also test that the largefiles are
 downloaded from 'default' instead of 'default-push' when no source is specified
 (issue3584)