D3393: bundle: introduce per-engine compression level
indygreg added a comment. I'm -0 on this because it's yet more experimental code. Since this experimental option was added, the code for parsing bundle specs has been drastically improved. I would rather we declare a bundlespec parameter to define the compression level (e.g. ``;complevel=4``) and have the bundler consume that. The code touched in commands.py already has access to the parsed bundlespec. But if we don't want to do that so close to freeze, I'm fine adding yet more experimental config options. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3393 To: joerg.sonnenberger, #hg-reviewers Cc: indygreg, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3401: wireproto: define HTTP version 2 protocol name in server module
indygreg abandoned this revision. indygreg added a comment. This one breaks tests. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3401 To: indygreg, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3401: wireproto: define HTTP version 2 protocol name in server module
indygreg created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY And subtly rename the canonical transport to "http-v2." I believe the key in the TRANSPORTS dict is only used internally. So the exact name should not matter. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3401 AFFECTED FILES mercurial/httppeer.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-0005' -HTTP_WIREPROTO_V2 = wireprototypes.HTTP_WIREPROTO_V2 +HTTP_WIREPROTO_V2 = b'exp-http-v2-0001' COMMANDS = wireprototypes.commanddict() diff --git a/mercurial/wireprototypes.py b/mercurial/wireprototypes.py --- a/mercurial/wireprototypes.py +++ b/mercurial/wireprototypes.py @@ -22,7 +22,6 @@ # These are advertised over the wire. Increment the counters at the end # to reflect BC breakages. SSHV2 = 'exp-ssh-v2-0001' -HTTP_WIREPROTO_V2 = 'exp-http-v2-0001' # All available wire protocol transports. TRANSPORTS = { @@ -39,7 +38,7 @@ 'transport': 'http', 'version': 1, }, -HTTP_WIREPROTO_V2: { +'http-v2': { 'transport': 'http', 'version': 2, } diff --git a/mercurial/httppeer.py b/mercurial/httppeer.py --- a/mercurial/httppeer.py +++ b/mercurial/httppeer.py @@ -33,7 +33,6 @@ url as urlmod, util, wireprotoframing, -wireprototypes, wireprotov1peer, wireprotov2peer, wireprotov2server, @@ -815,7 +814,7 @@ #Integer priority for the service. If we could choose from multiple #services, we choose the one with the highest priority. API_PEERS = { -wireprototypes.HTTP_WIREPROTO_V2: { +wireprotov2server.HTTP_WIREPROTO_V2: { 'init': httpv2peer, 'priority': 50, }, To: indygreg, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3395: wireproto: make version 2 @wireprotocommand an independent function
indygreg created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY Previously, the code for this decorator was shared between version 1 and version 2 commands. Very few parts of the function were identical. So I don't think sharing is justified. wireprotov2server now has its own @wireprotocommand decorator function. Because the decorator is no longer shared, code for configuring the transport policy has been removed. i.e. commands must have separate implementations for each wire protocol version. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3395 AFFECTED FILES mercurial/wireproto.py mercurial/wireprotov2server.py tests/wireprotohelpers.sh CHANGE DETAILS diff --git a/tests/wireprotohelpers.sh b/tests/wireprotohelpers.sh --- a/tests/wireprotohelpers.sh +++ b/tests/wireprotohelpers.sh @@ -16,24 +16,23 @@ cat > dummycommands.py << EOF from mercurial import ( wireprototypes, +wireprotov2server, wireproto, ) @wireproto.wireprotocommand('customreadonly', permission='pull') def customreadonlyv1(repo, proto): return wireprototypes.bytesresponse(b'customreadonly bytes response') -@wireproto.wireprotocommand('customreadonly', permission='pull', -transportpolicy=wireproto.POLICY_V2_ONLY) +@wireprotov2server.wireprotocommand('customreadonly', permission='pull') def customreadonlyv2(repo, proto): return wireprototypes.cborresponse(b'customreadonly bytes response') @wireproto.wireprotocommand('customreadwrite', permission='push') def customreadwrite(repo, proto): return wireprototypes.bytesresponse(b'customreadwrite bytes response') -@wireproto.wireprotocommand('customreadwrite', permission='push', -transportpolicy=wireproto.POLICY_V2_ONLY) +@wireprotov2server.wireprotocommand('customreadwrite', permission='push') def customreadwritev2(repo, proto): return wireprototypes.cborresponse(b'customreadwrite bytes response') EOF diff --git a/mercurial/wireprotov2server.py b/mercurial/wireprotov2server.py --- a/mercurial/wireprotov2server.py +++ b/mercurial/wireprotov2server.py @@ -405,10 +405,43 @@ return proto.addcapabilities(repo, caps) -def wireprotocommand(*args, **kwargs): +def wireprotocommand(name, args=None, permission='push'): +"""Decorator to declare a wire protocol command. + +``name`` is the name of the wire protocol command being provided. + +``args`` is a dict of argument names to example values. + +``permission`` defines the permission type needed to run this command. +Can be ``push`` or ``pull``. These roughly map to read-write and read-only, +respectively. Default is to assume command requires ``push`` permissions +because otherwise commands not declaring their permissions could modify +a repository that is supposed to be read-only. +""" +transports = {k for k, v in wireprototypes.TRANSPORTS.items() + if v['version'] == 2} + +if permission not in ('push', 'pull'): +raise error.ProgrammingError('invalid wire protocol permission; ' + 'got %s; expected "push" or "pull"' % + permission) + +if args is None: +args = {} + +if not isinstance(args, dict): +raise error.ProgrammingError('arguments for version 2 commands ' + 'must be declared as dicts') + def register(func): -return wireproto.wireprotocommand( -*args, transportpolicy=wireproto.POLICY_V2_ONLY, **kwargs)(func) +if name in wireproto.commandsv2: +raise error.ProgrammingError('%s command already registered ' + 'for version 2' % name) + +wireproto.commandsv2[name] = wireproto.commandentry( +func, args=args, transports=transports, permission=permission) + +return func return register diff --git a/mercurial/wireproto.py b/mercurial/wireproto.py --- a/mercurial/wireproto.py +++ b/mercurial/wireproto.py @@ -251,50 +251,29 @@ return True -# Constants specifying which transports a wire protocol command should be -# available on. For use with @wireprotocommand. -POLICY_V1_ONLY = 'v1-only' -POLICY_V2_ONLY = 'v2-only' - # For version 1 transports. commands = commanddict() # For version 2 transports. commandsv2 = commanddict() -def wireprotocommand(name, args=None, transportpolicy=POLICY_V1_ONLY, - permission='push'): +def wireprotocommand(name, args=None, permission='push'): """Decorator to declare a wire protocol command. ``name`` is the name of the wire protocol command being provided. ``args`` defines the named arguments accepted by the command. It is -ideally a dict mapping argument names to their types. For backwards -compatibility, it can be
D3400: wireproto: rename wireproto to wireprotov1server (API)
indygreg created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY We have wireprotov2server, wireprotov1peer, and wireprotov2peer. wireproto only contains server functionality. So it makes sense to rename it to wireprotov1server so the naming aligns with everything else. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3400 AFFECTED FILES hgext/clonebundles.py hgext/infinitepush/__init__.py hgext/largefiles/uisetup.py hgext/lfs/__init__.py mercurial/sshpeer.py mercurial/wireproto.py mercurial/wireprotoserver.py mercurial/wireprotov1server.py tests/sshprotoext.py tests/test-http-permissions.t tests/test-sshserver.py tests/test-wireproto.py tests/wireprotohelpers.sh CHANGE DETAILS diff --git a/tests/wireprotohelpers.sh b/tests/wireprotohelpers.sh --- a/tests/wireprotohelpers.sh +++ b/tests/wireprotohelpers.sh @@ -16,19 +16,19 @@ cat > dummycommands.py << EOF from mercurial import ( wireprototypes, +wireprotov1server, wireprotov2server, -wireproto, ) -@wireproto.wireprotocommand('customreadonly', permission='pull') +@wireprotov1server.wireprotocommand('customreadonly', permission='pull') def customreadonlyv1(repo, proto): return wireprototypes.bytesresponse(b'customreadonly bytes response') @wireprotov2server.wireprotocommand('customreadonly', permission='pull') def customreadonlyv2(repo, proto): return wireprototypes.cborresponse(b'customreadonly bytes response') -@wireproto.wireprotocommand('customreadwrite', permission='push') +@wireprotov1server.wireprotocommand('customreadwrite', permission='push') def customreadwrite(repo, proto): return wireprototypes.bytesresponse(b'customreadwrite bytes response') diff --git a/tests/test-wireproto.py b/tests/test-wireproto.py --- a/tests/test-wireproto.py +++ b/tests/test-wireproto.py @@ -5,9 +5,9 @@ pycompat, ui as uimod, util, -wireproto, wireprototypes, wireprotov1peer, +wireprotov1server, ) stringio = util.stringio @@ -55,7 +55,7 @@ def _call(self, cmd, **args): args = pycompat.byteskwargs(args) -res = wireproto.dispatch(self.serverrepo, proto(args), cmd) +res = wireprotov1server.dispatch(self.serverrepo, proto(args), cmd) if isinstance(res, wireprototypes.bytesresponse): return res.data elif isinstance(res, bytes): @@ -87,7 +87,7 @@ def greet(repo, proto, name): return mangle(repo.greet(unmangle(name))) -wireproto.commands[b'greet'] = (greet, b'name',) +wireprotov1server.commands[b'greet'] = (greet, b'name') srv = serverrepo() clt = clientpeer(srv, uimod.ui()) diff --git a/tests/test-sshserver.py b/tests/test-sshserver.py --- a/tests/test-sshserver.py +++ b/tests/test-sshserver.py @@ -6,8 +6,8 @@ import silenttestrunner from mercurial import ( -wireproto, wireprotoserver, +wireprotov1server, ) from mercurial.utils import ( @@ -29,7 +29,7 @@ proto = wireprotoserver.sshv1protocolhandler(server._ui, server._fin, server._fout) -_func, spec = wireproto.commands[cmd] +_func, spec = wireprotov1server.commands[cmd] self.assertEqual(proto.getargs(spec), expected) def mockserver(inbytes): diff --git a/tests/test-http-permissions.t b/tests/test-http-permissions.t --- a/tests/test-http-permissions.t +++ b/tests/test-http-permissions.t @@ -3,7 +3,7 @@ $ cat > fakeremoteuser.py << EOF > import os > from mercurial.hgweb import hgweb_mod - > from mercurial import wireproto + > from mercurial import wireprotov1server > class testenvhgweb(hgweb_mod.hgweb): > def __call__(self, env, respond): > # Allow REMOTE_USER to define authenticated user. @@ -15,16 +15,16 @@ > return super(testenvhgweb, self).__call__(env, respond) > hgweb_mod.hgweb = testenvhgweb > - > @wireproto.wireprotocommand('customreadnoperm') + > @wireprotov1server.wireprotocommand('customreadnoperm') > def customread(repo, proto): > return b'read-only command no defined permissions\n' - > @wireproto.wireprotocommand('customwritenoperm') + > @wireprotov1server.wireprotocommand('customwritenoperm') > def customwritenoperm(repo, proto): > return b'write command no defined permissions\n' - > @wireproto.wireprotocommand('customreadwithperm', permission='pull') + > @wireprotov1server.wireprotocommand('customreadwithperm', permission='pull') > def customreadwithperm(repo, proto): > return b'read-only command w/ defined permissions\n' - > @wireproto.wireprotocommand('customwritewithperm', permission='push') + > @wireprotov1server.wireprotocommand('customwritewithperm', permission='push') > def customwritewithperm(repo, proto): > return b'write command w/ defined
D3397: wireproto: reimplement dispatch() for version 2 server
indygreg created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY The code is minimal. I'm trying to create a cleaner break between version 1 and version 2 server code. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3397 AFFECTED FILES mercurial/wireproto.py mercurial/wireprotov2server.py CHANGE DETAILS diff --git a/mercurial/wireprotov2server.py b/mercurial/wireprotov2server.py --- a/mercurial/wireprotov2server.py +++ b/mercurial/wireprotov2server.py @@ -296,7 +296,7 @@ res.setbodybytes(_('command in frame must match command in URL')) return True -rsp = wireproto.dispatch(repo, proto, command['command']) +rsp = dispatch(repo, proto, command['command']) res.status = b'200 OK' res.headers[b'Content-Type'] = FRAMINGTYPE @@ -328,6 +328,17 @@ raise error.ProgrammingError('unhandled event from reactor: %s' % action) +def getdispatchrepo(repo, proto, command): +return repo.filtered('served') + +def dispatch(repo, proto, command): +repo = getdispatchrepo(repo, proto, command) + +func, spec = wireproto.commandsv2[command] +args = proto.getargs(spec) + +return func(repo, proto, **args) + @zi.implementer(wireprototypes.baseprotocolhandler) class httpv2protocolhandler(object): def __init__(self, req, ui, args=None): diff --git a/mercurial/wireproto.py b/mercurial/wireproto.py --- a/mercurial/wireproto.py +++ b/mercurial/wireproto.py @@ -69,20 +69,10 @@ def dispatch(repo, proto, command): repo = getdispatchrepo(repo, proto, command) -transportversion = wireprototypes.TRANSPORTS[proto.name]['version'] -commandtable = commandsv2 if transportversion == 2 else commands -func, spec = commandtable[command] - +func, spec = commands[command] args = proto.getargs(spec) -# Version 1 protocols define arguments as a list. Version 2 uses a dict. -if isinstance(args, list): -return func(repo, proto, *args) -elif isinstance(args, dict): -return func(repo, proto, **args) -else: -raise error.ProgrammingError('unexpected type returned from ' - 'proto.getargs(): %s' % type(args)) +return func(repo, proto, *args) def options(cmd, keys, others): opts = {} To: indygreg, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3398: wireproto: move supportedcompengines out of wireproto
indygreg created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY This function is used by both version 1 and version 2. It belongs in a common module. "wireprototypes" may not be the best module name. I may rename it... REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3398 AFFECTED FILES mercurial/wireproto.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 @@ -393,7 +393,7 @@ transports. """ compression = [] -for engine in wireproto.supportedcompengines(repo.ui, util.SERVERROLE): +for engine in wireprototypes.supportedcompengines(repo.ui, util.SERVERROLE): compression.append({ b'name': engine.wireprotosupport().name, }) diff --git a/mercurial/wireprototypes.py b/mercurial/wireprototypes.py --- a/mercurial/wireprototypes.py +++ b/mercurial/wireprototypes.py @@ -12,6 +12,10 @@ from .thirdparty.zope import ( interface as zi, ) +from . import ( +error, +util, +) # Names of the SSH protocol implementations. SSHV1 = 'ssh-v1' @@ -319,3 +323,52 @@ return False return True + +def supportedcompengines(ui, role): +"""Obtain the list of supported compression engines for a request.""" +assert role in (util.CLIENTROLE, util.SERVERROLE) + +compengines = util.compengines.supportedwireengines(role) + +# Allow config to override default list and ordering. +if role == util.SERVERROLE: +configengines = ui.configlist('server', 'compressionengines') +config = 'server.compressionengines' +else: +# This is currently implemented mainly to facilitate testing. In most +# cases, the server should be in charge of choosing a compression engine +# because a server has the most to lose from a sub-optimal choice. (e.g. +# CPU DoS due to an expensive engine or a network DoS due to poor +# compression ratio). +configengines = ui.configlist('experimental', + 'clientcompressionengines') +config = 'experimental.clientcompressionengines' + +# No explicit config. Filter out the ones that aren't supposed to be +# advertised and return default ordering. +if not configengines: +attr = 'serverpriority' if role == util.SERVERROLE else 'clientpriority' +return [e for e in compengines +if getattr(e.wireprotosupport(), attr) > 0] + +# If compression engines are listed in the config, assume there is a good +# reason for it (like server operators wanting to achieve specific +# performance characteristics). So fail fast if the config references +# unusable compression engines. +validnames = set(e.name() for e in compengines) +invalidnames = set(e for e in configengines if e not in validnames) +if invalidnames: +raise error.Abort(_('invalid compression engine defined in %s: %s') % + (config, ', '.join(sorted(invalidnames + +compengines = [e for e in compengines if e.name() in configengines] +compengines = sorted(compengines, + key=lambda e: configengines.index(e.name())) + +if not compengines: +raise error.Abort(_('%s config option does not specify any known ' +'compression engines') % config, + hint=_('usable compression engines: %s') % + ', '.sorted(validnames)) + +return compengines diff --git a/mercurial/wireprotoserver.py b/mercurial/wireprotoserver.py --- a/mercurial/wireprotoserver.py +++ b/mercurial/wireprotoserver.py @@ -149,7 +149,8 @@ # FUTURE advertise minrx and mintx after consulting config option caps.append('httpmediatype=0.1rx,0.1tx,0.2tx') -compengines = wireproto.supportedcompengines(repo.ui, util.SERVERROLE) +compengines = wireprototypes.supportedcompengines(repo.ui, + util.SERVERROLE) if compengines: comptypes = ','.join(urlreq.quote(e.wireprotosupport().name) for e in compengines) @@ -329,7 +330,7 @@ # Now find an agreed upon compression format. compformats = wireproto.clientcompressionsupport(proto) -for engine in wireproto.supportedcompengines(ui, util.SERVERROLE): +for engine in wireprototypes.supportedcompengines(ui, util.SERVERROLE): if engine.wireprotosupport().name in compformats: opts = {} level = ui.configint('server', '%slevel' % engine.name()) diff --git a/mercurial/wireproto.py b/mercurial/wireproto.py ---
D3399: wireproto: move version 2 commands dict to wireprotov2server
indygreg created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY This was the final piece of version 2 referenced in wireproto. The break between server implementations is now much cleaner. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3399 AFFECTED FILES mercurial/wireproto.py mercurial/wireprotov2server.py CHANGE DETAILS diff --git a/mercurial/wireprotov2server.py b/mercurial/wireprotov2server.py --- a/mercurial/wireprotov2server.py +++ b/mercurial/wireprotov2server.py @@ -21,15 +21,16 @@ pycompat, streamclone, util, -wireproto, wireprotoframing, wireprototypes, ) FRAMINGTYPE = b'application/mercurial-exp-framing-0005' HTTP_WIREPROTO_V2 = wireprototypes.HTTP_WIREPROTO_V2 +COMMANDS = wireprototypes.commanddict() + def handlehttpv2request(rctx, req, res, checkperm, urlparts): from .hgweb import common as hgwebcommon @@ -87,7 +88,7 @@ # extension. extracommands = {'multirequest'} -if command not in wireproto.commandsv2 and command not in extracommands: +if command not in COMMANDS and command not in extracommands: res.status = b'404 Not Found' res.headers[b'Content-Type'] = b'text/plain' res.setbodybytes(_('unknown wire protocol command: %s\n') % command) @@ -98,7 +99,7 @@ proto = httpv2protocolhandler(req, ui) -if (not wireproto.commandsv2.commandavailable(command, proto) +if (not COMMANDS.commandavailable(command, proto) and command not in extracommands): res.status = b'404 Not Found' res.headers[b'Content-Type'] = b'text/plain' @@ -254,7 +255,7 @@ proto = httpv2protocolhandler(req, ui, args=command['args']) if reqcommand == b'multirequest': -if not wireproto.commandsv2.commandavailable(command['command'], proto): +if not COMMANDS.commandavailable(command['command'], proto): # TODO proper error mechanism res.status = b'200 OK' res.headers[b'Content-Type'] = b'text/plain' @@ -264,7 +265,7 @@ # TODO don't use assert here, since it may be elided by -O. assert authedperm in (b'ro', b'rw') -wirecommand = wireproto.commandsv2[command['command']] +wirecommand = COMMANDS[command['command']] assert wirecommand.permission in ('push', 'pull') if authedperm == b'ro' and wirecommand.permission != 'pull': @@ -334,7 +335,7 @@ def dispatch(repo, proto, command): repo = getdispatchrepo(repo, proto, command) -func, spec = wireproto.commandsv2[command] +func, spec = COMMANDS[command] args = proto.getargs(spec) return func(repo, proto, **args) @@ -404,7 +405,7 @@ 'framingmediatypes': [FRAMINGTYPE], } -for command, entry in wireproto.commandsv2.items(): +for command, entry in COMMANDS.items(): caps['commands'][command] = { 'args': entry.args, 'permissions': [entry.permission], @@ -445,11 +446,11 @@ 'must be declared as dicts') def register(func): -if name in wireproto.commandsv2: +if name in COMMANDS: raise error.ProgrammingError('%s command already registered ' 'for version 2' % name) -wireproto.commandsv2[name] = wireprototypes.commandentry( +COMMANDS[name] = wireprototypes.commandentry( func, args=args, transports=transports, permission=permission) return func diff --git a/mercurial/wireproto.py b/mercurial/wireproto.py --- a/mercurial/wireproto.py +++ b/mercurial/wireproto.py @@ -114,12 +114,8 @@ return ui.configbool('server', 'bundle1') -# For version 1 transports. commands = wireprototypes.commanddict() -# For version 2 transports. -commandsv2 = wireprototypes.commanddict() - def wireprotocommand(name, args=None, permission='push'): """Decorator to declare a wire protocol command. To: indygreg, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3394: wireproto: don't pass transportpolicy argument
indygreg created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY The default is version 1 only. So we don't need to pass this argument when declaring commands. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3394 AFFECTED FILES mercurial/wireproto.py CHANGE DETAILS diff --git a/mercurial/wireproto.py b/mercurial/wireproto.py --- a/mercurial/wireproto.py +++ b/mercurial/wireproto.py @@ -346,8 +346,7 @@ return register # TODO define a more appropriate permissions type to use for this. -@wireprotocommand('batch', 'cmds *', permission='pull', - transportpolicy=POLICY_V1_ONLY) +@wireprotocommand('batch', 'cmds *', permission='pull') def batch(repo, proto, cmds, others): unescapearg = wireprototypes.unescapebatcharg repo = repo.filtered("served") @@ -393,18 +392,16 @@ return wireprototypes.bytesresponse(';'.join(res)) -@wireprotocommand('between', 'pairs', transportpolicy=POLICY_V1_ONLY, - permission='pull') +@wireprotocommand('between', 'pairs', permission='pull') def between(repo, proto, pairs): pairs = [wireprototypes.decodelist(p, '-') for p in pairs.split(" ")] r = [] for b in repo.between(pairs): r.append(wireprototypes.encodelist(b) + "\n") return wireprototypes.bytesresponse(''.join(r)) -@wireprotocommand('branchmap', permission='pull', - transportpolicy=POLICY_V1_ONLY) +@wireprotocommand('branchmap', permission='pull') def branchmap(repo, proto): branchmap = repo.branchmap() heads = [] @@ -415,18 +412,16 @@ return wireprototypes.bytesresponse('\n'.join(heads)) -@wireprotocommand('branches', 'nodes', transportpolicy=POLICY_V1_ONLY, - permission='pull') +@wireprotocommand('branches', 'nodes', permission='pull') def branches(repo, proto, nodes): nodes = wireprototypes.decodelist(nodes) r = [] for b in repo.branches(nodes): r.append(wireprototypes.encodelist(b) + "\n") return wireprototypes.bytesresponse(''.join(r)) -@wireprotocommand('clonebundles', '', permission='pull', - transportpolicy=POLICY_V1_ONLY) +@wireprotocommand('clonebundles', '', permission='pull') def clonebundles(repo, proto): """Server command for returning info for available bundles to seed clones. @@ -479,14 +474,12 @@ # If you are writing an extension and consider wrapping this function. Wrap # `_capabilities` instead. -@wireprotocommand('capabilities', permission='pull', - transportpolicy=POLICY_V1_ONLY) +@wireprotocommand('capabilities', permission='pull') def capabilities(repo, proto): caps = _capabilities(repo, proto) return wireprototypes.bytesresponse(' '.join(sorted(caps))) -@wireprotocommand('changegroup', 'roots', transportpolicy=POLICY_V1_ONLY, - permission='pull') +@wireprotocommand('changegroup', 'roots', permission='pull') def changegroup(repo, proto, roots): nodes = wireprototypes.decodelist(roots) outgoing = discovery.outgoing(repo, missingroots=nodes, @@ -496,7 +489,6 @@ return wireprototypes.streamres(gen=gen) @wireprotocommand('changegroupsubset', 'bases heads', - transportpolicy=POLICY_V1_ONLY, permission='pull') def changegroupsubset(repo, proto, bases, heads): bases = wireprototypes.decodelist(bases) @@ -508,7 +500,7 @@ return wireprototypes.streamres(gen=gen) @wireprotocommand('debugwireargs', 'one two *', - permission='pull', transportpolicy=POLICY_V1_ONLY) + permission='pull') def debugwireargs(repo, proto, one, two, others): # only accept optional args from the known set opts = options('debugwireargs', ['three', 'four'], others) @@ -579,8 +571,7 @@ continue return None -@wireprotocommand('getbundle', '*', permission='pull', - transportpolicy=POLICY_V1_ONLY) +@wireprotocommand('getbundle', '*', permission='pull') def getbundle(repo, proto, others): opts = options('getbundle', wireprototypes.GETBUNDLE_ARGUMENTS.keys(), others) @@ -656,12 +647,12 @@ return wireprototypes.streamres( gen=chunks, prefer_uncompressed=not prefercompressed) -@wireprotocommand('heads', permission='pull', transportpolicy=POLICY_V1_ONLY) +@wireprotocommand('heads', permission='pull') def heads(repo, proto): h = repo.heads() return wireprototypes.bytesresponse(wireprototypes.encodelist(h) + '\n') -@wireprotocommand('hello', permission='pull', transportpolicy=POLICY_V1_ONLY) +@wireprotocommand('hello', permission='pull') def hello(repo, proto): """Called as part of SSH handshake to obtain server info. @@ -676,14 +667,12 @@ caps = capabilities(repo, proto).data return wireprototypes.bytesresponse('capabilities: %s\n' % caps) -@wireprotocommand('listkeys',
D3396: wireproto: move command registration types to wireprototypes
indygreg created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY These are shared across wire protocol implementations. wireprototypes is our module for common code. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3396 AFFECTED FILES mercurial/wireproto.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 @@ -438,7 +438,7 @@ raise error.ProgrammingError('%s command already registered ' 'for version 2' % name) -wireproto.commandsv2[name] = wireproto.commandentry( +wireproto.commandsv2[name] = wireprototypes.commandentry( func, args=args, transports=transports, permission=permission) return func diff --git a/mercurial/wireprototypes.py b/mercurial/wireprototypes.py --- a/mercurial/wireprototypes.py +++ b/mercurial/wireprototypes.py @@ -241,3 +241,81 @@ doesn't have that permission, the exception should raise or abort in a protocol specific manner. """ + +class commandentry(object): +"""Represents a declared wire protocol command.""" +def __init__(self, func, args='', transports=None, + permission='push'): +self.func = func +self.args = args +self.transports = transports or set() +self.permission = permission + +def _merge(self, func, args): +"""Merge this instance with an incoming 2-tuple. + +This is called when a caller using the old 2-tuple API attempts +to replace an instance. The incoming values are merged with +data not captured by the 2-tuple and a new instance containing +the union of the two objects is returned. +""" +return commandentry(func, args=args, transports=set(self.transports), +permission=self.permission) + +# Old code treats instances as 2-tuples. So expose that interface. +def __iter__(self): +yield self.func +yield self.args + +def __getitem__(self, i): +if i == 0: +return self.func +elif i == 1: +return self.args +else: +raise IndexError('can only access elements 0 and 1') + +class commanddict(dict): +"""Container for registered wire protocol commands. + +It behaves like a dict. But __setitem__ is overwritten to allow silent +coercion of values from 2-tuples for API compatibility. +""" +def __setitem__(self, k, v): +if isinstance(v, commandentry): +pass +# Cast 2-tuples to commandentry instances. +elif isinstance(v, tuple): +if len(v) != 2: +raise ValueError('command tuples must have exactly 2 elements') + +# It is common for extensions to wrap wire protocol commands via +# e.g. ``wireproto.commands[x] = (newfn, args)``. Because callers +# doing this aren't aware of the new API that uses objects to store +# command entries, we automatically merge old state with new. +if k in self: +v = self[k]._merge(v[0], v[1]) +else: +# Use default values from @wireprotocommand. +v = commandentry(v[0], args=v[1], + transports=set(TRANSPORTS), + permission='push') +else: +raise ValueError('command entries must be commandentry instances ' + 'or 2-tuples') + +return super(commanddict, self).__setitem__(k, v) + +def commandavailable(self, command, proto): +"""Determine if a command is available for the requested protocol.""" +assert proto.name in TRANSPORTS + +entry = self.get(command) + +if not entry: +return False + +if proto.name not in entry.transports: +return False + +return True diff --git a/mercurial/wireproto.py b/mercurial/wireproto.py --- a/mercurial/wireproto.py +++ b/mercurial/wireproto.py @@ -173,89 +173,11 @@ return compengines -class commandentry(object): -"""Represents a declared wire protocol command.""" -def __init__(self, func, args='', transports=None, - permission='push'): -self.func = func -self.args = args -self.transports = transports or set() -self.permission = permission - -def _merge(self, func, args): -"""Merge this instance with an incoming 2-tuple. - -This is called when a caller using the old 2-tuple API attempts -to replace an instance. The incoming values are merged with -data not captured by the 2-tuple and a new instance containing -the
mercurial@37650: 28 new changesets
28 new changesets in mercurial: https://www.mercurial-scm.org/repo/hg/rev/eb687c28a915 changeset: 37623:eb687c28a915 user:Gregory Szorcdate:Wed Apr 11 14:48:24 2018 -0700 summary: thirdparty: vendor futures 3.2.0 https://www.mercurial-scm.org/repo/hg/rev/33db69b6b58b changeset: 37624:33db69b6b58b user:Gregory Szorc date:Mon Apr 09 12:19:37 2018 -0700 summary: futures: get rid of extend_path https://www.mercurial-scm.org/repo/hg/rev/3ccaf995f549 changeset: 37625:3ccaf995f549 user:Gregory Szorc date:Mon Apr 09 12:22:31 2018 -0700 summary: tests: silence pyflakes for thirdparty/concurrent https://www.mercurial-scm.org/repo/hg/rev/0a9c0d3480b2 changeset: 37626:0a9c0d3480b2 user:Gregory Szorc date:Mon Apr 09 12:23:48 2018 -0700 summary: futures: switch to absolute and relative imports https://www.mercurial-scm.org/repo/hg/rev/cfb32979abcd changeset: 37627:cfb32979abcd user:Gregory Szorc date:Mon Apr 09 12:27:52 2018 -0700 summary: setup: add packages for concurrent.futures https://www.mercurial-scm.org/repo/hg/rev/8da30ceae88f changeset: 37628:8da30ceae88f user:Gregory Szorc date:Mon Apr 09 12:28:57 2018 -0700 summary: pycompat: export a handle on concurrent.futures https://www.mercurial-scm.org/repo/hg/rev/fa0382088993 changeset: 37629:fa0382088993 user:Gregory Szorc date:Fri Apr 13 10:23:05 2018 -0700 summary: repository: define new interface for running commands https://www.mercurial-scm.org/repo/hg/rev/e1b32dc4646c changeset: 37630:e1b32dc4646c user:Gregory Szorc date:Fri Apr 13 10:51:23 2018 -0700 summary: wireproto: implement command executor interface for version 1 peers https://www.mercurial-scm.org/repo/hg/rev/2f626233859b changeset: 37631:2f626233859b user:Gregory Szorc date:Fri Apr 13 11:02:34 2018 -0700 summary: wireproto: implement batching on peer executor interface https://www.mercurial-scm.org/repo/hg/rev/6c55ce51d6c3 changeset: 37632:6c55ce51d6c3 user:Gregory Szorc date:Fri Apr 13 11:08:46 2018 -0700 summary: largefiles: use command executor for batch operation https://www.mercurial-scm.org/repo/hg/rev/33a6eee08db2 changeset: 37633:33a6eee08db2 user:Gregory Szorc date:Wed Apr 11 16:18:26 2018 -0700 summary: wireproto: remove iterbatch() from peer interface (API) https://www.mercurial-scm.org/repo/hg/rev/0ed11f9368fd changeset: 37634:0ed11f9368fd user:Gregory Szorc date:Fri Apr 13 11:10:59 2018 -0700 summary: treediscovery: switch to command executor interface https://www.mercurial-scm.org/repo/hg/rev/cc8c06835097 changeset: 37635:cc8c06835097 user:Gregory Szorc date:Fri Apr 13 11:12:19 2018 -0700 summary: wireproto: convert legacy commands to command executor https://www.mercurial-scm.org/repo/hg/rev/330ada7e8ea5 changeset: 37636:330ada7e8ea5 user:Gregory Szorc date:Wed Apr 11 17:24:43 2018 -0700 summary: discovery: don't redundantly call branchmap https://www.mercurial-scm.org/repo/hg/rev/1964d2d1f421 changeset: 37637:1964d2d1f421 user:Gregory Szorc date:Fri Apr 13 11:13:05 2018 -0700 summary: discovery: use command executor interface https://www.mercurial-scm.org/repo/hg/rev/65b86ee69383 changeset: 37638:65b86ee69383 user:Gregory Szorc date:Fri Apr 13 11:14:19 2018 -0700 summary: streamclone: use command executor for wire protocol commands https://www.mercurial-scm.org/repo/hg/rev/0e50dda7e9c1 changeset: 37639:0e50dda7e9c1 user:Gregory Szorc date:Fri Apr 13 11:14:54 2018 -0700 summary: logexchange: use command executor for wire protocol commands https://www.mercurial-scm.org/repo/hg/rev/ce8828217369 changeset: 37640:ce8828217369 user:Gregory Szorc date:Fri Apr 13 11:17:45 2018 -0700 summary: hg: use command executor for wire protocol commands https://www.mercurial-scm.org/repo/hg/rev/add129811176 changeset: 37641:add129811176 user:Gregory Szorc date:Fri Apr 13 11:19:39 2018 -0700 summary: bookmarks: use command executor for wire protocol commands https://www.mercurial-scm.org/repo/hg/rev/d959277ff1b5 changeset: 37642:d959277ff1b5 user:Gregory Szorc date:Wed Apr 11 17:51:40 2018 -0700 summary: bundlerepo: rename "other" to "peer"
[PATCH] tests: arrange for a server in wireproto-command-capabilities.t to be killed
# HG changeset patch # User Matt Harbison# Date 1523936370 14400 # Mon Apr 16 23:39:30 2018 -0400 # Node ID f31defc97cfbf6373bb756dc8af672ca3b959f1e # Parent 886754323bede9e79da8f05335458af63c377668 tests: arrange for a server in wireproto-command-capabilities.t to be killed The stray servers were piling up after the test harness exited. On Windows, this means the *.pyd files can't be rebuilt, which is why the build warning count dropped to 1 recently. diff --git a/tests/test-wireproto-command-capabilities.t b/tests/test-wireproto-command-capabilities.t --- a/tests/test-wireproto-command-capabilities.t +++ b/tests/test-wireproto-command-capabilities.t @@ -142,6 +142,7 @@ Restart server to enable HTTPv2 $ killdaemons.py $ enablehttpv2 server $ hg -R server serve -p $HGPORT -d --pid-file hg.pid -E error.log + $ cat hg.pid > $DAEMON_PIDS Only requested API services are returned ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D2934: forget: add --confirm option
mharbison72 added a comment. In https://phab.mercurial-scm.org/D2934#54155, @durin42 wrote: > (Suggestion: diff the output of `hg export` on your version vs the one that lands to see what I needed to tweak - there were some oversights in tests during development it looks like.) Alternately if you have the extdiff extension configured, you can diff the two revisions directly and supply `--patch` to the extdiff command get the same effect. I think it's easier to view graphically, than a diff of a diff. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D2934 To: khanchi97, #hg-reviewers, av6, pulkit, durin42 Cc: durin42, mharbison72, yuja, pulkit, av6, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
mercurial@37622: 14 new changesets
14 new changesets in mercurial: https://www.mercurial-scm.org/repo/hg/rev/01bfe5ad0c53 changeset: 37609:01bfe5ad0c53 user:Gregory Szorcdate:Wed Apr 11 11:03:45 2018 -0700 summary: httppeer: implement ipeerconnection https://www.mercurial-scm.org/repo/hg/rev/98861a2298b5 changeset: 37610:98861a2298b5 user:Gregory Szorc date:Tue Apr 10 18:47:09 2018 -0700 summary: repository: split capabilities methods into separate interface https://www.mercurial-scm.org/repo/hg/rev/ae8730877371 changeset: 37611:ae8730877371 user:Gregory Szorc date:Tue Apr 10 19:09:35 2018 -0700 summary: httppeer: basic implementation of capabilities interface https://www.mercurial-scm.org/repo/hg/rev/5e71dea79aae changeset: 37612:5e71dea79aae user:Gregory Szorc date:Wed Apr 11 10:50:58 2018 -0700 summary: wireproto: move value encoding functions to wireprototypes (API) https://www.mercurial-scm.org/repo/hg/rev/96d735601ca1 changeset: 37613:96d735601ca1 user:Gregory Szorc date:Wed Apr 11 10:51:38 2018 -0700 summary: wireproto: move gboptsmap to wireprototypes and rename (API) https://www.mercurial-scm.org/repo/hg/rev/a81d02ea65db changeset: 37614:a81d02ea65db user:Gregory Szorc date:Wed Apr 11 12:49:08 2018 -0700 summary: wireproto: move version 1 peer functionality to standalone module (API) https://www.mercurial-scm.org/repo/hg/rev/f3dc8239e3a9 changeset: 37615:f3dc8239e3a9 user:Gregory Szorc date:Wed Apr 11 12:51:09 2018 -0700 summary: peer: scatter module to the wind (API) https://www.mercurial-scm.org/repo/hg/rev/5e81cf9651c1 changeset: 37616:5e81cf9651c1 user:Matt Harbison date:Thu Apr 05 15:42:40 2018 -0400 summary: hgweb: fallback to checking wsgireq.env for REPO_NAME for 3rd party hosting https://www.mercurial-scm.org/repo/hg/rev/b03f2e0fdb88 changeset: 37617:b03f2e0fdb88 user:Matt Harbison date:Thu Apr 12 17:24:55 2018 -0700 summary: lfs: teach the blob server to handle --prefix https://www.mercurial-scm.org/repo/hg/rev/1edf3738e000 changeset: 37618:1edf3738e000 user:Augie Fackler date:Thu Apr 12 14:27:13 2018 -0400 summary: fix: port most of the way to python 3 https://www.mercurial-scm.org/repo/hg/rev/68132a95df31 changeset: 37619:68132a95df31 user:Gregory Szorc date:Thu Apr 12 20:42:42 2018 -0700 summary: stringutil: support more types with pprint() https://www.mercurial-scm.org/repo/hg/rev/fd1dd79cff20 changeset: 37620:fd1dd79cff20 user:Gregory Szorc date:Thu Apr 12 23:06:27 2018 -0700 summary: cmdutil: pass in parsed patch to tryimportone() (API) https://www.mercurial-scm.org/repo/hg/rev/5537d8f5e989 changeset: 37621:5537d8f5e989 user:Gregory Szorc date:Thu Apr 12 23:14:38 2018 -0700 summary: patch: make extract() a context manager (API) https://www.mercurial-scm.org/repo/hg/rev/bfdd20d22a86 changeset: 37622:bfdd20d22a86 bookmark:@ tag: tip user:Pulkit Goyal <7895pul...@gmail.com> date:Thu Apr 12 15:05:49 2018 +0530 summary: py3: make sure decode() first argument is str -- 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
D3390: exchange: use command executor interface for calling listkeys
This revision was automatically updated to reflect the committed changes. Closed by commit rHG2a8ad00b8aed: exchange: use command executor interface for calling listkeys (authored by indygreg, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3390?vs=8317=8363 REVISION DETAIL https://phab.mercurial-scm.org/D3390 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 @@ -591,7 +591,8 @@ (computed for both success and failure case for changesets push)""" outgoing = pushop.outgoing unfi = pushop.repo.unfiltered() -remotephases = pushop.remote.listkeys('phases') +remotephases = listkeys(pushop.remote, 'phases') + if (pushop.ui.configbool('ui', '_usedassubrepo') and remotephases# server supports phases and not pushop.outgoing.missing # no changesets to be pushed @@ -638,14 +639,20 @@ @pushdiscovery('obsmarker') def _pushdiscoveryobsmarkers(pushop): -if (obsolete.isenabled(pushop.repo, obsolete.exchangeopt) -and pushop.repo.obsstore -and 'obsolete' in pushop.remote.listkeys('namespaces')): -repo = pushop.repo -# very naive computation, that can be quite expensive on big repo. -# However: evolution is currently slow on them anyway. -nodes = (c.node() for c in repo.set('::%ln', pushop.futureheads)) -pushop.outobsmarkers = pushop.repo.obsstore.relevantmarkers(nodes) +if not obsolete.isenabled(pushop.repo, obsolete.exchangeopt): +return + +if not pushop.repo.obsstore: +return + +if 'obsolete' not in listkeys(pushop.remote, 'namespaces'): +return + +repo = pushop.repo +# very naive computation, that can be quite expensive on big repo. +# However: evolution is currently slow on them anyway. +nodes = (c.node() for c in repo.set('::%ln', pushop.futureheads)) +pushop.outobsmarkers = pushop.repo.obsstore.relevantmarkers(nodes) @pushdiscovery('bookmarks') def _pushdiscoverybookmarks(pushop): @@ -657,7 +664,8 @@ if pushop.revs: revnums = map(repo.changelog.rev, pushop.revs) ancestors = repo.changelog.ancestors(revnums, inclusive=True) -remotebookmark = remote.listkeys('bookmarks') + +remotebookmark = listkeys(remote, 'bookmarks') explicit = set([repo._bookmarks.expandname(bookmark) for bookmark in pushop.bookmarks]) @@ -1168,7 +1176,7 @@ """synchronise phase information locally and remotely""" cheads = pushop.commonheads # even when we don't push, exchanging phase data is useful -remotephases = pushop.remote.listkeys('phases') +remotephases = listkeys(pushop.remote, 'phases') if (pushop.ui.configbool('ui', '_usedassubrepo') and remotephases# server supports phases and pushop.cgresult is None # nothing was pushed @@ -1392,6 +1400,10 @@ if self._tr is not None: self._tr.release() +def listkeys(remote, namespace): +with remote.commandexecutor() as e: +return e.callcommand('listkeys', {'namespace': namespace}).result() + def _fullpullbundle2(repo, pullop): # The server may send a partial reply, i.e. when inlining # pre-computed bundles. In that case, update the common @@ -1529,7 +1541,7 @@ # all known bundle2 servers now support listkeys, but lets be nice with # new implementation. return -books = pullop.remote.listkeys('bookmarks') +books = listkeys(pullop.remote, 'bookmarks') pullop.remotebookmarks = bookmod.unhexlifybookmarks(books) @@ -1741,7 +1753,7 @@ # Get remote phases data from remote if 'phases' in pullop.stepsdone: return -remotephases = pullop.remote.listkeys('phases') +remotephases = listkeys(pullop.remote, 'phases') _pullapplyphases(pullop, remotephases) def _pullapplyphases(pullop, remotephases): @@ -1805,7 +1817,7 @@ tr = None if obsolete.isenabled(pullop.repo, obsolete.exchangeopt): pullop.repo.ui.debug('fetching remote obsolete markers\n') -remoteobs = pullop.remote.listkeys('obsolete') +remoteobs = listkeys(pullop.remote, 'obsolete') if 'dump0' in remoteobs: tr = pullop.gettransaction() markers = [] 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
D3391: commands: use command executor interface
This revision was automatically updated to reflect the committed changes. Closed by commit rHG9b3a348c9b2f: commands: use command executor interface (authored by indygreg, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3391?vs=8318=8364 REVISION DETAIL https://phab.mercurial-scm.org/D3391 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 @@ -4037,7 +4037,9 @@ oldrevs = revs revs = [] # actually, nodes for r in oldrevs: -node = other.lookup(r) +with other.commandexecutor() as e: +node = e.callcommand('lookup', {'key': r}).result() + revs.append(node) if r == checkout: checkout = node 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
D2934: forget: add --confirm option
This revision was automatically updated to reflect the committed changes. Closed by commit rHGe7bf5a73e4e1: forget: add --confirm option (authored by khanchi97, committed by ). CHANGED PRIOR TO COMMIT https://phab.mercurial-scm.org/D2934?vs=7285=8362#toc REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D2934?vs=7285=8362 REVISION DETAIL https://phab.mercurial-scm.org/D2934 AFFECTED FILES hgext/largefiles/overrides.py mercurial/cmdutil.py mercurial/commands.py mercurial/subrepo.py tests/test-add.t tests/test-completion.t CHANGE DETAILS diff --git a/tests/test-completion.t b/tests/test-completion.t --- a/tests/test-completion.t +++ b/tests/test-completion.t @@ -232,7 +232,7 @@ commit: addremove, close-branch, amend, secret, edit, interactive, include, exclude, message, logfile, date, user, subrepos diff: rev, change, text, git, binary, nodates, noprefix, show-function, reverse, ignore-all-space, ignore-space-change, ignore-blank-lines, ignore-space-at-eol, unified, stat, root, include, exclude, subrepos export: output, switch-parent, rev, text, git, binary, nodates, template - forget: include, exclude, dry-run + forget: include, exclude, dry-run, confirm init: ssh, remotecmd, insecure log: follow, follow-first, date, copies, keyword, rev, line-range, removed, only-merges, user, only-branch, branch, prune, patch, git, limit, no-merges, stat, graph, style, template, include, exclude merge: force, rev, preview, abort, tool diff --git a/tests/test-add.t b/tests/test-add.t --- a/tests/test-add.t +++ b/tests/test-add.t @@ -272,3 +272,58 @@ [1] $ cd .. + +test --confirm option in forget + + $ hg init forgetconfirm + $ cd forgetconfirm + $ echo foo > foo + $ hg commit -qAm "foo" + $ echo bar > bar + $ hg commit -qAm "bar" + $ hg forget foo --dry-run --confirm + abort: cannot specify both --dry-run and --confirm + [255] + + $ hg forget foo --config ui.interactive=True --confirm << EOF + > ? + > n + > EOF + forget foo [Ynsa?] ? + y - yes, forget this file + n - no, skip this file + s - skip remaining files + a - include all remaining files + ? - ? (display help) + forget foo [Ynsa?] n + + $ hg forget foo bar --config ui.interactive=True --confirm << EOF + > y + > n + > EOF + forget bar [Ynsa?] y + forget foo [Ynsa?] n + removing bar + $ hg status + R bar + $ hg up -qC . + + $ hg forget foo bar --config ui.interactive=True --confirm << EOF + > s + > EOF + forget bar [Ynsa?] s + $ hg st + $ hg up -qC . + + $ hg forget foo bar --config ui.interactive=True --confirm << EOF + > a + > EOF + forget bar [Ynsa?] a + removing bar + removing foo + $ hg status + R bar + R foo + $ hg up -qC . + + $ cd .. diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py --- a/mercurial/subrepo.py +++ b/mercurial/subrepo.py @@ -352,7 +352,7 @@ matched by the match function ''' -def forget(self, match, prefix, dryrun): +def forget(self, match, prefix, dryrun, confirm): return ([], []) def removefiles(self, matcher, prefix, after, force, subrepos, @@ -815,10 +815,10 @@ return ctx.walk(match) @annotatesubrepoerror -def forget(self, match, prefix, dryrun): +def forget(self, match, prefix, dryrun, confirm): return cmdutil.forget(self.ui, self._repo, match, self.wvfs.reljoin(prefix, self._path), - True, dryrun=dryrun) + True, dryrun=dryrun, confirm=confirm) @annotatesubrepoerror def removefiles(self, matcher, prefix, after, force, subrepos, diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -112,6 +112,7 @@ ] dryrunopts = cmdutil.dryrunopts +confirmopts = cmdutil.confirmopts remoteopts = cmdutil.remoteopts walkopts = cmdutil.walkopts commitopts = cmdutil.commitopts @@ -2060,7 +2061,7 @@ @command( '^forget', -walkopts + dryrunopts, +walkopts + dryrunopts + confirmopts, _('[OPTION]... FILE...'), inferrepo=True) def forget(ui, repo, *pats, **opts): """forget the specified files on the next commit @@ -2096,9 +2097,10 @@ raise error.Abort(_('no files specified')) m = scmutil.match(repo[None], pats, opts) -dryrun = opts.get('dry_run') +dryrun, confirm = opts.get('dry_run'), opts.get('confirm') rejected = cmdutil.forget(ui, repo, m, prefix="", - explicitonly=False, dryrun=dryrun)[0] + explicitonly=False, dryrun=dryrun, + confirm=confirm)[0] return rejected and 1 or 0 @command( diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py --- a/mercurial/cmdutil.py +++ b/mercurial/cmdutil.py @@ -63,6 +63,11 @@ _('do not perform actions, just print output')), ] +confirmopts = [ +('', 'confirm', None, + _('ask
D2934: forget: add --confirm option
durin42 accepted this revision. durin42 added a comment. I've touched this up in-flight and will land it, thanks. (Suggestion: diff the output of `hg export` on your version vs the one that lands to see what I needed to tweak - there were some oversights in tests during development it looks like.) REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D2934 To: khanchi97, #hg-reviewers, av6, pulkit, durin42 Cc: durin42, mharbison72, yuja, pulkit, av6, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D2668: rebase: introduce support for automatically rebasing orphan changes
durin42 updated this revision to Diff 8361. durin42 edited the summary of this revision. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D2668?vs=7914=8361 REVISION DETAIL https://phab.mercurial-scm.org/D2668 AFFECTED FILES hgext/rebase.py tests/test-rebase-obsolete.t CHANGE DETAILS diff --git a/tests/test-rebase-obsolete.t b/tests/test-rebase-obsolete.t --- a/tests/test-rebase-obsolete.t +++ b/tests/test-rebase-obsolete.t @@ -482,7 +482,31 @@ |/ o 0:cd010b8cd998 A + $ cd .. + $ cp -R hidden stabilize + $ cd stabilize + $ hg rebase --auto-orphans '0::' + rebasing 9:cf44d2f5a9f4 "D" + $ hg log -G + o 12:7e3935feaa68 D + | + o 11:0d8f238b634c C + | + o 10:7c6027df6a99 B + | + @ 7:02de42196ebe H + | + | o 6:eea13746799a G + |/| + o | 5:24b6387c8c8c F + | | + | o 4:9520eea781bc E + |/ + o 0:cd010b8cd998 A + + $ cd ../hidden + $ rm -r ../stabilize Test multiple root handling diff --git a/hgext/rebase.py b/hgext/rebase.py --- a/hgext/rebase.py +++ b/hgext/rebase.py @@ -108,6 +108,53 @@ sourceset = revset.getset(repo, smartset.fullreposet(repo), x) return subset & smartset.baseset([_destrebase(repo, sourceset)]) +def _possibledestination(repo, rev): +"""Return all changesets that may be a new parent for `rev`.""" +tonode = repo.changelog.node +parents = repo.changelog.parentrevs +torev = repo.changelog.rev +dest = set() +tovisit = list(parents(rev)) +while tovisit: +r = tovisit.pop() +succsets = obsutil.successorssets(repo, tonode(r)) +if not succsets: +# if there are no successors for r, r was probably pruned +# and we should walk up to r's parents to try and find +# some successors. +tovisit.extend(parents(r)) +else: +# We should probably pick only one destination from split +# (case where '1 < len(ss)'), This could be the currently +# tipmost, but the correct result is less clear when +# results of the split have been moved such that they +# reside on multiple branches. +for ss in succsets: +for n in ss: +dr = torev(n) +if dr != -1: +dest.add(dr) +return dest + +@revsetpredicate('_destautoorphanrebase') +def _revsetdestautoorphanrebase(repo, subset, x): +"""automatic rebase destination for a single orphan revision""" +unfi = repo.unfiltered() +obsoleted = unfi.revs('obsolete()') + +src = revset.getset(repo, subset, x).first() + +# Empty src or already obsoleted - Do not return a destination +if not src or src in obsoleted: +return smartset.baseset() +dests = _possibledestination(repo, src) +if len(dests) > 1: +raise error.Abort( +_("ambiguous automatic rebase: %r could end up on any of %r") % ( +src, dests)) +# We have zero or one destination, so we can just return here. +return smartset.baseset(dests) + def _ctxdesc(ctx): """short description for a context""" desc = '%d:%s "%s"' % (ctx.rev(), ctx, @@ -651,7 +698,10 @@ ('i', 'interactive', False, _('(DEPRECATED)')), ('t', 'tool', '', _('specify merge tool')), ('c', 'continue', False, _('continue an interrupted rebase')), -('a', 'abort', False, _('abort an interrupted rebase'))] + +('a', 'abort', False, _('abort an interrupted rebase')), +('', 'auto-orphans', '', _('automatically rebase orphan revisions ' + 'in the specified revset (EXPERIMENTAL)')), + ] + cmdutil.formatteropts, _('[-s REV | -b REV] [-d REV] [OPTION]')) def rebase(ui, repo, **opts): @@ -783,6 +833,15 @@ # fail the entire transaction.) inmemory = False +if opts.get('auto_orphans'): +for key in opts: +if key != 'auto_orphans' and opts.get(key): +raise error.Abort(_('--auto-orphans is incompatible with %s') % + ('--' + key)) +userrevs = list(repo.revs(opts.get('auto_orphans'))) +opts['rev'] = [revsetlang.formatspec('%ld and orphan()', userrevs)] +opts['dest'] = '_destautoorphanrebase(SRC)' + if inmemory: try: # in-memory merge doesn't support conflicts, so if we hit any, abort To: durin42, #hg-reviewers, indygreg Cc: mbthomas, spectral, quark, indygreg, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3393: bundle: introduce per-engine compression level
joerg.sonnenberger created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY If experimental.bundlecomplevel.$engine is set, prefer it over the generic experimental.bundlecomplevel. Given that compression levels have widely different meanings across engines, this allows much saner configuration. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3393 AFFECTED FILES mercurial/commands.py mercurial/configitems.py tests/test-bundle-type.t CHANGE DETAILS diff --git a/tests/test-bundle-type.t b/tests/test-bundle-type.t --- a/tests/test-bundle-type.t +++ b/tests/test-bundle-type.t @@ -154,6 +154,11 @@ $ f --size gzip-v2-level1.hg gzip-v2-level1.hg: size=475 + $ hg --config experimental.bundlecomplevel.gzip=1 --config experimental.bundlelevel=9 bundle -a -t gzip-v2 gzip-v2-level1.hg + 1 changesets found + $ f --size gzip-v2-level1.hg + gzip-v2-level1.hg: size=475 + $ cd .. #if zstd diff --git a/mercurial/configitems.py b/mercurial/configitems.py --- a/mercurial/configitems.py +++ b/mercurial/configitems.py @@ -440,6 +440,18 @@ coreconfigitem('experimental', 'bundlecomplevel', default=None, ) +coreconfigitem('experimental', 'bundlecomplevel.bzip2', +default=None, +) +coreconfigitem('experimental', 'bundlecomplevel.gzip', +default=None, +) +coreconfigitem('experimental', 'bundlecomplevel.none', +default=None, +) +coreconfigitem('experimental', 'bundlecomplevel.zstd', +default=None, +) coreconfigitem('experimental', 'changegroup3', default=False, ) diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -1258,7 +1258,10 @@ # level without a) formalizing the bundlespec changes to declare it # b) introducing a command flag. compopts = {} -complevel = ui.configint('experimental', 'bundlecomplevel') +complevel = ui.configint('experimental', + 'bundlecomplevel.' + bundlespec.compression) +if complevel is None: +complevel = ui.configint('experimental', 'bundlecomplevel') if complevel is not None: compopts['level'] = complevel To: joerg.sonnenberger, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3392: bundlespec: drop externalnames flag
joerg.sonnenberger created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY Always provide the human readable version of compression and version. Add the translated wire format name in the new wirecompression and wireversion fields. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3392 AFFECTED FILES mercurial/commands.py mercurial/exchange.py CHANGE DETAILS diff --git a/mercurial/exchange.py b/mercurial/exchange.py --- a/mercurial/exchange.py +++ b/mercurial/exchange.py @@ -86,11 +86,13 @@ @attr.s class bundlespec(object): compression = attr.ib() +wirecompression = attr.ib() version = attr.ib() +wireversion = attr.ib() params = attr.ib() contentopts = attr.ib() -def parsebundlespec(repo, spec, strict=True, externalnames=False): +def parsebundlespec(repo, spec, strict=True): """Parse a bundle string specification into parts. Bundle specifications denote a well-defined bundle/exchange format. @@ -110,9 +112,6 @@ If ``strict`` is True (the default) is required. Otherwise, it is optional. -If ``externalnames`` is False (the default), the human-centric names will -be converted to their internal representation. - Returns a bundlespec object of (compression, version, parameters). Compression will be ``None`` if not in strict mode and a compression isn't defined. @@ -215,12 +214,12 @@ variant = _bundlespecvariants["streamv2"] contentopts.update(variant) -if not externalnames: -engine = util.compengines.forbundlename(compression) -compression = engine.bundletype()[1] -version = _bundlespeccgversions[version] +engine = util.compengines.forbundlename(compression) +compression, wirecompression = engine.bundletype() +wireversion = _bundlespeccgversions[version] -return bundlespec(compression, version, params, contentopts) +return bundlespec(compression, wirecompression, version, wireversion, + params, contentopts) def readbundle(ui, fh, fname, vfs=None): header = changegroup.readexactly(fh, 4) @@ -2241,8 +2240,7 @@ # component of the BUNDLESPEC. if key == 'BUNDLESPEC': try: -bundlespec = parsebundlespec(repo, value, - externalnames=True) +bundlespec = parsebundlespec(repo, value) attrs['COMPRESSION'] = bundlespec.compression attrs['VERSION'] = bundlespec.version except error.InvalidBundleSpecification: @@ -2256,11 +2254,12 @@ def isstreamclonespec(bundlespec): # Stream clone v1 -if (bundlespec.compression == 'UN' and bundlespec.version == 's1'): +if (bundlespec.wirecompression == 'UN' and bundlespec.wireversion == 's1'): return True # Stream clone v2 -if (bundlespec.compression == 'UN' and bundlespec.version == '02' and \ +if (bundlespec.wirecompression == 'UN' and \ +bundlespec.wireversion == '02' and \ bundlespec.contentopts.get('streamv2')): return True diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -1243,14 +1243,12 @@ scmutil.nochangesfound(ui, repo, not base and outgoing.excluded) return 1 -bcompression = bundlespec.compression if cgversion == '01': #bundle1 -if bcompression is None: -bcompression = 'UN' -bversion = 'HG10' + bcompression +bversion = 'HG10' + bundlespec.wirecompression bcompression = None elif cgversion in ('02', '03'): bversion = 'HG20' +bcompression = bundlespec.wirecompression else: raise error.ProgrammingError( 'bundle: unexpected changegroup version %s' % cgversion) To: joerg.sonnenberger, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[Bug 5839] New: `hg split` can break when using diff.ignoreblanklines
https://bz.mercurial-scm.org/show_bug.cgi?id=5839 Bug ID: 5839 Summary: `hg split` can break when using diff.ignoreblanklines Product: Mercurial Version: unspecified Hardware: PC OS: Linux Status: UNCONFIRMED Severity: feature Priority: wish Component: record Assignee: bugzi...@mercurial-scm.org Reporter: h...@pewpew.net CC: mercurial-devel@mercurial-scm.org To reproduce: - Create a repo with two files, bar and foo, which have the contents of: the numbers 1-5, each on their own line (these contents don't really matter, but we need a few lines). - Commit - Create a second commit, adding a blank line to bar, and another line somewhere else (not part of the same diff hunk). Make some modification to foo, it doesn't matter much which - try to split it, keeping bar in the first commit, foo in the second Expected behavior: two commits Actual behavior: Never-ending series of 'no changes to record' This seems likely to be related to "whitespace=True" on this line: https://www.mercurial-scm.org/repo/hg/file/tip/mercurial/cmdutil.py#l278, I don't know why we would want split (or record...) to respect that :) ≻ hg version Mercurial Distributed SCM (version 4.5.2+1195-a708e1e4d7a8) (see https://mercurial-scm.org for more information) Copyright (C) 2005-2018 Matt Mackall and others This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. This is an untested .t file that resembles my shell when reproducing this: $ hg init $ printf '1\n2\n3\n4\n5\n' > foo $ cp foo bar $ hg ci -qAm initial $ printf '1\n\n2\n3\ntest\n4\n5\n' > bar $ printf '1\n2\n3\ntest\n4\n5\n' > foo $ hg ci -qm splitme $ hg diff -c . diff -r c51f1e043c06 -r 3d637dc4e862 bar --- a/bar Mon Apr 16 17:24:07 2018 -0700 +++ b/bar Mon Apr 16 17:24:44 2018 -0700 @@ -1,5 +1,7 @@ 1 + 2 3 +test 4 5 diff -r c51f1e043c06 -r 3d637dc4e862 foo --- a/foo Mon Apr 16 17:24:07 2018 -0700 +++ b/foo Mon Apr 16 17:24:44 2018 -0700 @@ -1,5 +1,6 @@ 1 2 3 +test 4 5 $ hg --config extensions.split= --config diff.ignoreblanklines=1 split diff --git a/bar b/bar 1 hunks, 1 lines changed examine changes to 'bar'? [Ynesfdaq?] f diff --git a/foo b/foo 1 hunks, 1 lines changed examine changes to 'foo'? [Ynesfdaq?] n created new head diff --git a/foo b/foo 1 hunks, 1 lines changed examine changes to 'foo'? [Ynesfdaq?] f no changes to record no changes to record -- You are receiving this mail because: You are on the CC list for the bug. ___ 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
This revision was automatically updated to reflect the committed changes. Closed by commit rHG700aaa19de63: tests: fix up a couple of minor bytes inconsistencies in run-tests.py (authored by durin42, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3350?vs=8313=8345 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 @@ -393,6 +393,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, indygreg 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
This revision was automatically updated to reflect the committed changes. Closed by commit rHG73d0a3dd7e53: stringutil: teach pprint how to format None (authored by durin42, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3358?vs=8272=8352 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, indygreg 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
This revision was automatically updated to reflect the committed changes. Closed by commit rHG886754323bed: largefiles: opts appears to already be bytes in this instance (authored by durin42, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3364?vs=8316=8358 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 @@ -211,6 +211,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, indygreg 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
This revision was automatically updated to reflect the committed changes. Closed by commit rHG89d82d2b68e9: py3: fix test-shelve.t on Python 3 (authored by durin42, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3351?vs=8314=8344 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 @@ -398,6 +398,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, indygreg 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
This revision was automatically updated to reflect the committed changes. Closed by commit rHGb29f490eb904: hgweb_mod: inform hgweb class about paths actually being bytes (authored by durin42, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3355?vs=8232=8349 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, indygreg 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
This revision was automatically updated to reflect the committed changes. Closed by commit rHG2d5b5bcc3b9f: wsgicgi: un-do some prior porting work that is now wrong (authored by durin42, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3356?vs=8315=8350 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, indygreg 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
This revision was automatically updated to reflect the committed changes. Closed by commit rHG42567ffa10a2: hgweb: inform hgweb.hgweb() entrypoint that paths should be bytes (authored by durin42, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3354?vs=8231=8348 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, indygreg 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
This revision was automatically updated to reflect the committed changes. Closed by commit rHGf450a3be62ec: tests: manually print list in test-hook.t (authored by durin42, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3362?vs=8239=8355 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, indygreg 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
This revision was automatically updated to reflect the committed changes. Closed by commit rHG9bbb13c0f982: tests: port inline extensions in test-hook.t to py3 (authored by durin42, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3363?vs=8240=8357 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, indygreg 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
This revision was automatically updated to reflect the committed changes. Closed by commit rHG25136e03012e: lfcommands: use %d on known-int in format string (authored by durin42, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3352?vs=8229=8346 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, indygreg 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
This revision was automatically updated to reflect the committed changes. Closed by commit rHGaffcecf20c15: tests: update inline extensions in test-bundle2-exchange.t to py3 (authored by durin42, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3357?vs=8234=8351 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, indygreg 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
This revision was automatically updated to reflect the committed changes. Closed by commit rHGf7194c925003: stringutil: make b prefixes on string output optional (authored by durin42, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3359?vs=8273=8353 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, indygreg 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
This revision was automatically updated to reflect the committed changes. Closed by commit rHG1b71a397d6b2: tests: make sure test-run-tests.t actually runs run-tests.py under Python 3 (authored by durin42, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3349?vs=8226=8343 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, indygreg Cc: indygreg, 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
This revision was automatically updated to reflect the committed changes. Closed by commit rHGce4ae9ead9e7: py3: another three passing (authored by durin42, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3348?vs=8312=8342 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 @@ -176,6 +177,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 @@ -433,6 +435,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, indygreg 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
This revision was automatically updated to reflect the committed changes. Closed by commit rHGa1f785148097: httppeer: work around API differences on urllib Request objects (authored by durin42, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3347?vs=8224=8341 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, indygreg 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
This revision was automatically updated to reflect the committed changes. Closed by commit rHGe10b695b9c41: httppeer: fix debug prints to work on Python 3 (authored by durin42, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3345?vs=8222=8339 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, indygreg 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
This revision was automatically updated to reflect the committed changes. Closed by commit rHG126998dcfb08: url: some bytes/str cleanup where we interface with stdlib funcs (authored by durin42, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3344?vs=8221=8338 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, indygreg 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
This revision was automatically updated to reflect the committed changes. Closed by commit rHG6cb7e3b91883: httppeer: no matter what Python 3 might think, http headers are bytes (authored by durin42, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3346?vs=8223=8340 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, indygreg 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
This revision was automatically updated to reflect the committed changes. Closed by commit rHGd43810fe52b0: tests: port inline extensions in test-http.t to Python 3 (authored by durin42, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3342?vs=8219=8336 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, indygreg 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
This revision was automatically updated to reflect the committed changes. Closed by commit rHGa1110db1e455: hgweb: these strings should be sysstrs, not bytes (authored by durin42, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3343?vs=8311=8337 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 @@ -133,7 +133,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, indygreg 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
indygreg accepted this revision. indygreg added a comment. This revision is now accepted and ready to land. *facepalm* REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3349 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
D3212: patch: implement a new worddiff algorithm
This revision was automatically updated to reflect the committed changes. Closed by commit rHG35632d392279: patch: implement a new worddiff algorithm (authored by quark, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3212?vs=7924=8335 REVISION DETAIL https://phab.mercurial-scm.org/D3212 AFFECTED FILES mercurial/color.py mercurial/patch.py tests/test-diff-color.t CHANGE DETAILS diff --git a/tests/test-diff-color.t b/tests/test-diff-color.t --- a/tests/test-diff-color.t +++ b/tests/test-diff-color.t @@ -337,41 +337,39 @@ [diff.deleted|-(to see if it works)] [diff.inserted|+three of those lines have] [diff.inserted|+collapsed onto one] -#if false $ hg diff --config experimental.worddiff=True --color=debug [diff.diffline|diff --git a/file1 b/file1] [diff.file_a|--- a/file1] [diff.file_b|+++ b/file1] [diff.hunk|@@ -1,16 +1,17 @@] - [diff.deleted|-this is the ][diff.deleted.highlight|first][diff.deleted| line] - [diff.deleted|-this is the second line] - [diff.deleted|-][diff.deleted.highlight|][diff.deleted|third line starts with space] - [diff.deleted|-][diff.deleted.highlight|+][diff.deleted| starts with a ][diff.deleted.highlight|plus][diff.deleted| sign] - [diff.deleted|-][diff.tab| ][diff.deleted|this one with ][diff.deleted.highlight|one][diff.deleted| tab] - [diff.deleted|-][diff.tab| ][diff.deleted|now with full ][diff.deleted.highlight|two][diff.deleted| tabs] - [diff.deleted|-][diff.tab| ][diff.deleted|now tabs][diff.tab| ][diff.deleted|everywhere, much fun] - [diff.inserted|+that is the first paragraph] - [diff.inserted|+][diff.inserted.highlight|][diff.inserted|this is the ][diff.inserted.highlight|second][diff.inserted| line] - [diff.inserted|+third line starts with space] - [diff.inserted|+][diff.inserted.highlight|-][diff.inserted| starts with a ][diff.inserted.highlight|minus][diff.inserted| sign] - [diff.inserted|+][diff.tab| ][diff.inserted|this one with ][diff.inserted.highlight|two][diff.inserted| tab] - [diff.inserted|+][diff.tab| ][diff.inserted|now with full ][diff.inserted.highlight|three][diff.inserted| tabs] - [diff.inserted|+][diff.tab| ][diff.inserted|now][diff.inserted.highlight| there are][diff.inserted| tabs][diff.tab| ][diff.inserted|everywhere, much fun] + [diff.deleted|-][diff.deleted.changed|this][diff.deleted.unchanged| is the first ][diff.deleted.changed|line] + [diff.deleted|-][diff.deleted.unchanged|this is the second line] + [diff.deleted|-][diff.deleted.changed|][diff.deleted.unchanged|third line starts with space] + [diff.deleted|-][diff.deleted.changed|+][diff.deleted.unchanged| starts with a ][diff.deleted.changed|plus][diff.deleted.unchanged| sign] + [diff.deleted|-][diff.tab| ][diff.deleted.unchanged|this one with ][diff.deleted.changed|one][diff.deleted.unchanged| tab] + [diff.deleted|-][diff.tab| ][diff.deleted.unchanged|now with full ][diff.deleted.changed|two][diff.deleted.unchanged| tabs] + [diff.deleted|-][diff.tab| ][diff.deleted.unchanged|now ][diff.deleted.unchanged|tabs][diff.tab| ][diff.deleted.unchanged|everywhere, much fun] + [diff.inserted|+][diff.inserted.changed|that][diff.inserted.unchanged| is the first ][diff.inserted.changed|paragraph] + [diff.inserted|+][diff.inserted.changed|][diff.inserted.unchanged|this is the second line] + [diff.inserted|+][diff.inserted.unchanged|third line starts with space] + [diff.inserted|+][diff.inserted.changed|-][diff.inserted.unchanged| starts with a ][diff.inserted.changed|minus][diff.inserted.unchanged| sign] + [diff.inserted|+][diff.tab| ][diff.inserted.unchanged|this one with ][diff.inserted.changed|two][diff.inserted.unchanged| tab] + [diff.inserted|+][diff.tab| ][diff.inserted.unchanged|now with full ][diff.inserted.changed|three][diff.inserted.unchanged| tabs] + [diff.inserted|+][diff.tab| ][diff.inserted.unchanged|now ][diff.inserted.changed|there are ][diff.inserted.unchanged|tabs][diff.tab| ][diff.inserted.unchanged|everywhere, much fun] this line won't change two lines are going to - [diff.deleted|-be changed into ][diff.deleted.highlight|three][diff.deleted|!] - [diff.inserted|+(entirely magically,] - [diff.inserted|+ assuming this works)] - [diff.inserted|+be changed into ][diff.inserted.highlight|four][diff.inserted|!] + [diff.deleted|-][diff.deleted.unchanged|be changed into ][diff.deleted.changed|three][diff.deleted.unchanged|!] + [diff.inserted|+][diff.inserted.changed|(entirely magically,] + [diff.inserted|+][diff.inserted.changed| assuming this works)] + [diff.inserted|+][diff.inserted.unchanged|be changed into ][diff.inserted.changed|four][diff.inserted.unchanged|!] - [diff.deleted|-three of those lines ][diff.deleted.highlight|will] -
D3211: patch: buffer lines for a same hunk
This revision was automatically updated to reflect the committed changes. Closed by commit rHG5471348921c1: patch: buffer lines for a same hunk (authored by quark, committed by ). CHANGED PRIOR TO COMMIT https://phab.mercurial-scm.org/D3211?vs=7923=8334#toc REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3211?vs=7923=8334 REVISION DETAIL https://phab.mercurial-scm.org/D3211 AFFECTED FILES mercurial/patch.py tests/test-diff-color.t CHANGE DETAILS diff --git a/tests/test-diff-color.t b/tests/test-diff-color.t --- a/tests/test-diff-color.t +++ b/tests/test-diff-color.t @@ -337,6 +337,7 @@ [diff.deleted|-(to see if it works)] [diff.inserted|+three of those lines have] [diff.inserted|+collapsed onto one] +#if false $ hg diff --config experimental.worddiff=True --color=debug [diff.diffline|diff --git a/file1 b/file1] [diff.file_a|--- a/file1] @@ -370,6 +371,7 @@ [diff.deleted|-(to see if it works)] [diff.inserted|+three of those lines ][diff.inserted.highlight|have] [diff.inserted|+][diff.inserted.highlight|collapsed][diff.inserted| onto one] +#endif multibyte character shouldn't be broken up in word diff: @@ -383,10 +385,13 @@ > f.write(b"blah \xe3\x82\xa4 blah\n") > EOF $ hg ci -m 'slightly change utf8 char' utf8 + +#if false $ hg diff --config experimental.worddiff=True --color=debug -c. [diff.diffline|diff --git a/utf8 b/utf8] [diff.file_a|--- a/utf8] [diff.file_b|+++ b/utf8] [diff.hunk|@@ -1,1 +1,1 @@] [diff.deleted|-blah ][diff.deleted.highlight|\xe3\x82\xa2][diff.deleted| blah] (esc) [diff.inserted|+blah ][diff.inserted.highlight|\xe3\x82\xa4][diff.inserted| blah] (esc) +#endif diff --git a/mercurial/patch.py b/mercurial/patch.py --- a/mercurial/patch.py +++ b/mercurial/patch.py @@ -11,7 +11,6 @@ import collections import contextlib import copy -import difflib import email import errno import hashlib @@ -2481,11 +2480,32 @@ else: return difffn(opts, None) +def diffsinglehunk(hunklines): +"""yield tokens for a list of lines in a single hunk""" +for line in hunklines: +# chomp +chompline = line.rstrip('\n') +# highlight tabs and trailing whitespace +stripline = chompline.rstrip() +if line[0] == '-': +label = 'diff.deleted' +elif line[0] == '+': +label = 'diff.inserted' +else: +raise error.ProgrammingError('unexpected hunk line: %s' % line) +for token in tabsplitter.findall(stripline): +if '\t' == token[0]: +yield (token, 'diff.tab') +else: +yield (token, label) + +if chompline != stripline: +yield (chompline[len(stripline):], 'diff.trailingwhitespace') +if chompline != line: +yield (line[len(chompline):], '') + def difflabel(func, *args, **kw): '''yields 2-tuples of (output, label) based on the output of func()''' -inlinecolor = False -if kw.get(r'opts'): -inlinecolor = kw[r'opts'].worddiff headprefixes = [('diff', 'diff.diffline'), ('copy', 'diff.extended'), ('rename', 'diff.extended'), @@ -2497,125 +2517,59 @@ ('---', 'diff.file_a'), ('+++', 'diff.file_b')] textprefixes = [('@', 'diff.hunk'), -('-', 'diff.deleted'), -('+', 'diff.inserted')] +# - and + are handled by diffsinglehunk + ] head = False + +# buffers a hunk, i.e. adjacent "-", "+" lines without other changes. +hunkbuffer = [] +def consumehunkbuffer(): +if hunkbuffer: +for token in diffsinglehunk(hunkbuffer): +yield token +hunkbuffer[:] = [] + for chunk in func(*args, **kw): lines = chunk.split('\n') -matches = {} -if inlinecolor: -matches = _findmatches(lines) linecount = len(lines) for i, line in enumerate(lines): if head: if line.startswith('@'): head = False else: if line and not line.startswith((' ', '+', '-', '@', '\\')): head = True -stripline = line diffline = False if not head and line and line.startswith(('+', '-')): -# highlight tabs and trailing whitespace, but only in -# changed lines -stripline = line.rstrip() diffline = True prefixes = textprefixes if head: prefixes = headprefixes -for prefix, label in prefixes: -if stripline.startswith(prefix): -if diffline: -if i in matches: -for t, l in _inlinediff(lines[i].rstrip(), -
D3385: wireprotov2: change command response protocol to include a leading map
This revision was automatically updated to reflect the committed changes. Closed by commit rHG3ea8323d6f95: wireprotov2: change command response protocol to include a leading map (authored by indygreg, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3385?vs=8297=8328 REVISION DETAIL https://phab.mercurial-scm.org/D3385 AFFECTED FILES mercurial/help/internals/wireprotocol.txt mercurial/wireprotoframing.py mercurial/wireprotov2peer.py 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 tests/test-wireproto-serverreactor.py tests/wireprotohelpers.sh CHANGE DETAILS diff --git a/tests/wireprotohelpers.sh b/tests/wireprotohelpers.sh --- a/tests/wireprotohelpers.sh +++ b/tests/wireprotohelpers.sh @@ -1,5 +1,5 @@ HTTPV2=exp-http-v2-0001 -MEDIATYPE=application/mercurial-exp-framing-0004 +MEDIATYPE=application/mercurial-exp-framing-0005 sendhttpraw() { hg --verbose debugwireproto --peer raw http://$LOCALIP:$HGPORT/ 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 @@ -12,6 +12,8 @@ ffs = framing.makeframefromhumanstring +OK = cbor.dumps({b'status': b'ok'}) + def makereactor(deferoutput=False): return framing.serverreactor(deferoutput=deferoutput) @@ -350,7 +352,7 @@ result = reactor.oncommandresponseready(outstream, 1, b'response') self.assertaction(result, b'sendframes') self.assertframesequal(result[1][b'framegen'], [ -b'1 2 stream-begin command-response eos response', +b'1 2 stream-begin command-response eos %sresponse' % OK, ]) def testmultiframeresponse(self): @@ -366,7 +368,8 @@ result = reactor.oncommandresponseready(outstream, 1, first + second) self.assertaction(result, b'sendframes') self.assertframesequal(result[1][b'framegen'], [ -b'1 2 stream-begin command-response continuation %s' % first, +b'1 2 stream-begin command-response continuation %s' % OK, +b'1 2 0 command-response continuation %s' % first, b'1 2 0 command-response eos %s' % second, ]) @@ -397,7 +400,7 @@ result = reactor.oninputeof() self.assertaction(result, b'sendframes') self.assertframesequal(result[1][b'framegen'], [ -b'1 2 stream-begin command-response eos response', +b'1 2 stream-begin command-response eos %sresponse' % OK, ]) def testmultiplecommanddeferresponse(self): @@ -414,8 +417,8 @@ result = reactor.oninputeof() self.assertaction(result, b'sendframes') self.assertframesequal(result[1][b'framegen'], [ -b'1 2 stream-begin command-response eos response1', -b'3 2 0 command-response eos response2' +b'1 2 stream-begin command-response eos %sresponse1' % OK, +b'3 2 0 command-response eos %sresponse2' % OK, ]) def testrequestidtracking(self): @@ -434,9 +437,9 @@ result = reactor.oninputeof() self.assertaction(result, b'sendframes') self.assertframesequal(result[1][b'framegen'], [ -b'3 2 stream-begin command-response eos response3', -b'1 2 0 command-response eos response1', -b'5 2 0 command-response eos response5', +b'3 2 stream-begin command-response eos %sresponse3' % OK, +b'1 2 0 command-response eos %sresponse1' % OK, +b'5 2 0 command-response eos %sresponse5' % OK, ]) def testduplicaterequestonactivecommand(self): 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 @@ -32,8 +32,8 @@ sending pushkey command s> *\r\n (glob) s> Accept-Encoding: identity\r\n - s> accept: application/mercurial-exp-framing-0004\r\n - s> content-type: application/mercurial-exp-framing-0004\r\n + s> accept: application/mercurial-exp-framing-0005\r\n + s> content-type: application/mercurial-exp-framing-0005\r\n s> content-length: 105\r\n s> host: $LOCALIP:$HGPORT\r\n (glob) s> user-agent: Mercurial debugwireproto\r\n @@ -43,14 +43,14 @@ 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-exp-framing-0004\r\n + s> Content-Type: application/mercurial-exp-framing-0005\r\n s> Transfer-Encoding:
D3210: patch: move yielding "\n" to the end of loop
This revision was automatically updated to reflect the committed changes. Closed by commit rHG8d730f96e792: patch: move yielding \n to the end of loop (authored by quark, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3210?vs=7922=8333 REVISION DETAIL https://phab.mercurial-scm.org/D3210 AFFECTED FILES mercurial/patch.py CHANGE DETAILS diff --git a/mercurial/patch.py b/mercurial/patch.py --- a/mercurial/patch.py +++ b/mercurial/patch.py @@ -2505,9 +2505,8 @@ matches = {} if inlinecolor: matches = _findmatches(lines) +linecount = len(lines) for i, line in enumerate(lines): -if i != 0: -yield ('\n', '') if head: if line.startswith('@'): head = False @@ -2546,6 +2545,8 @@ yield (line, '') if line != stripline: yield (line[len(stripline):], 'diff.trailingwhitespace') +if i + 1 < linecount: +yield ('\n', '') def _findmatches(slist): '''Look for insertion matches to deletion and returns a dict of To: quark, #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
D3389: context: clarify deprecation warning message
This revision was automatically updated to reflect the committed changes. Closed by commit rHG6e137da59ad9: context: clarify deprecation warning message (authored by martinvonz, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3389?vs=8310=8332 REVISION DETAIL https://phab.mercurial-scm.org/D3389 AFFECTED FILES mercurial/context.py CHANGE DETAILS diff --git a/mercurial/context.py b/mercurial/context.py --- a/mercurial/context.py +++ b/mercurial/context.py @@ -398,8 +398,9 @@ #user and the revset may be too costly), use scmutil.revsymbol(repo, x) # * If "x" can be a mix of the above, you'll have to figure it out #yourself -repo.ui.deprecwarn("changectx.__init__ is getting more limited, see source " - "for details", "4.6", stacklevel=4) +repo.ui.deprecwarn("changectx.__init__ is getting more limited, see " + "context.changectxdeprecwarn() for details", "4.6", + stacklevel=4) class changectx(basectx): """A changecontext object makes access to data related to a particular To: martinvonz, #hg-reviewers, durin42 Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3386: wireprotov2: change behavior of error frame
This revision was automatically updated to reflect the committed changes. Closed by commit rHG0c184ca594bb: wireprotov2: change behavior of error frame (authored by indygreg, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3386?vs=8298=8329 REVISION DETAIL https://phab.mercurial-scm.org/D3386 AFFECTED FILES mercurial/help/internals/wireprotocol.txt mercurial/wireprotoframing.py mercurial/wireprotov2server.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 @@ -373,16 +373,18 @@ b'1 2 0 command-response eos %s' % second, ]) -def testapplicationerror(self): +def testservererror(self): reactor = makereactor() instream = framing.stream(1) list(sendcommandframes(reactor, instream, 1, b'mycommand', {})) outstream = reactor.makeoutputstream() -result = reactor.onapplicationerror(outstream, 1, b'some message') +result = reactor.onservererror(outstream, 1, b'some message') self.assertaction(result, b'sendframes') self.assertframesequal(result[1][b'framegen'], [ -b'1 2 stream-begin error-response application some message', +b"1 2 stream-begin error-response 0 " +b"cbor:{b'type': b'server', " +b"b'message': [{b'msg': b'some message'}]}", ]) def test1commanddeferresponse(self): diff --git a/mercurial/wireprotov2server.py b/mercurial/wireprotov2server.py --- a/mercurial/wireprotov2server.py +++ b/mercurial/wireprotov2server.py @@ -311,7 +311,7 @@ command['requestid'], encoded) else: -action, meta = reactor.onapplicationerror( +action, meta = reactor.onservererror( _('unhandled response type from wire proto command')) if action == 'sendframes': diff --git a/mercurial/wireprotoframing.py b/mercurial/wireprotoframing.py --- a/mercurial/wireprotoframing.py +++ b/mercurial/wireprotoframing.py @@ -87,20 +87,12 @@ b'eos': FLAG_COMMAND_RESPONSE_EOS, } -FLAG_ERROR_RESPONSE_PROTOCOL = 0x01 -FLAG_ERROR_RESPONSE_APPLICATION = 0x02 - -FLAGS_ERROR_RESPONSE = { -b'protocol': FLAG_ERROR_RESPONSE_PROTOCOL, -b'application': FLAG_ERROR_RESPONSE_APPLICATION, -} - # Maps frame types to their available flags. FRAME_TYPE_FLAGS = { FRAME_TYPE_COMMAND_REQUEST: FLAGS_COMMAND_REQUEST, FRAME_TYPE_COMMAND_DATA: FLAGS_COMMAND_DATA, FRAME_TYPE_COMMAND_RESPONSE: FLAGS_COMMAND_RESPONSE, -FRAME_TYPE_ERROR_RESPONSE: FLAGS_ERROR_RESPONSE, +FRAME_TYPE_ERROR_RESPONSE: {}, FRAME_TYPE_TEXT_OUTPUT: {}, FRAME_TYPE_PROGRESS: {}, FRAME_TYPE_STREAM_SETTINGS: {}, @@ -394,20 +386,19 @@ if done: break -def createerrorframe(stream, requestid, msg, protocol=False, application=False): +def createerrorframe(stream, requestid, msg, errtype): # TODO properly handle frame size limits. assert len(msg) <= DEFAULT_MAX_FRAME_SIZE -flags = 0 -if protocol: -flags |= FLAG_ERROR_RESPONSE_PROTOCOL -if application: -flags |= FLAG_ERROR_RESPONSE_APPLICATION +payload = cbor.dumps({ +b'type': errtype, +b'message': [{b'msg': msg}], +}, canonical=True) yield stream.makeframe(requestid=requestid, typeid=FRAME_TYPE_ERROR_RESPONSE, - flags=flags, - payload=msg) + flags=0, + payload=payload) def createtextoutputframe(stream, requestid, atoms, maxframesize=DEFAULT_MAX_FRAME_SIZE): @@ -664,12 +655,12 @@ 'framegen': makegen(), } -def onapplicationerror(self, stream, requestid, msg): +def onservererror(self, stream, requestid, msg): ensureserverstream(stream) return 'sendframes', { 'framegen': createerrorframe(stream, requestid, msg, - application=True), + errtype='server'), } def makeoutputstream(self): @@ -1051,6 +1042,7 @@ handlers = { FRAME_TYPE_COMMAND_RESPONSE: self._oncommandresponseframe, +FRAME_TYPE_ERROR_RESPONSE: self._onerrorresponseframe, } meth = handlers.get(frame.typeid) @@ -1071,3 +1063,16 @@ 'eos': frame.flags & FLAG_COMMAND_RESPONSE_EOS, 'data': frame.payload, } + +def _onerrorresponseframe(self, request, frame): +request.state = 'errored' +del self._activerequests[request.requestid] + +# The payload should be a CBOR map. +
D3388: wireprotov2: add support for more response types
This revision was automatically updated to reflect the committed changes. Closed by commit rHG564a3eec6e63: wireprotov2: add support for more response types (authored by indygreg, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3388?vs=8304=8331 REVISION DETAIL https://phab.mercurial-scm.org/D3388 AFFECTED FILES mercurial/wireprotoframing.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 @@ -306,6 +306,15 @@ action, meta = reactor.oncommandresponseready(outstream, command['requestid'], encoded) +elif isinstance(rsp, wireprototypes.v2streamingresponse): +action, meta = reactor.oncommandresponsereadygen(outstream, + command['requestid'], + rsp.gen) +elif isinstance(rsp, wireprototypes.v2errorresponse): +action, meta = reactor.oncommanderror(outstream, + command['requestid'], + rsp.message, + rsp.args) else: action, meta = reactor.onservererror( _('unhandled response type from wire proto command')) diff --git a/mercurial/wireprototypes.py b/mercurial/wireprototypes.py --- a/mercurial/wireprototypes.py +++ b/mercurial/wireprototypes.py @@ -106,6 +106,22 @@ def __init__(self, v): self.value = v +class v2errorresponse(object): +"""Represents a command error for version 2 transports.""" +def __init__(self, message, args=None): +self.message = message +self.args = args + +class v2streamingresponse(object): +"""A response whose data is supplied by a generator. + +The generator can either consist of data structures to CBOR +encode or a stream of already-encoded bytes. +""" +def __init__(self, gen, compressible=True): +self.gen = gen +self.compressible = compressible + # list of nodes encoding / decoding def decodelist(l, sep=' '): if l: diff --git a/mercurial/wireprotoframing.py b/mercurial/wireprotoframing.py --- a/mercurial/wireprotoframing.py +++ b/mercurial/wireprotoframing.py @@ -386,6 +386,56 @@ if done: break +def createbytesresponseframesfromgen(stream, requestid, gen, + maxframesize=DEFAULT_MAX_FRAME_SIZE): +overall = cbor.dumps({b'status': b'ok'}, canonical=True) + +yield stream.makeframe(requestid=requestid, + typeid=FRAME_TYPE_COMMAND_RESPONSE, + flags=FLAG_COMMAND_RESPONSE_CONTINUATION, + payload=overall) + +cb = util.chunkbuffer(gen) + +flags = 0 + +while True: +chunk = cb.read(maxframesize) +if not chunk: +break + +yield stream.makeframe(requestid=requestid, + typeid=FRAME_TYPE_COMMAND_RESPONSE, + flags=flags, + payload=chunk) + +flags |= FLAG_COMMAND_RESPONSE_CONTINUATION + +flags ^= FLAG_COMMAND_RESPONSE_CONTINUATION +flags |= FLAG_COMMAND_RESPONSE_EOS +yield stream.makeframe(requestid=requestid, + typeid=FRAME_TYPE_COMMAND_RESPONSE, + flags=flags, + payload=b'') + +def createcommanderrorresponse(stream, requestid, message, args=None): +m = { +b'status': b'error', +b'error': { +b'message': message, +} +} + +if args: +m[b'error'][b'args'] = args + +overall = cbor.dumps(m, canonical=True) + +yield stream.makeframe(requestid=requestid, + typeid=FRAME_TYPE_COMMAND_RESPONSE, + flags=FLAG_COMMAND_RESPONSE_EOS, + payload=overall) + def createerrorframe(stream, requestid, msg, errtype): # TODO properly handle frame size limits. assert len(msg) <= DEFAULT_MAX_FRAME_SIZE @@ -634,6 +684,19 @@ 'framegen': result, } +def oncommandresponsereadygen(self, stream, requestid, gen): +"""Signal that a bytes response is ready, with data as a generator.""" +ensureserverstream(stream) + +def sendframes(): +for frame in createbytesresponseframesfromgen(stream, requestid, + gen): +yield frame + +self._activecommands.remove(requestid) + +return self._handlesendframes(sendframes()) + def
D3384: wireprotov2: change frame type and name for command response
This revision was automatically updated to reflect the committed changes. Closed by commit rHGdeff7cf7eefd: wireprotov2: change frame type and name for command response (authored by indygreg, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3384?vs=8296=8327 REVISION DETAIL https://phab.mercurial-scm.org/D3384 AFFECTED FILES mercurial/help/internals/wireprotocol.txt mercurial/wireprotoframing.py mercurial/wireprotov2server.py tests/test-http-api-httpv2.t tests/test-http-protocol.t tests/test-wireproto-clientreactor.py 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 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 @@ -211,19 +211,19 @@ results.append(self._sendsingleframe( reactor, ffs(b'1 1 stream-begin command-request new ' b"cbor:{b'name': b'command'}"))) -result = reactor.onbytesresponseready(outstream, 1, b'response1') +result = reactor.oncommandresponseready(outstream, 1, b'response1') self.assertaction(result, b'sendframes') list(result[1][b'framegen']) results.append(self._sendsingleframe( reactor, ffs(b'1 1 stream-begin command-request new ' b"cbor:{b'name': b'command'}"))) -result = reactor.onbytesresponseready(outstream, 1, b'response2') +result = reactor.oncommandresponseready(outstream, 1, b'response2') self.assertaction(result, b'sendframes') list(result[1][b'framegen']) results.append(self._sendsingleframe( reactor, ffs(b'1 1 stream-begin command-request new ' b"cbor:{b'name': b'command'}"))) -result = reactor.onbytesresponseready(outstream, 1, b'response3') +result = reactor.oncommandresponseready(outstream, 1, b'response3') self.assertaction(result, b'sendframes') list(result[1][b'framegen']) @@ -347,10 +347,10 @@ list(sendcommandframes(reactor, instream, 1, b'mycommand', {})) outstream = reactor.makeoutputstream() -result = reactor.onbytesresponseready(outstream, 1, b'response') +result = reactor.oncommandresponseready(outstream, 1, b'response') self.assertaction(result, b'sendframes') self.assertframesequal(result[1][b'framegen'], [ -b'1 2 stream-begin bytes-response eos response', +b'1 2 stream-begin command-response eos response', ]) def testmultiframeresponse(self): @@ -363,11 +363,11 @@ list(sendcommandframes(reactor, instream, 1, b'mycommand', {})) outstream = reactor.makeoutputstream() -result = reactor.onbytesresponseready(outstream, 1, first + second) +result = reactor.oncommandresponseready(outstream, 1, first + second) self.assertaction(result, b'sendframes') self.assertframesequal(result[1][b'framegen'], [ -b'1 2 stream-begin bytes-response continuation %s' % first, -b'1 2 0 bytes-response eos %s' % second, +b'1 2 stream-begin command-response continuation %s' % first, +b'1 2 0 command-response eos %s' % second, ]) def testapplicationerror(self): @@ -392,12 +392,12 @@ self.assertaction(results[0], b'runcommand') outstream = reactor.makeoutputstream() -result = reactor.onbytesresponseready(outstream, 1, b'response') +result = reactor.oncommandresponseready(outstream, 1, b'response') self.assertaction(result, b'noop') result = reactor.oninputeof() self.assertaction(result, b'sendframes') self.assertframesequal(result[1][b'framegen'], [ -b'1 2 stream-begin bytes-response eos response', +b'1 2 stream-begin command-response eos response', ]) def testmultiplecommanddeferresponse(self): @@ -407,15 +407,15 @@ list(sendcommandframes(reactor, instream, 3, b'command2', {})) outstream = reactor.makeoutputstream() -result = reactor.onbytesresponseready(outstream, 1, b'response1') +result = reactor.oncommandresponseready(outstream, 1, b'response1') self.assertaction(result, b'noop') -result = reactor.onbytesresponseready(outstream, 3, b'response2') +result = reactor.oncommandresponseready(outstream, 3, b'response2') self.assertaction(result, b'noop') result = reactor.oninputeof() self.assertaction(result, b'sendframes')
D3382: wireprotov2: define response data as CBOR
This revision was automatically updated to reflect the committed changes. Closed by commit rHG89a16704114c: wireprotov2: define response data as CBOR (authored by indygreg, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3382?vs=8294=8325 REVISION DETAIL https://phab.mercurial-scm.org/D3382 AFFECTED FILES mercurial/debugcommands.py mercurial/help/internals/wireprotocol.txt mercurial/wireprotoframing.py mercurial/wireprotov2peer.py 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 tests/wireprotohelpers.sh CHANGE DETAILS diff --git a/tests/wireprotohelpers.sh b/tests/wireprotohelpers.sh --- a/tests/wireprotohelpers.sh +++ b/tests/wireprotohelpers.sh @@ -1,5 +1,5 @@ HTTPV2=exp-http-v2-0001 -MEDIATYPE=application/mercurial-exp-framing-0003 +MEDIATYPE=application/mercurial-exp-framing-0004 sendhttpraw() { hg --verbose debugwireproto --peer raw http://$LOCALIP:$HGPORT/ @@ -26,16 +26,16 @@ @wireproto.wireprotocommand('customreadonly', permission='pull', transportpolicy=wireproto.POLICY_V2_ONLY) def customreadonlyv2(repo, proto): -return wireprototypes.bytesresponse(b'customreadonly bytes response') +return wireprototypes.cborresponse(b'customreadonly bytes response') @wireproto.wireprotocommand('customreadwrite', permission='push') def customreadwrite(repo, proto): return wireprototypes.bytesresponse(b'customreadwrite bytes response') @wireproto.wireprotocommand('customreadwrite', permission='push', transportpolicy=wireproto.POLICY_V2_ONLY) def customreadwritev2(repo, proto): -return wireprototypes.bytesresponse(b'customreadwrite bytes response') +return wireprototypes.cborresponse(b'customreadwrite bytes response') EOF cat >> $HGRCPATH << EOF 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 @@ -32,8 +32,8 @@ sending pushkey command s> *\r\n (glob) s> Accept-Encoding: identity\r\n - s> accept: application/mercurial-exp-framing-0003\r\n - s> content-type: application/mercurial-exp-framing-0003\r\n + s> accept: application/mercurial-exp-framing-0004\r\n + s> content-type: application/mercurial-exp-framing-0004\r\n s> content-length: 105\r\n s> host: $LOCALIP:$HGPORT\r\n (glob) s> user-agent: Mercurial debugwireproto\r\n @@ -43,14 +43,14 @@ 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-exp-framing-0003\r\n + s> Content-Type: application/mercurial-exp-framing-0004\r\n s> Transfer-Encoding: chunked\r\n s> \r\n s> 9\r\n - s> *\x00\x01\x00\x02\x01F (glob) + s> \x01\x00\x00\x01\x00\x02\x01B s> \xf5 s> \r\n - received frame(size=*; request=1; stream=2; streamflags=stream-begin; type=bytes-response; flags=eos|cbor) (glob) + received frame(size=1; request=1; stream=2; streamflags=stream-begin; type=bytes-response; flags=eos) s> 0\r\n s> \r\n response: True @@ -63,8 +63,8 @@ sending listkeys command s> POST /api/exp-http-v2-0001/ro/listkeys HTTP/1.1\r\n s> Accept-Encoding: identity\r\n - s> accept: application/mercurial-exp-framing-0003\r\n - s> content-type: application/mercurial-exp-framing-0003\r\n + s> accept: application/mercurial-exp-framing-0004\r\n + s> content-type: application/mercurial-exp-framing-0004\r\n s> content-length: 49\r\n s> host: $LOCALIP:$HGPORT\r\n (glob) s> user-agent: Mercurial debugwireproto\r\n @@ -74,14 +74,14 @@ 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-exp-framing-0003\r\n + s> Content-Type: application/mercurial-exp-framing-0004\r\n s> Transfer-Encoding: chunked\r\n s> \r\n s> 35\r\n - s> -\x00\x00\x01\x00\x02\x01F + s> -\x00\x00\x01\x00\x02\x01B s> \xa1A@X(426bada5c67598ca65036d57d9e4b64b0c1ce7a0 s> \r\n - received frame(size=45; request=1; stream=2; streamflags=stream-begin; type=bytes-response; flags=eos|cbor) + received frame(size=45; request=1; stream=2; streamflags=stream-begin; type=bytes-response; flags=eos) s> 0\r\n s> \r\n response: {b'@': b'426bada5c67598ca65036d57d9e4b64b0c1ce7a0'} diff --git a/tests/test-wireproto-command-lookup.t b/tests/test-wireproto-command-lookup.t ---
D3387: wireprotov2: remove support for sending bytes response
This revision was automatically updated to reflect the committed changes. Closed by commit rHG5cdde6158426: wireprotov2: remove support for sending bytes response (authored by indygreg, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3387?vs=8299=8330 REVISION DETAIL https://phab.mercurial-scm.org/D3387 AFFECTED FILES mercurial/wireprotov2server.py CHANGE DETAILS diff --git a/mercurial/wireprotov2server.py b/mercurial/wireprotov2server.py --- a/mercurial/wireprotov2server.py +++ b/mercurial/wireprotov2server.py @@ -301,11 +301,7 @@ res.status = b'200 OK' res.headers[b'Content-Type'] = FRAMINGTYPE -if isinstance(rsp, wireprototypes.bytesresponse): -action, meta = reactor.oncommandresponseready(outstream, - command['requestid'], - rsp.data) -elif isinstance(rsp, wireprototypes.cborresponse): +if isinstance(rsp, wireprototypes.cborresponse): encoded = cbor.dumps(rsp.value, canonical=True) action, meta = reactor.oncommandresponseready(outstream, command['requestid'], 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
D3376: registrar: replace "cmdtype" with an intent-based mechanism (API)
This revision was automatically updated to reflect the committed changes. Closed by commit rHGdfc51a482031: registrar: replace cmdtype with an intent-based mechanism (API) (authored by indygreg, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3376?vs=8288=8319 REVISION DETAIL https://phab.mercurial-scm.org/D3376 AFFECTED FILES mercurial/commands.py mercurial/dispatch.py mercurial/registrar.py tests/test-directaccess.t CHANGE DETAILS diff --git a/tests/test-directaccess.t b/tests/test-directaccess.t --- a/tests/test-directaccess.t +++ b/tests/test-directaccess.t @@ -192,7 +192,7 @@ $ hg log -qr 'null:wdir() & 2147483647' 2147483647: -Commands with undefined cmdtype should not work right now +Commands with undefined intent should not work right now $ hg phase -r 28ad74 abort: hidden revision '28ad74' was rewritten as: 2443a0e66469! diff --git a/mercurial/registrar.py b/mercurial/registrar.py --- a/mercurial/registrar.py +++ b/mercurial/registrar.py @@ -138,15 +138,18 @@ potential repository locations. See ``findrepo()``. If a repository is found, it will be used and passed to the decorated function. -There are three constants in the class which tells what type of the command -that is. That information will be helpful at various places. It will be also -be used to decide what level of access the command has on hidden commits. -The constants are: +The `intents` argument defines a set of intended actions or capabilities +the command is taking. These intents can be used to affect the construction +of the repository object passed to the command. For example, commands +declaring that they are read-only could receive a repository that doesn't +have any methods allowing repository mutation. Other intents could be used +to prevent the command from running if the requested intent could not be +fulfilled. -`unrecoverablewrite` is for those write commands which can't be recovered -like push. -`recoverablewrite` is for write commands which can be recovered like commit. -`readonly` is for commands which are read only. +The following intents are defined: + +readonly + The command is read-only The signature of the decorated function looks like this: def cmd(ui[, repo] [, ] [, ]) @@ -161,29 +164,22 @@ descriptions and examples. """ -unrecoverablewrite = "unrecoverable" -recoverablewrite = "recoverable" -readonly = "readonly" - -possiblecmdtypes = {unrecoverablewrite, recoverablewrite, readonly} - def _doregister(self, func, name, options=(), synopsis=None, norepo=False, optionalrepo=False, inferrepo=False, -cmdtype=unrecoverablewrite): +intents=None): -if cmdtype not in self.possiblecmdtypes: -raise error.ProgrammingError("unknown cmdtype value '%s' for " - "'%s' command" % (cmdtype, name)) func.norepo = norepo func.optionalrepo = optionalrepo func.inferrepo = inferrepo -func.cmdtype = cmdtype +func.intents = intents or set() if synopsis: self._table[name] = func, list(options), synopsis else: self._table[name] = func, list(options) return func +INTENT_READONLY = b'readonly' + class revsetpredicate(_funcregistrarbase): """Decorator to register revset predicate diff --git a/mercurial/dispatch.py b/mercurial/dispatch.py --- a/mercurial/dispatch.py +++ b/mercurial/dispatch.py @@ -35,7 +35,6 @@ hook, profiling, pycompat, -registrar, scmutil, ui as uimod, util, @@ -46,8 +45,6 @@ stringutil, ) -unrecoverablewrite = registrar.command.unrecoverablewrite - class request(object): def __init__(self, args, ui=None, repo=None, fin=None, fout=None, ferr=None, prereposetups=None): @@ -562,7 +559,7 @@ return aliasargs(self.fn, args) def __getattr__(self, name): -adefaults = {r'norepo': True, r'cmdtype': unrecoverablewrite, +adefaults = {r'norepo': True, r'intents': set(), r'optionalrepo': False, r'inferrepo': False} if name not in adefaults: raise AttributeError(name) diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -73,7 +73,7 @@ table.update(debugcommandsmod.command._table) command = registrar.command(table) -readonly = registrar.command.readonly +INTENT_READONLY = registrar.INTENT_READONLY # common command options @@ -1083,7 +1083,8 @@ _('show only branches that have unmerged heads (DEPRECATED)')), ('c', 'closed', False, _('show normal and closed branches')), ] + formatteropts, -_('[-c]'), cmdtype=readonly) +_('[-c]'), +
D3377: hg: pass command intents to repo/peer creation (API)
This revision was automatically updated to reflect the committed changes. Closed by commit rHG0664be4f0c1f: hg: pass command intents to repo/peer creation (API) (authored by indygreg, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3377?vs=8289=8320 REVISION DETAIL https://phab.mercurial-scm.org/D3377 AFFECTED FILES hgext/schemes.py mercurial/bundlerepo.py mercurial/dispatch.py mercurial/hg.py mercurial/httppeer.py mercurial/localrepo.py mercurial/sshpeer.py mercurial/statichttprepo.py mercurial/unionrepo.py CHANGE DETAILS diff --git a/mercurial/unionrepo.py b/mercurial/unionrepo.py --- a/mercurial/unionrepo.py +++ b/mercurial/unionrepo.py @@ -231,7 +231,7 @@ def getcwd(self): return pycompat.getcwd() # always outside the repo -def instance(ui, path, create): +def instance(ui, path, create, intents=None): if create: raise error.Abort(_('cannot create new union repository')) parentpath = ui.config("bundle", "mainreporoot") diff --git a/mercurial/statichttprepo.py b/mercurial/statichttprepo.py --- a/mercurial/statichttprepo.py +++ b/mercurial/statichttprepo.py @@ -215,7 +215,7 @@ def _writecaches(self): pass # statichttprepository are read only -def instance(ui, path, create): +def instance(ui, path, create, intents=None): if create: raise error.Abort(_('cannot create new static-http repository')) return statichttprepository(ui, path[7:]) diff --git a/mercurial/sshpeer.py b/mercurial/sshpeer.py --- a/mercurial/sshpeer.py +++ b/mercurial/sshpeer.py @@ -587,7 +587,7 @@ raise error.RepoError(_('unknown version of SSH protocol: %s') % protoname) -def instance(ui, path, create): +def instance(ui, path, create, intents=None): """Create an SSH peer. The returned object conforms to the ``wireprotov1peer.wirepeer`` interface. diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -413,7 +413,7 @@ 'bisect.state', } -def __init__(self, baseui, path, create=False): +def __init__(self, baseui, path, create=False, intents=None): self.requirements = set() self.filtername = None # wvfs: rooted at the repository root, used to access the working copy @@ -2332,8 +2332,9 @@ assert name.startswith('journal') return os.path.join(base, name.replace('journal', 'undo', 1)) -def instance(ui, path, create): -return localrepository(ui, util.urllocalpath(path), create) +def instance(ui, path, create, intents=None): +return localrepository(ui, util.urllocalpath(path), create, + intents=intents) def islocal(path): return True diff --git a/mercurial/httppeer.py b/mercurial/httppeer.py --- a/mercurial/httppeer.py +++ b/mercurial/httppeer.py @@ -990,7 +990,7 @@ return httppeer(ui, path, respurl, opener, requestbuilder, info['v1capabilities']) -def instance(ui, path, create): +def instance(ui, path, create, intents=None): if create: raise error.Abort(_('cannot create new http repository')) try: diff --git a/mercurial/hg.py b/mercurial/hg.py --- a/mercurial/hg.py +++ b/mercurial/hg.py @@ -157,9 +157,10 @@ # a list of (ui, repo) functions called for wire peer initialization wirepeersetupfuncs = [] -def _peerorrepo(ui, path, create=False, presetupfuncs=None): +def _peerorrepo(ui, path, create=False, presetupfuncs=None, +intents=None): """return a repository object for the specified path""" -obj = _peerlookup(path).instance(ui, path, create) +obj = _peerlookup(path).instance(ui, path, create, intents=intents) ui = getattr(obj, "ui", ui) for f in presetupfuncs or []: f(ui, obj) @@ -172,19 +173,20 @@ f(ui, obj) return obj -def repository(ui, path='', create=False, presetupfuncs=None): +def repository(ui, path='', create=False, presetupfuncs=None, intents=None): """return a repository object for the specified path""" -peer = _peerorrepo(ui, path, create, presetupfuncs=presetupfuncs) +peer = _peerorrepo(ui, path, create, presetupfuncs=presetupfuncs, + intents=intents) repo = peer.local() if not repo: raise error.Abort(_("repository '%s' is not local") % (path or peer.url())) return repo.filtered('visible') -def peer(uiorrepo, opts, path, create=False): +def peer(uiorrepo, opts, path, create=False, intents=None): '''return a repository peer for the specified path''' rui = remoteui(uiorrepo, opts) -return _peerorrepo(rui, path, create).peer() +return _peerorrepo(rui, path, create, intents=intents).peer() def defaultdest(source): '''return default destination of clone if none is given diff --git a/mercurial/dispatch.py b/mercurial/dispatch.py ---
D3379: wireprotov2: move response handling out of httppeer
This revision was automatically updated to reflect the committed changes. Closed by commit rHGa656cba08a04: wireprotov2: move response handling out of httppeer (authored by indygreg, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3379?vs=8291=8322 REVISION DETAIL https://phab.mercurial-scm.org/D3379 AFFECTED FILES mercurial/httppeer.py mercurial/wireprotov2peer.py tests/test-wireproto-command-known.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 @@ -53,7 +53,7 @@ received frame(size=*; request=1; stream=2; streamflags=stream-begin; type=bytes-response; flags=eos|cbor) (glob) s> 0\r\n s> \r\n - response: [] + response: [True] $ sendhttpv2peer << EOF > command listkeys diff --git a/tests/test-wireproto-command-known.t b/tests/test-wireproto-command-known.t --- a/tests/test-wireproto-command-known.t +++ b/tests/test-wireproto-command-known.t @@ -50,7 +50,7 @@ received frame(size=1; request=1; stream=2; streamflags=stream-begin; type=bytes-response; flags=eos|cbor) s> 0\r\n s> \r\n - response: [] + response: [b''] Single known node works diff --git a/mercurial/wireprotov2peer.py b/mercurial/wireprotov2peer.py new file mode 100644 --- /dev/null +++ b/mercurial/wireprotov2peer.py @@ -0,0 +1,135 @@ +# wireprotov2peer.py - client side code for wire protocol version 2 +# +# Copyright 2018 Gregory Szorc+# +# This software may be used and distributed according to the terms of the +# GNU General Public License version 2 or any later version. + +from __future__ import absolute_import + +from .i18n import _ +from .thirdparty import ( +cbor, +) +from . import ( +error, +util, +wireprotoframing, +) + +class clienthandler(object): +"""Object to handle higher-level client activities. + +The ``clientreactor`` is used to hold low-level state about the frame-based +protocol, such as which requests and streams are active. This type is used +for higher-level operations, such as reading frames from a socket, exposing +and managing a higher-level primitive for representing command responses, +etc. This class is what peers should probably use to bridge wire activity +with the higher-level peer API. +""" + +def __init__(self, ui, clientreactor): +self._ui = ui +self._reactor = clientreactor +self._requests = {} +self._futures = {} +self._responses = {} + +def callcommand(self, command, args, f): +"""Register a request to call a command. + +Returns an iterable of frames that should be sent over the wire. +""" +request, action, meta = self._reactor.callcommand(command, args) + +if action != 'noop': +raise error.ProgrammingError('%s not yet supported' % action) + +rid = request.requestid +self._requests[rid] = request +self._futures[rid] = f +self._responses[rid] = { +'cbor': False, +'b': util.bytesio(), +} + +return iter(()) + +def flushcommands(self): +"""Flush all queued commands. + +Returns an iterable of frames that should be sent over the wire. +""" +action, meta = self._reactor.flushcommands() + +if action != 'sendframes': +raise error.ProgrammingError('%s not yet supported' % action) + +return meta['framegen'] + +def readframe(self, fh): +"""Attempt to read and process a frame. + +Returns None if no frame was read. Presumably this means EOF. +""" +frame = wireprotoframing.readframe(fh) +if frame is None: +# TODO tell reactor? +return + +self._ui.note(_('received %r\n') % frame) +self._processframe(frame) + +return True + +def _processframe(self, frame): +"""Process a single read frame.""" + +action, meta = self._reactor.onframerecv(frame) + +if action == 'error': +e = error.RepoError(meta['message']) + +if frame.requestid in self._futures: +self._futures[frame.requestid].set_exception(e) +else: +raise e + +if frame.requestid not in self._requests: +raise error.ProgrammingError( +'received frame for unknown request; this is either a bug in ' +'the clientreactor not screening for this or this instance was ' +'never told about this request: %r' % frame) + +response = self._responses[frame.requestid] + +if action == 'responsedata': +response['b'].write(meta['data']) + +if meta['cbor']: +response['cbor'] =
D3390: exchange: use command executor interface for calling listkeys
indygreg created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY So the requests are compatible with version 2 peers. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3390 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 @@ -591,7 +591,8 @@ (computed for both success and failure case for changesets push)""" outgoing = pushop.outgoing unfi = pushop.repo.unfiltered() -remotephases = pushop.remote.listkeys('phases') +remotephases = listkeys(pushop.remote, 'phases') + if (pushop.ui.configbool('ui', '_usedassubrepo') and remotephases# server supports phases and not pushop.outgoing.missing # no changesets to be pushed @@ -638,14 +639,20 @@ @pushdiscovery('obsmarker') def _pushdiscoveryobsmarkers(pushop): -if (obsolete.isenabled(pushop.repo, obsolete.exchangeopt) -and pushop.repo.obsstore -and 'obsolete' in pushop.remote.listkeys('namespaces')): -repo = pushop.repo -# very naive computation, that can be quite expensive on big repo. -# However: evolution is currently slow on them anyway. -nodes = (c.node() for c in repo.set('::%ln', pushop.futureheads)) -pushop.outobsmarkers = pushop.repo.obsstore.relevantmarkers(nodes) +if not obsolete.isenabled(pushop.repo, obsolete.exchangeopt): +return + +if not pushop.repo.obsstore: +return + +if 'obsolete' not in listkeys(pushop.remote, 'namespaces'): +return + +repo = pushop.repo +# very naive computation, that can be quite expensive on big repo. +# However: evolution is currently slow on them anyway. +nodes = (c.node() for c in repo.set('::%ln', pushop.futureheads)) +pushop.outobsmarkers = pushop.repo.obsstore.relevantmarkers(nodes) @pushdiscovery('bookmarks') def _pushdiscoverybookmarks(pushop): @@ -657,7 +664,8 @@ if pushop.revs: revnums = map(repo.changelog.rev, pushop.revs) ancestors = repo.changelog.ancestors(revnums, inclusive=True) -remotebookmark = remote.listkeys('bookmarks') + +remotebookmark = listkeys(remote, 'bookmarks') explicit = set([repo._bookmarks.expandname(bookmark) for bookmark in pushop.bookmarks]) @@ -1168,7 +1176,7 @@ """synchronise phase information locally and remotely""" cheads = pushop.commonheads # even when we don't push, exchanging phase data is useful -remotephases = pushop.remote.listkeys('phases') +remotephases = listkeys(pushop.remote, 'phases') if (pushop.ui.configbool('ui', '_usedassubrepo') and remotephases# server supports phases and pushop.cgresult is None # nothing was pushed @@ -1392,6 +1400,10 @@ if self._tr is not None: self._tr.release() +def listkeys(remote, namespace): +with remote.commandexecutor() as e: +return e.callcommand('listkeys', {'namespace': namespace}).result() + def _fullpullbundle2(repo, pullop): # The server may send a partial reply, i.e. when inlining # pre-computed bundles. In that case, update the common @@ -1529,7 +1541,7 @@ # all known bundle2 servers now support listkeys, but lets be nice with # new implementation. return -books = pullop.remote.listkeys('bookmarks') +books = listkeys(pullop.remote, 'bookmarks') pullop.remotebookmarks = bookmod.unhexlifybookmarks(books) @@ -1741,7 +1753,7 @@ # Get remote phases data from remote if 'phases' in pullop.stepsdone: return -remotephases = pullop.remote.listkeys('phases') +remotephases = listkeys(pullop.remote, 'phases') _pullapplyphases(pullop, remotephases) def _pullapplyphases(pullop, remotephases): @@ -1805,7 +1817,7 @@ tr = None if obsolete.isenabled(pullop.repo, obsolete.exchangeopt): pullop.repo.ui.debug('fetching remote obsolete markers\n') -remoteobs = pullop.remote.listkeys('obsolete') +remoteobs = listkeys(pullop.remote, 'obsolete') if 'dump0' in remoteobs: tr = pullop.gettransaction() markers = [] To: indygreg, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3391: commands: use command executor interface
indygreg 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/D3391 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 @@ -4035,7 +4035,9 @@ oldrevs = revs revs = [] # actually, nodes for r in oldrevs: -node = other.lookup(r) +with other.commandexecutor() as e: +node = e.callcommand('lookup', {'key': r}).result() + revs.append(node) if r == checkout: checkout = node To: indygreg, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3212: patch: implement a new worddiff algorithm
durin42 added a comment. (I'll say that red-dimmed text is very hard for this moderate protan with a black terminal window.) REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3212 To: quark, #hg-reviewers, durin42, yuja Cc: indygreg, dhduvall, yuja, spectral, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3212: patch: implement a new worddiff algorithm
durin42 added a comment. In the name of progress, I'm going to land these. If we find problems with color defaults, let's try and fix them in the RC period, but it's still an experimental feature so we've got plenty of wiggle room. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3212 To: quark, #hg-reviewers, durin42, yuja Cc: indygreg, dhduvall, yuja, spectral, 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 updated this revision to Diff 8316. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3364?vs=8274=8316 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 @@ -211,6 +211,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
D3350: tests: fix up a couple of minor bytes inconsistencies in run-tests.py
durin42 updated this revision to Diff 8313. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3350?vs=8269=8313 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 @@ -393,6 +393,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
D3348: py3: another three passing
durin42 updated this revision to Diff 8312. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3348?vs=8268=8312 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 @@ -176,6 +177,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 @@ -433,6 +435,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
D3343: hgweb: these strings should be sysstrs, not bytes
durin42 updated this revision to Diff 8311. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3343?vs=8220=8311 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 @@ -133,7 +133,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
D3356: wsgicgi: un-do some prior porting work that is now wrong
durin42 updated this revision to Diff 8315. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3356?vs=8271=8315 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
D3351: py3: fix test-shelve.t on Python 3
durin42 updated this revision to Diff 8314. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3351?vs=8270=8314 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 @@ -398,6 +398,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
mercurial@37608: 52 new changesets
52 new changesets in mercurial: https://www.mercurial-scm.org/repo/hg/rev/734515aca84d changeset: 37557:734515aca84d user:Gregory Szorcdate:Tue Apr 10 14:29:15 2018 -0700 summary: wireproto: define and implement HTTP handshake to upgrade protocol https://www.mercurial-scm.org/repo/hg/rev/8a73132214a3 changeset: 37558:8a73132214a3 user:Gregory Szorc date:Tue Apr 10 18:16:47 2018 -0700 summary: httppeer: support protocol upgrade https://www.mercurial-scm.org/repo/hg/rev/c4a0626f6b6e changeset: 37559:c4a0626f6b6e user:Pulkit Goyal <7895pul...@gmail.com> date:Wed Apr 11 14:35:37 2018 +0530 summary: py3: use pycompat.bytestr() where repr in involved https://www.mercurial-scm.org/repo/hg/rev/41ba336d9f1e changeset: 37560:41ba336d9f1e user:Danny Hooper date:Fri Mar 30 17:01:12 2018 -0700 summary: fix: use a portable python script instead of sed in test https://www.mercurial-scm.org/repo/hg/rev/8478b198af9c changeset: 37561:8478b198af9c user:Pulkit Goyal <7895pul...@gmail.com> date:Wed Apr 04 17:37:35 2018 +0530 summary: tests: add tests showing pulling from infinitepush works over wire https://www.mercurial-scm.org/repo/hg/rev/e5cd8d1a094d changeset: 37562:e5cd8d1a094d user:Matt Harbison date:Wed Apr 11 17:29:55 2018 -0400 summary: lfs: special case the null:// usercache instead of treating it as a url https://www.mercurial-scm.org/repo/hg/rev/be1cc65bdb1c changeset: 37563:be1cc65bdb1c user:Matt Harbison date:Sun Apr 08 01:23:39 2018 -0400 summary: lfs: infer the blob store URL from an explicit pull source https://www.mercurial-scm.org/repo/hg/rev/31a4ea773369 changeset: 37564:31a4ea773369 user:Matt Harbison date:Sun Apr 08 14:22:12 2018 -0400 summary: lfs: infer the blob store URL from an explicit push dest or default-push https://www.mercurial-scm.org/repo/hg/rev/9c7a25ef5b49 changeset: 37565:9c7a25ef5b49 user:Matt Harbison date:Wed Apr 11 18:23:29 2018 -0400 summary: lfs: handle paths that don't end with '/' when inferring the blob store https://www.mercurial-scm.org/repo/hg/rev/f53b55b162f4 changeset: 37566:f53b55b162f4 user:Yuya Nishihara date:Mon Apr 09 20:44:41 2018 +0900 summary: py3: get rid of character access from pure.diffhelpers https://www.mercurial-scm.org/repo/hg/rev/53021c4ef0b2 changeset: 37567:53021c4ef0b2 user:Yuya Nishihara date:Mon Apr 09 20:47:43 2018 +0900 summary: diffhelpers: port docstrings from cext to pure https://www.mercurial-scm.org/repo/hg/rev/f5833651ad07 changeset: 37568:f5833651ad07 user:Yuya Nishihara date:Mon Apr 09 20:49:39 2018 +0900 summary: patch: stop using cext.diffhelpers https://www.mercurial-scm.org/repo/hg/rev/2025bf60adb2 changeset: 37569:2025bf60adb2 user:Yuya Nishihara date:Mon Apr 09 20:51:23 2018 +0900 summary: diffhelpers: remove C implementation in favor of pure Python version https://www.mercurial-scm.org/repo/hg/rev/c4c8d0d1267f changeset: 37570:c4c8d0d1267f user:Yuya Nishihara date:Mon Apr 09 20:52:54 2018 +0900 summary: diffhelpers: naming and whitespace cleanup https://www.mercurial-scm.org/repo/hg/rev/0ea8b9576d7c changeset: 37571:0ea8b9576d7c user:Yuya Nishihara date:Mon Apr 09 20:54:00 2018 +0900 summary: diffhelpers: move out of pure package https://www.mercurial-scm.org/repo/hg/rev/c6b8d614690a changeset: 37572:c6b8d614690a user:Yuya Nishihara date:Mon Apr 09 20:55:05 2018 +0900 summary: diffhelpers: remove unused return value from fixnewline() and addlines() https://www.mercurial-scm.org/repo/hg/rev/49b82cdb5983 changeset: 37573:49b82cdb5983 user:Yuya Nishihara date:Mon Apr 09 21:06:46 2018 +0900 summary: patch: error out if reached to EOF while reading hunk https://www.mercurial-scm.org/repo/hg/rev/a1bcc7ff0eac changeset: 37574:a1bcc7ff0eac user:Yuya Nishihara date:Mon Apr 09 21:08:52 2018 +0900 summary: diffhelpers: make return value of testhunk() more Pythonic https://www.mercurial-scm.org/repo/hg/rev/230eb9594150 changeset: 37575:230eb9594150 user:Yuya Nishihara date:Sat Apr 07 01:37:25 2018 +0900 summary: diffhelpers: be more tolerant for stripped empty lines of CRLF ending https://www.mercurial-scm.org/repo/hg/rev/6ef94f24aa82 changeset: 37576:6ef94f24aa82 user:Pulkit Goyal <7895pul...@gmail.com> date:Wed Apr 11 22:36:16 2018 +0530 summary: py3: make
[PATCH 2 of 4 V2] export: invoke the file prefetch hook
# HG changeset patch # User Matt Harbison# Date 1523749425 14400 # Sat Apr 14 19:43:45 2018 -0400 # Node ID c44d4efe94b05253d30bb507dd4cca70ad1d94f0 # Parent fe6824bcc6b8228f2eb141ea96efb6797b5530d7 export: invoke the file prefetch hook cmdutil.exportfile() is only called by shelve, mq and patchbomb. Those are unlikely to mix with lfs, but it may as well be invoked there for completeness. diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py --- a/mercurial/cmdutil.py +++ b/mercurial/cmdutil.py @@ -1619,6 +1619,8 @@ def export(repo, revs, basefm, fntemplat the given template. Otherwise: All revs will be written to basefm. ''' +scmutil.prefetchfiles(repo, revs, match) + if not fntemplate: _exportfile(repo, revs, basefm, '', switch_parent, opts, match) else: @@ -1627,6 +1629,8 @@ def export(repo, revs, basefm, fntemplat def exportfile(repo, revs, fp, switch_parent=False, opts=None, match=None): """Export changesets to the given file stream""" +scmutil.prefetchfiles(repo, revs, match) + dest = getattr(fp, 'name', '') with formatter.formatter(repo.ui, fp, 'export', {}) as fm: _exportfile(repo, revs, fm, dest, switch_parent, opts, match) diff --git a/tests/test-lfs-serve.t b/tests/test-lfs-serve.t --- a/tests/test-lfs-serve.t +++ b/tests/test-lfs-serve.t @@ -304,6 +304,67 @@ Misc: process dies early if a requiremen (see https://mercurial-scm.org/wiki/MissingRequirement for more information) [255] + $ echo 'this is an lfs file' > $TESTTMP/client6_clone/lfspair1.bin + $ echo 'this is an lfs file too' > $TESTTMP/client6_clone/lfspair2.bin + $ hg -R $TESTTMP/client6_clone ci -Aqm 'add lfs pair' + $ hg -R $TESTTMP/client6_clone push -q + + $ hg clone -qU http://localhost:$HGPORT $TESTTMP/bulkfetch + +Export will prefetch all needed files across all needed revisions + + $ hg -R $TESTTMP/bulkfetch -v export -r 0:tip -o all.export + lfs: assuming remote store: http://localhost:$HGPORT/.git/info/lfs + exporting patches: + lfs: assuming remote store: http://localhost:$HGPORT/.git/info/lfs + lfs: need to transfer 4 objects (92 bytes) + lfs: downloading a82f1c5cea0d40e3bb3a849686bb4e6ae47ca27e614de55c1ed0325698ef68de (25 bytes) + lfs: processed: a82f1c5cea0d40e3bb3a849686bb4e6ae47ca27e614de55c1ed0325698ef68de + lfs: downloading bed80f00180ac404b843628ab56a1c1984d6145c391cd1628a7dd7d2598d71fc (23 bytes) + lfs: processed: bed80f00180ac404b843628ab56a1c1984d6145c391cd1628a7dd7d2598d71fc + lfs: downloading cf1b2787b74e66547d931b6ebe28ff63303e803cb2baa14a8f57c4383d875782 (20 bytes) + lfs: processed: cf1b2787b74e66547d931b6ebe28ff63303e803cb2baa14a8f57c4383d875782 + lfs: downloading d96eda2c74b56e95cfb5ffb66b6503e198cc6fc4a09dc877de925feebc65786e (24 bytes) + lfs: processed: d96eda2c74b56e95cfb5ffb66b6503e198cc6fc4a09dc877de925feebc65786e + all.export + lfs: found bed80f00180ac404b843628ab56a1c1984d6145c391cd1628a7dd7d2598d71fc in the local lfs store + lfs: found a82f1c5cea0d40e3bb3a849686bb4e6ae47ca27e614de55c1ed0325698ef68de in the local lfs store + lfs: found cf1b2787b74e66547d931b6ebe28ff63303e803cb2baa14a8f57c4383d875782 in the local lfs store + lfs: found d96eda2c74b56e95cfb5ffb66b6503e198cc6fc4a09dc877de925feebc65786e in the local lfs store + +Export with selected files is used with `extdiff --patch` + + $ rm -r $TESTTMP/bulkfetch/.hg/store/lfs + $ hg --config extensions.extdiff= \ + >-R $TESTTMP/bulkfetch -v extdiff -r 2:tip --patch $TESTTMP/bulkfetch/lfs.bin + lfs: assuming remote store: http://localhost:$HGPORT/.git/info/lfs + lfs: assuming remote store: http://localhost:$HGPORT/.git/info/lfs + lfs: downloading bed80f00180ac404b843628ab56a1c1984d6145c391cd1628a7dd7d2598d71fc (23 bytes) + lfs: processed: bed80f00180ac404b843628ab56a1c1984d6145c391cd1628a7dd7d2598d71fc + */hg-8374dc4052cb.patch (glob) + lfs: found bed80f00180ac404b843628ab56a1c1984d6145c391cd1628a7dd7d2598d71fc in the local lfs store + */hg-9640b57e77b1.patch (glob) + --- */hg-8374dc4052cb.patch * (glob) + +++ */hg-9640b57e77b1.patch * (glob) + @@ -2,12 +2,7 @@ + # User test + # Date 0 0 + # Thu Jan 01 00:00:00 1970 + + -# Node ID 8374dc4052cbd388e79d9dc4ddb29784097aa354 + -# Parent 1477875038c60152e391238920a16381c627b487 + -lfs + +# Node ID 9640b57e77b14c3a0144fb4478b6cc13e13ea0d1 + +# Parent d3b84d50eacbd56638e11abce6b8616aaba54420 + +add lfs pair + + -diff -r 1477875038c6 -r 8374dc4052cb lfs.bin + /dev/null Thu Jan 01 00:00:00 1970 + + -+++ b/lfs.bin Thu Jan 01 00:00:00 1970 + + -@@ -0,0 +1,1 @@ + -+this is a big lfs file + cleaning up temp directory + [1] + #endif $ $PYTHON $TESTDIR/killdaemons.py $DAEMON_PIDS ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 1 of 4 V2] scmutil: teach the file prefetch hook to handle multiple commits
# HG changeset patch # User Matt Harbison# Date 1523746245 14400 # Sat Apr 14 18:50:45 2018 -0400 # Node ID fe6824bcc6b8228f2eb141ea96efb6797b5530d7 # Parent 1859b9a7ddefe90971259da0793e9289fd65c63f scmutil: teach the file prefetch hook to handle multiple commits The remainder of the commands that need prefetch deal with multiple revisions. I initially coded this as a separate hook, but then it needed a list of files to handle `diff` and `grep`, so it didn't seem worth keeping them separate. Not every matcher will emit bad file messages (some are built from a list of files that are known to exist). But it seems better to filter this in one place than to push this on either each caller or each hook implementation. diff --git a/hgext/lfs/wrapper.py b/hgext/lfs/wrapper.py --- a/hgext/lfs/wrapper.py +++ b/hgext/lfs/wrapper.py @@ -244,17 +244,21 @@ def hgpostshare(orig, sourcerepo, destre if 'lfs' in destrepo.requirements: destrepo.vfs.append('hgrc', util.tonativeeol('\n[extensions]\nlfs=\n')) -def _prefetchfiles(repo, ctx, files): +def _prefetchfiles(repo, revs, match): """Ensure that required LFS blobs are present, fetching them as a group if needed.""" pointers = [] +oids = set() localstore = repo.svfs.lfslocalblobstore -for f in files: -p = pointerfromctx(ctx, f) -if p and not localstore.has(p.oid()): -p.filename = f -pointers.append(p) +for rev in revs: +ctx = repo[rev] +for f in ctx.walk(match): +p = pointerfromctx(ctx, f) +if p and p.oid() not in oids and not localstore.has(p.oid()): +p.filename = f +pointers.append(p) +oids.add(p.oid()) if pointers: # Recalculating the repo store here allows 'paths.default' that is set diff --git a/mercurial/archival.py b/mercurial/archival.py --- a/mercurial/archival.py +++ b/mercurial/archival.py @@ -320,7 +320,8 @@ def archive(repo, dest, node, kind, deco total = len(files) if total: files.sort() -scmutil.fileprefetchhooks(repo, ctx, files) +scmutil.prefetchfiles(repo, [ctx.rev()], + scmutil.matchfiles(repo, files)) repo.ui.progress(_('archiving'), 0, unit=_('files'), total=total) for i, f in enumerate(files): ff = ctx.flags(f) diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py --- a/mercurial/cmdutil.py +++ b/mercurial/cmdutil.py @@ -2258,16 +2258,15 @@ def cat(ui, repo, ctx, matcher, basefm, mfnode = ctx.manifestnode() try: if mfnode and mfl[mfnode].find(file)[0]: -scmutil.fileprefetchhooks(repo, ctx, [file]) +scmutil.prefetchfiles(repo, [ctx.rev()], matcher) write(file) return 0 except KeyError: pass -files = [f for f in ctx.walk(matcher)] -scmutil.fileprefetchhooks(repo, ctx, files) - -for abs in files: +scmutil.prefetchfiles(repo, [ctx.rev()], matcher) + +for abs in ctx.walk(matcher): write(abs) err = 0 @@ -2945,8 +2944,11 @@ def revert(ui, repo, ctx, parents, *pats _revertprefetch(repo, ctx, *[actions[name][0] for name in needdata]) oplist = [actions[name][0] for name in needdata] -prefetch = scmutil.fileprefetchhooks -prefetch(repo, ctx, [f for sublist in oplist for f in sublist]) +prefetch = scmutil.prefetchfiles +matchfiles = scmutil.matchfiles +prefetch(repo, [ctx.rev()], + matchfiles(repo, +[f for sublist in oplist for f in sublist])) _performrevert(repo, parents, ctx, actions, interactive, tobackup) if targetsubs: diff --git a/mercurial/merge.py b/mercurial/merge.py --- a/mercurial/merge.py +++ b/mercurial/merge.py @@ -1473,8 +1473,11 @@ def _prefetchfiles(repo, ctx, actions): # changed/deleted never resolves to something from the remote side. oplist = [actions[a] for a in (ACTION_GET, ACTION_DELETED_CHANGED, ACTION_LOCAL_DIR_RENAME_GET, ACTION_MERGE)] -prefetch = scmutil.fileprefetchhooks -prefetch(repo, ctx, [f for sublist in oplist for f, args, msg in sublist]) +prefetch = scmutil.prefetchfiles +matchfiles = scmutil.matchfiles +prefetch(repo, [ctx.rev()], + matchfiles(repo, +[f for sublist in oplist for f, args, msg in sublist])) @attr.s(frozen=True) class updateresult(object): diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py --- a/mercurial/scmutil.py +++ b/mercurial/scmutil.py @@ -1357,9 +1357,20 @@ class simplekeyvaluefile(object): 'unbundle', ] -# a list of (repo, ctx, files) functions called by various commands to allow -# extensions to ensure the
[PATCH 4 of 4 V2] lfs: enable the final download count status message
# HG changeset patch # User Matt Harbison# Date 1523754995 14400 # Sat Apr 14 21:16:35 2018 -0400 # Node ID b6ebe7d35f7f3c72ff43dc306988c235f9ebc900 # Parent 317c4321147ef610a2f229dd87953829d7eebf3d lfs: enable the final download count status message At this point, I think all of the core commands are prefetching, except grep and verify. Verify will need some special handling, in case the revlogs are corrupt. Grep has an issue that still needs to be debugged, but we probably need to give the behavior some thought too- it would be a shame to have to download everything in order to search. I think the benefit of having this info for all commands outweighs extra printing in a command that is arguably not well behaved in this context anyway. diff --git a/hgext/lfs/blobstore.py b/hgext/lfs/blobstore.py --- a/hgext/lfs/blobstore.py +++ b/hgext/lfs/blobstore.py @@ -451,10 +451,9 @@ class _gitlfsremote(object): if action == 'upload': self.ui.status(_('lfs: uploaded %d files (%s)\n') % (blobs, util.bytecount(processed))) -# TODO: coalesce the download requests, and comment this in -#elif action == 'download': -#self.ui.status(_('lfs: downloaded %d files (%s)\n') -# % (blobs, util.bytecount(processed))) +elif action == 'download': +self.ui.status(_('lfs: downloaded %d files (%s)\n') + % (blobs, util.bytecount(processed))) def __del__(self): # copied from mercurial/httppeer.py 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 @@ -135,6 +135,7 @@ Blob URIs are correct when --prefix is u Server: testing stub value lfs: adding f03217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e to the usercache lfs: processed: f03217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e + lfs: downloaded 1 files (20 bytes) lfs.bin: remote created -> g getting lfs.bin lfs: found f03217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e in the local lfs store diff --git a/tests/test-lfs-serve.t b/tests/test-lfs-serve.t --- a/tests/test-lfs-serve.t +++ b/tests/test-lfs-serve.t @@ -282,6 +282,7 @@ lfs content, and the extension enabled. lfs: assuming remote store: http://localhost:$HGPORT/.git/info/lfs lfs: downloading a82f1c5cea0d40e3bb3a849686bb4e6ae47ca27e614de55c1ed0325698ef68de (25 bytes) lfs: processed: a82f1c5cea0d40e3bb3a849686bb4e6ae47ca27e614de55c1ed0325698ef68de + lfs: downloaded 1 files (25 bytes) getting lfs2.txt lfs: found a82f1c5cea0d40e3bb3a849686bb4e6ae47ca27e614de55c1ed0325698ef68de in the local lfs store getting nonlfs2.txt @@ -326,6 +327,7 @@ Export will prefetch all needed files ac lfs: processed: cf1b2787b74e66547d931b6ebe28ff63303e803cb2baa14a8f57c4383d875782 lfs: downloading d96eda2c74b56e95cfb5ffb66b6503e198cc6fc4a09dc877de925feebc65786e (24 bytes) lfs: processed: d96eda2c74b56e95cfb5ffb66b6503e198cc6fc4a09dc877de925feebc65786e + lfs: downloaded 4 files (92 bytes) all.export lfs: found bed80f00180ac404b843628ab56a1c1984d6145c391cd1628a7dd7d2598d71fc in the local lfs store lfs: found a82f1c5cea0d40e3bb3a849686bb4e6ae47ca27e614de55c1ed0325698ef68de in the local lfs store @@ -341,6 +343,7 @@ Export with selected files is used with lfs: assuming remote store: http://localhost:$HGPORT/.git/info/lfs lfs: downloading bed80f00180ac404b843628ab56a1c1984d6145c391cd1628a7dd7d2598d71fc (23 bytes) lfs: processed: bed80f00180ac404b843628ab56a1c1984d6145c391cd1628a7dd7d2598d71fc + lfs: downloaded 1 files (23 bytes) */hg-8374dc4052cb.patch (glob) lfs: found bed80f00180ac404b843628ab56a1c1984d6145c391cd1628a7dd7d2598d71fc in the local lfs store */hg-9640b57e77b1.patch (glob) @@ -380,6 +383,7 @@ Diff will prefetch files lfs: processed: cf1b2787b74e66547d931b6ebe28ff63303e803cb2baa14a8f57c4383d875782 lfs: downloading d96eda2c74b56e95cfb5ffb66b6503e198cc6fc4a09dc877de925feebc65786e (24 bytes) lfs: processed: d96eda2c74b56e95cfb5ffb66b6503e198cc6fc4a09dc877de925feebc65786e + lfs: downloaded 4 files (92 bytes) lfs: found bed80f00180ac404b843628ab56a1c1984d6145c391cd1628a7dd7d2598d71fc in the local lfs store lfs: found a82f1c5cea0d40e3bb3a849686bb4e6ae47ca27e614de55c1ed0325698ef68de in the local lfs store lfs: found cf1b2787b74e66547d931b6ebe28ff63303e803cb2baa14a8f57c4383d875782 in the local lfs store @@ -423,6 +427,7 @@ Only the files required by diff are pref lfs: assuming remote store: http://localhost:$HGPORT/.git/info/lfs lfs: downloading d96eda2c74b56e95cfb5ffb66b6503e198cc6fc4a09dc877de925feebc65786e (24 bytes) lfs: processed: d96eda2c74b56e95cfb5ffb66b6503e198cc6fc4a09dc877de925feebc65786e + lfs: downloaded 1 files (24 bytes) lfs: found
[PATCH 3 of 4 V2] diff: invoke the file prefetch hook
# HG changeset patch # User Matt Harbison# Date 1523751087 14400 # Sat Apr 14 20:11:27 2018 -0400 # Node ID 317c4321147ef610a2f229dd87953829d7eebf3d # Parent c44d4efe94b05253d30bb507dd4cca70ad1d94f0 diff: invoke the file prefetch hook By invoking it this deep within the command, we pick up both subrepo and hgweb support, as well as --patch support for commands that implement logopts. diff --git a/mercurial/patch.py b/mercurial/patch.py --- a/mercurial/patch.py +++ b/mercurial/patch.py @@ -2466,6 +2466,10 @@ def diffhunks(repo, node1=None, node2=No # reported as copies. We want to show them in the diff as additions. del copy[dst] +prefetchmatch = scmutil.matchfiles(repo, +[f for f in modifiedset | addedset | removedset]) +scmutil.prefetchfiles(repo, [ctx1.rev(), ctx2.rev()], prefetchmatch) + def difffn(opts, losedata): return trydiff(repo, revs, ctx1, ctx2, modified, added, removed, copy, getfilectx, opts, losedata, prefix, relroot) diff --git a/tests/test-lfs-serve.t b/tests/test-lfs-serve.t --- a/tests/test-lfs-serve.t +++ b/tests/test-lfs-serve.t @@ -365,6 +365,71 @@ Export with selected files is used with cleaning up temp directory [1] +Diff will prefetch files + + $ rm -r $TESTTMP/bulkfetch/.hg/store/lfs + $ hg -R $TESTTMP/bulkfetch -v diff -r 2:tip + lfs: assuming remote store: http://localhost:$HGPORT/.git/info/lfs + lfs: assuming remote store: http://localhost:$HGPORT/.git/info/lfs + lfs: need to transfer 4 objects (92 bytes) + lfs: downloading a82f1c5cea0d40e3bb3a849686bb4e6ae47ca27e614de55c1ed0325698ef68de (25 bytes) + lfs: processed: a82f1c5cea0d40e3bb3a849686bb4e6ae47ca27e614de55c1ed0325698ef68de + lfs: downloading bed80f00180ac404b843628ab56a1c1984d6145c391cd1628a7dd7d2598d71fc (23 bytes) + lfs: processed: bed80f00180ac404b843628ab56a1c1984d6145c391cd1628a7dd7d2598d71fc + lfs: downloading cf1b2787b74e66547d931b6ebe28ff63303e803cb2baa14a8f57c4383d875782 (20 bytes) + lfs: processed: cf1b2787b74e66547d931b6ebe28ff63303e803cb2baa14a8f57c4383d875782 + lfs: downloading d96eda2c74b56e95cfb5ffb66b6503e198cc6fc4a09dc877de925feebc65786e (24 bytes) + lfs: processed: d96eda2c74b56e95cfb5ffb66b6503e198cc6fc4a09dc877de925feebc65786e + lfs: found bed80f00180ac404b843628ab56a1c1984d6145c391cd1628a7dd7d2598d71fc in the local lfs store + lfs: found a82f1c5cea0d40e3bb3a849686bb4e6ae47ca27e614de55c1ed0325698ef68de in the local lfs store + lfs: found cf1b2787b74e66547d931b6ebe28ff63303e803cb2baa14a8f57c4383d875782 in the local lfs store + lfs: found d96eda2c74b56e95cfb5ffb66b6503e198cc6fc4a09dc877de925feebc65786e in the local lfs store + diff -r 8374dc4052cb -r 9640b57e77b1 lfs.bin + --- a/lfs.binThu Jan 01 00:00:00 1970 + + +++ /dev/nullThu Jan 01 00:00:00 1970 + + @@ -1,1 +0,0 @@ + -this is a big lfs file + diff -r 8374dc4052cb -r 9640b57e77b1 lfs2.txt + --- /dev/nullThu Jan 01 00:00:00 1970 + + +++ b/lfs2.txt Thu Jan 01 00:00:00 1970 + + @@ -0,0 +1,1 @@ + +this is another lfs file + diff -r 8374dc4052cb -r 9640b57e77b1 lfspair1.bin + --- /dev/nullThu Jan 01 00:00:00 1970 + + +++ b/lfspair1.bin Thu Jan 01 00:00:00 1970 + + @@ -0,0 +1,1 @@ + +this is an lfs file + diff -r 8374dc4052cb -r 9640b57e77b1 lfspair2.bin + --- /dev/nullThu Jan 01 00:00:00 1970 + + +++ b/lfspair2.bin Thu Jan 01 00:00:00 1970 + + @@ -0,0 +1,1 @@ + +this is an lfs file too + diff -r 8374dc4052cb -r 9640b57e77b1 nonlfs.txt + --- a/nonlfs.txt Thu Jan 01 00:00:00 1970 + + +++ /dev/nullThu Jan 01 00:00:00 1970 + + @@ -1,1 +0,0 @@ + -non-lfs + diff -r 8374dc4052cb -r 9640b57e77b1 nonlfs3.txt + --- /dev/nullThu Jan 01 00:00:00 1970 + + +++ b/nonlfs3.txtThu Jan 01 00:00:00 1970 + + @@ -0,0 +1,1 @@ + +non-lfs + +Only the files required by diff are prefetched + + $ rm -r $TESTTMP/bulkfetch/.hg/store/lfs + $ hg -R $TESTTMP/bulkfetch -v diff -r 2:tip $TESTTMP/bulkfetch/lfspair2.bin + lfs: assuming remote store: http://localhost:$HGPORT/.git/info/lfs + lfs: assuming remote store: http://localhost:$HGPORT/.git/info/lfs + lfs: downloading d96eda2c74b56e95cfb5ffb66b6503e198cc6fc4a09dc877de925feebc65786e (24 bytes) + lfs: processed: d96eda2c74b56e95cfb5ffb66b6503e198cc6fc4a09dc877de925feebc65786e + lfs: found d96eda2c74b56e95cfb5ffb66b6503e198cc6fc4a09dc877de925feebc65786e in the local lfs store + diff -r 8374dc4052cb -r 9640b57e77b1 lfspair2.bin + --- /dev/nullThu Jan 01 00:00:00 1970 + + +++ b/lfspair2.bin Thu Jan 01 00:00:00 1970 + + @@ -0,0 +1,1 @@ + +this is an lfs file too + #endif $ $PYTHON $TESTDIR/killdaemons.py $DAEMON_PIDS ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org
mercurial@37556: 10 new changesets
10 new changesets in mercurial: https://www.mercurial-scm.org/repo/hg/rev/835ccc2a5ef1 changeset: 37547:835ccc2a5ef1 user:Gregory Szorcdate:Tue Apr 10 10:22:26 2018 -0700 summary: httppeer: move requestbuilder defaults into makepeer() argument https://www.mercurial-scm.org/repo/hg/rev/8e7a4435ab6d changeset: 37548:8e7a4435ab6d user:Gregory Szorc date:Tue Apr 10 10:27:49 2018 -0700 summary: httppeer: extract code for performing an HTTP request https://www.mercurial-scm.org/repo/hg/rev/66d1001e1500 changeset: 37549:66d1001e1500 user:Gregory Szorc date:Tue Apr 10 10:51:12 2018 -0700 summary: httppeer: extract code for creating a request into own function https://www.mercurial-scm.org/repo/hg/rev/b5862ee01abe changeset: 37550:b5862ee01abe user:Gregory Szorc date:Tue Apr 10 12:12:07 2018 -0700 summary: httppeer: move error handling and response wrapping into sendrequest https://www.mercurial-scm.org/repo/hg/rev/946eb204ba67 changeset: 37551:946eb204ba67 user:Gregory Szorc date:Tue Apr 10 12:52:29 2018 -0700 summary: httppeer: extract common response handling into own function https://www.mercurial-scm.org/repo/hg/rev/8b8a845c85fc changeset: 37552:8b8a845c85fc user:Gregory Szorc date:Tue Apr 10 13:11:40 2018 -0700 summary: httppeer: perform capabilities request in makepeer() https://www.mercurial-scm.org/repo/hg/rev/6b08cf6b900f changeset: 37553:6b08cf6b900f user:Gregory Szorc date:Tue Apr 10 13:07:13 2018 -0700 summary: httppeer: allow opener to be passed to makepeer() https://www.mercurial-scm.org/repo/hg/rev/301a1d2e8016 changeset: 37554:301a1d2e8016 user:Gregory Szorc date:Tue Apr 10 13:41:21 2018 -0700 summary: httppeer: don't accept very old media types (BC) https://www.mercurial-scm.org/repo/hg/rev/930c433eb311 changeset: 37555:930c433eb311 user:Gregory Szorc date:Tue Apr 10 16:53:44 2018 -0700 summary: httppeer: always add x-hg* headers to Vary header https://www.mercurial-scm.org/repo/hg/rev/b77aa48ba690 changeset: 37556:b77aa48ba690 bookmark:@ tag: tip user:Gregory Szorc date:Tue Apr 10 18:13:28 2018 -0700 summary: httppeer: only advertise partial-pull if capabilities are known -- 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
Re: [PATCH 3 of 3 V5] revset: skip legacy lookup for revspec wrapped in 'revset(…)'
On 16/04/2018 14:24, Yuya Nishihara wrote: On Mon, 16 Apr 2018 08:58:31 +0200, Boris Feld wrote: # HG changeset patch # User Boris Feld# Date 1523369212 -7200 # Tue Apr 10 16:06:52 2018 +0200 # Node ID 109ca88347d7b531d4b48370efcbc4d6e850cf92 # Parent f363552ced37ae028bbcf2cba1f02ac623385f54 # EXP-Topic noname # Available At https://bitbucket.org/octobus/mercurial-devel/ # hg pull https://bitbucket.org/octobus/mercurial-devel/ -r 109ca88347d7 revset: skip legacy lookup for revspec wrapped in 'revset(…)' @@ -2191,7 +2194,12 @@ def matchany(ui, specs, lookup=None, loc raise error.ParseError(_("empty query")) parsedspecs = [] for s in specs: -parsedspecs.append(revsetlang.parse(s, lookup)) +lookupthis = lookup +stripped = s.strip() +if (stripped.startswith(prefixrevset) +and stripped.endswith(postfixrevset)): +lookupthis = None +parsedspecs.append(revsetlang.parse(s, lookupthis)) Is it okay to move this hack to revsetlang._parsewith? @@ -482,6 +485,8 @@ def _parsewith(spec, lookup=None, symini ... ParseError: ('invalid token', 4) """ +if spec.startswith('revset(') and spec.endswith(')'): +lookup = None p = parser.parser(elements) tree, pos = p.parse(tokenize(spec, lookup=lookup, syminitletters=syminitletters)) I don't think revset.match*() is the right place to do parsing stuff, and we'll need a tokenizer to make it more correctly handle variants such as ' revset ( ... )' or '... and revset(...)'. You're are right, moving it lower in the stack makes sense. Would it be possible to implement it even lower in revsetlang.tokenize? We tried preparing a V6 to move the code but we didn't find the queued version of the first changeset. Were you waiting for us to move the code yourself? ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3389: context: clarify deprecation warning message
martinvonz created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY I had one developer report that they couldn't find the message. This patch should make it clear where to find it. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3389 AFFECTED FILES mercurial/context.py CHANGE DETAILS diff --git a/mercurial/context.py b/mercurial/context.py --- a/mercurial/context.py +++ b/mercurial/context.py @@ -398,8 +398,9 @@ #user and the revset may be too costly), use scmutil.revsymbol(repo, x) # * If "x" can be a mix of the above, you'll have to figure it out #yourself -repo.ui.deprecwarn("changectx.__init__ is getting more limited, see source " - "for details", "4.6", stacklevel=4) +repo.ui.deprecwarn("changectx.__init__ is getting more limited, see " + "context.changectxdeprecwarn() for details", "4.6", + stacklevel=4) class changectx(basectx): """A changecontext object makes access to data related to a particular To: martinvonz, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
mercurial@37546: 2 new changesets
2 new changesets in mercurial: https://www.mercurial-scm.org/repo/hg/rev/93397c4633f6 changeset: 37545:93397c4633f6 user:Gregory Szorcdate:Mon Apr 09 19:35:04 2018 -0700 summary: wireproto: extract HTTP version 2 code to own module https://www.mercurial-scm.org/repo/hg/rev/3a2367e6c6f2 changeset: 37546:3a2367e6c6f2 bookmark:@ tag: tip user:Gregory Szorc date:Mon Apr 09 19:35:39 2018 -0700 summary: wireproto: move version 2 command handlers to wireprotov2server -- 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
Re: [PATCH 2 of 6] export: invoke the file prefetch hook
On Mon, 16 Apr 2018 10:24:51 -0400, Matt Harbison wrote: > > > On Apr 16, 2018, at 7:31 AM, Yuya Nishiharawrote: > > > >> On Sun, 15 Apr 2018 02:44:06 -0400, Matt Harbison wrote: > >> # HG changeset patch > >> # User Matt Harbison > >> # Date 1523749425 14400 > >> # Sat Apr 14 19:43:45 2018 -0400 > >> # Node ID 1c3654f7ed31e6770cbd97681083bab834554056 > >> # Parent de2975df3997148a832ef41425b069fc6f8ff3bc > >> export: invoke the file prefetch hook > >> > >> cmdutil.exportfile() is only called by shelve, mq and patchbomb. Those are > >> unlikely to mix with lfs, but it may as well be invoked there for > >> completeness. > >> > >> diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py > >> --- a/mercurial/cmdutil.py > >> +++ b/mercurial/cmdutil.py > >> @@ -1619,6 +1619,12 @@ def export(repo, revs, basefm, fntemplat > >> the given template. > >> Otherwise: All revs will be written to basefm. > >> ''' > >> +files = None > >> +ctxs = [repo[r] for r in revs] > >> +if match: > >> +files = set([f for ctx in ctxs for f in ctx if match(f)]) > >> +scmutil.fileprefetchhooks(repo, ctxs, files) > > > > Perhaps we'll need > > > > fileprefetchhooks(repo, revs, match) > > > > since it may take some time to build a list of ctxs and files. > > All of the callers other than export and verify already have ctx. Does it > make sense to ctx -> rev -> ctx like that? I don't think the cost of repo[ctx.rev()] matters here. We could have two variants of fileprefetchhooks, but I have no preference. > I really like the idea of using match (in fact, I started coding it up). But > I stopped when either diff or export printed a “no such file in rev $hash” > message. I was also a little concerned with not undermining how cat will > extract a single file from the matcher as an optimization. But I guess we > can fix that later. > > Wrapping in match.badmatch() works, so I’ll try that again. > > > We can reconstruct a matcher from files by scmutil.matchfiles(). > > Presumably we should only do that for things like revert, that are building > their own file list? I’m assuming that using the available matcher for > commands where there is one is ok. Yeah, we should reuse the matcher if possible. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 2 of 6] export: invoke the file prefetch hook
> On Apr 16, 2018, at 7:31 AM, Yuya Nishiharawrote: > >> On Sun, 15 Apr 2018 02:44:06 -0400, Matt Harbison wrote: >> # HG changeset patch >> # User Matt Harbison >> # Date 1523749425 14400 >> # Sat Apr 14 19:43:45 2018 -0400 >> # Node ID 1c3654f7ed31e6770cbd97681083bab834554056 >> # Parent de2975df3997148a832ef41425b069fc6f8ff3bc >> export: invoke the file prefetch hook >> >> cmdutil.exportfile() is only called by shelve, mq and patchbomb. Those are >> unlikely to mix with lfs, but it may as well be invoked there for >> completeness. >> >> diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py >> --- a/mercurial/cmdutil.py >> +++ b/mercurial/cmdutil.py >> @@ -1619,6 +1619,12 @@ def export(repo, revs, basefm, fntemplat >> the given template. >> Otherwise: All revs will be written to basefm. >> ''' >> +files = None >> +ctxs = [repo[r] for r in revs] >> +if match: >> +files = set([f for ctx in ctxs for f in ctx if match(f)]) >> +scmutil.fileprefetchhooks(repo, ctxs, files) > > Perhaps we'll need > > fileprefetchhooks(repo, revs, match) > > since it may take some time to build a list of ctxs and files. All of the callers other than export and verify already have ctx. Does it make sense to ctx -> rev -> ctx like that? I really like the idea of using match (in fact, I started coding it up). But I stopped when either diff or export printed a “no such file in rev $hash” message. I was also a little concerned with not undermining how cat will extract a single file from the matcher as an optimization. But I guess we can fix that later. Wrapping in match.badmatch() works, so I’ll try that again. > We can reconstruct a matcher from files by scmutil.matchfiles(). Presumably we should only do that for things like revert, that are building their own file list? I’m assuming that using the available matcher for commands where there is one is ok. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
mercurial@37544: 2 new changesets
2 new changesets in mercurial: https://www.mercurial-scm.org/repo/hg/rev/01361be9e2dc changeset: 37543:01361be9e2dc user:Gregory Szorcdate:Mon Apr 09 15:32:01 2018 -0700 summary: wireproto: introduce a reactor for client-side state https://www.mercurial-scm.org/repo/hg/rev/55b5ba8d4e68 changeset: 37544:55b5ba8d4e68 bookmark:@ tag: tip user:Gregory Szorc date:Mon Apr 09 16:54:20 2018 -0700 summary: wireproto: client reactor support for receiving frames -- 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
Re: [PATCH 4 of 6] verify: invoke the file prefetch hook
On Mon, 16 Apr 2018 09:59:49 -0400, Matt Harbison wrote: > > > On Apr 16, 2018, at 9:39 AM, Yuya Nishiharawrote: > > > >> On Mon, 16 Apr 2018 09:15:48 -0400, Matt Harbison wrote: > >> > On Apr 16, 2018, at 8:34 AM, Yuya Nishihara wrote: > > On Mon, 16 Apr 2018 08:25:07 -0400, Matt Harbison wrote: > > >> On Apr 16, 2018, at 7:35 AM, Yuya Nishihara wrote: > >> > >> On Sun, 15 Apr 2018 02:44:08 -0400, Matt Harbison wrote: > >> # HG changeset patch > >> # User Matt Harbison > >> # Date 1523752111 14400 > >> # Sat Apr 14 20:28:31 2018 -0400 > >> # Node ID 3b0c3d4939b56ca038dbbba17da424699a6b339d > >> # Parent 691a7d3f2df80908e52a170897a4492a528c3533 > >> verify: invoke the file prefetch hook > >> > >> It's unfortunate that verify wants to download everything. Maybe we > >> can create > >> a custom transfer handler for LFS. But it shouldn't be painful in the > >> meantime, > >> and it's likely that blobs will be served up from more than just hgweb. > >> > >> diff --git a/mercurial/verify.py b/mercurial/verify.py > >> --- a/mercurial/verify.py > >> +++ b/mercurial/verify.py > >> @@ -25,6 +25,7 @@ from . import ( > >> > >> def verify(repo): > >> with repo.lock(): > >> +scmutil.fileprefetchhooks(repo, repo.set('all()')) > >> return verifier(repo).verify() > > > > I don't think "hg verify" should go that abstraction level because the > > repository might be inconsistent state. > > Do you mean using a revset, or prefetching at all? Grabbing one file at > a time will likely be painfully slow. > > If the revset bit is the bad part, what is the alternative with a > corrupt repo? > >>> > >>> I think we should avoid any write operation on damaged repo. Is there any > >>> way > >>> to disable fetching at all? > >> > >> Maybe we could wrap hg.verify() to stuff a flag is svfs? But I think then > >> the revlog flag processor will flag each revision as corrupt anyway, > >> hiding the real error. > >> > >> Avoiding writes on a corrupt repo makes sense, but in this case I think it > >> is safe. The storage is external, so nothing gets more corrupt, and the > >> blobs are checksummed on their own before adding them to the store. > > > > That's true for lfs, but not all prefetch-able storage would behave as > > such. Another concern is we're doing prefetch *before* verifying revlogs. > > If a revlog is damaged, the prefetch would fail and no useful error would > > be reported. > > > > Perhaps we'll need "hg debugprefetch && hg verify" ? > > But that would also prefetch before verifying the revlog? Yes. The point is that "verify" never crashes because of prefetch. If we've already downloaded all lfs data, revlog corruption can be verified by running "hg verify." "hg verify" has to be robust for data corruption. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 4 of 6] verify: invoke the file prefetch hook
> On Apr 16, 2018, at 9:39 AM, Yuya Nishiharawrote: > >> On Mon, 16 Apr 2018 09:15:48 -0400, Matt Harbison wrote: >> On Apr 16, 2018, at 8:34 AM, Yuya Nishihara wrote: On Mon, 16 Apr 2018 08:25:07 -0400, Matt Harbison wrote: >> On Apr 16, 2018, at 7:35 AM, Yuya Nishihara wrote: >> >> On Sun, 15 Apr 2018 02:44:08 -0400, Matt Harbison wrote: >> # HG changeset patch >> # User Matt Harbison >> # Date 1523752111 14400 >> # Sat Apr 14 20:28:31 2018 -0400 >> # Node ID 3b0c3d4939b56ca038dbbba17da424699a6b339d >> # Parent 691a7d3f2df80908e52a170897a4492a528c3533 >> verify: invoke the file prefetch hook >> >> It's unfortunate that verify wants to download everything. Maybe we can >> create >> a custom transfer handler for LFS. But it shouldn't be painful in the >> meantime, >> and it's likely that blobs will be served up from more than just hgweb. >> >> diff --git a/mercurial/verify.py b/mercurial/verify.py >> --- a/mercurial/verify.py >> +++ b/mercurial/verify.py >> @@ -25,6 +25,7 @@ from . import ( >> >> def verify(repo): >> with repo.lock(): >> +scmutil.fileprefetchhooks(repo, repo.set('all()')) >> return verifier(repo).verify() > > I don't think "hg verify" should go that abstraction level because the > repository might be inconsistent state. Do you mean using a revset, or prefetching at all? Grabbing one file at a time will likely be painfully slow. If the revset bit is the bad part, what is the alternative with a corrupt repo? >>> >>> I think we should avoid any write operation on damaged repo. Is there any >>> way >>> to disable fetching at all? >> >> Maybe we could wrap hg.verify() to stuff a flag is svfs? But I think then >> the revlog flag processor will flag each revision as corrupt anyway, hiding >> the real error. >> >> Avoiding writes on a corrupt repo makes sense, but in this case I think it >> is safe. The storage is external, so nothing gets more corrupt, and the >> blobs are checksummed on their own before adding them to the store. > > That's true for lfs, but not all prefetch-able storage would behave as > such. Another concern is we're doing prefetch *before* verifying revlogs. > If a revlog is damaged, the prefetch would fail and no useful error would > be reported. > > Perhaps we'll need "hg debugprefetch && hg verify" ? But that would also prefetch before verifying the revlog? >> As a point of reference, largefiles will verify the external files (by >> asking the server to do it IIRC). I’d like to do something like that here, >> but obviously that extension won’t be supported anywhere else. So from a UX >> point of view, IDK how we can sanely do that if it doesn’t fallback to >> fetching them. > > IMHO, that is one of the most confusing features the largefiles has. > Largefiles > doesn't need to extend the verify command. I like that it’s easy to tell if a blob is missing from the server, and that you don’t need to script something with an external tool to verify the local blobs. I do remember being confused by the latest round of work in that area, but I thought maybe it was awkward because of BC concerns. I’ll drop this patch for now, because it won’t get resolved this cycle, even if there was a clear path forward. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 4 of 6] verify: invoke the file prefetch hook
On Mon, 16 Apr 2018 09:15:48 -0400, Matt Harbison wrote: > > > On Apr 16, 2018, at 8:34 AM, Yuya Nishiharawrote: > > > >> On Mon, 16 Apr 2018 08:25:07 -0400, Matt Harbison wrote: > >> > On Apr 16, 2018, at 7:35 AM, Yuya Nishihara wrote: > > On Sun, 15 Apr 2018 02:44:08 -0400, Matt Harbison wrote: > # HG changeset patch > # User Matt Harbison > # Date 1523752111 14400 > # Sat Apr 14 20:28:31 2018 -0400 > # Node ID 3b0c3d4939b56ca038dbbba17da424699a6b339d > # Parent 691a7d3f2df80908e52a170897a4492a528c3533 > verify: invoke the file prefetch hook > > It's unfortunate that verify wants to download everything. Maybe we can > create > a custom transfer handler for LFS. But it shouldn't be painful in the > meantime, > and it's likely that blobs will be served up from more than just hgweb. > > diff --git a/mercurial/verify.py b/mercurial/verify.py > --- a/mercurial/verify.py > +++ b/mercurial/verify.py > @@ -25,6 +25,7 @@ from . import ( > > def verify(repo): > with repo.lock(): > +scmutil.fileprefetchhooks(repo, repo.set('all()')) > return verifier(repo).verify() > >>> > >>> I don't think "hg verify" should go that abstraction level because the > >>> repository might be inconsistent state. > >> > >> Do you mean using a revset, or prefetching at all? Grabbing one file at a > >> time will likely be painfully slow. > >> > >> If the revset bit is the bad part, what is the alternative with a corrupt > >> repo? > > > > I think we should avoid any write operation on damaged repo. Is there any > > way > > to disable fetching at all? > > Maybe we could wrap hg.verify() to stuff a flag is svfs? But I think then > the revlog flag processor will flag each revision as corrupt anyway, hiding > the real error. > > Avoiding writes on a corrupt repo makes sense, but in this case I think it is > safe. The storage is external, so nothing gets more corrupt, and the blobs > are checksummed on their own before adding them to the store. That's true for lfs, but not all prefetch-able storage would behave as such. Another concern is we're doing prefetch *before* verifying revlogs. If a revlog is damaged, the prefetch would fail and no useful error would be reported. Perhaps we'll need "hg debugprefetch && hg verify" ? > As a point of reference, largefiles will verify the external files (by asking > the server to do it IIRC). I’d like to do something like that here, but > obviously that extension won’t be supported anywhere else. So from a UX > point of view, IDK how we can sanely do that if it doesn’t fallback to > fetching them. IMHO, that is one of the most confusing features the largefiles has. Largefiles doesn't need to extend the verify command. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3375: cleanup: polyfill assertRaisesRegex so we can avoid assertRaisesRegexp
This revision was automatically updated to reflect the committed changes. Closed by commit rHG1859b9a7ddef: cleanup: polyfill assertRaisesRegex so we can avoid assertRaisesRegexp (authored by durin42, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3375?vs=8281=8309 REVISION DETAIL https://phab.mercurial-scm.org/D3375 AFFECTED FILES tests/test-simplekeyvaluefile.py tests/test-wireproto-clientreactor.py tests/test-wireproto-framing.py tests/test-wsgirequest.py CHANGE DETAILS diff --git a/tests/test-wsgirequest.py b/tests/test-wsgirequest.py --- a/tests/test-wsgirequest.py +++ b/tests/test-wsgirequest.py @@ -196,21 +196,27 @@ self.assertEqual(r.dispatchparts, [b'pathinfo']) self.assertEqual(r.dispatchpath, b'pathinfo') +if not getattr(unittest.TestCase, 'assertRaisesRegex', False): +# Python 3.7 deprecates the regex*p* version, but 2.7 lacks +# the regex version. +assertRaisesRegex = (# camelcase-required +unittest.TestCase.assertRaisesRegexp) + def testreponame(self): """repository path components get stripped from URL.""" -with self.assertRaisesRegexp(error.ProgrammingError, +with self.assertRaisesRegex(error.ProgrammingError, b'reponame requires PATH_INFO'): parse(DEFAULT_ENV, reponame=b'repo') -with self.assertRaisesRegexp(error.ProgrammingError, +with self.assertRaisesRegex(error.ProgrammingError, b'PATH_INFO does not begin with repo ' b'name'): parse(DEFAULT_ENV, reponame=b'repo', extra={ r'PATH_INFO': r'/pathinfo', }) -with self.assertRaisesRegexp(error.ProgrammingError, +with self.assertRaisesRegex(error.ProgrammingError, b'reponame prefix of PATH_INFO'): parse(DEFAULT_ENV, reponame=b'repo', extra={ r'PATH_INFO': r'/repoextra/path', diff --git a/tests/test-wireproto-framing.py b/tests/test-wireproto-framing.py --- a/tests/test-wireproto-framing.py +++ b/tests/test-wireproto-framing.py @@ -103,19 +103,25 @@ ffs(b'1 1 0 command-data eos %s' % data.getvalue()), ]) +if not getattr(unittest.TestCase, 'assertRaisesRegex', False): +# Python 3.7 deprecates the regex*p* version, but 2.7 lacks +# the regex version. +assertRaisesRegex = (# camelcase-required +unittest.TestCase.assertRaisesRegexp) + def testtextoutputformattingstringtype(self): """Formatting string must be bytes.""" -with self.assertRaisesRegexp(ValueError, 'must use bytes formatting '): +with self.assertRaisesRegex(ValueError, 'must use bytes formatting '): list(framing.createtextoutputframe(None, 1, [ (b'foo'.decode('ascii'), [], [])])) def testtextoutputargumentbytes(self): -with self.assertRaisesRegexp(ValueError, 'must use bytes for argument'): +with self.assertRaisesRegex(ValueError, 'must use bytes for argument'): list(framing.createtextoutputframe(None, 1, [ (b'foo', [b'foo'.decode('ascii')], [])])) def testtextoutputlabelbytes(self): -with self.assertRaisesRegexp(ValueError, 'must use bytes for labels'): +with self.assertRaisesRegex(ValueError, 'must use bytes for labels'): list(framing.createtextoutputframe(None, 1, [ (b'foo', [], [b'foo'.decode('ascii')])])) 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 @@ -24,6 +24,13 @@ class SingleSendTests(unittest.TestCase): """A reactor that can only send once rejects subsequent sends.""" + +if not getattr(unittest.TestCase, 'assertRaisesRegex', False): +# Python 3.7 deprecates the regex*p* version, but 2.7 lacks +# the regex version. +assertRaisesRegex = (# camelcase-required +unittest.TestCase.assertRaisesRegexp) + def testbasic(self): reactor = framing.clientreactor(hasmultiplesend=False, buffersends=True) @@ -39,11 +46,11 @@ self.assertEqual(request.state, b'sent') -with self.assertRaisesRegexp(error.ProgrammingError, +with self.assertRaisesRegex(error.ProgrammingError, 'cannot issue new commands'): reactor.callcommand(b'foo', {}) -with self.assertRaisesRegexp(error.ProgrammingError, +with self.assertRaisesRegex(error.ProgrammingError, 'cannot issue new commands'): reactor.callcommand(b'foo', {}) @@ -77,6 +84,12 @@ self.assertEqual(request.state, b'sent') class
D3374: tests: add b prefixes to test-hg-parseurl.py
This revision was automatically updated to reflect the committed changes. Closed by commit rHG5dd71e9ae68a: tests: add b prefixes to test-hg-parseurl.py (authored by durin42, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3374?vs=8279=8308 REVISION DETAIL https://phab.mercurial-scm.org/D3374 AFFECTED FILES tests/test-hg-parseurl.py CHANGE DETAILS diff --git a/tests/test-hg-parseurl.py b/tests/test-hg-parseurl.py --- a/tests/test-hg-parseurl.py +++ b/tests/test-hg-parseurl.py @@ -9,25 +9,25 @@ class ParseRequestTests(unittest.TestCase): def testparse(self): -self.assertEqual(hg.parseurl('http://example.com/no/anchor'), - ('http://example.com/no/anchor', (None, []))) -self.assertEqual(hg.parseurl('http://example.com/an/anchor#foo'), - ('http://example.com/an/anchor', ('foo', []))) +self.assertEqual(hg.parseurl(b'http://example.com/no/anchor'), + (b'http://example.com/no/anchor', (None, []))) +self.assertEqual(hg.parseurl(b'http://example.com/an/anchor#foo'), + (b'http://example.com/an/anchor', (b'foo', []))) self.assertEqual( -hg.parseurl('http://example.com/no/anchor/branches', ['foo']), -('http://example.com/no/anchor/branches', (None, ['foo']))) +hg.parseurl(b'http://example.com/no/anchor/branches', [b'foo']), +(b'http://example.com/no/anchor/branches', (None, [b'foo']))) self.assertEqual( -hg.parseurl('http://example.com/an/anchor/branches#bar', ['foo']), -('http://example.com/an/anchor/branches', ('bar', ['foo']))) +hg.parseurl(b'http://example.com/an/anchor/branches#bar', [b'foo']), +(b'http://example.com/an/anchor/branches', (b'bar', [b'foo']))) self.assertEqual(hg.parseurl( -'http://example.com/an/anchor/branches-None#foo', None), -('http://example.com/an/anchor/branches-None', ('foo', []))) -self.assertEqual(hg.parseurl('http://example.com/'), - ('http://example.com/', (None, []))) -self.assertEqual(hg.parseurl('http://example.com'), - ('http://example.com/', (None, []))) -self.assertEqual(hg.parseurl('http://example.com#foo'), - ('http://example.com/', ('foo', []))) +b'http://example.com/an/anchor/branches-None#foo', None), +(b'http://example.com/an/anchor/branches-None', (b'foo', []))) +self.assertEqual(hg.parseurl(b'http://example.com/'), + (b'http://example.com/', (None, []))) +self.assertEqual(hg.parseurl(b'http://example.com'), + (b'http://example.com/', (None, []))) +self.assertEqual(hg.parseurl(b'http://example.com#foo'), + (b'http://example.com/', (b'foo', []))) if __name__ == '__main__': import silenttestrunner 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
D3367: hgwebdir: un-bytes the env dict before re-parsing env
This revision was automatically updated to reflect the committed changes. Closed by commit rHGa728e3695325: hgwebdir: un-bytes the env dict before re-parsing env (authored by durin42, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3367?vs=8277=8306 REVISION DETAIL https://phab.mercurial-scm.org/D3367 AFFECTED FILES contrib/python3-whitelist 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,12 @@ if real: # Re-parse the WSGI environment to take into account our # repository path component. +uenv = req.rawenv +if pycompat.ispy3: +uenv = {k.decode('latin1'): v for k, v in +uenv.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 diff --git a/contrib/python3-whitelist b/contrib/python3-whitelist --- a/contrib/python3-whitelist +++ b/contrib/python3-whitelist @@ -151,6 +151,7 @@ test-glog-topological.t test-gpg.t test-graft.t +test-hg-parseurl.py test-hghave.t test-hgignore.t test-hgk.t To: durin42, #hg-reviewers, yuja, pulkit Cc: yuja, 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
This revision was automatically updated to reflect the committed changes. Closed by commit rHG65a23cc8e75b: cborutil: implement support for streaming encoding, bytestring decoding (authored by indygreg, committed by ). CHANGED PRIOR TO COMMIT https://phab.mercurial-scm.org/D3303?vs=8301=8305#toc REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3303?vs=8301=8305 REVISION DETAIL https://phab.mercurial-scm.org/D3303 AFFECTED FILES contrib/import-checker.py mercurial/utils/cborutil.py tests/test-cbor.py CHANGE DETAILS diff --git a/tests/test-cbor.py b/tests/test-cbor.py new file mode 100644 --- /dev/null +++ b/tests/test-cbor.py @@ -0,0 +1,210 @@ +from __future__ import absolute_import + +import io +import unittest + +from mercurial.thirdparty import ( +cbor, +) +from mercurial.utils import ( +cborutil, +) + +def loadit(it): +return cbor.loads(b''.join(it)) + +class BytestringTests(unittest.TestCase): +def testsimple(self): +self.assertEqual( +list(cborutil.streamencode(b'foobar')), +[b'\x46', b'foobar']) + +self.assertEqual( +loadit(cborutil.streamencode(b'foobar')), +b'foobar') + +def testlong(self): +source = b'x' * 1048576 + +self.assertEqual(loadit(cborutil.streamencode(source)), source) + +def testfromiter(self): +# This is the example from RFC 7049 Section 2.2.2. +source = [b'\xaa\xbb\xcc\xdd', b'\xee\xff\x99'] + +self.assertEqual( +list(cborutil.streamencodebytestringfromiter(source)), +[ +b'\x5f', +b'\x44', +b'\xaa\xbb\xcc\xdd', +b'\x43', +b'\xee\xff\x99', +b'\xff', +]) + +self.assertEqual( +loadit(cborutil.streamencodebytestringfromiter(source)), +b''.join(source)) + +def testfromiterlarge(self): +source = [b'a' * 16, b'b' * 128, b'c' * 1024, b'd' * 1048576] + +self.assertEqual( +loadit(cborutil.streamencodebytestringfromiter(source)), +b''.join(source)) + +def testindefinite(self): +source = b'\x00\x01\x02\x03' + b'\xff' * 16384 + +it = cborutil.streamencodeindefinitebytestring(source, chunksize=2) + +self.assertEqual(next(it), b'\x5f') +self.assertEqual(next(it), b'\x42') +self.assertEqual(next(it), b'\x00\x01') +self.assertEqual(next(it), b'\x42') +self.assertEqual(next(it), b'\x02\x03') +self.assertEqual(next(it), b'\x42') +self.assertEqual(next(it), b'\xff\xff') + +dest = b''.join(cborutil.streamencodeindefinitebytestring( +source, chunksize=42)) +self.assertEqual(cbor.loads(dest), b''.join(source)) + +def testreadtoiter(self): +source = io.BytesIO(b'\x5f\x44\xaa\xbb\xcc\xdd\x43\xee\xff\x99\xff') + +it = cborutil.readindefinitebytestringtoiter(source) +self.assertEqual(next(it), b'\xaa\xbb\xcc\xdd') +self.assertEqual(next(it), b'\xee\xff\x99') + +with self.assertRaises(StopIteration): +next(it) + +class IntTests(unittest.TestCase): +def testsmall(self): +self.assertEqual(list(cborutil.streamencode(0)), [b'\x00']) +self.assertEqual(list(cborutil.streamencode(1)), [b'\x01']) +self.assertEqual(list(cborutil.streamencode(2)), [b'\x02']) +self.assertEqual(list(cborutil.streamencode(3)), [b'\x03']) +self.assertEqual(list(cborutil.streamencode(4)), [b'\x04']) + +def testnegativesmall(self): +self.assertEqual(list(cborutil.streamencode(-1)), [b'\x20']) +self.assertEqual(list(cborutil.streamencode(-2)), [b'\x21']) +self.assertEqual(list(cborutil.streamencode(-3)), [b'\x22']) +self.assertEqual(list(cborutil.streamencode(-4)), [b'\x23']) +self.assertEqual(list(cborutil.streamencode(-5)), [b'\x24']) + +def testrange(self): +for i in range(-7, 7, 10): +self.assertEqual( +b''.join(cborutil.streamencode(i)), +cbor.dumps(i)) + +class ArrayTests(unittest.TestCase): +def testempty(self): +self.assertEqual(list(cborutil.streamencode([])), [b'\x80']) +self.assertEqual(loadit(cborutil.streamencode([])), []) + +def testbasic(self): +source = [b'foo', b'bar', 1, -10] + +self.assertEqual(list(cborutil.streamencode(source)), [ +b'\x84', b'\x43', b'foo', b'\x43', b'bar', b'\x01', b'\x29']) + +def testemptyfromiter(self): +self.assertEqual(b''.join(cborutil.streamencodearrayfromiter([])), + b'\x9f\xff') + +def testfromiter1(self): +source = [b'foo'] + +self.assertEqual(list(cborutil.streamencodearrayfromiter(source)), [ +b'\x9f', +b'\x43', b'foo', +b'\xff', +]) + +dest =
Re: [PATCH 4 of 6] verify: invoke the file prefetch hook
> On Apr 16, 2018, at 8:34 AM, Yuya Nishiharawrote: > >> On Mon, 16 Apr 2018 08:25:07 -0400, Matt Harbison wrote: >> On Apr 16, 2018, at 7:35 AM, Yuya Nishihara wrote: On Sun, 15 Apr 2018 02:44:08 -0400, Matt Harbison wrote: # HG changeset patch # User Matt Harbison # Date 1523752111 14400 # Sat Apr 14 20:28:31 2018 -0400 # Node ID 3b0c3d4939b56ca038dbbba17da424699a6b339d # Parent 691a7d3f2df80908e52a170897a4492a528c3533 verify: invoke the file prefetch hook It's unfortunate that verify wants to download everything. Maybe we can create a custom transfer handler for LFS. But it shouldn't be painful in the meantime, and it's likely that blobs will be served up from more than just hgweb. diff --git a/mercurial/verify.py b/mercurial/verify.py --- a/mercurial/verify.py +++ b/mercurial/verify.py @@ -25,6 +25,7 @@ from . import ( def verify(repo): with repo.lock(): +scmutil.fileprefetchhooks(repo, repo.set('all()')) return verifier(repo).verify() >>> >>> I don't think "hg verify" should go that abstraction level because the >>> repository might be inconsistent state. >> >> Do you mean using a revset, or prefetching at all? Grabbing one file at a >> time will likely be painfully slow. >> >> If the revset bit is the bad part, what is the alternative with a corrupt >> repo? > > I think we should avoid any write operation on damaged repo. Is there any way > to disable fetching at all? Maybe we could wrap hg.verify() to stuff a flag is svfs? But I think then the revlog flag processor will flag each revision as corrupt anyway, hiding the real error. Avoiding writes on a corrupt repo makes sense, but in this case I think it is safe. The storage is external, so nothing gets more corrupt, and the blobs are checksummed on their own before adding them to the store. As a point of reference, largefiles will verify the external files (by asking the server to do it IIRC). I’d like to do something like that here, but obviously that extension won’t be supported anywhere else. So from a UX point of view, IDK how we can sanely do that if it doesn’t fallback to fetching them. ___ 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. Queued, thanks. INLINE COMMENTS > cborutil.py:206 > +""" > +fn = STREAM_ENCODERS.get(v.__class__) > + Nit: We might have to support subtypes such as util.sortdict. 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
Re: [PATCH 4 of 6] verify: invoke the file prefetch hook
On Mon, 16 Apr 2018 08:25:07 -0400, Matt Harbison wrote: > > > On Apr 16, 2018, at 7:35 AM, Yuya Nishiharawrote: > > > >> On Sun, 15 Apr 2018 02:44:08 -0400, Matt Harbison wrote: > >> # HG changeset patch > >> # User Matt Harbison > >> # Date 1523752111 14400 > >> # Sat Apr 14 20:28:31 2018 -0400 > >> # Node ID 3b0c3d4939b56ca038dbbba17da424699a6b339d > >> # Parent 691a7d3f2df80908e52a170897a4492a528c3533 > >> verify: invoke the file prefetch hook > >> > >> It's unfortunate that verify wants to download everything. Maybe we can > >> create > >> a custom transfer handler for LFS. But it shouldn't be painful in the > >> meantime, > >> and it's likely that blobs will be served up from more than just hgweb. > >> > >> diff --git a/mercurial/verify.py b/mercurial/verify.py > >> --- a/mercurial/verify.py > >> +++ b/mercurial/verify.py > >> @@ -25,6 +25,7 @@ from . import ( > >> > >> def verify(repo): > >> with repo.lock(): > >> +scmutil.fileprefetchhooks(repo, repo.set('all()')) > >> return verifier(repo).verify() > > > > I don't think "hg verify" should go that abstraction level because the > > repository might be inconsistent state. > > Do you mean using a revset, or prefetching at all? Grabbing one file at a > time will likely be painfully slow. > > If the revset bit is the bad part, what is the alternative with a corrupt > repo? I think we should avoid any write operation on damaged repo. Is there any way to disable fetching at all? ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 4 of 6] verify: invoke the file prefetch hook
> On Apr 16, 2018, at 7:35 AM, Yuya Nishiharawrote: > >> On Sun, 15 Apr 2018 02:44:08 -0400, Matt Harbison wrote: >> # HG changeset patch >> # User Matt Harbison >> # Date 1523752111 14400 >> # Sat Apr 14 20:28:31 2018 -0400 >> # Node ID 3b0c3d4939b56ca038dbbba17da424699a6b339d >> # Parent 691a7d3f2df80908e52a170897a4492a528c3533 >> verify: invoke the file prefetch hook >> >> It's unfortunate that verify wants to download everything. Maybe we can >> create >> a custom transfer handler for LFS. But it shouldn't be painful in the >> meantime, >> and it's likely that blobs will be served up from more than just hgweb. >> >> diff --git a/mercurial/verify.py b/mercurial/verify.py >> --- a/mercurial/verify.py >> +++ b/mercurial/verify.py >> @@ -25,6 +25,7 @@ from . import ( >> >> def verify(repo): >> with repo.lock(): >> +scmutil.fileprefetchhooks(repo, repo.set('all()')) >> return verifier(repo).verify() > > I don't think "hg verify" should go that abstraction level because the > repository might be inconsistent state. Do you mean using a revset, or prefetching at all? Grabbing one file at a time will likely be painfully slow. If the revset bit is the bad part, what is the alternative with a corrupt repo? ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 1 of 3 V5] revset: add more test to show current behaviors with label looking like revset
On Mon, 16 Apr 2018 08:58:29 +0200, Boris Feld wrote: > # HG changeset patch > # User Boris Feld> # Date 1519922236 18000 > # Thu Mar 01 11:37:16 2018 -0500 > # Node ID 99b314c5fe199b821705712324647971e79e8cbc > # Parent 7b29556247776a86ead7eb98fd3a20dafd0c08b4 > # EXP-Topic noname > # Available At https://bitbucket.org/octobus/mercurial-devel/ > # hg pull https://bitbucket.org/octobus/mercurial-devel/ -r > 99b314c5fe19 > revset: add more test to show current behaviors with label looking like revset Queued this, thanks. I renamed the test so we can do ./run-tests.py test-revset*. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 3 of 3 V5] revset: skip legacy lookup for revspec wrapped in 'revset(…)'
On Mon, 16 Apr 2018 08:58:31 +0200, Boris Feld wrote: > # HG changeset patch > # User Boris Feld> # Date 1523369212 -7200 > # Tue Apr 10 16:06:52 2018 +0200 > # Node ID 109ca88347d7b531d4b48370efcbc4d6e850cf92 > # Parent f363552ced37ae028bbcf2cba1f02ac623385f54 > # EXP-Topic noname > # Available At https://bitbucket.org/octobus/mercurial-devel/ > # hg pull https://bitbucket.org/octobus/mercurial-devel/ -r > 109ca88347d7 > revset: skip legacy lookup for revspec wrapped in 'revset(…)' > @@ -2191,7 +2194,12 @@ def matchany(ui, specs, lookup=None, loc > raise error.ParseError(_("empty query")) > parsedspecs = [] > for s in specs: > -parsedspecs.append(revsetlang.parse(s, lookup)) > +lookupthis = lookup > +stripped = s.strip() > +if (stripped.startswith(prefixrevset) > +and stripped.endswith(postfixrevset)): > +lookupthis = None > +parsedspecs.append(revsetlang.parse(s, lookupthis)) Is it okay to move this hack to revsetlang._parsewith? @@ -482,6 +485,8 @@ def _parsewith(spec, lookup=None, symini ... ParseError: ('invalid token', 4) """ +if spec.startswith('revset(') and spec.endswith(')'): +lookup = None p = parser.parser(elements) tree, pos = p.parse(tokenize(spec, lookup=lookup, syminitletters=syminitletters)) I don't think revset.match*() is the right place to do parsing stuff, and we'll need a tokenizer to make it more correctly handle variants such as ' revset ( ... )' or '... and revset(...)'. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH] lfs: add the 'Authorization' property to the Batch API response, if present
> On Apr 16, 2018, at 7:58 AM, Yuya Nishiharawrote: > >> On Sun, 15 Apr 2018 19:41:32 -0400, Matt Harbison wrote: >> # HG changeset patch >> # User Matt Harbison >> # Date 1523027627 14400 >> # Fri Apr 06 11:13:47 2018 -0400 >> # Node ID 6d8c47590030244033d51c2d0b390d2ee6337dea >> # Parent acd5a25c179269df689b8799aa7cbc52d5451251 >> lfs: add the 'Authorization' property to the Batch API response, if present >> >> The client copies all of these properties under 'header' to the HTTP Headers >> of >> the subsequent GET or PUT request that it performs. That allows the Basic >> HTTP >> authentication used to authorize the Batch API request to also authorize the >> upload/download action. > > I'm not pretty sure, but I think it's up to the client to resend an > Authorization header depending on the realm provided by the server. Doesn't > the server request authentication for batch requests? It does request authentication for batch requests, but doesn’t for the transfer, which surprised me. Somewhere I think I read that the authentication request is also tied to the URI, which would explain why the client isn’t resending on its own. I wireshark traced git-lfs to a couple of different servers, and this seemed to be what it was doing. That gitbucket footnote shows it rolling its own authorization token that it expects on transfer, so I thought this was by design. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH] configitems: register server.zstdlevel
On Sun, 15 Apr 2018 22:36:04 -0400, Matt Harbison wrote: > # HG changeset patch > # User Matt Harbison> # Date 1523845683 14400 > # Sun Apr 15 22:28:03 2018 -0400 > # Node ID 219d6a6bcbc3459ca2af6397346e8af6b80a8951 > # Parent 6d8c47590030244033d51c2d0b390d2ee6337dea > configitems: register server.zstdlevel Queued, thanks. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH] lfs: add the 'Authorization' property to the Batch API response, if present
On Sun, 15 Apr 2018 19:41:32 -0400, Matt Harbison wrote: > # HG changeset patch > # User Matt Harbison> # Date 1523027627 14400 > # Fri Apr 06 11:13:47 2018 -0400 > # Node ID 6d8c47590030244033d51c2d0b390d2ee6337dea > # Parent acd5a25c179269df689b8799aa7cbc52d5451251 > lfs: add the 'Authorization' property to the Batch API response, if present > > The client copies all of these properties under 'header' to the HTTP Headers > of > the subsequent GET or PUT request that it performs. That allows the Basic > HTTP > authentication used to authorize the Batch API request to also authorize the > upload/download action. I'm not pretty sure, but I think it's up to the client to resend an Authorization header depending on the realm provided by the server. Doesn't the server request authentication for batch requests? ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[PATCH 1 of 3 V5] revset: add more test to show current behaviors with label looking like revset
# HG changeset patch # User Boris Feld# Date 1519922236 18000 # Thu Mar 01 11:37:16 2018 -0500 # Node ID 99b314c5fe199b821705712324647971e79e8cbc # Parent 7b29556247776a86ead7eb98fd3a20dafd0c08b4 # EXP-Topic noname # Available At https://bitbucket.org/octobus/mercurial-devel/ # hg pull https://bitbucket.org/octobus/mercurial-devel/ -r 99b314c5fe19 revset: add more test to show current behaviors with label looking like revset There are very few constraints on what character can be put into tags and other labels. We add more tests showing some of extreme cases that user can currently use. diff --git a/tests/test-legacy-lookup.t b/tests/test-legacy-lookup.t new file mode 100644 --- /dev/null +++ b/tests/test-legacy-lookup.t @@ -0,0 +1,259 @@ + + $ cat >> $HGRCPATH << EOF + > [ui] + > logtemplate="{rev}:{node|short} {desc} [{tags}]\n" + > EOF + + $ hg init legacy-lookup + $ cd legacy-lookup + $ echo a > a + $ hg add a + $ hg commit -m 'first' + $ echo aa > a + $ hg commit -m 'second' + $ hg log -G + @ 1:43114e71eddd second [tip] + | + o 0:a87874c6ec31 first [] + + +Create a tag that looks like a revset + + $ hg tag 'rev(0)' + $ hg log -G + @ 2:fb616635b18f Added tag rev(0) for changeset 43114e71eddd [tip] + | + o 1:43114e71eddd second [rev(0)] + | + o 0:a87874c6ec31 first [] + + +See how various things are resolved +--- + +Revision numbers + + $ hg log -r '0' + 0:a87874c6ec31 first [] + $ hg log -r '1' + 1:43114e71eddd second [rev(0)] + +"rev(x)" form (the one conflicting with the tags) +(resolved as a label) + + $ hg log -r 'rev(0)' + 1:43114e71eddd second [rev(0)] + $ hg log -r 'rev(1)' + 1:43114e71eddd second [rev(0)] + +same within a simple revspec +(still resolved as the label) + + $ hg log -r ':rev(0)' + 0:a87874c6ec31 first [] + 1:43114e71eddd second [rev(0)] + $ hg log -r 'rev(0):' + 1:43114e71eddd second [rev(0)] + 2:fb616635b18f Added tag rev(0) for changeset 43114e71eddd [tip] + +within a more advances revset +(still resolved as the label) + + $ hg log -r 'rev(0) and branch(default)' + 0:a87874c6ec31 first [] + +some of the above with quote to force its resolution as a label + + $ hg log -r ':"rev(0)"' + 0:a87874c6ec31 first [] + 1:43114e71eddd second [rev(0)] + $ hg log -r '"rev(0)":' + 1:43114e71eddd second [rev(0)] + 2:fb616635b18f Added tag rev(0) for changeset 43114e71eddd [tip] + $ hg log -r '"rev(0)" and branch(default)' + 1:43114e71eddd second [rev(0)] + +confusing bits within parents + + $ hg log -r '(rev(0))' + 0:a87874c6ec31 first [] + $ hg log -r '( rev(0))' + 0:a87874c6ec31 first [] + $ hg log -r '("rev(0)")' + 1:43114e71eddd second [rev(0)] + +Test label with quote in them. + + $ hg tag '"foo"' + + $ hg log -r '"foo"' + 2:fb616635b18f Added tag rev(0) for changeset 43114e71eddd ["foo"] + $ hg log -r '("foo")' + abort: unknown revision 'foo'! + [255] + $ hg log -r '("\"foo\"")' + 2:fb616635b18f Added tag rev(0) for changeset 43114e71eddd ["foo"] + +Test label with dash in them. + + $ hg tag 'foo-bar' + + $ hg log -r 'foo-bar' + 3:a50aae922707 Added tag "foo" for changeset fb616635b18f [foo-bar] + $ hg log -r '(foo-bar)' + 3:a50aae922707 Added tag "foo" for changeset fb616635b18f [foo-bar] + $ hg log -r '"foo-bar"' + 3:a50aae922707 Added tag "foo" for changeset fb616635b18f [foo-bar] + $ hg log -r '("foo-bar")' + 3:a50aae922707 Added tag "foo" for changeset fb616635b18f [foo-bar] + +Test label with + in them. + + $ hg tag 'foo+bar' + + $ hg log -r 'foo+bar' + 4:bbf52b87b370 Added tag foo-bar for changeset a50aae922707 [foo+bar] + $ hg log -r '(foo+bar)' + abort: unknown revision 'foo'! + [255] + $ hg log -r '"foo+bar"' + 4:bbf52b87b370 Added tag foo-bar for changeset a50aae922707 [foo+bar] + $ hg log -r '("foo+bar")' + 4:bbf52b87b370 Added tag foo-bar for changeset a50aae922707 [foo+bar] + +Test tag with numeric version number. + + $ hg tag '1.2' + + $ hg log -r '1.2' + 5:ff42fde8edbb Added tag foo+bar for changeset bbf52b87b370 [1.2] + $ hg log -r '(1.2)' + 5:ff42fde8edbb Added tag foo+bar for changeset bbf52b87b370 [1.2] + $ hg log -r '"1.2"' + 5:ff42fde8edbb Added tag foo+bar for changeset bbf52b87b370 [1.2] + $ hg log -r '("1.2")' + 5:ff42fde8edbb Added tag foo+bar for changeset bbf52b87b370 [1.2] + $ hg log -r '::"1.2"' + 0:a87874c6ec31 first [] + 1:43114e71eddd second [rev(0)] + 2:fb616635b18f Added tag rev(0) for changeset 43114e71eddd ["foo"] + 3:a50aae922707 Added tag "foo" for changeset fb616635b18f [foo-bar] + 4:bbf52b87b370 Added tag foo-bar for changeset a50aae922707 [foo+bar] + 5:ff42fde8edbb Added tag foo+bar for changeset bbf52b87b370 [1.2] + $ hg log -r '::1.2' + 0:a87874c6ec31 first [] + 1:43114e71eddd second [rev(0)] + 2:fb616635b18f Added tag rev(0) for changeset 43114e71eddd ["foo"] + 3:a50aae922707 Added tag "foo" for changeset fb616635b18f [foo-bar] + 4:bbf52b87b370 Added tag
[PATCH 3 of 3 V5] revset: skip legacy lookup for revspec wrapped in 'revset(…)'
# HG changeset patch # User Boris Feld# Date 1523369212 -7200 # Tue Apr 10 16:06:52 2018 +0200 # Node ID 109ca88347d7b531d4b48370efcbc4d6e850cf92 # Parent f363552ced37ae028bbcf2cba1f02ac623385f54 # EXP-Topic noname # Available At https://bitbucket.org/octobus/mercurial-devel/ # hg pull https://bitbucket.org/octobus/mercurial-devel/ -r 109ca88347d7 revset: skip legacy lookup for revspec wrapped in 'revset(…)' Currently, multiple labels can take forms that can be confused with revset (eg: "rev(0)" is a valid tag). Since we look up for tags before evaluating revset, this means a tag can shadow a valid revset at any time. We now enforce the strict revset parsing when wrapped with 'revset(…)'. For now, This only work on a whole revspec (but can be used within the revset without effect). This might change in the future if we improve the implementation. The feature is undocumented for now, keeping it in the experimental namespace. In case a better approach to achieve the same goal is found. The syntax looks like a revset but is not implemented as such for now. Since the goal is to avoid some preprocessing that happens before revset parsing, we cannot simply implement it as a revset predicate. There was other approaches discussed over the mailing-list but they were less convincing. Having a configuration flag to disable legacy lookup have been considered but discarded. There are too many common uses of ambiguous identifier (eg: '+', '-' or '..') to have the legacy lookup mechanism turned off. In addition, the approach can control the parsing of each revset, making it more flexible. For example, a revset used as the value of an existing configuration option (eg: pushrev) could enforce its resolution as a revset (by using the prefix) while user inputs would still use the legacy lookup. In addition of offering a way to unambiguously input a revset, this prefix allow skipping the name lookup providing a significant speedup in some case. diff --git a/mercurial/revset.py b/mercurial/revset.py --- a/mercurial/revset.py +++ b/mercurial/revset.py @@ -2173,6 +2173,9 @@ def match(ui, spec, lookup=None): """Create a matcher for a single revision spec""" return matchany(ui, [spec], lookup=None) +prefixrevset = 'revset(' +postfixrevset = ')' + def matchany(ui, specs, lookup=None, localalias=None): """Create a matcher that will include any revisions matching one of the given specs @@ -2191,7 +2194,12 @@ def matchany(ui, specs, lookup=None, loc raise error.ParseError(_("empty query")) parsedspecs = [] for s in specs: -parsedspecs.append(revsetlang.parse(s, lookup)) +lookupthis = lookup +stripped = s.strip() +if (stripped.startswith(prefixrevset) +and stripped.endswith(postfixrevset)): +lookupthis = None +parsedspecs.append(revsetlang.parse(s, lookupthis)) if len(parsedspecs) == 1: tree = parsedspecs[0] else: diff --git a/mercurial/revsetlang.py b/mercurial/revsetlang.py --- a/mercurial/revsetlang.py +++ b/mercurial/revsetlang.py @@ -352,6 +352,9 @@ def _analyze(x): elif op == 'keyvalue': return (op, x[1], _analyze(x[2])) elif op == 'func': +f = getsymbol(x[1]) +if f == 'revset': +return _analyze(x[2]) return (op, x[1], _analyze(x[2])) raise ValueError('invalid operator %r' % op) diff --git a/tests/test-legacy-lookup.t b/tests/test-legacy-lookup.t --- a/tests/test-legacy-lookup.t +++ b/tests/test-legacy-lookup.t @@ -62,6 +62,12 @@ within a more advances revset $ hg log -r 'rev(0) and branch(default)' 0:a87874c6ec31 first [] +with explicit revset resolution +(still resolved as the label) + + $ hg log -r 'revset(rev(0))' + 0:a87874c6ec31 first [] + some of the above with quote to force its resolution as a label $ hg log -r ':"rev(0)"' @@ -91,8 +97,13 @@ Test label with quote in them. $ hg log -r '("foo")' abort: unknown revision 'foo'! [255] + $ hg log -r 'revset("foo")' + abort: unknown revision 'foo'! + [255] $ hg log -r '("\"foo\"")' 2:fb616635b18f Added tag rev(0) for changeset 43114e71eddd ["foo"] + $ hg log -r 'revset("\"foo\"")' + 2:fb616635b18f Added tag rev(0) for changeset 43114e71eddd ["foo"] Test label with dash in them. @@ -116,6 +127,9 @@ Test label with + in them. $ hg log -r '(foo+bar)' abort: unknown revision 'foo'! [255] + $ hg log -r 'revset(foo+bar)' + abort: unknown revision 'foo'! + [255] $ hg log -r '"foo+bar"' 4:bbf52b87b370 Added tag foo-bar for changeset a50aae922707 [foo+bar] $ hg log -r '("foo+bar")' @@ -129,6 +143,8 @@ Test tag with numeric version number. 5:ff42fde8edbb Added tag foo+bar for changeset bbf52b87b370 [1.2] $ hg log -r '(1.2)' 5:ff42fde8edbb Added tag foo+bar for changeset bbf52b87b370 [1.2] + $ hg log -r 'revset(1.2)' + 5:ff42fde8edbb Added tag foo+bar for changeset
[PATCH 2 of 3 V5] revset: use and explicit loop to resolve each spec
# HG changeset patch # User Boris Feld# Date 1523367822 -7200 # Tue Apr 10 15:43:42 2018 +0200 # Node ID f363552ced37ae028bbcf2cba1f02ac623385f54 # Parent 99b314c5fe199b821705712324647971e79e8cbc # EXP-Topic noname # Available At https://bitbucket.org/octobus/mercurial-devel/ # hg pull https://bitbucket.org/octobus/mercurial-devel/ -r f363552ced37 revset: use and explicit loop to resolve each spec This is useful to clarify the next changeset. diff --git a/mercurial/revset.py b/mercurial/revset.py --- a/mercurial/revset.py +++ b/mercurial/revset.py @@ -2189,11 +2189,13 @@ def matchany(ui, specs, lookup=None, loc return mfunc if not all(specs): raise error.ParseError(_("empty query")) -if len(specs) == 1: -tree = revsetlang.parse(specs[0], lookup) +parsedspecs = [] +for s in specs: +parsedspecs.append(revsetlang.parse(s, lookup)) +if len(parsedspecs) == 1: +tree = parsedspecs[0] else: -tree = ('or', -('list',) + tuple(revsetlang.parse(s, lookup) for s in specs)) +tree = ('or', ('list',) + tuple(parsedspecs)) aliases = [] warn = None ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH 1 of 3] makefile: mkdir is not needed on templatized docker builds
On Sun, 15 Apr 2018 15:24:28 +0200 Antonio Muci wrote: > Summarizing: I would try to find a more robust way of generating > packages, but it will take some time. Yep, people did discover that the way we do it now is not the most "correct", but it's hard to formulate what is "correct" when it comes to building packages in docker. Patches are welcome, and since code freeze is scheduled for today, there's plenty of time for the search of a better way: until May 1st or so only patches to stable will be accepted. Keep in mind that everything seems to be working not just on Linux hosts, I think some people build packages on OS X too. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
mercurial@37542: 45 new changesets
45 new changesets in mercurial: https://www.mercurial-scm.org/repo/hg/rev/aacfca6f9767 changeset: 37498:aacfca6f9767 user:Joerg Sonnenbergerdate:Thu Jan 18 12:54:01 2018 +0100 summary: wireproto: support for pullbundles https://www.mercurial-scm.org/repo/hg/rev/75c13343cf38 changeset: 37499:75c13343cf38 user:Yuya Nishihara date:Sun Mar 18 23:36:52 2018 +0900 summary: templater: wrap result of '%' operation so it never looks like a thunk https://www.mercurial-scm.org/repo/hg/rev/8bb3899a0f47 changeset: 37500:8bb3899a0f47 user:Yuya Nishihara date:Thu Mar 15 22:27:16 2018 +0900 summary: formatter: make nested items somewhat readable in template output https://www.mercurial-scm.org/repo/hg/rev/0f4de9c27973 changeset: 37501:0f4de9c27973 user:Yuya Nishihara date:Thu Mar 15 21:09:37 2018 +0900 summary: templater: add public interface returning a set of resource keys https://www.mercurial-scm.org/repo/hg/rev/40c7347f6848 changeset: 37502:40c7347f6848 user:Yuya Nishihara date:Sat Mar 17 23:34:38 2018 +0900 summary: formatter: remove template resources from nested items before generating JSON https://www.mercurial-scm.org/repo/hg/rev/49a8c2cc7978 changeset: 37503:49a8c2cc7978 user:Yuya Nishihara date:Mon Mar 19 20:23:27 2018 +0900 summary: templatekw: fix return type of {succsandmarkers} (BC) https://www.mercurial-scm.org/repo/hg/rev/901e749ca0e1 changeset: 37504:901e749ca0e1 user:Martin von Zweigbergk date:Sun Apr 08 08:06:34 2018 -0700 summary: context: extract partial nodeid lookup method to scmutil https://www.mercurial-scm.org/repo/hg/rev/966061b8826d changeset: 37505:966061b8826d user:Martin von Zweigbergk date:Fri Apr 06 09:41:25 2018 -0700 summary: histedit: drop unnecessary check for "self.node is not None" https://www.mercurial-scm.org/repo/hg/rev/c4131138eadb changeset: 37506:c4131138eadb user:Martin von Zweigbergk date:Fri Apr 06 09:43:17 2018 -0700 summary: histedit: look up partial nodeid as partial nodeid https://www.mercurial-scm.org/repo/hg/rev/9b16a67cef56 changeset: 37507:9b16a67cef56 user:Martin von Zweigbergk date:Fri Apr 06 09:53:17 2018 -0700 summary: eol: look up partial nodeid as partial nodeid https://www.mercurial-scm.org/repo/hg/rev/30a7b32897f1 changeset: 37508:30a7b32897f1 user:Yuya Nishihara date:Sun Apr 01 22:11:58 2018 +0900 summary: hgwebdir: wrap {entries} with mappinggenerator https://www.mercurial-scm.org/repo/hg/rev/cb7b275c0cd0 changeset: 37509:cb7b275c0cd0 user:Yuya Nishihara date:Sun Apr 01 22:14:36 2018 +0900 summary: hgweb: wrap {pathdef} with mappinglist https://www.mercurial-scm.org/repo/hg/rev/876d54f800cf changeset: 37510:876d54f800cf user:Yuya Nishihara date:Sun Apr 01 22:20:44 2018 +0900 summary: hgweb: wrap {labels} by hybridlist() https://www.mercurial-scm.org/repo/hg/rev/356e61e82c2a changeset: 37511:356e61e82c2a user:Yuya Nishihara date:Sun Apr 01 22:32:34 2018 +0900 summary: hgweb: move archivespecs to webutil https://www.mercurial-scm.org/repo/hg/rev/aac97d043e6d changeset: 37512:aac97d043e6d user:Yuya Nishihara date:Sun Apr 01 22:33:55 2018 +0900 summary: hgweb: drop archivespecs from requestcontext https://www.mercurial-scm.org/repo/hg/rev/40a7c1dd2df9 changeset: 37513:40a7c1dd2df9 user:Yuya Nishihara date:Sun Apr 01 22:37:03 2018 +0900 summary: hgweb: move archivelist() of hgwebdir to webutil https://www.mercurial-scm.org/repo/hg/rev/034a422aeaff changeset: 37514:034a422aeaff user:Yuya Nishihara date:Sun Apr 01 22:40:15 2018 +0900 summary: hgweb: forward archivelist() of hgweb to webutil https://www.mercurial-scm.org/repo/hg/rev/8a5ee6aa8870 changeset: 37515:8a5ee6aa8870 user:Yuya Nishihara date:Sun Apr 01 22:41:49 2018 +0900 summary: hgweb: wrap {archives} with mappinglist https://www.mercurial-scm.org/repo/hg/rev/20808ddb4990 changeset: 37516:20808ddb4990 user:Matt Harbison date:Tue Apr 10 22:57:55 2018 -0400 summary: tests: stabilize test-pull-bundle.t for Windows https://www.mercurial-scm.org/repo/hg/rev/491edf2435a0 changeset: 37517:491edf2435a0 user:Matt Harbison date:Sat Apr 07 22:40:11 2018 -0400 summary: lfs: add the ability to disable the usercache https://www.mercurial-scm.org/repo/hg/rev/092eff6833a7 changeset: