From: Debian Python Team Date: Thu, 20 Mar 2025 12:56:44 +0000 (+0100) Subject: from_upstream_stable X-Git-Tag: archive/raspbian/6.3.2-1+rpi1+deb12u1^2~12 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=b2051971c92de98a14486af6f2513865721cbe40;p=mercurial.git from_upstream_stable Gbp-Pq: Name from_upstream_stable.patch --- diff --git a/.hgsigs b/.hgsigs index a1eac72..4fe5403 100644 --- a/.hgsigs +++ b/.hgsigs @@ -237,3 +237,4 @@ dbdee8ac3e3fcdda1fa55b90c0a235125b7f8e6f 0 iQHNBAABCgA3FiEEH2b4zfZU6QXBHaBhoR4Bz a3356ab610fc50000cf0ba55c424a4d96da11db7 0 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 diff --git a/.hgtags b/.hgtags index c55ef4d..a0b6e30 100644 --- a/.hgtags +++ b/.hgtags @@ -253,3 +253,4 @@ a3356ab610fc50000cf0ba55c424a4d96da11db7 6.3rc0 04f1dba53c961dfdb875c8469adc96fa999cfbed 6.3.0 0000000000000000000000000000000000000000 6.3.0 c890d8b8bc59b18e5febf60caada629df5356ee2 6.3.1 +59466b13a3ae0e29a5d4f485393e516cfbb057d0 6.3.2 diff --git a/Makefile b/Makefile index 823838c..af831b4 100644 --- a/Makefile +++ b/Makefile @@ -58,7 +58,7 @@ help: all: build doc local: - $(PYTHON) setup.py $(PURE) \ + MERCURIAL_SETUP_MAKE_LOCAL=1 $(PYTHON) setup.py $(PURE) \ build_py -c -d . \ build_ext $(COMPILERFLAG) -i \ build_hgexe $(COMPILERFLAG) -i \ diff --git a/contrib/heptapod-ci.yml b/contrib/heptapod-ci.yml index 557c331..6c6bc75 100644 --- a/contrib/heptapod-ci.yml +++ b/contrib/heptapod-ci.yml @@ -34,6 +34,7 @@ checks: variables: RUNTEST_ARGS: "--time --test-list /tmp/check-tests.txt" PYTHON: python3 + CI_CLEVER_CLOUD_FLAVOR: S rust-cargo-test: <<: *all @@ -43,6 +44,7 @@ rust-cargo-test: - make rust-tests variables: PYTHON: python3 + CI_CLEVER_CLOUD_FLAVOR: S test-c: <<: *runtests diff --git a/hgext/convert/bzr.py b/hgext/convert/bzr.py index 3fbc14b..946fea4 100644 --- a/hgext/convert/bzr.py +++ b/hgext/convert/bzr.py @@ -41,6 +41,12 @@ try: revision = breezy.revision revisionspec = breezy.revisionspec revisionspec.RevisionSpec + + try: + # brz 3.3.0 (revno: 7614.2.2) + from breezy.transport import NoSuchFile + except ImportError: + from breezy.errors import NoSuchFile except ImportError: pass @@ -150,7 +156,7 @@ class bzr_source(common.converter_source): try: kind = revtree.kind(name) - except breezy.errors.NoSuchFile: + except NoSuchFile: return None, None if kind not in supportedkinds: # the file is not available anymore - was deleted diff --git a/hgext/convert/cvs.py b/hgext/convert/cvs.py index ebbc8ad..5593ccf 100644 --- a/hgext/convert/cvs.py +++ b/hgext/convert/cvs.py @@ -142,7 +142,9 @@ class convert_cvs(converter_source): if root.startswith(b":pserver:"): root = root[9:] - m = re.match(r'(?:(.*?)(?::(.*?))?@)?([^:/]*)(?::(\d*))?(.*)', root) + m = re.match( + br'(?:(.*?)(?::(.*?))?@)?([^:/]*)(?::(\d*))?(.*)', root + ) if m: conntype = b"pserver" user, passw, serv, port, root = m.groups() @@ -197,7 +199,7 @@ class convert_cvs(converter_source): if sck.recv(128) != b"I LOVE YOU\n": raise error.Abort(_(b"CVS pserver authentication failed")) - self.writep = self.readp = sck.makefile(b'r+') + self.writep = self.readp = sck.makefile('rwb') if not conntype and root.startswith(b":local:"): conntype = b"local" diff --git a/hgext/convert/cvsps.py b/hgext/convert/cvsps.py index abaaec0..4fd0908 100644 --- a/hgext/convert/cvsps.py +++ b/hgext/convert/cvsps.py @@ -686,7 +686,10 @@ def createchangeset(ui, log, fuzz=60, mergefrom=None, mergeto=None): files = set() if len(changesets) % 100 == 0: - t = b'%d %s' % (len(changesets), repr(e.comment)[1:-1]) + t = b'%d %s' % ( + len(changesets), + pycompat.byterepr(e.comment)[2:-1], + ) ui.status(stringutil.ellipsis(t, 80) + b'\n') c.entries.append(e) diff --git a/hgext/convert/darcs.py b/hgext/convert/darcs.py index 00d6805..7055884 100644 --- a/hgext/convert/darcs.py +++ b/hgext/convert/darcs.py @@ -143,7 +143,7 @@ class darcs_source(common.converter_source, common.commandline): def getcommit(self, rev): elt = self.changes[rev] dateformat = b'%a %b %d %H:%M:%S %Z %Y' - date = dateutil.strdate(elt.get('local_date'), dateformat) + date = dateutil.strdate(self.recode(elt.get('local_date')), dateformat) desc = elt.findtext('name') + '\n' + elt.findtext('comment', '') # etree can return unicode objects for name, comment, and author, # so recode() is used to ensure str objects are emitted. diff --git a/hgext/fix.py b/hgext/fix.py index 629384f..af63748 100644 --- a/hgext/fix.py +++ b/hgext/fix.py @@ -698,6 +698,9 @@ def fixfile(ui, repo, opts, fixers, fixctx, path, basepaths, basectxs): command = fixer.command(ui, path, ranges) if command is None: continue + msg = b'fixing: %s - %s - %s\n' + msg %= (fixctx, fixername, path) + ui.debug(msg) ui.debug(b'subprocess: %s\n' % (command,)) proc = subprocess.Popen( procutil.tonativestr(command), diff --git a/hgext/histedit.py b/hgext/histedit.py index fc8223c..a8b17eb 100644 --- a/hgext/histedit.py +++ b/hgext/histedit.py @@ -996,7 +996,7 @@ class base(histeditaction): @action( [b'_multifold'], _( - """fold subclass used for when multiple folds happen in a row + b"""fold subclass used for when multiple folds happen in a row We only want to fire the editor for the folded message once when (say) four changes are folded down into a single change. This is diff --git a/hgext/sparse.py b/hgext/sparse.py index 45dcc84..f3a399e 100644 --- a/hgext/sparse.py +++ b/hgext/sparse.py @@ -374,7 +374,7 @@ def debugsparse(ui, repo, **opts): if refresh: try: wlock = repo.wlock() - fcounts = map( + fcounts = pycompat.maplist( len, sparse.refreshwdir( repo, repo.status(), sparse.matcher(repo), force=force diff --git a/mercurial/bundlerepo.py b/mercurial/bundlerepo.py index ea7de4f..643c8fa 100644 --- a/mercurial/bundlerepo.py +++ b/mercurial/bundlerepo.py @@ -533,6 +533,8 @@ def makebundlerepository(ui, repopath, bundlepath): try: repo = localrepo.instance(ui, repopath, create=False) tempparent = None + except error.RequirementError: + raise # no fallback if the backing repo is unsupported except error.RepoError: tempparent = pycompat.mkdtemp() try: diff --git a/mercurial/commands.py b/mercurial/commands.py index 19d244b..6eea059 100644 --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -7472,6 +7472,9 @@ def tag(ui, repo, name1, *names, **opts): ) node = logcmdutil.revsingle(repo, rev_).node() + if node is None: + raise error.InputError(_(b"cannot tag working directory")) + if not message: # we don't translate commit messages message = b'Added tag %s for changeset %s' % ( diff --git a/mercurial/dirstate.py b/mercurial/dirstate.py index 5921385..c6db338 100644 --- a/mercurial/dirstate.py +++ b/mercurial/dirstate.py @@ -1444,6 +1444,9 @@ class dirstate: """return a filename to backup a data-file or None""" if not self._use_dirstate_v2: return None + if self._map.docket.uuid is None: + # not created yet, nothing to backup + return None data_filename = self._map.docket.data_filename() return data_filename, self.data_backup_filename(backupname) @@ -1514,10 +1517,23 @@ class dirstate: # this "invalidate()" prevents "wlock.release()" from writing # changes of dirstate out after restoring from backup file self.invalidate() - filename = self._actualfilename(tr) o = self._opener + if not o.exists(backupname): + # there was no file backup, delete existing files + filename = self._actualfilename(tr) + data_file = None + if self._use_dirstate_v2 and self._map.docket.uuid is not None: + data_file = self._map.docket.data_filename() + if o.exists(filename): + o.unlink(filename) + if data_file is not None and o.exists(data_file): + o.unlink(data_file) + return + filename = self._actualfilename(tr) data_pair = self.backup_data_file(backupname) - if util.samefile(o.join(backupname), o.join(filename)): + if o.exists(filename) and util.samefile( + o.join(backupname), o.join(filename) + ): o.unlink(backupname) else: o.rename(backupname, filename, checkambig=True) @@ -1534,11 +1550,11 @@ class dirstate: def clearbackup(self, tr, backupname): '''Clear backup file''' o = self._opener - data_backup = self.backup_data_file(backupname) - o.unlink(backupname) - - if data_backup is not None: - o.unlink(data_backup[0]) + if o.exists(backupname): + data_backup = self.backup_data_file(backupname) + o.unlink(backupname) + if data_backup is not None: + o.unlink(data_backup[0]) def verify(self, m1, m2): """check the dirstate content again the parent manifest and yield errors""" diff --git a/mercurial/dirstatemap.py b/mercurial/dirstatemap.py index 1925ee3..f446359 100644 --- a/mercurial/dirstatemap.py +++ b/mercurial/dirstatemap.py @@ -114,6 +114,8 @@ class _dirstatemapcommon: new_docket = docketmod.DirstateDocket.with_new_uuid( self.parents(), len(packed), meta ) + if old_docket.uuid == new_docket.uuid: + raise error.ProgrammingError(b'dirstate docket name collision') data_filename = new_docket.data_filename() self._opener.write(data_filename, packed) # Write the new docket after the new data file has been diff --git a/mercurial/hgweb/server.py b/mercurial/hgweb/server.py index e082552..2e8bcae 100644 --- a/mercurial/hgweb/server.py +++ b/mercurial/hgweb/server.py @@ -203,7 +203,7 @@ class _httprequesthandler(httpservermod.basehttprequesthandler): env['SERVER_PROTOCOL'] = self.request_version env['wsgi.version'] = (1, 0) env['wsgi.url_scheme'] = pycompat.sysstr(self.url_scheme) - if env.get('HTTP_EXPECT', b'').lower() == b'100-continue': + if env.get('HTTP_EXPECT', '').lower() == '100-continue': self.rfile = common.continuereader(self.rfile, self.wfile.write) env['wsgi.input'] = self.rfile diff --git a/mercurial/revset.py b/mercurial/revset.py index 4479b09..d19eed3 100644 --- a/mercurial/revset.py +++ b/mercurial/revset.py @@ -10,7 +10,6 @@ import binascii import functools import random import re -import sys from .i18n import _ from .pycompat import getattr @@ -2355,7 +2354,7 @@ def roots(repo, subset, x): return subset & s.filter(filter, condrepr=b'') -MAXINT = sys.maxsize +MAXINT = (1 << 31) - 1 MININT = -MAXINT - 1 diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py index 6ca6804..8337b2e 100644 --- a/mercurial/scmutil.py +++ b/mercurial/scmutil.py @@ -278,6 +278,11 @@ def checknewlabel(repo, lbl, kind): ) try: int(lbl) + if b'_' in lbl: + # If label contains underscores, Python might consider it an + # integer (with "_" as visual separators), but we do not. + # See PEP 515 - Underscores in Numeric Literals. + raise ValueError raise error.InputError(_(b"cannot use an integer as a name")) except ValueError: pass diff --git a/mercurial/utils/resourceutil.py b/mercurial/utils/resourceutil.py index 0a6d2f9..a30bc7e 100644 --- a/mercurial/utils/resourceutil.py +++ b/mercurial/utils/resourceutil.py @@ -59,7 +59,10 @@ try: from importlib import resources # pytype: disable=import-error # Force loading of the resources module - resources.open_binary # pytype: disable=module-attr + if pycompat.safehasattr(resources, 'files'): + resources.files # pytype: disable=module-attr + else: + resources.open_binary # pytype: disable=module-attr # py2exe raises an AssertionError if uses importlib.resources if getattr(sys, "frozen", None) in ("console_exe", "windows_exe"): @@ -92,9 +95,18 @@ else: from .. import encoding def open_resource(package, name): - return resources.open_binary( # pytype: disable=module-attr - pycompat.sysstr(package), pycompat.sysstr(name) - ) + if pycompat.safehasattr(resources, 'files'): + return ( + resources.files( # pytype: disable=module-attr + pycompat.sysstr(package) + ) + .joinpath(pycompat.sysstr(name)) + .open('rb') + ) + else: + return resources.open_binary( # pytype: disable=module-attr + pycompat.sysstr(package), pycompat.sysstr(name) + ) def is_resource(package, name): return resources.is_resource( # pytype: disable=module-attr diff --git a/relnotes/6.3 b/relnotes/6.3 index 95b6951..b5f5328 100644 --- a/relnotes/6.3 +++ b/relnotes/6.3 @@ -1,3 +1,23 @@ += Mercurial 6.3.2 = + + * [ecfc84b956a8] tests: expect the message from 1baf0fffd82f in test-hghave.t (issue6762) + * [5c095119bff4] tests: add the missing space to test-hghave.t (issue6762) + * [2c346c1c75ec] tests: use an all too familiar executable in test-run-tests.t (issue6661) + * [13c0e3b4fd35] tests: use `test -f` instead of `ls` to see if a file is present (issue6662) + * [8ced4ca30ea1] bisect: correct message about aborting an in-progress bisect (issue6527) + * filemerge: fix crash when using filesets in [partial-merge-tools] + * help: fix a py3 error interpolating Set into b'%s' + * match: make the FLAG_RE pattern a raw string + * python-compat: adapt to Python 3.11 BC breakage with `random.sample` + * rust-status: fix thread count ceiling + * hg: show the correct message when cloning an LFS repo with extension disabled + * extensions: process disabled external paths when `hgext` package is in-memory + * emitrevision: consider ancestors revision to emit as available base + * make: add a target for building pyoxidizer tests on macOS + * run-tests: support --pyoxidized on macOS + * packaging: add dependencies to the PyOxidizer build on macOS + * Miscellaneous test fixes + = Mercurial 6.3.1 = * memory-usage: fix `hg log --follow --rev R F` space complexity (dcb2581e33be) diff --git a/rust/Cargo.lock b/rust/Cargo.lock index 94f6396..55f37c7 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -232,9 +232,9 @@ dependencies = [ [[package]] name = "crossbeam-deque" -version = "0.8.0" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9" +checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc" dependencies = [ "cfg-if 1.0.0", "crossbeam-epoch", @@ -916,26 +916,23 @@ dependencies = [ [[package]] name = "rayon" -version = "1.5.1" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90" +checksum = "6db3a213adf02b3bcfd2d3846bb41cb22857d131789e01df434fb7e7bc0759b7" dependencies = [ - "autocfg", - "crossbeam-deque", "either", "rayon-core", ] [[package]] name = "rayon-core" -version = "1.9.1" +version = "1.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e" +checksum = "356a0625f1954f730c0201cdab48611198dc6ce21f4acff55089b5a78e6e835b" dependencies = [ "crossbeam-channel", "crossbeam-deque", "crossbeam-utils", - "lazy_static", "num_cpus", ] diff --git a/rust/hg-core/Cargo.toml b/rust/hg-core/Cargo.toml index eaa07b1..8c1a808 100644 --- a/rust/hg-core/Cargo.toml +++ b/rust/hg-core/Cargo.toml @@ -23,7 +23,7 @@ ouroboros = "0.15.0" rand = "0.8.4" rand_pcg = "0.3.1" rand_distr = "0.4.3" -rayon = "1.5.1" +rayon = "1.6.1" regex = "1.5.5" sha-1 = "0.10.0" twox-hash = "1.6.2" diff --git a/rust/hg-core/src/narrow.rs b/rust/hg-core/src/narrow.rs index d691bbe..f22afa7 100644 --- a/rust/hg-core/src/narrow.rs +++ b/rust/hg-core/src/narrow.rs @@ -100,12 +100,12 @@ fn validate_patterns(patterns: &[u8]) -> Result<(), SparseConfigError> { } for prefix in VALID_PREFIXES.iter() { if pattern.starts_with(prefix.as_bytes()) { - break; + return Ok(()); } - return Err(SparseConfigError::InvalidNarrowPrefix( - pattern.to_owned(), - )); } + return Err(SparseConfigError::InvalidNarrowPrefix( + pattern.to_owned(), + )); } Ok(()) } diff --git a/rust/rhg/Cargo.toml b/rust/rhg/Cargo.toml index e555ce6..6db4f60 100644 --- a/rust/rhg/Cargo.toml +++ b/rust/rhg/Cargo.toml @@ -22,4 +22,4 @@ env_logger = "0.9.0" format-bytes = "0.3.0" users = "0.11.0" which = "4.2.5" -rayon = "1.5.1" +rayon = "1.6.1" diff --git a/setup.py b/setup.py index a7afcd3..5958404 100644 --- a/setup.py +++ b/setup.py @@ -21,6 +21,11 @@ def sysstr(s): return s.decode('latin-1') +def eprint(*args, **kwargs): + kwargs['file'] = sys.stderr + print(*args, **kwargs) + + import ssl # ssl.HAS_TLSv1* are preferred to check support but they were added in Python @@ -221,9 +226,10 @@ class hgcommand: cmd = self.cmd + args returncode, out, err = runcmd(cmd, self.env) err = filterhgerr(err) - if err or returncode != 0: + if err: print("stderr from '%s':" % (' '.join(cmd)), file=sys.stderr) print(err, file=sys.stderr) + if returncode != 0: return b'' return out @@ -291,10 +297,11 @@ def findhg(): if retcode == 0 and not filterhgerr(err): return hgcommand(hgcmd, hgenv) - raise SystemExit( - 'Unable to find a working hg binary to extract the ' - 'version from the repository tags' - ) + eprint("/!\\") + eprint(r"/!\ Unable to find a working hg binary") + eprint(r"/!\ Version cannot be extract from the repository") + eprint(r"/!\ Re-run the setup once a first version is built") + return None def localhgenv(): @@ -319,29 +326,46 @@ def localhgenv(): version = '' -if os.path.isdir('.hg'): + +def _try_get_version(): hg = findhg() + if hg is None: + return '' + hgid = None + numerictags = [] cmd = ['log', '-r', '.', '--template', '{tags}\n'] - numerictags = [t for t in sysstr(hg.run(cmd)).split() if t[0:1].isdigit()] + pieces = sysstr(hg.run(cmd)).split() + numerictags = [t for t in pieces if t[0:1].isdigit()] hgid = sysstr(hg.run(['id', '-i'])).strip() if not hgid: - # Bail out if hg is having problems interacting with this repository, - # rather than falling through and producing a bogus version number. - # Continuing with an invalid version number will break extensions - # that define minimumhgversion. - raise SystemExit('Unable to determine hg version from local repository') + eprint("/!\\") + eprint(r"/!\ Unable to determine hg version from local repository") + eprint(r"/!\ Failed to retrieve current revision tags") + return '' if numerictags: # tag(s) found version = numerictags[-1] if hgid.endswith('+'): # propagate the dirty status to the tag version += '+' - else: # no tag found + else: # no tag found on the checked out revision ltagcmd = ['parents', '--template', '{latesttag}'] ltag = sysstr(hg.run(ltagcmd)) + if not ltag: + eprint("/!\\") + eprint(r"/!\ Unable to determine hg version from local repository") + eprint( + r"/!\ Failed to retrieve current revision distance to lated tag" + ) + return '' changessincecmd = ['log', '-T', 'x\n', '-r', "only(.,'%s')" % ltag] changessince = len(hg.run(changessincecmd).splitlines()) version = '%s+hg%s.%s' % (ltag, changessince, hgid) if version.endswith('+'): version = version[:-1] + 'local' + time.strftime('%Y%m%d') + return version + + +if os.path.isdir('.hg'): + version = _try_get_version() elif os.path.exists('.hg_archival.txt'): kw = dict( [[t.strip() for t in l.split(':', 1)] for l in open('.hg_archival.txt')] @@ -361,21 +385,35 @@ 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 - if not isinstance(versionb, bytes): - versionb = versionb.encode('ascii') - - write_if_changed( - 'mercurial/__version__.py', - b''.join( - [ - b'# this file is autogenerated by setup.py\n' - b'version = b"%s"\n' % versionb, - ] - ), - ) +if not version: + if os.environ.get("MERCURIAL_SETUP_MAKE_LOCAL") == "1": + version = "0.0+0" + eprint("/!\\") + eprint(r"/!\ Using '0.0+0' as the default version") + eprint(r"/!\ Re-run make local once that first version is built") + eprint("/!\\") + else: + eprint("/!\\") + eprint(r"/!\ Could not determine the Mercurial version") + eprint(r"/!\ You need to build a local version first") + eprint(r"/!\ Run `make local` and try again") + eprint("/!\\") + msg = "Run `make local` first to get a working local version" + raise SystemExit(msg) + +versionb = version +if not isinstance(versionb, bytes): + versionb = versionb.encode('ascii') + +write_if_changed( + 'mercurial/__version__.py', + b''.join( + [ + b'# this file is autogenerated by setup.py\n' + b'version = b"%s"\n' % versionb, + ] + ), +) class hgbuild(build): diff --git a/tests/filtertraceback.py b/tests/filtertraceback.py index 9d2817c..c69b2b7 100755 --- a/tests/filtertraceback.py +++ b/tests/filtertraceback.py @@ -31,6 +31,11 @@ for line in sys.stdin: elif not line.startswith(' '): state = 'none' + elif not line.replace('^', '').replace('~', '').strip(): + # PEP 657: Fine-grained error locations in tracebacks + # ~~~~~~^^^^^^^^^ + continue + elif state == 'file': # Ignore lines after " File " state = 'tb' diff --git a/tests/hghave.py b/tests/hghave.py index 8e45438..65d0a80 100644 --- a/tests/hghave.py +++ b/tests/hghave.py @@ -206,7 +206,7 @@ def has_pyoxidizer(): "pyoxidizer-in-memory", "running with pyoxidizer build as 'hg' with embedded resources", ) -def has_pyoxidizer(): +def has_pyoxidizer_mem(): return 'PYOXIDIZED_IN_MEMORY_RSRC' in os.environ @@ -214,7 +214,7 @@ def has_pyoxidizer(): "pyoxidizer-in-filesystem", "running with pyoxidizer build as 'hg' with external resources", ) -def has_pyoxidizer(): +def has_pyoxidizer_fs(): return 'PYOXIDIZED_FILESYSTEM_RSRC' in os.environ @@ -661,36 +661,22 @@ def has_pygments(): return False -@check("pygments25", "Pygments version >= 2.5") -def pygments25(): +def getpygmentsversion(): try: import pygments v = pygments.__version__ - except ImportError: - return False - - parts = v.split(".") - major = int(parts[0]) - minor = int(parts[1]) - - return (major, minor) >= (2, 5) - -@check("pygments211", "Pygments version >= 2.11") -def pygments211(): - try: - import pygments - - v = pygments.__version__ + parts = v.split(".") + return (int(parts[0]), int(parts[1])) except ImportError: - return False + return (0, 0) - parts = v.split(".") - major = int(parts[0]) - minor = int(parts[1]) - return (major, minor) >= (2, 11) +@checkvers("pygments", "Pygments version >= %s", (2.5, 2.11, 2.14)) +def has_pygments_range(v): + major, minor = v.split('.')[0:2] + return getpygmentsversion() >= (int(major), int(minor)) @check("outer-repo", "outer repo") diff --git a/tests/test-branches.t b/tests/test-branches.t index 60d1948..7317c57 100644 --- a/tests/test-branches.t +++ b/tests/test-branches.t @@ -82,6 +82,11 @@ trailing or leading spaces should be stripped before testing duplicates (use 'hg update' to switch to it) [10] +underscores in numeric branch names (issue6737) + + $ hg branch 2700_210 + marked working directory as branch 2700_210 + verify update will accept invalid legacy branch names $ hg init test-invalid-branch-name diff --git a/tests/test-check-shbang.t b/tests/test-check-shbang.t index 6399ff1..f00e795 100644 --- a/tests/test-check-shbang.t +++ b/tests/test-check-shbang.t @@ -14,7 +14,8 @@ In tests, enforce $PYTHON and *not* /usr/bin/env python or similar: > -X tests/test-check-format.t \ > -X tests/test-check-module-imports.t \ > -X tests/test-check-pyflakes.t \ - > -X tests/test-check-shbang.t + > -X tests/test-check-shbang.t \ + > -X tests/test-highlight.t [1] The above exclusions are because they're looking for files that diff --git a/tests/test-chg.t b/tests/test-chg.t index 613be1f..c908feb 100644 --- a/tests/test-chg.t +++ b/tests/test-chg.t @@ -352,11 +352,10 @@ remove foo repository cache ---------------- - $ rm log/server.log* $ cp $HGRCPATH.unconfigured $HGRCPATH $ cat <<'EOF' >> $HGRCPATH > [cmdserver] - > log = $TESTTMP/log/server.log + > log = $TESTTMP/log/server-cached.log > max-repo-cache = 1 > track-log = command, repocache > EOF @@ -420,9 +419,7 @@ shut down servers and restore environment: check server log: - $ cat log/server.log | filterlog - YYYY/MM/DD HH:MM:SS (PID)> worker process exited (pid=...) - YYYY/MM/DD HH:MM:SS (PID)> worker process exited (pid=...) (?) + $ cat log/server-cached.log | filterlog YYYY/MM/DD HH:MM:SS (PID)> init cached YYYY/MM/DD HH:MM:SS (PID)> id -R cached YYYY/MM/DD HH:MM:SS (PID)> loaded repo into cache: $TESTTMP/cached (in ...s) diff --git a/tests/test-demandimport.py b/tests/test-demandimport.py index 38eafa0..9e2de59 100644 --- a/tests/test-demandimport.py +++ b/tests/test-demandimport.py @@ -9,6 +9,7 @@ import types # Don't import pycompat because it has too many side-effects. ispy3 = sys.version_info[0] >= 3 +ispy311 = (sys.version_info.major, sys.version_info.minor) >= (3, 11) # Only run if demandimport is allowed if subprocess.call( @@ -81,8 +82,7 @@ assert 'mercurial.error' not in sys.modules from mercurial import error as errorproxy if ispy3: - # unsure why this isn't lazy. - assert not isinstance(f, _LazyModule) + assert isinstance(errorproxy, _LazyModule) assert f(errorproxy) == "", f(errorproxy) else: assert f(errorproxy) == "", f(errorproxy) @@ -106,12 +106,18 @@ import os if ispy3: assert not isinstance(os, _LazyModule) - assert f(os) == "", f(os) + if ispy311: + assert f(os) == "", f(os) + else: + assert f(os) == "", f(os) else: assert f(os) == "", f(os) assert f(os.system) == '', f(os.system) -assert f(os) == "", f(os) +if ispy311: + assert f(os) == "", f(os) +else: + assert f(os) == "", f(os) assert 'mercurial.utils.procutil' not in sys.modules from mercurial.utils import procutil diff --git a/tests/test-extension.t b/tests/test-extension.t index 35b0240..8c2ef0a 100644 --- a/tests/test-extension.t +++ b/tests/test-extension.t @@ -598,6 +598,7 @@ Even though the extension fails during uisetup, hg is still basically usable: uisetup(ui) File "$TESTTMP/baduisetup.py", line 2, in uisetup 1 / 0 + ~~^~~ (py311 !) ZeroDivisionError: * by zero (glob) *** failed to set up extension baduisetup: * by zero (glob) Mercurial Distributed SCM (version *) (glob) diff --git a/tests/test-fix.t b/tests/test-fix.t index 9352489..d557e05 100644 --- a/tests/test-fix.t +++ b/tests/test-fix.t @@ -1153,6 +1153,7 @@ useful for anyone trying to set up a new config. $ hg commit -Aqm "foo" $ printf "Foo\nbar\nBaz\n" > foo.changed $ hg --debug fix --working-dir + fixing: f65cf3136d41+ - uppercase-changed-lines - foo.changed subprocess: * $TESTTMP/uppercase.py 1-1 3-3 (glob) $ cd .. diff --git a/tests/test-highlight.t b/tests/test-highlight.t index cfe64dd..4770720 100644 --- a/tests/test-highlight.t +++ b/tests/test-highlight.t @@ -163,7 +163,8 @@ hgweb filerevision, html import itertools def primes(): - """Generate all primes.""" + """Generate all primes.""" (pygments214 !) + """Generate all primes.""" (no-pygments214 !) def sieve(ns): p = ns.next() # It is important to yield *here* in order to stop the @@ -489,7 +490,8 @@ hgweb fileannotate, html changeset - 10 """Generate all primes.""" + 10 """Generate all primes.""" (pygments214 !) + 10 """Generate all primes.""" (no-pygments214 !) @@ -1008,7 +1010,7 @@ We attempt to highlight unknown files by default > EOF $ cat > unknownfile << EOF - > #!$PYTHON + > #!/this/helps/pygments/detect/python > def foo(): > pass > EOF diff --git a/tests/test-lfs-serve-access.t b/tests/test-lfs-serve-access.t index b690258..db038ea 100644 --- a/tests/test-lfs-serve-access.t +++ b/tests/test-lfs-serve-access.t @@ -340,12 +340,14 @@ Test a checksum failure during the processing of the GET request $LOCALIP - - [$ERRDATE$] HG error: Exception happened while processing request '/.git/info/lfs/objects/batch': (glob) $LOCALIP - - [$ERRDATE$] HG error: Traceback (most recent call last): (glob) $LOCALIP - - [$ERRDATE$] HG error: verifies = store.verify(oid) (glob) + $LOCALIP - - [$ERRDATE$] HG error: ^^^^^^^^^^^^^^^^^ (glob) (py311 !) $LOCALIP - - [$ERRDATE$] HG error: raise IOError(errno.EIO, r'%s: I/O error' % oid.decode("utf-8")) (glob) $LOCALIP - - [$ERRDATE$] HG error: *Error: [Errno *] f03217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e: I/O error (glob) $LOCALIP - - [$ERRDATE$] HG error: (glob) $LOCALIP - - [$ERRDATE$] HG error: Exception happened while processing request '/.git/info/lfs/objects/batch': (glob) $LOCALIP - - [$ERRDATE$] HG error: Traceback (most recent call last): (glob) $LOCALIP - - [$ERRDATE$] HG error: verifies = store.verify(oid) (glob) + $LOCALIP - - [$ERRDATE$] HG error: ^^^^^^^^^^^^^^^^^ (glob) (py311 !) $LOCALIP - - [$ERRDATE$] HG error: raise IOError(errno.EIO, r'%s: I/O error' % oid.decode("utf-8")) (glob) $LOCALIP - - [$ERRDATE$] HG error: *Error: [Errno *] b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c: I/O error (glob) $LOCALIP - - [$ERRDATE$] HG error: (glob) @@ -363,19 +365,26 @@ Test a checksum failure during the processing of the GET request self.do_hgweb() for chunk in self.server.application(env, self._start_response): for r in self._runwsgi(req, res, repo): + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ (py311 !) handled = wireprotoserver.handlewsgirequest( (py38 !) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ (py311 !) return _processbasictransfer( (py38 !) + ^^^^^^^^^^^^^^^^^^^^^^ (py311 !) rctx, req, res, self.check_perm (no-py38 !) rctx.repo, req, res, lambda perm: checkperm(rctx, req, perm) (no-py38 !) res.setbodybytes(localstore.read(oid)) + ^^^^^^^^^^^^^^^^^^^^ (py311 !) blob = self._read(self.vfs, oid, verify) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ (py311 !) raise IOError(errno.EIO, r'%s: I/O error' % oid.decode("utf-8")) *Error: [Errno *] 276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d: I/O error (glob) $LOCALIP - - [$ERRDATE$] HG error: Exception happened while processing request '/.hg/lfs/objects/276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d': (glob) $LOCALIP - - [$ERRDATE$] HG error: Traceback (most recent call last): (glob) $LOCALIP - - [$ERRDATE$] HG error: res.setbodybytes(localstore.read(oid)) (glob) + $LOCALIP - - [$ERRDATE$] HG error: ^^^^^^^^^^^^^^^^^^^^ (glob) (py311 !) $LOCALIP - - [$ERRDATE$] HG error: blob = self._read(self.vfs, oid, verify) (glob) + $LOCALIP - - [$ERRDATE$] HG error: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ (glob) (py311 !) $LOCALIP - - [$ERRDATE$] HG error: blobstore._verify(oid, b'dummy content') (glob) $LOCALIP - - [$ERRDATE$] HG error: raise LfsCorruptionError( (glob) (py38 !) $LOCALIP - - [$ERRDATE$] HG error: hint=_(b'run hg verify'), (glob) (no-py38 !) diff --git a/tests/test-narrow-clone.t b/tests/test-narrow-clone.t index ab0076e..b1f5bbd 100644 --- a/tests/test-narrow-clone.t +++ b/tests/test-narrow-clone.t @@ -28,6 +28,18 @@ Only path: and rootfilesin: pattern prefixes are allowed (narrow patterns must begin with one of the following: path:, rootfilesin:) [255] +rootfilesin: patterns work + + $ hg clone --narrow ssh://user@dummy/master rootfilesin --noupdate --include 'rootfilesin:dir' + requesting all changes + adding changesets + adding manifests + adding file changes + added 1 changesets with 0 changes to 0 files + new changesets 26ce255d5b5d + $ hg tracked -R rootfilesin + I rootfilesin:dir + narrow clone a file, f10 $ hg clone --narrow ssh://user@dummy/master narrow --noupdate --include "dir/src/f10" diff --git a/tests/test-remotefilelog-local.t b/tests/test-remotefilelog-local.t index 181e394..a4bfdcb 100644 --- a/tests/test-remotefilelog-local.t +++ b/tests/test-remotefilelog-local.t @@ -77,6 +77,11 @@ n 644 2 * z (glob) $ echo xxxx > x $ echo yyyy > y +# run status early to avoid a flaky second fetch during commit. + $ hg st + M x + M y + \d+ files fetched over \d+ fetches .* (re) (?) $ hg commit -m x created new head 2 files fetched over 1 fetches - (2 misses, 0.00% hit ratio) over *s (glob) @@ -104,6 +109,9 @@ new changesets fed61014d323 (run 'hg heads' to see heads, 'hg merge' to merge) +# run status early to avoid a flaky second fetch during commit + $ hg status + \d+ files fetched over \d+ fetches .* (re) (?) $ hg rebase -d tip rebasing 1:9abfe7bca547 "a" saved backup bundle to $TESTTMP/shallow/.hg/strip-backup/9abfe7bca547-8b11e5ff-rebase.hg (glob) diff --git a/tests/test-requires.t b/tests/test-requires.t index 9f2e9e4..10c47af 100644 --- a/tests/test-requires.t +++ b/tests/test-requires.t @@ -81,4 +81,14 @@ another repository of push/pull/clone on localhost: abort: required features are not supported in the destination: featuresetup-test [255] +Bundlerepo also enforces the underlying repo requirements + + $ hg --cwd supported bundle --all ../bundle.hg + 1 changesets found + $ echo outdoor-pool > push-dst/.hg/requires + $ hg --cwd push-dst log -R ../bundle.hg -T phases + abort: repository requires features unknown to this Mercurial: outdoor-pool + (see https://mercurial-scm.org/wiki/MissingRequirement for more information) + [255] + $ cd .. diff --git a/tests/test-revset.t b/tests/test-revset.t index 6b83e69..d59feb3 100644 --- a/tests/test-revset.t +++ b/tests/test-revset.t @@ -2981,16 +2981,16 @@ random sort $ hg log --rev 'sort(all(), "-random")' | wc -l \s*8 (re) $ hg log --rev 'sort(all(), "random", random.seed=celeste)' + 0 b12 m111 u112 111 10800 + 4 b111 m112 u111 110 14400 + 2 b111 m11 u12 111 3600 6 b111 t2 tu 130 0 + 1 b11 m12 u111 112 7200 7 b111 t3 tu 130 0 - 4 b111 m112 u111 110 14400 - 3 b112 m111 u11 120 0 5 b111 t1 tu 130 0 - 0 b12 m111 u112 111 10800 - 1 b11 m12 u111 112 7200 - 2 b111 m11 u12 111 3600 + 3 b112 m111 u11 120 0 $ hg log --rev 'first(sort(all(), "random", random.seed=celeste))' - 6 b111 t2 tu 130 0 + 0 b12 m111 u112 111 10800 topographical sorting can't be combined with other sort keys, and you can't diff --git a/tests/test-tag.t b/tests/test-tag.t index d4649a3..fda8270 100644 --- a/tests/test-tag.t +++ b/tests/test-tag.t @@ -412,6 +412,10 @@ tagging on null rev abort: cannot tag null revision [10] + $ hg tag -R empty -r "wdir()" -f wdirtag + abort: cannot tag working directory + [10] + issue5539: pruned tags do not appear in .hgtags $ cat >> $HGRCPATH << EOF