D3368: stringutil: ast.literal_eval needs a unicode on py3
durin42 created this revision. Herald added a reviewer: pulkit. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY Fortunately for us, this is really only used internally, so we can be lazy about the encoding here. test-wireproto-framing.py now passes on Python 3. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3368 AFFECTED FILES contrib/python3-whitelist mercurial/utils/stringutil.py CHANGE DETAILS diff --git a/mercurial/utils/stringutil.py b/mercurial/utils/stringutil.py --- a/mercurial/utils/stringutil.py +++ b/mercurial/utils/stringutil.py @@ -516,4 +516,6 @@ def evalpythonliteral(s): """Evaluate a string containing a Python literal expression""" # We could backport our tokenizer hack to rewrite '' to u'' if we want +if pycompat.ispy3: +return ast.literal_eval(s.decode('latin1')) return ast.literal_eval(s) diff --git a/contrib/python3-whitelist b/contrib/python3-whitelist --- a/contrib/python3-whitelist +++ b/contrib/python3-whitelist @@ -444,4 +444,5 @@ test-verify.t test-websub.t test-win32text.t +test-wireproto-framing.py test-xdg.t To: durin42, pulkit, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3369: tests: add all missing b prefixes in reactor tests
durin42 created this revision. Herald added a reviewer: pulkit. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY Both of these tests now pass on Python 3. 1. skip-blame just b prefixes. So many b prefixes. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3369 AFFECTED FILES contrib/python3-whitelist tests/test-wireproto-clientreactor.py tests/test-wireproto-serverreactor.py CHANGE DETAILS diff --git a/tests/test-wireproto-serverreactor.py b/tests/test-wireproto-serverreactor.py --- a/tests/test-wireproto-serverreactor.py +++ b/tests/test-wireproto-serverreactor.py @@ -62,58 +62,58 @@ stream = framing.stream(1) results = list(sendcommandframes(reactor, stream, 1, b'mycommand', {})) self.assertEqual(len(results), 1) -self.assertaction(results[0], 'runcommand') +self.assertaction(results[0], b'runcommand') self.assertEqual(results[0][1], { -'requestid': 1, -'command': b'mycommand', -'args': {}, -'data': None, +b'requestid': 1, +b'command': b'mycommand', +b'args': {}, +b'data': None, }) result = reactor.oninputeof() -self.assertaction(result, 'noop') +self.assertaction(result, b'noop') def test1argument(self): reactor = makereactor() stream = framing.stream(1) results = list(sendcommandframes(reactor, stream, 41, b'mycommand', {b'foo': b'bar'})) self.assertEqual(len(results), 1) -self.assertaction(results[0], 'runcommand') +self.assertaction(results[0], b'runcommand') self.assertEqual(results[0][1], { -'requestid': 41, -'command': b'mycommand', -'args': {b'foo': b'bar'}, -'data': None, +b'requestid': 41, +b'command': b'mycommand', +b'args': {b'foo': b'bar'}, +b'data': None, }) def testmultiarguments(self): reactor = makereactor() stream = framing.stream(1) results = list(sendcommandframes(reactor, stream, 1, b'mycommand', {b'foo': b'bar', b'biz': b'baz'})) self.assertEqual(len(results), 1) -self.assertaction(results[0], 'runcommand') +self.assertaction(results[0], b'runcommand') self.assertEqual(results[0][1], { -'requestid': 1, -'command': b'mycommand', -'args': {b'foo': b'bar', b'biz': b'baz'}, -'data': None, +b'requestid': 1, +b'command': b'mycommand', +b'args': {b'foo': b'bar', b'biz': b'baz'}, +b'data': None, }) def testsimplecommanddata(self): reactor = makereactor() stream = framing.stream(1) results = list(sendcommandframes(reactor, stream, 1, b'mycommand', {}, util.bytesio(b'data!'))) self.assertEqual(len(results), 2) -self.assertaction(results[0], 'wantframe') -self.assertaction(results[1], 'runcommand') +self.assertaction(results[0], b'wantframe') +self.assertaction(results[1], b'runcommand') self.assertEqual(results[1][1], { -'requestid': 1, -'command': b'mycommand', -'args': {}, -'data': b'data!', +b'requestid': 1, +b'command': b'mycommand', +b'args': {}, +b'data': b'data!', }) def testmultipledataframes(self): @@ -129,13 +129,13 @@ results = list(sendframes(reactor, frames)) self.assertEqual(len(results), 4) for i in range(3): -self.assertaction(results[i], 'wantframe') -self.assertaction(results[3], 'runcommand') +self.assertaction(results[i], b'wantframe') +self.assertaction(results[3], b'runcommand') self.assertEqual(results[3][1], { -'requestid': 1, -'command': b'mycommand', -'args': {}, -'data': b'data1data2data3', +b'requestid': 1, +b'command': b'mycommand', +b'args': {}, +b'data': b'data1data2data3', }) def testargumentanddata(self): @@ -150,42 +150,42 @@ reactor = makereactor() results = list(sendframes(reactor, frames)) -self.assertaction(results[-1], 'runcommand') +self.assertaction(results[-1], b'runcommand') self.assertEqual(results[-1][1], { -'requestid': 1, -'command': b'command', -'args': { +b'requestid': 1, +b'command': b'command', +b'args': { b'key': b'val', b'foo': b'bar', }, -'data':
[PATCH] fix: use templater to substitute values in command string
# HG changeset patch # User Yuya Nishihara# Date 1523633439 -32400 # Sat Apr 14 00:30:39 2018 +0900 # Node ID c11220384fc8e9bea55193401835a60d241c372f # Parent 611a3c98d1b68836b5725a0d97c0ae1f0b3677f6 fix: use templater to substitute values in command string bytes.format() isn't supported on Python 3. Luckily, our template syntax is similar so we can reuse it. We need a hack to disable \-escapes as '\' is a directory separator on Windows. diff --git a/hgext/fix.py b/hgext/fix.py --- a/hgext/fix.py +++ b/hgext/fix.py @@ -387,7 +387,7 @@ def fixfile(ui, opts, fixers, fixctx, pa for fixername, fixer in fixers.iteritems(): if fixer.affects(opts, fixctx, path): ranges = lineranges(opts, path, basectxs, fixctx, newdata) -command = fixer.command(path, ranges) +command = fixer.command(ui, path, ranges) if command is None: continue ui.debug('subprocess: %s\n' % (command,)) @@ -534,18 +534,20 @@ class Fixer(object): """Should this fixer run on the file at the given path and context?""" return scmutil.match(fixctx, [self._fileset], opts)(path) -def command(self, path, ranges): +def command(self, ui, path, ranges): """A shell command to use to invoke this fixer on the given file/lines May return None if there is no appropriate command to run for the given parameters. """ -parts = [self._command.format(rootpath=path, - basename=os.path.basename(path))] +expand = cmdutil.rendercommandtemplate +parts = [expand(ui, self._command, +{'rootpath': path, 'basename': os.path.basename(path)})] if self._linerange: if not ranges: # No line ranges to fix, so don't run the fixer. return None for first, last in ranges: -parts.append(self._linerange.format(first=first, last=last)) +parts.append(expand(ui, self._linerange, +{'first': first, 'last': last})) return ' '.join(parts) diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py --- a/mercurial/cmdutil.py +++ b/mercurial/cmdutil.py @@ -899,6 +899,33 @@ def getcommiteditor(edit=False, finishde else: return commiteditor +def _escapecommandtemplate(tmpl): +parts = [] +for typ, start, end in templater.scantemplate(tmpl, raw=True): +if typ == b'string': +parts.append(stringutil.escapestr(tmpl[start:end])) +else: +parts.append(tmpl[start:end]) +return b''.join(parts) + +def rendercommandtemplate(ui, tmpl, props): +r"""Expand a literal template 'tmpl' in a way suitable for command line + +'\' in outermost string is not taken as an escape character because it +is a directory separator on Windows. + +>>> from . import ui as uimod +>>> ui = uimod.ui() +>>> rendercommandtemplate(ui, b'c:\\{path}', {b'path': b'foo'}) +'c:\\foo' +>>> rendercommandtemplate(ui, b'{"c:\\{path}"}', {'path': b'foo'}) +'c:{path}' +""" +if not tmpl: +return tmpl +t = formatter.maketemplater(ui, _escapecommandtemplate(tmpl)) +return t.renderdefault(props) + def rendertemplate(ctx, tmpl, props=None): """Expand a literal template 'tmpl' byte-string against one changeset ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
mercurial@37497: new changeset
New changeset in mercurial: https://www.mercurial-scm.org/repo/hg/rev/1541e1a8e87d changeset: 37497:1541e1a8e87d bookmark:@ tag: tip user:Gregory Szorcdate:Fri Apr 06 22:39:58 2018 -0700 summary: filelog: wrap revlog instead of inheriting it (API) -- Repository URL: https://www.mercurial-scm.org/repo/hg ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3367: hgwebdir: un-bytes the env dict before re-parsing env
durin42 created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY Not the most elegant, but it restores test-subrepo-deep-nested-change.t to passing on Python 3. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3367 AFFECTED FILES mercurial/hgweb/hgwebdir_mod.py CHANGE DETAILS diff --git a/mercurial/hgweb/hgwebdir_mod.py b/mercurial/hgweb/hgwebdir_mod.py --- a/mercurial/hgweb/hgwebdir_mod.py +++ b/mercurial/hgweb/hgwebdir_mod.py @@ -422,8 +422,10 @@ if real: # Re-parse the WSGI environment to take into account our # repository path component. +uenv = {k.decode('latin1'): v for k, v in +req.rawenv.iteritems()} req = requestmod.parserequestfromenv( -req.rawenv, reponame=virtualrepo, +uenv, reponame=virtualrepo, altbaseurl=self.ui.config('web', 'baseurl')) try: # ensure caller gets private copy of ui To: durin42, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3366: tests: port inline extension in test-http-bundle1.t to py3
durin42 created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY 1. skip-blame just b prefixes REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3366 AFFECTED FILES tests/test-http-bundle1.t CHANGE DETAILS diff --git a/tests/test-http-bundle1.t b/tests/test-http-bundle1.t --- a/tests/test-http-bundle1.t +++ b/tests/test-http-bundle1.t @@ -179,13 +179,13 @@ > import base64 > from mercurial.hgweb import common > def perform_authentication(hgweb, req, op): - > auth = req.headers.get('Authorization') + > auth = req.headers.get(b'Authorization') > if not auth: - > raise common.ErrorResponse(common.HTTP_UNAUTHORIZED, 'who', - > [('WWW-Authenticate', 'Basic Realm="mercurial"')]) + > raise common.ErrorResponse(common.HTTP_UNAUTHORIZED, b'who', + > [(b'WWW-Authenticate', b'Basic Realm="mercurial"')]) > if base64.b64decode(auth.split()[1]).split(b':', 1) != [b'user', > b'pass']: - > raise common.ErrorResponse(common.HTTP_FORBIDDEN, 'no') + > raise common.ErrorResponse(common.HTTP_FORBIDDEN, b'no') > def extsetup(): > common.permhooks.insert(0, perform_authentication) > EOT To: durin42, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3365: commands: drop spurious r'' on dry_run in forget
durin42 created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY Fixes test-add.t on Python 3. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3365 AFFECTED FILES mercurial/commands.py CHANGE DETAILS diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -2090,7 +2090,7 @@ raise error.Abort(_('no files specified')) m = scmutil.match(repo[None], pats, opts) -dryrun = opts.get(r'dry_run') +dryrun = opts.get('dry_run') rejected = cmdutil.forget(ui, repo, m, prefix="", explicitonly=False, dryrun=dryrun)[0] return rejected and 1 or 0 To: durin42, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3364: largefiles: opts appears to already be bytes in this instance
durin42 created this revision. Herald added a reviewer: pulkit. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY test-largefiles.t now passes. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3364 AFFECTED FILES contrib/python3-whitelist hgext/largefiles/overrides.py CHANGE DETAILS diff --git a/hgext/largefiles/overrides.py b/hgext/largefiles/overrides.py --- a/hgext/largefiles/overrides.py +++ b/hgext/largefiles/overrides.py @@ -897,7 +897,7 @@ # Caching is implicitly limited to 'rev' option, since the dest repo was # truncated at that point. The user may expect a download count with # this option, so attempt whether or not this is a largefile repo. -if opts.get(r'all_largefiles'): +if opts.get('all_largefiles'): success, missing = lfcommands.downloadlfiles(ui, repo, None) if missing != 0: diff --git a/contrib/python3-whitelist b/contrib/python3-whitelist --- a/contrib/python3-whitelist +++ b/contrib/python3-whitelist @@ -210,6 +210,7 @@ test-largefiles-misc.t test-largefiles-small-disk.t test-largefiles-update.t +test-largefiles.t test-lfs-largefiles.t test-linerange.py test-locate.t To: durin42, pulkit, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3363: tests: port inline extensions in test-hook.t to py3
durin42 created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY This test *almost* passes now, but some import errors print very differently in ways that seem at least somewhat important. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3363 AFFECTED FILES tests/test-hook.t CHANGE DETAILS diff --git a/tests/test-hook.t b/tests/test-hook.t --- a/tests/test-hook.t +++ b/tests/test-hook.t @@ -3,8 +3,11 @@ $ cat > $TESTTMP/txnabort.checkargs.py < from mercurial import pycompat > def showargs(ui, repo, hooktype, **kwargs): - > ui.write('%s Python hook: %s\n' % (hooktype, ','.join(sorted(kwargs + > kwargs = pycompat.byteskwargs(kwargs) + > ui.write(b'%s Python hook: %s\n' % (hooktype, + > b','.join(sorted(kwargs > EOF $ hg init a @@ -410,12 +413,15 @@ $ cat > hooktests.py < from __future__ import print_function - > from mercurial import error + > from mercurial import ( + > error, + > pycompat, + > ) > > uncallable = 0 > > def printargs(ui, args): - > a = list(args.items()) + > a = list(pycompat.byteskwargs(args).items()) > a.sort() > ui.write(b'hook args:\n') > for k, v in a: @@ -432,7 +438,7 @@ > pass > > def raisehook(**args): - > raise LocalException(b'exception from hook') + > raise LocalException('exception from hook') > > def aborthook(**args): > raise error.Abort(b'raise abort from hook') @@ -630,10 +636,10 @@ $ cat > hookext.py < def autohook(ui, **args): - > ui.write('Automatically installed hook\n') + > ui.write(b'Automatically installed hook\n') > > def reposetup(ui, repo): - > repo.ui.setconfig("hooks", "commit.auto", autohook) + > repo.ui.setconfig(b"hooks", b"commit.auto", autohook) > EOF $ echo '[extensions]' >> .hg/hgrc $ echo 'hookext = hookext.py' >> .hg/hgrc To: durin42, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3362: tests: manually print list in test-hook.t
durin42 created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY Changes the output a bit, but not in an important way. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3362 AFFECTED FILES tests/test-hook.t CHANGE DETAILS diff --git a/tests/test-hook.t b/tests/test-hook.t --- a/tests/test-hook.t +++ b/tests/test-hook.t @@ -444,7 +444,7 @@ > ui.note(b'verbose output from hook\n') > > def printtags(ui, repo, **args): - > ui.write(b'%s\n' % sorted(repo.tags())) + > ui.write(b'[%s]\n' % b', '.join(sorted(repo.tags( > > class container: > unreachable = 1 @@ -766,7 +766,7 @@ $ echo 'pretxncommit.printtags = python:hooktests.printtags' >> .hg/hgrc $ hg tag -f foo - ['a', 'foo', 'tip'] + [a, foo, tip] post-init hooks must not crash (issue4983) This also creates the `to` repo for the next test block. To: durin42, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3361: hook: also use pprint on lists for stable output on py2/3
durin42 created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3361 AFFECTED FILES mercurial/hook.py CHANGE DETAILS diff --git a/mercurial/hook.py b/mercurial/hook.py --- a/mercurial/hook.py +++ b/mercurial/hook.py @@ -137,7 +137,7 @@ for k, v in args.iteritems(): if callable(v): v = v() -if isinstance(v, dict): +if isinstance(v, (dict, list)): v = stringutil.pprint(v, bprefix=False) env['HG_' + k.upper()] = v To: durin42, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3360: hook: use stringutil.pprint instead of reinventing it
durin42 created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3360 AFFECTED FILES mercurial/hook.py CHANGE DETAILS diff --git a/mercurial/hook.py b/mercurial/hook.py --- a/mercurial/hook.py +++ b/mercurial/hook.py @@ -21,6 +21,7 @@ ) from .utils import ( procutil, +stringutil, ) def _pythonhook(ui, repo, htype, hname, funcname, args, throw): @@ -137,11 +138,7 @@ if callable(v): v = v() if isinstance(v, dict): -# make the dictionary element order stable across Python -# implementations -v = ('{' + - ', '.join('%r: %r' % i for i in sorted(v.iteritems())) + - '}') +v = stringutil.pprint(v, bprefix=False) env['HG_' + k.upper()] = v if repo: To: durin42, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3356: wsgicgi: un-do some prior porting work that is now wrong
durin42 created this revision. Herald added a reviewer: pulkit. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY The Python 3 WSGI behavior is that the environ dict should be full of unicodes. We previously tried Too Hard here, so we unwind that bit of porting. Also add some bytesurl() encodes on status and headers. test-clone-cgi.t now passes. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3356 AFFECTED FILES contrib/python3-whitelist mercurial/hgweb/wsgicgi.py CHANGE DETAILS diff --git a/mercurial/hgweb/wsgicgi.py b/mercurial/hgweb/wsgicgi.py --- a/mercurial/hgweb/wsgicgi.py +++ b/mercurial/hgweb/wsgicgi.py @@ -10,8 +10,10 @@ from __future__ import absolute_import +import os + from .. import ( -encoding, +pycompat, ) from ..utils import ( @@ -26,7 +28,7 @@ procutil.setbinary(procutil.stdin) procutil.setbinary(procutil.stdout) -environ = dict(encoding.environ.iteritems()) +environ = dict(os.environ.iteritems()) # re-exports environ.setdefault(r'PATH_INFO', '') if environ.get(r'SERVER_SOFTWARE', r'').startswith(r'Microsoft-IIS'): # IIS includes script_name in PATH_INFO @@ -61,9 +63,10 @@ elif not headers_sent: # Before the first output, send the stored headers status, response_headers = headers_sent[:] = headers_set -out.write('Status: %s\r\n' % status) -for header in response_headers: -out.write('%s: %s\r\n' % header) +out.write('Status: %s\r\n' % pycompat.bytesurl(status)) +for hk, hv in response_headers: +out.write('%s: %s\r\n' % (pycompat.bytesurl(hk), + pycompat.bytesurl(hv))) out.write('\r\n') out.write(data) diff --git a/contrib/python3-whitelist b/contrib/python3-whitelist --- a/contrib/python3-whitelist +++ b/contrib/python3-whitelist @@ -45,6 +45,7 @@ test-check-pylint.t test-check-shbang.t test-children.t +test-clone-cgi.t test-clone-pull-corruption.t test-clone-r.t test-clone-update-order.t To: durin42, pulkit, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3353: tests: port inline cgi script in test-largefiles.t to python 3
durin42 created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3353 AFFECTED FILES tests/test-largefiles.t CHANGE DETAILS diff --git a/tests/test-largefiles.t b/tests/test-largefiles.t --- a/tests/test-largefiles.t +++ b/tests/test-largefiles.t @@ -219,7 +219,7 @@ > from mercurial import demandimport; demandimport.enable() > from mercurial.hgweb import hgweb > from mercurial.hgweb import wsgicgi - > application = hgweb('.', 'test repo') + > application = hgweb(b'.', b'test repo') > wsgicgi.launch(application) > EOF $ . "$TESTDIR/cgienv" To: durin42, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3359: stringutil: make b prefixes on string output optional
durin42 created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY I need this to preserve some behavior in hook.py. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3359 AFFECTED FILES mercurial/utils/stringutil.py CHANGE DETAILS diff --git a/mercurial/utils/stringutil.py b/mercurial/utils/stringutil.py --- a/mercurial/utils/stringutil.py +++ b/mercurial/utils/stringutil.py @@ -23,19 +23,23 @@ pycompat, ) -def pprint(o): +def pprint(o, bprefix=True): """Pretty print an object.""" if isinstance(o, bytes): -return "b'%s'" % escapestr(o) +if bprefix: +return "b'%s'" % escapestr(o) +return "'%s'" % escapestr(o) elif isinstance(o, bytearray): # codecs.escape_encode() can't handle bytearray, so escapestr fails # without coercion. return "bytearray['%s']" % escapestr(bytes(o)) elif isinstance(o, list): -return '[%s]' % (b', '.join(pprint(a) for a in o)) +return '[%s]' % (b', '.join(pprint(a, bprefix=bprefix) for a in o)) elif isinstance(o, dict): return '{%s}' % (b', '.join( -'%s: %s' % (pprint(k), pprint(v)) for k, v in sorted(o.items( +'%s: %s' % (pprint(k, bprefix=bprefix), +pprint(v, bprefix=bprefix)) +for k, v in sorted(o.items( elif isinstance(o, bool): return b'True' if o else b'False' elif isinstance(o, int): To: durin42, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3357: tests: update inline extensions in test-bundle2-exchange.t to py3
durin42 created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY The test doesn't pass for what superficially look like good reasons. We'll need to come back to it later. 1. skip-blame because it's b prefixes and a couple of b'N' instead of str(N) REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3357 AFFECTED FILES tests/test-bundle2-exchange.t CHANGE DETAILS diff --git a/tests/test-bundle2-exchange.t b/tests/test-bundle2-exchange.t --- a/tests/test-bundle2-exchange.t +++ b/tests/test-bundle2-exchange.t @@ -472,28 +472,28 @@ > > configtable = {} > configitem = registrar.configitem(configtable) - > configitem('failpush', 'reason', + > configitem(b'failpush', b'reason', > default=None, > ) > > def _pushbundle2failpart(pushop, bundler): - > reason = pushop.ui.config('failpush', 'reason') + > reason = pushop.ui.config(b'failpush', b'reason') > part = None - > if reason == 'abort': - > bundler.newpart('test:abort') - > if reason == 'unknown': - > bundler.newpart('test:unknown') - > if reason == 'race': + > if reason == b'abort': + > bundler.newpart(b'test:abort') + > if reason == b'unknown': + > bundler.newpart(b'test:unknown') + > if reason == b'race': > # 20 Bytes of crap - > bundler.newpart('check:heads', data='01234567890123456789') + > bundler.newpart(b'check:heads', data=b'01234567890123456789') > - > @bundle2.parthandler("test:abort") + > @bundle2.parthandler(b"test:abort") > def handleabort(op, part): - > raise error.Abort('Abandon ship!', hint="don't panic") + > raise error.Abort(b'Abandon ship!', hint=b"don't panic") > > def uisetup(ui): - > exchange.b2partsgenmapping['failpart'] = _pushbundle2failpart - > exchange.b2partsgenorder.insert(0, 'failpart') + > exchange.b2partsgenmapping[b'failpart'] = _pushbundle2failpart + > exchange.b2partsgenorder.insert(0, b'failpart') > > EOF @@ -782,16 +782,16 @@ > from mercurial import pushkey > from mercurial import node > from mercurial import error - > @exchange.b2partsgenerator('failingpuskey') + > @exchange.b2partsgenerator(b'failingpuskey') > def addfailingpushey(pushop, bundler): > enc = pushkey.encode - > part = bundler.newpart('pushkey') - > part.addparam('namespace', enc('phases')) - > part.addparam('key', enc('cd010b8cd998f3981a5a8115f94f8da4ab506089')) - > part.addparam('old', enc(str(0))) # successful update - > part.addparam('new', enc(str(0))) + > part = bundler.newpart(b'pushkey') + > part.addparam(b'namespace', enc(b'phases')) + > part.addparam(b'key', enc(b'cd010b8cd998f3981a5a8115f94f8da4ab506089')) + > part.addparam(b'old', enc(b'0')) # successful update + > part.addparam(b'new', enc(b'0')) > def fail(pushop, exc): - > raise error.Abort('Correct phase push failed (because hooks)') + > raise error.Abort(b'Correct phase push failed (because hooks)') > pushop.pkfailcb[part.id] = fail > EOF $ cat >> $HGRCPATH << EOF @@ -858,16 +858,16 @@ > from mercurial import pushkey > from mercurial import node > from mercurial import error - > @exchange.b2partsgenerator('failingpuskey') + > @exchange.b2partsgenerator(b'failingpuskey') > def addfailingpushey(pushop, bundler): > enc = pushkey.encode - > part = bundler.newpart('pushkey') - > part.addparam('namespace', enc('phases')) - > part.addparam('key', enc('cd010b8cd998f3981a5a8115f94f8da4ab506089')) - > part.addparam('old', enc(str(4))) # will fail - > part.addparam('new', enc(str(3))) + > part = bundler.newpart(b'pushkey') + > part.addparam(b'namespace', enc(b'phases')) + > part.addparam(b'key', enc(b'cd010b8cd998f3981a5a8115f94f8da4ab506089')) + > part.addparam(b'old', enc(b'4')) # will fail + > part.addparam(b'new', enc(b'3')) > def fail(pushop, exc): - > raise error.Abort('Clown phase push failed') + > raise error.Abort(b'Clown phase push failed') > pushop.pkfailcb[part.id] = fail > EOF $ cat >> $HGRCPATH << EOF To: durin42, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3350: tests: fix up a couple of minor bytes inconsistencies in run-tests.py
durin42 created this revision. Herald added a reviewer: pulkit. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY Only in the automatic bisection code, so fortunately nothing major is amiss. Fixes test-run-tests.t under Python 3. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3350 AFFECTED FILES contrib/python3-whitelist tests/run-tests.py CHANGE DETAILS diff --git a/tests/run-tests.py b/tests/run-tests.py --- a/tests/run-tests.py +++ b/tests/run-tests.py @@ -2215,10 +2215,11 @@ 'Failed to identify failure point for %s' % test) continue dat = m.groupdict() -verb = 'broken' if dat['goodbad'] == 'bad' else 'fixed' +verb = 'broken' if dat['goodbad'] == b'bad' else 'fixed' self.stream.writeln( '%s %s by %s (%s)' % ( -test, verb, dat['node'], dat['summary'])) +test, verb, dat['node'].decode('ascii'), +dat['summary'].decode('utf8', 'ignore'))) def printtimes(self, times): # iolock held by run diff --git a/contrib/python3-whitelist b/contrib/python3-whitelist --- a/contrib/python3-whitelist +++ b/contrib/python3-whitelist @@ -392,6 +392,7 @@ test-revset-outgoing.t test-rollback.t test-run-tests.py +test-run-tests.t test-schemes.t test-serve.t test-setdiscovery.t To: durin42, pulkit, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3358: stringutil: teach pprint how to format None
durin42 created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3358 AFFECTED FILES mercurial/utils/stringutil.py CHANGE DETAILS diff --git a/mercurial/utils/stringutil.py b/mercurial/utils/stringutil.py --- a/mercurial/utils/stringutil.py +++ b/mercurial/utils/stringutil.py @@ -42,6 +42,8 @@ return '%d' % o elif isinstance(o, float): return '%f' % o +elif o is None: +return b'None' else: raise error.ProgrammingError('do not know how to format %r' % o) To: durin42, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3351: py3: fix test-shelve.t on Python 3
durin42 created this revision. Herald added a reviewer: pulkit. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY We get a better error message out of the abort here, which is fine. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3351 AFFECTED FILES contrib/python3-whitelist tests/test-shelve.t CHANGE DETAILS diff --git a/tests/test-shelve.t b/tests/test-shelve.t --- a/tests/test-shelve.t +++ b/tests/test-shelve.t @@ -1273,7 +1273,7 @@ $ rm .hg/unshelverebasestate $ hg unshelve --abort unshelve of 'default' aborted - abort: $ENOENT$ + abort: $ENOENT$* (glob) [255] Can the user leave the current state? $ hg up -C . diff --git a/contrib/python3-whitelist b/contrib/python3-whitelist --- a/contrib/python3-whitelist +++ b/contrib/python3-whitelist @@ -397,6 +397,7 @@ test-serve.t test-setdiscovery.t test-share.t +test-shelve.t test-show-stack.t test-show-work.t test-show.t To: durin42, pulkit, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3355: hgweb_mod: inform hgweb class about paths actually being bytes
durin42 created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3355 AFFECTED FILES mercurial/hgweb/hgweb_mod.py CHANGE DETAILS diff --git a/mercurial/hgweb/hgweb_mod.py b/mercurial/hgweb/hgweb_mod.py --- a/mercurial/hgweb/hgweb_mod.py +++ b/mercurial/hgweb/hgweb_mod.py @@ -208,7 +208,7 @@ be multiple active threads inside __call__. """ def __init__(self, repo, name=None, baseui=None): -if isinstance(repo, str): +if isinstance(repo, bytes): if baseui: u = baseui.copy() else: To: durin42, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3354: hgweb: inform hgweb.hgweb() entrypoint that paths should be bytes
durin42 created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3354 AFFECTED FILES mercurial/hgweb/__init__.py CHANGE DETAILS diff --git a/mercurial/hgweb/__init__.py b/mercurial/hgweb/__init__.py --- a/mercurial/hgweb/__init__.py +++ b/mercurial/hgweb/__init__.py @@ -38,7 +38,7 @@ - list of virtual:real tuples (multi-repo view) ''' -if ((isinstance(config, str) and not os.path.isdir(config)) or +if ((isinstance(config, bytes) and not os.path.isdir(config)) or isinstance(config, dict) or isinstance(config, list)): # create a multi-dir interface return hgwebdir_mod.hgwebdir(config, baseui=baseui) To: durin42, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3352: lfcommands: use %d on known-int in format string
durin42 created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3352 AFFECTED FILES hgext/largefiles/lfcommands.py CHANGE DETAILS diff --git a/hgext/largefiles/lfcommands.py b/hgext/largefiles/lfcommands.py --- a/hgext/largefiles/lfcommands.py +++ b/hgext/largefiles/lfcommands.py @@ -589,7 +589,7 @@ numcached = 0 for rev in revs: -ui.note(_('pulling largefiles for revision %s\n') % rev) +ui.note(_('pulling largefiles for revision %d\n') % rev) (cached, missing) = cachelfiles(ui, repo, rev) numcached += len(cached) ui.status(_("%d largefiles cached\n") % numcached) To: durin42, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3345: httppeer: fix debug prints to work on Python 3
durin42 created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3345 AFFECTED FILES mercurial/httppeer.py CHANGE DETAILS diff --git a/mercurial/httppeer.py b/mercurial/httppeer.py --- a/mercurial/httppeer.py +++ b/mercurial/httppeer.py @@ -273,7 +273,8 @@ and ui.configbool('devel', 'debug.peer-request')): dbg = ui.debug line = 'devel-peer-request: %s\n' -dbg(line % '%s %s' % (req.get_method(), req.get_full_url())) +dbg(line % '%s %s' % (pycompat.bytesurl(req.get_method()), + pycompat.bytesurl(req.get_full_url( hgargssize = None for header, value in sorted(req.header_items()): @@ -310,7 +311,7 @@ raise IOError(None, inst) finally: if ui.configbool('devel', 'debug.peer-request'): -dbg(line % ' finished in %.4f seconds (%s)' +dbg(line % ' finished in %.4f seconds (%d)' % (util.timer() - start, res.code)) # Insert error handlers for common I/O failures. To: durin42, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3346: httppeer: no matter what Python 3 might think, http headers are bytes
durin42 created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3346 AFFECTED FILES mercurial/httppeer.py CHANGE DETAILS diff --git a/mercurial/httppeer.py b/mercurial/httppeer.py --- a/mercurial/httppeer.py +++ b/mercurial/httppeer.py @@ -278,6 +278,8 @@ hgargssize = None for header, value in sorted(req.header_items()): +header = pycompat.bytesurl(header) +value = pycompat.bytesurl(value) if header.startswith('X-hgarg-'): if hgargssize is None: hgargssize = 0 To: durin42, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3348: py3: another three passing
durin42 created this revision. Herald added a reviewer: pulkit. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3348 AFFECTED FILES contrib/python3-whitelist CHANGE DETAILS diff --git a/contrib/python3-whitelist b/contrib/python3-whitelist --- a/contrib/python3-whitelist +++ b/contrib/python3-whitelist @@ -140,6 +140,7 @@ test-exchange-obsmarkers-case-D4.t test-execute-bit.t test-export.t +test-extdata.t test-extdiff.t test-extra-filelog-entry.t test-filebranch.t @@ -175,6 +176,7 @@ test-http-branchmap.t test-http-bundle1.t test-http-clone-r.t +test-http.t test-identify.t test-import-unknown.t test-import.t @@ -432,6 +434,7 @@ test-update-names.t test-update-reverse.t test-upgrade-repo.t +test-url-download.t test-url-rev.t test-username-newline.t test-verify.t To: durin42, pulkit, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3347: httppeer: work around API differences on urllib Request objects
durin42 created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY Since this is only a problem in httppeer, I'd rather keep this a local-to-the-module kludge rather than pile more on pycompat. We'll still find it easily to clean up later because it checks pycompat.ispy3. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3347 AFFECTED FILES mercurial/httppeer.py CHANGE DETAILS diff --git a/mercurial/httppeer.py b/mercurial/httppeer.py --- a/mercurial/httppeer.py +++ b/mercurial/httppeer.py @@ -264,6 +264,14 @@ return req, cu, qs +def _reqdata(req): +"""Get request data, if any. If no data, returns None.""" +if pycompat.ispy3: +return req.data +if not req.has_data(): +return None +return req.get_data() + def sendrequest(ui, opener, req): """Send a prepared HTTP request. @@ -290,9 +298,8 @@ if hgargssize is not None: dbg(line % ' %d bytes of commands arguments in headers' % hgargssize) - -if req.has_data(): -data = req.get_data() +data = _reqdata(req) +if data is not None: length = getattr(data, 'length', None) if length is None: length = len(data) To: durin42, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3349: tests: make sure test-run-tests.t actually runs run-tests.py under Python 3
durin42 created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY I'm fairly certain it hasn't been until now. Mercifully, there doesn't appear to be any ninja breakage. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3349 AFFECTED FILES tests/test-run-tests.t CHANGE DETAILS diff --git a/tests/test-run-tests.t b/tests/test-run-tests.t --- a/tests/test-run-tests.t +++ b/tests/test-run-tests.t @@ -6,32 +6,31 @@ Smoke test with install - - $ run-tests.py $HGTEST_RUN_TESTS_PURE -l + $ $PYTHON $TESTDIR/run-tests.py $HGTEST_RUN_TESTS_PURE -l # Ran 0 tests, 0 skipped, 0 failed. Define a helper to avoid the install step = $ rt() > { - > run-tests.py --with-hg=`which hg` "$@" + > $PYTHON $TESTDIR/run-tests.py --with-hg=`which hg` "$@" > } error paths #if symlink $ ln -s `which true` hg - $ run-tests.py --with-hg=./hg + $ $PYTHON $TESTDIR/run-tests.py --with-hg=./hg warning: --with-hg should specify an hg script # Ran 0 tests, 0 skipped, 0 failed. $ rm hg #endif #if execbit $ touch hg - $ run-tests.py --with-hg=./hg + $ $PYTHON $TESTDIR/run-tests.py --with-hg=./hg usage: run-tests.py [options] [tests] run-tests.py: error: --with-hg must specify an executable hg script [2] To: durin42, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3343: hgweb: these strings should be sysstrs, not bytes
durin42 created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3343 AFFECTED FILES mercurial/hgweb/common.py CHANGE DETAILS diff --git a/mercurial/hgweb/common.py b/mercurial/hgweb/common.py --- a/mercurial/hgweb/common.py +++ b/mercurial/hgweb/common.py @@ -131,7 +131,8 @@ def _statusmessage(code): responses = httpserver.basehttprequesthandler.responses -return responses.get(code, ('Error', 'Unknown error'))[0] +return pycompat.bytesurl( +responses.get(code, (r'Error', r'Unknown error'))[0]) def statusmessage(code, message=None): return '%d %s' % (code, message or _statusmessage(code)) To: durin42, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3344: url: some bytes/str cleanup where we interface with stdlib funcs
durin42 created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3344 AFFECTED FILES mercurial/url.py CHANGE DETAILS diff --git a/mercurial/url.py b/mercurial/url.py --- a/mercurial/url.py +++ b/mercurial/url.py @@ -486,7 +486,8 @@ cookiefile = util.expandpath(cookiefile) try: -cookiejar = util.cookielib.MozillaCookieJar(cookiefile) +cookiejar = util.cookielib.MozillaCookieJar( +pycompat.fsdecode(cookiefile)) cookiejar.load() self.cookiejar = cookiejar except util.cookielib.LoadError as e: @@ -591,6 +592,6 @@ url_, authinfo = u.authinfo() else: path = util.normpath(os.path.abspath(url_)) -url_ = 'file://' + urlreq.pathname2url(path) +url_ = 'file://' + pycompat.bytesurl(urlreq.pathname2url(path)) authinfo = None return opener(ui, authinfo).open(pycompat.strurl(url_), data) To: durin42, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3342: tests: port inline extensions in test-http.t to Python 3
durin42 created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3342 AFFECTED FILES tests/test-http.t CHANGE DETAILS diff --git a/tests/test-http.t b/tests/test-http.t --- a/tests/test-http.t +++ b/tests/test-http.t @@ -61,7 +61,7 @@ $ cat > $TESTTMP/removesupportedformat.py << EOF > from mercurial import localrepo > def extsetup(ui): - > localrepo.localrepository.supportedformats.remove('generaldelta') + > localrepo.localrepository.supportedformats.remove(b'generaldelta') > EOF $ hg clone --config extensions.rsf=$TESTTMP/removesupportedformat.py --stream http://localhost:$HGPORT/ copy3 @@ -170,12 +170,12 @@ > import base64 > from mercurial.hgweb import common > def perform_authentication(hgweb, req, op): - > auth = req.headers.get('Authorization') + > auth = req.headers.get(b'Authorization') > if not auth: - > raise common.ErrorResponse(common.HTTP_UNAUTHORIZED, 'who', - > [('WWW-Authenticate', 'Basic Realm="mercurial"')]) - > if base64.b64decode(auth.split()[1]).split(':', 1) != ['user', 'pass']: - > raise common.ErrorResponse(common.HTTP_FORBIDDEN, 'no') + > raise common.ErrorResponse(common.HTTP_UNAUTHORIZED, b'who', + > [(b'WWW-Authenticate', b'Basic Realm="mercurial"')]) + > if base64.b64decode(auth.split()[1]).split(b':', 1) != [b'user', b'pass']: + > raise common.ErrorResponse(common.HTTP_FORBIDDEN, b'no') > def extsetup(): > common.permhooks.insert(0, perform_authentication) > EOT @@ -514,10 +514,10 @@ > from mercurial import util > from mercurial.hgweb import common > def perform_authentication(hgweb, req, op): - > cookie = req.headers.get('Cookie') + > cookie = req.headers.get(b'Cookie') > if not cookie: - > raise common.ErrorResponse(common.HTTP_SERVER_ERROR, 'no-cookie') - > raise common.ErrorResponse(common.HTTP_SERVER_ERROR, 'Cookie: %s' % cookie) + > raise common.ErrorResponse(common.HTTP_SERVER_ERROR, b'no-cookie') + > raise common.ErrorResponse(common.HTTP_SERVER_ERROR, b'Cookie: %s' % cookie) > def extsetup(): > common.permhooks.insert(0, perform_authentication) > EOF To: durin42, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 2 of 2] revset: pass in lookup function instead of repo (API)
On Fri, Apr 13, 2018 at 9:21 PM Yuya Nishiharawrote: > # HG changeset patch > # User Yuya Nishihara > # Date 1523678252 -32400 > # Sat Apr 14 12:57:32 2018 +0900 > # Node ID 3b799d7e0865e9226ef1de1a858b6de08b612472 > # Parent 2536edebfeac00856d892847e1afea414ad3a985 > revset: pass in lookup function instead of repo (API) > Queued, thanks. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 4 of 4] logcmdutil: pass formatter to jsonchangeset as argument
# HG changeset patch # User Yuya Nishihara# Date 1523628432 -32400 # Fri Apr 13 23:07:12 2018 +0900 # Node ID 611a3c98d1b68836b5725a0d97c0ae1f0b3677f6 # Parent 60b88ab0b4238f95438c3ad2a3c9fc802da84d94 logcmdutil: pass formatter to jsonchangeset as argument And rename the class. Now we can reuse it for 'log -Tcbor' (and '-Tpickle' if we want.) diff --git a/mercurial/logcmdutil.py b/mercurial/logcmdutil.py --- a/mercurial/logcmdutil.py +++ b/mercurial/logcmdutil.py @@ -310,12 +310,13 @@ class changesetprinter(object): if stat or diff: self.ui.write("\n") -class jsonchangeset(changesetprinter): -'''format changeset information.''' +class changesetformatter(changesetprinter): +"""Format changeset information by generic formatter""" -def __init__(self, ui, repo, differ=None, diffopts=None, buffered=False): +def __init__(self, ui, repo, fm, differ=None, diffopts=None, + buffered=False): changesetprinter.__init__(self, ui, repo, differ, diffopts, buffered) -self._fm = formatter.jsonformatter(ui, ui, 'log', {}) +self._fm = fm def close(self): self._fm.end() @@ -519,7 +520,8 @@ def changesetdisplayer(ui, repo, opts, d """ postargs = (differ, opts, buffered) if opts.get('template') == 'json': -return jsonchangeset(ui, repo, *postargs) +fm = ui.formatter('log', opts) +return changesetformatter(ui, repo, fm, *postargs) spec = _lookuptemplate(ui, opts.get('template'), opts.get('style')) ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 2 of 4] logcmdutil: remove unused attribute 'cache' from jsonchangeset printer
# HG changeset patch # User Yuya Nishihara# Date 1523625613 -32400 # Fri Apr 13 22:20:13 2018 +0900 # Node ID 7a8009978a8f5f0a0b34d356fa4f506065f572f8 # Parent 356d01cf53f693c0ff8dd9de49ba85037f57a048 logcmdutil: remove unused attribute 'cache' from jsonchangeset printer Perhaps it's a copy-pasta of changeset_templater at bd15932846a4. diff --git a/mercurial/logcmdutil.py b/mercurial/logcmdutil.py --- a/mercurial/logcmdutil.py +++ b/mercurial/logcmdutil.py @@ -317,7 +317,6 @@ class jsonchangeset(changesetprinter): def __init__(self, ui, repo, differ=None, diffopts=None, buffered=False): changesetprinter.__init__(self, ui, repo, differ, diffopts, buffered) -self.cache = {} self._first = True def close(self): ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 1 of 4] formatter: convert timestamp to int
# HG changeset patch # User Yuya Nishihara# Date 1523627929 -32400 # Fri Apr 13 22:58:49 2018 +0900 # Node ID 356d01cf53f693c0ff8dd9de49ba85037f57a048 # Parent 3b799d7e0865e9226ef1de1a858b6de08b612472 formatter: convert timestamp to int Spotted while porting jsonchangeset printer to formatter. A timestamp may be float type, but its meaningful part is just int. diff --git a/mercurial/formatter.py b/mercurial/formatter.py --- a/mercurial/formatter.py +++ b/mercurial/formatter.py @@ -144,7 +144,9 @@ class _nullconverter(object): @staticmethod def formatdate(date, fmt): '''convert date tuple to appropriate format''' -return date +# timestamp can be float, but the canonical form should be int +ts, tz = date +return (int(ts), tz) @staticmethod def formatdict(data, key, value, fmt, sep): '''convert dict or key-value pairs to appropriate dict format''' diff --git a/tests/test-export.t b/tests/test-export.t --- a/tests/test-export.t +++ b/tests/test-export.t @@ -165,7 +165,7 @@ Templated output to stdout: [ { "branch": "default", -"date": [0.0, 0], +"date": [0, 0], "desc": "foo-0", "diff": "diff -r -r 871558de6af2 foo\n--- /dev/null\tThu Jan 01 00:00:00 1970 +\n+++ b/foo\tThu Jan 01 00:00:00 1970 +\n@@ -0,0 +1,1 @@\n+foo-0\n", "node": "871558de6af2e8c244222f8eea69b782c94ce3df", @@ -181,7 +181,7 @@ Templated output to single file: [ { "branch": "default", -"date": [0.0, 0], +"date": [0, 0], "desc": "foo-0", "diff": "diff -r -r 871558de6af2 foo\n--- /dev/null\tThu Jan 01 00:00:00 1970 +\n+++ b/foo\tThu Jan 01 00:00:00 1970 +\n@@ -0,0 +1,1 @@\n+foo-0\n", "node": "871558de6af2e8c244222f8eea69b782c94ce3df", @@ -190,7 +190,7 @@ Templated output to single file: }, { "branch": "default", -"date": [0.0, 0], +"date": [0, 0], "desc": "foo-1", "diff": "diff -r 871558de6af2 -r d1c9656e973c foo\n--- a/foo\tThu Jan 01 00:00:00 1970 +\n+++ b/foo\tThu Jan 01 00:00:00 1970 +\n@@ -1,1 +1,2 @@\n foo-0\n+foo-1\n", "node": "d1c9656e973cfb5aebd5499bbd2cb350e3b12266", @@ -206,7 +206,7 @@ Templated output to multiple files: [ { "branch": "default", -"date": [0.0, 0], +"date": [0, 0], "desc": "foo-0", "diff": "diff -r -r 871558de6af2 foo\n--- /dev/null\tThu Jan 01 00:00:00 1970 +\n+++ b/foo\tThu Jan 01 00:00:00 1970 +\n@@ -0,0 +1,1 @@\n+foo-0\n", "node": "871558de6af2e8c244222f8eea69b782c94ce3df", @@ -218,7 +218,7 @@ Templated output to multiple files: [ { "branch": "default", -"date": [0.0, 0], +"date": [0, 0], "desc": "foo-1", "diff": "diff -r 871558de6af2 -r d1c9656e973c foo\n--- a/foo\tThu Jan 01 00:00:00 1970 +\n+++ b/foo\tThu Jan 01 00:00:00 1970 +\n@@ -1,1 +1,2 @@\n foo-0\n+foo-1\n", "node": "d1c9656e973cfb5aebd5499bbd2cb350e3b12266", diff --git a/tests/test-grep.t b/tests/test-grep.t --- a/tests/test-grep.t +++ b/tests/test-grep.t @@ -58,7 +58,7 @@ simple JSON (no "change" field) $ hg grep -Tjson port [ { -"date": [4.0, 0], +"date": [4, 0], "file": "port", "line_number": 1, "node": "914fa752cdea8ac1a8d5c858b0c736218f6c", @@ -67,7 +67,7 @@ simple JSON (no "change" field) "user": "spam" }, { -"date": [4.0, 0], +"date": [4, 0], "file": "port", "line_number": 2, "node": "914fa752cdea8ac1a8d5c858b0c736218f6c", @@ -76,7 +76,7 @@ simple JSON (no "change" field) "user": "spam" }, { -"date": [4.0, 0], +"date": [4, 0], "file": "port", "line_number": 3, "node": "914fa752cdea8ac1a8d5c858b0c736218f6c", @@ -91,7 +91,7 @@ simple JSON without matching lines $ hg grep -Tjson -l port [ { -"date": [4.0, 0], +"date": [4, 0], "file": "port", "line_number": 1, "node": "914fa752cdea8ac1a8d5c858b0c736218f6c", @@ -119,7 +119,7 @@ all JSON [ { "change": "-", -"date": [4.0, 0], +"date": [4, 0], "file": "port", "line_number": 4, "node": "914fa752cdea8ac1a8d5c858b0c736218f6c", @@ -129,7 +129,7 @@ all JSON }, { "change": "+", -"date": [3.0, 0], +"date": [3, 0], "file": "port", "line_number": 4, "node": "95040cfd017d658c536071c6290230a613c4c2a6", @@ -139,7 +139,7 @@ all JSON }, { "change": "-", -"date": [2.0, 0], +"date": [2, 0], "file": "port", "line_number": 1, "node": "3b325e3481a1f07435d81dfdbfa434d9a0245b47", @@ -149,7 +149,7 @@ all JSON }, { "change": "-", -"date": [2.0, 0], +"date": [2, 0], "file": "port", "line_number": 2, "node": "3b325e3481a1f07435d81dfdbfa434d9a0245b47", @@ -159,7 +159,7 @@ all JSON }, { "change": "+", -"date": [2.0, 0], +"date": [2, 0], "file": "port",
[PATCH 2 of 2] revset: pass in lookup function instead of repo (API)
# HG changeset patch # User Yuya Nishihara# Date 1523678252 -32400 # Sat Apr 14 12:57:32 2018 +0900 # Node ID 3b799d7e0865e9226ef1de1a858b6de08b612472 # Parent 2536edebfeac00856d892847e1afea414ad3a985 revset: pass in lookup function instead of repo (API) And document that it's only for legacy lookup. If we have a repo, we're likely to do more things where that shouldn't be done. diff --git a/mercurial/hgweb/webcommands.py b/mercurial/hgweb/webcommands.py --- a/mercurial/hgweb/webcommands.py +++ b/mercurial/hgweb/webcommands.py @@ -276,7 +276,8 @@ def _search(web): if not funcsused.issubset(revset.safesymbols): return MODE_KEYWORD, query -mfunc = revset.match(web.repo.ui, revdef, repo=web.repo) +mfunc = revset.match(web.repo.ui, revdef, + lookup=revset.lookupfn(web.repo)) try: revs = mfunc(web.repo) return MODE_REVSET, revs diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -905,7 +905,8 @@ class localrepository(object): ``{name: definitionstring}``. ''' if user: -m = revset.matchany(self.ui, specs, repo=self, +m = revset.matchany(self.ui, specs, +lookup=revset.lookupfn(self), localalias=localalias) else: m = revset.matchany(None, specs, localalias=localalias) diff --git a/mercurial/revset.py b/mercurial/revset.py --- a/mercurial/revset.py +++ b/mercurial/revset.py @@ -2169,14 +2169,17 @@ methods = { def lookupfn(repo): return lambda symbol: scmutil.isrevsymbol(repo, symbol) -def match(ui, spec, repo=None): +def match(ui, spec, lookup=None): """Create a matcher for a single revision spec""" -return matchany(ui, [spec], repo=repo) +return matchany(ui, [spec], lookup=None) -def matchany(ui, specs, repo=None, localalias=None): +def matchany(ui, specs, lookup=None, localalias=None): """Create a matcher that will include any revisions matching one of the given specs +If lookup function is not None, the parser will first attempt to handle +old-style ranges, which may contain operator characters. + If localalias is not None, it is a dict {name: definitionstring}. It takes precedence over [revsetalias] config section. """ @@ -2186,9 +2189,6 @@ def matchany(ui, specs, repo=None, local return mfunc if not all(specs): raise error.ParseError(_("empty query")) -lookup = None -if repo: -lookup = lookupfn(repo) if len(specs) == 1: tree = revsetlang.parse(specs[0], lookup) else: diff --git a/mercurial/templatefuncs.py b/mercurial/templatefuncs.py --- a/mercurial/templatefuncs.py +++ b/mercurial/templatefuncs.py @@ -522,7 +522,7 @@ def revset(context, mapping, args): repo = ctx.repo() def query(expr): -m = revsetmod.match(repo.ui, expr, repo=repo) +m = revsetmod.match(repo.ui, expr, lookup=revsetmod.lookupfn(repo)) return m(repo) if len(args) > 1: diff --git a/tests/test-revset.t b/tests/test-revset.t --- a/tests/test-revset.t +++ b/tests/test-revset.t @@ -60,7 +60,7 @@ these predicates use '\0' as a separator > opttree = revsetlang.optimize(revsetlang.analyze(tree)) > ui.note(b"* optimized:\n", revsetlang.prettyformat(opttree), > b"\n") - > func = revset.match(ui, expr, repo) + > func = revset.match(ui, expr, lookup=revset.lookupfn(repo)) > revs = func(repo) > if ui.verbose: > ui.note(b"* set:\n", smartset.prettyformat(revs), b"\n") ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 1 of 2] revset: drop support for posttreebuilthook() (API)
# HG changeset patch # User Yuya Nishihara# Date 1523677480 -32400 # Sat Apr 14 12:44:40 2018 +0900 # Node ID 2536edebfeac00856d892847e1afea414ad3a985 # Parent 775ad61e04e28c49c78c7936d88826a3df024781 revset: drop support for posttreebuilthook() (API) AFAIK, the only user was the directaccess extension, which is in core now. diff --git a/mercurial/revset.py b/mercurial/revset.py --- a/mercurial/revset.py +++ b/mercurial/revset.py @@ -2166,10 +2166,6 @@ methods = { "parentpost": parentpost, } -def posttreebuilthook(tree, repo): -# hook for extensions to execute code on the optimized tree -pass - def lookupfn(repo): return lambda symbol: scmutil.isrevsymbol(repo, symbol) @@ -2211,7 +2207,6 @@ def matchany(ui, specs, repo=None, local tree = revsetlang.foldconcat(tree) tree = revsetlang.analyze(tree) tree = revsetlang.optimize(tree) -posttreebuilthook(tree, repo) return makematcher(tree) def makematcher(tree): ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH] log: fix crash on empty revision with --copies switch
# HG changeset patch # User Yuya Nishihara# Date 1523630707 -32400 # Fri Apr 13 23:45:07 2018 +0900 # Node ID 775ad61e04e28c49c78c7936d88826a3df024781 # Parent 8bacc09814ba5500d15fb40c472e84cb95ae2f99 log: fix crash on empty revision with --copies switch If a revset is empty, .max() raises ValueError. I don't see any reason to recompute the revs, so I made it reuse the one returned by logcmdutil.getrevs(). If no revs specified by command line, the endrev will be smartset.spanset(repo) + 1, which is basically the same as len(repo), the default of getrenamedfn(). If --follow specified, revs.max() points to the working parent, which seems more correct. diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -3463,8 +3463,8 @@ def log(ui, repo, *pats, **opts): getrenamed = None if opts.get('copies'): endrev = None -if opts.get('rev'): -endrev = scmutil.revrange(repo, opts.get('rev')).max() + 1 +if revs: +endrev = revs.max() + 1 getrenamed = templatekw.getrenamedfn(repo, endrev=endrev) ui.pager('log') diff --git a/tests/test-log.t b/tests/test-log.t --- a/tests/test-log.t +++ b/tests/test-log.t @@ -656,6 +656,9 @@ log copies, execute bit set 6 #endif +log copies, empty set + + $ hg log --copies -r '0 and not 0' log -p d ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3312: revlog: move shortest() to scmutil.shortesthexnodeidprefix() (API)
martinvonz added a comment. In https://phab.mercurial-scm.org/D3312#53423, @yuja wrote: > IIRC, @quark said it's in revlog because the implementation may vary > depending on storage, such as looking up in radix tree and rewind? That's reasonable. Perhaps I'll just make shortesthexnodeidprefix() a thin wrapper then, so all it does (at the end of this series) is to delegate to the unfiltered repo. Does that seem okay with you? REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3312 To: martinvonz, indygreg, #hg-reviewers Cc: yuja, quark, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3330: py3: make values bytes before passing into server.runservice()
This revision was automatically updated to reflect the committed changes. Closed by commit rHG8bacc09814ba: py3: make values bytes before passing into server.runservice() (authored by pulkit, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3330?vs=8150=8218 REVISION DETAIL https://phab.mercurial-scm.org/D3330 AFFECTED FILES tests/dumbhttp.py CHANGE DETAILS diff --git a/tests/dumbhttp.py b/tests/dumbhttp.py --- a/tests/dumbhttp.py +++ b/tests/dumbhttp.py @@ -13,6 +13,7 @@ import sys from mercurial import ( +pycompat, server, util, ) @@ -63,10 +64,12 @@ if options.foreground and options.pid: parser.error("options --pid and --foreground are mutually exclusive") -opts = {'pid_file': options.pid, -'daemon': not options.foreground, -'daemon_postexec': options.daemon_postexec} +opts = {b'pid_file': options.pid, +b'daemon': not options.foreground, +b'daemon_postexec': options.daemon_postexec} service = simplehttpservice(options.host, options.port) +runargs = [sys.executable, __file__] + sys.argv[1:] +runargs = [pycompat.fsencode(a) for a in runargs] server.runservice(opts, initfn=service.init, runfn=service.run, logfile=options.logfile, - runargs=[sys.executable, __file__] + sys.argv[1:]) + runargs=runargs) To: pulkit, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 2 of 2 V2] revset: skip old style lookup if external whitespace are detected
On Fri, 13 Apr 2018 19:56:21 +0200, Feld Boris wrote: > > We love the 'revset(EXPR)' idea and we have a v4 series that is ready > > to send. Can you mark it as "(EXPERIMENTAL)" in case we find a better way to work around the problem? > By re-reading your comments on the V3 series, I realized that the second > changeset is not necessary since repo is never passed for internal lookup I'm thinking of renaming repo argument to lookup=lookupfn(repo) to clarify that. > I will update the series and prepare a new V4. Thanks. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 2 of 4 V3] revset: disable compat with legacy compat for internal revsets API (API)
On Fri, 13 Apr 2018 23:42:19 +0530, Pulkit Goyal wrote: > On Fri, Apr 13, 2018 at 6:33 PM, Yuya Nishiharawrote: > > > > It is (was?) used at least by the directaccess extension. > > > > Pulkit, do we still need the posttreebuildhook? I think the only user was > > the directaccess, and it's in core. > > > > Nope, we don't need that as far as directaccess is concerned. Thanks. Let's remove it then. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH] dispatch: add a whitelist map of commands to implicitly loaded extensions
On Fri, 13 Apr 2018 15:10:45 -0400, Gregory Szorcwrote: On Fri, Apr 13, 2018 at 6:35 AM, Matt Harbison wrote: > On Apr 13, 2018, at 9:11 AM, Yuya Nishihara wrote: > >> On Thu, 12 Apr 2018 13:35:50 -0400, Matt Harbison wrote: >> # HG changeset patch >> # User Matt Harbison >> # Date 1523332699 14400 >> # Mon Apr 09 23:58:19 2018 -0400 >> # Node ID 986b51f15e9bce19b2f67573ff76612540320d1b >> # Parent 2e0e61312a257708a70201427b31deba964e9b05 >> dispatch: add a whitelist map of commands to implicitly loaded extensions > One thing I like about this is the user doesn’t have to do anything to switch. I can send out an email saying “upgrade to 4.6”, convert on the server, and nothing changes for the developer. Otherwise, everyone has to enable the extension in their user settings, or alias clone and pull to enable it anyway. I want to add a "capabilities" mechanism to hg.peer() and hg.repository() that makes the caller declare what features the returned repository must have. This would allow callers to say things like "I only want a read-only repo," "I need to be able to speak wire protocol command X," etc. These capabilities would get passed down to the localrepo or peer layers for evaluation, where they may result in the constructed instance being a different type, having a different composition of methods, etc. This may seem orthogonal to command dispatch. However, I would eventually like @command's to self-declare what features they need. e.g. `log` would say it needs a read-only repository. `update` would say it needs a repository with a working directory. `commit` would say it needs a mutable repository. A command to update the narrow profile would require a repository type that can be narrowed. And the list goes on. For your immediate use case, getting the extension tie-ins could be difficult. Obviously the extension needs to be loaded in order for the extension to declare a "capability" for a requested repo/peer instance. What we may want instead is to key things off .hg/requires or a to-be-invented supplemental requirements-like file that declares soft features. localrepository.__init__ could then load trusted extensions at repo open time if a requirements/capability was present/requested. i.e. if you talk to an LFS server, write a semaphore somewhere into .hg/ and have something in core look for that and automatically load lfs if present. This would get you the "automatically enable LFS when talking to LFS servers" benefits. Sounds promising. One of the things the lfs extension is doing is writing '[extensions]\nlfs=' to the repo's local hgrc file in a commit hook (it should probably be handling transactions too). So it would be nice if this was baked into the core somehow (largefiles could use exactly the same handling, and I'm assuming narrow will be similar). It's also manually adding to the requires file, since that doesn't seem to be updated in exchange. Assuming the semaphore is persistent, it could be beneficial to load extensions indicated by it around the normal load time (e.g., largefiles wraps the clone command and adds extra switches). I'm not sure if this addresses Yuya's concern about long lived processes though. Alternatively, you could move the client pieces of LFS into core so no extension loading is needed. That doesn't seem viable. The revlog flagprocessors drag along all of the store code. A commit hook and pretxnchangegroup hook scan the relevant csets to see if the requirement needs to be written out, and I can't justify inflicting that on all repos, unless there's an O(1) test in the changegroup/bundle that I'm not aware of. And the prefetchfiles hook is needed to support `hg clone` and `hg pull -u`. That may still require a semaphore somewhere. I think that's the best long-term behavior. But I think we should shore up the storage interfaces and figure out the narrow/partial clone integration story before we do that. Maybe much of this work has already been done? My backup plan of alias shadowing clone/pull to add '--config extensions.lfs=' was a bust too, but I can wait on this. I'm having trouble digesting the sheer volume of changes, so I guess when you think this has been reworked enough, let me know. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3312: revlog: move shortest() to scmutil.shortesthexnodeidprefix() (API)
yuja added subscribers: quark, yuja. yuja added a comment. IIRC, @quark said it's in revlog because the implementation may vary depending on storage, such as looking up in radix tree and rewind? REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3312 To: martinvonz, indygreg, #hg-reviewers Cc: yuja, quark, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3303: cborutil: implement support for streaming encoding, bytestring decoding
yuja added a comment. > FWIW, the more I'm looking at the CBOR code, the more I'm thinking > we will end up having to reinvent the full wheel. Sounds reasonable to me. > We need to at least implement support encoding floats in order to > support -Tcbor. If it's just for date tuple, I have a patch to get rid of floating-point timestamps as our timestamps should be effectively ints. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3303 To: indygreg, #hg-reviewers Cc: yuja, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3326: py3: use str variables to check keys in request header
yuja added a comment. Missing `**` ? https://docs.python.org/2.7/library/httplib.html?highlight=putrequest#httplib.HTTPConnection.putrequest REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3326 To: pulkit, #hg-reviewers, durin42 Cc: yuja, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3324: py3: use stringutil.forcebytestr() instead of str()
yuja added a comment. FYI, this one could be just `bytes(e)`. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3324 To: pulkit, #hg-reviewers, durin42 Cc: yuja, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
mercurial@37496: 3 new changesets
3 new changesets in mercurial: https://www.mercurial-scm.org/repo/hg/rev/1ce7a55b09d1 changeset: 37494:1ce7a55b09d1 user:Joerg Sonnenbergerdate:Sun Apr 08 01:08:43 2018 +0200 summary: revlog: reset _nodepos after strip https://www.mercurial-scm.org/repo/hg/rev/b1fb341d8a61 changeset: 37495:b1fb341d8a61 user:Gregory Szorc date:Mon Apr 09 10:13:29 2018 -0700 summary: zstandard: vendor python-zstandard 0.9.0 https://www.mercurial-scm.org/repo/hg/rev/1765ed63db40 changeset: 37496:1765ed63db40 bookmark:@ tag: tip user:Gregory Szorc date:Mon Apr 09 10:18:10 2018 -0700 summary: util: drop write_content_size=True -- Repository URL: https://www.mercurial-scm.org/repo/hg ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3337: localrepo: add some overlooked strkwargs love for py3
This revision was automatically updated to reflect the committed changes. Closed by commit rHG719b8cb22936: localrepo: add some overlooked strkwargs love for py3 (authored by durin42, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3337?vs=8206=8209 REVISION DETAIL https://phab.mercurial-scm.org/D3337 AFFECTED FILES mercurial/localrepo.py CHANGE DETAILS diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -182,7 +182,7 @@ f = pycompat.futures.Future() try: -result = fn(**args) +result = fn(**pycompat.strkwargs(args)) except Exception: pycompat.future_set_exception_info(f, sys.exc_info()[1:]) else: To: durin42, #hg-reviewers, indygreg Cc: indygreg, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3338: py3: two more passing tests
This revision was automatically updated to reflect the committed changes. Closed by commit rHG726a95a57eeb: py3: two more passing tests (authored by durin42, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3338?vs=8207=8210 REVISION DETAIL https://phab.mercurial-scm.org/D3338 AFFECTED FILES contrib/python3-whitelist CHANGE DETAILS diff --git a/contrib/python3-whitelist b/contrib/python3-whitelist --- a/contrib/python3-whitelist +++ b/contrib/python3-whitelist @@ -70,6 +70,7 @@ test-convert-hg-source.t test-convert-hg-startrev.t test-convert-splicemap.t +test-convert-tagsbranch-topology.t test-copy-move-merge.t test-copy.t test-copytrace-heuristics.t @@ -270,6 +271,7 @@ test-mv-cp-st-diff.t test-narrow-archive.t test-narrow-clone-no-ellipsis.t +test-narrow-clone-non-narrow-server.t test-narrow-clone-nonlinear.t test-narrow-clone.t test-narrow-commit.t To: durin42, pulkit, #hg-reviewers, indygreg Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3337: localrepo: add some overlooked strkwargs love for py3
indygreg accepted this revision. indygreg added a comment. This revision is now accepted and ready to land. Doh. I got it right everywhere but one place :) REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3337 To: durin42, #hg-reviewers, indygreg Cc: indygreg, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3336: py3: paper over differences in future exception handling
indygreg accepted this revision. indygreg added a comment. This revision is now accepted and ready to land. Ugh. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3336 To: durin42, #hg-reviewers, indygreg Cc: indygreg, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3338: py3: two more passing tests
durin42 created this revision. Herald added a reviewer: pulkit. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3338 AFFECTED FILES contrib/python3-whitelist CHANGE DETAILS diff --git a/contrib/python3-whitelist b/contrib/python3-whitelist --- a/contrib/python3-whitelist +++ b/contrib/python3-whitelist @@ -70,6 +70,7 @@ test-convert-hg-source.t test-convert-hg-startrev.t test-convert-splicemap.t +test-convert-tagsbranch-topology.t test-copy-move-merge.t test-copy.t test-copytrace-heuristics.t @@ -270,6 +271,7 @@ test-mv-cp-st-diff.t test-narrow-archive.t test-narrow-clone-no-ellipsis.t +test-narrow-clone-non-narrow-server.t test-narrow-clone-nonlinear.t test-narrow-clone.t test-narrow-commit.t To: durin42, pulkit, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3336: py3: paper over differences in future exception handling
durin42 created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY It looks like Python 3's futures library lacks set_exception_info entirely. We'll just give up and use set_exception in that case. 1. no-check-commit because the underbar naming is just saner here REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3336 AFFECTED FILES mercurial/httppeer.py mercurial/localrepo.py mercurial/pycompat.py mercurial/wireprotov1peer.py CHANGE DETAILS diff --git a/mercurial/wireprotov1peer.py b/mercurial/wireprotov1peer.py --- a/mercurial/wireprotov1peer.py +++ b/mercurial/wireprotov1peer.py @@ -209,7 +209,7 @@ try: result = fn(**pycompat.strkwargs(args)) except Exception: -f.set_exception_info(*sys.exc_info()[1:]) +pycompat.future_set_exception_info(f, sys.exc_info()[1:]) else: f.set_result(result) @@ -234,14 +234,14 @@ batchable = fn.batchable(fn.__self__, **pycompat.strkwargs(args)) except Exception: -f.set_exception_info(*sys.exc_info()[1:]) +pycompat.future_set_exception_info(f, sys.exc_info()[1:]) return # Encoded arguments and future holding remote result. try: encodedargs, fremote = next(batchable) except Exception: -f.set_exception_info(*sys.exc_info()[1:]) +pycompat.future_set_exception_info(f, sys.exc_info()[1:]) return requests.append((command, encodedargs)) @@ -304,7 +304,7 @@ try: result = next(batchable) except Exception: -f.set_exception_info(*sys.exc_info()[1:]) +pycompat.future_set_exception_info(f, sys.exc_info()[1:]) else: f.set_result(result) diff --git a/mercurial/pycompat.py b/mercurial/pycompat.py --- a/mercurial/pycompat.py +++ b/mercurial/pycompat.py @@ -28,6 +28,9 @@ import xmlrpclib from .thirdparty.concurrent import futures + +def future_set_exception_info(f, exc_info): +f.set_exception_info(*exc_info) else: import concurrent.futures as futures import http.cookiejar as cookielib @@ -37,6 +40,9 @@ import socketserver import xmlrpc.client as xmlrpclib +def future_set_exception_info(f, exc_info): +f.set_exception(exc_info[0]) + empty = _queue.Empty queue = _queue.Queue diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -184,7 +184,7 @@ try: result = fn(**args) except Exception: -f.set_exception_info(*sys.exc_info()[1:]) +pycompat.future_set_exception_info(f, sys.exc_info()[1:]) else: f.set_result(result) diff --git a/mercurial/httppeer.py b/mercurial/httppeer.py --- a/mercurial/httppeer.py +++ b/mercurial/httppeer.py @@ -754,7 +754,8 @@ try: result.append(decoder.decode()) except Exception: -f.set_exception_info(*sys.exc_info()[1:]) +pycompat.future_set_exception_info( +f, sys.exc_info()[1:]) continue else: result.append(meta['data']) To: durin42, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3337: localrepo: add some overlooked strkwargs love for py3
durin42 created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3337 AFFECTED FILES mercurial/localrepo.py CHANGE DETAILS diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -182,7 +182,7 @@ f = pycompat.futures.Future() try: -result = fn(**args) +result = fn(**pycompat.strkwargs(args)) except Exception: pycompat.future_set_exception_info(f, sys.exc_info()[1:]) else: To: durin42, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3329: py3: add b'' prefixes to make values bytes
This revision was automatically updated to reflect the committed changes. Closed by commit rHG2a42ca2679e2: py3: add b prefixes to make values bytes (authored by pulkit, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3329?vs=8149=8204 REVISION DETAIL https://phab.mercurial-scm.org/D3329 AFFECTED FILES tests/test-clone-cgi.t tests/test-clone.t CHANGE DETAILS diff --git a/tests/test-clone.t b/tests/test-clone.t --- a/tests/test-clone.t +++ b/tests/test-clone.t @@ -559,8 +559,8 @@ $ cat < simpleclone.py > from mercurial import ui, hg > myui = ui.ui.load() - > repo = hg.repository(myui, 'a') - > hg.clone(myui, {}, repo, dest="ua") + > repo = hg.repository(myui, b'a') + > hg.clone(myui, {}, repo, dest=b"ua") > EOF $ $PYTHON simpleclone.py @@ -573,8 +573,8 @@ > from mercurial import ui, hg, extensions > myui = ui.ui.load() > extensions.loadall(myui) - > repo = hg.repository(myui, 'a') - > hg.clone(myui, {}, repo, dest="ua", branch=["stable",]) + > repo = hg.repository(myui, b'a') + > hg.clone(myui, {}, repo, dest=b"ua", branch=[b"stable",]) > EOF $ $PYTHON branchclone.py diff --git a/tests/test-clone-cgi.t b/tests/test-clone-cgi.t --- a/tests/test-clone-cgi.t +++ b/tests/test-clone-cgi.t @@ -17,7 +17,7 @@ > from mercurial import demandimport; demandimport.enable() > from mercurial.hgweb import hgweb > from mercurial.hgweb import wsgicgi - > application = hgweb("test", "Empty test repository") + > application = hgweb(b"test", b"Empty test repository") > wsgicgi.launch(application) > HGWEB $ chmod 755 hgweb.cgi To: pulkit, #hg-reviewers, durin42 Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3324: py3: use stringutil.forcebytestr() instead of str()
This revision was automatically updated to reflect the committed changes. Closed by commit rHGfc114a16a484: py3: use stringutil.forcebytestr() instead of str() (authored by pulkit, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3324?vs=8144=8200 REVISION DETAIL https://phab.mercurial-scm.org/D3324 AFFECTED FILES mercurial/exchange.py CHANGE DETAILS diff --git a/mercurial/exchange.py b/mercurial/exchange.py --- a/mercurial/exchange.py +++ b/mercurial/exchange.py @@ -2291,7 +2291,7 @@ continue except error.InvalidBundleSpecification as e: -repo.ui.debug(str(e) + '\n') +repo.ui.debug(stringutil.forcebytestr(e) + '\n') continue except error.UnsupportedBundleSpecification as e: repo.ui.debug('filtering %s because unsupported bundle ' To: pulkit, #hg-reviewers, durin42 Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3326: py3: use str variables to check keys in request header
This revision was automatically updated to reflect the committed changes. Closed by commit rHG83250442dc81: py3: use str variables to check keys in request header (authored by pulkit, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3326?vs=8146=8201 REVISION DETAIL https://phab.mercurial-scm.org/D3326 AFFECTED FILES mercurial/keepalive.py CHANGE DETAILS diff --git a/mercurial/keepalive.py b/mercurial/keepalive.py --- a/mercurial/keepalive.py +++ b/mercurial/keepalive.py @@ -318,24 +318,24 @@ headers.update(sorted(req.unredirected_hdrs.items())) headers = util.sortdict((n.lower(), v) for n, v in headers.items()) skipheaders = {} -for n in ('host', 'accept-encoding'): +for n in (r'host', r'accept-encoding'): if n in headers: -skipheaders['skip_' + n.replace('-', '_')] = 1 +skipheaders[r'skip_' + n.replace(r'-', r'_')] = 1 try: if urllibcompat.hasdata(req): data = urllibcompat.getdata(req) h.putrequest( req.get_method(), urllibcompat.getselector(req), -**pycompat.strkwargs(skipheaders)) +skipheaders) if r'content-type' not in headers: h.putheader(r'Content-type', r'application/x-www-form-urlencoded') if r'content-length' not in headers: h.putheader(r'Content-length', r'%d' % len(data)) else: h.putrequest( req.get_method(), urllibcompat.getselector(req), -**pycompat.strkwargs(skipheaders)) +skipheaders) except socket.error as err: raise urlerr.urlerror(err) for k, v in headers.items(): To: pulkit, #hg-reviewers, durin42 Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3335: wireproto: expose repository formats via capabilities
This revision was automatically updated to reflect the committed changes. Closed by commit rHG23c4ddda7bbe: wireproto: expose repository formats via capabilities (authored by indygreg, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3335?vs=8158=8194 REVISION DETAIL https://phab.mercurial-scm.org/D3335 AFFECTED FILES mercurial/help/internals/wireprotocol.txt mercurial/wireprotov2server.py tests/test-http-api-httpv2.t tests/test-http-protocol.t tests/test-wireproto-command-branchmap.t tests/test-wireproto-command-capabilities.t tests/test-wireproto-command-known.t tests/test-wireproto-command-listkeys.t tests/test-wireproto-command-lookup.t tests/test-wireproto-command-pushkey.t CHANGE DETAILS diff --git a/tests/test-wireproto-command-pushkey.t b/tests/test-wireproto-command-pushkey.t --- a/tests/test-wireproto-command-pushkey.t +++ b/tests/test-wireproto-command-pushkey.t @@ -45,7 +45,7 @@ s> Content-Type: application/mercurial-cbor\r\n s> Content-Length: *\r\n (glob) s> \r\n - s> \xa3Dapis\xa1Pexp-http-v2-0001\xa3Hcommands\xa7Eheads\xa2Dargs\xa1Jpubliconly\xf4Kpermissions\x81DpullEknown\xa2Dargs\xa1Enodes\x81HdeadbeefKpermissions\x81DpullFlookup\xa2Dargs\xa1CkeyCfooKpermissions\x81DpullGpushkey\xa2Dargs\xa4CkeyCkeyCnewCnewColdColdInamespaceBnsKpermissions\x81DpushHlistkeys\xa2Dargs\xa1InamespaceBnsKpermissions\x81DpullIbranchmap\xa2Dargs\xa0Kpermissions\x81DpullLcapabilities\xa2Dargs\xa0Kpermissions\x81DpullKcompression\x82\xa1DnameDzstd\xa1DnameDzlibQframingmediatypes\x81X/mercurial-exp-framing-0003GapibaseDapi/Nv1capabilitiesY\x01\xcabatch branchmap $USUAL_BUNDLE2_CAPS_SERVER$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash + s> \xa3Dapis\xa1Pexp-http-v2-0001\xa4Hcommands\xa7Eheads\xa2Dargs\xa1Jpubliconly\xf4Kpermissions\x81DpullEknown\xa2Dargs\xa1Enodes\x81HdeadbeefKpermissions\x81DpullFlookup\xa2Dargs\xa1CkeyCfooKpermissions\x81DpullGpushkey\xa2Dargs\xa4CkeyCkeyCnewCnewColdColdInamespaceBnsKpermissions\x81DpushHlistkeys\xa2Dargs\xa1InamespaceBnsKpermissions\x81DpullIbranchmap\xa2Dargs\xa0Kpermissions\x81DpullLcapabilities\xa2Dargs\xa0Kpermissions\x81DpullKcompression\x82\xa1DnameDzstd\xa1DnameDzlibNrawrepoformats\x82LgeneraldeltaHrevlogv1Qframingmediatypes\x81X/mercurial-exp-framing-0003GapibaseDapi/Nv1capabilitiesY\x01\xcabatch branchmap $USUAL_BUNDLE2_CAPS_SERVER$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash sending pushkey command s> *\r\n (glob) s> Accept-Encoding: identity\r\n @@ -93,7 +93,7 @@ s> Content-Type: application/mercurial-cbor\r\n s> Content-Length: *\r\n (glob) s> \r\n - s> \xa3Dapis\xa1Pexp-http-v2-0001\xa3Hcommands\xa7Eheads\xa2Dargs\xa1Jpubliconly\xf4Kpermissions\x81DpullEknown\xa2Dargs\xa1Enodes\x81HdeadbeefKpermissions\x81DpullFlookup\xa2Dargs\xa1CkeyCfooKpermissions\x81DpullGpushkey\xa2Dargs\xa4CkeyCkeyCnewCnewColdColdInamespaceBnsKpermissions\x81DpushHlistkeys\xa2Dargs\xa1InamespaceBnsKpermissions\x81DpullIbranchmap\xa2Dargs\xa0Kpermissions\x81DpullLcapabilities\xa2Dargs\xa0Kpermissions\x81DpullKcompression\x82\xa1DnameDzstd\xa1DnameDzlibQframingmediatypes\x81X/mercurial-exp-framing-0003GapibaseDapi/Nv1capabilitiesY\x01\xcabatch branchmap $USUAL_BUNDLE2_CAPS_SERVER$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash + s> \xa3Dapis\xa1Pexp-http-v2-0001\xa4Hcommands\xa7Eheads\xa2Dargs\xa1Jpubliconly\xf4Kpermissions\x81DpullEknown\xa2Dargs\xa1Enodes\x81HdeadbeefKpermissions\x81DpullFlookup\xa2Dargs\xa1CkeyCfooKpermissions\x81DpullGpushkey\xa2Dargs\xa4CkeyCkeyCnewCnewColdColdInamespaceBnsKpermissions\x81DpushHlistkeys\xa2Dargs\xa1InamespaceBnsKpermissions\x81DpullIbranchmap\xa2Dargs\xa0Kpermissions\x81DpullLcapabilities\xa2Dargs\xa0Kpermissions\x81DpullKcompression\x82\xa1DnameDzstd\xa1DnameDzlibNrawrepoformats\x82LgeneraldeltaHrevlogv1Qframingmediatypes\x81X/mercurial-exp-framing-0003GapibaseDapi/Nv1capabilitiesY\x01\xcabatch branchmap $USUAL_BUNDLE2_CAPS_SERVER$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash sending listkeys command s> POST /api/exp-http-v2-0001/ro/listkeys HTTP/1.1\r\n s> Accept-Encoding: identity\r\n diff --git a/tests/test-wireproto-command-lookup.t b/tests/test-wireproto-command-lookup.t --- a/tests/test-wireproto-command-lookup.t
D3328: py3: use b"%d" instead of str() to convert int to bytes
This revision was automatically updated to reflect the committed changes. Closed by commit rHG701c261fba83: py3: use b%d instead of str() to convert int to bytes (authored by pulkit, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3328?vs=8148=8203 REVISION DETAIL https://phab.mercurial-scm.org/D3328 AFFECTED FILES tests/test-clone-uncompressed.t CHANGE DETAILS diff --git a/tests/test-clone-uncompressed.t b/tests/test-clone-uncompressed.t --- a/tests/test-clone-uncompressed.t +++ b/tests/test-clone-uncompressed.t @@ -18,7 +18,7 @@ $ hg -q commit -A -m initial >>> for i in range(1024): ... with open(str(i), 'wb') as fh: - ... fh.write(str(i)) + ... fh.write(b"%d" % i) and None $ hg -q commit -A -m 'add a lot of files' $ hg st $ hg --config server.uncompressed=false serve -p $HGPORT -d --pid-file=hg.pid To: pulkit, #hg-reviewers, durin42 Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3327: py3: add b'' prefixes to make values bytes
This revision was automatically updated to reflect the committed changes. Closed by commit rHG46e705b79323: py3: add b prefixes to make values bytes (authored by pulkit, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3327?vs=8147=8202 REVISION DETAIL https://phab.mercurial-scm.org/D3327 AFFECTED FILES mercurial/sslutil.py CHANGE DETAILS diff --git a/mercurial/sslutil.py b/mercurial/sslutil.py --- a/mercurial/sslutil.py +++ b/mercurial/sslutil.py @@ -621,13 +621,13 @@ pats.append(re.escape(leftmost)) else: # Otherwise, '*' matches any dotless string, e.g. www* -pats.append(re.escape(leftmost).replace(r'\*', '[^.]*')) +pats.append(re.escape(leftmost).replace(br'\*', '[^.]*')) # add the remaining fragments, ignore any wildcards for frag in remainder: pats.append(re.escape(frag)) -pat = re.compile(r'\A' + r'\.'.join(pats) + r'\Z', re.IGNORECASE) +pat = re.compile(br'\A' + br'\.'.join(pats) + br'\Z', re.IGNORECASE) return pat.match(hostname) is not None def _verifycert(cert, hostname): To: pulkit, #hg-reviewers, durin42 Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3299: wireproto: add media type to version 2 capabilities response
This revision was automatically updated to reflect the committed changes. Closed by commit rHGb2fa1591fb44: wireproto: add media type to version 2 capabilities response (authored by indygreg, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3299?vs=8092=8189 REVISION DETAIL https://phab.mercurial-scm.org/D3299 AFFECTED FILES mercurial/help/internals/wireprotocol.txt mercurial/wireprotov2server.py tests/test-http-api-httpv2.t tests/test-http-protocol.t tests/test-wireproto-command-branchmap.t tests/test-wireproto-command-capabilities.t tests/test-wireproto-command-heads.t tests/test-wireproto-command-known.t tests/test-wireproto-command-listkeys.t tests/test-wireproto-command-lookup.t tests/test-wireproto-command-pushkey.t CHANGE DETAILS diff --git a/tests/test-wireproto-command-pushkey.t b/tests/test-wireproto-command-pushkey.t --- a/tests/test-wireproto-command-pushkey.t +++ b/tests/test-wireproto-command-pushkey.t @@ -45,7 +45,7 @@ s> Content-Type: application/mercurial-cbor\r\n s> Content-Length: *\r\n (glob) s> \r\n - s> \xa3Dapis\xa1Pexp-http-v2-0001\xa2Hcommands\xa7Eheads\xa2Dargs\xa1Jpubliconly\xf4Kpermissions\x81DpullEknown\xa2Dargs\xa1Enodes\x81HdeadbeefKpermissions\x81DpullFlookup\xa2Dargs\xa1CkeyCfooKpermissions\x81DpullGpushkey\xa2Dargs\xa4CkeyCkeyCnewCnewColdColdInamespaceBnsKpermissions\x81DpushHlistkeys\xa2Dargs\xa1InamespaceBnsKpermissions\x81DpullIbranchmap\xa2Dargs\xa0Kpermissions\x81DpullLcapabilities\xa2Dargs\xa0Kpermissions\x81DpullKcompression\x82\xa1DnameDzstd\xa1DnameDzlibGapibaseDapi/Nv1capabilitiesY\x01\xcabatch branchmap $USUAL_BUNDLE2_CAPS_SERVER$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash + s> \xa3Dapis\xa1Pexp-http-v2-0001\xa3Hcommands\xa7Eheads\xa2Dargs\xa1Jpubliconly\xf4Kpermissions\x81DpullEknown\xa2Dargs\xa1Enodes\x81HdeadbeefKpermissions\x81DpullFlookup\xa2Dargs\xa1CkeyCfooKpermissions\x81DpullGpushkey\xa2Dargs\xa4CkeyCkeyCnewCnewColdColdInamespaceBnsKpermissions\x81DpushHlistkeys\xa2Dargs\xa1InamespaceBnsKpermissions\x81DpullIbranchmap\xa2Dargs\xa0Kpermissions\x81DpullLcapabilities\xa2Dargs\xa0Kpermissions\x81DpullKcompression\x82\xa1DnameDzstd\xa1DnameDzlibQframingmediatypes\x81X/mercurial-exp-framing-0003GapibaseDapi/Nv1capabilitiesY\x01\xcabatch branchmap $USUAL_BUNDLE2_CAPS_SERVER$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash sending pushkey command s> *\r\n (glob) s> Accept-Encoding: identity\r\n @@ -93,7 +93,7 @@ s> Content-Type: application/mercurial-cbor\r\n s> Content-Length: *\r\n (glob) s> \r\n - s> \xa3Dapis\xa1Pexp-http-v2-0001\xa2Hcommands\xa7Eheads\xa2Dargs\xa1Jpubliconly\xf4Kpermissions\x81DpullEknown\xa2Dargs\xa1Enodes\x81HdeadbeefKpermissions\x81DpullFlookup\xa2Dargs\xa1CkeyCfooKpermissions\x81DpullGpushkey\xa2Dargs\xa4CkeyCkeyCnewCnewColdColdInamespaceBnsKpermissions\x81DpushHlistkeys\xa2Dargs\xa1InamespaceBnsKpermissions\x81DpullIbranchmap\xa2Dargs\xa0Kpermissions\x81DpullLcapabilities\xa2Dargs\xa0Kpermissions\x81DpullKcompression\x82\xa1DnameDzstd\xa1DnameDzlibGapibaseDapi/Nv1capabilitiesY\x01\xcabatch branchmap $USUAL_BUNDLE2_CAPS_SERVER$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash + s> \xa3Dapis\xa1Pexp-http-v2-0001\xa3Hcommands\xa7Eheads\xa2Dargs\xa1Jpubliconly\xf4Kpermissions\x81DpullEknown\xa2Dargs\xa1Enodes\x81HdeadbeefKpermissions\x81DpullFlookup\xa2Dargs\xa1CkeyCfooKpermissions\x81DpullGpushkey\xa2Dargs\xa4CkeyCkeyCnewCnewColdColdInamespaceBnsKpermissions\x81DpushHlistkeys\xa2Dargs\xa1InamespaceBnsKpermissions\x81DpullIbranchmap\xa2Dargs\xa0Kpermissions\x81DpullLcapabilities\xa2Dargs\xa0Kpermissions\x81DpullKcompression\x82\xa1DnameDzstd\xa1DnameDzlibQframingmediatypes\x81X/mercurial-exp-framing-0003GapibaseDapi/Nv1capabilitiesY\x01\xcabatch branchmap $USUAL_BUNDLE2_CAPS_SERVER$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash sending listkeys command s> POST /api/exp-http-v2-0001/ro/listkeys HTTP/1.1\r\n s> Accept-Encoding: identity\r\n diff --git a/tests/test-wireproto-command-lookup.t b/tests/test-wireproto-command-lookup.t --- a/tests/test-wireproto-command-lookup.t +++ b/tests/test-wireproto-command-lookup.t @@ -42,7 +42,7 @@ s> Content-Type: application/mercurial-cbor\r\n s>
D3325: py3: make sure curses.tigetstr() first argument is a str
This revision was automatically updated to reflect the committed changes. Closed by commit rHG483cafc3762a: py3: make sure curses.tigetstr() first argument is a str (authored by pulkit, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3325?vs=8145=8199 REVISION DETAIL https://phab.mercurial-scm.org/D3325 AFFECTED FILES mercurial/color.py CHANGE DETAILS diff --git a/mercurial/color.py b/mercurial/color.py --- a/mercurial/color.py +++ b/mercurial/color.py @@ -171,12 +171,12 @@ for key, (b, e, c) in ui._terminfoparams.copy().items(): if not b: continue -if not c and not curses.tigetstr(e): +if not c and not curses.tigetstr(pycompat.sysstr(e)): # Most terminals don't support dim, invis, etc, so don't be # noisy and use ui.debug(). ui.debug("no terminfo entry for %s\n" % e) del ui._terminfoparams[key] -if not curses.tigetstr('setaf') or not curses.tigetstr('setab'): +if not curses.tigetstr(r'setaf') or not curses.tigetstr(r'setab'): # Only warn about missing terminfo entries if we explicitly asked for # terminfo mode and we're in a formatted terminal. if mode == "terminfo" and formatted: @@ -325,11 +325,11 @@ if termcode: return termcode else: -return curses.tigetstr(val) +return curses.tigetstr(pycompat.sysstr(val)) elif bg: -return curses.tparm(curses.tigetstr('setab'), val) +return curses.tparm(curses.tigetstr(r'setab'), val) else: -return curses.tparm(curses.tigetstr('setaf'), val) +return curses.tparm(curses.tigetstr(r'setaf'), val) def _mergeeffects(text, start, stop): """Insert start sequence at every occurrence of stop sequence To: pulkit, #hg-reviewers, durin42 Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3322: py3: use urllib.parse.unquote_plus instead of urllib.unquote_plus
This revision was automatically updated to reflect the committed changes. Closed by commit rHGafe624d78d43: py3: use urllib.parse.unquote_plus instead of urllib.unquote_plus (authored by pulkit, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3322?vs=8142=8197 REVISION DETAIL https://phab.mercurial-scm.org/D3322 AFFECTED FILES tests/test-narrow-clone-non-narrow-server.t CHANGE DETAILS diff --git a/tests/test-narrow-clone-non-narrow-server.t b/tests/test-narrow-clone-non-narrow-server.t --- a/tests/test-narrow-clone-non-narrow-server.t +++ b/tests/test-narrow-clone-non-narrow-server.t @@ -18,8 +18,20 @@ $ cat hg.pid >> "$DAEMON_PIDS" Verify that narrow is advertised in the bundle2 capabilities: + + $ cat >> unquote.py < from __future__ import print_function + > import sys + > if sys.version[0] == '3': + > import urllib.parse as up + > unquote = up.unquote_plus + > else: + > import urllib + > unquote = urllib.unquote_plus + > print(unquote(list(sys.stdin)[1])) + > EOF $ echo hello | hg -R . serve --stdio | \ - > $PYTHON -c "from __future__ import print_function; import sys, urllib; print(urllib.unquote_plus(list(sys.stdin)[1]))" | grep narrow + > $PYTHON unquote.py | grep narrow narrow=v0 $ cd .. To: pulkit, durin42, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3323: py3: iterate over a copy of dict while changing it
This revision was automatically updated to reflect the committed changes. Closed by commit rHG5340daa85c62: py3: iterate over a copy of dict while changing it (authored by pulkit, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3323?vs=8143=8198 REVISION DETAIL https://phab.mercurial-scm.org/D3323 AFFECTED FILES mercurial/color.py CHANGE DETAILS diff --git a/mercurial/color.py b/mercurial/color.py --- a/mercurial/color.py +++ b/mercurial/color.py @@ -168,7 +168,7 @@ ui._terminfoparams.clear() return -for key, (b, e, c) in ui._terminfoparams.items(): +for key, (b, e, c) in ui._terminfoparams.copy().items(): if not b: continue if not c and not curses.tigetstr(e): To: pulkit, #hg-reviewers, spectral, durin42 Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3320: lock: don't use 'file' as a variable name
This revision was automatically updated to reflect the committed changes. Closed by commit rHG575f59cdd8a1: lock: dont use file as a variable name (authored by pulkit, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3320?vs=8140=8196 REVISION DETAIL https://phab.mercurial-scm.org/D3320 AFFECTED FILES mercurial/lock.py CHANGE DETAILS diff --git a/mercurial/lock.py b/mercurial/lock.py --- a/mercurial/lock.py +++ b/mercurial/lock.py @@ -175,11 +175,11 @@ _host = None -def __init__(self, vfs, file, timeout=-1, releasefn=None, acquirefn=None, +def __init__(self, vfs, fname, timeout=-1, releasefn=None, acquirefn=None, desc=None, inheritchecker=None, parentlock=None, dolock=True): self.vfs = vfs -self.f = file +self.f = fname self.held = 0 self.timeout = timeout self.releasefn = releasefn To: pulkit, #hg-reviewers, durin42 Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3334: wireprotoframing: record when new stream is encountered
This revision was automatically updated to reflect the committed changes. Closed by commit rHGe6870bca1f47: wireprotoframing: record when new stream is encountered (authored by indygreg, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3334?vs=8157=8192 REVISION DETAIL https://phab.mercurial-scm.org/D3334 AFFECTED FILES mercurial/wireprotoframing.py tests/test-wireproto-clientreactor.py CHANGE DETAILS diff --git a/tests/test-wireproto-clientreactor.py b/tests/test-wireproto-clientreactor.py --- a/tests/test-wireproto-clientreactor.py +++ b/tests/test-wireproto-clientreactor.py @@ -105,6 +105,26 @@ 'unhandled frame type'): sendframe(reactor, ffs(b'1 0 stream-begin text-output 0 foo')) +class StreamTests(unittest.TestCase): +def testmultipleresponseframes(self): +reactor = framing.clientreactor(buffersends=False) + +request, action, meta = reactor.callcommand(b'foo', {}) + +self.assertEqual(action, 'sendframes') +for f in meta['framegen']: +pass + +action, meta = sendframe( +reactor, +ffs(b'%d 0 stream-begin 4 0 foo' % request.requestid)) +self.assertEqual(action, 'responsedata') + +action, meta = sendframe( +reactor, +ffs(b'%d 0 0 4 eos bar' % request.requestid)) +self.assertEqual(action, 'responsedata') + if __name__ == '__main__': import silenttestrunner silenttestrunner.main(__name__) diff --git a/mercurial/wireprotoframing.py b/mercurial/wireprotoframing.py --- a/mercurial/wireprotoframing.py +++ b/mercurial/wireprotoframing.py @@ -1029,6 +1029,8 @@ 'without beginning of stream flag set'), } +self._incomingstreams[frame.streamid] = stream(frame.streamid) + if frame.streamflags & STREAM_FLAG_ENCODING_APPLIED: raise error.ProgrammingError('support for decoding stream ' 'payloads not yet implemneted') To: indygreg, #hg-reviewers, durin42 Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3298: debugcommands: use command executor for invoking commands
This revision was automatically updated to reflect the committed changes. Closed by commit rHGfe8c6f9f2914: debugcommands: use command executor for invoking commands (authored by indygreg, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3298?vs=8154=8188 REVISION DETAIL https://phab.mercurial-scm.org/D3298 AFFECTED FILES mercurial/debugcommands.py tests/test-http-protocol.t tests/test-ssh-proto.t CHANGE DETAILS diff --git a/tests/test-ssh-proto.t b/tests/test-ssh-proto.t --- a/tests/test-ssh-proto.t +++ b/tests/test-ssh-proto.t @@ -1367,7 +1367,7 @@ o> bookmarks\t\n o> namespaces\t\n o> phases\t - response: b'bookmarks\t\nnamespaces\t\nphases\t' + response: {b'bookmarks': b'', b'namespaces': b'', b'phases': b''} testing ssh2 creating ssh peer from handshake results @@ -1398,7 +1398,7 @@ o> bookmarks\t\n o> namespaces\t\n o> phases\t - response: b'bookmarks\t\nnamespaces\t\nphases\t' + response: {b'bookmarks': b'', b'namespaces': b'', b'phases': b''} $ cd .. @@ -1443,7 +1443,7 @@ i> flush() -> None o> bufferedreadline() -> 2: o> 0\n - response: b'' + response: {} testing ssh2 creating ssh peer from handshake results @@ -1470,7 +1470,7 @@ i> flush() -> None o> bufferedreadline() -> 2: o> 0\n - response: b'' + response: {} With a single bookmark set @@ -1505,7 +1505,7 @@ o> bufferedreadline() -> 3: o> 46\n o> bufferedread(46) -> 46: bookA\t68986213bd4485ea51533535e3fc9e78007a711f - response: b'bookA\t68986213bd4485ea51533535e3fc9e78007a711f' + response: {b'bookA': b'68986213bd4485ea51533535e3fc9e78007a711f'} testing ssh2 creating ssh peer from handshake results @@ -1533,7 +1533,7 @@ o> bufferedreadline() -> 3: o> 46\n o> bufferedread(46) -> 46: bookA\t68986213bd4485ea51533535e3fc9e78007a711f - response: b'bookA\t68986213bd4485ea51533535e3fc9e78007a711f' + response: {b'bookA': b'68986213bd4485ea51533535e3fc9e78007a711f'} With multiple bookmarks set @@ -1570,7 +1570,7 @@ o> bufferedread(93) -> 93: o> bookA\t68986213bd4485ea51533535e3fc9e78007a711f\n o> bookB\t1880f3755e2e52e3199e0ee5638128b08642f34d - response: b'bookA\t68986213bd4485ea51533535e3fc9e78007a711f\nbookB\t1880f3755e2e52e3199e0ee5638128b08642f34d' + response: {b'bookA': b'68986213bd4485ea51533535e3fc9e78007a711f', b'bookB': b'1880f3755e2e52e3199e0ee5638128b08642f34d'} testing ssh2 creating ssh peer from handshake results @@ -1600,7 +1600,7 @@ o> bufferedread(93) -> 93: o> bookA\t68986213bd4485ea51533535e3fc9e78007a711f\n o> bookB\t1880f3755e2e52e3199e0ee5638128b08642f34d - response: b'bookA\t68986213bd4485ea51533535e3fc9e78007a711f\nbookB\t1880f3755e2e52e3199e0ee5638128b08642f34d' + response: {b'bookA': b'68986213bd4485ea51533535e3fc9e78007a711f', b'bookB': b'1880f3755e2e52e3199e0ee5638128b08642f34d'} Test pushkey for bookmarks @@ -1646,7 +1646,7 @@ o> 2\n o> bufferedread(2) -> 2: o> 1\n - response: b'1\n' + response: True testing ssh2 creating ssh peer from handshake results @@ -1683,7 +1683,7 @@ o> 2\n o> bufferedread(2) -> 2: o> 1\n - response: b'1\n' + response: True $ hg bookmarks bookA 0:68986213bd44 @@ -1729,7 +1729,7 @@ o> bufferedreadline() -> 3: o> 15\n o> bufferedread(15) -> 15: publishing\tTrue - response: b'publishing\tTrue' + response: {b'publishing': b'True'} testing ssh2 creating ssh peer from handshake results @@ -1757,7 +1757,7 @@ o> bufferedreadline() -> 3: o> 15\n o> bufferedread(15) -> 15: publishing\tTrue - response: b'publishing\tTrue' + response: {b'publishing': b'True'} Create some commits @@ -1811,7 +1811,7 @@ o> 20b8a89289d80036e6c4e87c2083e3bea1586637\t1\n o> c4750011d906c18ea2f0527419cbc1a544435150\t1\n o> publishing\tTrue - response: b'20b8a89289d80036e6c4e87c2083e3bea1586637\t1\nc4750011d906c18ea2f0527419cbc1a544435150\t1\npublishing\tTrue' + response: {b'20b8a89289d80036e6c4e87c2083e3bea1586637': b'1', b'c4750011d906c18ea2f0527419cbc1a544435150': b'1', b'publishing': b'True'} testing ssh2 creating ssh peer from handshake results @@ -1842,7 +1842,7 @@ o> 20b8a89289d80036e6c4e87c2083e3bea1586637\t1\n o> c4750011d906c18ea2f0527419cbc1a544435150\t1\n o> publishing\tTrue - response: b'20b8a89289d80036e6c4e87c2083e3bea1586637\t1\nc4750011d906c18ea2f0527419cbc1a544435150\t1\npublishing\tTrue' + response: {b'20b8a89289d80036e6c4e87c2083e3bea1586637': b'1', b'c4750011d906c18ea2f0527419cbc1a544435150': b'1', b'publishing': b'True'} Single draft head @@ -1879,7 +1879,7 @@ o> bufferedread(58) -> 58: o> c4750011d906c18ea2f0527419cbc1a544435150\t1\n o> publishing\tTrue - response: b'c4750011d906c18ea2f0527419cbc1a544435150\t1\npublishing\tTrue' +
D3319: py3: use b"%d" instead of str() to convert integers to bytes
This revision was automatically updated to reflect the committed changes. Closed by commit rHG34758397ad1b: py3: use b%d instead of str() to convert integers to bytes (authored by pulkit, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3319?vs=8139=8193 REVISION DETAIL https://phab.mercurial-scm.org/D3319 AFFECTED FILES hgext/convert/__init__.py hgext/convert/cvs.py hgext/convert/cvsps.py mercurial/lock.py CHANGE DETAILS diff --git a/mercurial/lock.py b/mercurial/lock.py --- a/mercurial/lock.py +++ b/mercurial/lock.py @@ -348,7 +348,7 @@ if self._parentheld: lockname = self.parentlock else: -lockname = '%s:%s' % (lock._host, self.pid) +lockname = b'%s:%d' % (lock._host, self.pid) self._inherited = True try: yield lockname diff --git a/hgext/convert/cvsps.py b/hgext/convert/cvsps.py --- a/hgext/convert/cvsps.py +++ b/hgext/convert/cvsps.py @@ -919,7 +919,7 @@ if opts["parents"] and cs.parents: if len(cs.parents) > 1: ui.write(('Parents: %s\n' % - (','.join([str(p.id) for p in cs.parents] + (','.join([(b"%d" % p.id) for p in cs.parents] else: ui.write(('Parent: %d\n' % cs.parents[0].id)) @@ -941,18 +941,18 @@ fn = fn[len(opts["prefix"]):] ui.write('\t%s:%s->%s%s \n' % ( fn, '.'.join([str(x) for x in f.parent]) or 'INITIAL', -'.'.join([str(x) for x in f.revision]), +'.'.join([(b"%d" % x) for x in f.revision]), ['', '(DEAD)'][f.dead])) ui.write('\n') # have we seen the start tag? if revisions and off: -if revisions[0] == str(cs.id) or \ +if revisions[0] == (b"%d" % cs.id) or \ revisions[0] in cs.tags: off = False # see if we reached the end tag if len(revisions) > 1 and not off: -if revisions[1] == str(cs.id) or \ +if revisions[1] == (b"%d" % cs.id) or \ revisions[1] in cs.tags: break diff --git a/hgext/convert/cvs.py b/hgext/convert/cvs.py --- a/hgext/convert/cvs.py +++ b/hgext/convert/cvs.py @@ -91,7 +91,7 @@ for cs in db: if maxrev and cs.id > maxrev: break -id = str(cs.id) +id = (b"%d" % cs.id) cs.author = self.recode(cs.author) self.lastbranch[cs.branch] = id cs.comment = self.recode(cs.comment) @@ -102,13 +102,13 @@ files = {} for f in cs.entries: -files[f.file] = "%s%s" % ('.'.join([str(x) +files[f.file] = "%s%s" % ('.'.join([(b"%d" % x) for x in f.revision]), ['', '(DEAD)'][f.dead]) # add current commit to set c = commit(author=cs.author, date=date, - parents=[str(p.id) for p in cs.parents], + parents=[(b"%d" % p.id) for p in cs.parents], desc=cs.comment, branch=cs.branch or '') self.changeset[id] = c self.files[id] = files diff --git a/hgext/convert/__init__.py b/hgext/convert/__init__.py --- a/hgext/convert/__init__.py +++ b/hgext/convert/__init__.py @@ -482,7 +482,7 @@ rev = ctx.extra().get('convert_revision', '') if rev.startswith('svn:'): if name == 'svnrev': -return str(subversion.revsplit(rev)[2]) +return (b"%d" % subversion.revsplit(rev)[2]) elif name == 'svnpath': return subversion.revsplit(rev)[1] elif name == 'svnuuid': To: pulkit, #hg-reviewers, durin42 Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3321: py3: add b'' prefixes to tests/test-status-inprocess.py
This revision was automatically updated to reflect the committed changes. Closed by commit rHG9dfa4e9ed45d: py3: add b prefixes to tests/test-status-inprocess.py (authored by pulkit, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3321?vs=8141=8195 REVISION DETAIL https://phab.mercurial-scm.org/D3321 AFFECTED FILES tests/test-status-inprocess.py CHANGE DETAILS diff --git a/tests/test-status-inprocess.py b/tests/test-status-inprocess.py --- a/tests/test-status-inprocess.py +++ b/tests/test-status-inprocess.py @@ -10,17 +10,17 @@ u = uimod.ui.load() print('% creating repo') -repo = localrepo.localrepository(u, '.', create=True) +repo = localrepo.localrepository(u, b'.', create=True) f = open('test.py', 'w') try: f.write('foo\n') finally: f.close print('% add and commit') -commands.add(u, repo, 'test.py') -commands.commit(u, repo, message='*') +commands.add(u, repo, b'test.py') +commands.commit(u, repo, message=b'*') commands.status(u, repo, clean=True) To: pulkit, #hg-reviewers, durin42 Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3317: wireproto: properly call clonebundles command
This revision was automatically updated to reflect the committed changes. Closed by commit rHGa168799687e5: wireproto: properly call clonebundles command (authored by indygreg, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3317?vs=8137=8185 REVISION DETAIL https://phab.mercurial-scm.org/D3317 AFFECTED FILES mercurial/exchange.py mercurial/localrepo.py mercurial/repository.py mercurial/wireprotov1peer.py CHANGE DETAILS diff --git a/mercurial/wireprotov1peer.py b/mercurial/wireprotov1peer.py --- a/mercurial/wireprotov1peer.py +++ b/mercurial/wireprotov1peer.py @@ -322,6 +322,10 @@ # Begin of ipeercommands interface. +def clonebundles(self): +self.requirecap('clonebundles', _('clone bundles')) +return self._call('clonebundles') + @batchable def lookup(self, key): self.requirecap('lookup', _('look up remote revision')) diff --git a/mercurial/repository.py b/mercurial/repository.py --- a/mercurial/repository.py +++ b/mercurial/repository.py @@ -101,6 +101,12 @@ Returns a set of string capabilities. """ +def clonebundles(): +"""Obtains the clone bundles manifest for the repo. + +Returns the manifest as unparsed bytes. +""" + def debugwireargs(one, two, three=None, four=None, five=None): """Used to facilitate debugging of arguments passed over the wire.""" diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -235,6 +235,9 @@ def capabilities(self): return self._caps +def clonebundles(self): +return self._repo.tryread('clonebundles.manifest') + def debugwireargs(self, one, two, three=None, four=None, five=None): """Used to test argument passing over the wire""" return "%s %s %s %s %s" % (one, two, pycompat.bytestr(three), diff --git a/mercurial/exchange.py b/mercurial/exchange.py --- a/mercurial/exchange.py +++ b/mercurial/exchange.py @@ -2170,7 +2170,8 @@ if not remote.capable('clonebundles'): return -res = remote._call('clonebundles') +with remote.commandexecutor() as e: +res = e.callcommand('clonebundles', {}).result() # If we call the wire protocol command, that's good enough to record the # attempt. To: indygreg, #hg-reviewers, durin42 Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3318: repository: remove ipeercommands from ipeerbase
This revision was automatically updated to reflect the committed changes. Closed by commit rHG62ebfda864de: repository: remove ipeercommands from ipeerbase (authored by indygreg, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3318?vs=8138=8186 REVISION DETAIL https://phab.mercurial-scm.org/D3318 AFFECTED FILES mercurial/localrepo.py mercurial/repository.py mercurial/wireprotov1peer.py CHANGE DETAILS diff --git a/mercurial/wireprotov1peer.py b/mercurial/wireprotov1peer.py --- a/mercurial/wireprotov1peer.py +++ b/mercurial/wireprotov1peer.py @@ -308,7 +308,7 @@ else: f.set_result(result) -@zi.implementer(repository.ipeerlegacycommands) +@zi.implementer(repository.ipeercommands, repository.ipeerlegacycommands) class wirepeer(repository.peer): """Client-side interface for communicating with a peer repository. diff --git a/mercurial/repository.py b/mercurial/repository.py --- a/mercurial/repository.py +++ b/mercurial/repository.py @@ -284,8 +284,7 @@ being issued. """ -class ipeerbase(ipeerconnection, ipeercapabilities, ipeercommands, -ipeerrequests): +class ipeerbase(ipeerconnection, ipeercapabilities, ipeerrequests): """Unified interface for peer repositories. All peer instances must conform to this interface. diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -196,6 +196,7 @@ def close(self): self._closed = True +@zi.implementer(repository.ipeercommands) class localpeer(repository.peer): '''peer for a local repo; reflects only the most recent API''' To: indygreg, #hg-reviewers, durin42 Cc: durin42, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3332: httppeer: handle error response from client reactor
This revision was automatically updated to reflect the committed changes. Closed by commit rHG8cea0d57bf37: httppeer: handle error response from client reactor (authored by indygreg, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3332?vs=8155=8190 REVISION DETAIL https://phab.mercurial-scm.org/D3332 AFFECTED FILES mercurial/httppeer.py CHANGE DETAILS diff --git a/mercurial/httppeer.py b/mercurial/httppeer.py --- a/mercurial/httppeer.py +++ b/mercurial/httppeer.py @@ -763,6 +763,14 @@ f.set_result(result) del results[request.requestid] +elif action == 'error': +e = error.RepoError(meta['message']) + +if f: +f.set_exception(e) +else: +raise e + else: e = error.ProgrammingError('unhandled action: %s' % action) To: indygreg, #hg-reviewers, durin42 Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3333: wireprotoframing: use value passed into function
This revision was automatically updated to reflect the committed changes. Closed by commit rHGb9502b5f2066: wireprotoframing: use value passed into function (authored by indygreg, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D?vs=8156=8191 REVISION DETAIL https://phab.mercurial-scm.org/D AFFECTED FILES mercurial/wireprotoframing.py CHANGE DETAILS diff --git a/mercurial/wireprotoframing.py b/mercurial/wireprotoframing.py --- a/mercurial/wireprotoframing.py +++ b/mercurial/wireprotoframing.py @@ -464,7 +464,7 @@ def __init__(self, streamid, active=False): self.streamid = streamid -self._active = False +self._active = active def makeframe(self, requestid, typeid, flags, payload): """Create a frame to be sent out over this stream. To: indygreg, #hg-reviewers, durin42 Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3296: debugcommands: perform handshake when obtaining httpv2 peer
This revision was automatically updated to reflect the committed changes. Closed by commit rHG72b0982cd509: debugcommands: perform handshake when obtaining httpv2 peer (authored by indygreg, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3296?vs=8089=8181 REVISION DETAIL https://phab.mercurial-scm.org/D3296 AFFECTED FILES mercurial/debugcommands.py tests/test-http-api-httpv2.t tests/test-http-protocol.t tests/test-wireproto-command-branchmap.t tests/test-wireproto-command-capabilities.t tests/test-wireproto-command-heads.t tests/test-wireproto-command-known.t tests/test-wireproto-command-listkeys.t tests/test-wireproto-command-lookup.t tests/test-wireproto-command-pushkey.t CHANGE DETAILS diff --git a/tests/test-wireproto-command-pushkey.t b/tests/test-wireproto-command-pushkey.t --- a/tests/test-wireproto-command-pushkey.t +++ b/tests/test-wireproto-command-pushkey.t @@ -29,6 +29,23 @@ > new 426bada5c67598ca65036d57d9e4b64b0c1ce7a0 > EOF creating http peer for wire protocol version 2 + s> *\r\n (glob) + s> Accept-Encoding: identity\r\n + s> vary: X-HgProto-1,X-HgUpgrade-1\r\n + s> x-hgproto-1: cbor\r\n + s> x-hgupgrade-1: exp-http-v2-0001\r\n + s> accept: application/mercurial-0.1\r\n + s> host: $LOCALIP:$HGPORT\r\n (glob) + s> user-agent: Mercurial debugwireproto\r\n + s> \r\n + s> makefile('rb', None) + s> HTTP/1.1 200 OK\r\n + s> Server: testing stub value\r\n + s> Date: $HTTP_DATE$\r\n + s> Content-Type: application/mercurial-cbor\r\n + s> Content-Length: *\r\n (glob) + s> \r\n + s> \xa3Dapis\xa1Pexp-http-v2-0001\xa2Hcommands\xa7Eheads\xa2Dargs\xa1Jpubliconly\xf4Kpermissions\x81DpullEknown\xa2Dargs\xa1Enodes\x81HdeadbeefKpermissions\x81DpullFlookup\xa2Dargs\xa1CkeyCfooKpermissions\x81DpullGpushkey\xa2Dargs\xa4CkeyCkeyCnewCnewColdColdInamespaceBnsKpermissions\x81DpushHlistkeys\xa2Dargs\xa1InamespaceBnsKpermissions\x81DpullIbranchmap\xa2Dargs\xa0Kpermissions\x81DpullLcapabilities\xa2Dargs\xa0Kpermissions\x81DpullKcompression\x82\xa1DnameDzstd\xa1DnameDzlibGapibaseDapi/Nv1capabilitiesY\x01\xcabatch branchmap $USUAL_BUNDLE2_CAPS_SERVER$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash sending pushkey command s> *\r\n (glob) s> Accept-Encoding: identity\r\n @@ -60,6 +77,23 @@ > namespace bookmarks > EOF creating http peer for wire protocol version 2 + s> GET /?cmd=capabilities HTTP/1.1\r\n + s> Accept-Encoding: identity\r\n + s> vary: X-HgProto-1,X-HgUpgrade-1\r\n + s> x-hgproto-1: cbor\r\n + s> x-hgupgrade-1: exp-http-v2-0001\r\n + s> accept: application/mercurial-0.1\r\n + s> host: $LOCALIP:$HGPORT\r\n (glob) + s> user-agent: Mercurial debugwireproto\r\n + s> \r\n + s> makefile('rb', None) + s> HTTP/1.1 200 OK\r\n + s> Server: testing stub value\r\n + s> Date: $HTTP_DATE$\r\n + s> Content-Type: application/mercurial-cbor\r\n + s> Content-Length: *\r\n (glob) + s> \r\n + s> \xa3Dapis\xa1Pexp-http-v2-0001\xa2Hcommands\xa7Eheads\xa2Dargs\xa1Jpubliconly\xf4Kpermissions\x81DpullEknown\xa2Dargs\xa1Enodes\x81HdeadbeefKpermissions\x81DpullFlookup\xa2Dargs\xa1CkeyCfooKpermissions\x81DpullGpushkey\xa2Dargs\xa4CkeyCkeyCnewCnewColdColdInamespaceBnsKpermissions\x81DpushHlistkeys\xa2Dargs\xa1InamespaceBnsKpermissions\x81DpullIbranchmap\xa2Dargs\xa0Kpermissions\x81DpullLcapabilities\xa2Dargs\xa0Kpermissions\x81DpullKcompression\x82\xa1DnameDzstd\xa1DnameDzlibGapibaseDapi/Nv1capabilitiesY\x01\xcabatch branchmap $USUAL_BUNDLE2_CAPS_SERVER$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash sending listkeys command s> POST /api/exp-http-v2-0001/ro/listkeys HTTP/1.1\r\n s> Accept-Encoding: identity\r\n diff --git a/tests/test-wireproto-command-lookup.t b/tests/test-wireproto-command-lookup.t --- a/tests/test-wireproto-command-lookup.t +++ b/tests/test-wireproto-command-lookup.t @@ -26,6 +26,23 @@ > key 426bada5c67598ca65036d57d9e4b64b0c1ce7a0 > EOF creating http peer for wire protocol version 2 + s> *\r\n (glob) + s> Accept-Encoding: identity\r\n + s> vary: X-HgProto-1,X-HgUpgrade-1\r\n + s> x-hgproto-1: cbor\r\n + s> x-hgupgrade-1: exp-http-v2-0001\r\n + s> accept: application/mercurial-0.1\r\n + s> host: $LOCALIP:$HGPORT\r\n (glob) + s> user-agent: Mercurial debugwireproto\r\n + s> \r\n + s> makefile('rb', None) + s> HTTP/1.1 200 OK\r\n + s> Server: testing stub value\r\n + s> Date: $HTTP_DATE$\r\n + s> Content-Type:
D3297: httppeer: implement command executor for version 2 peer
This revision was automatically updated to reflect the committed changes. Closed by commit rHG950294e28136: httppeer: implement command executor for version 2 peer (authored by indygreg, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3297?vs=8153=8187 REVISION DETAIL https://phab.mercurial-scm.org/D3297 AFFECTED FILES mercurial/httppeer.py CHANGE DETAILS diff --git a/mercurial/httppeer.py b/mercurial/httppeer.py --- a/mercurial/httppeer.py +++ b/mercurial/httppeer.py @@ -13,7 +13,9 @@ import os import socket import struct +import sys import tempfile +import weakref from .i18n import _ from .thirdparty import ( @@ -31,7 +33,6 @@ statichttprepo, url as urlmod, util, -wireproto, wireprotoframing, wireprototypes, wireprotov1peer, @@ -517,8 +518,262 @@ def _abort(self, exception): raise exception +def sendv2request(ui, opener, requestbuilder, apiurl, permission, requests): +reactor = wireprotoframing.clientreactor(hasmultiplesend=False, + buffersends=True) + +url = '%s/%s' % (apiurl, permission) + +if len(requests) > 1: +url += '/multirequest' +else: +url += '/%s' % requests[0][0] + +# Request ID to (request, future) +requestmap = {} + +for command, args, f in requests: +request, action, meta = reactor.callcommand(command, args) +assert action == 'noop' + +requestmap[request.requestid] = (request, f) + +action, meta = reactor.flushcommands() +assert action == 'sendframes' + +# TODO stream this. +body = b''.join(map(bytes, meta['framegen'])) + +# TODO modify user-agent to reflect v2 +headers = { +r'Accept': wireprotov2server.FRAMINGTYPE, +r'Content-Type': wireprotov2server.FRAMINGTYPE, +} + +req = requestbuilder(pycompat.strurl(url), body, headers) +req.add_unredirected_header(r'Content-Length', r'%d' % len(body)) + +try: +res = opener.open(req) +except urlerr.httperror as e: +if e.code == 401: +raise error.Abort(_('authorization failed')) + +raise +except httplib.HTTPException as e: +ui.traceback() +raise IOError(None, e) + +return reactor, requestmap, res + +class queuedcommandfuture(pycompat.futures.Future): +"""Wraps result() on command futures to trigger submission on call.""" + +def result(self, timeout=None): +if self.done(): +return pycompat.futures.Future.result(self, timeout) + +self._peerexecutor.sendcommands() + +# sendcommands() will restore the original __class__ and self.result +# will resolve to Future.result. +return self.result(timeout) + +@zi.implementer(repository.ipeercommandexecutor) +class httpv2executor(object): +def __init__(self, ui, opener, requestbuilder, apiurl, descriptor): +self._ui = ui +self._opener = opener +self._requestbuilder = requestbuilder +self._apiurl = apiurl +self._descriptor = descriptor +self._sent = False +self._closed = False +self._neededpermissions = set() +self._calls = [] +self._futures = weakref.WeakSet() +self._responseexecutor = None +self._responsef = None + +def __enter__(self): +return self + +def __exit__(self, exctype, excvalue, exctb): +self.close() + +def callcommand(self, command, args): +if self._sent: +raise error.ProgrammingError('callcommand() cannot be used after ' + 'commands are sent') + +if self._closed: +raise error.ProgrammingError('callcommand() cannot be used after ' + 'close()') + +# The service advertises which commands are available. So if we attempt +# to call an unknown command or pass an unknown argument, we can screen +# for this. +if command not in self._descriptor['commands']: +raise error.ProgrammingError( +'wire protocol command %s is not available' % command) + +cmdinfo = self._descriptor['commands'][command] +unknownargs = set(args.keys()) - set(cmdinfo.get('args', {})) + +if unknownargs: +raise error.ProgrammingError( +'wire protocol command %s does not accept argument: %s' % ( +command, ', '.join(sorted(unknownargs + +self._neededpermissions |= set(cmdinfo['permissions']) + +# TODO we /could/ also validate types here, since the API descriptor +# includes types... + +f = pycompat.futures.Future() + +# Monkeypatch it so result() triggers sendcommands(), otherwise result() +# could deadlock. +f.__class__ = queuedcommandfuture +f._peerexecutor = self + +
D3315: exchange: use command executor for pushkey
This revision was automatically updated to reflect the committed changes. Closed by commit rHG516b5a5edae3: exchange: use command executor for pushkey (authored by indygreg, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3315?vs=8135=8183 REVISION DETAIL https://phab.mercurial-scm.org/D3315 AFFECTED FILES mercurial/debugcommands.py mercurial/exchange.py CHANGE DETAILS diff --git a/mercurial/exchange.py b/mercurial/exchange.py --- a/mercurial/exchange.py +++ b/mercurial/exchange.py @@ -1212,10 +1212,14 @@ outdated = [c for c in outdated if c.node() not in pheads] # fallback to independent pushkey command for newremotehead in outdated: -r = pushop.remote.pushkey('phases', - newremotehead.hex(), - ('%d' % phases.draft), - ('%d' % phases.public)) +with pushop.remote.commandexecutor() as e: +r = e.callcommand('pushkey', { +'namespace': 'phases', +'key': newremotehead.hex(), +'old': '%d' % phases.draft, +'new': '%d' % phases.public +}).result() + if not r: pushop.ui.warn(_('updating %s to public failed!\n') % newremotehead) @@ -1270,7 +1274,16 @@ action = 'export' elif not new: action = 'delete' -if remote.pushkey('bookmarks', b, old, new): + +with remote.commandexecutor() as e: +r = e.callcommand('pushkey', { +'namespace': 'bookmarks', +'key': b, +'old': old, +'new': new, +}).result() + +if r: ui.status(bookmsgmap[action][0] % b) else: ui.warn(bookmsgmap[action][1] % b) diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py --- a/mercurial/debugcommands.py +++ b/mercurial/debugcommands.py @@ -1832,7 +1832,14 @@ target = hg.peer(ui, {}, repopath) if keyinfo: key, old, new = keyinfo -r = target.pushkey(namespace, key, old, new) +with target.commandexecutor() as e: +r = e.callcommand('pushkey', { +'namespace': namespace, +'key': key, +'old': old, +'new': new, +}).result() + ui.status(pycompat.bytestr(r) + '\n') return not r else: To: indygreg, #hg-reviewers, durin42 Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3316: exchange: use command executor for getbundle
This revision was automatically updated to reflect the committed changes. Closed by commit rHG8f3c6fb55369: exchange: use command executor for getbundle (authored by indygreg, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3316?vs=8136=8184 REVISION DETAIL https://phab.mercurial-scm.org/D3316 AFFECTED FILES mercurial/exchange.py CHANGE DETAILS diff --git a/mercurial/exchange.py b/mercurial/exchange.py --- a/mercurial/exchange.py +++ b/mercurial/exchange.py @@ -1648,17 +1648,22 @@ kwargs['obsmarkers'] = True pullop.stepsdone.add('obsmarkers') _pullbundle2extraprepare(pullop, kwargs) -bundle = pullop.remote.getbundle('pull', **pycompat.strkwargs(kwargs)) -try: -op = bundle2.bundleoperation(pullop.repo, pullop.gettransaction, - source='pull') -op.modes['bookmarks'] = 'records' -bundle2.processbundle(pullop.repo, bundle, op=op) -except bundle2.AbortFromPart as exc: -pullop.repo.ui.status(_('remote: abort: %s\n') % exc) -raise error.Abort(_('pull failed on remote'), hint=exc.hint) -except error.BundleValueError as exc: -raise error.Abort(_('missing support for %s') % exc) + +with pullop.remote.commandexecutor() as e: +args = dict(kwargs) +args['source'] = 'pull' +bundle = e.callcommand('getbundle', args).result() + +try: +op = bundle2.bundleoperation(pullop.repo, pullop.gettransaction, + source='pull') +op.modes['bookmarks'] = 'records' +bundle2.processbundle(pullop.repo, bundle, op=op) +except bundle2.AbortFromPart as exc: +pullop.repo.ui.status(_('remote: abort: %s\n') % exc) +raise error.Abort(_('pull failed on remote'), hint=exc.hint) +except error.BundleValueError as exc: +raise error.Abort(_('missing support for %s') % exc) if pullop.fetch: pullop.cgresult = bundle2.combinechangegroupresults(op) To: indygreg, #hg-reviewers, durin42 Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3314: wireproto: use command executor for unbundle
This revision was automatically updated to reflect the committed changes. Closed by commit rHG72e26319f3b8: wireproto: use command executor for unbundle (authored by indygreg, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3314?vs=8134=8182 REVISION DETAIL https://phab.mercurial-scm.org/D3314 AFFECTED FILES mercurial/exchange.py mercurial/localrepo.py mercurial/wireprotov1peer.py CHANGE DETAILS diff --git a/mercurial/wireprotov1peer.py b/mercurial/wireprotov1peer.py --- a/mercurial/wireprotov1peer.py +++ b/mercurial/wireprotov1peer.py @@ -436,7 +436,7 @@ else: return changegroupmod.cg1unpacker(f, 'UN') -def unbundle(self, cg, heads, url): +def unbundle(self, bundle, heads, url): '''Send cg (a readable file-like object representing the changegroup to push, typically a chunkbuffer object) to the remote server as a bundle. @@ -456,9 +456,9 @@ else: heads = wireprototypes.encodelist(heads) -if util.safehasattr(cg, 'deltaheader'): +if util.safehasattr(bundle, 'deltaheader'): # this a bundle10, do the old style call sequence -ret, output = self._callpush("unbundle", cg, heads=heads) +ret, output = self._callpush("unbundle", bundle, heads=heads) if ret == "": raise error.ResponseError( _('push failed:'), output) @@ -472,7 +472,7 @@ self.ui.status(_('remote: '), l) else: # bundle2 push. Send a stream, fetch a stream. -stream = self._calltwowaystream('unbundle', cg, heads=heads) +stream = self._calltwowaystream('unbundle', bundle, heads=heads) ret = bundle2.getunbundler(self.ui, stream) return ret diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -275,14 +275,14 @@ raise error.Abort(_('cannot perform stream clone against local ' 'peer')) -def unbundle(self, cg, heads, url): +def unbundle(self, bundle, heads, url): """apply a bundle on a repo This function handles the repo locking itself.""" try: try: -cg = exchange.readbundle(self.ui, cg, None) -ret = exchange.unbundle(self._repo, cg, heads, 'push', url) +bundle = exchange.readbundle(self.ui, bundle, None) +ret = exchange.unbundle(self._repo, bundle, heads, 'push', url) if util.safehasattr(ret, 'getchunks'): # This is a bundle20 object, turn it into an unbundler. # This little dance should be dropped eventually when the diff --git a/mercurial/exchange.py b/mercurial/exchange.py --- a/mercurial/exchange.py +++ b/mercurial/exchange.py @@ -1096,8 +1096,12 @@ stream = util.chunkbuffer(bundler.getchunks()) try: try: -reply = pushop.remote.unbundle( -stream, ['force'], pushop.remote.url()) +with pushop.remote.commandexecutor() as e: +reply = e.callcommand('unbundle', { +'bundle': stream, +'heads': ['force'], +'url': pushop.remote.url(), +}).result() except error.BundleValueError as exc: raise error.Abort(_('missing support for %s') % exc) try: To: indygreg, #hg-reviewers, durin42 Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3295: wireproto: rename HTTPV2 so it less like HTTP/2
This revision was automatically updated to reflect the committed changes. Closed by commit rHG77c9ee77687c: wireproto: rename HTTPV2 so it less like HTTP/2 (authored by indygreg, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3295?vs=8088=8180 REVISION DETAIL https://phab.mercurial-scm.org/D3295 AFFECTED FILES mercurial/debugcommands.py mercurial/httppeer.py mercurial/wireprotoserver.py mercurial/wireprototypes.py mercurial/wireprotov2server.py CHANGE DETAILS diff --git a/mercurial/wireprotov2server.py b/mercurial/wireprotov2server.py --- a/mercurial/wireprotov2server.py +++ b/mercurial/wireprotov2server.py @@ -27,7 +27,7 @@ FRAMINGTYPE = b'application/mercurial-exp-framing-0003' -HTTPV2 = wireprototypes.HTTPV2 +HTTP_WIREPROTO_V2 = wireprototypes.HTTP_WIREPROTO_V2 def handlehttpv2request(rctx, req, res, checkperm, urlparts): from .hgweb import common as hgwebcommon @@ -332,7 +332,7 @@ @property def name(self): -return HTTPV2 +return HTTP_WIREPROTO_V2 def getargs(self, args): data = {} diff --git a/mercurial/wireprototypes.py b/mercurial/wireprototypes.py --- a/mercurial/wireprototypes.py +++ b/mercurial/wireprototypes.py @@ -18,7 +18,7 @@ # These are advertised over the wire. Increment the counters at the end # to reflect BC breakages. SSHV2 = 'exp-ssh-v2-0001' -HTTPV2 = 'exp-http-v2-0001' +HTTP_WIREPROTO_V2 = 'exp-http-v2-0001' # All available wire protocol transports. TRANSPORTS = { @@ -35,7 +35,7 @@ 'transport': 'http', 'version': 1, }, -HTTPV2: { +HTTP_WIREPROTO_V2: { 'transport': 'http', 'version': 2, } diff --git a/mercurial/wireprotoserver.py b/mercurial/wireprotoserver.py --- a/mercurial/wireprotoserver.py +++ b/mercurial/wireprotoserver.py @@ -307,7 +307,7 @@ #Callable receiving (req, repo) that is called to obtain an API #descriptor for this service. The response must be serializable to CBOR. API_HANDLERS = { -wireprotov2server.HTTPV2: { +wireprotov2server.HTTP_WIREPROTO_V2: { 'config': ('experimental', 'web.api.http-v2'), 'handler': wireprotov2server.handlehttpv2request, 'apidescriptor': wireprotov2server.httpv2apidescriptor, diff --git a/mercurial/httppeer.py b/mercurial/httppeer.py --- a/mercurial/httppeer.py +++ b/mercurial/httppeer.py @@ -672,7 +672,7 @@ #Integer priority for the service. If we could choose from multiple #services, we choose the one with the highest priority. API_PEERS = { -wireprototypes.HTTPV2: { +wireprototypes.HTTP_WIREPROTO_V2: { 'init': httpv2peer, 'priority': 50, }, diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py --- a/mercurial/debugcommands.py +++ b/mercurial/debugcommands.py @@ -2912,7 +2912,7 @@ if opts['peer'] == 'http2': ui.write(_('creating http peer for wire protocol version 2\n')) peer = httppeer.httpv2peer( -ui, path, 'api/%s' % wireprototypes.HTTPV2, +ui, path, 'api/%s' % wireprototypes.HTTP_WIREPROTO_V2, opener, httppeer.urlreq.request, {}) elif opts['peer'] == 'raw': ui.write(_('using raw connection to peer\n')) To: indygreg, #hg-reviewers, durin42 Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3292: bookmarks: use command executor for wire protocol commands
indygreg added a comment. In https://phab.mercurial-scm.org/D3292#53207, @durin42 wrote: > btw, I don't love how this looks, it feels like we could probably revisit letting "normal" function calls work for one-shot requests like this, but let's do it later once we map the new wireproto world a little more I’m not opposed to providing a helper method that wraps and makes the consumer simpler. Where my mind is at is that proto v2 commands will be smaller and we’ll issue more of them. I wanted to make batching and transfer semantics for half-duplex connections explicit. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3292 To: indygreg, #hg-reviewers, durin42 Cc: durin42, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3292: bookmarks: use command executor for wire protocol commands
This revision was automatically updated to reflect the committed changes. Closed by commit rHGadd129811176: bookmarks: use command executor for wire protocol commands (authored by indygreg, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3292?vs=8131=8177 REVISION DETAIL https://phab.mercurial-scm.org/D3292 AFFECTED FILES mercurial/bookmarks.py CHANGE DETAILS diff --git a/mercurial/bookmarks.py b/mercurial/bookmarks.py --- a/mercurial/bookmarks.py +++ b/mercurial/bookmarks.py @@ -646,12 +646,16 @@ writer(msg) localmarks.applychanges(repo, tr, changes) -def incoming(ui, repo, other): +def incoming(ui, repo, peer): '''Show bookmarks incoming from other to repo ''' ui.status(_("searching for changed bookmarks\n")) -remotemarks = unhexlifybookmarks(other.listkeys('bookmarks')) +with peer.commandexecutor() as e: +remotemarks = unhexlifybookmarks(e.callcommand('listkeys', { +'namespace': 'bookmarks', +}).result()) + r = comparebookmarks(repo, remotemarks, repo._bookmarks) addsrc, adddst, advsrc, advdst, diverge, differ, invalid, same = r @@ -733,12 +737,16 @@ return 0 -def summary(repo, other): +def summary(repo, peer): '''Compare bookmarks between repo and other for "hg summary" output This returns "(# of incoming, # of outgoing)" tuple. ''' -remotemarks = unhexlifybookmarks(other.listkeys('bookmarks')) +with peer.commandexecutor() as e: +remotemarks = unhexlifybookmarks(e.callcommand('listkeys', { +'namespace': 'bookmarks', +}).result()) + r = comparebookmarks(repo, remotemarks, repo._bookmarks) addsrc, adddst, advsrc, advdst, diverge, differ, invalid, same = r return (len(addsrc), len(adddst)) To: indygreg, #hg-reviewers, durin42 Cc: durin42, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3294: bundlerepo: use command executor for wire protocol commands
This revision was automatically updated to reflect the committed changes. Closed by commit rHG1aa4d646d0de: bundlerepo: use command executor for wire protocol commands (authored by indygreg, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3294?vs=8133=8179 REVISION DETAIL https://phab.mercurial-scm.org/D3294 AFFECTED FILES mercurial/bundlerepo.py CHANGE DETAILS diff --git a/mercurial/bundlerepo.py b/mercurial/bundlerepo.py --- a/mercurial/bundlerepo.py +++ b/mercurial/bundlerepo.py @@ -540,17 +540,26 @@ and peer.capable('getbundle') and peer.capable('bundle2')) if canbundle2: -kwargs = {} -kwargs[r'common'] = common -kwargs[r'heads'] = rheads -kwargs[r'bundlecaps'] = exchange.caps20to10(repo, role='client') -kwargs[r'cg'] = True -b2 = peer.getbundle('incoming', **kwargs) -fname = bundle = changegroup.writechunks(ui, b2._forwardchunks(), - bundlename) +with peer.commandexecutor() as e: +b2 = e.callcommand('getbundle', { +'source': 'incoming', +'common': common, +'heads': rheads, +'bundlecaps': exchange.caps20to10(repo, role='client'), +'cg': True, +}).result() + +fname = bundle = changegroup.writechunks(ui, + b2._forwardchunks(), + bundlename) else: if peer.capable('getbundle'): -cg = peer.getbundle('incoming', common=common, heads=rheads) +with peer.commandexecutor() as e: +cg = e.callcommand('getbundle', { +'source': 'incoming', +'common': common, +'heads': rheads, +}).result() elif onlyheads is None and not peer.capable('changegroupsubset'): # compat with older servers when pulling all remote heads @@ -594,7 +603,11 @@ if bundlerepo: reponodes = [ctx.node() for ctx in bundlerepo[bundlerepo.firstnewrev:]] -remotephases = peer.listkeys('phases') + +with peer.commandexecutor() as e: +remotephases = e.callcommand('listkeys', { +'namespace': 'phases', +}).result() pullop = exchange.pulloperation(bundlerepo, peer, heads=reponodes) pullop.trmanager = bundletransactionmanager() To: indygreg, #hg-reviewers, durin42 Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3293: bundlerepo: rename "other" to "peer"
This revision was automatically updated to reflect the committed changes. Closed by commit rHGd959277ff1b5: bundlerepo: rename other to peer (authored by indygreg, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3293?vs=8132=8178 REVISION DETAIL https://phab.mercurial-scm.org/D3293 AFFECTED FILES mercurial/bundlerepo.py CHANGE DETAILS diff --git a/mercurial/bundlerepo.py b/mercurial/bundlerepo.py --- a/mercurial/bundlerepo.py +++ b/mercurial/bundlerepo.py @@ -492,9 +492,9 @@ def release(self): raise NotImplementedError -def getremotechanges(ui, repo, other, onlyheads=None, bundlename=None, +def getremotechanges(ui, repo, peer, onlyheads=None, bundlename=None, force=False): -'''obtains a bundle of changes incoming from other +'''obtains a bundle of changes incoming from peer "onlyheads" restricts the returned changes to those reachable from the specified heads. @@ -507,62 +507,62 @@ "local" is a local repo from which to obtain the actual incoming changesets; it is a bundlerepo for the obtained bundle when the - original "other" is remote. + original "peer" is remote. "csets" lists the incoming changeset node ids. "cleanupfn" must be called without arguments when you're done processing - the changes; it closes both the original "other" and the one returned + the changes; it closes both the original "peer" and the one returned here. ''' -tmp = discovery.findcommonincoming(repo, other, heads=onlyheads, +tmp = discovery.findcommonincoming(repo, peer, heads=onlyheads, force=force) common, incoming, rheads = tmp if not incoming: try: if bundlename: os.unlink(bundlename) except OSError: pass -return repo, [], other.close +return repo, [], peer.close commonset = set(common) rheads = [x for x in rheads if x not in commonset] bundle = None bundlerepo = None -localrepo = other.local() +localrepo = peer.local() if bundlename or not localrepo: -# create a bundle (uncompressed if other repo is not local) +# create a bundle (uncompressed if peer repo is not local) # developer config: devel.legacy.exchange legexc = ui.configlist('devel', 'legacy.exchange') forcebundle1 = 'bundle2' not in legexc and 'bundle1' in legexc canbundle2 = (not forcebundle1 - and other.capable('getbundle') - and other.capable('bundle2')) + and peer.capable('getbundle') + and peer.capable('bundle2')) if canbundle2: kwargs = {} kwargs[r'common'] = common kwargs[r'heads'] = rheads kwargs[r'bundlecaps'] = exchange.caps20to10(repo, role='client') kwargs[r'cg'] = True -b2 = other.getbundle('incoming', **kwargs) +b2 = peer.getbundle('incoming', **kwargs) fname = bundle = changegroup.writechunks(ui, b2._forwardchunks(), bundlename) else: -if other.capable('getbundle'): -cg = other.getbundle('incoming', common=common, heads=rheads) -elif onlyheads is None and not other.capable('changegroupsubset'): +if peer.capable('getbundle'): +cg = peer.getbundle('incoming', common=common, heads=rheads) +elif onlyheads is None and not peer.capable('changegroupsubset'): # compat with older servers when pulling all remote heads -with other.commandexecutor() as e: +with peer.commandexecutor() as e: cg = e.callcommand('changegroup', { 'nodes': incoming, 'source': 'incoming', }).result() rheads = None else: -with other.commandexecutor() as e: +with peer.commandexecutor() as e: cg = e.callcommand('changegroupsubset', { 'bases': incoming, 'heads': rheads, @@ -582,7 +582,7 @@ # use the created uncompressed bundlerepo localrepo = bundlerepo = bundlerepository(repo.baseui, repo.root, fname) -# this repo contains local and other now, so filter out local again +# this repo contains local and peer now, so filter out local again common = repo.heads() if localrepo: # Part of common may be remotely filtered @@ -594,17 +594,17 @@ if bundlerepo: reponodes = [ctx.node() for ctx in bundlerepo[bundlerepo.firstnewrev:]] -remotephases
D3273: wireproto: convert legacy commands to command executor
This revision was automatically updated to reflect the committed changes. Closed by commit rHGcc8c06835097: wireproto: convert legacy commands to command executor (authored by indygreg, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3273?vs=8126=8171 REVISION DETAIL https://phab.mercurial-scm.org/D3273 AFFECTED FILES mercurial/bundlerepo.py mercurial/exchange.py mercurial/localrepo.py mercurial/repository.py mercurial/wireprotov1peer.py tests/test-check-interfaces.py CHANGE DETAILS diff --git a/tests/test-check-interfaces.py b/tests/test-check-interfaces.py --- a/tests/test-check-interfaces.py +++ b/tests/test-check-interfaces.py @@ -89,8 +89,7 @@ checkzobject(badpeer()) -ziverify.verifyClass(repository.ipeerbaselegacycommands, - httppeer.httppeer) +ziverify.verifyClass(repository.ipeerbase, httppeer.httppeer) checkzobject(httppeer.httppeer(None, None, None, dummyopener(), None, None)) ziverify.verifyClass(repository.ipeerconnection, @@ -111,13 +110,11 @@ wireprotov1peer.peerexecutor) checkzobject(wireprotov1peer.peerexecutor(None)) -ziverify.verifyClass(repository.ipeerbaselegacycommands, - sshpeer.sshv1peer) +ziverify.verifyClass(repository.ipeerbase, sshpeer.sshv1peer) checkzobject(sshpeer.sshv1peer(ui, 'ssh://localhost/foo', None, dummypipe(), dummypipe(), None, None)) -ziverify.verifyClass(repository.ipeerbaselegacycommands, - sshpeer.sshv2peer) +ziverify.verifyClass(repository.ipeerbase, sshpeer.sshv2peer) checkzobject(sshpeer.sshv2peer(ui, 'ssh://localhost/foo', None, dummypipe(), dummypipe(), None, None)) diff --git a/mercurial/wireprotov1peer.py b/mercurial/wireprotov1peer.py --- a/mercurial/wireprotov1peer.py +++ b/mercurial/wireprotov1peer.py @@ -308,7 +308,8 @@ else: f.set_result(result) -class wirepeer(repository.legacypeer): +@zi.implementer(repository.ipeerlegacycommands) +class wirepeer(repository.peer): """Client-side interface for communicating with a peer repository. Methods commonly call wire protocol commands of the same name. @@ -502,12 +503,12 @@ self._abort(error.ResponseError(_("unexpected response:"), d)) return r -def changegroup(self, nodes, kind): +def changegroup(self, nodes, source): n = wireprototypes.encodelist(nodes) f = self._callcompressable("changegroup", roots=n) return changegroupmod.cg1unpacker(f, 'UN') -def changegroupsubset(self, bases, heads, kind): +def changegroupsubset(self, bases, heads, source): self.requirecap('changegroupsubset', _('look up remote changes')) bases = wireprototypes.encodelist(bases) heads = wireprototypes.encodelist(heads) diff --git a/mercurial/repository.py b/mercurial/repository.py --- a/mercurial/repository.py +++ b/mercurial/repository.py @@ -190,10 +190,10 @@ Returns an iterable of iterables with the resolved values for each node. """ -def changegroup(nodes, kind): +def changegroup(nodes, source): """Obtain a changegroup with data for descendants of specified nodes.""" -def changegroupsubset(bases, heads, kind): +def changegroupsubset(bases, heads, source): pass class ipeercommandexecutor(zi.Interface): @@ -285,9 +285,6 @@ All peer instances must conform to this interface. """ -class ipeerbaselegacycommands(ipeerbase, ipeerlegacycommands): -"""Unified peer interface that supports legacy commands.""" - @zi.implementer(ipeerbase) class peer(object): """Base class for peer repositories.""" @@ -312,10 +309,6 @@ _('cannot %s; remote repository does not support the %r ' 'capability') % (purpose, name)) -@zi.implementer(ipeerbaselegacycommands) -class legacypeer(peer): -"""peer but with support for legacy wire protocol commands.""" - class ifilerevisionssequence(zi.Interface): """Contains index data for all revisions of a file. diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -320,7 +320,8 @@ # End of peer interface. -class locallegacypeer(repository.legacypeer, localpeer): +@zi.implementer(repository.ipeerlegacycommands) +class locallegacypeer(localpeer): '''peer extension which implements legacy methods too; used for tests with restricted capabilities''' @@ -335,8 +336,8 @@ def branches(self, nodes): return self._repo.branches(nodes) -def changegroup(self, basenodes, source): -outgoing = discovery.outgoing(self._repo, missingroots=basenodes, +def changegroup(self, nodes, source): +outgoing = discovery.outgoing(self._repo,
D3287: discovery: don't redundantly call branchmap
This revision was automatically updated to reflect the committed changes. Closed by commit rHG330ada7e8ea5: discovery: dont redundantly call branchmap (authored by indygreg, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3287?vs=8080=8172 REVISION DETAIL https://phab.mercurial-scm.org/D3287 AFFECTED FILES mercurial/discovery.py tests/test-http-bundle1.t tests/test-http.t tests/test-treediscovery.t CHANGE DETAILS diff --git a/tests/test-treediscovery.t b/tests/test-treediscovery.t --- a/tests/test-treediscovery.t +++ b/tests/test-treediscovery.t @@ -537,7 +537,6 @@ "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull "GET /?cmd=branchmap HTTP/1.1" 200 - x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull - "GET /?cmd=branchmap HTTP/1.1" 200 - x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull "POST /?cmd=unbundle HTTP/1.1" 200 - x-hgarg-1:heads=686173686564+1827a5bb63e602382eb89dd58f2ac9f3b007ad91* (glob) "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull diff --git a/tests/test-http.t b/tests/test-http.t --- a/tests/test-http.t +++ b/tests/test-http.t @@ -296,11 +296,6 @@ devel-peer-request: Vary X-HgProto-1 devel-peer-request: X-hgproto-1 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull devel-peer-request: finished in *. seconds (200) (glob) - sending branchmap command - devel-peer-request: GET http://localhost:$HGPORT2/?cmd=branchmap - devel-peer-request: Vary X-HgProto-1 - devel-peer-request: X-hgproto-1 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull - devel-peer-request: finished in *. seconds (200) (glob) preparing listkeys for "bookmarks" sending listkeys command devel-peer-request: GET http://localhost:$HGPORT2/?cmd=listkeys @@ -395,7 +390,6 @@ "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull "GET /?cmd=branchmap HTTP/1.1" 200 - x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull - "GET /?cmd=branchmap HTTP/1.1" 200 - x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull "POST /?cmd=unbundle HTTP/1.1" 200 - x-hgarg-1:heads=666f726365* (glob) "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull @@ -405,7 +399,6 @@ "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull "GET /?cmd=branchmap HTTP/1.1" 200 - x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull - "GET /?cmd=branchmap HTTP/1.1" 200 - x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull "POST /?cmd=unbundle HTTP/1.1" 200 - x-hgarg-1:heads=666f726365 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull diff --git a/tests/test-http-bundle1.t b/tests/test-http-bundle1.t --- a/tests/test-http-bundle1.t +++ b/tests/test-http-bundle1.t @@ -316,7 +316,6 @@ "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull "GET /?cmd=branchmap HTTP/1.1" 200 - x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull - "GET /?cmd=branchmap HTTP/1.1" 200 - x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull "POST /?cmd=unbundle HTTP/1.1" 200 - x-hgarg-1:heads=686173686564+5eb5abfefeea63c80dd7553bcc3783f37e0c5524* (glob) "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull diff --git a/mercurial/discovery.py b/mercurial/discovery.py --- a/mercurial/discovery.py +++ b/mercurial/discovery.py @@ -209,7 +209,7 @@ #
D3291: hg: use command executor for wire protocol commands
This revision was automatically updated to reflect the committed changes. Closed by commit rHGce8828217369: hg: use command executor for wire protocol commands (authored by indygreg, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3291?vs=8130=8176 REVISION DETAIL https://phab.mercurial-scm.org/D3291 AFFECTED FILES mercurial/hg.py CHANGE DETAILS diff --git a/mercurial/hg.py b/mercurial/hg.py --- a/mercurial/hg.py +++ b/mercurial/hg.py @@ -81,7 +81,9 @@ raise error.Abort(_("remote branch lookup not supported")) revs.append(hashbranch) return revs, revs[0] -branchmap = peer.branchmap() + +with peer.commandexecutor() as e: +branchmap = e.callcommand('branchmap', {}).result() def primary(branch): if branch == '.': @@ -421,7 +423,15 @@ raise error.Abort(_("src repository does not support " "revision lookup and so doesn't " "support clone by revision")) -revs = [srcpeer.lookup(r) for r in rev] + +# TODO this is batchable. +remoterevs = [] +for r in rev: +with srcpeer.commandexecutor() as e: +remoterevs.append(e.callcommand('lookup', { +'key': r, +}).result()) +revs = remoterevs # Obtain a lock before checking for or cloning the pooled repo otherwise # 2 clients may race creating or populating it. @@ -567,7 +577,11 @@ # raises RepoLookupError if revision 0 is filtered or otherwise # not available. If we fail to resolve, sharing is not enabled. try: -rootnode = srcpeer.lookup('0') +with srcpeer.commandexecutor() as e: +rootnode = e.callcommand('lookup', { +'key': '0', +}).result() + if rootnode != node.nullid: sharepath = os.path.join(sharepool, node.hex(rootnode)) else: @@ -663,7 +677,16 @@ raise error.Abort(_("src repository does not support " "revision lookup and so doesn't " "support clone by revision")) -revs = [srcpeer.lookup(r) for r in revs] + +# TODO this is batchable. +remoterevs = [] +for rev in revs: +with srcpeer.commandexecutor() as e: +remoterevs.append(e.callcommand('lookup', { +'key': rev, +}).result()) +revs = remoterevs + checkout = revs[0] else: revs = None @@ -705,7 +728,11 @@ if update: if update is not True: -checkout = srcpeer.lookup(update) +with srcpeer.commandexecutor() as e: +checkout = e.callcommand('lookup', { +'key': update, +}).result() + uprev = None status = None if checkout is not None: To: indygreg, #hg-reviewers, durin42 Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3272: treediscovery: switch to command executor interface
This revision was automatically updated to reflect the committed changes. Closed by commit rHG0ed11f9368fd: treediscovery: switch to command executor interface (authored by indygreg, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3272?vs=8125=8170 REVISION DETAIL https://phab.mercurial-scm.org/D3272 AFFECTED FILES mercurial/treediscovery.py CHANGE DETAILS diff --git a/mercurial/treediscovery.py b/mercurial/treediscovery.py --- a/mercurial/treediscovery.py +++ b/mercurial/treediscovery.py @@ -36,7 +36,8 @@ base = set() if not heads: -heads = remote.heads() +with remote.commandexecutor() as e: +heads = e.callcommand('heads', {}).result() if repo.changelog.tip() == nullid: base.add(nullid) @@ -65,7 +66,10 @@ # a 'branch' here is a linear segment of history, with four parts: # head, root, first parent, second parent # (a branch always has two parents (or none) by definition) -unknown = collections.deque(remote.branches(unknown)) +with remote.commandexecutor() as e: +branches = e.callcommand('branches', {'nodes': unknown}).result() + +unknown = collections.deque(branches) while unknown: r = [] while unknown: @@ -107,7 +111,12 @@ repo.ui.debug("request %d: %s\n" % (reqcnt, " ".join(map(short, r for p in xrange(0, len(r), 10): -for b in remote.branches(r[p:p + 10]): +with remote.commandexecutor() as e: +branches = e.callcommand('branches', { +'nodes': r[p:p + 10], +}).result() + +for b in branches: repo.ui.debug("received %s:%s\n" % (short(b[0]), short(b[1]))) unknown.append(b) @@ -117,7 +126,11 @@ newsearch = [] reqcnt += 1 repo.ui.progress(_('searching'), reqcnt, unit=_('queries')) -for n, l in zip(search, remote.between(search)): + +with remote.commandexecutor() as e: +between = e.callcommand('between', {'pairs': search}).result() + +for n, l in zip(search, between): l.append(n[1]) p = n[0] f = 1 To: indygreg, #hg-reviewers, durin42 Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3288: discovery: use command executor interface
This revision was automatically updated to reflect the committed changes. Closed by commit rHG1964d2d1f421: discovery: use command executor interface (authored by indygreg, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3288?vs=8127=8173 REVISION DETAIL https://phab.mercurial-scm.org/D3288 AFFECTED FILES mercurial/discovery.py CHANGE DETAILS diff --git a/mercurial/discovery.py b/mercurial/discovery.py --- a/mercurial/discovery.py +++ b/mercurial/discovery.py @@ -203,7 +203,10 @@ headssum = {} # A. Create set of branches involved in the push. branches = set(repo[n].branch() for n in outgoing.missing) -remotemap = remote.branchmap() + +with remote.commandexecutor() as e: +remotemap = e.callcommand('branchmap', {}).result() + newbranches = branches - set(remotemap) branches.difference_update(newbranches) @@ -287,7 +290,12 @@ repo = pushop.repo.unfiltered() remote = pushop.remote localbookmarks = repo._bookmarks -remotebookmarks = remote.listkeys('bookmarks') + +with remote.commandexecutor() as e: +remotebookmarks = e.callcommand('listkeys', { +'namespace': 'bookmarks', +}).result() + bookmarkedheads = set() # internal config: bookmarks.pushing To: indygreg, #hg-reviewers, durin42 Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3318: repository: remove ipeercommands from ipeerbase
indygreg added a comment. In https://phab.mercurial-scm.org/D3318#53227, @durin42 wrote: > I think we should probably avoid breaking that API until after we get remotefilelog in core? That'd at least be nice for me, because RFL is pretty invasive proto-wise. :( I have little desire to purge this until at least next release. Minimal gains from it. Wins come from core and new peers being able to use new API. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3318 To: indygreg, #hg-reviewers, durin42 Cc: durin42, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 1 of 5] test-lfs: add tests to force server error path coverage
# HG changeset patch # User Matt Harbison# Date 1523119701 14400 # Sat Apr 07 12:48:21 2018 -0400 # Node ID 1d394ac0efd4aa4f61f428fbac140fe57398f0b8 # Parent bfdd20d22a86edc318493b4da84a1d7ff4ef98f2 test-lfs: add tests to force server error path coverage The tests are somewhat fragile in that the extension that forces the errors is counting how many times some of the functions are being called, so it depends heavily on the content of the repo. Maybe we can do something clever like load an extension on the client, and have it send over instructions in the HTTP header how to fail. (I'm trying to avoid killing and restarting the server, because Windows seems to have issues with doing that a lot.) But I'd rather fix issues than polish tests before the freeze. diff --git a/tests/test-lfs-serve-access.t b/tests/test-lfs-serve-access.t --- a/tests/test-lfs-serve-access.t +++ b/tests/test-lfs-serve-access.t @@ -4,7 +4,6 @@ > [extensions] > lfs= > [lfs] - > url=http://localhost:$HGPORT/.git/info/lfs > track=all() > [web] > push_ssl = False @@ -149,3 +148,189 @@ Blob URIs are correct when --prefix is u $LOCALIP - - [$LOGDATE$] "GET /subdir/mount/point?cmd=getbundle HTTP/1.1" 200 - x-hgarg-1:bookmarks=1=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%252C03%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Aphases%253Dheads%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps%250Arev-branch-cache%250Astream%253Dv2=1==525251863cad618e55d483555f3d00a2ca99597e=bookmarks=1 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob) $LOCALIP - - [$LOGDATE$] "POST /subdir/mount/point/.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob) $LOCALIP - - [$LOGDATE$] "GET /subdir/mount/point/.hg/lfs/objects/f03217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e HTTP/1.1" 200 - (glob) + + $ cat >> $TESTTMP/lfsstoreerror.py < import errno + > from hgext.lfs import blobstore + > + > _numverifies = 0 + > _readerr = True + > + > def reposetup(ui, repo): + > # Nothing to do with a remote repo + > if not repo.local(): + > return + > + > store = repo.svfs.lfslocalblobstore + > class badstore(store.__class__): + > def download(self, oid, src): + > '''Called in the server to handle reading from the client in a + > PUT request.''' + > origread = src.read + > def _badread(nbytes): + > # Simulate bad data/checksum failure from the client + > return b'0' * len(origread(nbytes)) + > src.read = _badread + > super(badstore, self).download(oid, src) + > + > def _read(self, vfs, oid, verify): + > '''Called in the server to read data for a GET request, and then + > calls self._verify() on it before returning.''' + > global _readerr + > # One time simulation of a read error + > if _readerr: + > _readerr = False + > raise IOError(errno.EIO, '%s: I/O error' % oid) + > # Simulate corrupt content on client download + > blobstore._verify(oid, 'dummy content') + > + > def verify(self, oid): + > '''Called in the server to populate the Batch API response, + > letting the client re-upload if the file is corrupt.''' + > # Fail verify in Batch API for one clone command and one push + > # command with an IOError. Then let it through to access other + > # functions. Checksum failure is tested elsewhere. + > global _numverifies + > _numverifies += 1 + > if _numverifies <= 2: + > raise IOError(errno.EIO, '%s: I/O error' % oid) + > return super(badstore, self).verify(oid) + > + > store.__class__ = badstore + > EOF + + $ rm -rf `hg config lfs.usercache` + $ rm -f $TESTTMP/access.log $TESTTMP/errors.log + $ hg --config "lfs.usercache=$TESTTMP/servercache" \ + >--config extensions.lfsstoreerror=$TESTTMP/lfsstoreerror.py \ + >-R server serve -d \ + >-p $HGPORT1 --pid-file=hg.pid -A $TESTTMP/access.log -E $TESTTMP/errors.log + $ cat hg.pid >> $DAEMON_PIDS + +Test an I/O error in localstore.verify() (Batch API) with GET + + $ hg clone http://localhost:$HGPORT1 httpclone2 + requesting all changes + adding changesets + adding manifests + adding file changes + added 1 changesets with 1 changes to 1 files + new changesets 525251863cad + updating to branch default + abort: LFS server error for "lfs.bin": Internal server error! + [255] + +Test an I/O error in localstore.verify() (Batch API) with PUT + + $ echo foo > client/lfs.bin + $ hg -R client ci -m 'mod lfs' + $
[PATCH 5 of 5] lfs: update the HTTP status codes in error cases
# HG changeset patch # User Matt Harbison# Date 1523651553 14400 # Fri Apr 13 16:32:33 2018 -0400 # Node ID f7f3443324c9ebcb065bebedfd54d4167eb673d4 # Parent b795b3f8eca0aa917b10612dc95d46dee8ee7972 lfs: update the HTTP status codes in error cases I'm not bothering with validating PUT requests (for now), because the spec doesn't explicitly call out a Content-Type (though the example transcript does use the sensible 'application/octet-stream'). diff --git a/hgext/lfs/wireprotolfsserver.py b/hgext/lfs/wireprotolfsserver.py --- a/hgext/lfs/wireprotolfsserver.py +++ b/hgext/lfs/wireprotolfsserver.py @@ -26,6 +26,9 @@ HTTP_OK = hgwebcommon.HTTP_OK HTTP_CREATED = hgwebcommon.HTTP_CREATED HTTP_BAD_REQUEST = hgwebcommon.HTTP_BAD_REQUEST HTTP_NOT_FOUND = hgwebcommon.HTTP_NOT_FOUND +HTTP_METHOD_NOT_ALLOWED = hgwebcommon.HTTP_METHOD_NOT_ALLOWED +HTTP_NOT_ACCEPTABLE = hgwebcommon.HTTP_NOT_ACCEPTABLE +HTTP_UNSUPPORTED_MEDIA_TYPE = hgwebcommon.HTTP_UNSUPPORTED_MEDIA_TYPE def handlewsgirequest(orig, rctx, req, res, checkperm): """Wrap wireprotoserver.handlewsgirequest() to possibly process an LFS @@ -109,12 +112,16 @@ def _processbatchrequest(repo, req, res) # "operation": "upload" # } -if (req.method != b'POST' -or req.headers[b'Content-Type'] != b'application/vnd.git-lfs+json' -or req.headers[b'Accept'] != b'application/vnd.git-lfs+json'): -# TODO: figure out what the proper handling for a bad request to the -# Batch API is. -_sethttperror(res, HTTP_BAD_REQUEST, b'Invalid Batch API request') +if req.method != b'POST': +_sethttperror(res, HTTP_METHOD_NOT_ALLOWED) +return True + +if req.headers[b'Content-Type'] != b'application/vnd.git-lfs+json': +_sethttperror(res, HTTP_UNSUPPORTED_MEDIA_TYPE) +return True + +if req.headers[b'Accept'] != b'application/vnd.git-lfs+json': +_sethttperror(res, HTTP_NOT_ACCEPTABLE) return True # XXX: specify an encoding? @@ -319,6 +326,6 @@ def _processbasictransfer(repo, req, res return True else: -_sethttperror(res, HTTP_BAD_REQUEST, +_sethttperror(res, HTTP_METHOD_NOT_ALLOWED, message=b'Unsupported LFS transfer method: %s' % method) return True diff --git a/mercurial/hgweb/common.py b/mercurial/hgweb/common.py --- a/mercurial/hgweb/common.py +++ b/mercurial/hgweb/common.py @@ -30,6 +30,8 @@ HTTP_UNAUTHORIZED = 401 HTTP_FORBIDDEN = 403 HTTP_NOT_FOUND = 404 HTTP_METHOD_NOT_ALLOWED = 405 +HTTP_NOT_ACCEPTABLE = 406 +HTTP_UNSUPPORTED_MEDIA_TYPE = 415 HTTP_SERVER_ERROR = 500 ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 3 of 5] lfs: fix the inferred remote store path when using a --prefix
# HG changeset patch # User Matt Harbison# Date 1523643390 14400 # Fri Apr 13 14:16:30 2018 -0400 # Node ID a4c12789ef4bac6e736681ef8a08ccbe71fb5c41 # Parent 54c1ab20ed7fbf415d087e6e94ca273d172046e8 lfs: fix the inferred remote store path when using a --prefix This wasn't appending the '.git/info/lfs' path in this case. diff --git a/hgext/lfs/blobstore.py b/hgext/lfs/blobstore.py --- a/hgext/lfs/blobstore.py +++ b/hgext/lfs/blobstore.py @@ -561,7 +561,7 @@ def remote(repo, remote=None): if defaulturl.scheme in (b'http', b'https'): if defaulturl.path and defaulturl.path[:-1] != b'/': defaulturl.path += b'/' -defaulturl.path = defaulturl.path or b'' + b'.git/info/lfs' +defaulturl.path = (defaulturl.path or b'') + b'.git/info/lfs' url = util.url(bytes(defaulturl)) repo.ui.note(_('lfs: assuming remote store: %s\n') % url) diff --git a/tests/test-lfs-serve-access.t b/tests/test-lfs-serve-access.t --- a/tests/test-lfs-serve-access.t +++ b/tests/test-lfs-serve-access.t @@ -73,8 +73,7 @@ Blob URIs are correct when --prefix is u >-A $TESTTMP/access.log -E $TESTTMP/errors.log $ cat hg.pid >> $DAEMON_PIDS - $ hg --config lfs.url=http://localhost:$HGPORT/subdir/mount/point/.git/info/lfs \ - >clone --debug http://localhost:$HGPORT/subdir/mount/point cloned2 + $ hg clone --debug http://localhost:$HGPORT/subdir/mount/point cloned2 using http://localhost:$HGPORT/subdir/mount/point sending capabilities command query 1; heads @@ -104,6 +103,7 @@ Blob URIs are correct when --prefix is u resolving manifests branchmerge: False, force: False, partial: False ancestor: , local: +, remote: 525251863cad + lfs: assuming remote store: http://localhost:$HGPORT/subdir/mount/point/.git/info/lfs Status: 200 Content-Length: 371 Content-Type: application/vnd.git-lfs+json ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 4 of 5] lfs: gracefully handle aborts on the server when corrupt blobs are detected
# HG changeset patch # User Matt Harbison# Date 1519585633 18000 # Sun Feb 25 14:07:13 2018 -0500 # Node ID b795b3f8eca0aa917b10612dc95d46dee8ee7972 # Parent a4c12789ef4bac6e736681ef8a08ccbe71fb5c41 lfs: gracefully handle aborts on the server when corrupt blobs are detected The aborts weren't killing the server, but this seems cleaner. I'm not sure if it matters to handle the remaining IOError in the test like this, for consistency. The error code still feels wrong (especially if the client is trying to download a corrupt blob) but I don't see anything better in the RFCs, and this is already used elsewhere because the Batch API spec specifically mentioned this as a "Validation Error". diff --git a/hgext/lfs/blobstore.py b/hgext/lfs/blobstore.py --- a/hgext/lfs/blobstore.py +++ b/hgext/lfs/blobstore.py @@ -152,7 +152,8 @@ class local(object): realoid = sha256.hexdigest() if realoid != oid: -raise error.Abort(_('corrupt remote lfs object: %s') % oid) +raise LfsCorruptionError(_('corrupt remote lfs object: %s') + % oid) self._linktousercache(oid) @@ -526,8 +527,8 @@ def _deduplicate(pointers): def _verify(oid, content): realoid = hashlib.sha256(content).hexdigest() if realoid != oid: -raise error.Abort(_('detected corrupt lfs object: %s') % oid, - hint=_('run hg verify')) +raise LfsCorruptionError(_('detected corrupt lfs object: %s') % oid, + hint=_('run hg verify')) def remote(repo, remote=None): """remotestore factory. return a store in _storemap depending on config @@ -573,3 +574,8 @@ def remote(repo, remote=None): class LfsRemoteError(error.RevlogError): pass + +class LfsCorruptionError(error.Abort): +"""Raised when a corrupt blob is detected, aborting an operation + +It exists to allow specialized handling on the server side.""" diff --git a/hgext/lfs/wireprotolfsserver.py b/hgext/lfs/wireprotolfsserver.py --- a/hgext/lfs/wireprotolfsserver.py +++ b/hgext/lfs/wireprotolfsserver.py @@ -20,6 +20,8 @@ from mercurial import ( pycompat, ) +from . import blobstore + HTTP_OK = hgwebcommon.HTTP_OK HTTP_CREATED = hgwebcommon.HTTP_CREATED HTTP_BAD_REQUEST = hgwebcommon.HTTP_BAD_REQUEST @@ -280,13 +282,15 @@ def _processbasictransfer(repo, req, res # Content-Length, but what happens if a client sends less than it # says it will? -# TODO: download() will abort if the checksum fails. It should raise -# something checksum specific that can be caught here, and turned -# into an http code. -localstore.download(oid, req.bodyfh) +statusmessage = hgwebcommon.statusmessage +try: +localstore.download(oid, req.bodyfh) +res.status = statusmessage(HTTP_OK if existed else HTTP_CREATED) +except blobstore.LfsCorruptionError: +_logexception(req) -statusmessage = hgwebcommon.statusmessage -res.status = statusmessage(HTTP_OK if existed else HTTP_CREATED) +# XXX: Is this the right code? +res.status = statusmessage(422, b'corrupt blob') # There's no payload here, but this is the header that lfs-test-server # sends back. This eliminates some gratuitous test output conditionals. @@ -300,9 +304,18 @@ def _processbasictransfer(repo, req, res res.status = hgwebcommon.statusmessage(HTTP_OK) res.headers[b'Content-Type'] = b'application/octet-stream' -# TODO: figure out how to send back the file in chunks, instead of -# reading the whole thing. -res.setbodybytes(localstore.read(oid)) +try: +# TODO: figure out how to send back the file in chunks, instead of +# reading the whole thing. (Also figure out how to send back +# an error status if an IOError occurs after a partial write +# in that case. Here, everything is read before starting.) +res.setbodybytes(localstore.read(oid)) +except blobstore.LfsCorruptionError: +_logexception(req) + +# XXX: Is this the right code? +res.status = hgwebcommon.statusmessage(422, b'corrupt blob') +res.setbodybytes(b'') return True else: diff --git a/tests/test-lfs-serve-access.t b/tests/test-lfs-serve-access.t --- a/tests/test-lfs-serve-access.t +++ b/tests/test-lfs-serve-access.t @@ -236,7 +236,7 @@ Test a bad checksum sent by the client i $ hg -R client push http://localhost:$HGPORT1 pushing to http://localhost:$HGPORT1/ searching for changes - abort: HTTP error: HTTP Error 500: Internal Server Error (oid=b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c, action=upload)! + abort: HTTP error: HTTP Error 422: corrupt
[PATCH 2 of 5] lfs: log information about Internal Server Errors reported in the Batch API
# HG changeset patch # User Matt Harbison# Date 1523637594 14400 # Fri Apr 13 12:39:54 2018 -0400 # Node ID 54c1ab20ed7fbf415d087e6e94ca273d172046e8 # Parent 1d394ac0efd4aa4f61f428fbac140fe57398f0b8 lfs: log information about Internal Server Errors reported in the Batch API Reporting a 500 and then not leaving any traces on the server seems like a receipe for frustration. The log writing was cargoculted from do_POST() in hgweb.server. That doesn't write directly to the wsgi.errors object, so it doesn't seem worth trying to refactor. It does seem like earlier stack frames are missing for some reason. diff --git a/hgext/lfs/wireprotolfsserver.py b/hgext/lfs/wireprotolfsserver.py --- a/hgext/lfs/wireprotolfsserver.py +++ b/hgext/lfs/wireprotolfsserver.py @@ -10,6 +10,7 @@ from __future__ import absolute_import import datetime import errno import json +import traceback from mercurial.hgweb import ( common as hgwebcommon, @@ -63,6 +64,23 @@ def _sethttperror(res, code, message=Non res.headers[b'Content-Type'] = b'text/plain; charset=utf-8' res.setbodybytes(b'') +def _logexception(req): +"""Write information about the current exception to wsgi.errors.""" +tb = traceback.format_exc() +# We need a native-string newline to poke in the log +# message, because we won't get a newline when using an +# r-string. This is the easy way out. +newline = chr(10) +errorlog = req.rawenv[r'wsgi.errors'] + +uri = '' +if req.apppath: +uri += req.apppath +uri += b'/' + req.dispatchpath + +errorlog.write(r"Exception happened while processing request " + r"'%s':%s%s" % (uri.decode('latin-1'), newline, tb)) + def _processbatchrequest(repo, req, res): """Handle a request for the Batch API, which is the gateway to granting file access. @@ -179,6 +197,8 @@ def _batchresponseobjects(req, objects, verifies = store.verify(oid) except IOError as inst: if inst.errno != errno.ENOENT: +_logexception(req) + rsp['error'] = { 'code': 500, 'message': inst.strerror or 'Internal Server Server' diff --git a/tests/test-lfs-serve-access.t b/tests/test-lfs-serve-access.t --- a/tests/test-lfs-serve-access.t +++ b/tests/test-lfs-serve-access.t @@ -291,6 +291,18 @@ Test a checksum failure during the proce $LOCALIP - - [$LOGDATE$] "GET /.hg/lfs/objects/276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d HTTP/1.1" 500 - (glob) $ grep -v ' File "' $TESTTMP/errors.log + $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: raise IOError(errno.EIO, '%s: I/O error' % oid) (glob) + $LOCALIP - - [$ERRDATE$] HG error: IOError: [Errno 5] 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: raise IOError(errno.EIO, '%s: I/O error' % oid) (glob) + $LOCALIP - - [$ERRDATE$] HG error: IOError: [Errno 5] b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c: I/O error (glob) + $LOCALIP - - [$ERRDATE$] HG error: (glob) $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/.hg/lfs/objects/b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c': (glob) Traceback (most recent call last): self.do_write() ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3318: repository: remove ipeercommands from ipeerbase
durin42 added a comment. I think we should probably avoid breaking that API until after we get remotefilelog in core? That'd at least be nice for me, because RFL is pretty invasive proto-wise. :( REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3318 To: indygreg, #hg-reviewers Cc: durin42, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3271: wireproto: remove iterbatch() from peer interface (API)
This revision was automatically updated to reflect the committed changes. Closed by commit rHG33a6eee08db2: wireproto: remove iterbatch() from peer interface (API) (authored by indygreg, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3271?vs=8124=8169 REVISION DETAIL https://phab.mercurial-scm.org/D3271 AFFECTED FILES mercurial/localrepo.py mercurial/repository.py mercurial/wireprotov1peer.py tests/test-batching.py tests/test-batching.py.out tests/test-wireproto.py CHANGE DETAILS diff --git a/tests/test-wireproto.py b/tests/test-wireproto.py --- a/tests/test-wireproto.py +++ b/tests/test-wireproto.py @@ -93,7 +93,9 @@ clt = clientpeer(srv, uimod.ui()) print(clt.greet(b"Foobar")) -b = clt.iterbatch() -list(map(b.greet, (b'Fo, =;:
D3268: wireproto: implement command executor interface for version 1 peers
This revision was automatically updated to reflect the committed changes. Closed by commit rHGe1b32dc4646c: wireproto: implement command executor interface for version 1 peers (authored by indygreg, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3268?vs=8121=8167 REVISION DETAIL https://phab.mercurial-scm.org/D3268 AFFECTED FILES mercurial/localrepo.py mercurial/repository.py mercurial/setdiscovery.py mercurial/wireprotov1peer.py tests/test-check-interfaces.py CHANGE DETAILS diff --git a/tests/test-check-interfaces.py b/tests/test-check-interfaces.py --- a/tests/test-check-interfaces.py +++ b/tests/test-check-interfaces.py @@ -23,6 +23,7 @@ vfs as vfsmod, wireprotoserver, wireprototypes, +wireprotov1peer, wireprotov2server, ) @@ -102,6 +103,14 @@ localrepo.localpeer) checkzobject(localrepo.localpeer(dummyrepo())) +ziverify.verifyClass(repository.ipeercommandexecutor, + localrepo.localcommandexecutor) +checkzobject(localrepo.localcommandexecutor(None)) + +ziverify.verifyClass(repository.ipeercommandexecutor, + wireprotov1peer.peerexecutor) +checkzobject(wireprotov1peer.peerexecutor(None)) + ziverify.verifyClass(repository.ipeerbaselegacycommands, sshpeer.sshv1peer) checkzobject(sshpeer.sshv1peer(ui, 'ssh://localhost/foo', None, dummypipe(), diff --git a/mercurial/wireprotov1peer.py b/mercurial/wireprotov1peer.py --- a/mercurial/wireprotov1peer.py +++ b/mercurial/wireprotov1peer.py @@ -8,12 +8,15 @@ from __future__ import absolute_import import hashlib +import sys from .i18n import _ from .node import ( bin, ) - +from .thirdparty.zope import ( +interface as zi, +) from . import ( bundle2, changegroup as changegroupmod, @@ -177,14 +180,104 @@ return ';'.join(cmds) +@zi.implementer(repository.ipeercommandexecutor) +class peerexecutor(object): +def __init__(self, peer): +self._peer = peer +self._sent = False +self._closed = False +self._calls = [] + +def __enter__(self): +return self + +def __exit__(self, exctype, excvalee, exctb): +self.close() + +def callcommand(self, command, args): +if self._sent: +raise error.ProgrammingError('callcommand() cannot be used ' + 'after commands are sent') + +if self._closed: +raise error.ProgrammingError('callcommand() cannot be used ' + 'after close()') + +# Commands are dispatched through methods on the peer. +fn = getattr(self._peer, pycompat.sysstr(command), None) + +if not fn: +raise error.ProgrammingError( +'cannot call command %s: method of same name not available ' +'on peer' % command) + +# Commands are either batchable or they aren't. If a command +# isn't batchable, we send it immediately because the executor +# can no longer accept new commands after a non-batchable command. +# If a command is batchable, we queue it for later. + +if getattr(fn, 'batchable', False): +pass +else: +if self._calls: +raise error.ProgrammingError( +'%s is not batchable and cannot be called on a command ' +'executor along with other commands' % command) + +# We don't support batching yet. So resolve it immediately. +f = pycompat.futures.Future() +self._calls.append((command, args, fn, f)) +self.sendcommands() +return f + +def sendcommands(self): +if self._sent: +return + +if not self._calls: +return + +self._sent = True + +calls = self._calls +# Mainly to destroy references to futures. +self._calls = None + +if len(calls) == 1: +command, args, fn, f = calls[0] + +# Future was cancelled. Ignore it. +if not f.set_running_or_notify_cancel(): +return + +try: +result = fn(**pycompat.strkwargs(args)) +except Exception: +f.set_exception_info(*sys.exc_info()[1:]) +else: +f.set_result(result) + +return + +raise error.ProgrammingError('support for multiple commands not ' + 'yet implemented') + +def close(self): +self.sendcommands() + +self._closed = True + class wirepeer(repository.legacypeer): """Client-side interface for communicating with a peer repository. Methods commonly call wire protocol commands of the same name. See also httppeer.py and sshpeer.py for protocol-specific implementations of
D3270: largefiles: use command executor for batch operation
This revision was automatically updated to reflect the committed changes. Closed by commit rHG6c55ce51d6c3: largefiles: use command executor for batch operation (authored by indygreg, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3270?vs=8123=8168 REVISION DETAIL https://phab.mercurial-scm.org/D3270 AFFECTED FILES hgext/largefiles/wirestore.py tests/test-largefiles-wireproto.t CHANGE DETAILS diff --git a/tests/test-largefiles-wireproto.t b/tests/test-largefiles-wireproto.t --- a/tests/test-largefiles-wireproto.t +++ b/tests/test-largefiles-wireproto.t @@ -312,7 +312,7 @@ getting changed largefiles using http://localhost:$HGPORT2/ sending capabilities command - sending batch command + sending statlfile command getting largefiles: 0/1 files (0.00%) getting f1:02a439e5c31c526465ab1a0ca1f431f76b827b90 sending getlfile command @@ -400,7 +400,7 @@ searching 3 changesets for largefiles verified existence of 3 revisions of 3 largefiles $ tail -1 access.log - $LOCALIP - - [$LOGDATE$] "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=statlfile+sha%3Dc8559c3c9cfb42131794b7d8009230403b9b454c x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob) + $LOCALIP - - [$LOGDATE$] "GET /?cmd=statlfile HTTP/1.1" 200 - x-hgarg-1:sha=c8559c3c9cfb42131794b7d8009230403b9b454c x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob) $ killdaemons.py diff --git a/hgext/largefiles/wirestore.py b/hgext/largefiles/wirestore.py --- a/hgext/largefiles/wirestore.py +++ b/hgext/largefiles/wirestore.py @@ -32,8 +32,12 @@ '''For each hash, return 0 if it is available, other values if not. It is usually 2 if the largefile is missing, but might be 1 the server has a corrupted copy.''' -batch = self.remote.iterbatch() -for hash in hashes: -batch.statlfile(hash) -batch.submit() -return dict(zip(hashes, batch.results())) + +with self.remote.commandexecutor() as e: +fs = [] +for hash in hashes: +fs.append((hash, e.callcommand('statlfile', { +'sha': hash, +}))) + +return {hash: f.result() for hash, f in fs} To: indygreg, #hg-reviewers, durin42 Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3269: wireproto: implement batching on peer executor interface
This revision was automatically updated to reflect the committed changes. Closed by commit rHG2f626233859b: wireproto: implement batching on peer executor interface (authored by indygreg, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3269?vs=8122=8166 REVISION DETAIL https://phab.mercurial-scm.org/D3269 AFFECTED FILES mercurial/setdiscovery.py mercurial/wireprotov1peer.py CHANGE DETAILS diff --git a/mercurial/wireprotov1peer.py b/mercurial/wireprotov1peer.py --- a/mercurial/wireprotov1peer.py +++ b/mercurial/wireprotov1peer.py @@ -9,6 +9,7 @@ import hashlib import sys +import weakref from .i18n import _ from .node import ( @@ -180,13 +181,36 @@ return ';'.join(cmds) +class unsentfuture(pycompat.futures.Future): +"""A Future variation to represent an unsent command. + +Because we buffer commands and don't submit them immediately, calling +``result()`` on an unsent future could deadlock. Futures for buffered +commands are represented by this type, which wraps ``result()`` to +call ``sendcommands()``. +""" + +def result(self, timeout=None): +if self.done(): +return pycompat.futures.Future.result(self, timeout) + +self._peerexecutor.sendcommands() + +# This looks like it will infinitely recurse. However, +# sendcommands() should modify __class__. This call serves as a check +# on that. +return self.result(timeout) + @zi.implementer(repository.ipeercommandexecutor) class peerexecutor(object): def __init__(self, peer): self._peer = peer self._sent = False self._closed = False self._calls = [] +self._futures = weakref.WeakSet() +self._responseexecutor = None +self._responsef = None def __enter__(self): return self @@ -214,20 +238,35 @@ # Commands are either batchable or they aren't. If a command # isn't batchable, we send it immediately because the executor # can no longer accept new commands after a non-batchable command. -# If a command is batchable, we queue it for later. +# If a command is batchable, we queue it for later. But we have +# to account for the case of a non-batchable command arriving after +# a batchable one and refuse to service it. + +def addcall(): +f = pycompat.futures.Future() +self._futures.add(f) +self._calls.append((command, args, fn, f)) +return f if getattr(fn, 'batchable', False): -pass +f = addcall() + +# But since we don't issue it immediately, we wrap its result() +# to trigger sending so we avoid deadlocks. +f.__class__ = unsentfuture +f._peerexecutor = self else: if self._calls: raise error.ProgrammingError( '%s is not batchable and cannot be called on a command ' 'executor along with other commands' % command) -# We don't support batching yet. So resolve it immediately. -f = pycompat.futures.Future() -self._calls.append((command, args, fn, f)) -self.sendcommands() +f = addcall() + +# Non-batchable commands can never coexist with another command +# in this executor. So send the command immediately. +self.sendcommands() + return f def sendcommands(self): @@ -239,10 +278,18 @@ self._sent = True +# Unhack any future types so caller seens a clean type and to break +# cycle between us and futures. +for f in self._futures: +if isinstance(f, unsentfuture): +f.__class__ = pycompat.futures.Future +f._peerexecutor = None + calls = self._calls # Mainly to destroy references to futures. self._calls = None +# Simple case of a single command. We call it synchronously. if len(calls) == 1: command, args, fn, f = calls[0] @@ -259,14 +306,99 @@ return -raise error.ProgrammingError('support for multiple commands not ' - 'yet implemented') +# Batch commands are a bit harder. First, we have to deal with the +# @batchable coroutine. That's a bit annoying. Furthermore, we also +# need to preserve streaming. i.e. it should be possible for the +# futures to resolve as data is coming in off the wire without having +# to wait for the final byte of the final response. We do this by +# spinning up a thread to read the responses. + +requests = [] +states = [] + +for command, args, fn, f in calls: +# Future was cancelled. Ignore it. +if not f.set_running_or_notify_cancel(): +
D3267: repository: define new interface for running commands
This revision was automatically updated to reflect the committed changes. Closed by commit rHGfa0382088993: repository: define new interface for running commands (authored by indygreg, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3267?vs=8120=8165 REVISION DETAIL https://phab.mercurial-scm.org/D3267 AFFECTED FILES mercurial/repository.py CHANGE DETAILS diff --git a/mercurial/repository.py b/mercurial/repository.py --- a/mercurial/repository.py +++ b/mercurial/repository.py @@ -196,6 +196,88 @@ def changegroupsubset(bases, heads, kind): pass +class ipeercommandexecutor(zi.Interface): +"""Represents a mechanism to execute remote commands. + +This is the primary interface for requesting that wire protocol commands +be executed. Instances of this interface are active in a context manager +and have a well-defined lifetime. When the context manager exits, all +outstanding requests are waited on. +""" + +def callcommand(name, args): +"""Request that a named command be executed. + +Receives the command name and a dictionary of command arguments. + +Returns a ``concurrent.futures.Future`` that will resolve to the +result of that command request. That exact value is left up to +the implementation and possibly varies by command. + +Not all commands can coexist with other commands in an executor +instance: it depends on the underlying wire protocol transport being +used and the command itself. + +Implementations MAY call ``sendcommands()`` automatically if the +requested command can not coexist with other commands in this executor. + +Implementations MAY call ``sendcommands()`` automatically when the +future's ``result()`` is called. So, consumers using multiple +commands with an executor MUST ensure that ``result()`` is not called +until all command requests have been issued. +""" + +def sendcommands(): +"""Trigger submission of queued command requests. + +Not all transports submit commands as soon as they are requested to +run. When called, this method forces queued command requests to be +issued. It will no-op if all commands have already been sent. + +When called, no more new commands may be issued with this executor. +""" + +def close(): +"""Signal that this command request is finished. + +When called, no more new commands may be issued. All outstanding +commands that have previously been issued are waited on before +returning. This not only includes waiting for the futures to resolve, +but also waiting for all response data to arrive. In other words, +calling this waits for all on-wire state for issued command requests +to finish. + +When used as a context manager, this method is called when exiting the +context manager. + +This method may call ``sendcommands()`` if there are buffered commands. +""" + +class ipeerrequests(zi.Interface): +"""Interface for executing commands on a peer.""" + +def commandexecutor(): +"""A context manager that resolves to an ipeercommandexecutor. + +The object this resolves to can be used to issue command requests +to the peer. + +Callers should call its ``callcommand`` method to issue command +requests. + +A new executor should be obtained for each distinct set of commands +(possibly just a single command) that the consumer wants to execute +as part of a single operation or round trip. This is because some +peers are half-duplex and/or don't support persistent connections. +e.g. in the case of HTTP peers, commands sent to an executor represent +a single HTTP request. While some peers may support multiple command +sends over the wire per executor, consumers need to code to the least +capable peer. So it should be assumed that command executors buffer +called commands until they are told to send them and that each +command executor could result in a new connection or wire-level request +being issued. +""" + class ipeerbase(ipeerconnection, ipeercapabilities, ipeercommands): """Unified interface for peer repositories. To: indygreg, #hg-reviewers, durin42 Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel