narrow: send specs as bundle2 data instead of param (issue5952) (issue6019) stable
authorPulkit Goyal <pulkit@yandex-team.ru>
Wed, 17 Apr 2019 15:06:41 +0300
branchstable
changeset 42209 280f7a095df8
parent 42204 723ed4402896
child 42215 07e479ef7c96
narrow: send specs as bundle2 data instead of param (issue5952) (issue6019) Before this patch, when ACL is involved, narrowspecs are send as bundle2 parameter for narrow:spec bundle2 part. The limitation of bundle2 parts are they cannot send data larger than 255 bytes. Includes and excludes in narrow are not limited by size and they can grow over 255 bytes. This patch introduces a new mandatory bundle2 part and send narrowspecs as data of that. The new bundle2 part is introduced to keep things cleaner and easy to distinguish related to backward compatibility. The part is mandatory because without server's narrowspec, the local ACL narrow repo won't work. This patch makes clients compatible with servers which have older versions. However I left a comment that we should drop the other bundle2 part soon as that's broken and people should not rely on that. I named the new bundle2 part 'Narrow:responsespec' because: 1) Capital 'N' to make it mandatory 2) 'Narrow:spec' cannot be used because bundle2 enforces that there should not be two different parts which resolve to same name when lowercased. 3) reponsespec clears that they are specs which are send as reponse by the server While I was here, I renamed `narrowhgacl` section to `narrowacl` as suggested by idlsoft@ and martinvonz@. Differential Revision: https://phab.mercurial-scm.org/D6310
hgext/narrow/narrowbundle2.py
mercurial/exchange.py
tests/test-narrow-acl.t
--- a/hgext/narrow/narrowbundle2.py	Fri Apr 26 23:52:49 2019 -0400
+++ b/hgext/narrow/narrowbundle2.py	Wed Apr 17 15:06:41 2019 +0300
@@ -31,8 +31,9 @@
     stringutil,
 )
 
-_NARROWACL_SECTION = 'narrowhgacl'
+_NARROWACL_SECTION = 'narrowacl'
 _CHANGESPECPART = 'narrow:changespec'
+_RESSPECS = 'narrow:responsespec'
 _SPECPART = 'narrow:spec'
 _SPECPART_INCLUDE = 'include'
 _SPECPART_EXCLUDE = 'exclude'
@@ -142,6 +143,10 @@
 
 @bundle2.parthandler(_SPECPART, (_SPECPART_INCLUDE, _SPECPART_EXCLUDE))
 def _handlechangespec_2(op, inpart):
+    # XXX: This bundle2 handling is buggy and should be removed after hg5.2 is
+    # released. New servers will send a mandatory bundle2 part named
+    # 'Narrowspec' and will send specs as data instead of params.
+    # Refer to issue5952 and 6019
     includepats = set(inpart.params.get(_SPECPART_INCLUDE, '').splitlines())
     excludepats = set(inpart.params.get(_SPECPART_EXCLUDE, '').splitlines())
     narrowspec.validatepatterns(includepats)
@@ -153,6 +158,21 @@
     op.repo.setnarrowpats(includepats, excludepats)
     narrowspec.copytoworkingcopy(op.repo)
 
+@bundle2.parthandler(_RESSPECS)
+def _handlenarrowspecs(op, inpart):
+    data = inpart.read()
+    inc, exc = data.split('\0')
+    includepats = set(inc.splitlines())
+    excludepats = set(exc.splitlines())
+    narrowspec.validatepatterns(includepats)
+    narrowspec.validatepatterns(excludepats)
+
+    if repository.NARROW_REQUIREMENT not in op.repo.requirements:
+        op.repo.requirements.add(repository.NARROW_REQUIREMENT)
+        op.repo._writerequirements()
+    op.repo.setnarrowpats(includepats, excludepats)
+    narrowspec.copytoworkingcopy(op.repo)
+
 @bundle2.parthandler(_CHANGESPECPART)
 def _handlechangespec(op, inpart):
     repo = op.repo
--- a/mercurial/exchange.py	Fri Apr 26 23:52:49 2019 -0400
+++ b/mercurial/exchange.py	Wed Apr 17 15:06:41 2019 +0300
@@ -49,7 +49,7 @@
 urlerr = util.urlerr
 urlreq = util.urlreq
 
-_NARROWACL_SECTION = 'narrowhgacl'
+_NARROWACL_SECTION = 'narrowacl'
 
 # Maps bundle version human names to changegroup versions.
 _bundlespeccgversions = {'v1': '01',
@@ -2213,13 +2213,10 @@
 
     if (kwargs.get(r'narrow', False) and kwargs.get(r'narrow_acl', False)
         and (include or exclude)):
-        narrowspecpart = bundler.newpart('narrow:spec')
-        if include:
-            narrowspecpart.addparam(
-                'include', '\n'.join(include), mandatory=True)
-        if exclude:
-            narrowspecpart.addparam(
-                'exclude', '\n'.join(exclude), mandatory=True)
+        # this is mandatory because otherwise ACL clients won't work
+        narrowspecpart = bundler.newpart('Narrow:responsespec')
+        narrowspecpart.data = '%s\0%s' % ('\n'.join(include),
+                                           '\n'.join(exclude))
 
 @getbundle2partsgenerator('bookmarks')
 def _getbundlebookmarkpart(bundler, repo, source, bundlecaps=None,
--- a/tests/test-narrow-acl.t	Fri Apr 26 23:52:49 2019 -0400
+++ b/tests/test-narrow-acl.t	Wed Apr 17 15:06:41 2019 +0300
@@ -10,7 +10,7 @@
   >   hg commit -m "Add $x"
   > done
   $ cat >> .hg/hgrc << EOF
-  > [narrowhgacl]
+  > [narrowacl]
   > default.includes=f1 f2
   > EOF
   $ hg serve -a localhost -p $HGPORT1 -d --pid-file=hg.pid