D3393: bundle: introduce per-engine compression level

2018-04-16 Thread indygreg (Gregory Szorc)
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

2018-04-16 Thread indygreg (Gregory Szorc)
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

2018-04-16 Thread indygreg (Gregory Szorc)
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

2018-04-16 Thread indygreg (Gregory Szorc)
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)

2018-04-16 Thread indygreg (Gregory Szorc)
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

2018-04-16 Thread indygreg (Gregory Szorc)
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

2018-04-16 Thread indygreg (Gregory Szorc)
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

2018-04-16 Thread indygreg (Gregory Szorc)
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

2018-04-16 Thread indygreg (Gregory Szorc)
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

2018-04-16 Thread indygreg (Gregory Szorc)
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

2018-04-16 Thread Mercurial Commits
28 new changesets in mercurial:

https://www.mercurial-scm.org/repo/hg/rev/eb687c28a915
changeset:   37623:eb687c28a915
user:Gregory Szorc 
date: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

2018-04-16 Thread Matt Harbison
# 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

2018-04-16 Thread mharbison72 (Matt Harbison)
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

2018-04-16 Thread Mercurial Commits
14 new changesets in mercurial:

https://www.mercurial-scm.org/repo/hg/rev/01bfe5ad0c53
changeset:   37609:01bfe5ad0c53
user:Gregory Szorc 
date: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

2018-04-16 Thread indygreg (Gregory Szorc)
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

2018-04-16 Thread indygreg (Gregory Szorc)
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

2018-04-16 Thread khanchi97 (Sushil khanchi)
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

2018-04-16 Thread durin42 (Augie Fackler)
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

2018-04-16 Thread durin42 (Augie Fackler)
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

2018-04-16 Thread joerg.sonnenberger (Joerg Sonnenberger)
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

2018-04-16 Thread joerg.sonnenberger (Joerg Sonnenberger)
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

2018-04-16 Thread mercurial-bugs
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

2018-04-16 Thread durin42 (Augie Fackler)
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

2018-04-16 Thread durin42 (Augie Fackler)
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

2018-04-16 Thread durin42 (Augie Fackler)
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

2018-04-16 Thread durin42 (Augie Fackler)
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

2018-04-16 Thread durin42 (Augie Fackler)
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

2018-04-16 Thread durin42 (Augie Fackler)
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

2018-04-16 Thread durin42 (Augie Fackler)
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

2018-04-16 Thread durin42 (Augie Fackler)
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

2018-04-16 Thread durin42 (Augie Fackler)
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

2018-04-16 Thread durin42 (Augie Fackler)
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

2018-04-16 Thread durin42 (Augie Fackler)
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

2018-04-16 Thread durin42 (Augie Fackler)
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

2018-04-16 Thread durin42 (Augie Fackler)
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

2018-04-16 Thread durin42 (Augie Fackler)
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

2018-04-16 Thread durin42 (Augie Fackler)
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

2018-04-16 Thread durin42 (Augie Fackler)
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

2018-04-16 Thread durin42 (Augie Fackler)
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

2018-04-16 Thread durin42 (Augie Fackler)
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

2018-04-16 Thread durin42 (Augie Fackler)
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

2018-04-16 Thread durin42 (Augie Fackler)
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

2018-04-16 Thread indygreg (Gregory Szorc)
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

2018-04-16 Thread quark (Jun Wu)
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

2018-04-16 Thread quark (Jun Wu)
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

2018-04-16 Thread indygreg (Gregory Szorc)
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

2018-04-16 Thread quark (Jun Wu)
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

2018-04-16 Thread martinvonz (Martin von Zweigbergk)
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

2018-04-16 Thread indygreg (Gregory Szorc)
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

2018-04-16 Thread indygreg (Gregory Szorc)
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

2018-04-16 Thread indygreg (Gregory Szorc)
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

2018-04-16 Thread indygreg (Gregory Szorc)
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

2018-04-16 Thread indygreg (Gregory Szorc)
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)

2018-04-16 Thread indygreg (Gregory Szorc)
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)

2018-04-16 Thread indygreg (Gregory Szorc)
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

2018-04-16 Thread indygreg (Gregory Szorc)
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

2018-04-16 Thread indygreg (Gregory Szorc)
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

2018-04-16 Thread indygreg (Gregory Szorc)
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

2018-04-16 Thread durin42 (Augie Fackler)
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

2018-04-16 Thread durin42 (Augie Fackler)
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

2018-04-16 Thread durin42 (Augie Fackler)
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

2018-04-16 Thread durin42 (Augie Fackler)
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

2018-04-16 Thread durin42 (Augie Fackler)
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

2018-04-16 Thread durin42 (Augie Fackler)
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

2018-04-16 Thread durin42 (Augie Fackler)
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

2018-04-16 Thread durin42 (Augie Fackler)
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

2018-04-16 Thread Mercurial Commits
52 new changesets in mercurial:

https://www.mercurial-scm.org/repo/hg/rev/734515aca84d
changeset:   37557:734515aca84d
user:Gregory Szorc 
date: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

2018-04-16 Thread Matt Harbison
# 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

2018-04-16 Thread Matt Harbison
# 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

2018-04-16 Thread Matt Harbison
# 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

2018-04-16 Thread Matt Harbison
# 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

2018-04-16 Thread Mercurial Commits
10 new changesets in mercurial:

https://www.mercurial-scm.org/repo/hg/rev/835ccc2a5ef1
changeset:   37547:835ccc2a5ef1
user:Gregory Szorc 
date: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(…)'

2018-04-16 Thread Feld Boris

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

2018-04-16 Thread martinvonz (Martin von Zweigbergk)
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

2018-04-16 Thread Mercurial Commits
2 new changesets in mercurial:

https://www.mercurial-scm.org/repo/hg/rev/93397c4633f6
changeset:   37545:93397c4633f6
user:Gregory Szorc 
date: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

2018-04-16 Thread Yuya Nishihara
On Mon, 16 Apr 2018 10:24:51 -0400, Matt Harbison wrote:
> 
> > On Apr 16, 2018, at 7:31 AM, Yuya Nishihara  wrote:
> > 
> >> 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

2018-04-16 Thread Matt Harbison

> On Apr 16, 2018, at 7:31 AM, Yuya Nishihara  wrote:
> 
>> 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

2018-04-16 Thread Mercurial Commits
2 new changesets in mercurial:

https://www.mercurial-scm.org/repo/hg/rev/01361be9e2dc
changeset:   37543:01361be9e2dc
user:Gregory Szorc 
date: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

2018-04-16 Thread Yuya Nishihara
On Mon, 16 Apr 2018 09:59:49 -0400, Matt Harbison wrote:
> 
> > On Apr 16, 2018, at 9:39 AM, Yuya Nishihara  wrote:
> > 
> >> 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

2018-04-16 Thread Matt Harbison

> On Apr 16, 2018, at 9:39 AM, Yuya Nishihara  wrote:
> 
>> 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

2018-04-16 Thread Yuya Nishihara
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" ?

> 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

2018-04-16 Thread durin42 (Augie Fackler)
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

2018-04-16 Thread durin42 (Augie Fackler)
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

2018-04-16 Thread durin42 (Augie Fackler)
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

2018-04-16 Thread indygreg (Gregory Szorc)
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

2018-04-16 Thread Matt Harbison

> 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.

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

2018-04-16 Thread yuja (Yuya Nishihara)
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

2018-04-16 Thread Yuya Nishihara
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?
___
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

2018-04-16 Thread Matt Harbison

> 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?

___
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

2018-04-16 Thread Yuya Nishihara
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(…)'

2018-04-16 Thread Yuya Nishihara
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

2018-04-16 Thread Matt Harbison

> On Apr 16, 2018, at 7:58 AM, Yuya Nishihara  wrote:
> 
>> 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

2018-04-16 Thread Yuya Nishihara
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

2018-04-16 Thread Yuya Nishihara
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

2018-04-16 Thread Boris Feld
# 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(…)'

2018-04-16 Thread Boris Feld
# 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

2018-04-16 Thread Boris Feld
# 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

2018-04-16 Thread Anton Shestakov
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

2018-04-16 Thread Mercurial Commits
45 new changesets in mercurial:

https://www.mercurial-scm.org/repo/hg/rev/aacfca6f9767
changeset:   37498:aacfca6f9767
user:Joerg Sonnenberger 
date: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: