##// END OF EJS Templates
widening: remove always-true condition in widening code...
Martin von Zweigbergk -
r43538:c5adf480 default
parent child Browse files
Show More
@@ -1,386 +1,385 b''
1 # narrowbundle2.py - bundle2 extensions for narrow repository support
1 # narrowbundle2.py - bundle2 extensions for narrow repository support
2 #
2 #
3 # Copyright 2017 Google, Inc.
3 # Copyright 2017 Google, Inc.
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 import errno
10 import errno
11 import struct
11 import struct
12
12
13 from mercurial.i18n import _
13 from mercurial.i18n import _
14 from mercurial.node import nullid
14 from mercurial.node import nullid
15 from mercurial import (
15 from mercurial import (
16 bundle2,
16 bundle2,
17 changegroup,
17 changegroup,
18 error,
18 error,
19 exchange,
19 exchange,
20 localrepo,
20 localrepo,
21 narrowspec,
21 narrowspec,
22 repair,
22 repair,
23 util,
23 util,
24 wireprototypes,
24 wireprototypes,
25 )
25 )
26 from mercurial.interfaces import repository
26 from mercurial.interfaces import repository
27 from mercurial.utils import stringutil
27 from mercurial.utils import stringutil
28
28
29 _NARROWACL_SECTION = b'narrowacl'
29 _NARROWACL_SECTION = b'narrowacl'
30 _CHANGESPECPART = b'narrow:changespec'
30 _CHANGESPECPART = b'narrow:changespec'
31 _RESSPECS = b'narrow:responsespec'
31 _RESSPECS = b'narrow:responsespec'
32 _SPECPART = b'narrow:spec'
32 _SPECPART = b'narrow:spec'
33 _SPECPART_INCLUDE = b'include'
33 _SPECPART_INCLUDE = b'include'
34 _SPECPART_EXCLUDE = b'exclude'
34 _SPECPART_EXCLUDE = b'exclude'
35 _KILLNODESIGNAL = b'KILL'
35 _KILLNODESIGNAL = b'KILL'
36 _DONESIGNAL = b'DONE'
36 _DONESIGNAL = b'DONE'
37 _ELIDEDCSHEADER = b'>20s20s20sl' # cset id, p1, p2, len(text)
37 _ELIDEDCSHEADER = b'>20s20s20sl' # cset id, p1, p2, len(text)
38 _ELIDEDMFHEADER = b'>20s20s20s20sl' # manifest id, p1, p2, link id, len(text)
38 _ELIDEDMFHEADER = b'>20s20s20s20sl' # manifest id, p1, p2, link id, len(text)
39 _CSHEADERSIZE = struct.calcsize(_ELIDEDCSHEADER)
39 _CSHEADERSIZE = struct.calcsize(_ELIDEDCSHEADER)
40 _MFHEADERSIZE = struct.calcsize(_ELIDEDMFHEADER)
40 _MFHEADERSIZE = struct.calcsize(_ELIDEDMFHEADER)
41
41
42 # Serve a changegroup for a client with a narrow clone.
42 # Serve a changegroup for a client with a narrow clone.
43 def getbundlechangegrouppart_narrow(
43 def getbundlechangegrouppart_narrow(
44 bundler,
44 bundler,
45 repo,
45 repo,
46 source,
46 source,
47 bundlecaps=None,
47 bundlecaps=None,
48 b2caps=None,
48 b2caps=None,
49 heads=None,
49 heads=None,
50 common=None,
50 common=None,
51 **kwargs
51 **kwargs
52 ):
52 ):
53 assert repo.ui.configbool(b'experimental', b'narrowservebrokenellipses')
53 assert repo.ui.configbool(b'experimental', b'narrowservebrokenellipses')
54
54
55 cgversions = b2caps.get(b'changegroup')
55 cgversions = b2caps.get(b'changegroup')
56 cgversions = [
56 cgversions = [
57 v
57 v
58 for v in cgversions
58 for v in cgversions
59 if v in changegroup.supportedoutgoingversions(repo)
59 if v in changegroup.supportedoutgoingversions(repo)
60 ]
60 ]
61 if not cgversions:
61 if not cgversions:
62 raise ValueError(_(b'no common changegroup version'))
62 raise ValueError(_(b'no common changegroup version'))
63 version = max(cgversions)
63 version = max(cgversions)
64
64
65 include = sorted(filter(bool, kwargs.get(r'includepats', [])))
65 include = sorted(filter(bool, kwargs.get(r'includepats', [])))
66 exclude = sorted(filter(bool, kwargs.get(r'excludepats', [])))
66 exclude = sorted(filter(bool, kwargs.get(r'excludepats', [])))
67 generateellipsesbundle2(
67 generateellipsesbundle2(
68 bundler,
68 bundler,
69 repo,
69 repo,
70 include,
70 include,
71 exclude,
71 exclude,
72 version,
72 version,
73 common,
73 common,
74 heads,
74 heads,
75 kwargs.get(r'depth', None),
75 kwargs.get(r'depth', None),
76 )
76 )
77
77
78
78
79 def generateellipsesbundle2(
79 def generateellipsesbundle2(
80 bundler, repo, include, exclude, version, common, heads, depth,
80 bundler, repo, include, exclude, version, common, heads, depth,
81 ):
81 ):
82 match = narrowspec.match(repo.root, include=include, exclude=exclude)
82 match = narrowspec.match(repo.root, include=include, exclude=exclude)
83 if depth is not None:
83 if depth is not None:
84 depth = int(depth)
84 depth = int(depth)
85 if depth < 1:
85 if depth < 1:
86 raise error.Abort(_(b'depth must be positive, got %d') % depth)
86 raise error.Abort(_(b'depth must be positive, got %d') % depth)
87
87
88 heads = set(heads or repo.heads())
88 heads = set(heads or repo.heads())
89 common = set(common or [nullid])
89 common = set(common or [nullid])
90
90
91 visitnodes, relevant_nodes, ellipsisroots = exchange._computeellipsis(
91 visitnodes, relevant_nodes, ellipsisroots = exchange._computeellipsis(
92 repo, common, heads, set(), match, depth=depth
92 repo, common, heads, set(), match, depth=depth
93 )
93 )
94
94
95 repo.ui.debug(b'Found %d relevant revs\n' % len(relevant_nodes))
95 repo.ui.debug(b'Found %d relevant revs\n' % len(relevant_nodes))
96 if visitnodes:
96 if visitnodes:
97 packer = changegroup.getbundler(
97 packer = changegroup.getbundler(
98 version,
98 version,
99 repo,
99 repo,
100 matcher=match,
100 matcher=match,
101 ellipses=True,
101 ellipses=True,
102 shallow=depth is not None,
102 shallow=depth is not None,
103 ellipsisroots=ellipsisroots,
103 ellipsisroots=ellipsisroots,
104 fullnodes=relevant_nodes,
104 fullnodes=relevant_nodes,
105 )
105 )
106 cgdata = packer.generate(common, visitnodes, False, b'narrow_widen')
106 cgdata = packer.generate(common, visitnodes, False, b'narrow_widen')
107
107
108 part = bundler.newpart(b'changegroup', data=cgdata)
108 part = bundler.newpart(b'changegroup', data=cgdata)
109 part.addparam(b'version', version)
109 part.addparam(b'version', version)
110 if b'treemanifest' in repo.requirements:
110 if b'treemanifest' in repo.requirements:
111 part.addparam(b'treemanifest', b'1')
111 part.addparam(b'treemanifest', b'1')
112
112
113
113
114 def generate_ellipses_bundle2_for_widening(
114 def generate_ellipses_bundle2_for_widening(
115 bundler,
115 bundler,
116 repo,
116 repo,
117 oldinclude,
117 oldinclude,
118 oldexclude,
118 oldexclude,
119 newinclude,
119 newinclude,
120 newexclude,
120 newexclude,
121 version,
121 version,
122 common,
122 common,
123 heads,
123 heads,
124 known,
124 known,
125 depth,
125 depth,
126 ):
126 ):
127 newmatch = narrowspec.match(
127 newmatch = narrowspec.match(
128 repo.root, include=newinclude, exclude=newexclude
128 repo.root, include=newinclude, exclude=newexclude
129 )
129 )
130 if depth is not None:
130 if depth is not None:
131 depth = int(depth)
131 depth = int(depth)
132 if depth < 1:
132 if depth < 1:
133 raise error.Abort(_(b'depth must be positive, got %d') % depth)
133 raise error.Abort(_(b'depth must be positive, got %d') % depth)
134
134
135 heads = set(heads or repo.heads())
135 heads = set(heads or repo.heads())
136 common = set(common or [nullid])
136 common = set(common or [nullid])
137 if known and (oldinclude != newinclude or oldexclude != newexclude):
137 # Steps:
138 # Steps:
138 # 1. Send kill for "$known & ::common"
139 # 1. Send kill for "$known & ::common"
139 #
140 #
140 # 2. Send changegroup for ::common
141 # 2. Send changegroup for ::common
141 #
142 #
142 # 3. Proceed.
143 # 3. Proceed.
143 #
144 #
144 # In the future, we can send kills for only the specific
145 # In the future, we can send kills for only the specific
145 # nodes we know should go away or change shape, and then
146 # nodes we know should go away or change shape, and then
146 # send a data stream that tells the client something like this:
147 # send a data stream that tells the client something like this:
147 #
148 #
148 # a) apply this changegroup
149 # a) apply this changegroup
149 # b) apply nodes XXX, YYY, ZZZ that you already have
150 # b) apply nodes XXX, YYY, ZZZ that you already have
150 # c) goto a
151 # c) goto a
151 #
152 #
152 # until they've built up the full new state.
153 # until they've built up the full new state.
153 # Convert to revnums and intersect with "common". The client should
154 # Convert to revnums and intersect with "common". The client should
154 # have made it a subset of "common" already, but let's be safe.
155 # have made it a subset of "common" already, but let's be safe.
155 known = set(repo.revs(b"%ln & ::%ln", known, common))
156 known = set(repo.revs(b"%ln & ::%ln", known, common))
156 # TODO: we could send only roots() of this set, and the
157 # TODO: we could send only roots() of this set, and the
157 # list of nodes in common, and the client could work out
158 # list of nodes in common, and the client could work out
158 # what to strip, instead of us explicitly sending every
159 # what to strip, instead of us explicitly sending every
159 # single node.
160 # single node.
160 deadrevs = known
161 deadrevs = known
162
161
163 def genkills():
162 def genkills():
164 for r in deadrevs:
163 for r in deadrevs:
165 yield _KILLNODESIGNAL
164 yield _KILLNODESIGNAL
166 yield repo.changelog.node(r)
165 yield repo.changelog.node(r)
167 yield _DONESIGNAL
166 yield _DONESIGNAL
168
167
169 bundler.newpart(_CHANGESPECPART, data=genkills())
168 bundler.newpart(_CHANGESPECPART, data=genkills())
170 newvisit, newfull, newellipsis = exchange._computeellipsis(
169 newvisit, newfull, newellipsis = exchange._computeellipsis(
171 repo, set(), common, known, newmatch
170 repo, set(), common, known, newmatch
171 )
172 if newvisit:
173 packer = changegroup.getbundler(
174 version,
175 repo,
176 matcher=newmatch,
177 ellipses=True,
178 shallow=depth is not None,
179 ellipsisroots=newellipsis,
180 fullnodes=newfull,
172 )
181 )
173 if newvisit:
182 cgdata = packer.generate(common, newvisit, False, b'narrow_widen')
174 packer = changegroup.getbundler(
175 version,
176 repo,
177 matcher=newmatch,
178 ellipses=True,
179 shallow=depth is not None,
180 ellipsisroots=newellipsis,
181 fullnodes=newfull,
182 )
183 cgdata = packer.generate(common, newvisit, False, b'narrow_widen')
184
183
185 part = bundler.newpart(b'changegroup', data=cgdata)
184 part = bundler.newpart(b'changegroup', data=cgdata)
186 part.addparam(b'version', version)
185 part.addparam(b'version', version)
187 if b'treemanifest' in repo.requirements:
186 if b'treemanifest' in repo.requirements:
188 part.addparam(b'treemanifest', b'1')
187 part.addparam(b'treemanifest', b'1')
189
188
190 visitnodes, relevant_nodes, ellipsisroots = exchange._computeellipsis(
189 visitnodes, relevant_nodes, ellipsisroots = exchange._computeellipsis(
191 repo, common, heads, set(), newmatch, depth=depth
190 repo, common, heads, set(), newmatch, depth=depth
192 )
191 )
193
192
194 repo.ui.debug(b'Found %d relevant revs\n' % len(relevant_nodes))
193 repo.ui.debug(b'Found %d relevant revs\n' % len(relevant_nodes))
195 if visitnodes:
194 if visitnodes:
196 packer = changegroup.getbundler(
195 packer = changegroup.getbundler(
197 version,
196 version,
198 repo,
197 repo,
199 matcher=newmatch,
198 matcher=newmatch,
200 ellipses=True,
199 ellipses=True,
201 shallow=depth is not None,
200 shallow=depth is not None,
202 ellipsisroots=ellipsisroots,
201 ellipsisroots=ellipsisroots,
203 fullnodes=relevant_nodes,
202 fullnodes=relevant_nodes,
204 )
203 )
205 cgdata = packer.generate(common, visitnodes, False, b'narrow_widen')
204 cgdata = packer.generate(common, visitnodes, False, b'narrow_widen')
206
205
207 part = bundler.newpart(b'changegroup', data=cgdata)
206 part = bundler.newpart(b'changegroup', data=cgdata)
208 part.addparam(b'version', version)
207 part.addparam(b'version', version)
209 if b'treemanifest' in repo.requirements:
208 if b'treemanifest' in repo.requirements:
210 part.addparam(b'treemanifest', b'1')
209 part.addparam(b'treemanifest', b'1')
211
210
212
211
213 @bundle2.parthandler(_SPECPART, (_SPECPART_INCLUDE, _SPECPART_EXCLUDE))
212 @bundle2.parthandler(_SPECPART, (_SPECPART_INCLUDE, _SPECPART_EXCLUDE))
214 def _handlechangespec_2(op, inpart):
213 def _handlechangespec_2(op, inpart):
215 # XXX: This bundle2 handling is buggy and should be removed after hg5.2 is
214 # XXX: This bundle2 handling is buggy and should be removed after hg5.2 is
216 # released. New servers will send a mandatory bundle2 part named
215 # released. New servers will send a mandatory bundle2 part named
217 # 'Narrowspec' and will send specs as data instead of params.
216 # 'Narrowspec' and will send specs as data instead of params.
218 # Refer to issue5952 and 6019
217 # Refer to issue5952 and 6019
219 includepats = set(inpart.params.get(_SPECPART_INCLUDE, b'').splitlines())
218 includepats = set(inpart.params.get(_SPECPART_INCLUDE, b'').splitlines())
220 excludepats = set(inpart.params.get(_SPECPART_EXCLUDE, b'').splitlines())
219 excludepats = set(inpart.params.get(_SPECPART_EXCLUDE, b'').splitlines())
221 narrowspec.validatepatterns(includepats)
220 narrowspec.validatepatterns(includepats)
222 narrowspec.validatepatterns(excludepats)
221 narrowspec.validatepatterns(excludepats)
223
222
224 if not repository.NARROW_REQUIREMENT in op.repo.requirements:
223 if not repository.NARROW_REQUIREMENT in op.repo.requirements:
225 op.repo.requirements.add(repository.NARROW_REQUIREMENT)
224 op.repo.requirements.add(repository.NARROW_REQUIREMENT)
226 op.repo._writerequirements()
225 op.repo._writerequirements()
227 op.repo.setnarrowpats(includepats, excludepats)
226 op.repo.setnarrowpats(includepats, excludepats)
228 narrowspec.copytoworkingcopy(op.repo)
227 narrowspec.copytoworkingcopy(op.repo)
229
228
230
229
231 @bundle2.parthandler(_RESSPECS)
230 @bundle2.parthandler(_RESSPECS)
232 def _handlenarrowspecs(op, inpart):
231 def _handlenarrowspecs(op, inpart):
233 data = inpart.read()
232 data = inpart.read()
234 inc, exc = data.split(b'\0')
233 inc, exc = data.split(b'\0')
235 includepats = set(inc.splitlines())
234 includepats = set(inc.splitlines())
236 excludepats = set(exc.splitlines())
235 excludepats = set(exc.splitlines())
237 narrowspec.validatepatterns(includepats)
236 narrowspec.validatepatterns(includepats)
238 narrowspec.validatepatterns(excludepats)
237 narrowspec.validatepatterns(excludepats)
239
238
240 if repository.NARROW_REQUIREMENT not in op.repo.requirements:
239 if repository.NARROW_REQUIREMENT not in op.repo.requirements:
241 op.repo.requirements.add(repository.NARROW_REQUIREMENT)
240 op.repo.requirements.add(repository.NARROW_REQUIREMENT)
242 op.repo._writerequirements()
241 op.repo._writerequirements()
243 op.repo.setnarrowpats(includepats, excludepats)
242 op.repo.setnarrowpats(includepats, excludepats)
244 narrowspec.copytoworkingcopy(op.repo)
243 narrowspec.copytoworkingcopy(op.repo)
245
244
246
245
247 @bundle2.parthandler(_CHANGESPECPART)
246 @bundle2.parthandler(_CHANGESPECPART)
248 def _handlechangespec(op, inpart):
247 def _handlechangespec(op, inpart):
249 repo = op.repo
248 repo = op.repo
250 cl = repo.changelog
249 cl = repo.changelog
251
250
252 # changesets which need to be stripped entirely. either they're no longer
251 # changesets which need to be stripped entirely. either they're no longer
253 # needed in the new narrow spec, or the server is sending a replacement
252 # needed in the new narrow spec, or the server is sending a replacement
254 # in the changegroup part.
253 # in the changegroup part.
255 clkills = set()
254 clkills = set()
256
255
257 # A changespec part contains all the updates to ellipsis nodes
256 # A changespec part contains all the updates to ellipsis nodes
258 # that will happen as a result of widening or narrowing a
257 # that will happen as a result of widening or narrowing a
259 # repo. All the changes that this block encounters are ellipsis
258 # repo. All the changes that this block encounters are ellipsis
260 # nodes or flags to kill an existing ellipsis.
259 # nodes or flags to kill an existing ellipsis.
261 chunksignal = changegroup.readexactly(inpart, 4)
260 chunksignal = changegroup.readexactly(inpart, 4)
262 while chunksignal != _DONESIGNAL:
261 while chunksignal != _DONESIGNAL:
263 if chunksignal == _KILLNODESIGNAL:
262 if chunksignal == _KILLNODESIGNAL:
264 # a node used to be an ellipsis but isn't anymore
263 # a node used to be an ellipsis but isn't anymore
265 ck = changegroup.readexactly(inpart, 20)
264 ck = changegroup.readexactly(inpart, 20)
266 if cl.hasnode(ck):
265 if cl.hasnode(ck):
267 clkills.add(ck)
266 clkills.add(ck)
268 else:
267 else:
269 raise error.Abort(
268 raise error.Abort(
270 _(b'unexpected changespec node chunk type: %s') % chunksignal
269 _(b'unexpected changespec node chunk type: %s') % chunksignal
271 )
270 )
272 chunksignal = changegroup.readexactly(inpart, 4)
271 chunksignal = changegroup.readexactly(inpart, 4)
273
272
274 if clkills:
273 if clkills:
275 # preserve bookmarks that repair.strip() would otherwise strip
274 # preserve bookmarks that repair.strip() would otherwise strip
276 op._bookmarksbackup = repo._bookmarks
275 op._bookmarksbackup = repo._bookmarks
277
276
278 class dummybmstore(dict):
277 class dummybmstore(dict):
279 def applychanges(self, repo, tr, changes):
278 def applychanges(self, repo, tr, changes):
280 pass
279 pass
281
280
282 localrepo.localrepository._bookmarks.set(repo, dummybmstore())
281 localrepo.localrepository._bookmarks.set(repo, dummybmstore())
283 chgrpfile = repair.strip(
282 chgrpfile = repair.strip(
284 op.ui, repo, list(clkills), backup=True, topic=b'widen'
283 op.ui, repo, list(clkills), backup=True, topic=b'widen'
285 )
284 )
286 if chgrpfile:
285 if chgrpfile:
287 op._widen_uninterr = repo.ui.uninterruptible()
286 op._widen_uninterr = repo.ui.uninterruptible()
288 op._widen_uninterr.__enter__()
287 op._widen_uninterr.__enter__()
289 # presence of _widen_bundle attribute activates widen handler later
288 # presence of _widen_bundle attribute activates widen handler later
290 op._widen_bundle = chgrpfile
289 op._widen_bundle = chgrpfile
291 # Set the new narrowspec if we're widening. The setnewnarrowpats() method
290 # Set the new narrowspec if we're widening. The setnewnarrowpats() method
292 # will currently always be there when using the core+narrowhg server, but
291 # will currently always be there when using the core+narrowhg server, but
293 # other servers may include a changespec part even when not widening (e.g.
292 # other servers may include a changespec part even when not widening (e.g.
294 # because we're deepening a shallow repo).
293 # because we're deepening a shallow repo).
295 if util.safehasattr(repo, 'setnewnarrowpats'):
294 if util.safehasattr(repo, 'setnewnarrowpats'):
296 repo.setnewnarrowpats()
295 repo.setnewnarrowpats()
297
296
298
297
299 def handlechangegroup_widen(op, inpart):
298 def handlechangegroup_widen(op, inpart):
300 """Changegroup exchange handler which restores temporarily-stripped nodes"""
299 """Changegroup exchange handler which restores temporarily-stripped nodes"""
301 # We saved a bundle with stripped node data we must now restore.
300 # We saved a bundle with stripped node data we must now restore.
302 # This approach is based on mercurial/repair.py@6ee26a53c111.
301 # This approach is based on mercurial/repair.py@6ee26a53c111.
303 repo = op.repo
302 repo = op.repo
304 ui = op.ui
303 ui = op.ui
305
304
306 chgrpfile = op._widen_bundle
305 chgrpfile = op._widen_bundle
307 del op._widen_bundle
306 del op._widen_bundle
308 vfs = repo.vfs
307 vfs = repo.vfs
309
308
310 ui.note(_(b"adding branch\n"))
309 ui.note(_(b"adding branch\n"))
311 f = vfs.open(chgrpfile, b"rb")
310 f = vfs.open(chgrpfile, b"rb")
312 try:
311 try:
313 gen = exchange.readbundle(ui, f, chgrpfile, vfs)
312 gen = exchange.readbundle(ui, f, chgrpfile, vfs)
314 # silence internal shuffling chatter
313 # silence internal shuffling chatter
315 override = {(b'ui', b'quiet'): True}
314 override = {(b'ui', b'quiet'): True}
316 if ui.verbose:
315 if ui.verbose:
317 override = {}
316 override = {}
318 with ui.configoverride(override):
317 with ui.configoverride(override):
319 if isinstance(gen, bundle2.unbundle20):
318 if isinstance(gen, bundle2.unbundle20):
320 with repo.transaction(b'strip') as tr:
319 with repo.transaction(b'strip') as tr:
321 bundle2.processbundle(repo, gen, lambda: tr)
320 bundle2.processbundle(repo, gen, lambda: tr)
322 else:
321 else:
323 gen.apply(
322 gen.apply(
324 repo, b'strip', b'bundle:' + vfs.join(chgrpfile), True
323 repo, b'strip', b'bundle:' + vfs.join(chgrpfile), True
325 )
324 )
326 finally:
325 finally:
327 f.close()
326 f.close()
328
327
329 # remove undo files
328 # remove undo files
330 for undovfs, undofile in repo.undofiles():
329 for undovfs, undofile in repo.undofiles():
331 try:
330 try:
332 undovfs.unlink(undofile)
331 undovfs.unlink(undofile)
333 except OSError as e:
332 except OSError as e:
334 if e.errno != errno.ENOENT:
333 if e.errno != errno.ENOENT:
335 ui.warn(
334 ui.warn(
336 _(b'error removing %s: %s\n')
335 _(b'error removing %s: %s\n')
337 % (undovfs.join(undofile), stringutil.forcebytestr(e))
336 % (undovfs.join(undofile), stringutil.forcebytestr(e))
338 )
337 )
339
338
340 # Remove partial backup only if there were no exceptions
339 # Remove partial backup only if there were no exceptions
341 op._widen_uninterr.__exit__(None, None, None)
340 op._widen_uninterr.__exit__(None, None, None)
342 vfs.unlink(chgrpfile)
341 vfs.unlink(chgrpfile)
343
342
344
343
345 def setup():
344 def setup():
346 """Enable narrow repo support in bundle2-related extension points."""
345 """Enable narrow repo support in bundle2-related extension points."""
347 getbundleargs = wireprototypes.GETBUNDLE_ARGUMENTS
346 getbundleargs = wireprototypes.GETBUNDLE_ARGUMENTS
348
347
349 getbundleargs[b'narrow'] = b'boolean'
348 getbundleargs[b'narrow'] = b'boolean'
350 getbundleargs[b'depth'] = b'plain'
349 getbundleargs[b'depth'] = b'plain'
351 getbundleargs[b'oldincludepats'] = b'csv'
350 getbundleargs[b'oldincludepats'] = b'csv'
352 getbundleargs[b'oldexcludepats'] = b'csv'
351 getbundleargs[b'oldexcludepats'] = b'csv'
353 getbundleargs[b'known'] = b'csv'
352 getbundleargs[b'known'] = b'csv'
354
353
355 # Extend changegroup serving to handle requests from narrow clients.
354 # Extend changegroup serving to handle requests from narrow clients.
356 origcgfn = exchange.getbundle2partsmapping[b'changegroup']
355 origcgfn = exchange.getbundle2partsmapping[b'changegroup']
357
356
358 def wrappedcgfn(*args, **kwargs):
357 def wrappedcgfn(*args, **kwargs):
359 repo = args[1]
358 repo = args[1]
360 if repo.ui.has_section(_NARROWACL_SECTION):
359 if repo.ui.has_section(_NARROWACL_SECTION):
361 kwargs = exchange.applynarrowacl(repo, kwargs)
360 kwargs = exchange.applynarrowacl(repo, kwargs)
362
361
363 if kwargs.get(r'narrow', False) and repo.ui.configbool(
362 if kwargs.get(r'narrow', False) and repo.ui.configbool(
364 b'experimental', b'narrowservebrokenellipses'
363 b'experimental', b'narrowservebrokenellipses'
365 ):
364 ):
366 getbundlechangegrouppart_narrow(*args, **kwargs)
365 getbundlechangegrouppart_narrow(*args, **kwargs)
367 else:
366 else:
368 origcgfn(*args, **kwargs)
367 origcgfn(*args, **kwargs)
369
368
370 exchange.getbundle2partsmapping[b'changegroup'] = wrappedcgfn
369 exchange.getbundle2partsmapping[b'changegroup'] = wrappedcgfn
371
370
372 # Extend changegroup receiver so client can fixup after widen requests.
371 # Extend changegroup receiver so client can fixup after widen requests.
373 origcghandler = bundle2.parthandlermapping[b'changegroup']
372 origcghandler = bundle2.parthandlermapping[b'changegroup']
374
373
375 def wrappedcghandler(op, inpart):
374 def wrappedcghandler(op, inpart):
376 origcghandler(op, inpart)
375 origcghandler(op, inpart)
377 if util.safehasattr(op, '_widen_bundle'):
376 if util.safehasattr(op, '_widen_bundle'):
378 handlechangegroup_widen(op, inpart)
377 handlechangegroup_widen(op, inpart)
379 if util.safehasattr(op, '_bookmarksbackup'):
378 if util.safehasattr(op, '_bookmarksbackup'):
380 localrepo.localrepository._bookmarks.set(
379 localrepo.localrepository._bookmarks.set(
381 op.repo, op._bookmarksbackup
380 op.repo, op._bookmarksbackup
382 )
381 )
383 del op._bookmarksbackup
382 del op._bookmarksbackup
384
383
385 wrappedcghandler.params = origcghandler.params
384 wrappedcghandler.params = origcghandler.params
386 bundle2.parthandlermapping[b'changegroup'] = wrappedcghandler
385 bundle2.parthandlermapping[b'changegroup'] = wrappedcghandler
General Comments 0
You need to be logged in to leave comments. Login now