##// END OF EJS Templates
exchange: stop advertising rev-branch-cache bundle capability...
Joerg Sonnenberger -
r47378:7015b023 default
parent child Browse files
Show More

The requested changes are too big and content was truncated. Show full diff

@@ -1,2561 +1,2563 b''
1 # bundle2.py - generic container format to transmit arbitrary data.
1 # bundle2.py - generic container format to transmit arbitrary data.
2 #
2 #
3 # Copyright 2013 Facebook, Inc.
3 # Copyright 2013 Facebook, 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 """Handling of the new bundle2 format
7 """Handling of the new bundle2 format
8
8
9 The goal of bundle2 is to act as an atomically packet to transmit a set of
9 The goal of bundle2 is to act as an atomically packet to transmit a set of
10 payloads in an application agnostic way. It consist in a sequence of "parts"
10 payloads in an application agnostic way. It consist in a sequence of "parts"
11 that will be handed to and processed by the application layer.
11 that will be handed to and processed by the application layer.
12
12
13
13
14 General format architecture
14 General format architecture
15 ===========================
15 ===========================
16
16
17 The format is architectured as follow
17 The format is architectured as follow
18
18
19 - magic string
19 - magic string
20 - stream level parameters
20 - stream level parameters
21 - payload parts (any number)
21 - payload parts (any number)
22 - end of stream marker.
22 - end of stream marker.
23
23
24 the Binary format
24 the Binary format
25 ============================
25 ============================
26
26
27 All numbers are unsigned and big-endian.
27 All numbers are unsigned and big-endian.
28
28
29 stream level parameters
29 stream level parameters
30 ------------------------
30 ------------------------
31
31
32 Binary format is as follow
32 Binary format is as follow
33
33
34 :params size: int32
34 :params size: int32
35
35
36 The total number of Bytes used by the parameters
36 The total number of Bytes used by the parameters
37
37
38 :params value: arbitrary number of Bytes
38 :params value: arbitrary number of Bytes
39
39
40 A blob of `params size` containing the serialized version of all stream level
40 A blob of `params size` containing the serialized version of all stream level
41 parameters.
41 parameters.
42
42
43 The blob contains a space separated list of parameters. Parameters with value
43 The blob contains a space separated list of parameters. Parameters with value
44 are stored in the form `<name>=<value>`. Both name and value are urlquoted.
44 are stored in the form `<name>=<value>`. Both name and value are urlquoted.
45
45
46 Empty name are obviously forbidden.
46 Empty name are obviously forbidden.
47
47
48 Name MUST start with a letter. If this first letter is lower case, the
48 Name MUST start with a letter. If this first letter is lower case, the
49 parameter is advisory and can be safely ignored. However when the first
49 parameter is advisory and can be safely ignored. However when the first
50 letter is capital, the parameter is mandatory and the bundling process MUST
50 letter is capital, the parameter is mandatory and the bundling process MUST
51 stop if he is not able to proceed it.
51 stop if he is not able to proceed it.
52
52
53 Stream parameters use a simple textual format for two main reasons:
53 Stream parameters use a simple textual format for two main reasons:
54
54
55 - Stream level parameters should remain simple and we want to discourage any
55 - Stream level parameters should remain simple and we want to discourage any
56 crazy usage.
56 crazy usage.
57 - Textual data allow easy human inspection of a bundle2 header in case of
57 - Textual data allow easy human inspection of a bundle2 header in case of
58 troubles.
58 troubles.
59
59
60 Any Applicative level options MUST go into a bundle2 part instead.
60 Any Applicative level options MUST go into a bundle2 part instead.
61
61
62 Payload part
62 Payload part
63 ------------------------
63 ------------------------
64
64
65 Binary format is as follow
65 Binary format is as follow
66
66
67 :header size: int32
67 :header size: int32
68
68
69 The total number of Bytes used by the part header. When the header is empty
69 The total number of Bytes used by the part header. When the header is empty
70 (size = 0) this is interpreted as the end of stream marker.
70 (size = 0) this is interpreted as the end of stream marker.
71
71
72 :header:
72 :header:
73
73
74 The header defines how to interpret the part. It contains two piece of
74 The header defines how to interpret the part. It contains two piece of
75 data: the part type, and the part parameters.
75 data: the part type, and the part parameters.
76
76
77 The part type is used to route an application level handler, that can
77 The part type is used to route an application level handler, that can
78 interpret payload.
78 interpret payload.
79
79
80 Part parameters are passed to the application level handler. They are
80 Part parameters are passed to the application level handler. They are
81 meant to convey information that will help the application level object to
81 meant to convey information that will help the application level object to
82 interpret the part payload.
82 interpret the part payload.
83
83
84 The binary format of the header is has follow
84 The binary format of the header is has follow
85
85
86 :typesize: (one byte)
86 :typesize: (one byte)
87
87
88 :parttype: alphanumerical part name (restricted to [a-zA-Z0-9_:-]*)
88 :parttype: alphanumerical part name (restricted to [a-zA-Z0-9_:-]*)
89
89
90 :partid: A 32bits integer (unique in the bundle) that can be used to refer
90 :partid: A 32bits integer (unique in the bundle) that can be used to refer
91 to this part.
91 to this part.
92
92
93 :parameters:
93 :parameters:
94
94
95 Part's parameter may have arbitrary content, the binary structure is::
95 Part's parameter may have arbitrary content, the binary structure is::
96
96
97 <mandatory-count><advisory-count><param-sizes><param-data>
97 <mandatory-count><advisory-count><param-sizes><param-data>
98
98
99 :mandatory-count: 1 byte, number of mandatory parameters
99 :mandatory-count: 1 byte, number of mandatory parameters
100
100
101 :advisory-count: 1 byte, number of advisory parameters
101 :advisory-count: 1 byte, number of advisory parameters
102
102
103 :param-sizes:
103 :param-sizes:
104
104
105 N couple of bytes, where N is the total number of parameters. Each
105 N couple of bytes, where N is the total number of parameters. Each
106 couple contains (<size-of-key>, <size-of-value) for one parameter.
106 couple contains (<size-of-key>, <size-of-value) for one parameter.
107
107
108 :param-data:
108 :param-data:
109
109
110 A blob of bytes from which each parameter key and value can be
110 A blob of bytes from which each parameter key and value can be
111 retrieved using the list of size couples stored in the previous
111 retrieved using the list of size couples stored in the previous
112 field.
112 field.
113
113
114 Mandatory parameters comes first, then the advisory ones.
114 Mandatory parameters comes first, then the advisory ones.
115
115
116 Each parameter's key MUST be unique within the part.
116 Each parameter's key MUST be unique within the part.
117
117
118 :payload:
118 :payload:
119
119
120 payload is a series of `<chunksize><chunkdata>`.
120 payload is a series of `<chunksize><chunkdata>`.
121
121
122 `chunksize` is an int32, `chunkdata` are plain bytes (as much as
122 `chunksize` is an int32, `chunkdata` are plain bytes (as much as
123 `chunksize` says)` The payload part is concluded by a zero size chunk.
123 `chunksize` says)` The payload part is concluded by a zero size chunk.
124
124
125 The current implementation always produces either zero or one chunk.
125 The current implementation always produces either zero or one chunk.
126 This is an implementation limitation that will ultimately be lifted.
126 This is an implementation limitation that will ultimately be lifted.
127
127
128 `chunksize` can be negative to trigger special case processing. No such
128 `chunksize` can be negative to trigger special case processing. No such
129 processing is in place yet.
129 processing is in place yet.
130
130
131 Bundle processing
131 Bundle processing
132 ============================
132 ============================
133
133
134 Each part is processed in order using a "part handler". Handler are registered
134 Each part is processed in order using a "part handler". Handler are registered
135 for a certain part type.
135 for a certain part type.
136
136
137 The matching of a part to its handler is case insensitive. The case of the
137 The matching of a part to its handler is case insensitive. The case of the
138 part type is used to know if a part is mandatory or advisory. If the Part type
138 part type is used to know if a part is mandatory or advisory. If the Part type
139 contains any uppercase char it is considered mandatory. When no handler is
139 contains any uppercase char it is considered mandatory. When no handler is
140 known for a Mandatory part, the process is aborted and an exception is raised.
140 known for a Mandatory part, the process is aborted and an exception is raised.
141 If the part is advisory and no handler is known, the part is ignored. When the
141 If the part is advisory and no handler is known, the part is ignored. When the
142 process is aborted, the full bundle is still read from the stream to keep the
142 process is aborted, the full bundle is still read from the stream to keep the
143 channel usable. But none of the part read from an abort are processed. In the
143 channel usable. But none of the part read from an abort are processed. In the
144 future, dropping the stream may become an option for channel we do not care to
144 future, dropping the stream may become an option for channel we do not care to
145 preserve.
145 preserve.
146 """
146 """
147
147
148 from __future__ import absolute_import, division
148 from __future__ import absolute_import, division
149
149
150 import collections
150 import collections
151 import errno
151 import errno
152 import os
152 import os
153 import re
153 import re
154 import string
154 import string
155 import struct
155 import struct
156 import sys
156 import sys
157
157
158 from .i18n import _
158 from .i18n import _
159 from .node import (
159 from .node import (
160 hex,
160 hex,
161 nullid,
161 nullid,
162 short,
162 short,
163 )
163 )
164 from . import (
164 from . import (
165 bookmarks,
165 bookmarks,
166 changegroup,
166 changegroup,
167 encoding,
167 encoding,
168 error,
168 error,
169 obsolete,
169 obsolete,
170 phases,
170 phases,
171 pushkey,
171 pushkey,
172 pycompat,
172 pycompat,
173 requirements,
173 requirements,
174 scmutil,
174 scmutil,
175 streamclone,
175 streamclone,
176 tags,
176 tags,
177 url,
177 url,
178 util,
178 util,
179 )
179 )
180 from .utils import stringutil
180 from .utils import stringutil
181
181
182 urlerr = util.urlerr
182 urlerr = util.urlerr
183 urlreq = util.urlreq
183 urlreq = util.urlreq
184
184
185 _pack = struct.pack
185 _pack = struct.pack
186 _unpack = struct.unpack
186 _unpack = struct.unpack
187
187
188 _fstreamparamsize = b'>i'
188 _fstreamparamsize = b'>i'
189 _fpartheadersize = b'>i'
189 _fpartheadersize = b'>i'
190 _fparttypesize = b'>B'
190 _fparttypesize = b'>B'
191 _fpartid = b'>I'
191 _fpartid = b'>I'
192 _fpayloadsize = b'>i'
192 _fpayloadsize = b'>i'
193 _fpartparamcount = b'>BB'
193 _fpartparamcount = b'>BB'
194
194
195 preferedchunksize = 32768
195 preferedchunksize = 32768
196
196
197 _parttypeforbidden = re.compile(b'[^a-zA-Z0-9_:-]')
197 _parttypeforbidden = re.compile(b'[^a-zA-Z0-9_:-]')
198
198
199
199
200 def outdebug(ui, message):
200 def outdebug(ui, message):
201 """debug regarding output stream (bundling)"""
201 """debug regarding output stream (bundling)"""
202 if ui.configbool(b'devel', b'bundle2.debug'):
202 if ui.configbool(b'devel', b'bundle2.debug'):
203 ui.debug(b'bundle2-output: %s\n' % message)
203 ui.debug(b'bundle2-output: %s\n' % message)
204
204
205
205
206 def indebug(ui, message):
206 def indebug(ui, message):
207 """debug on input stream (unbundling)"""
207 """debug on input stream (unbundling)"""
208 if ui.configbool(b'devel', b'bundle2.debug'):
208 if ui.configbool(b'devel', b'bundle2.debug'):
209 ui.debug(b'bundle2-input: %s\n' % message)
209 ui.debug(b'bundle2-input: %s\n' % message)
210
210
211
211
212 def validateparttype(parttype):
212 def validateparttype(parttype):
213 """raise ValueError if a parttype contains invalid character"""
213 """raise ValueError if a parttype contains invalid character"""
214 if _parttypeforbidden.search(parttype):
214 if _parttypeforbidden.search(parttype):
215 raise ValueError(parttype)
215 raise ValueError(parttype)
216
216
217
217
218 def _makefpartparamsizes(nbparams):
218 def _makefpartparamsizes(nbparams):
219 """return a struct format to read part parameter sizes
219 """return a struct format to read part parameter sizes
220
220
221 The number parameters is variable so we need to build that format
221 The number parameters is variable so we need to build that format
222 dynamically.
222 dynamically.
223 """
223 """
224 return b'>' + (b'BB' * nbparams)
224 return b'>' + (b'BB' * nbparams)
225
225
226
226
227 parthandlermapping = {}
227 parthandlermapping = {}
228
228
229
229
230 def parthandler(parttype, params=()):
230 def parthandler(parttype, params=()):
231 """decorator that register a function as a bundle2 part handler
231 """decorator that register a function as a bundle2 part handler
232
232
233 eg::
233 eg::
234
234
235 @parthandler('myparttype', ('mandatory', 'param', 'handled'))
235 @parthandler('myparttype', ('mandatory', 'param', 'handled'))
236 def myparttypehandler(...):
236 def myparttypehandler(...):
237 '''process a part of type "my part".'''
237 '''process a part of type "my part".'''
238 ...
238 ...
239 """
239 """
240 validateparttype(parttype)
240 validateparttype(parttype)
241
241
242 def _decorator(func):
242 def _decorator(func):
243 lparttype = parttype.lower() # enforce lower case matching.
243 lparttype = parttype.lower() # enforce lower case matching.
244 assert lparttype not in parthandlermapping
244 assert lparttype not in parthandlermapping
245 parthandlermapping[lparttype] = func
245 parthandlermapping[lparttype] = func
246 func.params = frozenset(params)
246 func.params = frozenset(params)
247 return func
247 return func
248
248
249 return _decorator
249 return _decorator
250
250
251
251
252 class unbundlerecords(object):
252 class unbundlerecords(object):
253 """keep record of what happens during and unbundle
253 """keep record of what happens during and unbundle
254
254
255 New records are added using `records.add('cat', obj)`. Where 'cat' is a
255 New records are added using `records.add('cat', obj)`. Where 'cat' is a
256 category of record and obj is an arbitrary object.
256 category of record and obj is an arbitrary object.
257
257
258 `records['cat']` will return all entries of this category 'cat'.
258 `records['cat']` will return all entries of this category 'cat'.
259
259
260 Iterating on the object itself will yield `('category', obj)` tuples
260 Iterating on the object itself will yield `('category', obj)` tuples
261 for all entries.
261 for all entries.
262
262
263 All iterations happens in chronological order.
263 All iterations happens in chronological order.
264 """
264 """
265
265
266 def __init__(self):
266 def __init__(self):
267 self._categories = {}
267 self._categories = {}
268 self._sequences = []
268 self._sequences = []
269 self._replies = {}
269 self._replies = {}
270
270
271 def add(self, category, entry, inreplyto=None):
271 def add(self, category, entry, inreplyto=None):
272 """add a new record of a given category.
272 """add a new record of a given category.
273
273
274 The entry can then be retrieved in the list returned by
274 The entry can then be retrieved in the list returned by
275 self['category']."""
275 self['category']."""
276 self._categories.setdefault(category, []).append(entry)
276 self._categories.setdefault(category, []).append(entry)
277 self._sequences.append((category, entry))
277 self._sequences.append((category, entry))
278 if inreplyto is not None:
278 if inreplyto is not None:
279 self.getreplies(inreplyto).add(category, entry)
279 self.getreplies(inreplyto).add(category, entry)
280
280
281 def getreplies(self, partid):
281 def getreplies(self, partid):
282 """get the records that are replies to a specific part"""
282 """get the records that are replies to a specific part"""
283 return self._replies.setdefault(partid, unbundlerecords())
283 return self._replies.setdefault(partid, unbundlerecords())
284
284
285 def __getitem__(self, cat):
285 def __getitem__(self, cat):
286 return tuple(self._categories.get(cat, ()))
286 return tuple(self._categories.get(cat, ()))
287
287
288 def __iter__(self):
288 def __iter__(self):
289 return iter(self._sequences)
289 return iter(self._sequences)
290
290
291 def __len__(self):
291 def __len__(self):
292 return len(self._sequences)
292 return len(self._sequences)
293
293
294 def __nonzero__(self):
294 def __nonzero__(self):
295 return bool(self._sequences)
295 return bool(self._sequences)
296
296
297 __bool__ = __nonzero__
297 __bool__ = __nonzero__
298
298
299
299
300 class bundleoperation(object):
300 class bundleoperation(object):
301 """an object that represents a single bundling process
301 """an object that represents a single bundling process
302
302
303 Its purpose is to carry unbundle-related objects and states.
303 Its purpose is to carry unbundle-related objects and states.
304
304
305 A new object should be created at the beginning of each bundle processing.
305 A new object should be created at the beginning of each bundle processing.
306 The object is to be returned by the processing function.
306 The object is to be returned by the processing function.
307
307
308 The object has very little content now it will ultimately contain:
308 The object has very little content now it will ultimately contain:
309 * an access to the repo the bundle is applied to,
309 * an access to the repo the bundle is applied to,
310 * a ui object,
310 * a ui object,
311 * a way to retrieve a transaction to add changes to the repo,
311 * a way to retrieve a transaction to add changes to the repo,
312 * a way to record the result of processing each part,
312 * a way to record the result of processing each part,
313 * a way to construct a bundle response when applicable.
313 * a way to construct a bundle response when applicable.
314 """
314 """
315
315
316 def __init__(self, repo, transactiongetter, captureoutput=True, source=b''):
316 def __init__(self, repo, transactiongetter, captureoutput=True, source=b''):
317 self.repo = repo
317 self.repo = repo
318 self.ui = repo.ui
318 self.ui = repo.ui
319 self.records = unbundlerecords()
319 self.records = unbundlerecords()
320 self.reply = None
320 self.reply = None
321 self.captureoutput = captureoutput
321 self.captureoutput = captureoutput
322 self.hookargs = {}
322 self.hookargs = {}
323 self._gettransaction = transactiongetter
323 self._gettransaction = transactiongetter
324 # carries value that can modify part behavior
324 # carries value that can modify part behavior
325 self.modes = {}
325 self.modes = {}
326 self.source = source
326 self.source = source
327
327
328 def gettransaction(self):
328 def gettransaction(self):
329 transaction = self._gettransaction()
329 transaction = self._gettransaction()
330
330
331 if self.hookargs:
331 if self.hookargs:
332 # the ones added to the transaction supercede those added
332 # the ones added to the transaction supercede those added
333 # to the operation.
333 # to the operation.
334 self.hookargs.update(transaction.hookargs)
334 self.hookargs.update(transaction.hookargs)
335 transaction.hookargs = self.hookargs
335 transaction.hookargs = self.hookargs
336
336
337 # mark the hookargs as flushed. further attempts to add to
337 # mark the hookargs as flushed. further attempts to add to
338 # hookargs will result in an abort.
338 # hookargs will result in an abort.
339 self.hookargs = None
339 self.hookargs = None
340
340
341 return transaction
341 return transaction
342
342
343 def addhookargs(self, hookargs):
343 def addhookargs(self, hookargs):
344 if self.hookargs is None:
344 if self.hookargs is None:
345 raise error.ProgrammingError(
345 raise error.ProgrammingError(
346 b'attempted to add hookargs to '
346 b'attempted to add hookargs to '
347 b'operation after transaction started'
347 b'operation after transaction started'
348 )
348 )
349 self.hookargs.update(hookargs)
349 self.hookargs.update(hookargs)
350
350
351
351
352 class TransactionUnavailable(RuntimeError):
352 class TransactionUnavailable(RuntimeError):
353 pass
353 pass
354
354
355
355
356 def _notransaction():
356 def _notransaction():
357 """default method to get a transaction while processing a bundle
357 """default method to get a transaction while processing a bundle
358
358
359 Raise an exception to highlight the fact that no transaction was expected
359 Raise an exception to highlight the fact that no transaction was expected
360 to be created"""
360 to be created"""
361 raise TransactionUnavailable()
361 raise TransactionUnavailable()
362
362
363
363
364 def applybundle(repo, unbundler, tr, source, url=None, **kwargs):
364 def applybundle(repo, unbundler, tr, source, url=None, **kwargs):
365 # transform me into unbundler.apply() as soon as the freeze is lifted
365 # transform me into unbundler.apply() as soon as the freeze is lifted
366 if isinstance(unbundler, unbundle20):
366 if isinstance(unbundler, unbundle20):
367 tr.hookargs[b'bundle2'] = b'1'
367 tr.hookargs[b'bundle2'] = b'1'
368 if source is not None and b'source' not in tr.hookargs:
368 if source is not None and b'source' not in tr.hookargs:
369 tr.hookargs[b'source'] = source
369 tr.hookargs[b'source'] = source
370 if url is not None and b'url' not in tr.hookargs:
370 if url is not None and b'url' not in tr.hookargs:
371 tr.hookargs[b'url'] = url
371 tr.hookargs[b'url'] = url
372 return processbundle(repo, unbundler, lambda: tr, source=source)
372 return processbundle(repo, unbundler, lambda: tr, source=source)
373 else:
373 else:
374 # the transactiongetter won't be used, but we might as well set it
374 # the transactiongetter won't be used, but we might as well set it
375 op = bundleoperation(repo, lambda: tr, source=source)
375 op = bundleoperation(repo, lambda: tr, source=source)
376 _processchangegroup(op, unbundler, tr, source, url, **kwargs)
376 _processchangegroup(op, unbundler, tr, source, url, **kwargs)
377 return op
377 return op
378
378
379
379
380 class partiterator(object):
380 class partiterator(object):
381 def __init__(self, repo, op, unbundler):
381 def __init__(self, repo, op, unbundler):
382 self.repo = repo
382 self.repo = repo
383 self.op = op
383 self.op = op
384 self.unbundler = unbundler
384 self.unbundler = unbundler
385 self.iterator = None
385 self.iterator = None
386 self.count = 0
386 self.count = 0
387 self.current = None
387 self.current = None
388
388
389 def __enter__(self):
389 def __enter__(self):
390 def func():
390 def func():
391 itr = enumerate(self.unbundler.iterparts(), 1)
391 itr = enumerate(self.unbundler.iterparts(), 1)
392 for count, p in itr:
392 for count, p in itr:
393 self.count = count
393 self.count = count
394 self.current = p
394 self.current = p
395 yield p
395 yield p
396 p.consume()
396 p.consume()
397 self.current = None
397 self.current = None
398
398
399 self.iterator = func()
399 self.iterator = func()
400 return self.iterator
400 return self.iterator
401
401
402 def __exit__(self, type, exc, tb):
402 def __exit__(self, type, exc, tb):
403 if not self.iterator:
403 if not self.iterator:
404 return
404 return
405
405
406 # Only gracefully abort in a normal exception situation. User aborts
406 # Only gracefully abort in a normal exception situation. User aborts
407 # like Ctrl+C throw a KeyboardInterrupt which is not a base Exception,
407 # like Ctrl+C throw a KeyboardInterrupt which is not a base Exception,
408 # and should not gracefully cleanup.
408 # and should not gracefully cleanup.
409 if isinstance(exc, Exception):
409 if isinstance(exc, Exception):
410 # Any exceptions seeking to the end of the bundle at this point are
410 # Any exceptions seeking to the end of the bundle at this point are
411 # almost certainly related to the underlying stream being bad.
411 # almost certainly related to the underlying stream being bad.
412 # And, chances are that the exception we're handling is related to
412 # And, chances are that the exception we're handling is related to
413 # getting in that bad state. So, we swallow the seeking error and
413 # getting in that bad state. So, we swallow the seeking error and
414 # re-raise the original error.
414 # re-raise the original error.
415 seekerror = False
415 seekerror = False
416 try:
416 try:
417 if self.current:
417 if self.current:
418 # consume the part content to not corrupt the stream.
418 # consume the part content to not corrupt the stream.
419 self.current.consume()
419 self.current.consume()
420
420
421 for part in self.iterator:
421 for part in self.iterator:
422 # consume the bundle content
422 # consume the bundle content
423 part.consume()
423 part.consume()
424 except Exception:
424 except Exception:
425 seekerror = True
425 seekerror = True
426
426
427 # Small hack to let caller code distinguish exceptions from bundle2
427 # Small hack to let caller code distinguish exceptions from bundle2
428 # processing from processing the old format. This is mostly needed
428 # processing from processing the old format. This is mostly needed
429 # to handle different return codes to unbundle according to the type
429 # to handle different return codes to unbundle according to the type
430 # of bundle. We should probably clean up or drop this return code
430 # of bundle. We should probably clean up or drop this return code
431 # craziness in a future version.
431 # craziness in a future version.
432 exc.duringunbundle2 = True
432 exc.duringunbundle2 = True
433 salvaged = []
433 salvaged = []
434 replycaps = None
434 replycaps = None
435 if self.op.reply is not None:
435 if self.op.reply is not None:
436 salvaged = self.op.reply.salvageoutput()
436 salvaged = self.op.reply.salvageoutput()
437 replycaps = self.op.reply.capabilities
437 replycaps = self.op.reply.capabilities
438 exc._replycaps = replycaps
438 exc._replycaps = replycaps
439 exc._bundle2salvagedoutput = salvaged
439 exc._bundle2salvagedoutput = salvaged
440
440
441 # Re-raising from a variable loses the original stack. So only use
441 # Re-raising from a variable loses the original stack. So only use
442 # that form if we need to.
442 # that form if we need to.
443 if seekerror:
443 if seekerror:
444 raise exc
444 raise exc
445
445
446 self.repo.ui.debug(
446 self.repo.ui.debug(
447 b'bundle2-input-bundle: %i parts total\n' % self.count
447 b'bundle2-input-bundle: %i parts total\n' % self.count
448 )
448 )
449
449
450
450
451 def processbundle(repo, unbundler, transactiongetter=None, op=None, source=b''):
451 def processbundle(repo, unbundler, transactiongetter=None, op=None, source=b''):
452 """This function process a bundle, apply effect to/from a repo
452 """This function process a bundle, apply effect to/from a repo
453
453
454 It iterates over each part then searches for and uses the proper handling
454 It iterates over each part then searches for and uses the proper handling
455 code to process the part. Parts are processed in order.
455 code to process the part. Parts are processed in order.
456
456
457 Unknown Mandatory part will abort the process.
457 Unknown Mandatory part will abort the process.
458
458
459 It is temporarily possible to provide a prebuilt bundleoperation to the
459 It is temporarily possible to provide a prebuilt bundleoperation to the
460 function. This is used to ensure output is properly propagated in case of
460 function. This is used to ensure output is properly propagated in case of
461 an error during the unbundling. This output capturing part will likely be
461 an error during the unbundling. This output capturing part will likely be
462 reworked and this ability will probably go away in the process.
462 reworked and this ability will probably go away in the process.
463 """
463 """
464 if op is None:
464 if op is None:
465 if transactiongetter is None:
465 if transactiongetter is None:
466 transactiongetter = _notransaction
466 transactiongetter = _notransaction
467 op = bundleoperation(repo, transactiongetter, source=source)
467 op = bundleoperation(repo, transactiongetter, source=source)
468 # todo:
468 # todo:
469 # - replace this is a init function soon.
469 # - replace this is a init function soon.
470 # - exception catching
470 # - exception catching
471 unbundler.params
471 unbundler.params
472 if repo.ui.debugflag:
472 if repo.ui.debugflag:
473 msg = [b'bundle2-input-bundle:']
473 msg = [b'bundle2-input-bundle:']
474 if unbundler.params:
474 if unbundler.params:
475 msg.append(b' %i params' % len(unbundler.params))
475 msg.append(b' %i params' % len(unbundler.params))
476 if op._gettransaction is None or op._gettransaction is _notransaction:
476 if op._gettransaction is None or op._gettransaction is _notransaction:
477 msg.append(b' no-transaction')
477 msg.append(b' no-transaction')
478 else:
478 else:
479 msg.append(b' with-transaction')
479 msg.append(b' with-transaction')
480 msg.append(b'\n')
480 msg.append(b'\n')
481 repo.ui.debug(b''.join(msg))
481 repo.ui.debug(b''.join(msg))
482
482
483 processparts(repo, op, unbundler)
483 processparts(repo, op, unbundler)
484
484
485 return op
485 return op
486
486
487
487
488 def processparts(repo, op, unbundler):
488 def processparts(repo, op, unbundler):
489 with partiterator(repo, op, unbundler) as parts:
489 with partiterator(repo, op, unbundler) as parts:
490 for part in parts:
490 for part in parts:
491 _processpart(op, part)
491 _processpart(op, part)
492
492
493
493
494 def _processchangegroup(op, cg, tr, source, url, **kwargs):
494 def _processchangegroup(op, cg, tr, source, url, **kwargs):
495 ret = cg.apply(op.repo, tr, source, url, **kwargs)
495 ret = cg.apply(op.repo, tr, source, url, **kwargs)
496 op.records.add(
496 op.records.add(
497 b'changegroup',
497 b'changegroup',
498 {
498 {
499 b'return': ret,
499 b'return': ret,
500 },
500 },
501 )
501 )
502 return ret
502 return ret
503
503
504
504
505 def _gethandler(op, part):
505 def _gethandler(op, part):
506 status = b'unknown' # used by debug output
506 status = b'unknown' # used by debug output
507 try:
507 try:
508 handler = parthandlermapping.get(part.type)
508 handler = parthandlermapping.get(part.type)
509 if handler is None:
509 if handler is None:
510 status = b'unsupported-type'
510 status = b'unsupported-type'
511 raise error.BundleUnknownFeatureError(parttype=part.type)
511 raise error.BundleUnknownFeatureError(parttype=part.type)
512 indebug(op.ui, b'found a handler for part %s' % part.type)
512 indebug(op.ui, b'found a handler for part %s' % part.type)
513 unknownparams = part.mandatorykeys - handler.params
513 unknownparams = part.mandatorykeys - handler.params
514 if unknownparams:
514 if unknownparams:
515 unknownparams = list(unknownparams)
515 unknownparams = list(unknownparams)
516 unknownparams.sort()
516 unknownparams.sort()
517 status = b'unsupported-params (%s)' % b', '.join(unknownparams)
517 status = b'unsupported-params (%s)' % b', '.join(unknownparams)
518 raise error.BundleUnknownFeatureError(
518 raise error.BundleUnknownFeatureError(
519 parttype=part.type, params=unknownparams
519 parttype=part.type, params=unknownparams
520 )
520 )
521 status = b'supported'
521 status = b'supported'
522 except error.BundleUnknownFeatureError as exc:
522 except error.BundleUnknownFeatureError as exc:
523 if part.mandatory: # mandatory parts
523 if part.mandatory: # mandatory parts
524 raise
524 raise
525 indebug(op.ui, b'ignoring unsupported advisory part %s' % exc)
525 indebug(op.ui, b'ignoring unsupported advisory part %s' % exc)
526 return # skip to part processing
526 return # skip to part processing
527 finally:
527 finally:
528 if op.ui.debugflag:
528 if op.ui.debugflag:
529 msg = [b'bundle2-input-part: "%s"' % part.type]
529 msg = [b'bundle2-input-part: "%s"' % part.type]
530 if not part.mandatory:
530 if not part.mandatory:
531 msg.append(b' (advisory)')
531 msg.append(b' (advisory)')
532 nbmp = len(part.mandatorykeys)
532 nbmp = len(part.mandatorykeys)
533 nbap = len(part.params) - nbmp
533 nbap = len(part.params) - nbmp
534 if nbmp or nbap:
534 if nbmp or nbap:
535 msg.append(b' (params:')
535 msg.append(b' (params:')
536 if nbmp:
536 if nbmp:
537 msg.append(b' %i mandatory' % nbmp)
537 msg.append(b' %i mandatory' % nbmp)
538 if nbap:
538 if nbap:
539 msg.append(b' %i advisory' % nbmp)
539 msg.append(b' %i advisory' % nbmp)
540 msg.append(b')')
540 msg.append(b')')
541 msg.append(b' %s\n' % status)
541 msg.append(b' %s\n' % status)
542 op.ui.debug(b''.join(msg))
542 op.ui.debug(b''.join(msg))
543
543
544 return handler
544 return handler
545
545
546
546
547 def _processpart(op, part):
547 def _processpart(op, part):
548 """process a single part from a bundle
548 """process a single part from a bundle
549
549
550 The part is guaranteed to have been fully consumed when the function exits
550 The part is guaranteed to have been fully consumed when the function exits
551 (even if an exception is raised)."""
551 (even if an exception is raised)."""
552 handler = _gethandler(op, part)
552 handler = _gethandler(op, part)
553 if handler is None:
553 if handler is None:
554 return
554 return
555
555
556 # handler is called outside the above try block so that we don't
556 # handler is called outside the above try block so that we don't
557 # risk catching KeyErrors from anything other than the
557 # risk catching KeyErrors from anything other than the
558 # parthandlermapping lookup (any KeyError raised by handler()
558 # parthandlermapping lookup (any KeyError raised by handler()
559 # itself represents a defect of a different variety).
559 # itself represents a defect of a different variety).
560 output = None
560 output = None
561 if op.captureoutput and op.reply is not None:
561 if op.captureoutput and op.reply is not None:
562 op.ui.pushbuffer(error=True, subproc=True)
562 op.ui.pushbuffer(error=True, subproc=True)
563 output = b''
563 output = b''
564 try:
564 try:
565 handler(op, part)
565 handler(op, part)
566 finally:
566 finally:
567 if output is not None:
567 if output is not None:
568 output = op.ui.popbuffer()
568 output = op.ui.popbuffer()
569 if output:
569 if output:
570 outpart = op.reply.newpart(b'output', data=output, mandatory=False)
570 outpart = op.reply.newpart(b'output', data=output, mandatory=False)
571 outpart.addparam(
571 outpart.addparam(
572 b'in-reply-to', pycompat.bytestr(part.id), mandatory=False
572 b'in-reply-to', pycompat.bytestr(part.id), mandatory=False
573 )
573 )
574
574
575
575
576 def decodecaps(blob):
576 def decodecaps(blob):
577 """decode a bundle2 caps bytes blob into a dictionary
577 """decode a bundle2 caps bytes blob into a dictionary
578
578
579 The blob is a list of capabilities (one per line)
579 The blob is a list of capabilities (one per line)
580 Capabilities may have values using a line of the form::
580 Capabilities may have values using a line of the form::
581
581
582 capability=value1,value2,value3
582 capability=value1,value2,value3
583
583
584 The values are always a list."""
584 The values are always a list."""
585 caps = {}
585 caps = {}
586 for line in blob.splitlines():
586 for line in blob.splitlines():
587 if not line:
587 if not line:
588 continue
588 continue
589 if b'=' not in line:
589 if b'=' not in line:
590 key, vals = line, ()
590 key, vals = line, ()
591 else:
591 else:
592 key, vals = line.split(b'=', 1)
592 key, vals = line.split(b'=', 1)
593 vals = vals.split(b',')
593 vals = vals.split(b',')
594 key = urlreq.unquote(key)
594 key = urlreq.unquote(key)
595 vals = [urlreq.unquote(v) for v in vals]
595 vals = [urlreq.unquote(v) for v in vals]
596 caps[key] = vals
596 caps[key] = vals
597 return caps
597 return caps
598
598
599
599
600 def encodecaps(caps):
600 def encodecaps(caps):
601 """encode a bundle2 caps dictionary into a bytes blob"""
601 """encode a bundle2 caps dictionary into a bytes blob"""
602 chunks = []
602 chunks = []
603 for ca in sorted(caps):
603 for ca in sorted(caps):
604 vals = caps[ca]
604 vals = caps[ca]
605 ca = urlreq.quote(ca)
605 ca = urlreq.quote(ca)
606 vals = [urlreq.quote(v) for v in vals]
606 vals = [urlreq.quote(v) for v in vals]
607 if vals:
607 if vals:
608 ca = b"%s=%s" % (ca, b','.join(vals))
608 ca = b"%s=%s" % (ca, b','.join(vals))
609 chunks.append(ca)
609 chunks.append(ca)
610 return b'\n'.join(chunks)
610 return b'\n'.join(chunks)
611
611
612
612
613 bundletypes = {
613 bundletypes = {
614 b"": (b"", b'UN'), # only when using unbundle on ssh and old http servers
614 b"": (b"", b'UN'), # only when using unbundle on ssh and old http servers
615 # since the unification ssh accepts a header but there
615 # since the unification ssh accepts a header but there
616 # is no capability signaling it.
616 # is no capability signaling it.
617 b"HG20": (), # special-cased below
617 b"HG20": (), # special-cased below
618 b"HG10UN": (b"HG10UN", b'UN'),
618 b"HG10UN": (b"HG10UN", b'UN'),
619 b"HG10BZ": (b"HG10", b'BZ'),
619 b"HG10BZ": (b"HG10", b'BZ'),
620 b"HG10GZ": (b"HG10GZ", b'GZ'),
620 b"HG10GZ": (b"HG10GZ", b'GZ'),
621 }
621 }
622
622
623 # hgweb uses this list to communicate its preferred type
623 # hgweb uses this list to communicate its preferred type
624 bundlepriority = [b'HG10GZ', b'HG10BZ', b'HG10UN']
624 bundlepriority = [b'HG10GZ', b'HG10BZ', b'HG10UN']
625
625
626
626
627 class bundle20(object):
627 class bundle20(object):
628 """represent an outgoing bundle2 container
628 """represent an outgoing bundle2 container
629
629
630 Use the `addparam` method to add stream level parameter. and `newpart` to
630 Use the `addparam` method to add stream level parameter. and `newpart` to
631 populate it. Then call `getchunks` to retrieve all the binary chunks of
631 populate it. Then call `getchunks` to retrieve all the binary chunks of
632 data that compose the bundle2 container."""
632 data that compose the bundle2 container."""
633
633
634 _magicstring = b'HG20'
634 _magicstring = b'HG20'
635
635
636 def __init__(self, ui, capabilities=()):
636 def __init__(self, ui, capabilities=()):
637 self.ui = ui
637 self.ui = ui
638 self._params = []
638 self._params = []
639 self._parts = []
639 self._parts = []
640 self.capabilities = dict(capabilities)
640 self.capabilities = dict(capabilities)
641 self._compengine = util.compengines.forbundletype(b'UN')
641 self._compengine = util.compengines.forbundletype(b'UN')
642 self._compopts = None
642 self._compopts = None
643 # If compression is being handled by a consumer of the raw
643 # If compression is being handled by a consumer of the raw
644 # data (e.g. the wire protocol), unsetting this flag tells
644 # data (e.g. the wire protocol), unsetting this flag tells
645 # consumers that the bundle is best left uncompressed.
645 # consumers that the bundle is best left uncompressed.
646 self.prefercompressed = True
646 self.prefercompressed = True
647
647
648 def setcompression(self, alg, compopts=None):
648 def setcompression(self, alg, compopts=None):
649 """setup core part compression to <alg>"""
649 """setup core part compression to <alg>"""
650 if alg in (None, b'UN'):
650 if alg in (None, b'UN'):
651 return
651 return
652 assert not any(n.lower() == b'compression' for n, v in self._params)
652 assert not any(n.lower() == b'compression' for n, v in self._params)
653 self.addparam(b'Compression', alg)
653 self.addparam(b'Compression', alg)
654 self._compengine = util.compengines.forbundletype(alg)
654 self._compengine = util.compengines.forbundletype(alg)
655 self._compopts = compopts
655 self._compopts = compopts
656
656
657 @property
657 @property
658 def nbparts(self):
658 def nbparts(self):
659 """total number of parts added to the bundler"""
659 """total number of parts added to the bundler"""
660 return len(self._parts)
660 return len(self._parts)
661
661
662 # methods used to defines the bundle2 content
662 # methods used to defines the bundle2 content
663 def addparam(self, name, value=None):
663 def addparam(self, name, value=None):
664 """add a stream level parameter"""
664 """add a stream level parameter"""
665 if not name:
665 if not name:
666 raise error.ProgrammingError(b'empty parameter name')
666 raise error.ProgrammingError(b'empty parameter name')
667 if name[0:1] not in pycompat.bytestr(
667 if name[0:1] not in pycompat.bytestr(
668 string.ascii_letters # pytype: disable=wrong-arg-types
668 string.ascii_letters # pytype: disable=wrong-arg-types
669 ):
669 ):
670 raise error.ProgrammingError(
670 raise error.ProgrammingError(
671 b'non letter first character: %s' % name
671 b'non letter first character: %s' % name
672 )
672 )
673 self._params.append((name, value))
673 self._params.append((name, value))
674
674
675 def addpart(self, part):
675 def addpart(self, part):
676 """add a new part to the bundle2 container
676 """add a new part to the bundle2 container
677
677
678 Parts contains the actual applicative payload."""
678 Parts contains the actual applicative payload."""
679 assert part.id is None
679 assert part.id is None
680 part.id = len(self._parts) # very cheap counter
680 part.id = len(self._parts) # very cheap counter
681 self._parts.append(part)
681 self._parts.append(part)
682
682
683 def newpart(self, typeid, *args, **kwargs):
683 def newpart(self, typeid, *args, **kwargs):
684 """create a new part and add it to the containers
684 """create a new part and add it to the containers
685
685
686 As the part is directly added to the containers. For now, this means
686 As the part is directly added to the containers. For now, this means
687 that any failure to properly initialize the part after calling
687 that any failure to properly initialize the part after calling
688 ``newpart`` should result in a failure of the whole bundling process.
688 ``newpart`` should result in a failure of the whole bundling process.
689
689
690 You can still fall back to manually create and add if you need better
690 You can still fall back to manually create and add if you need better
691 control."""
691 control."""
692 part = bundlepart(typeid, *args, **kwargs)
692 part = bundlepart(typeid, *args, **kwargs)
693 self.addpart(part)
693 self.addpart(part)
694 return part
694 return part
695
695
696 # methods used to generate the bundle2 stream
696 # methods used to generate the bundle2 stream
697 def getchunks(self):
697 def getchunks(self):
698 if self.ui.debugflag:
698 if self.ui.debugflag:
699 msg = [b'bundle2-output-bundle: "%s",' % self._magicstring]
699 msg = [b'bundle2-output-bundle: "%s",' % self._magicstring]
700 if self._params:
700 if self._params:
701 msg.append(b' (%i params)' % len(self._params))
701 msg.append(b' (%i params)' % len(self._params))
702 msg.append(b' %i parts total\n' % len(self._parts))
702 msg.append(b' %i parts total\n' % len(self._parts))
703 self.ui.debug(b''.join(msg))
703 self.ui.debug(b''.join(msg))
704 outdebug(self.ui, b'start emission of %s stream' % self._magicstring)
704 outdebug(self.ui, b'start emission of %s stream' % self._magicstring)
705 yield self._magicstring
705 yield self._magicstring
706 param = self._paramchunk()
706 param = self._paramchunk()
707 outdebug(self.ui, b'bundle parameter: %s' % param)
707 outdebug(self.ui, b'bundle parameter: %s' % param)
708 yield _pack(_fstreamparamsize, len(param))
708 yield _pack(_fstreamparamsize, len(param))
709 if param:
709 if param:
710 yield param
710 yield param
711 for chunk in self._compengine.compressstream(
711 for chunk in self._compengine.compressstream(
712 self._getcorechunk(), self._compopts
712 self._getcorechunk(), self._compopts
713 ):
713 ):
714 yield chunk
714 yield chunk
715
715
716 def _paramchunk(self):
716 def _paramchunk(self):
717 """return a encoded version of all stream parameters"""
717 """return a encoded version of all stream parameters"""
718 blocks = []
718 blocks = []
719 for par, value in self._params:
719 for par, value in self._params:
720 par = urlreq.quote(par)
720 par = urlreq.quote(par)
721 if value is not None:
721 if value is not None:
722 value = urlreq.quote(value)
722 value = urlreq.quote(value)
723 par = b'%s=%s' % (par, value)
723 par = b'%s=%s' % (par, value)
724 blocks.append(par)
724 blocks.append(par)
725 return b' '.join(blocks)
725 return b' '.join(blocks)
726
726
727 def _getcorechunk(self):
727 def _getcorechunk(self):
728 """yield chunk for the core part of the bundle
728 """yield chunk for the core part of the bundle
729
729
730 (all but headers and parameters)"""
730 (all but headers and parameters)"""
731 outdebug(self.ui, b'start of parts')
731 outdebug(self.ui, b'start of parts')
732 for part in self._parts:
732 for part in self._parts:
733 outdebug(self.ui, b'bundle part: "%s"' % part.type)
733 outdebug(self.ui, b'bundle part: "%s"' % part.type)
734 for chunk in part.getchunks(ui=self.ui):
734 for chunk in part.getchunks(ui=self.ui):
735 yield chunk
735 yield chunk
736 outdebug(self.ui, b'end of bundle')
736 outdebug(self.ui, b'end of bundle')
737 yield _pack(_fpartheadersize, 0)
737 yield _pack(_fpartheadersize, 0)
738
738
739 def salvageoutput(self):
739 def salvageoutput(self):
740 """return a list with a copy of all output parts in the bundle
740 """return a list with a copy of all output parts in the bundle
741
741
742 This is meant to be used during error handling to make sure we preserve
742 This is meant to be used during error handling to make sure we preserve
743 server output"""
743 server output"""
744 salvaged = []
744 salvaged = []
745 for part in self._parts:
745 for part in self._parts:
746 if part.type.startswith(b'output'):
746 if part.type.startswith(b'output'):
747 salvaged.append(part.copy())
747 salvaged.append(part.copy())
748 return salvaged
748 return salvaged
749
749
750
750
751 class unpackermixin(object):
751 class unpackermixin(object):
752 """A mixin to extract bytes and struct data from a stream"""
752 """A mixin to extract bytes and struct data from a stream"""
753
753
754 def __init__(self, fp):
754 def __init__(self, fp):
755 self._fp = fp
755 self._fp = fp
756
756
757 def _unpack(self, format):
757 def _unpack(self, format):
758 """unpack this struct format from the stream
758 """unpack this struct format from the stream
759
759
760 This method is meant for internal usage by the bundle2 protocol only.
760 This method is meant for internal usage by the bundle2 protocol only.
761 They directly manipulate the low level stream including bundle2 level
761 They directly manipulate the low level stream including bundle2 level
762 instruction.
762 instruction.
763
763
764 Do not use it to implement higher-level logic or methods."""
764 Do not use it to implement higher-level logic or methods."""
765 data = self._readexact(struct.calcsize(format))
765 data = self._readexact(struct.calcsize(format))
766 return _unpack(format, data)
766 return _unpack(format, data)
767
767
768 def _readexact(self, size):
768 def _readexact(self, size):
769 """read exactly <size> bytes from the stream
769 """read exactly <size> bytes from the stream
770
770
771 This method is meant for internal usage by the bundle2 protocol only.
771 This method is meant for internal usage by the bundle2 protocol only.
772 They directly manipulate the low level stream including bundle2 level
772 They directly manipulate the low level stream including bundle2 level
773 instruction.
773 instruction.
774
774
775 Do not use it to implement higher-level logic or methods."""
775 Do not use it to implement higher-level logic or methods."""
776 return changegroup.readexactly(self._fp, size)
776 return changegroup.readexactly(self._fp, size)
777
777
778
778
779 def getunbundler(ui, fp, magicstring=None):
779 def getunbundler(ui, fp, magicstring=None):
780 """return a valid unbundler object for a given magicstring"""
780 """return a valid unbundler object for a given magicstring"""
781 if magicstring is None:
781 if magicstring is None:
782 magicstring = changegroup.readexactly(fp, 4)
782 magicstring = changegroup.readexactly(fp, 4)
783 magic, version = magicstring[0:2], magicstring[2:4]
783 magic, version = magicstring[0:2], magicstring[2:4]
784 if magic != b'HG':
784 if magic != b'HG':
785 ui.debug(
785 ui.debug(
786 b"error: invalid magic: %r (version %r), should be 'HG'\n"
786 b"error: invalid magic: %r (version %r), should be 'HG'\n"
787 % (magic, version)
787 % (magic, version)
788 )
788 )
789 raise error.Abort(_(b'not a Mercurial bundle'))
789 raise error.Abort(_(b'not a Mercurial bundle'))
790 unbundlerclass = formatmap.get(version)
790 unbundlerclass = formatmap.get(version)
791 if unbundlerclass is None:
791 if unbundlerclass is None:
792 raise error.Abort(_(b'unknown bundle version %s') % version)
792 raise error.Abort(_(b'unknown bundle version %s') % version)
793 unbundler = unbundlerclass(ui, fp)
793 unbundler = unbundlerclass(ui, fp)
794 indebug(ui, b'start processing of %s stream' % magicstring)
794 indebug(ui, b'start processing of %s stream' % magicstring)
795 return unbundler
795 return unbundler
796
796
797
797
798 class unbundle20(unpackermixin):
798 class unbundle20(unpackermixin):
799 """interpret a bundle2 stream
799 """interpret a bundle2 stream
800
800
801 This class is fed with a binary stream and yields parts through its
801 This class is fed with a binary stream and yields parts through its
802 `iterparts` methods."""
802 `iterparts` methods."""
803
803
804 _magicstring = b'HG20'
804 _magicstring = b'HG20'
805
805
806 def __init__(self, ui, fp):
806 def __init__(self, ui, fp):
807 """If header is specified, we do not read it out of the stream."""
807 """If header is specified, we do not read it out of the stream."""
808 self.ui = ui
808 self.ui = ui
809 self._compengine = util.compengines.forbundletype(b'UN')
809 self._compengine = util.compengines.forbundletype(b'UN')
810 self._compressed = None
810 self._compressed = None
811 super(unbundle20, self).__init__(fp)
811 super(unbundle20, self).__init__(fp)
812
812
813 @util.propertycache
813 @util.propertycache
814 def params(self):
814 def params(self):
815 """dictionary of stream level parameters"""
815 """dictionary of stream level parameters"""
816 indebug(self.ui, b'reading bundle2 stream parameters')
816 indebug(self.ui, b'reading bundle2 stream parameters')
817 params = {}
817 params = {}
818 paramssize = self._unpack(_fstreamparamsize)[0]
818 paramssize = self._unpack(_fstreamparamsize)[0]
819 if paramssize < 0:
819 if paramssize < 0:
820 raise error.BundleValueError(
820 raise error.BundleValueError(
821 b'negative bundle param size: %i' % paramssize
821 b'negative bundle param size: %i' % paramssize
822 )
822 )
823 if paramssize:
823 if paramssize:
824 params = self._readexact(paramssize)
824 params = self._readexact(paramssize)
825 params = self._processallparams(params)
825 params = self._processallparams(params)
826 return params
826 return params
827
827
828 def _processallparams(self, paramsblock):
828 def _processallparams(self, paramsblock):
829 """"""
829 """"""
830 params = util.sortdict()
830 params = util.sortdict()
831 for p in paramsblock.split(b' '):
831 for p in paramsblock.split(b' '):
832 p = p.split(b'=', 1)
832 p = p.split(b'=', 1)
833 p = [urlreq.unquote(i) for i in p]
833 p = [urlreq.unquote(i) for i in p]
834 if len(p) < 2:
834 if len(p) < 2:
835 p.append(None)
835 p.append(None)
836 self._processparam(*p)
836 self._processparam(*p)
837 params[p[0]] = p[1]
837 params[p[0]] = p[1]
838 return params
838 return params
839
839
840 def _processparam(self, name, value):
840 def _processparam(self, name, value):
841 """process a parameter, applying its effect if needed
841 """process a parameter, applying its effect if needed
842
842
843 Parameter starting with a lower case letter are advisory and will be
843 Parameter starting with a lower case letter are advisory and will be
844 ignored when unknown. Those starting with an upper case letter are
844 ignored when unknown. Those starting with an upper case letter are
845 mandatory and will this function will raise a KeyError when unknown.
845 mandatory and will this function will raise a KeyError when unknown.
846
846
847 Note: no option are currently supported. Any input will be either
847 Note: no option are currently supported. Any input will be either
848 ignored or failing.
848 ignored or failing.
849 """
849 """
850 if not name:
850 if not name:
851 raise ValueError('empty parameter name')
851 raise ValueError('empty parameter name')
852 if name[0:1] not in pycompat.bytestr(
852 if name[0:1] not in pycompat.bytestr(
853 string.ascii_letters # pytype: disable=wrong-arg-types
853 string.ascii_letters # pytype: disable=wrong-arg-types
854 ):
854 ):
855 raise ValueError('non letter first character: %s' % name)
855 raise ValueError('non letter first character: %s' % name)
856 try:
856 try:
857 handler = b2streamparamsmap[name.lower()]
857 handler = b2streamparamsmap[name.lower()]
858 except KeyError:
858 except KeyError:
859 if name[0:1].islower():
859 if name[0:1].islower():
860 indebug(self.ui, b"ignoring unknown parameter %s" % name)
860 indebug(self.ui, b"ignoring unknown parameter %s" % name)
861 else:
861 else:
862 raise error.BundleUnknownFeatureError(params=(name,))
862 raise error.BundleUnknownFeatureError(params=(name,))
863 else:
863 else:
864 handler(self, name, value)
864 handler(self, name, value)
865
865
866 def _forwardchunks(self):
866 def _forwardchunks(self):
867 """utility to transfer a bundle2 as binary
867 """utility to transfer a bundle2 as binary
868
868
869 This is made necessary by the fact the 'getbundle' command over 'ssh'
869 This is made necessary by the fact the 'getbundle' command over 'ssh'
870 have no way to know then the reply end, relying on the bundle to be
870 have no way to know then the reply end, relying on the bundle to be
871 interpreted to know its end. This is terrible and we are sorry, but we
871 interpreted to know its end. This is terrible and we are sorry, but we
872 needed to move forward to get general delta enabled.
872 needed to move forward to get general delta enabled.
873 """
873 """
874 yield self._magicstring
874 yield self._magicstring
875 assert 'params' not in vars(self)
875 assert 'params' not in vars(self)
876 paramssize = self._unpack(_fstreamparamsize)[0]
876 paramssize = self._unpack(_fstreamparamsize)[0]
877 if paramssize < 0:
877 if paramssize < 0:
878 raise error.BundleValueError(
878 raise error.BundleValueError(
879 b'negative bundle param size: %i' % paramssize
879 b'negative bundle param size: %i' % paramssize
880 )
880 )
881 if paramssize:
881 if paramssize:
882 params = self._readexact(paramssize)
882 params = self._readexact(paramssize)
883 self._processallparams(params)
883 self._processallparams(params)
884 # The payload itself is decompressed below, so drop
884 # The payload itself is decompressed below, so drop
885 # the compression parameter passed down to compensate.
885 # the compression parameter passed down to compensate.
886 outparams = []
886 outparams = []
887 for p in params.split(b' '):
887 for p in params.split(b' '):
888 k, v = p.split(b'=', 1)
888 k, v = p.split(b'=', 1)
889 if k.lower() != b'compression':
889 if k.lower() != b'compression':
890 outparams.append(p)
890 outparams.append(p)
891 outparams = b' '.join(outparams)
891 outparams = b' '.join(outparams)
892 yield _pack(_fstreamparamsize, len(outparams))
892 yield _pack(_fstreamparamsize, len(outparams))
893 yield outparams
893 yield outparams
894 else:
894 else:
895 yield _pack(_fstreamparamsize, paramssize)
895 yield _pack(_fstreamparamsize, paramssize)
896 # From there, payload might need to be decompressed
896 # From there, payload might need to be decompressed
897 self._fp = self._compengine.decompressorreader(self._fp)
897 self._fp = self._compengine.decompressorreader(self._fp)
898 emptycount = 0
898 emptycount = 0
899 while emptycount < 2:
899 while emptycount < 2:
900 # so we can brainlessly loop
900 # so we can brainlessly loop
901 assert _fpartheadersize == _fpayloadsize
901 assert _fpartheadersize == _fpayloadsize
902 size = self._unpack(_fpartheadersize)[0]
902 size = self._unpack(_fpartheadersize)[0]
903 yield _pack(_fpartheadersize, size)
903 yield _pack(_fpartheadersize, size)
904 if size:
904 if size:
905 emptycount = 0
905 emptycount = 0
906 else:
906 else:
907 emptycount += 1
907 emptycount += 1
908 continue
908 continue
909 if size == flaginterrupt:
909 if size == flaginterrupt:
910 continue
910 continue
911 elif size < 0:
911 elif size < 0:
912 raise error.BundleValueError(b'negative chunk size: %i')
912 raise error.BundleValueError(b'negative chunk size: %i')
913 yield self._readexact(size)
913 yield self._readexact(size)
914
914
915 def iterparts(self, seekable=False):
915 def iterparts(self, seekable=False):
916 """yield all parts contained in the stream"""
916 """yield all parts contained in the stream"""
917 cls = seekableunbundlepart if seekable else unbundlepart
917 cls = seekableunbundlepart if seekable else unbundlepart
918 # make sure param have been loaded
918 # make sure param have been loaded
919 self.params
919 self.params
920 # From there, payload need to be decompressed
920 # From there, payload need to be decompressed
921 self._fp = self._compengine.decompressorreader(self._fp)
921 self._fp = self._compengine.decompressorreader(self._fp)
922 indebug(self.ui, b'start extraction of bundle2 parts')
922 indebug(self.ui, b'start extraction of bundle2 parts')
923 headerblock = self._readpartheader()
923 headerblock = self._readpartheader()
924 while headerblock is not None:
924 while headerblock is not None:
925 part = cls(self.ui, headerblock, self._fp)
925 part = cls(self.ui, headerblock, self._fp)
926 yield part
926 yield part
927 # Ensure part is fully consumed so we can start reading the next
927 # Ensure part is fully consumed so we can start reading the next
928 # part.
928 # part.
929 part.consume()
929 part.consume()
930
930
931 headerblock = self._readpartheader()
931 headerblock = self._readpartheader()
932 indebug(self.ui, b'end of bundle2 stream')
932 indebug(self.ui, b'end of bundle2 stream')
933
933
934 def _readpartheader(self):
934 def _readpartheader(self):
935 """reads a part header size and return the bytes blob
935 """reads a part header size and return the bytes blob
936
936
937 returns None if empty"""
937 returns None if empty"""
938 headersize = self._unpack(_fpartheadersize)[0]
938 headersize = self._unpack(_fpartheadersize)[0]
939 if headersize < 0:
939 if headersize < 0:
940 raise error.BundleValueError(
940 raise error.BundleValueError(
941 b'negative part header size: %i' % headersize
941 b'negative part header size: %i' % headersize
942 )
942 )
943 indebug(self.ui, b'part header size: %i' % headersize)
943 indebug(self.ui, b'part header size: %i' % headersize)
944 if headersize:
944 if headersize:
945 return self._readexact(headersize)
945 return self._readexact(headersize)
946 return None
946 return None
947
947
948 def compressed(self):
948 def compressed(self):
949 self.params # load params
949 self.params # load params
950 return self._compressed
950 return self._compressed
951
951
952 def close(self):
952 def close(self):
953 """close underlying file"""
953 """close underlying file"""
954 if util.safehasattr(self._fp, 'close'):
954 if util.safehasattr(self._fp, 'close'):
955 return self._fp.close()
955 return self._fp.close()
956
956
957
957
958 formatmap = {b'20': unbundle20}
958 formatmap = {b'20': unbundle20}
959
959
960 b2streamparamsmap = {}
960 b2streamparamsmap = {}
961
961
962
962
963 def b2streamparamhandler(name):
963 def b2streamparamhandler(name):
964 """register a handler for a stream level parameter"""
964 """register a handler for a stream level parameter"""
965
965
966 def decorator(func):
966 def decorator(func):
967 assert name not in formatmap
967 assert name not in formatmap
968 b2streamparamsmap[name] = func
968 b2streamparamsmap[name] = func
969 return func
969 return func
970
970
971 return decorator
971 return decorator
972
972
973
973
974 @b2streamparamhandler(b'compression')
974 @b2streamparamhandler(b'compression')
975 def processcompression(unbundler, param, value):
975 def processcompression(unbundler, param, value):
976 """read compression parameter and install payload decompression"""
976 """read compression parameter and install payload decompression"""
977 if value not in util.compengines.supportedbundletypes:
977 if value not in util.compengines.supportedbundletypes:
978 raise error.BundleUnknownFeatureError(params=(param,), values=(value,))
978 raise error.BundleUnknownFeatureError(params=(param,), values=(value,))
979 unbundler._compengine = util.compengines.forbundletype(value)
979 unbundler._compengine = util.compengines.forbundletype(value)
980 if value is not None:
980 if value is not None:
981 unbundler._compressed = True
981 unbundler._compressed = True
982
982
983
983
984 class bundlepart(object):
984 class bundlepart(object):
985 """A bundle2 part contains application level payload
985 """A bundle2 part contains application level payload
986
986
987 The part `type` is used to route the part to the application level
987 The part `type` is used to route the part to the application level
988 handler.
988 handler.
989
989
990 The part payload is contained in ``part.data``. It could be raw bytes or a
990 The part payload is contained in ``part.data``. It could be raw bytes or a
991 generator of byte chunks.
991 generator of byte chunks.
992
992
993 You can add parameters to the part using the ``addparam`` method.
993 You can add parameters to the part using the ``addparam`` method.
994 Parameters can be either mandatory (default) or advisory. Remote side
994 Parameters can be either mandatory (default) or advisory. Remote side
995 should be able to safely ignore the advisory ones.
995 should be able to safely ignore the advisory ones.
996
996
997 Both data and parameters cannot be modified after the generation has begun.
997 Both data and parameters cannot be modified after the generation has begun.
998 """
998 """
999
999
1000 def __init__(
1000 def __init__(
1001 self,
1001 self,
1002 parttype,
1002 parttype,
1003 mandatoryparams=(),
1003 mandatoryparams=(),
1004 advisoryparams=(),
1004 advisoryparams=(),
1005 data=b'',
1005 data=b'',
1006 mandatory=True,
1006 mandatory=True,
1007 ):
1007 ):
1008 validateparttype(parttype)
1008 validateparttype(parttype)
1009 self.id = None
1009 self.id = None
1010 self.type = parttype
1010 self.type = parttype
1011 self._data = data
1011 self._data = data
1012 self._mandatoryparams = list(mandatoryparams)
1012 self._mandatoryparams = list(mandatoryparams)
1013 self._advisoryparams = list(advisoryparams)
1013 self._advisoryparams = list(advisoryparams)
1014 # checking for duplicated entries
1014 # checking for duplicated entries
1015 self._seenparams = set()
1015 self._seenparams = set()
1016 for pname, __ in self._mandatoryparams + self._advisoryparams:
1016 for pname, __ in self._mandatoryparams + self._advisoryparams:
1017 if pname in self._seenparams:
1017 if pname in self._seenparams:
1018 raise error.ProgrammingError(b'duplicated params: %s' % pname)
1018 raise error.ProgrammingError(b'duplicated params: %s' % pname)
1019 self._seenparams.add(pname)
1019 self._seenparams.add(pname)
1020 # status of the part's generation:
1020 # status of the part's generation:
1021 # - None: not started,
1021 # - None: not started,
1022 # - False: currently generated,
1022 # - False: currently generated,
1023 # - True: generation done.
1023 # - True: generation done.
1024 self._generated = None
1024 self._generated = None
1025 self.mandatory = mandatory
1025 self.mandatory = mandatory
1026
1026
1027 def __repr__(self):
1027 def __repr__(self):
1028 cls = "%s.%s" % (self.__class__.__module__, self.__class__.__name__)
1028 cls = "%s.%s" % (self.__class__.__module__, self.__class__.__name__)
1029 return '<%s object at %x; id: %s; type: %s; mandatory: %s>' % (
1029 return '<%s object at %x; id: %s; type: %s; mandatory: %s>' % (
1030 cls,
1030 cls,
1031 id(self),
1031 id(self),
1032 self.id,
1032 self.id,
1033 self.type,
1033 self.type,
1034 self.mandatory,
1034 self.mandatory,
1035 )
1035 )
1036
1036
1037 def copy(self):
1037 def copy(self):
1038 """return a copy of the part
1038 """return a copy of the part
1039
1039
1040 The new part have the very same content but no partid assigned yet.
1040 The new part have the very same content but no partid assigned yet.
1041 Parts with generated data cannot be copied."""
1041 Parts with generated data cannot be copied."""
1042 assert not util.safehasattr(self.data, 'next')
1042 assert not util.safehasattr(self.data, 'next')
1043 return self.__class__(
1043 return self.__class__(
1044 self.type,
1044 self.type,
1045 self._mandatoryparams,
1045 self._mandatoryparams,
1046 self._advisoryparams,
1046 self._advisoryparams,
1047 self._data,
1047 self._data,
1048 self.mandatory,
1048 self.mandatory,
1049 )
1049 )
1050
1050
1051 # methods used to defines the part content
1051 # methods used to defines the part content
1052 @property
1052 @property
1053 def data(self):
1053 def data(self):
1054 return self._data
1054 return self._data
1055
1055
1056 @data.setter
1056 @data.setter
1057 def data(self, data):
1057 def data(self, data):
1058 if self._generated is not None:
1058 if self._generated is not None:
1059 raise error.ReadOnlyPartError(b'part is being generated')
1059 raise error.ReadOnlyPartError(b'part is being generated')
1060 self._data = data
1060 self._data = data
1061
1061
1062 @property
1062 @property
1063 def mandatoryparams(self):
1063 def mandatoryparams(self):
1064 # make it an immutable tuple to force people through ``addparam``
1064 # make it an immutable tuple to force people through ``addparam``
1065 return tuple(self._mandatoryparams)
1065 return tuple(self._mandatoryparams)
1066
1066
1067 @property
1067 @property
1068 def advisoryparams(self):
1068 def advisoryparams(self):
1069 # make it an immutable tuple to force people through ``addparam``
1069 # make it an immutable tuple to force people through ``addparam``
1070 return tuple(self._advisoryparams)
1070 return tuple(self._advisoryparams)
1071
1071
1072 def addparam(self, name, value=b'', mandatory=True):
1072 def addparam(self, name, value=b'', mandatory=True):
1073 """add a parameter to the part
1073 """add a parameter to the part
1074
1074
1075 If 'mandatory' is set to True, the remote handler must claim support
1075 If 'mandatory' is set to True, the remote handler must claim support
1076 for this parameter or the unbundling will be aborted.
1076 for this parameter or the unbundling will be aborted.
1077
1077
1078 The 'name' and 'value' cannot exceed 255 bytes each.
1078 The 'name' and 'value' cannot exceed 255 bytes each.
1079 """
1079 """
1080 if self._generated is not None:
1080 if self._generated is not None:
1081 raise error.ReadOnlyPartError(b'part is being generated')
1081 raise error.ReadOnlyPartError(b'part is being generated')
1082 if name in self._seenparams:
1082 if name in self._seenparams:
1083 raise ValueError(b'duplicated params: %s' % name)
1083 raise ValueError(b'duplicated params: %s' % name)
1084 self._seenparams.add(name)
1084 self._seenparams.add(name)
1085 params = self._advisoryparams
1085 params = self._advisoryparams
1086 if mandatory:
1086 if mandatory:
1087 params = self._mandatoryparams
1087 params = self._mandatoryparams
1088 params.append((name, value))
1088 params.append((name, value))
1089
1089
1090 # methods used to generates the bundle2 stream
1090 # methods used to generates the bundle2 stream
1091 def getchunks(self, ui):
1091 def getchunks(self, ui):
1092 if self._generated is not None:
1092 if self._generated is not None:
1093 raise error.ProgrammingError(b'part can only be consumed once')
1093 raise error.ProgrammingError(b'part can only be consumed once')
1094 self._generated = False
1094 self._generated = False
1095
1095
1096 if ui.debugflag:
1096 if ui.debugflag:
1097 msg = [b'bundle2-output-part: "%s"' % self.type]
1097 msg = [b'bundle2-output-part: "%s"' % self.type]
1098 if not self.mandatory:
1098 if not self.mandatory:
1099 msg.append(b' (advisory)')
1099 msg.append(b' (advisory)')
1100 nbmp = len(self.mandatoryparams)
1100 nbmp = len(self.mandatoryparams)
1101 nbap = len(self.advisoryparams)
1101 nbap = len(self.advisoryparams)
1102 if nbmp or nbap:
1102 if nbmp or nbap:
1103 msg.append(b' (params:')
1103 msg.append(b' (params:')
1104 if nbmp:
1104 if nbmp:
1105 msg.append(b' %i mandatory' % nbmp)
1105 msg.append(b' %i mandatory' % nbmp)
1106 if nbap:
1106 if nbap:
1107 msg.append(b' %i advisory' % nbmp)
1107 msg.append(b' %i advisory' % nbmp)
1108 msg.append(b')')
1108 msg.append(b')')
1109 if not self.data:
1109 if not self.data:
1110 msg.append(b' empty payload')
1110 msg.append(b' empty payload')
1111 elif util.safehasattr(self.data, 'next') or util.safehasattr(
1111 elif util.safehasattr(self.data, 'next') or util.safehasattr(
1112 self.data, b'__next__'
1112 self.data, b'__next__'
1113 ):
1113 ):
1114 msg.append(b' streamed payload')
1114 msg.append(b' streamed payload')
1115 else:
1115 else:
1116 msg.append(b' %i bytes payload' % len(self.data))
1116 msg.append(b' %i bytes payload' % len(self.data))
1117 msg.append(b'\n')
1117 msg.append(b'\n')
1118 ui.debug(b''.join(msg))
1118 ui.debug(b''.join(msg))
1119
1119
1120 #### header
1120 #### header
1121 if self.mandatory:
1121 if self.mandatory:
1122 parttype = self.type.upper()
1122 parttype = self.type.upper()
1123 else:
1123 else:
1124 parttype = self.type.lower()
1124 parttype = self.type.lower()
1125 outdebug(ui, b'part %s: "%s"' % (pycompat.bytestr(self.id), parttype))
1125 outdebug(ui, b'part %s: "%s"' % (pycompat.bytestr(self.id), parttype))
1126 ## parttype
1126 ## parttype
1127 header = [
1127 header = [
1128 _pack(_fparttypesize, len(parttype)),
1128 _pack(_fparttypesize, len(parttype)),
1129 parttype,
1129 parttype,
1130 _pack(_fpartid, self.id),
1130 _pack(_fpartid, self.id),
1131 ]
1131 ]
1132 ## parameters
1132 ## parameters
1133 # count
1133 # count
1134 manpar = self.mandatoryparams
1134 manpar = self.mandatoryparams
1135 advpar = self.advisoryparams
1135 advpar = self.advisoryparams
1136 header.append(_pack(_fpartparamcount, len(manpar), len(advpar)))
1136 header.append(_pack(_fpartparamcount, len(manpar), len(advpar)))
1137 # size
1137 # size
1138 parsizes = []
1138 parsizes = []
1139 for key, value in manpar:
1139 for key, value in manpar:
1140 parsizes.append(len(key))
1140 parsizes.append(len(key))
1141 parsizes.append(len(value))
1141 parsizes.append(len(value))
1142 for key, value in advpar:
1142 for key, value in advpar:
1143 parsizes.append(len(key))
1143 parsizes.append(len(key))
1144 parsizes.append(len(value))
1144 parsizes.append(len(value))
1145 paramsizes = _pack(_makefpartparamsizes(len(parsizes) // 2), *parsizes)
1145 paramsizes = _pack(_makefpartparamsizes(len(parsizes) // 2), *parsizes)
1146 header.append(paramsizes)
1146 header.append(paramsizes)
1147 # key, value
1147 # key, value
1148 for key, value in manpar:
1148 for key, value in manpar:
1149 header.append(key)
1149 header.append(key)
1150 header.append(value)
1150 header.append(value)
1151 for key, value in advpar:
1151 for key, value in advpar:
1152 header.append(key)
1152 header.append(key)
1153 header.append(value)
1153 header.append(value)
1154 ## finalize header
1154 ## finalize header
1155 try:
1155 try:
1156 headerchunk = b''.join(header)
1156 headerchunk = b''.join(header)
1157 except TypeError:
1157 except TypeError:
1158 raise TypeError(
1158 raise TypeError(
1159 'Found a non-bytes trying to '
1159 'Found a non-bytes trying to '
1160 'build bundle part header: %r' % header
1160 'build bundle part header: %r' % header
1161 )
1161 )
1162 outdebug(ui, b'header chunk size: %i' % len(headerchunk))
1162 outdebug(ui, b'header chunk size: %i' % len(headerchunk))
1163 yield _pack(_fpartheadersize, len(headerchunk))
1163 yield _pack(_fpartheadersize, len(headerchunk))
1164 yield headerchunk
1164 yield headerchunk
1165 ## payload
1165 ## payload
1166 try:
1166 try:
1167 for chunk in self._payloadchunks():
1167 for chunk in self._payloadchunks():
1168 outdebug(ui, b'payload chunk size: %i' % len(chunk))
1168 outdebug(ui, b'payload chunk size: %i' % len(chunk))
1169 yield _pack(_fpayloadsize, len(chunk))
1169 yield _pack(_fpayloadsize, len(chunk))
1170 yield chunk
1170 yield chunk
1171 except GeneratorExit:
1171 except GeneratorExit:
1172 # GeneratorExit means that nobody is listening for our
1172 # GeneratorExit means that nobody is listening for our
1173 # results anyway, so just bail quickly rather than trying
1173 # results anyway, so just bail quickly rather than trying
1174 # to produce an error part.
1174 # to produce an error part.
1175 ui.debug(b'bundle2-generatorexit\n')
1175 ui.debug(b'bundle2-generatorexit\n')
1176 raise
1176 raise
1177 except BaseException as exc:
1177 except BaseException as exc:
1178 bexc = stringutil.forcebytestr(exc)
1178 bexc = stringutil.forcebytestr(exc)
1179 # backup exception data for later
1179 # backup exception data for later
1180 ui.debug(
1180 ui.debug(
1181 b'bundle2-input-stream-interrupt: encoding exception %s' % bexc
1181 b'bundle2-input-stream-interrupt: encoding exception %s' % bexc
1182 )
1182 )
1183 tb = sys.exc_info()[2]
1183 tb = sys.exc_info()[2]
1184 msg = b'unexpected error: %s' % bexc
1184 msg = b'unexpected error: %s' % bexc
1185 interpart = bundlepart(
1185 interpart = bundlepart(
1186 b'error:abort', [(b'message', msg)], mandatory=False
1186 b'error:abort', [(b'message', msg)], mandatory=False
1187 )
1187 )
1188 interpart.id = 0
1188 interpart.id = 0
1189 yield _pack(_fpayloadsize, -1)
1189 yield _pack(_fpayloadsize, -1)
1190 for chunk in interpart.getchunks(ui=ui):
1190 for chunk in interpart.getchunks(ui=ui):
1191 yield chunk
1191 yield chunk
1192 outdebug(ui, b'closing payload chunk')
1192 outdebug(ui, b'closing payload chunk')
1193 # abort current part payload
1193 # abort current part payload
1194 yield _pack(_fpayloadsize, 0)
1194 yield _pack(_fpayloadsize, 0)
1195 pycompat.raisewithtb(exc, tb)
1195 pycompat.raisewithtb(exc, tb)
1196 # end of payload
1196 # end of payload
1197 outdebug(ui, b'closing payload chunk')
1197 outdebug(ui, b'closing payload chunk')
1198 yield _pack(_fpayloadsize, 0)
1198 yield _pack(_fpayloadsize, 0)
1199 self._generated = True
1199 self._generated = True
1200
1200
1201 def _payloadchunks(self):
1201 def _payloadchunks(self):
1202 """yield chunks of a the part payload
1202 """yield chunks of a the part payload
1203
1203
1204 Exists to handle the different methods to provide data to a part."""
1204 Exists to handle the different methods to provide data to a part."""
1205 # we only support fixed size data now.
1205 # we only support fixed size data now.
1206 # This will be improved in the future.
1206 # This will be improved in the future.
1207 if util.safehasattr(self.data, 'next') or util.safehasattr(
1207 if util.safehasattr(self.data, 'next') or util.safehasattr(
1208 self.data, b'__next__'
1208 self.data, b'__next__'
1209 ):
1209 ):
1210 buff = util.chunkbuffer(self.data)
1210 buff = util.chunkbuffer(self.data)
1211 chunk = buff.read(preferedchunksize)
1211 chunk = buff.read(preferedchunksize)
1212 while chunk:
1212 while chunk:
1213 yield chunk
1213 yield chunk
1214 chunk = buff.read(preferedchunksize)
1214 chunk = buff.read(preferedchunksize)
1215 elif len(self.data):
1215 elif len(self.data):
1216 yield self.data
1216 yield self.data
1217
1217
1218
1218
1219 flaginterrupt = -1
1219 flaginterrupt = -1
1220
1220
1221
1221
1222 class interrupthandler(unpackermixin):
1222 class interrupthandler(unpackermixin):
1223 """read one part and process it with restricted capability
1223 """read one part and process it with restricted capability
1224
1224
1225 This allows to transmit exception raised on the producer size during part
1225 This allows to transmit exception raised on the producer size during part
1226 iteration while the consumer is reading a part.
1226 iteration while the consumer is reading a part.
1227
1227
1228 Part processed in this manner only have access to a ui object,"""
1228 Part processed in this manner only have access to a ui object,"""
1229
1229
1230 def __init__(self, ui, fp):
1230 def __init__(self, ui, fp):
1231 super(interrupthandler, self).__init__(fp)
1231 super(interrupthandler, self).__init__(fp)
1232 self.ui = ui
1232 self.ui = ui
1233
1233
1234 def _readpartheader(self):
1234 def _readpartheader(self):
1235 """reads a part header size and return the bytes blob
1235 """reads a part header size and return the bytes blob
1236
1236
1237 returns None if empty"""
1237 returns None if empty"""
1238 headersize = self._unpack(_fpartheadersize)[0]
1238 headersize = self._unpack(_fpartheadersize)[0]
1239 if headersize < 0:
1239 if headersize < 0:
1240 raise error.BundleValueError(
1240 raise error.BundleValueError(
1241 b'negative part header size: %i' % headersize
1241 b'negative part header size: %i' % headersize
1242 )
1242 )
1243 indebug(self.ui, b'part header size: %i\n' % headersize)
1243 indebug(self.ui, b'part header size: %i\n' % headersize)
1244 if headersize:
1244 if headersize:
1245 return self._readexact(headersize)
1245 return self._readexact(headersize)
1246 return None
1246 return None
1247
1247
1248 def __call__(self):
1248 def __call__(self):
1249
1249
1250 self.ui.debug(
1250 self.ui.debug(
1251 b'bundle2-input-stream-interrupt: opening out of band context\n'
1251 b'bundle2-input-stream-interrupt: opening out of band context\n'
1252 )
1252 )
1253 indebug(self.ui, b'bundle2 stream interruption, looking for a part.')
1253 indebug(self.ui, b'bundle2 stream interruption, looking for a part.')
1254 headerblock = self._readpartheader()
1254 headerblock = self._readpartheader()
1255 if headerblock is None:
1255 if headerblock is None:
1256 indebug(self.ui, b'no part found during interruption.')
1256 indebug(self.ui, b'no part found during interruption.')
1257 return
1257 return
1258 part = unbundlepart(self.ui, headerblock, self._fp)
1258 part = unbundlepart(self.ui, headerblock, self._fp)
1259 op = interruptoperation(self.ui)
1259 op = interruptoperation(self.ui)
1260 hardabort = False
1260 hardabort = False
1261 try:
1261 try:
1262 _processpart(op, part)
1262 _processpart(op, part)
1263 except (SystemExit, KeyboardInterrupt):
1263 except (SystemExit, KeyboardInterrupt):
1264 hardabort = True
1264 hardabort = True
1265 raise
1265 raise
1266 finally:
1266 finally:
1267 if not hardabort:
1267 if not hardabort:
1268 part.consume()
1268 part.consume()
1269 self.ui.debug(
1269 self.ui.debug(
1270 b'bundle2-input-stream-interrupt: closing out of band context\n'
1270 b'bundle2-input-stream-interrupt: closing out of band context\n'
1271 )
1271 )
1272
1272
1273
1273
1274 class interruptoperation(object):
1274 class interruptoperation(object):
1275 """A limited operation to be use by part handler during interruption
1275 """A limited operation to be use by part handler during interruption
1276
1276
1277 It only have access to an ui object.
1277 It only have access to an ui object.
1278 """
1278 """
1279
1279
1280 def __init__(self, ui):
1280 def __init__(self, ui):
1281 self.ui = ui
1281 self.ui = ui
1282 self.reply = None
1282 self.reply = None
1283 self.captureoutput = False
1283 self.captureoutput = False
1284
1284
1285 @property
1285 @property
1286 def repo(self):
1286 def repo(self):
1287 raise error.ProgrammingError(b'no repo access from stream interruption')
1287 raise error.ProgrammingError(b'no repo access from stream interruption')
1288
1288
1289 def gettransaction(self):
1289 def gettransaction(self):
1290 raise TransactionUnavailable(b'no repo access from stream interruption')
1290 raise TransactionUnavailable(b'no repo access from stream interruption')
1291
1291
1292
1292
1293 def decodepayloadchunks(ui, fh):
1293 def decodepayloadchunks(ui, fh):
1294 """Reads bundle2 part payload data into chunks.
1294 """Reads bundle2 part payload data into chunks.
1295
1295
1296 Part payload data consists of framed chunks. This function takes
1296 Part payload data consists of framed chunks. This function takes
1297 a file handle and emits those chunks.
1297 a file handle and emits those chunks.
1298 """
1298 """
1299 dolog = ui.configbool(b'devel', b'bundle2.debug')
1299 dolog = ui.configbool(b'devel', b'bundle2.debug')
1300 debug = ui.debug
1300 debug = ui.debug
1301
1301
1302 headerstruct = struct.Struct(_fpayloadsize)
1302 headerstruct = struct.Struct(_fpayloadsize)
1303 headersize = headerstruct.size
1303 headersize = headerstruct.size
1304 unpack = headerstruct.unpack
1304 unpack = headerstruct.unpack
1305
1305
1306 readexactly = changegroup.readexactly
1306 readexactly = changegroup.readexactly
1307 read = fh.read
1307 read = fh.read
1308
1308
1309 chunksize = unpack(readexactly(fh, headersize))[0]
1309 chunksize = unpack(readexactly(fh, headersize))[0]
1310 indebug(ui, b'payload chunk size: %i' % chunksize)
1310 indebug(ui, b'payload chunk size: %i' % chunksize)
1311
1311
1312 # changegroup.readexactly() is inlined below for performance.
1312 # changegroup.readexactly() is inlined below for performance.
1313 while chunksize:
1313 while chunksize:
1314 if chunksize >= 0:
1314 if chunksize >= 0:
1315 s = read(chunksize)
1315 s = read(chunksize)
1316 if len(s) < chunksize:
1316 if len(s) < chunksize:
1317 raise error.Abort(
1317 raise error.Abort(
1318 _(
1318 _(
1319 b'stream ended unexpectedly '
1319 b'stream ended unexpectedly '
1320 b' (got %d bytes, expected %d)'
1320 b' (got %d bytes, expected %d)'
1321 )
1321 )
1322 % (len(s), chunksize)
1322 % (len(s), chunksize)
1323 )
1323 )
1324
1324
1325 yield s
1325 yield s
1326 elif chunksize == flaginterrupt:
1326 elif chunksize == flaginterrupt:
1327 # Interrupt "signal" detected. The regular stream is interrupted
1327 # Interrupt "signal" detected. The regular stream is interrupted
1328 # and a bundle2 part follows. Consume it.
1328 # and a bundle2 part follows. Consume it.
1329 interrupthandler(ui, fh)()
1329 interrupthandler(ui, fh)()
1330 else:
1330 else:
1331 raise error.BundleValueError(
1331 raise error.BundleValueError(
1332 b'negative payload chunk size: %s' % chunksize
1332 b'negative payload chunk size: %s' % chunksize
1333 )
1333 )
1334
1334
1335 s = read(headersize)
1335 s = read(headersize)
1336 if len(s) < headersize:
1336 if len(s) < headersize:
1337 raise error.Abort(
1337 raise error.Abort(
1338 _(b'stream ended unexpectedly (got %d bytes, expected %d)')
1338 _(b'stream ended unexpectedly (got %d bytes, expected %d)')
1339 % (len(s), chunksize)
1339 % (len(s), chunksize)
1340 )
1340 )
1341
1341
1342 chunksize = unpack(s)[0]
1342 chunksize = unpack(s)[0]
1343
1343
1344 # indebug() inlined for performance.
1344 # indebug() inlined for performance.
1345 if dolog:
1345 if dolog:
1346 debug(b'bundle2-input: payload chunk size: %i\n' % chunksize)
1346 debug(b'bundle2-input: payload chunk size: %i\n' % chunksize)
1347
1347
1348
1348
1349 class unbundlepart(unpackermixin):
1349 class unbundlepart(unpackermixin):
1350 """a bundle part read from a bundle"""
1350 """a bundle part read from a bundle"""
1351
1351
1352 def __init__(self, ui, header, fp):
1352 def __init__(self, ui, header, fp):
1353 super(unbundlepart, self).__init__(fp)
1353 super(unbundlepart, self).__init__(fp)
1354 self._seekable = util.safehasattr(fp, 'seek') and util.safehasattr(
1354 self._seekable = util.safehasattr(fp, 'seek') and util.safehasattr(
1355 fp, b'tell'
1355 fp, b'tell'
1356 )
1356 )
1357 self.ui = ui
1357 self.ui = ui
1358 # unbundle state attr
1358 # unbundle state attr
1359 self._headerdata = header
1359 self._headerdata = header
1360 self._headeroffset = 0
1360 self._headeroffset = 0
1361 self._initialized = False
1361 self._initialized = False
1362 self.consumed = False
1362 self.consumed = False
1363 # part data
1363 # part data
1364 self.id = None
1364 self.id = None
1365 self.type = None
1365 self.type = None
1366 self.mandatoryparams = None
1366 self.mandatoryparams = None
1367 self.advisoryparams = None
1367 self.advisoryparams = None
1368 self.params = None
1368 self.params = None
1369 self.mandatorykeys = ()
1369 self.mandatorykeys = ()
1370 self._readheader()
1370 self._readheader()
1371 self._mandatory = None
1371 self._mandatory = None
1372 self._pos = 0
1372 self._pos = 0
1373
1373
1374 def _fromheader(self, size):
1374 def _fromheader(self, size):
1375 """return the next <size> byte from the header"""
1375 """return the next <size> byte from the header"""
1376 offset = self._headeroffset
1376 offset = self._headeroffset
1377 data = self._headerdata[offset : (offset + size)]
1377 data = self._headerdata[offset : (offset + size)]
1378 self._headeroffset = offset + size
1378 self._headeroffset = offset + size
1379 return data
1379 return data
1380
1380
1381 def _unpackheader(self, format):
1381 def _unpackheader(self, format):
1382 """read given format from header
1382 """read given format from header
1383
1383
1384 This automatically compute the size of the format to read."""
1384 This automatically compute the size of the format to read."""
1385 data = self._fromheader(struct.calcsize(format))
1385 data = self._fromheader(struct.calcsize(format))
1386 return _unpack(format, data)
1386 return _unpack(format, data)
1387
1387
1388 def _initparams(self, mandatoryparams, advisoryparams):
1388 def _initparams(self, mandatoryparams, advisoryparams):
1389 """internal function to setup all logic related parameters"""
1389 """internal function to setup all logic related parameters"""
1390 # make it read only to prevent people touching it by mistake.
1390 # make it read only to prevent people touching it by mistake.
1391 self.mandatoryparams = tuple(mandatoryparams)
1391 self.mandatoryparams = tuple(mandatoryparams)
1392 self.advisoryparams = tuple(advisoryparams)
1392 self.advisoryparams = tuple(advisoryparams)
1393 # user friendly UI
1393 # user friendly UI
1394 self.params = util.sortdict(self.mandatoryparams)
1394 self.params = util.sortdict(self.mandatoryparams)
1395 self.params.update(self.advisoryparams)
1395 self.params.update(self.advisoryparams)
1396 self.mandatorykeys = frozenset(p[0] for p in mandatoryparams)
1396 self.mandatorykeys = frozenset(p[0] for p in mandatoryparams)
1397
1397
1398 def _readheader(self):
1398 def _readheader(self):
1399 """read the header and setup the object"""
1399 """read the header and setup the object"""
1400 typesize = self._unpackheader(_fparttypesize)[0]
1400 typesize = self._unpackheader(_fparttypesize)[0]
1401 self.type = self._fromheader(typesize)
1401 self.type = self._fromheader(typesize)
1402 indebug(self.ui, b'part type: "%s"' % self.type)
1402 indebug(self.ui, b'part type: "%s"' % self.type)
1403 self.id = self._unpackheader(_fpartid)[0]
1403 self.id = self._unpackheader(_fpartid)[0]
1404 indebug(self.ui, b'part id: "%s"' % pycompat.bytestr(self.id))
1404 indebug(self.ui, b'part id: "%s"' % pycompat.bytestr(self.id))
1405 # extract mandatory bit from type
1405 # extract mandatory bit from type
1406 self.mandatory = self.type != self.type.lower()
1406 self.mandatory = self.type != self.type.lower()
1407 self.type = self.type.lower()
1407 self.type = self.type.lower()
1408 ## reading parameters
1408 ## reading parameters
1409 # param count
1409 # param count
1410 mancount, advcount = self._unpackheader(_fpartparamcount)
1410 mancount, advcount = self._unpackheader(_fpartparamcount)
1411 indebug(self.ui, b'part parameters: %i' % (mancount + advcount))
1411 indebug(self.ui, b'part parameters: %i' % (mancount + advcount))
1412 # param size
1412 # param size
1413 fparamsizes = _makefpartparamsizes(mancount + advcount)
1413 fparamsizes = _makefpartparamsizes(mancount + advcount)
1414 paramsizes = self._unpackheader(fparamsizes)
1414 paramsizes = self._unpackheader(fparamsizes)
1415 # make it a list of couple again
1415 # make it a list of couple again
1416 paramsizes = list(zip(paramsizes[::2], paramsizes[1::2]))
1416 paramsizes = list(zip(paramsizes[::2], paramsizes[1::2]))
1417 # split mandatory from advisory
1417 # split mandatory from advisory
1418 mansizes = paramsizes[:mancount]
1418 mansizes = paramsizes[:mancount]
1419 advsizes = paramsizes[mancount:]
1419 advsizes = paramsizes[mancount:]
1420 # retrieve param value
1420 # retrieve param value
1421 manparams = []
1421 manparams = []
1422 for key, value in mansizes:
1422 for key, value in mansizes:
1423 manparams.append((self._fromheader(key), self._fromheader(value)))
1423 manparams.append((self._fromheader(key), self._fromheader(value)))
1424 advparams = []
1424 advparams = []
1425 for key, value in advsizes:
1425 for key, value in advsizes:
1426 advparams.append((self._fromheader(key), self._fromheader(value)))
1426 advparams.append((self._fromheader(key), self._fromheader(value)))
1427 self._initparams(manparams, advparams)
1427 self._initparams(manparams, advparams)
1428 ## part payload
1428 ## part payload
1429 self._payloadstream = util.chunkbuffer(self._payloadchunks())
1429 self._payloadstream = util.chunkbuffer(self._payloadchunks())
1430 # we read the data, tell it
1430 # we read the data, tell it
1431 self._initialized = True
1431 self._initialized = True
1432
1432
1433 def _payloadchunks(self):
1433 def _payloadchunks(self):
1434 """Generator of decoded chunks in the payload."""
1434 """Generator of decoded chunks in the payload."""
1435 return decodepayloadchunks(self.ui, self._fp)
1435 return decodepayloadchunks(self.ui, self._fp)
1436
1436
1437 def consume(self):
1437 def consume(self):
1438 """Read the part payload until completion.
1438 """Read the part payload until completion.
1439
1439
1440 By consuming the part data, the underlying stream read offset will
1440 By consuming the part data, the underlying stream read offset will
1441 be advanced to the next part (or end of stream).
1441 be advanced to the next part (or end of stream).
1442 """
1442 """
1443 if self.consumed:
1443 if self.consumed:
1444 return
1444 return
1445
1445
1446 chunk = self.read(32768)
1446 chunk = self.read(32768)
1447 while chunk:
1447 while chunk:
1448 self._pos += len(chunk)
1448 self._pos += len(chunk)
1449 chunk = self.read(32768)
1449 chunk = self.read(32768)
1450
1450
1451 def read(self, size=None):
1451 def read(self, size=None):
1452 """read payload data"""
1452 """read payload data"""
1453 if not self._initialized:
1453 if not self._initialized:
1454 self._readheader()
1454 self._readheader()
1455 if size is None:
1455 if size is None:
1456 data = self._payloadstream.read()
1456 data = self._payloadstream.read()
1457 else:
1457 else:
1458 data = self._payloadstream.read(size)
1458 data = self._payloadstream.read(size)
1459 self._pos += len(data)
1459 self._pos += len(data)
1460 if size is None or len(data) < size:
1460 if size is None or len(data) < size:
1461 if not self.consumed and self._pos:
1461 if not self.consumed and self._pos:
1462 self.ui.debug(
1462 self.ui.debug(
1463 b'bundle2-input-part: total payload size %i\n' % self._pos
1463 b'bundle2-input-part: total payload size %i\n' % self._pos
1464 )
1464 )
1465 self.consumed = True
1465 self.consumed = True
1466 return data
1466 return data
1467
1467
1468
1468
1469 class seekableunbundlepart(unbundlepart):
1469 class seekableunbundlepart(unbundlepart):
1470 """A bundle2 part in a bundle that is seekable.
1470 """A bundle2 part in a bundle that is seekable.
1471
1471
1472 Regular ``unbundlepart`` instances can only be read once. This class
1472 Regular ``unbundlepart`` instances can only be read once. This class
1473 extends ``unbundlepart`` to enable bi-directional seeking within the
1473 extends ``unbundlepart`` to enable bi-directional seeking within the
1474 part.
1474 part.
1475
1475
1476 Bundle2 part data consists of framed chunks. Offsets when seeking
1476 Bundle2 part data consists of framed chunks. Offsets when seeking
1477 refer to the decoded data, not the offsets in the underlying bundle2
1477 refer to the decoded data, not the offsets in the underlying bundle2
1478 stream.
1478 stream.
1479
1479
1480 To facilitate quickly seeking within the decoded data, instances of this
1480 To facilitate quickly seeking within the decoded data, instances of this
1481 class maintain a mapping between offsets in the underlying stream and
1481 class maintain a mapping between offsets in the underlying stream and
1482 the decoded payload. This mapping will consume memory in proportion
1482 the decoded payload. This mapping will consume memory in proportion
1483 to the number of chunks within the payload (which almost certainly
1483 to the number of chunks within the payload (which almost certainly
1484 increases in proportion with the size of the part).
1484 increases in proportion with the size of the part).
1485 """
1485 """
1486
1486
1487 def __init__(self, ui, header, fp):
1487 def __init__(self, ui, header, fp):
1488 # (payload, file) offsets for chunk starts.
1488 # (payload, file) offsets for chunk starts.
1489 self._chunkindex = []
1489 self._chunkindex = []
1490
1490
1491 super(seekableunbundlepart, self).__init__(ui, header, fp)
1491 super(seekableunbundlepart, self).__init__(ui, header, fp)
1492
1492
1493 def _payloadchunks(self, chunknum=0):
1493 def _payloadchunks(self, chunknum=0):
1494 '''seek to specified chunk and start yielding data'''
1494 '''seek to specified chunk and start yielding data'''
1495 if len(self._chunkindex) == 0:
1495 if len(self._chunkindex) == 0:
1496 assert chunknum == 0, b'Must start with chunk 0'
1496 assert chunknum == 0, b'Must start with chunk 0'
1497 self._chunkindex.append((0, self._tellfp()))
1497 self._chunkindex.append((0, self._tellfp()))
1498 else:
1498 else:
1499 assert chunknum < len(self._chunkindex), (
1499 assert chunknum < len(self._chunkindex), (
1500 b'Unknown chunk %d' % chunknum
1500 b'Unknown chunk %d' % chunknum
1501 )
1501 )
1502 self._seekfp(self._chunkindex[chunknum][1])
1502 self._seekfp(self._chunkindex[chunknum][1])
1503
1503
1504 pos = self._chunkindex[chunknum][0]
1504 pos = self._chunkindex[chunknum][0]
1505
1505
1506 for chunk in decodepayloadchunks(self.ui, self._fp):
1506 for chunk in decodepayloadchunks(self.ui, self._fp):
1507 chunknum += 1
1507 chunknum += 1
1508 pos += len(chunk)
1508 pos += len(chunk)
1509 if chunknum == len(self._chunkindex):
1509 if chunknum == len(self._chunkindex):
1510 self._chunkindex.append((pos, self._tellfp()))
1510 self._chunkindex.append((pos, self._tellfp()))
1511
1511
1512 yield chunk
1512 yield chunk
1513
1513
1514 def _findchunk(self, pos):
1514 def _findchunk(self, pos):
1515 '''for a given payload position, return a chunk number and offset'''
1515 '''for a given payload position, return a chunk number and offset'''
1516 for chunk, (ppos, fpos) in enumerate(self._chunkindex):
1516 for chunk, (ppos, fpos) in enumerate(self._chunkindex):
1517 if ppos == pos:
1517 if ppos == pos:
1518 return chunk, 0
1518 return chunk, 0
1519 elif ppos > pos:
1519 elif ppos > pos:
1520 return chunk - 1, pos - self._chunkindex[chunk - 1][0]
1520 return chunk - 1, pos - self._chunkindex[chunk - 1][0]
1521 raise ValueError(b'Unknown chunk')
1521 raise ValueError(b'Unknown chunk')
1522
1522
1523 def tell(self):
1523 def tell(self):
1524 return self._pos
1524 return self._pos
1525
1525
1526 def seek(self, offset, whence=os.SEEK_SET):
1526 def seek(self, offset, whence=os.SEEK_SET):
1527 if whence == os.SEEK_SET:
1527 if whence == os.SEEK_SET:
1528 newpos = offset
1528 newpos = offset
1529 elif whence == os.SEEK_CUR:
1529 elif whence == os.SEEK_CUR:
1530 newpos = self._pos + offset
1530 newpos = self._pos + offset
1531 elif whence == os.SEEK_END:
1531 elif whence == os.SEEK_END:
1532 if not self.consumed:
1532 if not self.consumed:
1533 # Can't use self.consume() here because it advances self._pos.
1533 # Can't use self.consume() here because it advances self._pos.
1534 chunk = self.read(32768)
1534 chunk = self.read(32768)
1535 while chunk:
1535 while chunk:
1536 chunk = self.read(32768)
1536 chunk = self.read(32768)
1537 newpos = self._chunkindex[-1][0] - offset
1537 newpos = self._chunkindex[-1][0] - offset
1538 else:
1538 else:
1539 raise ValueError(b'Unknown whence value: %r' % (whence,))
1539 raise ValueError(b'Unknown whence value: %r' % (whence,))
1540
1540
1541 if newpos > self._chunkindex[-1][0] and not self.consumed:
1541 if newpos > self._chunkindex[-1][0] and not self.consumed:
1542 # Can't use self.consume() here because it advances self._pos.
1542 # Can't use self.consume() here because it advances self._pos.
1543 chunk = self.read(32768)
1543 chunk = self.read(32768)
1544 while chunk:
1544 while chunk:
1545 chunk = self.read(32668)
1545 chunk = self.read(32668)
1546
1546
1547 if not 0 <= newpos <= self._chunkindex[-1][0]:
1547 if not 0 <= newpos <= self._chunkindex[-1][0]:
1548 raise ValueError(b'Offset out of range')
1548 raise ValueError(b'Offset out of range')
1549
1549
1550 if self._pos != newpos:
1550 if self._pos != newpos:
1551 chunk, internaloffset = self._findchunk(newpos)
1551 chunk, internaloffset = self._findchunk(newpos)
1552 self._payloadstream = util.chunkbuffer(self._payloadchunks(chunk))
1552 self._payloadstream = util.chunkbuffer(self._payloadchunks(chunk))
1553 adjust = self.read(internaloffset)
1553 adjust = self.read(internaloffset)
1554 if len(adjust) != internaloffset:
1554 if len(adjust) != internaloffset:
1555 raise error.Abort(_(b'Seek failed\n'))
1555 raise error.Abort(_(b'Seek failed\n'))
1556 self._pos = newpos
1556 self._pos = newpos
1557
1557
1558 def _seekfp(self, offset, whence=0):
1558 def _seekfp(self, offset, whence=0):
1559 """move the underlying file pointer
1559 """move the underlying file pointer
1560
1560
1561 This method is meant for internal usage by the bundle2 protocol only.
1561 This method is meant for internal usage by the bundle2 protocol only.
1562 They directly manipulate the low level stream including bundle2 level
1562 They directly manipulate the low level stream including bundle2 level
1563 instruction.
1563 instruction.
1564
1564
1565 Do not use it to implement higher-level logic or methods."""
1565 Do not use it to implement higher-level logic or methods."""
1566 if self._seekable:
1566 if self._seekable:
1567 return self._fp.seek(offset, whence)
1567 return self._fp.seek(offset, whence)
1568 else:
1568 else:
1569 raise NotImplementedError(_(b'File pointer is not seekable'))
1569 raise NotImplementedError(_(b'File pointer is not seekable'))
1570
1570
1571 def _tellfp(self):
1571 def _tellfp(self):
1572 """return the file offset, or None if file is not seekable
1572 """return the file offset, or None if file is not seekable
1573
1573
1574 This method is meant for internal usage by the bundle2 protocol only.
1574 This method is meant for internal usage by the bundle2 protocol only.
1575 They directly manipulate the low level stream including bundle2 level
1575 They directly manipulate the low level stream including bundle2 level
1576 instruction.
1576 instruction.
1577
1577
1578 Do not use it to implement higher-level logic or methods."""
1578 Do not use it to implement higher-level logic or methods."""
1579 if self._seekable:
1579 if self._seekable:
1580 try:
1580 try:
1581 return self._fp.tell()
1581 return self._fp.tell()
1582 except IOError as e:
1582 except IOError as e:
1583 if e.errno == errno.ESPIPE:
1583 if e.errno == errno.ESPIPE:
1584 self._seekable = False
1584 self._seekable = False
1585 else:
1585 else:
1586 raise
1586 raise
1587 return None
1587 return None
1588
1588
1589
1589
1590 # These are only the static capabilities.
1590 # These are only the static capabilities.
1591 # Check the 'getrepocaps' function for the rest.
1591 # Check the 'getrepocaps' function for the rest.
1592 capabilities = {
1592 capabilities = {
1593 b'HG20': (),
1593 b'HG20': (),
1594 b'bookmarks': (),
1594 b'bookmarks': (),
1595 b'error': (b'abort', b'unsupportedcontent', b'pushraced', b'pushkey'),
1595 b'error': (b'abort', b'unsupportedcontent', b'pushraced', b'pushkey'),
1596 b'listkeys': (),
1596 b'listkeys': (),
1597 b'pushkey': (),
1597 b'pushkey': (),
1598 b'digests': tuple(sorted(util.DIGESTS.keys())),
1598 b'digests': tuple(sorted(util.DIGESTS.keys())),
1599 b'remote-changegroup': (b'http', b'https'),
1599 b'remote-changegroup': (b'http', b'https'),
1600 b'hgtagsfnodes': (),
1600 b'hgtagsfnodes': (),
1601 b'rev-branch-cache': (),
1602 b'phases': (b'heads',),
1601 b'phases': (b'heads',),
1603 b'stream': (b'v2',),
1602 b'stream': (b'v2',),
1604 }
1603 }
1605
1604
1606
1605
1607 def getrepocaps(repo, allowpushback=False, role=None):
1606 def getrepocaps(repo, allowpushback=False, role=None):
1608 """return the bundle2 capabilities for a given repo
1607 """return the bundle2 capabilities for a given repo
1609
1608
1610 Exists to allow extensions (like evolution) to mutate the capabilities.
1609 Exists to allow extensions (like evolution) to mutate the capabilities.
1611
1610
1612 The returned value is used for servers advertising their capabilities as
1611 The returned value is used for servers advertising their capabilities as
1613 well as clients advertising their capabilities to servers as part of
1612 well as clients advertising their capabilities to servers as part of
1614 bundle2 requests. The ``role`` argument specifies which is which.
1613 bundle2 requests. The ``role`` argument specifies which is which.
1615 """
1614 """
1616 if role not in (b'client', b'server'):
1615 if role not in (b'client', b'server'):
1617 raise error.ProgrammingError(b'role argument must be client or server')
1616 raise error.ProgrammingError(b'role argument must be client or server')
1618
1617
1619 caps = capabilities.copy()
1618 caps = capabilities.copy()
1620 caps[b'changegroup'] = tuple(
1619 caps[b'changegroup'] = tuple(
1621 sorted(changegroup.supportedincomingversions(repo))
1620 sorted(changegroup.supportedincomingversions(repo))
1622 )
1621 )
1623 if obsolete.isenabled(repo, obsolete.exchangeopt):
1622 if obsolete.isenabled(repo, obsolete.exchangeopt):
1624 supportedformat = tuple(b'V%i' % v for v in obsolete.formats)
1623 supportedformat = tuple(b'V%i' % v for v in obsolete.formats)
1625 caps[b'obsmarkers'] = supportedformat
1624 caps[b'obsmarkers'] = supportedformat
1626 if allowpushback:
1625 if allowpushback:
1627 caps[b'pushback'] = ()
1626 caps[b'pushback'] = ()
1628 cpmode = repo.ui.config(b'server', b'concurrent-push-mode')
1627 cpmode = repo.ui.config(b'server', b'concurrent-push-mode')
1629 if cpmode == b'check-related':
1628 if cpmode == b'check-related':
1630 caps[b'checkheads'] = (b'related',)
1629 caps[b'checkheads'] = (b'related',)
1631 if b'phases' in repo.ui.configlist(b'devel', b'legacy.exchange'):
1630 if b'phases' in repo.ui.configlist(b'devel', b'legacy.exchange'):
1632 caps.pop(b'phases')
1631 caps.pop(b'phases')
1633
1632
1634 # Don't advertise stream clone support in server mode if not configured.
1633 # Don't advertise stream clone support in server mode if not configured.
1635 if role == b'server':
1634 if role == b'server':
1636 streamsupported = repo.ui.configbool(
1635 streamsupported = repo.ui.configbool(
1637 b'server', b'uncompressed', untrusted=True
1636 b'server', b'uncompressed', untrusted=True
1638 )
1637 )
1639 featuresupported = repo.ui.configbool(b'server', b'bundle2.stream')
1638 featuresupported = repo.ui.configbool(b'server', b'bundle2.stream')
1640
1639
1641 if not streamsupported or not featuresupported:
1640 if not streamsupported or not featuresupported:
1642 caps.pop(b'stream')
1641 caps.pop(b'stream')
1643 # Else always advertise support on client, because payload support
1642 # Else always advertise support on client, because payload support
1644 # should always be advertised.
1643 # should always be advertised.
1645
1644
1645 # b'rev-branch-cache is no longer advertised, but still supported
1646 # for legacy clients.
1647
1646 return caps
1648 return caps
1647
1649
1648
1650
1649 def bundle2caps(remote):
1651 def bundle2caps(remote):
1650 """return the bundle capabilities of a peer as dict"""
1652 """return the bundle capabilities of a peer as dict"""
1651 raw = remote.capable(b'bundle2')
1653 raw = remote.capable(b'bundle2')
1652 if not raw and raw != b'':
1654 if not raw and raw != b'':
1653 return {}
1655 return {}
1654 capsblob = urlreq.unquote(remote.capable(b'bundle2'))
1656 capsblob = urlreq.unquote(remote.capable(b'bundle2'))
1655 return decodecaps(capsblob)
1657 return decodecaps(capsblob)
1656
1658
1657
1659
1658 def obsmarkersversion(caps):
1660 def obsmarkersversion(caps):
1659 """extract the list of supported obsmarkers versions from a bundle2caps dict"""
1661 """extract the list of supported obsmarkers versions from a bundle2caps dict"""
1660 obscaps = caps.get(b'obsmarkers', ())
1662 obscaps = caps.get(b'obsmarkers', ())
1661 return [int(c[1:]) for c in obscaps if c.startswith(b'V')]
1663 return [int(c[1:]) for c in obscaps if c.startswith(b'V')]
1662
1664
1663
1665
1664 def writenewbundle(
1666 def writenewbundle(
1665 ui,
1667 ui,
1666 repo,
1668 repo,
1667 source,
1669 source,
1668 filename,
1670 filename,
1669 bundletype,
1671 bundletype,
1670 outgoing,
1672 outgoing,
1671 opts,
1673 opts,
1672 vfs=None,
1674 vfs=None,
1673 compression=None,
1675 compression=None,
1674 compopts=None,
1676 compopts=None,
1675 ):
1677 ):
1676 if bundletype.startswith(b'HG10'):
1678 if bundletype.startswith(b'HG10'):
1677 cg = changegroup.makechangegroup(repo, outgoing, b'01', source)
1679 cg = changegroup.makechangegroup(repo, outgoing, b'01', source)
1678 return writebundle(
1680 return writebundle(
1679 ui,
1681 ui,
1680 cg,
1682 cg,
1681 filename,
1683 filename,
1682 bundletype,
1684 bundletype,
1683 vfs=vfs,
1685 vfs=vfs,
1684 compression=compression,
1686 compression=compression,
1685 compopts=compopts,
1687 compopts=compopts,
1686 )
1688 )
1687 elif not bundletype.startswith(b'HG20'):
1689 elif not bundletype.startswith(b'HG20'):
1688 raise error.ProgrammingError(b'unknown bundle type: %s' % bundletype)
1690 raise error.ProgrammingError(b'unknown bundle type: %s' % bundletype)
1689
1691
1690 caps = {}
1692 caps = {}
1691 if b'obsolescence' in opts:
1693 if b'obsolescence' in opts:
1692 caps[b'obsmarkers'] = (b'V1',)
1694 caps[b'obsmarkers'] = (b'V1',)
1693 bundle = bundle20(ui, caps)
1695 bundle = bundle20(ui, caps)
1694 bundle.setcompression(compression, compopts)
1696 bundle.setcompression(compression, compopts)
1695 _addpartsfromopts(ui, repo, bundle, source, outgoing, opts)
1697 _addpartsfromopts(ui, repo, bundle, source, outgoing, opts)
1696 chunkiter = bundle.getchunks()
1698 chunkiter = bundle.getchunks()
1697
1699
1698 return changegroup.writechunks(ui, chunkiter, filename, vfs=vfs)
1700 return changegroup.writechunks(ui, chunkiter, filename, vfs=vfs)
1699
1701
1700
1702
1701 def _addpartsfromopts(ui, repo, bundler, source, outgoing, opts):
1703 def _addpartsfromopts(ui, repo, bundler, source, outgoing, opts):
1702 # We should eventually reconcile this logic with the one behind
1704 # We should eventually reconcile this logic with the one behind
1703 # 'exchange.getbundle2partsgenerator'.
1705 # 'exchange.getbundle2partsgenerator'.
1704 #
1706 #
1705 # The type of input from 'getbundle' and 'writenewbundle' are a bit
1707 # The type of input from 'getbundle' and 'writenewbundle' are a bit
1706 # different right now. So we keep them separated for now for the sake of
1708 # different right now. So we keep them separated for now for the sake of
1707 # simplicity.
1709 # simplicity.
1708
1710
1709 # we might not always want a changegroup in such bundle, for example in
1711 # we might not always want a changegroup in such bundle, for example in
1710 # stream bundles
1712 # stream bundles
1711 if opts.get(b'changegroup', True):
1713 if opts.get(b'changegroup', True):
1712 cgversion = opts.get(b'cg.version')
1714 cgversion = opts.get(b'cg.version')
1713 if cgversion is None:
1715 if cgversion is None:
1714 cgversion = changegroup.safeversion(repo)
1716 cgversion = changegroup.safeversion(repo)
1715 cg = changegroup.makechangegroup(repo, outgoing, cgversion, source)
1717 cg = changegroup.makechangegroup(repo, outgoing, cgversion, source)
1716 part = bundler.newpart(b'changegroup', data=cg.getchunks())
1718 part = bundler.newpart(b'changegroup', data=cg.getchunks())
1717 part.addparam(b'version', cg.version)
1719 part.addparam(b'version', cg.version)
1718 if b'clcount' in cg.extras:
1720 if b'clcount' in cg.extras:
1719 part.addparam(
1721 part.addparam(
1720 b'nbchanges', b'%d' % cg.extras[b'clcount'], mandatory=False
1722 b'nbchanges', b'%d' % cg.extras[b'clcount'], mandatory=False
1721 )
1723 )
1722 if opts.get(b'phases') and repo.revs(
1724 if opts.get(b'phases') and repo.revs(
1723 b'%ln and secret()', outgoing.ancestorsof
1725 b'%ln and secret()', outgoing.ancestorsof
1724 ):
1726 ):
1725 part.addparam(
1727 part.addparam(
1726 b'targetphase', b'%d' % phases.secret, mandatory=False
1728 b'targetphase', b'%d' % phases.secret, mandatory=False
1727 )
1729 )
1728 if b'exp-sidedata-flag' in repo.requirements:
1730 if b'exp-sidedata-flag' in repo.requirements:
1729 part.addparam(b'exp-sidedata', b'1')
1731 part.addparam(b'exp-sidedata', b'1')
1730
1732
1731 if opts.get(b'streamv2', False):
1733 if opts.get(b'streamv2', False):
1732 addpartbundlestream2(bundler, repo, stream=True)
1734 addpartbundlestream2(bundler, repo, stream=True)
1733
1735
1734 if opts.get(b'tagsfnodescache', True):
1736 if opts.get(b'tagsfnodescache', True):
1735 addparttagsfnodescache(repo, bundler, outgoing)
1737 addparttagsfnodescache(repo, bundler, outgoing)
1736
1738
1737 if opts.get(b'revbranchcache', True):
1739 if opts.get(b'revbranchcache', True):
1738 addpartrevbranchcache(repo, bundler, outgoing)
1740 addpartrevbranchcache(repo, bundler, outgoing)
1739
1741
1740 if opts.get(b'obsolescence', False):
1742 if opts.get(b'obsolescence', False):
1741 obsmarkers = repo.obsstore.relevantmarkers(outgoing.missing)
1743 obsmarkers = repo.obsstore.relevantmarkers(outgoing.missing)
1742 buildobsmarkerspart(
1744 buildobsmarkerspart(
1743 bundler,
1745 bundler,
1744 obsmarkers,
1746 obsmarkers,
1745 mandatory=opts.get(b'obsolescence-mandatory', True),
1747 mandatory=opts.get(b'obsolescence-mandatory', True),
1746 )
1748 )
1747
1749
1748 if opts.get(b'phases', False):
1750 if opts.get(b'phases', False):
1749 headsbyphase = phases.subsetphaseheads(repo, outgoing.missing)
1751 headsbyphase = phases.subsetphaseheads(repo, outgoing.missing)
1750 phasedata = phases.binaryencode(headsbyphase)
1752 phasedata = phases.binaryencode(headsbyphase)
1751 bundler.newpart(b'phase-heads', data=phasedata)
1753 bundler.newpart(b'phase-heads', data=phasedata)
1752
1754
1753
1755
1754 def addparttagsfnodescache(repo, bundler, outgoing):
1756 def addparttagsfnodescache(repo, bundler, outgoing):
1755 # we include the tags fnode cache for the bundle changeset
1757 # we include the tags fnode cache for the bundle changeset
1756 # (as an optional parts)
1758 # (as an optional parts)
1757 cache = tags.hgtagsfnodescache(repo.unfiltered())
1759 cache = tags.hgtagsfnodescache(repo.unfiltered())
1758 chunks = []
1760 chunks = []
1759
1761
1760 # .hgtags fnodes are only relevant for head changesets. While we could
1762 # .hgtags fnodes are only relevant for head changesets. While we could
1761 # transfer values for all known nodes, there will likely be little to
1763 # transfer values for all known nodes, there will likely be little to
1762 # no benefit.
1764 # no benefit.
1763 #
1765 #
1764 # We don't bother using a generator to produce output data because
1766 # We don't bother using a generator to produce output data because
1765 # a) we only have 40 bytes per head and even esoteric numbers of heads
1767 # a) we only have 40 bytes per head and even esoteric numbers of heads
1766 # consume little memory (1M heads is 40MB) b) we don't want to send the
1768 # consume little memory (1M heads is 40MB) b) we don't want to send the
1767 # part if we don't have entries and knowing if we have entries requires
1769 # part if we don't have entries and knowing if we have entries requires
1768 # cache lookups.
1770 # cache lookups.
1769 for node in outgoing.ancestorsof:
1771 for node in outgoing.ancestorsof:
1770 # Don't compute missing, as this may slow down serving.
1772 # Don't compute missing, as this may slow down serving.
1771 fnode = cache.getfnode(node, computemissing=False)
1773 fnode = cache.getfnode(node, computemissing=False)
1772 if fnode:
1774 if fnode:
1773 chunks.extend([node, fnode])
1775 chunks.extend([node, fnode])
1774
1776
1775 if chunks:
1777 if chunks:
1776 bundler.newpart(b'hgtagsfnodes', data=b''.join(chunks))
1778 bundler.newpart(b'hgtagsfnodes', data=b''.join(chunks))
1777
1779
1778
1780
1779 def addpartrevbranchcache(repo, bundler, outgoing):
1781 def addpartrevbranchcache(repo, bundler, outgoing):
1780 # we include the rev branch cache for the bundle changeset
1782 # we include the rev branch cache for the bundle changeset
1781 # (as an optional parts)
1783 # (as an optional parts)
1782 cache = repo.revbranchcache()
1784 cache = repo.revbranchcache()
1783 cl = repo.unfiltered().changelog
1785 cl = repo.unfiltered().changelog
1784 branchesdata = collections.defaultdict(lambda: (set(), set()))
1786 branchesdata = collections.defaultdict(lambda: (set(), set()))
1785 for node in outgoing.missing:
1787 for node in outgoing.missing:
1786 branch, close = cache.branchinfo(cl.rev(node))
1788 branch, close = cache.branchinfo(cl.rev(node))
1787 branchesdata[branch][close].add(node)
1789 branchesdata[branch][close].add(node)
1788
1790
1789 def generate():
1791 def generate():
1790 for branch, (nodes, closed) in sorted(branchesdata.items()):
1792 for branch, (nodes, closed) in sorted(branchesdata.items()):
1791 utf8branch = encoding.fromlocal(branch)
1793 utf8branch = encoding.fromlocal(branch)
1792 yield rbcstruct.pack(len(utf8branch), len(nodes), len(closed))
1794 yield rbcstruct.pack(len(utf8branch), len(nodes), len(closed))
1793 yield utf8branch
1795 yield utf8branch
1794 for n in sorted(nodes):
1796 for n in sorted(nodes):
1795 yield n
1797 yield n
1796 for n in sorted(closed):
1798 for n in sorted(closed):
1797 yield n
1799 yield n
1798
1800
1799 bundler.newpart(b'cache:rev-branch-cache', data=generate(), mandatory=False)
1801 bundler.newpart(b'cache:rev-branch-cache', data=generate(), mandatory=False)
1800
1802
1801
1803
1802 def _formatrequirementsspec(requirements):
1804 def _formatrequirementsspec(requirements):
1803 requirements = [req for req in requirements if req != b"shared"]
1805 requirements = [req for req in requirements if req != b"shared"]
1804 return urlreq.quote(b','.join(sorted(requirements)))
1806 return urlreq.quote(b','.join(sorted(requirements)))
1805
1807
1806
1808
1807 def _formatrequirementsparams(requirements):
1809 def _formatrequirementsparams(requirements):
1808 requirements = _formatrequirementsspec(requirements)
1810 requirements = _formatrequirementsspec(requirements)
1809 params = b"%s%s" % (urlreq.quote(b"requirements="), requirements)
1811 params = b"%s%s" % (urlreq.quote(b"requirements="), requirements)
1810 return params
1812 return params
1811
1813
1812
1814
1813 def addpartbundlestream2(bundler, repo, **kwargs):
1815 def addpartbundlestream2(bundler, repo, **kwargs):
1814 if not kwargs.get('stream', False):
1816 if not kwargs.get('stream', False):
1815 return
1817 return
1816
1818
1817 if not streamclone.allowservergeneration(repo):
1819 if not streamclone.allowservergeneration(repo):
1818 raise error.Abort(
1820 raise error.Abort(
1819 _(
1821 _(
1820 b'stream data requested but server does not allow '
1822 b'stream data requested but server does not allow '
1821 b'this feature'
1823 b'this feature'
1822 ),
1824 ),
1823 hint=_(
1825 hint=_(
1824 b'well-behaved clients should not be '
1826 b'well-behaved clients should not be '
1825 b'requesting stream data from servers not '
1827 b'requesting stream data from servers not '
1826 b'advertising it; the client may be buggy'
1828 b'advertising it; the client may be buggy'
1827 ),
1829 ),
1828 )
1830 )
1829
1831
1830 # Stream clones don't compress well. And compression undermines a
1832 # Stream clones don't compress well. And compression undermines a
1831 # goal of stream clones, which is to be fast. Communicate the desire
1833 # goal of stream clones, which is to be fast. Communicate the desire
1832 # to avoid compression to consumers of the bundle.
1834 # to avoid compression to consumers of the bundle.
1833 bundler.prefercompressed = False
1835 bundler.prefercompressed = False
1834
1836
1835 # get the includes and excludes
1837 # get the includes and excludes
1836 includepats = kwargs.get('includepats')
1838 includepats = kwargs.get('includepats')
1837 excludepats = kwargs.get('excludepats')
1839 excludepats = kwargs.get('excludepats')
1838
1840
1839 narrowstream = repo.ui.configbool(
1841 narrowstream = repo.ui.configbool(
1840 b'experimental', b'server.stream-narrow-clones'
1842 b'experimental', b'server.stream-narrow-clones'
1841 )
1843 )
1842
1844
1843 if (includepats or excludepats) and not narrowstream:
1845 if (includepats or excludepats) and not narrowstream:
1844 raise error.Abort(_(b'server does not support narrow stream clones'))
1846 raise error.Abort(_(b'server does not support narrow stream clones'))
1845
1847
1846 includeobsmarkers = False
1848 includeobsmarkers = False
1847 if repo.obsstore:
1849 if repo.obsstore:
1848 remoteversions = obsmarkersversion(bundler.capabilities)
1850 remoteversions = obsmarkersversion(bundler.capabilities)
1849 if not remoteversions:
1851 if not remoteversions:
1850 raise error.Abort(
1852 raise error.Abort(
1851 _(
1853 _(
1852 b'server has obsolescence markers, but client '
1854 b'server has obsolescence markers, but client '
1853 b'cannot receive them via stream clone'
1855 b'cannot receive them via stream clone'
1854 )
1856 )
1855 )
1857 )
1856 elif repo.obsstore._version in remoteversions:
1858 elif repo.obsstore._version in remoteversions:
1857 includeobsmarkers = True
1859 includeobsmarkers = True
1858
1860
1859 filecount, bytecount, it = streamclone.generatev2(
1861 filecount, bytecount, it = streamclone.generatev2(
1860 repo, includepats, excludepats, includeobsmarkers
1862 repo, includepats, excludepats, includeobsmarkers
1861 )
1863 )
1862 requirements = _formatrequirementsspec(repo.requirements)
1864 requirements = _formatrequirementsspec(repo.requirements)
1863 part = bundler.newpart(b'stream2', data=it)
1865 part = bundler.newpart(b'stream2', data=it)
1864 part.addparam(b'bytecount', b'%d' % bytecount, mandatory=True)
1866 part.addparam(b'bytecount', b'%d' % bytecount, mandatory=True)
1865 part.addparam(b'filecount', b'%d' % filecount, mandatory=True)
1867 part.addparam(b'filecount', b'%d' % filecount, mandatory=True)
1866 part.addparam(b'requirements', requirements, mandatory=True)
1868 part.addparam(b'requirements', requirements, mandatory=True)
1867
1869
1868
1870
1869 def buildobsmarkerspart(bundler, markers, mandatory=True):
1871 def buildobsmarkerspart(bundler, markers, mandatory=True):
1870 """add an obsmarker part to the bundler with <markers>
1872 """add an obsmarker part to the bundler with <markers>
1871
1873
1872 No part is created if markers is empty.
1874 No part is created if markers is empty.
1873 Raises ValueError if the bundler doesn't support any known obsmarker format.
1875 Raises ValueError if the bundler doesn't support any known obsmarker format.
1874 """
1876 """
1875 if not markers:
1877 if not markers:
1876 return None
1878 return None
1877
1879
1878 remoteversions = obsmarkersversion(bundler.capabilities)
1880 remoteversions = obsmarkersversion(bundler.capabilities)
1879 version = obsolete.commonversion(remoteversions)
1881 version = obsolete.commonversion(remoteversions)
1880 if version is None:
1882 if version is None:
1881 raise ValueError(b'bundler does not support common obsmarker format')
1883 raise ValueError(b'bundler does not support common obsmarker format')
1882 stream = obsolete.encodemarkers(markers, True, version=version)
1884 stream = obsolete.encodemarkers(markers, True, version=version)
1883 return bundler.newpart(b'obsmarkers', data=stream, mandatory=mandatory)
1885 return bundler.newpart(b'obsmarkers', data=stream, mandatory=mandatory)
1884
1886
1885
1887
1886 def writebundle(
1888 def writebundle(
1887 ui, cg, filename, bundletype, vfs=None, compression=None, compopts=None
1889 ui, cg, filename, bundletype, vfs=None, compression=None, compopts=None
1888 ):
1890 ):
1889 """Write a bundle file and return its filename.
1891 """Write a bundle file and return its filename.
1890
1892
1891 Existing files will not be overwritten.
1893 Existing files will not be overwritten.
1892 If no filename is specified, a temporary file is created.
1894 If no filename is specified, a temporary file is created.
1893 bz2 compression can be turned off.
1895 bz2 compression can be turned off.
1894 The bundle file will be deleted in case of errors.
1896 The bundle file will be deleted in case of errors.
1895 """
1897 """
1896
1898
1897 if bundletype == b"HG20":
1899 if bundletype == b"HG20":
1898 bundle = bundle20(ui)
1900 bundle = bundle20(ui)
1899 bundle.setcompression(compression, compopts)
1901 bundle.setcompression(compression, compopts)
1900 part = bundle.newpart(b'changegroup', data=cg.getchunks())
1902 part = bundle.newpart(b'changegroup', data=cg.getchunks())
1901 part.addparam(b'version', cg.version)
1903 part.addparam(b'version', cg.version)
1902 if b'clcount' in cg.extras:
1904 if b'clcount' in cg.extras:
1903 part.addparam(
1905 part.addparam(
1904 b'nbchanges', b'%d' % cg.extras[b'clcount'], mandatory=False
1906 b'nbchanges', b'%d' % cg.extras[b'clcount'], mandatory=False
1905 )
1907 )
1906 chunkiter = bundle.getchunks()
1908 chunkiter = bundle.getchunks()
1907 else:
1909 else:
1908 # compression argument is only for the bundle2 case
1910 # compression argument is only for the bundle2 case
1909 assert compression is None
1911 assert compression is None
1910 if cg.version != b'01':
1912 if cg.version != b'01':
1911 raise error.Abort(
1913 raise error.Abort(
1912 _(b'old bundle types only supports v1 changegroups')
1914 _(b'old bundle types only supports v1 changegroups')
1913 )
1915 )
1914 header, comp = bundletypes[bundletype]
1916 header, comp = bundletypes[bundletype]
1915 if comp not in util.compengines.supportedbundletypes:
1917 if comp not in util.compengines.supportedbundletypes:
1916 raise error.Abort(_(b'unknown stream compression type: %s') % comp)
1918 raise error.Abort(_(b'unknown stream compression type: %s') % comp)
1917 compengine = util.compengines.forbundletype(comp)
1919 compengine = util.compengines.forbundletype(comp)
1918
1920
1919 def chunkiter():
1921 def chunkiter():
1920 yield header
1922 yield header
1921 for chunk in compengine.compressstream(cg.getchunks(), compopts):
1923 for chunk in compengine.compressstream(cg.getchunks(), compopts):
1922 yield chunk
1924 yield chunk
1923
1925
1924 chunkiter = chunkiter()
1926 chunkiter = chunkiter()
1925
1927
1926 # parse the changegroup data, otherwise we will block
1928 # parse the changegroup data, otherwise we will block
1927 # in case of sshrepo because we don't know the end of the stream
1929 # in case of sshrepo because we don't know the end of the stream
1928 return changegroup.writechunks(ui, chunkiter, filename, vfs=vfs)
1930 return changegroup.writechunks(ui, chunkiter, filename, vfs=vfs)
1929
1931
1930
1932
1931 def combinechangegroupresults(op):
1933 def combinechangegroupresults(op):
1932 """logic to combine 0 or more addchangegroup results into one"""
1934 """logic to combine 0 or more addchangegroup results into one"""
1933 results = [r.get(b'return', 0) for r in op.records[b'changegroup']]
1935 results = [r.get(b'return', 0) for r in op.records[b'changegroup']]
1934 changedheads = 0
1936 changedheads = 0
1935 result = 1
1937 result = 1
1936 for ret in results:
1938 for ret in results:
1937 # If any changegroup result is 0, return 0
1939 # If any changegroup result is 0, return 0
1938 if ret == 0:
1940 if ret == 0:
1939 result = 0
1941 result = 0
1940 break
1942 break
1941 if ret < -1:
1943 if ret < -1:
1942 changedheads += ret + 1
1944 changedheads += ret + 1
1943 elif ret > 1:
1945 elif ret > 1:
1944 changedheads += ret - 1
1946 changedheads += ret - 1
1945 if changedheads > 0:
1947 if changedheads > 0:
1946 result = 1 + changedheads
1948 result = 1 + changedheads
1947 elif changedheads < 0:
1949 elif changedheads < 0:
1948 result = -1 + changedheads
1950 result = -1 + changedheads
1949 return result
1951 return result
1950
1952
1951
1953
1952 @parthandler(
1954 @parthandler(
1953 b'changegroup',
1955 b'changegroup',
1954 (
1956 (
1955 b'version',
1957 b'version',
1956 b'nbchanges',
1958 b'nbchanges',
1957 b'exp-sidedata',
1959 b'exp-sidedata',
1958 b'treemanifest',
1960 b'treemanifest',
1959 b'targetphase',
1961 b'targetphase',
1960 ),
1962 ),
1961 )
1963 )
1962 def handlechangegroup(op, inpart):
1964 def handlechangegroup(op, inpart):
1963 """apply a changegroup part on the repo"""
1965 """apply a changegroup part on the repo"""
1964 from . import localrepo
1966 from . import localrepo
1965
1967
1966 tr = op.gettransaction()
1968 tr = op.gettransaction()
1967 unpackerversion = inpart.params.get(b'version', b'01')
1969 unpackerversion = inpart.params.get(b'version', b'01')
1968 # We should raise an appropriate exception here
1970 # We should raise an appropriate exception here
1969 cg = changegroup.getunbundler(unpackerversion, inpart, None)
1971 cg = changegroup.getunbundler(unpackerversion, inpart, None)
1970 # the source and url passed here are overwritten by the one contained in
1972 # the source and url passed here are overwritten by the one contained in
1971 # the transaction.hookargs argument. So 'bundle2' is a placeholder
1973 # the transaction.hookargs argument. So 'bundle2' is a placeholder
1972 nbchangesets = None
1974 nbchangesets = None
1973 if b'nbchanges' in inpart.params:
1975 if b'nbchanges' in inpart.params:
1974 nbchangesets = int(inpart.params.get(b'nbchanges'))
1976 nbchangesets = int(inpart.params.get(b'nbchanges'))
1975 if b'treemanifest' in inpart.params and not scmutil.istreemanifest(op.repo):
1977 if b'treemanifest' in inpart.params and not scmutil.istreemanifest(op.repo):
1976 if len(op.repo.changelog) != 0:
1978 if len(op.repo.changelog) != 0:
1977 raise error.Abort(
1979 raise error.Abort(
1978 _(
1980 _(
1979 b"bundle contains tree manifests, but local repo is "
1981 b"bundle contains tree manifests, but local repo is "
1980 b"non-empty and does not use tree manifests"
1982 b"non-empty and does not use tree manifests"
1981 )
1983 )
1982 )
1984 )
1983 op.repo.requirements.add(requirements.TREEMANIFEST_REQUIREMENT)
1985 op.repo.requirements.add(requirements.TREEMANIFEST_REQUIREMENT)
1984 op.repo.svfs.options = localrepo.resolvestorevfsoptions(
1986 op.repo.svfs.options = localrepo.resolvestorevfsoptions(
1985 op.repo.ui, op.repo.requirements, op.repo.features
1987 op.repo.ui, op.repo.requirements, op.repo.features
1986 )
1988 )
1987 scmutil.writereporequirements(op.repo)
1989 scmutil.writereporequirements(op.repo)
1988
1990
1989 bundlesidedata = bool(b'exp-sidedata' in inpart.params)
1991 bundlesidedata = bool(b'exp-sidedata' in inpart.params)
1990 reposidedata = bool(b'exp-sidedata-flag' in op.repo.requirements)
1992 reposidedata = bool(b'exp-sidedata-flag' in op.repo.requirements)
1991 if reposidedata and not bundlesidedata:
1993 if reposidedata and not bundlesidedata:
1992 msg = b"repository is using sidedata but the bundle source do not"
1994 msg = b"repository is using sidedata but the bundle source do not"
1993 hint = b'this is currently unsupported'
1995 hint = b'this is currently unsupported'
1994 raise error.Abort(msg, hint=hint)
1996 raise error.Abort(msg, hint=hint)
1995
1997
1996 extrakwargs = {}
1998 extrakwargs = {}
1997 targetphase = inpart.params.get(b'targetphase')
1999 targetphase = inpart.params.get(b'targetphase')
1998 if targetphase is not None:
2000 if targetphase is not None:
1999 extrakwargs['targetphase'] = int(targetphase)
2001 extrakwargs['targetphase'] = int(targetphase)
2000 ret = _processchangegroup(
2002 ret = _processchangegroup(
2001 op,
2003 op,
2002 cg,
2004 cg,
2003 tr,
2005 tr,
2004 op.source,
2006 op.source,
2005 b'bundle2',
2007 b'bundle2',
2006 expectedtotal=nbchangesets,
2008 expectedtotal=nbchangesets,
2007 **extrakwargs
2009 **extrakwargs
2008 )
2010 )
2009 if op.reply is not None:
2011 if op.reply is not None:
2010 # This is definitely not the final form of this
2012 # This is definitely not the final form of this
2011 # return. But one need to start somewhere.
2013 # return. But one need to start somewhere.
2012 part = op.reply.newpart(b'reply:changegroup', mandatory=False)
2014 part = op.reply.newpart(b'reply:changegroup', mandatory=False)
2013 part.addparam(
2015 part.addparam(
2014 b'in-reply-to', pycompat.bytestr(inpart.id), mandatory=False
2016 b'in-reply-to', pycompat.bytestr(inpart.id), mandatory=False
2015 )
2017 )
2016 part.addparam(b'return', b'%i' % ret, mandatory=False)
2018 part.addparam(b'return', b'%i' % ret, mandatory=False)
2017 assert not inpart.read()
2019 assert not inpart.read()
2018
2020
2019
2021
2020 _remotechangegroupparams = tuple(
2022 _remotechangegroupparams = tuple(
2021 [b'url', b'size', b'digests']
2023 [b'url', b'size', b'digests']
2022 + [b'digest:%s' % k for k in util.DIGESTS.keys()]
2024 + [b'digest:%s' % k for k in util.DIGESTS.keys()]
2023 )
2025 )
2024
2026
2025
2027
2026 @parthandler(b'remote-changegroup', _remotechangegroupparams)
2028 @parthandler(b'remote-changegroup', _remotechangegroupparams)
2027 def handleremotechangegroup(op, inpart):
2029 def handleremotechangegroup(op, inpart):
2028 """apply a bundle10 on the repo, given an url and validation information
2030 """apply a bundle10 on the repo, given an url and validation information
2029
2031
2030 All the information about the remote bundle to import are given as
2032 All the information about the remote bundle to import are given as
2031 parameters. The parameters include:
2033 parameters. The parameters include:
2032 - url: the url to the bundle10.
2034 - url: the url to the bundle10.
2033 - size: the bundle10 file size. It is used to validate what was
2035 - size: the bundle10 file size. It is used to validate what was
2034 retrieved by the client matches the server knowledge about the bundle.
2036 retrieved by the client matches the server knowledge about the bundle.
2035 - digests: a space separated list of the digest types provided as
2037 - digests: a space separated list of the digest types provided as
2036 parameters.
2038 parameters.
2037 - digest:<digest-type>: the hexadecimal representation of the digest with
2039 - digest:<digest-type>: the hexadecimal representation of the digest with
2038 that name. Like the size, it is used to validate what was retrieved by
2040 that name. Like the size, it is used to validate what was retrieved by
2039 the client matches what the server knows about the bundle.
2041 the client matches what the server knows about the bundle.
2040
2042
2041 When multiple digest types are given, all of them are checked.
2043 When multiple digest types are given, all of them are checked.
2042 """
2044 """
2043 try:
2045 try:
2044 raw_url = inpart.params[b'url']
2046 raw_url = inpart.params[b'url']
2045 except KeyError:
2047 except KeyError:
2046 raise error.Abort(_(b'remote-changegroup: missing "%s" param') % b'url')
2048 raise error.Abort(_(b'remote-changegroup: missing "%s" param') % b'url')
2047 parsed_url = util.url(raw_url)
2049 parsed_url = util.url(raw_url)
2048 if parsed_url.scheme not in capabilities[b'remote-changegroup']:
2050 if parsed_url.scheme not in capabilities[b'remote-changegroup']:
2049 raise error.Abort(
2051 raise error.Abort(
2050 _(b'remote-changegroup does not support %s urls')
2052 _(b'remote-changegroup does not support %s urls')
2051 % parsed_url.scheme
2053 % parsed_url.scheme
2052 )
2054 )
2053
2055
2054 try:
2056 try:
2055 size = int(inpart.params[b'size'])
2057 size = int(inpart.params[b'size'])
2056 except ValueError:
2058 except ValueError:
2057 raise error.Abort(
2059 raise error.Abort(
2058 _(b'remote-changegroup: invalid value for param "%s"') % b'size'
2060 _(b'remote-changegroup: invalid value for param "%s"') % b'size'
2059 )
2061 )
2060 except KeyError:
2062 except KeyError:
2061 raise error.Abort(
2063 raise error.Abort(
2062 _(b'remote-changegroup: missing "%s" param') % b'size'
2064 _(b'remote-changegroup: missing "%s" param') % b'size'
2063 )
2065 )
2064
2066
2065 digests = {}
2067 digests = {}
2066 for typ in inpart.params.get(b'digests', b'').split():
2068 for typ in inpart.params.get(b'digests', b'').split():
2067 param = b'digest:%s' % typ
2069 param = b'digest:%s' % typ
2068 try:
2070 try:
2069 value = inpart.params[param]
2071 value = inpart.params[param]
2070 except KeyError:
2072 except KeyError:
2071 raise error.Abort(
2073 raise error.Abort(
2072 _(b'remote-changegroup: missing "%s" param') % param
2074 _(b'remote-changegroup: missing "%s" param') % param
2073 )
2075 )
2074 digests[typ] = value
2076 digests[typ] = value
2075
2077
2076 real_part = util.digestchecker(url.open(op.ui, raw_url), size, digests)
2078 real_part = util.digestchecker(url.open(op.ui, raw_url), size, digests)
2077
2079
2078 tr = op.gettransaction()
2080 tr = op.gettransaction()
2079 from . import exchange
2081 from . import exchange
2080
2082
2081 cg = exchange.readbundle(op.repo.ui, real_part, raw_url)
2083 cg = exchange.readbundle(op.repo.ui, real_part, raw_url)
2082 if not isinstance(cg, changegroup.cg1unpacker):
2084 if not isinstance(cg, changegroup.cg1unpacker):
2083 raise error.Abort(
2085 raise error.Abort(
2084 _(b'%s: not a bundle version 1.0') % util.hidepassword(raw_url)
2086 _(b'%s: not a bundle version 1.0') % util.hidepassword(raw_url)
2085 )
2087 )
2086 ret = _processchangegroup(op, cg, tr, op.source, b'bundle2')
2088 ret = _processchangegroup(op, cg, tr, op.source, b'bundle2')
2087 if op.reply is not None:
2089 if op.reply is not None:
2088 # This is definitely not the final form of this
2090 # This is definitely not the final form of this
2089 # return. But one need to start somewhere.
2091 # return. But one need to start somewhere.
2090 part = op.reply.newpart(b'reply:changegroup')
2092 part = op.reply.newpart(b'reply:changegroup')
2091 part.addparam(
2093 part.addparam(
2092 b'in-reply-to', pycompat.bytestr(inpart.id), mandatory=False
2094 b'in-reply-to', pycompat.bytestr(inpart.id), mandatory=False
2093 )
2095 )
2094 part.addparam(b'return', b'%i' % ret, mandatory=False)
2096 part.addparam(b'return', b'%i' % ret, mandatory=False)
2095 try:
2097 try:
2096 real_part.validate()
2098 real_part.validate()
2097 except error.Abort as e:
2099 except error.Abort as e:
2098 raise error.Abort(
2100 raise error.Abort(
2099 _(b'bundle at %s is corrupted:\n%s')
2101 _(b'bundle at %s is corrupted:\n%s')
2100 % (util.hidepassword(raw_url), e.message)
2102 % (util.hidepassword(raw_url), e.message)
2101 )
2103 )
2102 assert not inpart.read()
2104 assert not inpart.read()
2103
2105
2104
2106
2105 @parthandler(b'reply:changegroup', (b'return', b'in-reply-to'))
2107 @parthandler(b'reply:changegroup', (b'return', b'in-reply-to'))
2106 def handlereplychangegroup(op, inpart):
2108 def handlereplychangegroup(op, inpart):
2107 ret = int(inpart.params[b'return'])
2109 ret = int(inpart.params[b'return'])
2108 replyto = int(inpart.params[b'in-reply-to'])
2110 replyto = int(inpart.params[b'in-reply-to'])
2109 op.records.add(b'changegroup', {b'return': ret}, replyto)
2111 op.records.add(b'changegroup', {b'return': ret}, replyto)
2110
2112
2111
2113
2112 @parthandler(b'check:bookmarks')
2114 @parthandler(b'check:bookmarks')
2113 def handlecheckbookmarks(op, inpart):
2115 def handlecheckbookmarks(op, inpart):
2114 """check location of bookmarks
2116 """check location of bookmarks
2115
2117
2116 This part is to be used to detect push race regarding bookmark, it
2118 This part is to be used to detect push race regarding bookmark, it
2117 contains binary encoded (bookmark, node) tuple. If the local state does
2119 contains binary encoded (bookmark, node) tuple. If the local state does
2118 not marks the one in the part, a PushRaced exception is raised
2120 not marks the one in the part, a PushRaced exception is raised
2119 """
2121 """
2120 bookdata = bookmarks.binarydecode(inpart)
2122 bookdata = bookmarks.binarydecode(inpart)
2121
2123
2122 msgstandard = (
2124 msgstandard = (
2123 b'remote repository changed while pushing - please try again '
2125 b'remote repository changed while pushing - please try again '
2124 b'(bookmark "%s" move from %s to %s)'
2126 b'(bookmark "%s" move from %s to %s)'
2125 )
2127 )
2126 msgmissing = (
2128 msgmissing = (
2127 b'remote repository changed while pushing - please try again '
2129 b'remote repository changed while pushing - please try again '
2128 b'(bookmark "%s" is missing, expected %s)'
2130 b'(bookmark "%s" is missing, expected %s)'
2129 )
2131 )
2130 msgexist = (
2132 msgexist = (
2131 b'remote repository changed while pushing - please try again '
2133 b'remote repository changed while pushing - please try again '
2132 b'(bookmark "%s" set on %s, expected missing)'
2134 b'(bookmark "%s" set on %s, expected missing)'
2133 )
2135 )
2134 for book, node in bookdata:
2136 for book, node in bookdata:
2135 currentnode = op.repo._bookmarks.get(book)
2137 currentnode = op.repo._bookmarks.get(book)
2136 if currentnode != node:
2138 if currentnode != node:
2137 if node is None:
2139 if node is None:
2138 finalmsg = msgexist % (book, short(currentnode))
2140 finalmsg = msgexist % (book, short(currentnode))
2139 elif currentnode is None:
2141 elif currentnode is None:
2140 finalmsg = msgmissing % (book, short(node))
2142 finalmsg = msgmissing % (book, short(node))
2141 else:
2143 else:
2142 finalmsg = msgstandard % (
2144 finalmsg = msgstandard % (
2143 book,
2145 book,
2144 short(node),
2146 short(node),
2145 short(currentnode),
2147 short(currentnode),
2146 )
2148 )
2147 raise error.PushRaced(finalmsg)
2149 raise error.PushRaced(finalmsg)
2148
2150
2149
2151
2150 @parthandler(b'check:heads')
2152 @parthandler(b'check:heads')
2151 def handlecheckheads(op, inpart):
2153 def handlecheckheads(op, inpart):
2152 """check that head of the repo did not change
2154 """check that head of the repo did not change
2153
2155
2154 This is used to detect a push race when using unbundle.
2156 This is used to detect a push race when using unbundle.
2155 This replaces the "heads" argument of unbundle."""
2157 This replaces the "heads" argument of unbundle."""
2156 h = inpart.read(20)
2158 h = inpart.read(20)
2157 heads = []
2159 heads = []
2158 while len(h) == 20:
2160 while len(h) == 20:
2159 heads.append(h)
2161 heads.append(h)
2160 h = inpart.read(20)
2162 h = inpart.read(20)
2161 assert not h
2163 assert not h
2162 # Trigger a transaction so that we are guaranteed to have the lock now.
2164 # Trigger a transaction so that we are guaranteed to have the lock now.
2163 if op.ui.configbool(b'experimental', b'bundle2lazylocking'):
2165 if op.ui.configbool(b'experimental', b'bundle2lazylocking'):
2164 op.gettransaction()
2166 op.gettransaction()
2165 if sorted(heads) != sorted(op.repo.heads()):
2167 if sorted(heads) != sorted(op.repo.heads()):
2166 raise error.PushRaced(
2168 raise error.PushRaced(
2167 b'remote repository changed while pushing - please try again'
2169 b'remote repository changed while pushing - please try again'
2168 )
2170 )
2169
2171
2170
2172
2171 @parthandler(b'check:updated-heads')
2173 @parthandler(b'check:updated-heads')
2172 def handlecheckupdatedheads(op, inpart):
2174 def handlecheckupdatedheads(op, inpart):
2173 """check for race on the heads touched by a push
2175 """check for race on the heads touched by a push
2174
2176
2175 This is similar to 'check:heads' but focus on the heads actually updated
2177 This is similar to 'check:heads' but focus on the heads actually updated
2176 during the push. If other activities happen on unrelated heads, it is
2178 during the push. If other activities happen on unrelated heads, it is
2177 ignored.
2179 ignored.
2178
2180
2179 This allow server with high traffic to avoid push contention as long as
2181 This allow server with high traffic to avoid push contention as long as
2180 unrelated parts of the graph are involved."""
2182 unrelated parts of the graph are involved."""
2181 h = inpart.read(20)
2183 h = inpart.read(20)
2182 heads = []
2184 heads = []
2183 while len(h) == 20:
2185 while len(h) == 20:
2184 heads.append(h)
2186 heads.append(h)
2185 h = inpart.read(20)
2187 h = inpart.read(20)
2186 assert not h
2188 assert not h
2187 # trigger a transaction so that we are guaranteed to have the lock now.
2189 # trigger a transaction so that we are guaranteed to have the lock now.
2188 if op.ui.configbool(b'experimental', b'bundle2lazylocking'):
2190 if op.ui.configbool(b'experimental', b'bundle2lazylocking'):
2189 op.gettransaction()
2191 op.gettransaction()
2190
2192
2191 currentheads = set()
2193 currentheads = set()
2192 for ls in op.repo.branchmap().iterheads():
2194 for ls in op.repo.branchmap().iterheads():
2193 currentheads.update(ls)
2195 currentheads.update(ls)
2194
2196
2195 for h in heads:
2197 for h in heads:
2196 if h not in currentheads:
2198 if h not in currentheads:
2197 raise error.PushRaced(
2199 raise error.PushRaced(
2198 b'remote repository changed while pushing - '
2200 b'remote repository changed while pushing - '
2199 b'please try again'
2201 b'please try again'
2200 )
2202 )
2201
2203
2202
2204
2203 @parthandler(b'check:phases')
2205 @parthandler(b'check:phases')
2204 def handlecheckphases(op, inpart):
2206 def handlecheckphases(op, inpart):
2205 """check that phase boundaries of the repository did not change
2207 """check that phase boundaries of the repository did not change
2206
2208
2207 This is used to detect a push race.
2209 This is used to detect a push race.
2208 """
2210 """
2209 phasetonodes = phases.binarydecode(inpart)
2211 phasetonodes = phases.binarydecode(inpart)
2210 unfi = op.repo.unfiltered()
2212 unfi = op.repo.unfiltered()
2211 cl = unfi.changelog
2213 cl = unfi.changelog
2212 phasecache = unfi._phasecache
2214 phasecache = unfi._phasecache
2213 msg = (
2215 msg = (
2214 b'remote repository changed while pushing - please try again '
2216 b'remote repository changed while pushing - please try again '
2215 b'(%s is %s expected %s)'
2217 b'(%s is %s expected %s)'
2216 )
2218 )
2217 for expectedphase, nodes in pycompat.iteritems(phasetonodes):
2219 for expectedphase, nodes in pycompat.iteritems(phasetonodes):
2218 for n in nodes:
2220 for n in nodes:
2219 actualphase = phasecache.phase(unfi, cl.rev(n))
2221 actualphase = phasecache.phase(unfi, cl.rev(n))
2220 if actualphase != expectedphase:
2222 if actualphase != expectedphase:
2221 finalmsg = msg % (
2223 finalmsg = msg % (
2222 short(n),
2224 short(n),
2223 phases.phasenames[actualphase],
2225 phases.phasenames[actualphase],
2224 phases.phasenames[expectedphase],
2226 phases.phasenames[expectedphase],
2225 )
2227 )
2226 raise error.PushRaced(finalmsg)
2228 raise error.PushRaced(finalmsg)
2227
2229
2228
2230
2229 @parthandler(b'output')
2231 @parthandler(b'output')
2230 def handleoutput(op, inpart):
2232 def handleoutput(op, inpart):
2231 """forward output captured on the server to the client"""
2233 """forward output captured on the server to the client"""
2232 for line in inpart.read().splitlines():
2234 for line in inpart.read().splitlines():
2233 op.ui.status(_(b'remote: %s\n') % line)
2235 op.ui.status(_(b'remote: %s\n') % line)
2234
2236
2235
2237
2236 @parthandler(b'replycaps')
2238 @parthandler(b'replycaps')
2237 def handlereplycaps(op, inpart):
2239 def handlereplycaps(op, inpart):
2238 """Notify that a reply bundle should be created
2240 """Notify that a reply bundle should be created
2239
2241
2240 The payload contains the capabilities information for the reply"""
2242 The payload contains the capabilities information for the reply"""
2241 caps = decodecaps(inpart.read())
2243 caps = decodecaps(inpart.read())
2242 if op.reply is None:
2244 if op.reply is None:
2243 op.reply = bundle20(op.ui, caps)
2245 op.reply = bundle20(op.ui, caps)
2244
2246
2245
2247
2246 class AbortFromPart(error.Abort):
2248 class AbortFromPart(error.Abort):
2247 """Sub-class of Abort that denotes an error from a bundle2 part."""
2249 """Sub-class of Abort that denotes an error from a bundle2 part."""
2248
2250
2249
2251
2250 @parthandler(b'error:abort', (b'message', b'hint'))
2252 @parthandler(b'error:abort', (b'message', b'hint'))
2251 def handleerrorabort(op, inpart):
2253 def handleerrorabort(op, inpart):
2252 """Used to transmit abort error over the wire"""
2254 """Used to transmit abort error over the wire"""
2253 raise AbortFromPart(
2255 raise AbortFromPart(
2254 inpart.params[b'message'], hint=inpart.params.get(b'hint')
2256 inpart.params[b'message'], hint=inpart.params.get(b'hint')
2255 )
2257 )
2256
2258
2257
2259
2258 @parthandler(
2260 @parthandler(
2259 b'error:pushkey',
2261 b'error:pushkey',
2260 (b'namespace', b'key', b'new', b'old', b'ret', b'in-reply-to'),
2262 (b'namespace', b'key', b'new', b'old', b'ret', b'in-reply-to'),
2261 )
2263 )
2262 def handleerrorpushkey(op, inpart):
2264 def handleerrorpushkey(op, inpart):
2263 """Used to transmit failure of a mandatory pushkey over the wire"""
2265 """Used to transmit failure of a mandatory pushkey over the wire"""
2264 kwargs = {}
2266 kwargs = {}
2265 for name in (b'namespace', b'key', b'new', b'old', b'ret'):
2267 for name in (b'namespace', b'key', b'new', b'old', b'ret'):
2266 value = inpart.params.get(name)
2268 value = inpart.params.get(name)
2267 if value is not None:
2269 if value is not None:
2268 kwargs[name] = value
2270 kwargs[name] = value
2269 raise error.PushkeyFailed(
2271 raise error.PushkeyFailed(
2270 inpart.params[b'in-reply-to'], **pycompat.strkwargs(kwargs)
2272 inpart.params[b'in-reply-to'], **pycompat.strkwargs(kwargs)
2271 )
2273 )
2272
2274
2273
2275
2274 @parthandler(b'error:unsupportedcontent', (b'parttype', b'params'))
2276 @parthandler(b'error:unsupportedcontent', (b'parttype', b'params'))
2275 def handleerrorunsupportedcontent(op, inpart):
2277 def handleerrorunsupportedcontent(op, inpart):
2276 """Used to transmit unknown content error over the wire"""
2278 """Used to transmit unknown content error over the wire"""
2277 kwargs = {}
2279 kwargs = {}
2278 parttype = inpart.params.get(b'parttype')
2280 parttype = inpart.params.get(b'parttype')
2279 if parttype is not None:
2281 if parttype is not None:
2280 kwargs[b'parttype'] = parttype
2282 kwargs[b'parttype'] = parttype
2281 params = inpart.params.get(b'params')
2283 params = inpart.params.get(b'params')
2282 if params is not None:
2284 if params is not None:
2283 kwargs[b'params'] = params.split(b'\0')
2285 kwargs[b'params'] = params.split(b'\0')
2284
2286
2285 raise error.BundleUnknownFeatureError(**pycompat.strkwargs(kwargs))
2287 raise error.BundleUnknownFeatureError(**pycompat.strkwargs(kwargs))
2286
2288
2287
2289
2288 @parthandler(b'error:pushraced', (b'message',))
2290 @parthandler(b'error:pushraced', (b'message',))
2289 def handleerrorpushraced(op, inpart):
2291 def handleerrorpushraced(op, inpart):
2290 """Used to transmit push race error over the wire"""
2292 """Used to transmit push race error over the wire"""
2291 raise error.ResponseError(_(b'push failed:'), inpart.params[b'message'])
2293 raise error.ResponseError(_(b'push failed:'), inpart.params[b'message'])
2292
2294
2293
2295
2294 @parthandler(b'listkeys', (b'namespace',))
2296 @parthandler(b'listkeys', (b'namespace',))
2295 def handlelistkeys(op, inpart):
2297 def handlelistkeys(op, inpart):
2296 """retrieve pushkey namespace content stored in a bundle2"""
2298 """retrieve pushkey namespace content stored in a bundle2"""
2297 namespace = inpart.params[b'namespace']
2299 namespace = inpart.params[b'namespace']
2298 r = pushkey.decodekeys(inpart.read())
2300 r = pushkey.decodekeys(inpart.read())
2299 op.records.add(b'listkeys', (namespace, r))
2301 op.records.add(b'listkeys', (namespace, r))
2300
2302
2301
2303
2302 @parthandler(b'pushkey', (b'namespace', b'key', b'old', b'new'))
2304 @parthandler(b'pushkey', (b'namespace', b'key', b'old', b'new'))
2303 def handlepushkey(op, inpart):
2305 def handlepushkey(op, inpart):
2304 """process a pushkey request"""
2306 """process a pushkey request"""
2305 dec = pushkey.decode
2307 dec = pushkey.decode
2306 namespace = dec(inpart.params[b'namespace'])
2308 namespace = dec(inpart.params[b'namespace'])
2307 key = dec(inpart.params[b'key'])
2309 key = dec(inpart.params[b'key'])
2308 old = dec(inpart.params[b'old'])
2310 old = dec(inpart.params[b'old'])
2309 new = dec(inpart.params[b'new'])
2311 new = dec(inpart.params[b'new'])
2310 # Grab the transaction to ensure that we have the lock before performing the
2312 # Grab the transaction to ensure that we have the lock before performing the
2311 # pushkey.
2313 # pushkey.
2312 if op.ui.configbool(b'experimental', b'bundle2lazylocking'):
2314 if op.ui.configbool(b'experimental', b'bundle2lazylocking'):
2313 op.gettransaction()
2315 op.gettransaction()
2314 ret = op.repo.pushkey(namespace, key, old, new)
2316 ret = op.repo.pushkey(namespace, key, old, new)
2315 record = {b'namespace': namespace, b'key': key, b'old': old, b'new': new}
2317 record = {b'namespace': namespace, b'key': key, b'old': old, b'new': new}
2316 op.records.add(b'pushkey', record)
2318 op.records.add(b'pushkey', record)
2317 if op.reply is not None:
2319 if op.reply is not None:
2318 rpart = op.reply.newpart(b'reply:pushkey')
2320 rpart = op.reply.newpart(b'reply:pushkey')
2319 rpart.addparam(
2321 rpart.addparam(
2320 b'in-reply-to', pycompat.bytestr(inpart.id), mandatory=False
2322 b'in-reply-to', pycompat.bytestr(inpart.id), mandatory=False
2321 )
2323 )
2322 rpart.addparam(b'return', b'%i' % ret, mandatory=False)
2324 rpart.addparam(b'return', b'%i' % ret, mandatory=False)
2323 if inpart.mandatory and not ret:
2325 if inpart.mandatory and not ret:
2324 kwargs = {}
2326 kwargs = {}
2325 for key in (b'namespace', b'key', b'new', b'old', b'ret'):
2327 for key in (b'namespace', b'key', b'new', b'old', b'ret'):
2326 if key in inpart.params:
2328 if key in inpart.params:
2327 kwargs[key] = inpart.params[key]
2329 kwargs[key] = inpart.params[key]
2328 raise error.PushkeyFailed(
2330 raise error.PushkeyFailed(
2329 partid=b'%d' % inpart.id, **pycompat.strkwargs(kwargs)
2331 partid=b'%d' % inpart.id, **pycompat.strkwargs(kwargs)
2330 )
2332 )
2331
2333
2332
2334
2333 @parthandler(b'bookmarks')
2335 @parthandler(b'bookmarks')
2334 def handlebookmark(op, inpart):
2336 def handlebookmark(op, inpart):
2335 """transmit bookmark information
2337 """transmit bookmark information
2336
2338
2337 The part contains binary encoded bookmark information.
2339 The part contains binary encoded bookmark information.
2338
2340
2339 The exact behavior of this part can be controlled by the 'bookmarks' mode
2341 The exact behavior of this part can be controlled by the 'bookmarks' mode
2340 on the bundle operation.
2342 on the bundle operation.
2341
2343
2342 When mode is 'apply' (the default) the bookmark information is applied as
2344 When mode is 'apply' (the default) the bookmark information is applied as
2343 is to the unbundling repository. Make sure a 'check:bookmarks' part is
2345 is to the unbundling repository. Make sure a 'check:bookmarks' part is
2344 issued earlier to check for push races in such update. This behavior is
2346 issued earlier to check for push races in such update. This behavior is
2345 suitable for pushing.
2347 suitable for pushing.
2346
2348
2347 When mode is 'records', the information is recorded into the 'bookmarks'
2349 When mode is 'records', the information is recorded into the 'bookmarks'
2348 records of the bundle operation. This behavior is suitable for pulling.
2350 records of the bundle operation. This behavior is suitable for pulling.
2349 """
2351 """
2350 changes = bookmarks.binarydecode(inpart)
2352 changes = bookmarks.binarydecode(inpart)
2351
2353
2352 pushkeycompat = op.repo.ui.configbool(
2354 pushkeycompat = op.repo.ui.configbool(
2353 b'server', b'bookmarks-pushkey-compat'
2355 b'server', b'bookmarks-pushkey-compat'
2354 )
2356 )
2355 bookmarksmode = op.modes.get(b'bookmarks', b'apply')
2357 bookmarksmode = op.modes.get(b'bookmarks', b'apply')
2356
2358
2357 if bookmarksmode == b'apply':
2359 if bookmarksmode == b'apply':
2358 tr = op.gettransaction()
2360 tr = op.gettransaction()
2359 bookstore = op.repo._bookmarks
2361 bookstore = op.repo._bookmarks
2360 if pushkeycompat:
2362 if pushkeycompat:
2361 allhooks = []
2363 allhooks = []
2362 for book, node in changes:
2364 for book, node in changes:
2363 hookargs = tr.hookargs.copy()
2365 hookargs = tr.hookargs.copy()
2364 hookargs[b'pushkeycompat'] = b'1'
2366 hookargs[b'pushkeycompat'] = b'1'
2365 hookargs[b'namespace'] = b'bookmarks'
2367 hookargs[b'namespace'] = b'bookmarks'
2366 hookargs[b'key'] = book
2368 hookargs[b'key'] = book
2367 hookargs[b'old'] = hex(bookstore.get(book, b''))
2369 hookargs[b'old'] = hex(bookstore.get(book, b''))
2368 hookargs[b'new'] = hex(node if node is not None else b'')
2370 hookargs[b'new'] = hex(node if node is not None else b'')
2369 allhooks.append(hookargs)
2371 allhooks.append(hookargs)
2370
2372
2371 for hookargs in allhooks:
2373 for hookargs in allhooks:
2372 op.repo.hook(
2374 op.repo.hook(
2373 b'prepushkey', throw=True, **pycompat.strkwargs(hookargs)
2375 b'prepushkey', throw=True, **pycompat.strkwargs(hookargs)
2374 )
2376 )
2375
2377
2376 for book, node in changes:
2378 for book, node in changes:
2377 if bookmarks.isdivergent(book):
2379 if bookmarks.isdivergent(book):
2378 msg = _(b'cannot accept divergent bookmark %s!') % book
2380 msg = _(b'cannot accept divergent bookmark %s!') % book
2379 raise error.Abort(msg)
2381 raise error.Abort(msg)
2380
2382
2381 bookstore.applychanges(op.repo, op.gettransaction(), changes)
2383 bookstore.applychanges(op.repo, op.gettransaction(), changes)
2382
2384
2383 if pushkeycompat:
2385 if pushkeycompat:
2384
2386
2385 def runhook(unused_success):
2387 def runhook(unused_success):
2386 for hookargs in allhooks:
2388 for hookargs in allhooks:
2387 op.repo.hook(b'pushkey', **pycompat.strkwargs(hookargs))
2389 op.repo.hook(b'pushkey', **pycompat.strkwargs(hookargs))
2388
2390
2389 op.repo._afterlock(runhook)
2391 op.repo._afterlock(runhook)
2390
2392
2391 elif bookmarksmode == b'records':
2393 elif bookmarksmode == b'records':
2392 for book, node in changes:
2394 for book, node in changes:
2393 record = {b'bookmark': book, b'node': node}
2395 record = {b'bookmark': book, b'node': node}
2394 op.records.add(b'bookmarks', record)
2396 op.records.add(b'bookmarks', record)
2395 else:
2397 else:
2396 raise error.ProgrammingError(
2398 raise error.ProgrammingError(
2397 b'unkown bookmark mode: %s' % bookmarksmode
2399 b'unkown bookmark mode: %s' % bookmarksmode
2398 )
2400 )
2399
2401
2400
2402
2401 @parthandler(b'phase-heads')
2403 @parthandler(b'phase-heads')
2402 def handlephases(op, inpart):
2404 def handlephases(op, inpart):
2403 """apply phases from bundle part to repo"""
2405 """apply phases from bundle part to repo"""
2404 headsbyphase = phases.binarydecode(inpart)
2406 headsbyphase = phases.binarydecode(inpart)
2405 phases.updatephases(op.repo.unfiltered(), op.gettransaction, headsbyphase)
2407 phases.updatephases(op.repo.unfiltered(), op.gettransaction, headsbyphase)
2406
2408
2407
2409
2408 @parthandler(b'reply:pushkey', (b'return', b'in-reply-to'))
2410 @parthandler(b'reply:pushkey', (b'return', b'in-reply-to'))
2409 def handlepushkeyreply(op, inpart):
2411 def handlepushkeyreply(op, inpart):
2410 """retrieve the result of a pushkey request"""
2412 """retrieve the result of a pushkey request"""
2411 ret = int(inpart.params[b'return'])
2413 ret = int(inpart.params[b'return'])
2412 partid = int(inpart.params[b'in-reply-to'])
2414 partid = int(inpart.params[b'in-reply-to'])
2413 op.records.add(b'pushkey', {b'return': ret}, partid)
2415 op.records.add(b'pushkey', {b'return': ret}, partid)
2414
2416
2415
2417
2416 @parthandler(b'obsmarkers')
2418 @parthandler(b'obsmarkers')
2417 def handleobsmarker(op, inpart):
2419 def handleobsmarker(op, inpart):
2418 """add a stream of obsmarkers to the repo"""
2420 """add a stream of obsmarkers to the repo"""
2419 tr = op.gettransaction()
2421 tr = op.gettransaction()
2420 markerdata = inpart.read()
2422 markerdata = inpart.read()
2421 if op.ui.config(b'experimental', b'obsmarkers-exchange-debug'):
2423 if op.ui.config(b'experimental', b'obsmarkers-exchange-debug'):
2422 op.ui.writenoi18n(
2424 op.ui.writenoi18n(
2423 b'obsmarker-exchange: %i bytes received\n' % len(markerdata)
2425 b'obsmarker-exchange: %i bytes received\n' % len(markerdata)
2424 )
2426 )
2425 # The mergemarkers call will crash if marker creation is not enabled.
2427 # The mergemarkers call will crash if marker creation is not enabled.
2426 # we want to avoid this if the part is advisory.
2428 # we want to avoid this if the part is advisory.
2427 if not inpart.mandatory and op.repo.obsstore.readonly:
2429 if not inpart.mandatory and op.repo.obsstore.readonly:
2428 op.repo.ui.debug(
2430 op.repo.ui.debug(
2429 b'ignoring obsolescence markers, feature not enabled\n'
2431 b'ignoring obsolescence markers, feature not enabled\n'
2430 )
2432 )
2431 return
2433 return
2432 new = op.repo.obsstore.mergemarkers(tr, markerdata)
2434 new = op.repo.obsstore.mergemarkers(tr, markerdata)
2433 op.repo.invalidatevolatilesets()
2435 op.repo.invalidatevolatilesets()
2434 op.records.add(b'obsmarkers', {b'new': new})
2436 op.records.add(b'obsmarkers', {b'new': new})
2435 if op.reply is not None:
2437 if op.reply is not None:
2436 rpart = op.reply.newpart(b'reply:obsmarkers')
2438 rpart = op.reply.newpart(b'reply:obsmarkers')
2437 rpart.addparam(
2439 rpart.addparam(
2438 b'in-reply-to', pycompat.bytestr(inpart.id), mandatory=False
2440 b'in-reply-to', pycompat.bytestr(inpart.id), mandatory=False
2439 )
2441 )
2440 rpart.addparam(b'new', b'%i' % new, mandatory=False)
2442 rpart.addparam(b'new', b'%i' % new, mandatory=False)
2441
2443
2442
2444
2443 @parthandler(b'reply:obsmarkers', (b'new', b'in-reply-to'))
2445 @parthandler(b'reply:obsmarkers', (b'new', b'in-reply-to'))
2444 def handleobsmarkerreply(op, inpart):
2446 def handleobsmarkerreply(op, inpart):
2445 """retrieve the result of a pushkey request"""
2447 """retrieve the result of a pushkey request"""
2446 ret = int(inpart.params[b'new'])
2448 ret = int(inpart.params[b'new'])
2447 partid = int(inpart.params[b'in-reply-to'])
2449 partid = int(inpart.params[b'in-reply-to'])
2448 op.records.add(b'obsmarkers', {b'new': ret}, partid)
2450 op.records.add(b'obsmarkers', {b'new': ret}, partid)
2449
2451
2450
2452
2451 @parthandler(b'hgtagsfnodes')
2453 @parthandler(b'hgtagsfnodes')
2452 def handlehgtagsfnodes(op, inpart):
2454 def handlehgtagsfnodes(op, inpart):
2453 """Applies .hgtags fnodes cache entries to the local repo.
2455 """Applies .hgtags fnodes cache entries to the local repo.
2454
2456
2455 Payload is pairs of 20 byte changeset nodes and filenodes.
2457 Payload is pairs of 20 byte changeset nodes and filenodes.
2456 """
2458 """
2457 # Grab the transaction so we ensure that we have the lock at this point.
2459 # Grab the transaction so we ensure that we have the lock at this point.
2458 if op.ui.configbool(b'experimental', b'bundle2lazylocking'):
2460 if op.ui.configbool(b'experimental', b'bundle2lazylocking'):
2459 op.gettransaction()
2461 op.gettransaction()
2460 cache = tags.hgtagsfnodescache(op.repo.unfiltered())
2462 cache = tags.hgtagsfnodescache(op.repo.unfiltered())
2461
2463
2462 count = 0
2464 count = 0
2463 while True:
2465 while True:
2464 node = inpart.read(20)
2466 node = inpart.read(20)
2465 fnode = inpart.read(20)
2467 fnode = inpart.read(20)
2466 if len(node) < 20 or len(fnode) < 20:
2468 if len(node) < 20 or len(fnode) < 20:
2467 op.ui.debug(b'ignoring incomplete received .hgtags fnodes data\n')
2469 op.ui.debug(b'ignoring incomplete received .hgtags fnodes data\n')
2468 break
2470 break
2469 cache.setfnode(node, fnode)
2471 cache.setfnode(node, fnode)
2470 count += 1
2472 count += 1
2471
2473
2472 cache.write()
2474 cache.write()
2473 op.ui.debug(b'applied %i hgtags fnodes cache entries\n' % count)
2475 op.ui.debug(b'applied %i hgtags fnodes cache entries\n' % count)
2474
2476
2475
2477
2476 rbcstruct = struct.Struct(b'>III')
2478 rbcstruct = struct.Struct(b'>III')
2477
2479
2478
2480
2479 @parthandler(b'cache:rev-branch-cache')
2481 @parthandler(b'cache:rev-branch-cache')
2480 def handlerbc(op, inpart):
2482 def handlerbc(op, inpart):
2481 """Legacy part, ignored for compatibility with bundles from or
2483 """Legacy part, ignored for compatibility with bundles from or
2482 for Mercurial before 5.7. Newer Mercurial computes the cache
2484 for Mercurial before 5.7. Newer Mercurial computes the cache
2483 efficiently enough during unbundling that the additional transfer
2485 efficiently enough during unbundling that the additional transfer
2484 is unnecessary."""
2486 is unnecessary."""
2485
2487
2486
2488
2487 @parthandler(b'pushvars')
2489 @parthandler(b'pushvars')
2488 def bundle2getvars(op, part):
2490 def bundle2getvars(op, part):
2489 '''unbundle a bundle2 containing shellvars on the server'''
2491 '''unbundle a bundle2 containing shellvars on the server'''
2490 # An option to disable unbundling on server-side for security reasons
2492 # An option to disable unbundling on server-side for security reasons
2491 if op.ui.configbool(b'push', b'pushvars.server'):
2493 if op.ui.configbool(b'push', b'pushvars.server'):
2492 hookargs = {}
2494 hookargs = {}
2493 for key, value in part.advisoryparams:
2495 for key, value in part.advisoryparams:
2494 key = key.upper()
2496 key = key.upper()
2495 # We want pushed variables to have USERVAR_ prepended so we know
2497 # We want pushed variables to have USERVAR_ prepended so we know
2496 # they came from the --pushvar flag.
2498 # they came from the --pushvar flag.
2497 key = b"USERVAR_" + key
2499 key = b"USERVAR_" + key
2498 hookargs[key] = value
2500 hookargs[key] = value
2499 op.addhookargs(hookargs)
2501 op.addhookargs(hookargs)
2500
2502
2501
2503
2502 @parthandler(b'stream2', (b'requirements', b'filecount', b'bytecount'))
2504 @parthandler(b'stream2', (b'requirements', b'filecount', b'bytecount'))
2503 def handlestreamv2bundle(op, part):
2505 def handlestreamv2bundle(op, part):
2504
2506
2505 requirements = urlreq.unquote(part.params[b'requirements']).split(b',')
2507 requirements = urlreq.unquote(part.params[b'requirements']).split(b',')
2506 filecount = int(part.params[b'filecount'])
2508 filecount = int(part.params[b'filecount'])
2507 bytecount = int(part.params[b'bytecount'])
2509 bytecount = int(part.params[b'bytecount'])
2508
2510
2509 repo = op.repo
2511 repo = op.repo
2510 if len(repo):
2512 if len(repo):
2511 msg = _(b'cannot apply stream clone to non empty repository')
2513 msg = _(b'cannot apply stream clone to non empty repository')
2512 raise error.Abort(msg)
2514 raise error.Abort(msg)
2513
2515
2514 repo.ui.debug(b'applying stream bundle\n')
2516 repo.ui.debug(b'applying stream bundle\n')
2515 streamclone.applybundlev2(repo, part, filecount, bytecount, requirements)
2517 streamclone.applybundlev2(repo, part, filecount, bytecount, requirements)
2516
2518
2517
2519
2518 def widen_bundle(
2520 def widen_bundle(
2519 bundler, repo, oldmatcher, newmatcher, common, known, cgversion, ellipses
2521 bundler, repo, oldmatcher, newmatcher, common, known, cgversion, ellipses
2520 ):
2522 ):
2521 """generates bundle2 for widening a narrow clone
2523 """generates bundle2 for widening a narrow clone
2522
2524
2523 bundler is the bundle to which data should be added
2525 bundler is the bundle to which data should be added
2524 repo is the localrepository instance
2526 repo is the localrepository instance
2525 oldmatcher matches what the client already has
2527 oldmatcher matches what the client already has
2526 newmatcher matches what the client needs (including what it already has)
2528 newmatcher matches what the client needs (including what it already has)
2527 common is set of common heads between server and client
2529 common is set of common heads between server and client
2528 known is a set of revs known on the client side (used in ellipses)
2530 known is a set of revs known on the client side (used in ellipses)
2529 cgversion is the changegroup version to send
2531 cgversion is the changegroup version to send
2530 ellipses is boolean value telling whether to send ellipses data or not
2532 ellipses is boolean value telling whether to send ellipses data or not
2531
2533
2532 returns bundle2 of the data required for extending
2534 returns bundle2 of the data required for extending
2533 """
2535 """
2534 commonnodes = set()
2536 commonnodes = set()
2535 cl = repo.changelog
2537 cl = repo.changelog
2536 for r in repo.revs(b"::%ln", common):
2538 for r in repo.revs(b"::%ln", common):
2537 commonnodes.add(cl.node(r))
2539 commonnodes.add(cl.node(r))
2538 if commonnodes:
2540 if commonnodes:
2539 packer = changegroup.getbundler(
2541 packer = changegroup.getbundler(
2540 cgversion,
2542 cgversion,
2541 repo,
2543 repo,
2542 oldmatcher=oldmatcher,
2544 oldmatcher=oldmatcher,
2543 matcher=newmatcher,
2545 matcher=newmatcher,
2544 fullnodes=commonnodes,
2546 fullnodes=commonnodes,
2545 )
2547 )
2546 cgdata = packer.generate(
2548 cgdata = packer.generate(
2547 {nullid},
2549 {nullid},
2548 list(commonnodes),
2550 list(commonnodes),
2549 False,
2551 False,
2550 b'narrow_widen',
2552 b'narrow_widen',
2551 changelog=False,
2553 changelog=False,
2552 )
2554 )
2553
2555
2554 part = bundler.newpart(b'changegroup', data=cgdata)
2556 part = bundler.newpart(b'changegroup', data=cgdata)
2555 part.addparam(b'version', cgversion)
2557 part.addparam(b'version', cgversion)
2556 if scmutil.istreemanifest(repo):
2558 if scmutil.istreemanifest(repo):
2557 part.addparam(b'treemanifest', b'1')
2559 part.addparam(b'treemanifest', b'1')
2558 if b'exp-sidedata-flag' in repo.requirements:
2560 if b'exp-sidedata-flag' in repo.requirements:
2559 part.addparam(b'exp-sidedata', b'1')
2561 part.addparam(b'exp-sidedata', b'1')
2560
2562
2561 return bundler
2563 return bundler
@@ -1,202 +1,198 b''
1 # common patterns in test at can safely be replaced
1 # common patterns in test at can safely be replaced
2 from __future__ import absolute_import
2 from __future__ import absolute_import
3
3
4 import os
4 import os
5
5
6 substitutions = [
6 substitutions = [
7 # list of possible compressions
7 # list of possible compressions
8 (br'(zstd,)?zlib,none,bzip2', br'$USUAL_COMPRESSIONS$'),
8 (br'(zstd,)?zlib,none,bzip2', br'$USUAL_COMPRESSIONS$'),
9 (br'=(zstd,)?zlib', br'=$BUNDLE2_COMPRESSIONS$'),
9 (br'=(zstd,)?zlib', br'=$BUNDLE2_COMPRESSIONS$'),
10 # capabilities sent through http
10 # capabilities sent through http
11 (
11 (
12 br'bundlecaps=HG20%2Cbundle2%3DHG20%250A'
12 br'bundlecaps=HG20%2Cbundle2%3DHG20%250A'
13 br'bookmarks%250A'
13 br'bookmarks%250A'
14 br'changegroup%253D01%252C02%250A'
14 br'changegroup%253D01%252C02%250A'
15 br'checkheads%253Drelated%250A'
15 br'checkheads%253Drelated%250A'
16 br'digests%253Dmd5%252Csha1%252Csha512%250A'
16 br'digests%253Dmd5%252Csha1%252Csha512%250A'
17 br'error%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250A'
17 br'error%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250A'
18 br'hgtagsfnodes%250A'
18 br'hgtagsfnodes%250A'
19 br'listkeys%250A'
19 br'listkeys%250A'
20 br'phases%253Dheads%250A'
20 br'phases%253Dheads%250A'
21 br'pushkey%250A'
21 br'pushkey%250A'
22 br'remote-changegroup%253Dhttp%252Chttps%250A'
22 br'remote-changegroup%253Dhttp%252Chttps%250A'
23 br'rev-branch-cache%250A'
24 br'stream%253Dv2',
23 br'stream%253Dv2',
25 # (the replacement patterns)
24 # (the replacement patterns)
26 br'$USUAL_BUNDLE_CAPS$',
25 br'$USUAL_BUNDLE_CAPS$',
27 ),
26 ),
28 (
27 (
29 br'bundlecaps=HG20%2Cbundle2%3DHG20%250A'
28 br'bundlecaps=HG20%2Cbundle2%3DHG20%250A'
30 br'bookmarks%250A'
29 br'bookmarks%250A'
31 br'changegroup%253D01%252C02%250A'
30 br'changegroup%253D01%252C02%250A'
32 br'checkheads%3Drelated%0A'
31 br'checkheads%3Drelated%0A'
33 br'digests%253Dmd5%252Csha1%252Csha512%250A'
32 br'digests%253Dmd5%252Csha1%252Csha512%250A'
34 br'error%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250A'
33 br'error%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250A'
35 br'hgtagsfnodes%250A'
34 br'hgtagsfnodes%250A'
36 br'listkeys%250A'
35 br'listkeys%250A'
37 br'phases%253Dheads%250A'
36 br'phases%253Dheads%250A'
38 br'pushkey%250A'
37 br'pushkey%250A'
39 br'remote-changegroup%253Dhttp%252Chttps',
38 br'remote-changegroup%253Dhttp%252Chttps',
40 # (the replacement patterns)
39 # (the replacement patterns)
41 br'$USUAL_BUNDLE_CAPS_SERVER$',
40 br'$USUAL_BUNDLE_CAPS_SERVER$',
42 ),
41 ),
43 # bundle2 capabilities sent through ssh
42 # bundle2 capabilities sent through ssh
44 (
43 (
45 br'bundle2=HG20%0A'
44 br'bundle2=HG20%0A'
46 br'bookmarks%0A'
45 br'bookmarks%0A'
47 br'changegroup%3D01%2C02%0A'
46 br'changegroup%3D01%2C02%0A'
48 br'checkheads%3Drelated%0A'
47 br'checkheads%3Drelated%0A'
49 br'digests%3Dmd5%2Csha1%2Csha512%0A'
48 br'digests%3Dmd5%2Csha1%2Csha512%0A'
50 br'error%3Dabort%2Cunsupportedcontent%2Cpushraced%2Cpushkey%0A'
49 br'error%3Dabort%2Cunsupportedcontent%2Cpushraced%2Cpushkey%0A'
51 br'hgtagsfnodes%0A'
50 br'hgtagsfnodes%0A'
52 br'listkeys%0A'
51 br'listkeys%0A'
53 br'phases%3Dheads%0A'
52 br'phases%3Dheads%0A'
54 br'pushkey%0A'
53 br'pushkey%0A'
55 br'remote-changegroup%3Dhttp%2Chttps%0A'
54 br'remote-changegroup%3Dhttp%2Chttps%0A'
56 br'rev-branch-cache%0A'
57 br'stream%3Dv2',
55 br'stream%3Dv2',
58 # (replacement patterns)
56 # (replacement patterns)
59 br'$USUAL_BUNDLE2_CAPS$',
57 br'$USUAL_BUNDLE2_CAPS$',
60 ),
58 ),
61 # bundle2 capabilities advertised by the server
59 # bundle2 capabilities advertised by the server
62 (
60 (
63 br'bundle2=HG20%0A'
61 br'bundle2=HG20%0A'
64 br'bookmarks%0A'
62 br'bookmarks%0A'
65 br'changegroup%3D01%2C02%0A'
63 br'changegroup%3D01%2C02%0A'
66 br'checkheads%3Drelated%0A'
64 br'checkheads%3Drelated%0A'
67 br'digests%3Dmd5%2Csha1%2Csha512%0A'
65 br'digests%3Dmd5%2Csha1%2Csha512%0A'
68 br'error%3Dabort%2Cunsupportedcontent%2Cpushraced%2Cpushkey%0A'
66 br'error%3Dabort%2Cunsupportedcontent%2Cpushraced%2Cpushkey%0A'
69 br'hgtagsfnodes%0A'
67 br'hgtagsfnodes%0A'
70 br'listkeys%0A'
68 br'listkeys%0A'
71 br'phases%3Dheads%0A'
69 br'phases%3Dheads%0A'
72 br'pushkey%0A'
70 br'pushkey%0A'
73 br'remote-changegroup%3Dhttp%2Chttps%0A'
71 br'remote-changegroup%3Dhttp%2Chttps',
74 br'rev-branch-cache',
75 # (replacement patterns)
72 # (replacement patterns)
76 br'$USUAL_BUNDLE2_CAPS_SERVER$',
73 br'$USUAL_BUNDLE2_CAPS_SERVER$',
77 ),
74 ),
78 (
75 (
79 br'bundle2=HG20%0A'
76 br'bundle2=HG20%0A'
80 br'bookmarks%0A'
77 br'bookmarks%0A'
81 br'changegroup%3D01%2C02%0A'
78 br'changegroup%3D01%2C02%0A'
82 br'digests%3Dmd5%2Csha1%2Csha512%0A'
79 br'digests%3Dmd5%2Csha1%2Csha512%0A'
83 br'error%3Dabort%2Cunsupportedcontent%2Cpushraced%2Cpushkey%0A'
80 br'error%3Dabort%2Cunsupportedcontent%2Cpushraced%2Cpushkey%0A'
84 br'hgtagsfnodes%0A'
81 br'hgtagsfnodes%0A'
85 br'listkeys%0A'
82 br'listkeys%0A'
86 br'pushkey%0A'
83 br'pushkey%0A'
87 br'remote-changegroup%3Dhttp%2Chttps%0A'
84 br'remote-changegroup%3Dhttp%2Chttps%0A'
88 br'rev-branch-cache%0A'
89 br'stream%3Dv2',
85 br'stream%3Dv2',
90 # (replacement patterns)
86 # (replacement patterns)
91 br'$USUAL_BUNDLE2_CAPS_NO_PHASES$',
87 br'$USUAL_BUNDLE2_CAPS_NO_PHASES$',
92 ),
88 ),
93 # HTTP access log dates
89 # HTTP access log dates
94 (
90 (
95 br' - - \[\d\d/.../2\d\d\d \d\d:\d\d:\d\d] "(GET|PUT|POST)',
91 br' - - \[\d\d/.../2\d\d\d \d\d:\d\d:\d\d] "(GET|PUT|POST)',
96 lambda m: br' - - [$LOGDATE$] "' + m.group(1),
92 lambda m: br' - - [$LOGDATE$] "' + m.group(1),
97 ),
93 ),
98 # HTTP error log dates
94 # HTTP error log dates
99 (
95 (
100 br' - - \[\d\d/.../2\d\d\d \d\d:\d\d:\d\d] (HG error:|Exception)',
96 br' - - \[\d\d/.../2\d\d\d \d\d:\d\d:\d\d] (HG error:|Exception)',
101 lambda m: br' - - [$ERRDATE$] ' + m.group(1),
97 lambda m: br' - - [$ERRDATE$] ' + m.group(1),
102 ),
98 ),
103 # HTTP header dates- RFC 1123
99 # HTTP header dates- RFC 1123
104 (
100 (
105 br'([Dd]ate): [A-Za-z]{3}, \d\d [A-Za-z]{3} \d{4} \d\d:\d\d:\d\d GMT',
101 br'([Dd]ate): [A-Za-z]{3}, \d\d [A-Za-z]{3} \d{4} \d\d:\d\d:\d\d GMT',
106 lambda m: br'%s: $HTTP_DATE$' % m.group(1),
102 lambda m: br'%s: $HTTP_DATE$' % m.group(1),
107 ),
103 ),
108 # LFS expiration value
104 # LFS expiration value
109 (
105 (
110 br'"expires_at": "\d{4}-\d\d-\d\dT\d\d:\d\d:\d\dZ"',
106 br'"expires_at": "\d{4}-\d\d-\d\dT\d\d:\d\d:\d\dZ"',
111 br'"expires_at": "$ISO_8601_DATE_TIME$"',
107 br'"expires_at": "$ISO_8601_DATE_TIME$"',
112 ),
108 ),
113 # Windows has an extra '/' in the following lines that get globbed away:
109 # Windows has an extra '/' in the following lines that get globbed away:
114 # pushing to file:/*/$TESTTMP/r2 (glob)
110 # pushing to file:/*/$TESTTMP/r2 (glob)
115 # comparing with file:/*/$TESTTMP/r2 (glob)
111 # comparing with file:/*/$TESTTMP/r2 (glob)
116 # sub/maybelarge.dat: largefile 34..9c not available from
112 # sub/maybelarge.dat: largefile 34..9c not available from
117 # file:/*/$TESTTMP/largefiles-repo (glob)
113 # file:/*/$TESTTMP/largefiles-repo (glob)
118 (
114 (
119 br'(.*file:/)/?(/\$TESTTMP.*)',
115 br'(.*file:/)/?(/\$TESTTMP.*)',
120 lambda m: m.group(1) + b'*' + m.group(2) + b' (glob)',
116 lambda m: m.group(1) + b'*' + m.group(2) + b' (glob)',
121 ),
117 ),
122 ]
118 ]
123
119
124 # Various platform error strings, keyed on a common replacement string
120 # Various platform error strings, keyed on a common replacement string
125 _errors = {
121 _errors = {
126 br'$ENOENT$': (
122 br'$ENOENT$': (
127 # IOError in Python does not have the same error message
123 # IOError in Python does not have the same error message
128 # than in Rust, and automatic conversion is not possible
124 # than in Rust, and automatic conversion is not possible
129 # because of module member privacy.
125 # because of module member privacy.
130 br'No such file or directory \(os error 2\)',
126 br'No such file or directory \(os error 2\)',
131 # strerror()
127 # strerror()
132 br'No such file or directory',
128 br'No such file or directory',
133 # FormatMessage(ERROR_FILE_NOT_FOUND)
129 # FormatMessage(ERROR_FILE_NOT_FOUND)
134 br'The system cannot find the file specified',
130 br'The system cannot find the file specified',
135 ),
131 ),
136 br'$ENOTDIR$': (
132 br'$ENOTDIR$': (
137 # strerror()
133 # strerror()
138 br'Not a directory',
134 br'Not a directory',
139 # FormatMessage(ERROR_PATH_NOT_FOUND)
135 # FormatMessage(ERROR_PATH_NOT_FOUND)
140 br'The system cannot find the path specified',
136 br'The system cannot find the path specified',
141 ),
137 ),
142 br'$ECONNRESET$': (
138 br'$ECONNRESET$': (
143 # strerror()
139 # strerror()
144 br'Connection reset by peer',
140 br'Connection reset by peer',
145 # FormatMessage(WSAECONNRESET)
141 # FormatMessage(WSAECONNRESET)
146 br'An existing connection was forcibly closed by the remote host',
142 br'An existing connection was forcibly closed by the remote host',
147 ),
143 ),
148 br'$EADDRINUSE$': (
144 br'$EADDRINUSE$': (
149 # strerror()
145 # strerror()
150 br'Address already in use',
146 br'Address already in use',
151 # FormatMessage(WSAEADDRINUSE)
147 # FormatMessage(WSAEADDRINUSE)
152 br'Only one usage of each socket address'
148 br'Only one usage of each socket address'
153 br' \(protocol/network address/port\) is normally permitted',
149 br' \(protocol/network address/port\) is normally permitted',
154 ),
150 ),
155 br'$EADDRNOTAVAIL$': (
151 br'$EADDRNOTAVAIL$': (
156 # strerror()
152 # strerror()
157 br'Cannot assign requested address',
153 br'Cannot assign requested address',
158 # FormatMessage(WSAEADDRNOTAVAIL)
154 # FormatMessage(WSAEADDRNOTAVAIL)
159 ),
155 ),
160 }
156 }
161
157
162 for replace, msgs in _errors.items():
158 for replace, msgs in _errors.items():
163 substitutions.extend((m, replace) for m in msgs)
159 substitutions.extend((m, replace) for m in msgs)
164
160
165 # Output lines on Windows that can be autocorrected for '\' vs '/' path
161 # Output lines on Windows that can be autocorrected for '\' vs '/' path
166 # differences.
162 # differences.
167 _winpathfixes = [
163 _winpathfixes = [
168 # cloning subrepo s\ss from $TESTTMP/t/s/ss
164 # cloning subrepo s\ss from $TESTTMP/t/s/ss
169 # cloning subrepo foo\bar from http://localhost:$HGPORT/foo/bar
165 # cloning subrepo foo\bar from http://localhost:$HGPORT/foo/bar
170 br'(?m)^cloning subrepo \S+\\.*',
166 br'(?m)^cloning subrepo \S+\\.*',
171 # pulling from $TESTTMP\issue1852a
167 # pulling from $TESTTMP\issue1852a
172 br'(?m)^pulling from \$TESTTMP\\.*',
168 br'(?m)^pulling from \$TESTTMP\\.*',
173 # pushing to $TESTTMP\a
169 # pushing to $TESTTMP\a
174 br'(?m)^pushing to \$TESTTMP\\.*',
170 br'(?m)^pushing to \$TESTTMP\\.*',
175 # pushing subrepo s\ss to $TESTTMP/t/s/ss
171 # pushing subrepo s\ss to $TESTTMP/t/s/ss
176 br'(?m)^pushing subrepo \S+\\\S+ to.*',
172 br'(?m)^pushing subrepo \S+\\\S+ to.*',
177 # moving d1\d11\a1 to d3/d11/a1
173 # moving d1\d11\a1 to d3/d11/a1
178 br'(?m)^moving \S+\\.*',
174 br'(?m)^moving \S+\\.*',
179 # d1\a: not recording move - dummy does not exist
175 # d1\a: not recording move - dummy does not exist
180 br'\S+\\\S+: not recording move .+',
176 br'\S+\\\S+: not recording move .+',
181 # reverting s\a
177 # reverting s\a
182 br'(?m)^reverting (?!subrepo ).*\\.*',
178 br'(?m)^reverting (?!subrepo ).*\\.*',
183 # saved backup bundle to
179 # saved backup bundle to
184 # $TESTTMP\test\.hg\strip-backup/443431ffac4f-2fc5398a-backup.hg
180 # $TESTTMP\test\.hg\strip-backup/443431ffac4f-2fc5398a-backup.hg
185 br'(?m)^saved backup bundle to \$TESTTMP.*\.hg',
181 br'(?m)^saved backup bundle to \$TESTTMP.*\.hg',
186 # no changes made to subrepo s\ss since last push to ../tcc/s/ss
182 # no changes made to subrepo s\ss since last push to ../tcc/s/ss
187 br'(?m)^no changes made to subrepo \S+\\\S+ since.*',
183 br'(?m)^no changes made to subrepo \S+\\\S+ since.*',
188 # changeset 5:9cc5aa7204f0: stuff/maybelarge.dat references missing
184 # changeset 5:9cc5aa7204f0: stuff/maybelarge.dat references missing
189 # $TESTTMP\largefiles-repo-hg\.hg\largefiles\76..38
185 # $TESTTMP\largefiles-repo-hg\.hg\largefiles\76..38
190 br'(?m)^changeset .* references (corrupted|missing) \$TESTTMP\\.*',
186 br'(?m)^changeset .* references (corrupted|missing) \$TESTTMP\\.*',
191 # stuff/maybelarge.dat: largefile 76..38 not available from
187 # stuff/maybelarge.dat: largefile 76..38 not available from
192 # file:/*/$TESTTMP\largefiles-repo (glob)
188 # file:/*/$TESTTMP\largefiles-repo (glob)
193 br'.*: largefile \S+ not available from file:/\*/.+',
189 br'.*: largefile \S+ not available from file:/\*/.+',
194 ]
190 ]
195
191
196 if os.name == 'nt':
192 if os.name == 'nt':
197 substitutions.extend(
193 substitutions.extend(
198 [
194 [
199 (s, lambda match: match.group().replace(b'\\', b'/'))
195 (s, lambda match: match.group().replace(b'\\', b'/'))
200 for s in _winpathfixes
196 for s in _winpathfixes
201 ]
197 ]
202 )
198 )
@@ -1,2444 +1,2444 b''
1 > do_push()
1 > do_push()
2 > {
2 > {
3 > user=$1
3 > user=$1
4 > shift
4 > shift
5 > echo "Pushing as user $user"
5 > echo "Pushing as user $user"
6 > echo 'hgrc = """'
6 > echo 'hgrc = """'
7 > sed -n '/\[[ha]/,$p' b/.hg/hgrc | grep -v fakegroups.py
7 > sed -n '/\[[ha]/,$p' b/.hg/hgrc | grep -v fakegroups.py
8 > echo '"""'
8 > echo '"""'
9 > if test -f acl.config; then
9 > if test -f acl.config; then
10 > echo 'acl.config = """'
10 > echo 'acl.config = """'
11 > cat acl.config
11 > cat acl.config
12 > echo '"""'
12 > echo '"""'
13 > fi
13 > fi
14 > # On AIX /etc/profile sets LOGNAME read-only. So
14 > # On AIX /etc/profile sets LOGNAME read-only. So
15 > # LOGNAME=$user hg --cws a --debug push ../b
15 > # LOGNAME=$user hg --cws a --debug push ../b
16 > # fails with "This variable is read only."
16 > # fails with "This variable is read only."
17 > # Use env to work around this.
17 > # Use env to work around this.
18 > env LOGNAME=$user hg --cwd a --debug push ../b $*
18 > env LOGNAME=$user hg --cwd a --debug push ../b $*
19 > hg --cwd b rollback
19 > hg --cwd b rollback
20 > hg --cwd b --quiet tip
20 > hg --cwd b --quiet tip
21 > echo
21 > echo
22 > }
22 > }
23
23
24 > cat > posixgetuser.py <<'EOF'
24 > cat > posixgetuser.py <<'EOF'
25 > import getpass
25 > import getpass
26 > from mercurial import pycompat
26 > from mercurial import pycompat
27 > from mercurial.utils import procutil
27 > from mercurial.utils import procutil
28 > def posixgetuser():
28 > def posixgetuser():
29 > return pycompat.fsencode(getpass.getuser())
29 > return pycompat.fsencode(getpass.getuser())
30 > if not pycompat.isposix:
30 > if not pycompat.isposix:
31 > procutil.getuser = posixgetuser # forcibly trust $LOGNAME
31 > procutil.getuser = posixgetuser # forcibly trust $LOGNAME
32 > EOF
32 > EOF
33
33
34 > init_config()
34 > init_config()
35 > {
35 > {
36 > cat > fakegroups.py <<EOF
36 > cat > fakegroups.py <<EOF
37 > from hgext import acl
37 > from hgext import acl
38 > def fakegetusers(ui, group):
38 > def fakegetusers(ui, group):
39 > try:
39 > try:
40 > return acl._getusersorig(ui, group)
40 > return acl._getusersorig(ui, group)
41 > except BaseException:
41 > except BaseException:
42 > return [b"fred", b"betty"]
42 > return [b"fred", b"betty"]
43 > acl._getusersorig = acl._getusers
43 > acl._getusersorig = acl._getusers
44 > acl._getusers = fakegetusers
44 > acl._getusers = fakegetusers
45 > EOF
45 > EOF
46 > rm -f acl.config
46 > rm -f acl.config
47 > cat > $config <<EOF
47 > cat > $config <<EOF
48 > [hooks]
48 > [hooks]
49 > pretxnchangegroup.acl = python:hgext.acl.hook
49 > pretxnchangegroup.acl = python:hgext.acl.hook
50 > prepushkey.acl = python:hgext.acl.hook
50 > prepushkey.acl = python:hgext.acl.hook
51 > [acl]
51 > [acl]
52 > sources = push
52 > sources = push
53 > [extensions]
53 > [extensions]
54 > f=`pwd`/fakegroups.py
54 > f=`pwd`/fakegroups.py
55 > posixgetuser=$TESTTMP/posixgetuser.py
55 > posixgetuser=$TESTTMP/posixgetuser.py
56 > EOF
56 > EOF
57 > }
57 > }
58
58
59 $ hg init a
59 $ hg init a
60 $ cd a
60 $ cd a
61 $ mkdir foo foo/Bar quux
61 $ mkdir foo foo/Bar quux
62 $ echo 'in foo' > foo/file.txt
62 $ echo 'in foo' > foo/file.txt
63 $ echo 'in foo/Bar' > foo/Bar/file.txt
63 $ echo 'in foo/Bar' > foo/Bar/file.txt
64 $ echo 'in quux' > quux/file.py
64 $ echo 'in quux' > quux/file.py
65 $ hg add -q
65 $ hg add -q
66 $ hg ci -m 'add files' -d '1000000 0'
66 $ hg ci -m 'add files' -d '1000000 0'
67 $ echo >> foo/file.txt
67 $ echo >> foo/file.txt
68 $ hg ci -m 'change foo/file' -d '1000001 0'
68 $ hg ci -m 'change foo/file' -d '1000001 0'
69 $ echo >> foo/Bar/file.txt
69 $ echo >> foo/Bar/file.txt
70 $ hg ci -m 'change foo/Bar/file' -d '1000002 0'
70 $ hg ci -m 'change foo/Bar/file' -d '1000002 0'
71 $ echo >> quux/file.py
71 $ echo >> quux/file.py
72 $ hg ci -m 'change quux/file' -d '1000003 0'
72 $ hg ci -m 'change quux/file' -d '1000003 0'
73 $ hg tip --quiet
73 $ hg tip --quiet
74 3:911600dab2ae
74 3:911600dab2ae
75
75
76 $ cd ..
76 $ cd ..
77 $ hg clone -r 0 a b
77 $ hg clone -r 0 a b
78 adding changesets
78 adding changesets
79 adding manifests
79 adding manifests
80 adding file changes
80 adding file changes
81 added 1 changesets with 3 changes to 3 files
81 added 1 changesets with 3 changes to 3 files
82 new changesets 6675d58eff77
82 new changesets 6675d58eff77
83 updating to branch default
83 updating to branch default
84 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
84 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
85
85
86 $ config=b/.hg/hgrc
86 $ config=b/.hg/hgrc
87 $ cat >> "$config" <<EOF
87 $ cat >> "$config" <<EOF
88 > [extensions]
88 > [extensions]
89 > posixgetuser=$TESTTMP/posixgetuser.py
89 > posixgetuser=$TESTTMP/posixgetuser.py
90 > EOF
90 > EOF
91
91
92 Extension disabled for lack of a hook
92 Extension disabled for lack of a hook
93
93
94 $ do_push fred
94 $ do_push fred
95 Pushing as user fred
95 Pushing as user fred
96 hgrc = """
96 hgrc = """
97 """
97 """
98 pushing to ../b
98 pushing to ../b
99 query 1; heads
99 query 1; heads
100 searching for changes
100 searching for changes
101 all remote heads known locally
101 all remote heads known locally
102 listing keys for "phases"
102 listing keys for "phases"
103 checking for updated bookmarks
103 checking for updated bookmarks
104 listing keys for "bookmarks"
104 listing keys for "bookmarks"
105 listing keys for "bookmarks"
105 listing keys for "bookmarks"
106 3 changesets found
106 3 changesets found
107 list of changesets:
107 list of changesets:
108 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
108 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
109 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
109 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
110 911600dab2ae7a9baff75958b84fe606851ce955
110 911600dab2ae7a9baff75958b84fe606851ce955
111 bundle2-output-bundle: "HG20", 5 parts total
111 bundle2-output-bundle: "HG20", 5 parts total
112 bundle2-output-part: "replycaps" 224 bytes payload
112 bundle2-output-part: "replycaps" 207 bytes payload
113 bundle2-output-part: "check:phases" 24 bytes payload
113 bundle2-output-part: "check:phases" 24 bytes payload
114 bundle2-output-part: "check:updated-heads" streamed payload
114 bundle2-output-part: "check:updated-heads" streamed payload
115 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
115 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
116 bundle2-output-part: "phase-heads" 24 bytes payload
116 bundle2-output-part: "phase-heads" 24 bytes payload
117 bundle2-input-bundle: with-transaction
117 bundle2-input-bundle: with-transaction
118 bundle2-input-part: "replycaps" supported
118 bundle2-input-part: "replycaps" supported
119 bundle2-input-part: total payload size 224
119 bundle2-input-part: total payload size 207
120 bundle2-input-part: "check:phases" supported
120 bundle2-input-part: "check:phases" supported
121 bundle2-input-part: total payload size 24
121 bundle2-input-part: total payload size 24
122 bundle2-input-part: "check:updated-heads" supported
122 bundle2-input-part: "check:updated-heads" supported
123 bundle2-input-part: total payload size 20
123 bundle2-input-part: total payload size 20
124 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
124 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
125 adding changesets
125 adding changesets
126 add changeset ef1ea85a6374
126 add changeset ef1ea85a6374
127 add changeset f9cafe1212c8
127 add changeset f9cafe1212c8
128 add changeset 911600dab2ae
128 add changeset 911600dab2ae
129 adding manifests
129 adding manifests
130 adding file changes
130 adding file changes
131 adding foo/Bar/file.txt revisions
131 adding foo/Bar/file.txt revisions
132 adding foo/file.txt revisions
132 adding foo/file.txt revisions
133 adding quux/file.py revisions
133 adding quux/file.py revisions
134 bundle2-input-part: total payload size 1553
134 bundle2-input-part: total payload size 1553
135 bundle2-input-part: "phase-heads" supported
135 bundle2-input-part: "phase-heads" supported
136 bundle2-input-part: total payload size 24
136 bundle2-input-part: total payload size 24
137 bundle2-input-bundle: 5 parts total
137 bundle2-input-bundle: 5 parts total
138 updating the branch cache
138 updating the branch cache
139 added 3 changesets with 3 changes to 3 files
139 added 3 changesets with 3 changes to 3 files
140 bundle2-output-bundle: "HG20", 1 parts total
140 bundle2-output-bundle: "HG20", 1 parts total
141 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
141 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
142 bundle2-input-bundle: no-transaction
142 bundle2-input-bundle: no-transaction
143 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
143 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
144 bundle2-input-bundle: 1 parts total
144 bundle2-input-bundle: 1 parts total
145 listing keys for "phases"
145 listing keys for "phases"
146 repository tip rolled back to revision 0 (undo push)
146 repository tip rolled back to revision 0 (undo push)
147 0:6675d58eff77
147 0:6675d58eff77
148
148
149
149
150 $ echo '[hooks]' >> $config
150 $ echo '[hooks]' >> $config
151 $ echo 'pretxnchangegroup.acl = python:hgext.acl.hook' >> $config
151 $ echo 'pretxnchangegroup.acl = python:hgext.acl.hook' >> $config
152 $ echo 'prepushkey.acl = python:hgext.acl.hook' >> $config
152 $ echo 'prepushkey.acl = python:hgext.acl.hook' >> $config
153
153
154 Extension disabled for lack of acl.sources
154 Extension disabled for lack of acl.sources
155
155
156 $ do_push fred
156 $ do_push fred
157 Pushing as user fred
157 Pushing as user fred
158 hgrc = """
158 hgrc = """
159 [hooks]
159 [hooks]
160 pretxnchangegroup.acl = python:hgext.acl.hook
160 pretxnchangegroup.acl = python:hgext.acl.hook
161 prepushkey.acl = python:hgext.acl.hook
161 prepushkey.acl = python:hgext.acl.hook
162 """
162 """
163 pushing to ../b
163 pushing to ../b
164 query 1; heads
164 query 1; heads
165 searching for changes
165 searching for changes
166 all remote heads known locally
166 all remote heads known locally
167 listing keys for "phases"
167 listing keys for "phases"
168 checking for updated bookmarks
168 checking for updated bookmarks
169 listing keys for "bookmarks"
169 listing keys for "bookmarks"
170 invalid branch cache (served): tip differs
170 invalid branch cache (served): tip differs
171 listing keys for "bookmarks"
171 listing keys for "bookmarks"
172 3 changesets found
172 3 changesets found
173 list of changesets:
173 list of changesets:
174 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
174 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
175 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
175 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
176 911600dab2ae7a9baff75958b84fe606851ce955
176 911600dab2ae7a9baff75958b84fe606851ce955
177 bundle2-output-bundle: "HG20", 5 parts total
177 bundle2-output-bundle: "HG20", 5 parts total
178 bundle2-output-part: "replycaps" 224 bytes payload
178 bundle2-output-part: "replycaps" 207 bytes payload
179 bundle2-output-part: "check:phases" 24 bytes payload
179 bundle2-output-part: "check:phases" 24 bytes payload
180 bundle2-output-part: "check:updated-heads" streamed payload
180 bundle2-output-part: "check:updated-heads" streamed payload
181 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
181 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
182 bundle2-output-part: "phase-heads" 24 bytes payload
182 bundle2-output-part: "phase-heads" 24 bytes payload
183 bundle2-input-bundle: with-transaction
183 bundle2-input-bundle: with-transaction
184 bundle2-input-part: "replycaps" supported
184 bundle2-input-part: "replycaps" supported
185 bundle2-input-part: total payload size 224
185 bundle2-input-part: total payload size 207
186 bundle2-input-part: "check:phases" supported
186 bundle2-input-part: "check:phases" supported
187 bundle2-input-part: total payload size 24
187 bundle2-input-part: total payload size 24
188 bundle2-input-part: "check:updated-heads" supported
188 bundle2-input-part: "check:updated-heads" supported
189 bundle2-input-part: total payload size 20
189 bundle2-input-part: total payload size 20
190 invalid branch cache (served): tip differs
190 invalid branch cache (served): tip differs
191 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
191 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
192 adding changesets
192 adding changesets
193 add changeset ef1ea85a6374
193 add changeset ef1ea85a6374
194 add changeset f9cafe1212c8
194 add changeset f9cafe1212c8
195 add changeset 911600dab2ae
195 add changeset 911600dab2ae
196 adding manifests
196 adding manifests
197 adding file changes
197 adding file changes
198 adding foo/Bar/file.txt revisions
198 adding foo/Bar/file.txt revisions
199 adding foo/file.txt revisions
199 adding foo/file.txt revisions
200 adding quux/file.py revisions
200 adding quux/file.py revisions
201 calling hook pretxnchangegroup.acl: hgext.acl.hook
201 calling hook pretxnchangegroup.acl: hgext.acl.hook
202 acl: changes have source "push" - skipping
202 acl: changes have source "push" - skipping
203 bundle2-input-part: total payload size 1553
203 bundle2-input-part: total payload size 1553
204 bundle2-input-part: "phase-heads" supported
204 bundle2-input-part: "phase-heads" supported
205 bundle2-input-part: total payload size 24
205 bundle2-input-part: total payload size 24
206 bundle2-input-bundle: 5 parts total
206 bundle2-input-bundle: 5 parts total
207 truncating cache/rbc-revs-v1 to 8
207 truncating cache/rbc-revs-v1 to 8
208 updating the branch cache
208 updating the branch cache
209 added 3 changesets with 3 changes to 3 files
209 added 3 changesets with 3 changes to 3 files
210 bundle2-output-bundle: "HG20", 1 parts total
210 bundle2-output-bundle: "HG20", 1 parts total
211 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
211 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
212 bundle2-input-bundle: no-transaction
212 bundle2-input-bundle: no-transaction
213 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
213 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
214 bundle2-input-bundle: 1 parts total
214 bundle2-input-bundle: 1 parts total
215 listing keys for "phases"
215 listing keys for "phases"
216 repository tip rolled back to revision 0 (undo push)
216 repository tip rolled back to revision 0 (undo push)
217 0:6675d58eff77
217 0:6675d58eff77
218
218
219
219
220 No [acl.allow]/[acl.deny]
220 No [acl.allow]/[acl.deny]
221
221
222 $ echo '[acl]' >> $config
222 $ echo '[acl]' >> $config
223 $ echo 'sources = push' >> $config
223 $ echo 'sources = push' >> $config
224 $ do_push fred
224 $ do_push fred
225 Pushing as user fred
225 Pushing as user fred
226 hgrc = """
226 hgrc = """
227 [hooks]
227 [hooks]
228 pretxnchangegroup.acl = python:hgext.acl.hook
228 pretxnchangegroup.acl = python:hgext.acl.hook
229 prepushkey.acl = python:hgext.acl.hook
229 prepushkey.acl = python:hgext.acl.hook
230 [acl]
230 [acl]
231 sources = push
231 sources = push
232 """
232 """
233 pushing to ../b
233 pushing to ../b
234 query 1; heads
234 query 1; heads
235 searching for changes
235 searching for changes
236 all remote heads known locally
236 all remote heads known locally
237 listing keys for "phases"
237 listing keys for "phases"
238 checking for updated bookmarks
238 checking for updated bookmarks
239 listing keys for "bookmarks"
239 listing keys for "bookmarks"
240 invalid branch cache (served): tip differs
240 invalid branch cache (served): tip differs
241 listing keys for "bookmarks"
241 listing keys for "bookmarks"
242 3 changesets found
242 3 changesets found
243 list of changesets:
243 list of changesets:
244 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
244 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
245 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
245 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
246 911600dab2ae7a9baff75958b84fe606851ce955
246 911600dab2ae7a9baff75958b84fe606851ce955
247 bundle2-output-bundle: "HG20", 5 parts total
247 bundle2-output-bundle: "HG20", 5 parts total
248 bundle2-output-part: "replycaps" 224 bytes payload
248 bundle2-output-part: "replycaps" 207 bytes payload
249 bundle2-output-part: "check:phases" 24 bytes payload
249 bundle2-output-part: "check:phases" 24 bytes payload
250 bundle2-output-part: "check:updated-heads" streamed payload
250 bundle2-output-part: "check:updated-heads" streamed payload
251 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
251 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
252 bundle2-output-part: "phase-heads" 24 bytes payload
252 bundle2-output-part: "phase-heads" 24 bytes payload
253 bundle2-input-bundle: with-transaction
253 bundle2-input-bundle: with-transaction
254 bundle2-input-part: "replycaps" supported
254 bundle2-input-part: "replycaps" supported
255 bundle2-input-part: total payload size 224
255 bundle2-input-part: total payload size 207
256 bundle2-input-part: "check:phases" supported
256 bundle2-input-part: "check:phases" supported
257 bundle2-input-part: total payload size 24
257 bundle2-input-part: total payload size 24
258 bundle2-input-part: "check:updated-heads" supported
258 bundle2-input-part: "check:updated-heads" supported
259 bundle2-input-part: total payload size 20
259 bundle2-input-part: total payload size 20
260 invalid branch cache (served): tip differs
260 invalid branch cache (served): tip differs
261 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
261 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
262 adding changesets
262 adding changesets
263 add changeset ef1ea85a6374
263 add changeset ef1ea85a6374
264 add changeset f9cafe1212c8
264 add changeset f9cafe1212c8
265 add changeset 911600dab2ae
265 add changeset 911600dab2ae
266 adding manifests
266 adding manifests
267 adding file changes
267 adding file changes
268 adding foo/Bar/file.txt revisions
268 adding foo/Bar/file.txt revisions
269 adding foo/file.txt revisions
269 adding foo/file.txt revisions
270 adding quux/file.py revisions
270 adding quux/file.py revisions
271 calling hook pretxnchangegroup.acl: hgext.acl.hook
271 calling hook pretxnchangegroup.acl: hgext.acl.hook
272 acl: checking access for user "fred"
272 acl: checking access for user "fred"
273 acl: acl.allow.branches not enabled
273 acl: acl.allow.branches not enabled
274 acl: acl.deny.branches not enabled
274 acl: acl.deny.branches not enabled
275 acl: acl.allow not enabled
275 acl: acl.allow not enabled
276 acl: acl.deny not enabled
276 acl: acl.deny not enabled
277 acl: branch access granted: "ef1ea85a6374" on branch "default"
277 acl: branch access granted: "ef1ea85a6374" on branch "default"
278 acl: path access granted: "ef1ea85a6374"
278 acl: path access granted: "ef1ea85a6374"
279 acl: branch access granted: "f9cafe1212c8" on branch "default"
279 acl: branch access granted: "f9cafe1212c8" on branch "default"
280 acl: path access granted: "f9cafe1212c8"
280 acl: path access granted: "f9cafe1212c8"
281 acl: branch access granted: "911600dab2ae" on branch "default"
281 acl: branch access granted: "911600dab2ae" on branch "default"
282 acl: path access granted: "911600dab2ae"
282 acl: path access granted: "911600dab2ae"
283 bundle2-input-part: total payload size 1553
283 bundle2-input-part: total payload size 1553
284 bundle2-input-part: "phase-heads" supported
284 bundle2-input-part: "phase-heads" supported
285 bundle2-input-part: total payload size 24
285 bundle2-input-part: total payload size 24
286 bundle2-input-bundle: 5 parts total
286 bundle2-input-bundle: 5 parts total
287 truncating cache/rbc-revs-v1 to 8
287 truncating cache/rbc-revs-v1 to 8
288 updating the branch cache
288 updating the branch cache
289 added 3 changesets with 3 changes to 3 files
289 added 3 changesets with 3 changes to 3 files
290 bundle2-output-bundle: "HG20", 1 parts total
290 bundle2-output-bundle: "HG20", 1 parts total
291 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
291 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
292 bundle2-input-bundle: no-transaction
292 bundle2-input-bundle: no-transaction
293 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
293 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
294 bundle2-input-bundle: 1 parts total
294 bundle2-input-bundle: 1 parts total
295 listing keys for "phases"
295 listing keys for "phases"
296 repository tip rolled back to revision 0 (undo push)
296 repository tip rolled back to revision 0 (undo push)
297 0:6675d58eff77
297 0:6675d58eff77
298
298
299
299
300 Empty [acl.allow]
300 Empty [acl.allow]
301
301
302 $ echo '[acl.allow]' >> $config
302 $ echo '[acl.allow]' >> $config
303 $ do_push fred
303 $ do_push fred
304 Pushing as user fred
304 Pushing as user fred
305 hgrc = """
305 hgrc = """
306 [hooks]
306 [hooks]
307 pretxnchangegroup.acl = python:hgext.acl.hook
307 pretxnchangegroup.acl = python:hgext.acl.hook
308 prepushkey.acl = python:hgext.acl.hook
308 prepushkey.acl = python:hgext.acl.hook
309 [acl]
309 [acl]
310 sources = push
310 sources = push
311 [acl.allow]
311 [acl.allow]
312 """
312 """
313 pushing to ../b
313 pushing to ../b
314 query 1; heads
314 query 1; heads
315 searching for changes
315 searching for changes
316 all remote heads known locally
316 all remote heads known locally
317 listing keys for "phases"
317 listing keys for "phases"
318 checking for updated bookmarks
318 checking for updated bookmarks
319 listing keys for "bookmarks"
319 listing keys for "bookmarks"
320 invalid branch cache (served): tip differs
320 invalid branch cache (served): tip differs
321 listing keys for "bookmarks"
321 listing keys for "bookmarks"
322 3 changesets found
322 3 changesets found
323 list of changesets:
323 list of changesets:
324 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
324 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
325 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
325 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
326 911600dab2ae7a9baff75958b84fe606851ce955
326 911600dab2ae7a9baff75958b84fe606851ce955
327 bundle2-output-bundle: "HG20", 5 parts total
327 bundle2-output-bundle: "HG20", 5 parts total
328 bundle2-output-part: "replycaps" 224 bytes payload
328 bundle2-output-part: "replycaps" 207 bytes payload
329 bundle2-output-part: "check:phases" 24 bytes payload
329 bundle2-output-part: "check:phases" 24 bytes payload
330 bundle2-output-part: "check:updated-heads" streamed payload
330 bundle2-output-part: "check:updated-heads" streamed payload
331 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
331 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
332 bundle2-output-part: "phase-heads" 24 bytes payload
332 bundle2-output-part: "phase-heads" 24 bytes payload
333 bundle2-input-bundle: with-transaction
333 bundle2-input-bundle: with-transaction
334 bundle2-input-part: "replycaps" supported
334 bundle2-input-part: "replycaps" supported
335 bundle2-input-part: total payload size 224
335 bundle2-input-part: total payload size 207
336 bundle2-input-part: "check:phases" supported
336 bundle2-input-part: "check:phases" supported
337 bundle2-input-part: total payload size 24
337 bundle2-input-part: total payload size 24
338 bundle2-input-part: "check:updated-heads" supported
338 bundle2-input-part: "check:updated-heads" supported
339 bundle2-input-part: total payload size 20
339 bundle2-input-part: total payload size 20
340 invalid branch cache (served): tip differs
340 invalid branch cache (served): tip differs
341 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
341 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
342 adding changesets
342 adding changesets
343 add changeset ef1ea85a6374
343 add changeset ef1ea85a6374
344 add changeset f9cafe1212c8
344 add changeset f9cafe1212c8
345 add changeset 911600dab2ae
345 add changeset 911600dab2ae
346 adding manifests
346 adding manifests
347 adding file changes
347 adding file changes
348 adding foo/Bar/file.txt revisions
348 adding foo/Bar/file.txt revisions
349 adding foo/file.txt revisions
349 adding foo/file.txt revisions
350 adding quux/file.py revisions
350 adding quux/file.py revisions
351 calling hook pretxnchangegroup.acl: hgext.acl.hook
351 calling hook pretxnchangegroup.acl: hgext.acl.hook
352 acl: checking access for user "fred"
352 acl: checking access for user "fred"
353 acl: acl.allow.branches not enabled
353 acl: acl.allow.branches not enabled
354 acl: acl.deny.branches not enabled
354 acl: acl.deny.branches not enabled
355 acl: acl.allow enabled, 0 entries for user fred
355 acl: acl.allow enabled, 0 entries for user fred
356 acl: acl.deny not enabled
356 acl: acl.deny not enabled
357 acl: branch access granted: "ef1ea85a6374" on branch "default"
357 acl: branch access granted: "ef1ea85a6374" on branch "default"
358 error: pretxnchangegroup.acl hook failed: acl: user "fred" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
358 error: pretxnchangegroup.acl hook failed: acl: user "fred" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
359 bundle2-input-part: total payload size 1553
359 bundle2-input-part: total payload size 1553
360 bundle2-input-part: total payload size 24
360 bundle2-input-part: total payload size 24
361 bundle2-input-bundle: 5 parts total
361 bundle2-input-bundle: 5 parts total
362 transaction abort!
362 transaction abort!
363 rollback completed
363 rollback completed
364 abort: acl: user "fred" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
364 abort: acl: user "fred" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
365 no rollback information available
365 no rollback information available
366 0:6675d58eff77
366 0:6675d58eff77
367
367
368
368
369 fred is allowed inside foo/
369 fred is allowed inside foo/
370
370
371 $ echo 'foo/** = fred' >> $config
371 $ echo 'foo/** = fred' >> $config
372 $ do_push fred
372 $ do_push fred
373 Pushing as user fred
373 Pushing as user fred
374 hgrc = """
374 hgrc = """
375 [hooks]
375 [hooks]
376 pretxnchangegroup.acl = python:hgext.acl.hook
376 pretxnchangegroup.acl = python:hgext.acl.hook
377 prepushkey.acl = python:hgext.acl.hook
377 prepushkey.acl = python:hgext.acl.hook
378 [acl]
378 [acl]
379 sources = push
379 sources = push
380 [acl.allow]
380 [acl.allow]
381 foo/** = fred
381 foo/** = fred
382 """
382 """
383 pushing to ../b
383 pushing to ../b
384 query 1; heads
384 query 1; heads
385 searching for changes
385 searching for changes
386 all remote heads known locally
386 all remote heads known locally
387 listing keys for "phases"
387 listing keys for "phases"
388 checking for updated bookmarks
388 checking for updated bookmarks
389 listing keys for "bookmarks"
389 listing keys for "bookmarks"
390 invalid branch cache (served): tip differs
390 invalid branch cache (served): tip differs
391 listing keys for "bookmarks"
391 listing keys for "bookmarks"
392 3 changesets found
392 3 changesets found
393 list of changesets:
393 list of changesets:
394 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
394 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
395 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
395 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
396 911600dab2ae7a9baff75958b84fe606851ce955
396 911600dab2ae7a9baff75958b84fe606851ce955
397 bundle2-output-bundle: "HG20", 5 parts total
397 bundle2-output-bundle: "HG20", 5 parts total
398 bundle2-output-part: "replycaps" 224 bytes payload
398 bundle2-output-part: "replycaps" 207 bytes payload
399 bundle2-output-part: "check:phases" 24 bytes payload
399 bundle2-output-part: "check:phases" 24 bytes payload
400 bundle2-output-part: "check:updated-heads" streamed payload
400 bundle2-output-part: "check:updated-heads" streamed payload
401 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
401 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
402 bundle2-output-part: "phase-heads" 24 bytes payload
402 bundle2-output-part: "phase-heads" 24 bytes payload
403 bundle2-input-bundle: with-transaction
403 bundle2-input-bundle: with-transaction
404 bundle2-input-part: "replycaps" supported
404 bundle2-input-part: "replycaps" supported
405 bundle2-input-part: total payload size 224
405 bundle2-input-part: total payload size 207
406 bundle2-input-part: "check:phases" supported
406 bundle2-input-part: "check:phases" supported
407 bundle2-input-part: total payload size 24
407 bundle2-input-part: total payload size 24
408 bundle2-input-part: "check:updated-heads" supported
408 bundle2-input-part: "check:updated-heads" supported
409 bundle2-input-part: total payload size 20
409 bundle2-input-part: total payload size 20
410 invalid branch cache (served): tip differs
410 invalid branch cache (served): tip differs
411 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
411 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
412 adding changesets
412 adding changesets
413 add changeset ef1ea85a6374
413 add changeset ef1ea85a6374
414 add changeset f9cafe1212c8
414 add changeset f9cafe1212c8
415 add changeset 911600dab2ae
415 add changeset 911600dab2ae
416 adding manifests
416 adding manifests
417 adding file changes
417 adding file changes
418 adding foo/Bar/file.txt revisions
418 adding foo/Bar/file.txt revisions
419 adding foo/file.txt revisions
419 adding foo/file.txt revisions
420 adding quux/file.py revisions
420 adding quux/file.py revisions
421 calling hook pretxnchangegroup.acl: hgext.acl.hook
421 calling hook pretxnchangegroup.acl: hgext.acl.hook
422 acl: checking access for user "fred"
422 acl: checking access for user "fred"
423 acl: acl.allow.branches not enabled
423 acl: acl.allow.branches not enabled
424 acl: acl.deny.branches not enabled
424 acl: acl.deny.branches not enabled
425 acl: acl.allow enabled, 1 entries for user fred
425 acl: acl.allow enabled, 1 entries for user fred
426 acl: acl.deny not enabled
426 acl: acl.deny not enabled
427 acl: branch access granted: "ef1ea85a6374" on branch "default"
427 acl: branch access granted: "ef1ea85a6374" on branch "default"
428 acl: path access granted: "ef1ea85a6374"
428 acl: path access granted: "ef1ea85a6374"
429 acl: branch access granted: "f9cafe1212c8" on branch "default"
429 acl: branch access granted: "f9cafe1212c8" on branch "default"
430 acl: path access granted: "f9cafe1212c8"
430 acl: path access granted: "f9cafe1212c8"
431 acl: branch access granted: "911600dab2ae" on branch "default"
431 acl: branch access granted: "911600dab2ae" on branch "default"
432 error: pretxnchangegroup.acl hook failed: acl: user "fred" not allowed on "quux/file.py" (changeset "911600dab2ae")
432 error: pretxnchangegroup.acl hook failed: acl: user "fred" not allowed on "quux/file.py" (changeset "911600dab2ae")
433 bundle2-input-part: total payload size 1553
433 bundle2-input-part: total payload size 1553
434 bundle2-input-part: total payload size 24
434 bundle2-input-part: total payload size 24
435 bundle2-input-bundle: 5 parts total
435 bundle2-input-bundle: 5 parts total
436 transaction abort!
436 transaction abort!
437 rollback completed
437 rollback completed
438 abort: acl: user "fred" not allowed on "quux/file.py" (changeset "911600dab2ae")
438 abort: acl: user "fred" not allowed on "quux/file.py" (changeset "911600dab2ae")
439 no rollback information available
439 no rollback information available
440 0:6675d58eff77
440 0:6675d58eff77
441
441
442
442
443 Empty [acl.deny]
443 Empty [acl.deny]
444
444
445 $ echo '[acl.deny]' >> $config
445 $ echo '[acl.deny]' >> $config
446 $ do_push barney
446 $ do_push barney
447 Pushing as user barney
447 Pushing as user barney
448 hgrc = """
448 hgrc = """
449 [hooks]
449 [hooks]
450 pretxnchangegroup.acl = python:hgext.acl.hook
450 pretxnchangegroup.acl = python:hgext.acl.hook
451 prepushkey.acl = python:hgext.acl.hook
451 prepushkey.acl = python:hgext.acl.hook
452 [acl]
452 [acl]
453 sources = push
453 sources = push
454 [acl.allow]
454 [acl.allow]
455 foo/** = fred
455 foo/** = fred
456 [acl.deny]
456 [acl.deny]
457 """
457 """
458 pushing to ../b
458 pushing to ../b
459 query 1; heads
459 query 1; heads
460 searching for changes
460 searching for changes
461 all remote heads known locally
461 all remote heads known locally
462 listing keys for "phases"
462 listing keys for "phases"
463 checking for updated bookmarks
463 checking for updated bookmarks
464 listing keys for "bookmarks"
464 listing keys for "bookmarks"
465 invalid branch cache (served): tip differs
465 invalid branch cache (served): tip differs
466 listing keys for "bookmarks"
466 listing keys for "bookmarks"
467 3 changesets found
467 3 changesets found
468 list of changesets:
468 list of changesets:
469 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
469 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
470 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
470 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
471 911600dab2ae7a9baff75958b84fe606851ce955
471 911600dab2ae7a9baff75958b84fe606851ce955
472 bundle2-output-bundle: "HG20", 5 parts total
472 bundle2-output-bundle: "HG20", 5 parts total
473 bundle2-output-part: "replycaps" 224 bytes payload
473 bundle2-output-part: "replycaps" 207 bytes payload
474 bundle2-output-part: "check:phases" 24 bytes payload
474 bundle2-output-part: "check:phases" 24 bytes payload
475 bundle2-output-part: "check:updated-heads" streamed payload
475 bundle2-output-part: "check:updated-heads" streamed payload
476 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
476 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
477 bundle2-output-part: "phase-heads" 24 bytes payload
477 bundle2-output-part: "phase-heads" 24 bytes payload
478 bundle2-input-bundle: with-transaction
478 bundle2-input-bundle: with-transaction
479 bundle2-input-part: "replycaps" supported
479 bundle2-input-part: "replycaps" supported
480 bundle2-input-part: total payload size 224
480 bundle2-input-part: total payload size 207
481 bundle2-input-part: "check:phases" supported
481 bundle2-input-part: "check:phases" supported
482 bundle2-input-part: total payload size 24
482 bundle2-input-part: total payload size 24
483 bundle2-input-part: "check:updated-heads" supported
483 bundle2-input-part: "check:updated-heads" supported
484 bundle2-input-part: total payload size 20
484 bundle2-input-part: total payload size 20
485 invalid branch cache (served): tip differs
485 invalid branch cache (served): tip differs
486 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
486 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
487 adding changesets
487 adding changesets
488 add changeset ef1ea85a6374
488 add changeset ef1ea85a6374
489 add changeset f9cafe1212c8
489 add changeset f9cafe1212c8
490 add changeset 911600dab2ae
490 add changeset 911600dab2ae
491 adding manifests
491 adding manifests
492 adding file changes
492 adding file changes
493 adding foo/Bar/file.txt revisions
493 adding foo/Bar/file.txt revisions
494 adding foo/file.txt revisions
494 adding foo/file.txt revisions
495 adding quux/file.py revisions
495 adding quux/file.py revisions
496 calling hook pretxnchangegroup.acl: hgext.acl.hook
496 calling hook pretxnchangegroup.acl: hgext.acl.hook
497 acl: checking access for user "barney"
497 acl: checking access for user "barney"
498 acl: acl.allow.branches not enabled
498 acl: acl.allow.branches not enabled
499 acl: acl.deny.branches not enabled
499 acl: acl.deny.branches not enabled
500 acl: acl.allow enabled, 0 entries for user barney
500 acl: acl.allow enabled, 0 entries for user barney
501 acl: acl.deny enabled, 0 entries for user barney
501 acl: acl.deny enabled, 0 entries for user barney
502 acl: branch access granted: "ef1ea85a6374" on branch "default"
502 acl: branch access granted: "ef1ea85a6374" on branch "default"
503 error: pretxnchangegroup.acl hook failed: acl: user "barney" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
503 error: pretxnchangegroup.acl hook failed: acl: user "barney" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
504 bundle2-input-part: total payload size 1553
504 bundle2-input-part: total payload size 1553
505 bundle2-input-part: total payload size 24
505 bundle2-input-part: total payload size 24
506 bundle2-input-bundle: 5 parts total
506 bundle2-input-bundle: 5 parts total
507 transaction abort!
507 transaction abort!
508 rollback completed
508 rollback completed
509 abort: acl: user "barney" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
509 abort: acl: user "barney" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
510 no rollback information available
510 no rollback information available
511 0:6675d58eff77
511 0:6675d58eff77
512
512
513
513
514 fred is allowed inside foo/, but not foo/bar/ (case matters)
514 fred is allowed inside foo/, but not foo/bar/ (case matters)
515
515
516 $ echo 'foo/bar/** = fred' >> $config
516 $ echo 'foo/bar/** = fred' >> $config
517 $ do_push fred
517 $ do_push fred
518 Pushing as user fred
518 Pushing as user fred
519 hgrc = """
519 hgrc = """
520 [hooks]
520 [hooks]
521 pretxnchangegroup.acl = python:hgext.acl.hook
521 pretxnchangegroup.acl = python:hgext.acl.hook
522 prepushkey.acl = python:hgext.acl.hook
522 prepushkey.acl = python:hgext.acl.hook
523 [acl]
523 [acl]
524 sources = push
524 sources = push
525 [acl.allow]
525 [acl.allow]
526 foo/** = fred
526 foo/** = fred
527 [acl.deny]
527 [acl.deny]
528 foo/bar/** = fred
528 foo/bar/** = fred
529 """
529 """
530 pushing to ../b
530 pushing to ../b
531 query 1; heads
531 query 1; heads
532 searching for changes
532 searching for changes
533 all remote heads known locally
533 all remote heads known locally
534 listing keys for "phases"
534 listing keys for "phases"
535 checking for updated bookmarks
535 checking for updated bookmarks
536 listing keys for "bookmarks"
536 listing keys for "bookmarks"
537 invalid branch cache (served): tip differs
537 invalid branch cache (served): tip differs
538 listing keys for "bookmarks"
538 listing keys for "bookmarks"
539 3 changesets found
539 3 changesets found
540 list of changesets:
540 list of changesets:
541 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
541 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
542 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
542 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
543 911600dab2ae7a9baff75958b84fe606851ce955
543 911600dab2ae7a9baff75958b84fe606851ce955
544 bundle2-output-bundle: "HG20", 5 parts total
544 bundle2-output-bundle: "HG20", 5 parts total
545 bundle2-output-part: "replycaps" 224 bytes payload
545 bundle2-output-part: "replycaps" 207 bytes payload
546 bundle2-output-part: "check:phases" 24 bytes payload
546 bundle2-output-part: "check:phases" 24 bytes payload
547 bundle2-output-part: "check:updated-heads" streamed payload
547 bundle2-output-part: "check:updated-heads" streamed payload
548 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
548 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
549 bundle2-output-part: "phase-heads" 24 bytes payload
549 bundle2-output-part: "phase-heads" 24 bytes payload
550 bundle2-input-bundle: with-transaction
550 bundle2-input-bundle: with-transaction
551 bundle2-input-part: "replycaps" supported
551 bundle2-input-part: "replycaps" supported
552 bundle2-input-part: total payload size 224
552 bundle2-input-part: total payload size 207
553 bundle2-input-part: "check:phases" supported
553 bundle2-input-part: "check:phases" supported
554 bundle2-input-part: total payload size 24
554 bundle2-input-part: total payload size 24
555 bundle2-input-part: "check:updated-heads" supported
555 bundle2-input-part: "check:updated-heads" supported
556 bundle2-input-part: total payload size 20
556 bundle2-input-part: total payload size 20
557 invalid branch cache (served): tip differs
557 invalid branch cache (served): tip differs
558 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
558 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
559 adding changesets
559 adding changesets
560 add changeset ef1ea85a6374
560 add changeset ef1ea85a6374
561 add changeset f9cafe1212c8
561 add changeset f9cafe1212c8
562 add changeset 911600dab2ae
562 add changeset 911600dab2ae
563 adding manifests
563 adding manifests
564 adding file changes
564 adding file changes
565 adding foo/Bar/file.txt revisions
565 adding foo/Bar/file.txt revisions
566 adding foo/file.txt revisions
566 adding foo/file.txt revisions
567 adding quux/file.py revisions
567 adding quux/file.py revisions
568 calling hook pretxnchangegroup.acl: hgext.acl.hook
568 calling hook pretxnchangegroup.acl: hgext.acl.hook
569 acl: checking access for user "fred"
569 acl: checking access for user "fred"
570 acl: acl.allow.branches not enabled
570 acl: acl.allow.branches not enabled
571 acl: acl.deny.branches not enabled
571 acl: acl.deny.branches not enabled
572 acl: acl.allow enabled, 1 entries for user fred
572 acl: acl.allow enabled, 1 entries for user fred
573 acl: acl.deny enabled, 1 entries for user fred
573 acl: acl.deny enabled, 1 entries for user fred
574 acl: branch access granted: "ef1ea85a6374" on branch "default"
574 acl: branch access granted: "ef1ea85a6374" on branch "default"
575 acl: path access granted: "ef1ea85a6374"
575 acl: path access granted: "ef1ea85a6374"
576 acl: branch access granted: "f9cafe1212c8" on branch "default"
576 acl: branch access granted: "f9cafe1212c8" on branch "default"
577 acl: path access granted: "f9cafe1212c8"
577 acl: path access granted: "f9cafe1212c8"
578 acl: branch access granted: "911600dab2ae" on branch "default"
578 acl: branch access granted: "911600dab2ae" on branch "default"
579 error: pretxnchangegroup.acl hook failed: acl: user "fred" not allowed on "quux/file.py" (changeset "911600dab2ae")
579 error: pretxnchangegroup.acl hook failed: acl: user "fred" not allowed on "quux/file.py" (changeset "911600dab2ae")
580 bundle2-input-part: total payload size 1553
580 bundle2-input-part: total payload size 1553
581 bundle2-input-part: total payload size 24
581 bundle2-input-part: total payload size 24
582 bundle2-input-bundle: 5 parts total
582 bundle2-input-bundle: 5 parts total
583 transaction abort!
583 transaction abort!
584 rollback completed
584 rollback completed
585 abort: acl: user "fred" not allowed on "quux/file.py" (changeset "911600dab2ae")
585 abort: acl: user "fred" not allowed on "quux/file.py" (changeset "911600dab2ae")
586 no rollback information available
586 no rollback information available
587 0:6675d58eff77
587 0:6675d58eff77
588
588
589
589
590 fred is allowed inside foo/, but not foo/Bar/
590 fred is allowed inside foo/, but not foo/Bar/
591
591
592 $ echo 'foo/Bar/** = fred' >> $config
592 $ echo 'foo/Bar/** = fred' >> $config
593 $ do_push fred
593 $ do_push fred
594 Pushing as user fred
594 Pushing as user fred
595 hgrc = """
595 hgrc = """
596 [hooks]
596 [hooks]
597 pretxnchangegroup.acl = python:hgext.acl.hook
597 pretxnchangegroup.acl = python:hgext.acl.hook
598 prepushkey.acl = python:hgext.acl.hook
598 prepushkey.acl = python:hgext.acl.hook
599 [acl]
599 [acl]
600 sources = push
600 sources = push
601 [acl.allow]
601 [acl.allow]
602 foo/** = fred
602 foo/** = fred
603 [acl.deny]
603 [acl.deny]
604 foo/bar/** = fred
604 foo/bar/** = fred
605 foo/Bar/** = fred
605 foo/Bar/** = fred
606 """
606 """
607 pushing to ../b
607 pushing to ../b
608 query 1; heads
608 query 1; heads
609 searching for changes
609 searching for changes
610 all remote heads known locally
610 all remote heads known locally
611 listing keys for "phases"
611 listing keys for "phases"
612 checking for updated bookmarks
612 checking for updated bookmarks
613 listing keys for "bookmarks"
613 listing keys for "bookmarks"
614 invalid branch cache (served): tip differs
614 invalid branch cache (served): tip differs
615 listing keys for "bookmarks"
615 listing keys for "bookmarks"
616 3 changesets found
616 3 changesets found
617 list of changesets:
617 list of changesets:
618 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
618 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
619 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
619 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
620 911600dab2ae7a9baff75958b84fe606851ce955
620 911600dab2ae7a9baff75958b84fe606851ce955
621 bundle2-output-bundle: "HG20", 5 parts total
621 bundle2-output-bundle: "HG20", 5 parts total
622 bundle2-output-part: "replycaps" 224 bytes payload
622 bundle2-output-part: "replycaps" 207 bytes payload
623 bundle2-output-part: "check:phases" 24 bytes payload
623 bundle2-output-part: "check:phases" 24 bytes payload
624 bundle2-output-part: "check:updated-heads" streamed payload
624 bundle2-output-part: "check:updated-heads" streamed payload
625 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
625 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
626 bundle2-output-part: "phase-heads" 24 bytes payload
626 bundle2-output-part: "phase-heads" 24 bytes payload
627 bundle2-input-bundle: with-transaction
627 bundle2-input-bundle: with-transaction
628 bundle2-input-part: "replycaps" supported
628 bundle2-input-part: "replycaps" supported
629 bundle2-input-part: total payload size 224
629 bundle2-input-part: total payload size 207
630 bundle2-input-part: "check:phases" supported
630 bundle2-input-part: "check:phases" supported
631 bundle2-input-part: total payload size 24
631 bundle2-input-part: total payload size 24
632 bundle2-input-part: "check:updated-heads" supported
632 bundle2-input-part: "check:updated-heads" supported
633 bundle2-input-part: total payload size 20
633 bundle2-input-part: total payload size 20
634 invalid branch cache (served): tip differs
634 invalid branch cache (served): tip differs
635 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
635 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
636 adding changesets
636 adding changesets
637 add changeset ef1ea85a6374
637 add changeset ef1ea85a6374
638 add changeset f9cafe1212c8
638 add changeset f9cafe1212c8
639 add changeset 911600dab2ae
639 add changeset 911600dab2ae
640 adding manifests
640 adding manifests
641 adding file changes
641 adding file changes
642 adding foo/Bar/file.txt revisions
642 adding foo/Bar/file.txt revisions
643 adding foo/file.txt revisions
643 adding foo/file.txt revisions
644 adding quux/file.py revisions
644 adding quux/file.py revisions
645 calling hook pretxnchangegroup.acl: hgext.acl.hook
645 calling hook pretxnchangegroup.acl: hgext.acl.hook
646 acl: checking access for user "fred"
646 acl: checking access for user "fred"
647 acl: acl.allow.branches not enabled
647 acl: acl.allow.branches not enabled
648 acl: acl.deny.branches not enabled
648 acl: acl.deny.branches not enabled
649 acl: acl.allow enabled, 1 entries for user fred
649 acl: acl.allow enabled, 1 entries for user fred
650 acl: acl.deny enabled, 2 entries for user fred
650 acl: acl.deny enabled, 2 entries for user fred
651 acl: branch access granted: "ef1ea85a6374" on branch "default"
651 acl: branch access granted: "ef1ea85a6374" on branch "default"
652 acl: path access granted: "ef1ea85a6374"
652 acl: path access granted: "ef1ea85a6374"
653 acl: branch access granted: "f9cafe1212c8" on branch "default"
653 acl: branch access granted: "f9cafe1212c8" on branch "default"
654 error: pretxnchangegroup.acl hook failed: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
654 error: pretxnchangegroup.acl hook failed: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
655 bundle2-input-part: total payload size 1553
655 bundle2-input-part: total payload size 1553
656 bundle2-input-part: total payload size 24
656 bundle2-input-part: total payload size 24
657 bundle2-input-bundle: 5 parts total
657 bundle2-input-bundle: 5 parts total
658 transaction abort!
658 transaction abort!
659 rollback completed
659 rollback completed
660 abort: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
660 abort: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
661 no rollback information available
661 no rollback information available
662 0:6675d58eff77
662 0:6675d58eff77
663
663
664
664
665 $ echo 'barney is not mentioned => not allowed anywhere'
665 $ echo 'barney is not mentioned => not allowed anywhere'
666 barney is not mentioned => not allowed anywhere
666 barney is not mentioned => not allowed anywhere
667 $ do_push barney
667 $ do_push barney
668 Pushing as user barney
668 Pushing as user barney
669 hgrc = """
669 hgrc = """
670 [hooks]
670 [hooks]
671 pretxnchangegroup.acl = python:hgext.acl.hook
671 pretxnchangegroup.acl = python:hgext.acl.hook
672 prepushkey.acl = python:hgext.acl.hook
672 prepushkey.acl = python:hgext.acl.hook
673 [acl]
673 [acl]
674 sources = push
674 sources = push
675 [acl.allow]
675 [acl.allow]
676 foo/** = fred
676 foo/** = fred
677 [acl.deny]
677 [acl.deny]
678 foo/bar/** = fred
678 foo/bar/** = fred
679 foo/Bar/** = fred
679 foo/Bar/** = fred
680 """
680 """
681 pushing to ../b
681 pushing to ../b
682 query 1; heads
682 query 1; heads
683 searching for changes
683 searching for changes
684 all remote heads known locally
684 all remote heads known locally
685 listing keys for "phases"
685 listing keys for "phases"
686 checking for updated bookmarks
686 checking for updated bookmarks
687 listing keys for "bookmarks"
687 listing keys for "bookmarks"
688 invalid branch cache (served): tip differs
688 invalid branch cache (served): tip differs
689 listing keys for "bookmarks"
689 listing keys for "bookmarks"
690 3 changesets found
690 3 changesets found
691 list of changesets:
691 list of changesets:
692 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
692 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
693 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
693 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
694 911600dab2ae7a9baff75958b84fe606851ce955
694 911600dab2ae7a9baff75958b84fe606851ce955
695 bundle2-output-bundle: "HG20", 5 parts total
695 bundle2-output-bundle: "HG20", 5 parts total
696 bundle2-output-part: "replycaps" 224 bytes payload
696 bundle2-output-part: "replycaps" 207 bytes payload
697 bundle2-output-part: "check:phases" 24 bytes payload
697 bundle2-output-part: "check:phases" 24 bytes payload
698 bundle2-output-part: "check:updated-heads" streamed payload
698 bundle2-output-part: "check:updated-heads" streamed payload
699 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
699 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
700 bundle2-output-part: "phase-heads" 24 bytes payload
700 bundle2-output-part: "phase-heads" 24 bytes payload
701 bundle2-input-bundle: with-transaction
701 bundle2-input-bundle: with-transaction
702 bundle2-input-part: "replycaps" supported
702 bundle2-input-part: "replycaps" supported
703 bundle2-input-part: total payload size 224
703 bundle2-input-part: total payload size 207
704 bundle2-input-part: "check:phases" supported
704 bundle2-input-part: "check:phases" supported
705 bundle2-input-part: total payload size 24
705 bundle2-input-part: total payload size 24
706 bundle2-input-part: "check:updated-heads" supported
706 bundle2-input-part: "check:updated-heads" supported
707 bundle2-input-part: total payload size 20
707 bundle2-input-part: total payload size 20
708 invalid branch cache (served): tip differs
708 invalid branch cache (served): tip differs
709 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
709 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
710 adding changesets
710 adding changesets
711 add changeset ef1ea85a6374
711 add changeset ef1ea85a6374
712 add changeset f9cafe1212c8
712 add changeset f9cafe1212c8
713 add changeset 911600dab2ae
713 add changeset 911600dab2ae
714 adding manifests
714 adding manifests
715 adding file changes
715 adding file changes
716 adding foo/Bar/file.txt revisions
716 adding foo/Bar/file.txt revisions
717 adding foo/file.txt revisions
717 adding foo/file.txt revisions
718 adding quux/file.py revisions
718 adding quux/file.py revisions
719 calling hook pretxnchangegroup.acl: hgext.acl.hook
719 calling hook pretxnchangegroup.acl: hgext.acl.hook
720 acl: checking access for user "barney"
720 acl: checking access for user "barney"
721 acl: acl.allow.branches not enabled
721 acl: acl.allow.branches not enabled
722 acl: acl.deny.branches not enabled
722 acl: acl.deny.branches not enabled
723 acl: acl.allow enabled, 0 entries for user barney
723 acl: acl.allow enabled, 0 entries for user barney
724 acl: acl.deny enabled, 0 entries for user barney
724 acl: acl.deny enabled, 0 entries for user barney
725 acl: branch access granted: "ef1ea85a6374" on branch "default"
725 acl: branch access granted: "ef1ea85a6374" on branch "default"
726 error: pretxnchangegroup.acl hook failed: acl: user "barney" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
726 error: pretxnchangegroup.acl hook failed: acl: user "barney" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
727 bundle2-input-part: total payload size 1553
727 bundle2-input-part: total payload size 1553
728 bundle2-input-part: total payload size 24
728 bundle2-input-part: total payload size 24
729 bundle2-input-bundle: 5 parts total
729 bundle2-input-bundle: 5 parts total
730 transaction abort!
730 transaction abort!
731 rollback completed
731 rollback completed
732 abort: acl: user "barney" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
732 abort: acl: user "barney" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
733 no rollback information available
733 no rollback information available
734 0:6675d58eff77
734 0:6675d58eff77
735
735
736
736
737 fred is not blocked from moving bookmarks
737 fred is not blocked from moving bookmarks
738
738
739 $ hg -R a book -q moving-bookmark -r 1
739 $ hg -R a book -q moving-bookmark -r 1
740 $ hg -R b book -q moving-bookmark -r 0
740 $ hg -R b book -q moving-bookmark -r 0
741 $ cp $config normalconfig
741 $ cp $config normalconfig
742 $ do_push fred -r 1
742 $ do_push fred -r 1
743 Pushing as user fred
743 Pushing as user fred
744 hgrc = """
744 hgrc = """
745 [hooks]
745 [hooks]
746 pretxnchangegroup.acl = python:hgext.acl.hook
746 pretxnchangegroup.acl = python:hgext.acl.hook
747 prepushkey.acl = python:hgext.acl.hook
747 prepushkey.acl = python:hgext.acl.hook
748 [acl]
748 [acl]
749 sources = push
749 sources = push
750 [acl.allow]
750 [acl.allow]
751 foo/** = fred
751 foo/** = fred
752 [acl.deny]
752 [acl.deny]
753 foo/bar/** = fred
753 foo/bar/** = fred
754 foo/Bar/** = fred
754 foo/Bar/** = fred
755 """
755 """
756 pushing to ../b
756 pushing to ../b
757 query 1; heads
757 query 1; heads
758 searching for changes
758 searching for changes
759 all remote heads known locally
759 all remote heads known locally
760 listing keys for "phases"
760 listing keys for "phases"
761 checking for updated bookmarks
761 checking for updated bookmarks
762 listing keys for "bookmarks"
762 listing keys for "bookmarks"
763 invalid branch cache (served): tip differs
763 invalid branch cache (served): tip differs
764 listing keys for "bookmarks"
764 listing keys for "bookmarks"
765 1 changesets found
765 1 changesets found
766 list of changesets:
766 list of changesets:
767 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
767 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
768 bundle2-output-bundle: "HG20", 7 parts total
768 bundle2-output-bundle: "HG20", 7 parts total
769 bundle2-output-part: "replycaps" 224 bytes payload
769 bundle2-output-part: "replycaps" 207 bytes payload
770 bundle2-output-part: "check:bookmarks" 37 bytes payload
770 bundle2-output-part: "check:bookmarks" 37 bytes payload
771 bundle2-output-part: "check:phases" 24 bytes payload
771 bundle2-output-part: "check:phases" 24 bytes payload
772 bundle2-output-part: "check:updated-heads" streamed payload
772 bundle2-output-part: "check:updated-heads" streamed payload
773 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
773 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
774 bundle2-output-part: "phase-heads" 24 bytes payload
774 bundle2-output-part: "phase-heads" 24 bytes payload
775 bundle2-output-part: "bookmarks" 37 bytes payload
775 bundle2-output-part: "bookmarks" 37 bytes payload
776 bundle2-input-bundle: with-transaction
776 bundle2-input-bundle: with-transaction
777 bundle2-input-part: "replycaps" supported
777 bundle2-input-part: "replycaps" supported
778 bundle2-input-part: total payload size 224
778 bundle2-input-part: total payload size 207
779 bundle2-input-part: "check:bookmarks" supported
779 bundle2-input-part: "check:bookmarks" supported
780 bundle2-input-part: total payload size 37
780 bundle2-input-part: total payload size 37
781 bundle2-input-part: "check:phases" supported
781 bundle2-input-part: "check:phases" supported
782 bundle2-input-part: total payload size 24
782 bundle2-input-part: total payload size 24
783 bundle2-input-part: "check:updated-heads" supported
783 bundle2-input-part: "check:updated-heads" supported
784 bundle2-input-part: total payload size 20
784 bundle2-input-part: total payload size 20
785 invalid branch cache (served): tip differs
785 invalid branch cache (served): tip differs
786 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
786 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
787 adding changesets
787 adding changesets
788 add changeset ef1ea85a6374
788 add changeset ef1ea85a6374
789 adding manifests
789 adding manifests
790 adding file changes
790 adding file changes
791 adding foo/file.txt revisions
791 adding foo/file.txt revisions
792 calling hook pretxnchangegroup.acl: hgext.acl.hook
792 calling hook pretxnchangegroup.acl: hgext.acl.hook
793 acl: checking access for user "fred"
793 acl: checking access for user "fred"
794 acl: acl.allow.branches not enabled
794 acl: acl.allow.branches not enabled
795 acl: acl.deny.branches not enabled
795 acl: acl.deny.branches not enabled
796 acl: acl.allow enabled, 1 entries for user fred
796 acl: acl.allow enabled, 1 entries for user fred
797 acl: acl.deny enabled, 2 entries for user fred
797 acl: acl.deny enabled, 2 entries for user fred
798 acl: branch access granted: "ef1ea85a6374" on branch "default"
798 acl: branch access granted: "ef1ea85a6374" on branch "default"
799 acl: path access granted: "ef1ea85a6374"
799 acl: path access granted: "ef1ea85a6374"
800 bundle2-input-part: total payload size 520
800 bundle2-input-part: total payload size 520
801 bundle2-input-part: "phase-heads" supported
801 bundle2-input-part: "phase-heads" supported
802 bundle2-input-part: total payload size 24
802 bundle2-input-part: total payload size 24
803 bundle2-input-part: "bookmarks" supported
803 bundle2-input-part: "bookmarks" supported
804 bundle2-input-part: total payload size 37
804 bundle2-input-part: total payload size 37
805 calling hook prepushkey.acl: hgext.acl.hook
805 calling hook prepushkey.acl: hgext.acl.hook
806 acl: checking access for user "fred"
806 acl: checking access for user "fred"
807 acl: acl.allow.bookmarks not enabled
807 acl: acl.allow.bookmarks not enabled
808 acl: acl.deny.bookmarks not enabled
808 acl: acl.deny.bookmarks not enabled
809 acl: bookmark access granted: "ef1ea85a6374b77d6da9dcda9541f498f2d17df7" on bookmark "moving-bookmark"
809 acl: bookmark access granted: "ef1ea85a6374b77d6da9dcda9541f498f2d17df7" on bookmark "moving-bookmark"
810 bundle2-input-bundle: 7 parts total
810 bundle2-input-bundle: 7 parts total
811 truncating cache/rbc-revs-v1 to 8
811 truncating cache/rbc-revs-v1 to 8
812 updating the branch cache
812 updating the branch cache
813 invalid branch cache (served.hidden): tip differs
813 invalid branch cache (served.hidden): tip differs
814 added 1 changesets with 1 changes to 1 files
814 added 1 changesets with 1 changes to 1 files
815 bundle2-output-bundle: "HG20", 1 parts total
815 bundle2-output-bundle: "HG20", 1 parts total
816 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
816 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
817 bundle2-input-bundle: no-transaction
817 bundle2-input-bundle: no-transaction
818 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
818 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
819 bundle2-input-bundle: 1 parts total
819 bundle2-input-bundle: 1 parts total
820 updating bookmark moving-bookmark
820 updating bookmark moving-bookmark
821 listing keys for "phases"
821 listing keys for "phases"
822 repository tip rolled back to revision 0 (undo push)
822 repository tip rolled back to revision 0 (undo push)
823 0:6675d58eff77
823 0:6675d58eff77
824
824
825
825
826 fred is not allowed to move bookmarks
826 fred is not allowed to move bookmarks
827
827
828 $ echo '[acl.deny.bookmarks]' >> $config
828 $ echo '[acl.deny.bookmarks]' >> $config
829 $ echo '* = fred' >> $config
829 $ echo '* = fred' >> $config
830 $ do_push fred -r 1
830 $ do_push fred -r 1
831 Pushing as user fred
831 Pushing as user fred
832 hgrc = """
832 hgrc = """
833 [hooks]
833 [hooks]
834 pretxnchangegroup.acl = python:hgext.acl.hook
834 pretxnchangegroup.acl = python:hgext.acl.hook
835 prepushkey.acl = python:hgext.acl.hook
835 prepushkey.acl = python:hgext.acl.hook
836 [acl]
836 [acl]
837 sources = push
837 sources = push
838 [acl.allow]
838 [acl.allow]
839 foo/** = fred
839 foo/** = fred
840 [acl.deny]
840 [acl.deny]
841 foo/bar/** = fred
841 foo/bar/** = fred
842 foo/Bar/** = fred
842 foo/Bar/** = fred
843 [acl.deny.bookmarks]
843 [acl.deny.bookmarks]
844 * = fred
844 * = fred
845 """
845 """
846 pushing to ../b
846 pushing to ../b
847 query 1; heads
847 query 1; heads
848 searching for changes
848 searching for changes
849 all remote heads known locally
849 all remote heads known locally
850 listing keys for "phases"
850 listing keys for "phases"
851 checking for updated bookmarks
851 checking for updated bookmarks
852 listing keys for "bookmarks"
852 listing keys for "bookmarks"
853 invalid branch cache (served): tip differs
853 invalid branch cache (served): tip differs
854 listing keys for "bookmarks"
854 listing keys for "bookmarks"
855 1 changesets found
855 1 changesets found
856 list of changesets:
856 list of changesets:
857 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
857 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
858 bundle2-output-bundle: "HG20", 7 parts total
858 bundle2-output-bundle: "HG20", 7 parts total
859 bundle2-output-part: "replycaps" 224 bytes payload
859 bundle2-output-part: "replycaps" 207 bytes payload
860 bundle2-output-part: "check:bookmarks" 37 bytes payload
860 bundle2-output-part: "check:bookmarks" 37 bytes payload
861 bundle2-output-part: "check:phases" 24 bytes payload
861 bundle2-output-part: "check:phases" 24 bytes payload
862 bundle2-output-part: "check:updated-heads" streamed payload
862 bundle2-output-part: "check:updated-heads" streamed payload
863 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
863 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
864 bundle2-output-part: "phase-heads" 24 bytes payload
864 bundle2-output-part: "phase-heads" 24 bytes payload
865 bundle2-output-part: "bookmarks" 37 bytes payload
865 bundle2-output-part: "bookmarks" 37 bytes payload
866 bundle2-input-bundle: with-transaction
866 bundle2-input-bundle: with-transaction
867 bundle2-input-part: "replycaps" supported
867 bundle2-input-part: "replycaps" supported
868 bundle2-input-part: total payload size 224
868 bundle2-input-part: total payload size 207
869 bundle2-input-part: "check:bookmarks" supported
869 bundle2-input-part: "check:bookmarks" supported
870 bundle2-input-part: total payload size 37
870 bundle2-input-part: total payload size 37
871 bundle2-input-part: "check:phases" supported
871 bundle2-input-part: "check:phases" supported
872 bundle2-input-part: total payload size 24
872 bundle2-input-part: total payload size 24
873 bundle2-input-part: "check:updated-heads" supported
873 bundle2-input-part: "check:updated-heads" supported
874 bundle2-input-part: total payload size 20
874 bundle2-input-part: total payload size 20
875 invalid branch cache (served): tip differs
875 invalid branch cache (served): tip differs
876 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
876 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
877 adding changesets
877 adding changesets
878 add changeset ef1ea85a6374
878 add changeset ef1ea85a6374
879 adding manifests
879 adding manifests
880 adding file changes
880 adding file changes
881 adding foo/file.txt revisions
881 adding foo/file.txt revisions
882 calling hook pretxnchangegroup.acl: hgext.acl.hook
882 calling hook pretxnchangegroup.acl: hgext.acl.hook
883 acl: checking access for user "fred"
883 acl: checking access for user "fred"
884 acl: acl.allow.branches not enabled
884 acl: acl.allow.branches not enabled
885 acl: acl.deny.branches not enabled
885 acl: acl.deny.branches not enabled
886 acl: acl.allow enabled, 1 entries for user fred
886 acl: acl.allow enabled, 1 entries for user fred
887 acl: acl.deny enabled, 2 entries for user fred
887 acl: acl.deny enabled, 2 entries for user fred
888 acl: branch access granted: "ef1ea85a6374" on branch "default"
888 acl: branch access granted: "ef1ea85a6374" on branch "default"
889 acl: path access granted: "ef1ea85a6374"
889 acl: path access granted: "ef1ea85a6374"
890 bundle2-input-part: total payload size 520
890 bundle2-input-part: total payload size 520
891 bundle2-input-part: "phase-heads" supported
891 bundle2-input-part: "phase-heads" supported
892 bundle2-input-part: total payload size 24
892 bundle2-input-part: total payload size 24
893 bundle2-input-part: "bookmarks" supported
893 bundle2-input-part: "bookmarks" supported
894 bundle2-input-part: total payload size 37
894 bundle2-input-part: total payload size 37
895 calling hook prepushkey.acl: hgext.acl.hook
895 calling hook prepushkey.acl: hgext.acl.hook
896 acl: checking access for user "fred"
896 acl: checking access for user "fred"
897 acl: acl.allow.bookmarks not enabled
897 acl: acl.allow.bookmarks not enabled
898 acl: acl.deny.bookmarks enabled, 1 entries for user fred
898 acl: acl.deny.bookmarks enabled, 1 entries for user fred
899 error: prepushkey.acl hook failed: acl: user "fred" denied on bookmark "moving-bookmark" (changeset "ef1ea85a6374b77d6da9dcda9541f498f2d17df7")
899 error: prepushkey.acl hook failed: acl: user "fred" denied on bookmark "moving-bookmark" (changeset "ef1ea85a6374b77d6da9dcda9541f498f2d17df7")
900 bundle2-input-bundle: 7 parts total
900 bundle2-input-bundle: 7 parts total
901 transaction abort!
901 transaction abort!
902 rollback completed
902 rollback completed
903 abort: acl: user "fred" denied on bookmark "moving-bookmark" (changeset "ef1ea85a6374b77d6da9dcda9541f498f2d17df7")
903 abort: acl: user "fred" denied on bookmark "moving-bookmark" (changeset "ef1ea85a6374b77d6da9dcda9541f498f2d17df7")
904 no rollback information available
904 no rollback information available
905 0:6675d58eff77
905 0:6675d58eff77
906
906
907
907
908 cleanup bookmark stuff
908 cleanup bookmark stuff
909
909
910 $ hg book -R a -d moving-bookmark
910 $ hg book -R a -d moving-bookmark
911 $ hg book -R b -d moving-bookmark
911 $ hg book -R b -d moving-bookmark
912 $ cp normalconfig $config
912 $ cp normalconfig $config
913
913
914 barney is allowed everywhere
914 barney is allowed everywhere
915
915
916 $ echo '[acl.allow]' >> $config
916 $ echo '[acl.allow]' >> $config
917 $ echo '** = barney' >> $config
917 $ echo '** = barney' >> $config
918 $ do_push barney
918 $ do_push barney
919 Pushing as user barney
919 Pushing as user barney
920 hgrc = """
920 hgrc = """
921 [hooks]
921 [hooks]
922 pretxnchangegroup.acl = python:hgext.acl.hook
922 pretxnchangegroup.acl = python:hgext.acl.hook
923 prepushkey.acl = python:hgext.acl.hook
923 prepushkey.acl = python:hgext.acl.hook
924 [acl]
924 [acl]
925 sources = push
925 sources = push
926 [acl.allow]
926 [acl.allow]
927 foo/** = fred
927 foo/** = fred
928 [acl.deny]
928 [acl.deny]
929 foo/bar/** = fred
929 foo/bar/** = fred
930 foo/Bar/** = fred
930 foo/Bar/** = fred
931 [acl.allow]
931 [acl.allow]
932 ** = barney
932 ** = barney
933 """
933 """
934 pushing to ../b
934 pushing to ../b
935 query 1; heads
935 query 1; heads
936 searching for changes
936 searching for changes
937 all remote heads known locally
937 all remote heads known locally
938 listing keys for "phases"
938 listing keys for "phases"
939 checking for updated bookmarks
939 checking for updated bookmarks
940 listing keys for "bookmarks"
940 listing keys for "bookmarks"
941 invalid branch cache (served): tip differs
941 invalid branch cache (served): tip differs
942 listing keys for "bookmarks"
942 listing keys for "bookmarks"
943 3 changesets found
943 3 changesets found
944 list of changesets:
944 list of changesets:
945 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
945 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
946 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
946 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
947 911600dab2ae7a9baff75958b84fe606851ce955
947 911600dab2ae7a9baff75958b84fe606851ce955
948 bundle2-output-bundle: "HG20", 5 parts total
948 bundle2-output-bundle: "HG20", 5 parts total
949 bundle2-output-part: "replycaps" 224 bytes payload
949 bundle2-output-part: "replycaps" 207 bytes payload
950 bundle2-output-part: "check:phases" 24 bytes payload
950 bundle2-output-part: "check:phases" 24 bytes payload
951 bundle2-output-part: "check:updated-heads" streamed payload
951 bundle2-output-part: "check:updated-heads" streamed payload
952 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
952 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
953 bundle2-output-part: "phase-heads" 24 bytes payload
953 bundle2-output-part: "phase-heads" 24 bytes payload
954 bundle2-input-bundle: with-transaction
954 bundle2-input-bundle: with-transaction
955 bundle2-input-part: "replycaps" supported
955 bundle2-input-part: "replycaps" supported
956 bundle2-input-part: total payload size 224
956 bundle2-input-part: total payload size 207
957 bundle2-input-part: "check:phases" supported
957 bundle2-input-part: "check:phases" supported
958 bundle2-input-part: total payload size 24
958 bundle2-input-part: total payload size 24
959 bundle2-input-part: "check:updated-heads" supported
959 bundle2-input-part: "check:updated-heads" supported
960 bundle2-input-part: total payload size 20
960 bundle2-input-part: total payload size 20
961 invalid branch cache (served): tip differs
961 invalid branch cache (served): tip differs
962 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
962 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
963 adding changesets
963 adding changesets
964 add changeset ef1ea85a6374
964 add changeset ef1ea85a6374
965 add changeset f9cafe1212c8
965 add changeset f9cafe1212c8
966 add changeset 911600dab2ae
966 add changeset 911600dab2ae
967 adding manifests
967 adding manifests
968 adding file changes
968 adding file changes
969 adding foo/Bar/file.txt revisions
969 adding foo/Bar/file.txt revisions
970 adding foo/file.txt revisions
970 adding foo/file.txt revisions
971 adding quux/file.py revisions
971 adding quux/file.py revisions
972 calling hook pretxnchangegroup.acl: hgext.acl.hook
972 calling hook pretxnchangegroup.acl: hgext.acl.hook
973 acl: checking access for user "barney"
973 acl: checking access for user "barney"
974 acl: acl.allow.branches not enabled
974 acl: acl.allow.branches not enabled
975 acl: acl.deny.branches not enabled
975 acl: acl.deny.branches not enabled
976 acl: acl.allow enabled, 1 entries for user barney
976 acl: acl.allow enabled, 1 entries for user barney
977 acl: acl.deny enabled, 0 entries for user barney
977 acl: acl.deny enabled, 0 entries for user barney
978 acl: branch access granted: "ef1ea85a6374" on branch "default"
978 acl: branch access granted: "ef1ea85a6374" on branch "default"
979 acl: path access granted: "ef1ea85a6374"
979 acl: path access granted: "ef1ea85a6374"
980 acl: branch access granted: "f9cafe1212c8" on branch "default"
980 acl: branch access granted: "f9cafe1212c8" on branch "default"
981 acl: path access granted: "f9cafe1212c8"
981 acl: path access granted: "f9cafe1212c8"
982 acl: branch access granted: "911600dab2ae" on branch "default"
982 acl: branch access granted: "911600dab2ae" on branch "default"
983 acl: path access granted: "911600dab2ae"
983 acl: path access granted: "911600dab2ae"
984 bundle2-input-part: total payload size 1553
984 bundle2-input-part: total payload size 1553
985 bundle2-input-part: "phase-heads" supported
985 bundle2-input-part: "phase-heads" supported
986 bundle2-input-part: total payload size 24
986 bundle2-input-part: total payload size 24
987 bundle2-input-bundle: 5 parts total
987 bundle2-input-bundle: 5 parts total
988 truncating cache/rbc-revs-v1 to 8
988 truncating cache/rbc-revs-v1 to 8
989 updating the branch cache
989 updating the branch cache
990 added 3 changesets with 3 changes to 3 files
990 added 3 changesets with 3 changes to 3 files
991 bundle2-output-bundle: "HG20", 1 parts total
991 bundle2-output-bundle: "HG20", 1 parts total
992 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
992 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
993 bundle2-input-bundle: no-transaction
993 bundle2-input-bundle: no-transaction
994 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
994 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
995 bundle2-input-bundle: 1 parts total
995 bundle2-input-bundle: 1 parts total
996 listing keys for "phases"
996 listing keys for "phases"
997 repository tip rolled back to revision 0 (undo push)
997 repository tip rolled back to revision 0 (undo push)
998 0:6675d58eff77
998 0:6675d58eff77
999
999
1000
1000
1001 wilma can change files with a .txt extension
1001 wilma can change files with a .txt extension
1002
1002
1003 $ echo '**/*.txt = wilma' >> $config
1003 $ echo '**/*.txt = wilma' >> $config
1004 $ do_push wilma
1004 $ do_push wilma
1005 Pushing as user wilma
1005 Pushing as user wilma
1006 hgrc = """
1006 hgrc = """
1007 [hooks]
1007 [hooks]
1008 pretxnchangegroup.acl = python:hgext.acl.hook
1008 pretxnchangegroup.acl = python:hgext.acl.hook
1009 prepushkey.acl = python:hgext.acl.hook
1009 prepushkey.acl = python:hgext.acl.hook
1010 [acl]
1010 [acl]
1011 sources = push
1011 sources = push
1012 [acl.allow]
1012 [acl.allow]
1013 foo/** = fred
1013 foo/** = fred
1014 [acl.deny]
1014 [acl.deny]
1015 foo/bar/** = fred
1015 foo/bar/** = fred
1016 foo/Bar/** = fred
1016 foo/Bar/** = fred
1017 [acl.allow]
1017 [acl.allow]
1018 ** = barney
1018 ** = barney
1019 **/*.txt = wilma
1019 **/*.txt = wilma
1020 """
1020 """
1021 pushing to ../b
1021 pushing to ../b
1022 query 1; heads
1022 query 1; heads
1023 searching for changes
1023 searching for changes
1024 all remote heads known locally
1024 all remote heads known locally
1025 listing keys for "phases"
1025 listing keys for "phases"
1026 checking for updated bookmarks
1026 checking for updated bookmarks
1027 listing keys for "bookmarks"
1027 listing keys for "bookmarks"
1028 invalid branch cache (served): tip differs
1028 invalid branch cache (served): tip differs
1029 listing keys for "bookmarks"
1029 listing keys for "bookmarks"
1030 3 changesets found
1030 3 changesets found
1031 list of changesets:
1031 list of changesets:
1032 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1032 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1033 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1033 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1034 911600dab2ae7a9baff75958b84fe606851ce955
1034 911600dab2ae7a9baff75958b84fe606851ce955
1035 bundle2-output-bundle: "HG20", 5 parts total
1035 bundle2-output-bundle: "HG20", 5 parts total
1036 bundle2-output-part: "replycaps" 224 bytes payload
1036 bundle2-output-part: "replycaps" 207 bytes payload
1037 bundle2-output-part: "check:phases" 24 bytes payload
1037 bundle2-output-part: "check:phases" 24 bytes payload
1038 bundle2-output-part: "check:updated-heads" streamed payload
1038 bundle2-output-part: "check:updated-heads" streamed payload
1039 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1039 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1040 bundle2-output-part: "phase-heads" 24 bytes payload
1040 bundle2-output-part: "phase-heads" 24 bytes payload
1041 bundle2-input-bundle: with-transaction
1041 bundle2-input-bundle: with-transaction
1042 bundle2-input-part: "replycaps" supported
1042 bundle2-input-part: "replycaps" supported
1043 bundle2-input-part: total payload size 224
1043 bundle2-input-part: total payload size 207
1044 bundle2-input-part: "check:phases" supported
1044 bundle2-input-part: "check:phases" supported
1045 bundle2-input-part: total payload size 24
1045 bundle2-input-part: total payload size 24
1046 bundle2-input-part: "check:updated-heads" supported
1046 bundle2-input-part: "check:updated-heads" supported
1047 bundle2-input-part: total payload size 20
1047 bundle2-input-part: total payload size 20
1048 invalid branch cache (served): tip differs
1048 invalid branch cache (served): tip differs
1049 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1049 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1050 adding changesets
1050 adding changesets
1051 add changeset ef1ea85a6374
1051 add changeset ef1ea85a6374
1052 add changeset f9cafe1212c8
1052 add changeset f9cafe1212c8
1053 add changeset 911600dab2ae
1053 add changeset 911600dab2ae
1054 adding manifests
1054 adding manifests
1055 adding file changes
1055 adding file changes
1056 adding foo/Bar/file.txt revisions
1056 adding foo/Bar/file.txt revisions
1057 adding foo/file.txt revisions
1057 adding foo/file.txt revisions
1058 adding quux/file.py revisions
1058 adding quux/file.py revisions
1059 calling hook pretxnchangegroup.acl: hgext.acl.hook
1059 calling hook pretxnchangegroup.acl: hgext.acl.hook
1060 acl: checking access for user "wilma"
1060 acl: checking access for user "wilma"
1061 acl: acl.allow.branches not enabled
1061 acl: acl.allow.branches not enabled
1062 acl: acl.deny.branches not enabled
1062 acl: acl.deny.branches not enabled
1063 acl: acl.allow enabled, 1 entries for user wilma
1063 acl: acl.allow enabled, 1 entries for user wilma
1064 acl: acl.deny enabled, 0 entries for user wilma
1064 acl: acl.deny enabled, 0 entries for user wilma
1065 acl: branch access granted: "ef1ea85a6374" on branch "default"
1065 acl: branch access granted: "ef1ea85a6374" on branch "default"
1066 acl: path access granted: "ef1ea85a6374"
1066 acl: path access granted: "ef1ea85a6374"
1067 acl: branch access granted: "f9cafe1212c8" on branch "default"
1067 acl: branch access granted: "f9cafe1212c8" on branch "default"
1068 acl: path access granted: "f9cafe1212c8"
1068 acl: path access granted: "f9cafe1212c8"
1069 acl: branch access granted: "911600dab2ae" on branch "default"
1069 acl: branch access granted: "911600dab2ae" on branch "default"
1070 error: pretxnchangegroup.acl hook failed: acl: user "wilma" not allowed on "quux/file.py" (changeset "911600dab2ae")
1070 error: pretxnchangegroup.acl hook failed: acl: user "wilma" not allowed on "quux/file.py" (changeset "911600dab2ae")
1071 bundle2-input-part: total payload size 1553
1071 bundle2-input-part: total payload size 1553
1072 bundle2-input-part: total payload size 24
1072 bundle2-input-part: total payload size 24
1073 bundle2-input-bundle: 5 parts total
1073 bundle2-input-bundle: 5 parts total
1074 transaction abort!
1074 transaction abort!
1075 rollback completed
1075 rollback completed
1076 abort: acl: user "wilma" not allowed on "quux/file.py" (changeset "911600dab2ae")
1076 abort: acl: user "wilma" not allowed on "quux/file.py" (changeset "911600dab2ae")
1077 no rollback information available
1077 no rollback information available
1078 0:6675d58eff77
1078 0:6675d58eff77
1079
1079
1080
1080
1081 file specified by acl.config does not exist
1081 file specified by acl.config does not exist
1082
1082
1083 $ echo '[acl]' >> $config
1083 $ echo '[acl]' >> $config
1084 $ echo 'config = ../acl.config' >> $config
1084 $ echo 'config = ../acl.config' >> $config
1085 $ do_push barney
1085 $ do_push barney
1086 Pushing as user barney
1086 Pushing as user barney
1087 hgrc = """
1087 hgrc = """
1088 [hooks]
1088 [hooks]
1089 pretxnchangegroup.acl = python:hgext.acl.hook
1089 pretxnchangegroup.acl = python:hgext.acl.hook
1090 prepushkey.acl = python:hgext.acl.hook
1090 prepushkey.acl = python:hgext.acl.hook
1091 [acl]
1091 [acl]
1092 sources = push
1092 sources = push
1093 [acl.allow]
1093 [acl.allow]
1094 foo/** = fred
1094 foo/** = fred
1095 [acl.deny]
1095 [acl.deny]
1096 foo/bar/** = fred
1096 foo/bar/** = fred
1097 foo/Bar/** = fred
1097 foo/Bar/** = fred
1098 [acl.allow]
1098 [acl.allow]
1099 ** = barney
1099 ** = barney
1100 **/*.txt = wilma
1100 **/*.txt = wilma
1101 [acl]
1101 [acl]
1102 config = ../acl.config
1102 config = ../acl.config
1103 """
1103 """
1104 pushing to ../b
1104 pushing to ../b
1105 query 1; heads
1105 query 1; heads
1106 searching for changes
1106 searching for changes
1107 all remote heads known locally
1107 all remote heads known locally
1108 listing keys for "phases"
1108 listing keys for "phases"
1109 checking for updated bookmarks
1109 checking for updated bookmarks
1110 listing keys for "bookmarks"
1110 listing keys for "bookmarks"
1111 invalid branch cache (served): tip differs
1111 invalid branch cache (served): tip differs
1112 listing keys for "bookmarks"
1112 listing keys for "bookmarks"
1113 3 changesets found
1113 3 changesets found
1114 list of changesets:
1114 list of changesets:
1115 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1115 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1116 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1116 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1117 911600dab2ae7a9baff75958b84fe606851ce955
1117 911600dab2ae7a9baff75958b84fe606851ce955
1118 bundle2-output-bundle: "HG20", 5 parts total
1118 bundle2-output-bundle: "HG20", 5 parts total
1119 bundle2-output-part: "replycaps" 224 bytes payload
1119 bundle2-output-part: "replycaps" 207 bytes payload
1120 bundle2-output-part: "check:phases" 24 bytes payload
1120 bundle2-output-part: "check:phases" 24 bytes payload
1121 bundle2-output-part: "check:updated-heads" streamed payload
1121 bundle2-output-part: "check:updated-heads" streamed payload
1122 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1122 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1123 bundle2-output-part: "phase-heads" 24 bytes payload
1123 bundle2-output-part: "phase-heads" 24 bytes payload
1124 bundle2-input-bundle: with-transaction
1124 bundle2-input-bundle: with-transaction
1125 bundle2-input-part: "replycaps" supported
1125 bundle2-input-part: "replycaps" supported
1126 bundle2-input-part: total payload size 224
1126 bundle2-input-part: total payload size 207
1127 bundle2-input-part: "check:phases" supported
1127 bundle2-input-part: "check:phases" supported
1128 bundle2-input-part: total payload size 24
1128 bundle2-input-part: total payload size 24
1129 bundle2-input-part: "check:updated-heads" supported
1129 bundle2-input-part: "check:updated-heads" supported
1130 bundle2-input-part: total payload size 20
1130 bundle2-input-part: total payload size 20
1131 invalid branch cache (served): tip differs
1131 invalid branch cache (served): tip differs
1132 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1132 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1133 adding changesets
1133 adding changesets
1134 add changeset ef1ea85a6374
1134 add changeset ef1ea85a6374
1135 add changeset f9cafe1212c8
1135 add changeset f9cafe1212c8
1136 add changeset 911600dab2ae
1136 add changeset 911600dab2ae
1137 adding manifests
1137 adding manifests
1138 adding file changes
1138 adding file changes
1139 adding foo/Bar/file.txt revisions
1139 adding foo/Bar/file.txt revisions
1140 adding foo/file.txt revisions
1140 adding foo/file.txt revisions
1141 adding quux/file.py revisions
1141 adding quux/file.py revisions
1142 calling hook pretxnchangegroup.acl: hgext.acl.hook
1142 calling hook pretxnchangegroup.acl: hgext.acl.hook
1143 acl: checking access for user "barney"
1143 acl: checking access for user "barney"
1144 error: pretxnchangegroup.acl hook raised an exception: [Errno *] * (glob)
1144 error: pretxnchangegroup.acl hook raised an exception: [Errno *] * (glob)
1145 bundle2-input-part: total payload size 1553
1145 bundle2-input-part: total payload size 1553
1146 bundle2-input-part: total payload size 24
1146 bundle2-input-part: total payload size 24
1147 bundle2-input-bundle: 5 parts total
1147 bundle2-input-bundle: 5 parts total
1148 transaction abort!
1148 transaction abort!
1149 rollback completed
1149 rollback completed
1150 abort: $ENOENT$: '../acl.config'
1150 abort: $ENOENT$: '../acl.config'
1151 no rollback information available
1151 no rollback information available
1152 0:6675d58eff77
1152 0:6675d58eff77
1153
1153
1154
1154
1155 betty is allowed inside foo/ by a acl.config file
1155 betty is allowed inside foo/ by a acl.config file
1156
1156
1157 $ echo '[acl.allow]' >> acl.config
1157 $ echo '[acl.allow]' >> acl.config
1158 $ echo 'foo/** = betty' >> acl.config
1158 $ echo 'foo/** = betty' >> acl.config
1159 $ do_push betty
1159 $ do_push betty
1160 Pushing as user betty
1160 Pushing as user betty
1161 hgrc = """
1161 hgrc = """
1162 [hooks]
1162 [hooks]
1163 pretxnchangegroup.acl = python:hgext.acl.hook
1163 pretxnchangegroup.acl = python:hgext.acl.hook
1164 prepushkey.acl = python:hgext.acl.hook
1164 prepushkey.acl = python:hgext.acl.hook
1165 [acl]
1165 [acl]
1166 sources = push
1166 sources = push
1167 [acl.allow]
1167 [acl.allow]
1168 foo/** = fred
1168 foo/** = fred
1169 [acl.deny]
1169 [acl.deny]
1170 foo/bar/** = fred
1170 foo/bar/** = fred
1171 foo/Bar/** = fred
1171 foo/Bar/** = fred
1172 [acl.allow]
1172 [acl.allow]
1173 ** = barney
1173 ** = barney
1174 **/*.txt = wilma
1174 **/*.txt = wilma
1175 [acl]
1175 [acl]
1176 config = ../acl.config
1176 config = ../acl.config
1177 """
1177 """
1178 acl.config = """
1178 acl.config = """
1179 [acl.allow]
1179 [acl.allow]
1180 foo/** = betty
1180 foo/** = betty
1181 """
1181 """
1182 pushing to ../b
1182 pushing to ../b
1183 query 1; heads
1183 query 1; heads
1184 searching for changes
1184 searching for changes
1185 all remote heads known locally
1185 all remote heads known locally
1186 listing keys for "phases"
1186 listing keys for "phases"
1187 checking for updated bookmarks
1187 checking for updated bookmarks
1188 listing keys for "bookmarks"
1188 listing keys for "bookmarks"
1189 invalid branch cache (served): tip differs
1189 invalid branch cache (served): tip differs
1190 listing keys for "bookmarks"
1190 listing keys for "bookmarks"
1191 3 changesets found
1191 3 changesets found
1192 list of changesets:
1192 list of changesets:
1193 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1193 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1194 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1194 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1195 911600dab2ae7a9baff75958b84fe606851ce955
1195 911600dab2ae7a9baff75958b84fe606851ce955
1196 bundle2-output-bundle: "HG20", 5 parts total
1196 bundle2-output-bundle: "HG20", 5 parts total
1197 bundle2-output-part: "replycaps" 224 bytes payload
1197 bundle2-output-part: "replycaps" 207 bytes payload
1198 bundle2-output-part: "check:phases" 24 bytes payload
1198 bundle2-output-part: "check:phases" 24 bytes payload
1199 bundle2-output-part: "check:updated-heads" streamed payload
1199 bundle2-output-part: "check:updated-heads" streamed payload
1200 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1200 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1201 bundle2-output-part: "phase-heads" 24 bytes payload
1201 bundle2-output-part: "phase-heads" 24 bytes payload
1202 bundle2-input-bundle: with-transaction
1202 bundle2-input-bundle: with-transaction
1203 bundle2-input-part: "replycaps" supported
1203 bundle2-input-part: "replycaps" supported
1204 bundle2-input-part: total payload size 224
1204 bundle2-input-part: total payload size 207
1205 bundle2-input-part: "check:phases" supported
1205 bundle2-input-part: "check:phases" supported
1206 bundle2-input-part: total payload size 24
1206 bundle2-input-part: total payload size 24
1207 bundle2-input-part: "check:updated-heads" supported
1207 bundle2-input-part: "check:updated-heads" supported
1208 bundle2-input-part: total payload size 20
1208 bundle2-input-part: total payload size 20
1209 invalid branch cache (served): tip differs
1209 invalid branch cache (served): tip differs
1210 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1210 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1211 adding changesets
1211 adding changesets
1212 add changeset ef1ea85a6374
1212 add changeset ef1ea85a6374
1213 add changeset f9cafe1212c8
1213 add changeset f9cafe1212c8
1214 add changeset 911600dab2ae
1214 add changeset 911600dab2ae
1215 adding manifests
1215 adding manifests
1216 adding file changes
1216 adding file changes
1217 adding foo/Bar/file.txt revisions
1217 adding foo/Bar/file.txt revisions
1218 adding foo/file.txt revisions
1218 adding foo/file.txt revisions
1219 adding quux/file.py revisions
1219 adding quux/file.py revisions
1220 calling hook pretxnchangegroup.acl: hgext.acl.hook
1220 calling hook pretxnchangegroup.acl: hgext.acl.hook
1221 acl: checking access for user "betty"
1221 acl: checking access for user "betty"
1222 acl: acl.allow.branches not enabled
1222 acl: acl.allow.branches not enabled
1223 acl: acl.deny.branches not enabled
1223 acl: acl.deny.branches not enabled
1224 acl: acl.allow enabled, 1 entries for user betty
1224 acl: acl.allow enabled, 1 entries for user betty
1225 acl: acl.deny enabled, 0 entries for user betty
1225 acl: acl.deny enabled, 0 entries for user betty
1226 acl: branch access granted: "ef1ea85a6374" on branch "default"
1226 acl: branch access granted: "ef1ea85a6374" on branch "default"
1227 acl: path access granted: "ef1ea85a6374"
1227 acl: path access granted: "ef1ea85a6374"
1228 acl: branch access granted: "f9cafe1212c8" on branch "default"
1228 acl: branch access granted: "f9cafe1212c8" on branch "default"
1229 acl: path access granted: "f9cafe1212c8"
1229 acl: path access granted: "f9cafe1212c8"
1230 acl: branch access granted: "911600dab2ae" on branch "default"
1230 acl: branch access granted: "911600dab2ae" on branch "default"
1231 error: pretxnchangegroup.acl hook failed: acl: user "betty" not allowed on "quux/file.py" (changeset "911600dab2ae")
1231 error: pretxnchangegroup.acl hook failed: acl: user "betty" not allowed on "quux/file.py" (changeset "911600dab2ae")
1232 bundle2-input-part: total payload size 1553
1232 bundle2-input-part: total payload size 1553
1233 bundle2-input-part: total payload size 24
1233 bundle2-input-part: total payload size 24
1234 bundle2-input-bundle: 5 parts total
1234 bundle2-input-bundle: 5 parts total
1235 transaction abort!
1235 transaction abort!
1236 rollback completed
1236 rollback completed
1237 abort: acl: user "betty" not allowed on "quux/file.py" (changeset "911600dab2ae")
1237 abort: acl: user "betty" not allowed on "quux/file.py" (changeset "911600dab2ae")
1238 no rollback information available
1238 no rollback information available
1239 0:6675d58eff77
1239 0:6675d58eff77
1240
1240
1241
1241
1242 acl.config can set only [acl.allow]/[acl.deny]
1242 acl.config can set only [acl.allow]/[acl.deny]
1243
1243
1244 $ echo '[hooks]' >> acl.config
1244 $ echo '[hooks]' >> acl.config
1245 $ echo 'changegroup.acl = false' >> acl.config
1245 $ echo 'changegroup.acl = false' >> acl.config
1246 $ do_push barney
1246 $ do_push barney
1247 Pushing as user barney
1247 Pushing as user barney
1248 hgrc = """
1248 hgrc = """
1249 [hooks]
1249 [hooks]
1250 pretxnchangegroup.acl = python:hgext.acl.hook
1250 pretxnchangegroup.acl = python:hgext.acl.hook
1251 prepushkey.acl = python:hgext.acl.hook
1251 prepushkey.acl = python:hgext.acl.hook
1252 [acl]
1252 [acl]
1253 sources = push
1253 sources = push
1254 [acl.allow]
1254 [acl.allow]
1255 foo/** = fred
1255 foo/** = fred
1256 [acl.deny]
1256 [acl.deny]
1257 foo/bar/** = fred
1257 foo/bar/** = fred
1258 foo/Bar/** = fred
1258 foo/Bar/** = fred
1259 [acl.allow]
1259 [acl.allow]
1260 ** = barney
1260 ** = barney
1261 **/*.txt = wilma
1261 **/*.txt = wilma
1262 [acl]
1262 [acl]
1263 config = ../acl.config
1263 config = ../acl.config
1264 """
1264 """
1265 acl.config = """
1265 acl.config = """
1266 [acl.allow]
1266 [acl.allow]
1267 foo/** = betty
1267 foo/** = betty
1268 [hooks]
1268 [hooks]
1269 changegroup.acl = false
1269 changegroup.acl = false
1270 """
1270 """
1271 pushing to ../b
1271 pushing to ../b
1272 query 1; heads
1272 query 1; heads
1273 searching for changes
1273 searching for changes
1274 all remote heads known locally
1274 all remote heads known locally
1275 listing keys for "phases"
1275 listing keys for "phases"
1276 checking for updated bookmarks
1276 checking for updated bookmarks
1277 listing keys for "bookmarks"
1277 listing keys for "bookmarks"
1278 invalid branch cache (served): tip differs
1278 invalid branch cache (served): tip differs
1279 listing keys for "bookmarks"
1279 listing keys for "bookmarks"
1280 3 changesets found
1280 3 changesets found
1281 list of changesets:
1281 list of changesets:
1282 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1282 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1283 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1283 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1284 911600dab2ae7a9baff75958b84fe606851ce955
1284 911600dab2ae7a9baff75958b84fe606851ce955
1285 bundle2-output-bundle: "HG20", 5 parts total
1285 bundle2-output-bundle: "HG20", 5 parts total
1286 bundle2-output-part: "replycaps" 224 bytes payload
1286 bundle2-output-part: "replycaps" 207 bytes payload
1287 bundle2-output-part: "check:phases" 24 bytes payload
1287 bundle2-output-part: "check:phases" 24 bytes payload
1288 bundle2-output-part: "check:updated-heads" streamed payload
1288 bundle2-output-part: "check:updated-heads" streamed payload
1289 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1289 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1290 bundle2-output-part: "phase-heads" 24 bytes payload
1290 bundle2-output-part: "phase-heads" 24 bytes payload
1291 bundle2-input-bundle: with-transaction
1291 bundle2-input-bundle: with-transaction
1292 bundle2-input-part: "replycaps" supported
1292 bundle2-input-part: "replycaps" supported
1293 bundle2-input-part: total payload size 224
1293 bundle2-input-part: total payload size 207
1294 bundle2-input-part: "check:phases" supported
1294 bundle2-input-part: "check:phases" supported
1295 bundle2-input-part: total payload size 24
1295 bundle2-input-part: total payload size 24
1296 bundle2-input-part: "check:updated-heads" supported
1296 bundle2-input-part: "check:updated-heads" supported
1297 bundle2-input-part: total payload size 20
1297 bundle2-input-part: total payload size 20
1298 invalid branch cache (served): tip differs
1298 invalid branch cache (served): tip differs
1299 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1299 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1300 adding changesets
1300 adding changesets
1301 add changeset ef1ea85a6374
1301 add changeset ef1ea85a6374
1302 add changeset f9cafe1212c8
1302 add changeset f9cafe1212c8
1303 add changeset 911600dab2ae
1303 add changeset 911600dab2ae
1304 adding manifests
1304 adding manifests
1305 adding file changes
1305 adding file changes
1306 adding foo/Bar/file.txt revisions
1306 adding foo/Bar/file.txt revisions
1307 adding foo/file.txt revisions
1307 adding foo/file.txt revisions
1308 adding quux/file.py revisions
1308 adding quux/file.py revisions
1309 calling hook pretxnchangegroup.acl: hgext.acl.hook
1309 calling hook pretxnchangegroup.acl: hgext.acl.hook
1310 acl: checking access for user "barney"
1310 acl: checking access for user "barney"
1311 acl: acl.allow.branches not enabled
1311 acl: acl.allow.branches not enabled
1312 acl: acl.deny.branches not enabled
1312 acl: acl.deny.branches not enabled
1313 acl: acl.allow enabled, 1 entries for user barney
1313 acl: acl.allow enabled, 1 entries for user barney
1314 acl: acl.deny enabled, 0 entries for user barney
1314 acl: acl.deny enabled, 0 entries for user barney
1315 acl: branch access granted: "ef1ea85a6374" on branch "default"
1315 acl: branch access granted: "ef1ea85a6374" on branch "default"
1316 acl: path access granted: "ef1ea85a6374"
1316 acl: path access granted: "ef1ea85a6374"
1317 acl: branch access granted: "f9cafe1212c8" on branch "default"
1317 acl: branch access granted: "f9cafe1212c8" on branch "default"
1318 acl: path access granted: "f9cafe1212c8"
1318 acl: path access granted: "f9cafe1212c8"
1319 acl: branch access granted: "911600dab2ae" on branch "default"
1319 acl: branch access granted: "911600dab2ae" on branch "default"
1320 acl: path access granted: "911600dab2ae"
1320 acl: path access granted: "911600dab2ae"
1321 bundle2-input-part: total payload size 1553
1321 bundle2-input-part: total payload size 1553
1322 bundle2-input-part: "phase-heads" supported
1322 bundle2-input-part: "phase-heads" supported
1323 bundle2-input-part: total payload size 24
1323 bundle2-input-part: total payload size 24
1324 bundle2-input-bundle: 5 parts total
1324 bundle2-input-bundle: 5 parts total
1325 truncating cache/rbc-revs-v1 to 8
1325 truncating cache/rbc-revs-v1 to 8
1326 updating the branch cache
1326 updating the branch cache
1327 added 3 changesets with 3 changes to 3 files
1327 added 3 changesets with 3 changes to 3 files
1328 bundle2-output-bundle: "HG20", 1 parts total
1328 bundle2-output-bundle: "HG20", 1 parts total
1329 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
1329 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
1330 bundle2-input-bundle: no-transaction
1330 bundle2-input-bundle: no-transaction
1331 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
1331 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
1332 bundle2-input-bundle: 1 parts total
1332 bundle2-input-bundle: 1 parts total
1333 listing keys for "phases"
1333 listing keys for "phases"
1334 repository tip rolled back to revision 0 (undo push)
1334 repository tip rolled back to revision 0 (undo push)
1335 0:6675d58eff77
1335 0:6675d58eff77
1336
1336
1337
1337
1338 asterisk
1338 asterisk
1339
1339
1340 $ init_config
1340 $ init_config
1341
1341
1342 asterisk test
1342 asterisk test
1343
1343
1344 $ echo '[acl.allow]' >> $config
1344 $ echo '[acl.allow]' >> $config
1345 $ echo "** = fred" >> $config
1345 $ echo "** = fred" >> $config
1346
1346
1347 fred is always allowed
1347 fred is always allowed
1348
1348
1349 $ do_push fred
1349 $ do_push fred
1350 Pushing as user fred
1350 Pushing as user fred
1351 hgrc = """
1351 hgrc = """
1352 [hooks]
1352 [hooks]
1353 pretxnchangegroup.acl = python:hgext.acl.hook
1353 pretxnchangegroup.acl = python:hgext.acl.hook
1354 prepushkey.acl = python:hgext.acl.hook
1354 prepushkey.acl = python:hgext.acl.hook
1355 [acl]
1355 [acl]
1356 sources = push
1356 sources = push
1357 [extensions]
1357 [extensions]
1358 posixgetuser=$TESTTMP/posixgetuser.py
1358 posixgetuser=$TESTTMP/posixgetuser.py
1359 [acl.allow]
1359 [acl.allow]
1360 ** = fred
1360 ** = fred
1361 """
1361 """
1362 pushing to ../b
1362 pushing to ../b
1363 query 1; heads
1363 query 1; heads
1364 searching for changes
1364 searching for changes
1365 all remote heads known locally
1365 all remote heads known locally
1366 listing keys for "phases"
1366 listing keys for "phases"
1367 checking for updated bookmarks
1367 checking for updated bookmarks
1368 listing keys for "bookmarks"
1368 listing keys for "bookmarks"
1369 invalid branch cache (served): tip differs
1369 invalid branch cache (served): tip differs
1370 listing keys for "bookmarks"
1370 listing keys for "bookmarks"
1371 3 changesets found
1371 3 changesets found
1372 list of changesets:
1372 list of changesets:
1373 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1373 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1374 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1374 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1375 911600dab2ae7a9baff75958b84fe606851ce955
1375 911600dab2ae7a9baff75958b84fe606851ce955
1376 bundle2-output-bundle: "HG20", 5 parts total
1376 bundle2-output-bundle: "HG20", 5 parts total
1377 bundle2-output-part: "replycaps" 224 bytes payload
1377 bundle2-output-part: "replycaps" 207 bytes payload
1378 bundle2-output-part: "check:phases" 24 bytes payload
1378 bundle2-output-part: "check:phases" 24 bytes payload
1379 bundle2-output-part: "check:updated-heads" streamed payload
1379 bundle2-output-part: "check:updated-heads" streamed payload
1380 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1380 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1381 bundle2-output-part: "phase-heads" 24 bytes payload
1381 bundle2-output-part: "phase-heads" 24 bytes payload
1382 bundle2-input-bundle: with-transaction
1382 bundle2-input-bundle: with-transaction
1383 bundle2-input-part: "replycaps" supported
1383 bundle2-input-part: "replycaps" supported
1384 bundle2-input-part: total payload size 224
1384 bundle2-input-part: total payload size 207
1385 bundle2-input-part: "check:phases" supported
1385 bundle2-input-part: "check:phases" supported
1386 bundle2-input-part: total payload size 24
1386 bundle2-input-part: total payload size 24
1387 bundle2-input-part: "check:updated-heads" supported
1387 bundle2-input-part: "check:updated-heads" supported
1388 bundle2-input-part: total payload size 20
1388 bundle2-input-part: total payload size 20
1389 invalid branch cache (served): tip differs
1389 invalid branch cache (served): tip differs
1390 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1390 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1391 adding changesets
1391 adding changesets
1392 add changeset ef1ea85a6374
1392 add changeset ef1ea85a6374
1393 add changeset f9cafe1212c8
1393 add changeset f9cafe1212c8
1394 add changeset 911600dab2ae
1394 add changeset 911600dab2ae
1395 adding manifests
1395 adding manifests
1396 adding file changes
1396 adding file changes
1397 adding foo/Bar/file.txt revisions
1397 adding foo/Bar/file.txt revisions
1398 adding foo/file.txt revisions
1398 adding foo/file.txt revisions
1399 adding quux/file.py revisions
1399 adding quux/file.py revisions
1400 calling hook pretxnchangegroup.acl: hgext.acl.hook
1400 calling hook pretxnchangegroup.acl: hgext.acl.hook
1401 acl: checking access for user "fred"
1401 acl: checking access for user "fred"
1402 acl: acl.allow.branches not enabled
1402 acl: acl.allow.branches not enabled
1403 acl: acl.deny.branches not enabled
1403 acl: acl.deny.branches not enabled
1404 acl: acl.allow enabled, 1 entries for user fred
1404 acl: acl.allow enabled, 1 entries for user fred
1405 acl: acl.deny not enabled
1405 acl: acl.deny not enabled
1406 acl: branch access granted: "ef1ea85a6374" on branch "default"
1406 acl: branch access granted: "ef1ea85a6374" on branch "default"
1407 acl: path access granted: "ef1ea85a6374"
1407 acl: path access granted: "ef1ea85a6374"
1408 acl: branch access granted: "f9cafe1212c8" on branch "default"
1408 acl: branch access granted: "f9cafe1212c8" on branch "default"
1409 acl: path access granted: "f9cafe1212c8"
1409 acl: path access granted: "f9cafe1212c8"
1410 acl: branch access granted: "911600dab2ae" on branch "default"
1410 acl: branch access granted: "911600dab2ae" on branch "default"
1411 acl: path access granted: "911600dab2ae"
1411 acl: path access granted: "911600dab2ae"
1412 bundle2-input-part: total payload size 1553
1412 bundle2-input-part: total payload size 1553
1413 bundle2-input-part: "phase-heads" supported
1413 bundle2-input-part: "phase-heads" supported
1414 bundle2-input-part: total payload size 24
1414 bundle2-input-part: total payload size 24
1415 bundle2-input-bundle: 5 parts total
1415 bundle2-input-bundle: 5 parts total
1416 truncating cache/rbc-revs-v1 to 8
1416 truncating cache/rbc-revs-v1 to 8
1417 updating the branch cache
1417 updating the branch cache
1418 added 3 changesets with 3 changes to 3 files
1418 added 3 changesets with 3 changes to 3 files
1419 bundle2-output-bundle: "HG20", 1 parts total
1419 bundle2-output-bundle: "HG20", 1 parts total
1420 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
1420 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
1421 bundle2-input-bundle: no-transaction
1421 bundle2-input-bundle: no-transaction
1422 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
1422 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
1423 bundle2-input-bundle: 1 parts total
1423 bundle2-input-bundle: 1 parts total
1424 listing keys for "phases"
1424 listing keys for "phases"
1425 repository tip rolled back to revision 0 (undo push)
1425 repository tip rolled back to revision 0 (undo push)
1426 0:6675d58eff77
1426 0:6675d58eff77
1427
1427
1428
1428
1429 $ echo '[acl.deny]' >> $config
1429 $ echo '[acl.deny]' >> $config
1430 $ echo "foo/Bar/** = *" >> $config
1430 $ echo "foo/Bar/** = *" >> $config
1431
1431
1432 no one is allowed inside foo/Bar/
1432 no one is allowed inside foo/Bar/
1433
1433
1434 $ do_push fred
1434 $ do_push fred
1435 Pushing as user fred
1435 Pushing as user fred
1436 hgrc = """
1436 hgrc = """
1437 [hooks]
1437 [hooks]
1438 pretxnchangegroup.acl = python:hgext.acl.hook
1438 pretxnchangegroup.acl = python:hgext.acl.hook
1439 prepushkey.acl = python:hgext.acl.hook
1439 prepushkey.acl = python:hgext.acl.hook
1440 [acl]
1440 [acl]
1441 sources = push
1441 sources = push
1442 [extensions]
1442 [extensions]
1443 posixgetuser=$TESTTMP/posixgetuser.py
1443 posixgetuser=$TESTTMP/posixgetuser.py
1444 [acl.allow]
1444 [acl.allow]
1445 ** = fred
1445 ** = fred
1446 [acl.deny]
1446 [acl.deny]
1447 foo/Bar/** = *
1447 foo/Bar/** = *
1448 """
1448 """
1449 pushing to ../b
1449 pushing to ../b
1450 query 1; heads
1450 query 1; heads
1451 searching for changes
1451 searching for changes
1452 all remote heads known locally
1452 all remote heads known locally
1453 listing keys for "phases"
1453 listing keys for "phases"
1454 checking for updated bookmarks
1454 checking for updated bookmarks
1455 listing keys for "bookmarks"
1455 listing keys for "bookmarks"
1456 invalid branch cache (served): tip differs
1456 invalid branch cache (served): tip differs
1457 listing keys for "bookmarks"
1457 listing keys for "bookmarks"
1458 3 changesets found
1458 3 changesets found
1459 list of changesets:
1459 list of changesets:
1460 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1460 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1461 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1461 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1462 911600dab2ae7a9baff75958b84fe606851ce955
1462 911600dab2ae7a9baff75958b84fe606851ce955
1463 bundle2-output-bundle: "HG20", 5 parts total
1463 bundle2-output-bundle: "HG20", 5 parts total
1464 bundle2-output-part: "replycaps" 224 bytes payload
1464 bundle2-output-part: "replycaps" 207 bytes payload
1465 bundle2-output-part: "check:phases" 24 bytes payload
1465 bundle2-output-part: "check:phases" 24 bytes payload
1466 bundle2-output-part: "check:updated-heads" streamed payload
1466 bundle2-output-part: "check:updated-heads" streamed payload
1467 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1467 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1468 bundle2-output-part: "phase-heads" 24 bytes payload
1468 bundle2-output-part: "phase-heads" 24 bytes payload
1469 bundle2-input-bundle: with-transaction
1469 bundle2-input-bundle: with-transaction
1470 bundle2-input-part: "replycaps" supported
1470 bundle2-input-part: "replycaps" supported
1471 bundle2-input-part: total payload size 224
1471 bundle2-input-part: total payload size 207
1472 bundle2-input-part: "check:phases" supported
1472 bundle2-input-part: "check:phases" supported
1473 bundle2-input-part: total payload size 24
1473 bundle2-input-part: total payload size 24
1474 bundle2-input-part: "check:updated-heads" supported
1474 bundle2-input-part: "check:updated-heads" supported
1475 bundle2-input-part: total payload size 20
1475 bundle2-input-part: total payload size 20
1476 invalid branch cache (served): tip differs
1476 invalid branch cache (served): tip differs
1477 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1477 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1478 adding changesets
1478 adding changesets
1479 add changeset ef1ea85a6374
1479 add changeset ef1ea85a6374
1480 add changeset f9cafe1212c8
1480 add changeset f9cafe1212c8
1481 add changeset 911600dab2ae
1481 add changeset 911600dab2ae
1482 adding manifests
1482 adding manifests
1483 adding file changes
1483 adding file changes
1484 adding foo/Bar/file.txt revisions
1484 adding foo/Bar/file.txt revisions
1485 adding foo/file.txt revisions
1485 adding foo/file.txt revisions
1486 adding quux/file.py revisions
1486 adding quux/file.py revisions
1487 calling hook pretxnchangegroup.acl: hgext.acl.hook
1487 calling hook pretxnchangegroup.acl: hgext.acl.hook
1488 acl: checking access for user "fred"
1488 acl: checking access for user "fred"
1489 acl: acl.allow.branches not enabled
1489 acl: acl.allow.branches not enabled
1490 acl: acl.deny.branches not enabled
1490 acl: acl.deny.branches not enabled
1491 acl: acl.allow enabled, 1 entries for user fred
1491 acl: acl.allow enabled, 1 entries for user fred
1492 acl: acl.deny enabled, 1 entries for user fred
1492 acl: acl.deny enabled, 1 entries for user fred
1493 acl: branch access granted: "ef1ea85a6374" on branch "default"
1493 acl: branch access granted: "ef1ea85a6374" on branch "default"
1494 acl: path access granted: "ef1ea85a6374"
1494 acl: path access granted: "ef1ea85a6374"
1495 acl: branch access granted: "f9cafe1212c8" on branch "default"
1495 acl: branch access granted: "f9cafe1212c8" on branch "default"
1496 error: pretxnchangegroup.acl hook failed: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
1496 error: pretxnchangegroup.acl hook failed: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
1497 bundle2-input-part: total payload size 1553
1497 bundle2-input-part: total payload size 1553
1498 bundle2-input-part: total payload size 24
1498 bundle2-input-part: total payload size 24
1499 bundle2-input-bundle: 5 parts total
1499 bundle2-input-bundle: 5 parts total
1500 transaction abort!
1500 transaction abort!
1501 rollback completed
1501 rollback completed
1502 abort: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
1502 abort: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
1503 no rollback information available
1503 no rollback information available
1504 0:6675d58eff77
1504 0:6675d58eff77
1505
1505
1506
1506
1507 Groups
1507 Groups
1508
1508
1509 $ init_config
1509 $ init_config
1510
1510
1511 OS-level groups
1511 OS-level groups
1512
1512
1513 $ echo '[acl.allow]' >> $config
1513 $ echo '[acl.allow]' >> $config
1514 $ echo "** = @group1" >> $config
1514 $ echo "** = @group1" >> $config
1515
1515
1516 @group1 is always allowed
1516 @group1 is always allowed
1517
1517
1518 $ do_push fred
1518 $ do_push fred
1519 Pushing as user fred
1519 Pushing as user fred
1520 hgrc = """
1520 hgrc = """
1521 [hooks]
1521 [hooks]
1522 pretxnchangegroup.acl = python:hgext.acl.hook
1522 pretxnchangegroup.acl = python:hgext.acl.hook
1523 prepushkey.acl = python:hgext.acl.hook
1523 prepushkey.acl = python:hgext.acl.hook
1524 [acl]
1524 [acl]
1525 sources = push
1525 sources = push
1526 [extensions]
1526 [extensions]
1527 posixgetuser=$TESTTMP/posixgetuser.py
1527 posixgetuser=$TESTTMP/posixgetuser.py
1528 [acl.allow]
1528 [acl.allow]
1529 ** = @group1
1529 ** = @group1
1530 """
1530 """
1531 pushing to ../b
1531 pushing to ../b
1532 query 1; heads
1532 query 1; heads
1533 searching for changes
1533 searching for changes
1534 all remote heads known locally
1534 all remote heads known locally
1535 listing keys for "phases"
1535 listing keys for "phases"
1536 checking for updated bookmarks
1536 checking for updated bookmarks
1537 listing keys for "bookmarks"
1537 listing keys for "bookmarks"
1538 invalid branch cache (served): tip differs
1538 invalid branch cache (served): tip differs
1539 listing keys for "bookmarks"
1539 listing keys for "bookmarks"
1540 3 changesets found
1540 3 changesets found
1541 list of changesets:
1541 list of changesets:
1542 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1542 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1543 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1543 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1544 911600dab2ae7a9baff75958b84fe606851ce955
1544 911600dab2ae7a9baff75958b84fe606851ce955
1545 bundle2-output-bundle: "HG20", 5 parts total
1545 bundle2-output-bundle: "HG20", 5 parts total
1546 bundle2-output-part: "replycaps" 224 bytes payload
1546 bundle2-output-part: "replycaps" 207 bytes payload
1547 bundle2-output-part: "check:phases" 24 bytes payload
1547 bundle2-output-part: "check:phases" 24 bytes payload
1548 bundle2-output-part: "check:updated-heads" streamed payload
1548 bundle2-output-part: "check:updated-heads" streamed payload
1549 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1549 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1550 bundle2-output-part: "phase-heads" 24 bytes payload
1550 bundle2-output-part: "phase-heads" 24 bytes payload
1551 bundle2-input-bundle: with-transaction
1551 bundle2-input-bundle: with-transaction
1552 bundle2-input-part: "replycaps" supported
1552 bundle2-input-part: "replycaps" supported
1553 bundle2-input-part: total payload size 224
1553 bundle2-input-part: total payload size 207
1554 bundle2-input-part: "check:phases" supported
1554 bundle2-input-part: "check:phases" supported
1555 bundle2-input-part: total payload size 24
1555 bundle2-input-part: total payload size 24
1556 bundle2-input-part: "check:updated-heads" supported
1556 bundle2-input-part: "check:updated-heads" supported
1557 bundle2-input-part: total payload size 20
1557 bundle2-input-part: total payload size 20
1558 invalid branch cache (served): tip differs
1558 invalid branch cache (served): tip differs
1559 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1559 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1560 adding changesets
1560 adding changesets
1561 add changeset ef1ea85a6374
1561 add changeset ef1ea85a6374
1562 add changeset f9cafe1212c8
1562 add changeset f9cafe1212c8
1563 add changeset 911600dab2ae
1563 add changeset 911600dab2ae
1564 adding manifests
1564 adding manifests
1565 adding file changes
1565 adding file changes
1566 adding foo/Bar/file.txt revisions
1566 adding foo/Bar/file.txt revisions
1567 adding foo/file.txt revisions
1567 adding foo/file.txt revisions
1568 adding quux/file.py revisions
1568 adding quux/file.py revisions
1569 calling hook pretxnchangegroup.acl: hgext.acl.hook
1569 calling hook pretxnchangegroup.acl: hgext.acl.hook
1570 acl: checking access for user "fred"
1570 acl: checking access for user "fred"
1571 acl: acl.allow.branches not enabled
1571 acl: acl.allow.branches not enabled
1572 acl: acl.deny.branches not enabled
1572 acl: acl.deny.branches not enabled
1573 acl: "group1" not defined in [acl.groups]
1573 acl: "group1" not defined in [acl.groups]
1574 acl: acl.allow enabled, 1 entries for user fred
1574 acl: acl.allow enabled, 1 entries for user fred
1575 acl: acl.deny not enabled
1575 acl: acl.deny not enabled
1576 acl: branch access granted: "ef1ea85a6374" on branch "default"
1576 acl: branch access granted: "ef1ea85a6374" on branch "default"
1577 acl: path access granted: "ef1ea85a6374"
1577 acl: path access granted: "ef1ea85a6374"
1578 acl: branch access granted: "f9cafe1212c8" on branch "default"
1578 acl: branch access granted: "f9cafe1212c8" on branch "default"
1579 acl: path access granted: "f9cafe1212c8"
1579 acl: path access granted: "f9cafe1212c8"
1580 acl: branch access granted: "911600dab2ae" on branch "default"
1580 acl: branch access granted: "911600dab2ae" on branch "default"
1581 acl: path access granted: "911600dab2ae"
1581 acl: path access granted: "911600dab2ae"
1582 bundle2-input-part: total payload size 1553
1582 bundle2-input-part: total payload size 1553
1583 bundle2-input-part: "phase-heads" supported
1583 bundle2-input-part: "phase-heads" supported
1584 bundle2-input-part: total payload size 24
1584 bundle2-input-part: total payload size 24
1585 bundle2-input-bundle: 5 parts total
1585 bundle2-input-bundle: 5 parts total
1586 truncating cache/rbc-revs-v1 to 8
1586 truncating cache/rbc-revs-v1 to 8
1587 updating the branch cache
1587 updating the branch cache
1588 added 3 changesets with 3 changes to 3 files
1588 added 3 changesets with 3 changes to 3 files
1589 bundle2-output-bundle: "HG20", 1 parts total
1589 bundle2-output-bundle: "HG20", 1 parts total
1590 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
1590 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
1591 bundle2-input-bundle: no-transaction
1591 bundle2-input-bundle: no-transaction
1592 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
1592 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
1593 bundle2-input-bundle: 1 parts total
1593 bundle2-input-bundle: 1 parts total
1594 listing keys for "phases"
1594 listing keys for "phases"
1595 repository tip rolled back to revision 0 (undo push)
1595 repository tip rolled back to revision 0 (undo push)
1596 0:6675d58eff77
1596 0:6675d58eff77
1597
1597
1598
1598
1599 $ echo '[acl.deny]' >> $config
1599 $ echo '[acl.deny]' >> $config
1600 $ echo "foo/Bar/** = @group1" >> $config
1600 $ echo "foo/Bar/** = @group1" >> $config
1601
1601
1602 @group is allowed inside anything but foo/Bar/
1602 @group is allowed inside anything but foo/Bar/
1603
1603
1604 $ do_push fred
1604 $ do_push fred
1605 Pushing as user fred
1605 Pushing as user fred
1606 hgrc = """
1606 hgrc = """
1607 [hooks]
1607 [hooks]
1608 pretxnchangegroup.acl = python:hgext.acl.hook
1608 pretxnchangegroup.acl = python:hgext.acl.hook
1609 prepushkey.acl = python:hgext.acl.hook
1609 prepushkey.acl = python:hgext.acl.hook
1610 [acl]
1610 [acl]
1611 sources = push
1611 sources = push
1612 [extensions]
1612 [extensions]
1613 posixgetuser=$TESTTMP/posixgetuser.py
1613 posixgetuser=$TESTTMP/posixgetuser.py
1614 [acl.allow]
1614 [acl.allow]
1615 ** = @group1
1615 ** = @group1
1616 [acl.deny]
1616 [acl.deny]
1617 foo/Bar/** = @group1
1617 foo/Bar/** = @group1
1618 """
1618 """
1619 pushing to ../b
1619 pushing to ../b
1620 query 1; heads
1620 query 1; heads
1621 searching for changes
1621 searching for changes
1622 all remote heads known locally
1622 all remote heads known locally
1623 listing keys for "phases"
1623 listing keys for "phases"
1624 checking for updated bookmarks
1624 checking for updated bookmarks
1625 listing keys for "bookmarks"
1625 listing keys for "bookmarks"
1626 invalid branch cache (served): tip differs
1626 invalid branch cache (served): tip differs
1627 listing keys for "bookmarks"
1627 listing keys for "bookmarks"
1628 3 changesets found
1628 3 changesets found
1629 list of changesets:
1629 list of changesets:
1630 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1630 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1631 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1631 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1632 911600dab2ae7a9baff75958b84fe606851ce955
1632 911600dab2ae7a9baff75958b84fe606851ce955
1633 bundle2-output-bundle: "HG20", 5 parts total
1633 bundle2-output-bundle: "HG20", 5 parts total
1634 bundle2-output-part: "replycaps" 224 bytes payload
1634 bundle2-output-part: "replycaps" 207 bytes payload
1635 bundle2-output-part: "check:phases" 24 bytes payload
1635 bundle2-output-part: "check:phases" 24 bytes payload
1636 bundle2-output-part: "check:updated-heads" streamed payload
1636 bundle2-output-part: "check:updated-heads" streamed payload
1637 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1637 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1638 bundle2-output-part: "phase-heads" 24 bytes payload
1638 bundle2-output-part: "phase-heads" 24 bytes payload
1639 bundle2-input-bundle: with-transaction
1639 bundle2-input-bundle: with-transaction
1640 bundle2-input-part: "replycaps" supported
1640 bundle2-input-part: "replycaps" supported
1641 bundle2-input-part: total payload size 224
1641 bundle2-input-part: total payload size 207
1642 bundle2-input-part: "check:phases" supported
1642 bundle2-input-part: "check:phases" supported
1643 bundle2-input-part: total payload size 24
1643 bundle2-input-part: total payload size 24
1644 bundle2-input-part: "check:updated-heads" supported
1644 bundle2-input-part: "check:updated-heads" supported
1645 bundle2-input-part: total payload size 20
1645 bundle2-input-part: total payload size 20
1646 invalid branch cache (served): tip differs
1646 invalid branch cache (served): tip differs
1647 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1647 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1648 adding changesets
1648 adding changesets
1649 add changeset ef1ea85a6374
1649 add changeset ef1ea85a6374
1650 add changeset f9cafe1212c8
1650 add changeset f9cafe1212c8
1651 add changeset 911600dab2ae
1651 add changeset 911600dab2ae
1652 adding manifests
1652 adding manifests
1653 adding file changes
1653 adding file changes
1654 adding foo/Bar/file.txt revisions
1654 adding foo/Bar/file.txt revisions
1655 adding foo/file.txt revisions
1655 adding foo/file.txt revisions
1656 adding quux/file.py revisions
1656 adding quux/file.py revisions
1657 calling hook pretxnchangegroup.acl: hgext.acl.hook
1657 calling hook pretxnchangegroup.acl: hgext.acl.hook
1658 acl: checking access for user "fred"
1658 acl: checking access for user "fred"
1659 acl: acl.allow.branches not enabled
1659 acl: acl.allow.branches not enabled
1660 acl: acl.deny.branches not enabled
1660 acl: acl.deny.branches not enabled
1661 acl: "group1" not defined in [acl.groups]
1661 acl: "group1" not defined in [acl.groups]
1662 acl: acl.allow enabled, 1 entries for user fred
1662 acl: acl.allow enabled, 1 entries for user fred
1663 acl: "group1" not defined in [acl.groups]
1663 acl: "group1" not defined in [acl.groups]
1664 acl: acl.deny enabled, 1 entries for user fred
1664 acl: acl.deny enabled, 1 entries for user fred
1665 acl: branch access granted: "ef1ea85a6374" on branch "default"
1665 acl: branch access granted: "ef1ea85a6374" on branch "default"
1666 acl: path access granted: "ef1ea85a6374"
1666 acl: path access granted: "ef1ea85a6374"
1667 acl: branch access granted: "f9cafe1212c8" on branch "default"
1667 acl: branch access granted: "f9cafe1212c8" on branch "default"
1668 error: pretxnchangegroup.acl hook failed: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
1668 error: pretxnchangegroup.acl hook failed: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
1669 bundle2-input-part: total payload size 1553
1669 bundle2-input-part: total payload size 1553
1670 bundle2-input-part: total payload size 24
1670 bundle2-input-part: total payload size 24
1671 bundle2-input-bundle: 5 parts total
1671 bundle2-input-bundle: 5 parts total
1672 transaction abort!
1672 transaction abort!
1673 rollback completed
1673 rollback completed
1674 abort: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
1674 abort: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
1675 no rollback information available
1675 no rollback information available
1676 0:6675d58eff77
1676 0:6675d58eff77
1677
1677
1678
1678
1679 Invalid group
1679 Invalid group
1680
1680
1681 Disable the fakegroups trick to get real failures
1681 Disable the fakegroups trick to get real failures
1682
1682
1683 $ grep -v fakegroups $config > config.tmp
1683 $ grep -v fakegroups $config > config.tmp
1684 $ mv config.tmp $config
1684 $ mv config.tmp $config
1685 $ echo '[acl.allow]' >> $config
1685 $ echo '[acl.allow]' >> $config
1686 $ echo "** = @unlikelytoexist" >> $config
1686 $ echo "** = @unlikelytoexist" >> $config
1687 $ do_push fred 2>&1 | grep unlikelytoexist
1687 $ do_push fred 2>&1 | grep unlikelytoexist
1688 ** = @unlikelytoexist
1688 ** = @unlikelytoexist
1689 acl: "unlikelytoexist" not defined in [acl.groups]
1689 acl: "unlikelytoexist" not defined in [acl.groups]
1690 error: pretxnchangegroup.acl hook failed: group 'unlikelytoexist' is undefined
1690 error: pretxnchangegroup.acl hook failed: group 'unlikelytoexist' is undefined
1691 abort: group 'unlikelytoexist' is undefined
1691 abort: group 'unlikelytoexist' is undefined
1692
1692
1693
1693
1694 Branch acl tests setup
1694 Branch acl tests setup
1695
1695
1696 $ init_config
1696 $ init_config
1697 $ cd b
1697 $ cd b
1698 $ hg up
1698 $ hg up
1699 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1699 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1700 $ hg branch foobar
1700 $ hg branch foobar
1701 marked working directory as branch foobar
1701 marked working directory as branch foobar
1702 (branches are permanent and global, did you want a bookmark?)
1702 (branches are permanent and global, did you want a bookmark?)
1703 $ hg commit -m 'create foobar'
1703 $ hg commit -m 'create foobar'
1704 $ echo 'foo contents' > abc.txt
1704 $ echo 'foo contents' > abc.txt
1705 $ hg add abc.txt
1705 $ hg add abc.txt
1706 $ hg commit -m 'foobar contents'
1706 $ hg commit -m 'foobar contents'
1707 $ cd ..
1707 $ cd ..
1708 $ hg --cwd a pull ../b
1708 $ hg --cwd a pull ../b
1709 pulling from ../b
1709 pulling from ../b
1710 searching for changes
1710 searching for changes
1711 adding changesets
1711 adding changesets
1712 adding manifests
1712 adding manifests
1713 adding file changes
1713 adding file changes
1714 added 2 changesets with 1 changes to 1 files (+1 heads)
1714 added 2 changesets with 1 changes to 1 files (+1 heads)
1715 new changesets 81fbf4469322:fb35475503ef
1715 new changesets 81fbf4469322:fb35475503ef
1716 (run 'hg heads' to see heads)
1716 (run 'hg heads' to see heads)
1717
1717
1718 Create additional changeset on foobar branch
1718 Create additional changeset on foobar branch
1719
1719
1720 $ cd a
1720 $ cd a
1721 $ hg up -C foobar
1721 $ hg up -C foobar
1722 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
1722 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
1723 $ echo 'foo contents2' > abc.txt
1723 $ echo 'foo contents2' > abc.txt
1724 $ hg commit -m 'foobar contents2'
1724 $ hg commit -m 'foobar contents2'
1725 $ cd ..
1725 $ cd ..
1726
1726
1727
1727
1728 No branch acls specified
1728 No branch acls specified
1729
1729
1730 $ do_push astro
1730 $ do_push astro
1731 Pushing as user astro
1731 Pushing as user astro
1732 hgrc = """
1732 hgrc = """
1733 [hooks]
1733 [hooks]
1734 pretxnchangegroup.acl = python:hgext.acl.hook
1734 pretxnchangegroup.acl = python:hgext.acl.hook
1735 prepushkey.acl = python:hgext.acl.hook
1735 prepushkey.acl = python:hgext.acl.hook
1736 [acl]
1736 [acl]
1737 sources = push
1737 sources = push
1738 [extensions]
1738 [extensions]
1739 posixgetuser=$TESTTMP/posixgetuser.py
1739 posixgetuser=$TESTTMP/posixgetuser.py
1740 """
1740 """
1741 pushing to ../b
1741 pushing to ../b
1742 query 1; heads
1742 query 1; heads
1743 searching for changes
1743 searching for changes
1744 all remote heads known locally
1744 all remote heads known locally
1745 listing keys for "phases"
1745 listing keys for "phases"
1746 checking for updated bookmarks
1746 checking for updated bookmarks
1747 listing keys for "bookmarks"
1747 listing keys for "bookmarks"
1748 listing keys for "bookmarks"
1748 listing keys for "bookmarks"
1749 4 changesets found
1749 4 changesets found
1750 list of changesets:
1750 list of changesets:
1751 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1751 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1752 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1752 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1753 911600dab2ae7a9baff75958b84fe606851ce955
1753 911600dab2ae7a9baff75958b84fe606851ce955
1754 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1754 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1755 bundle2-output-bundle: "HG20", 5 parts total
1755 bundle2-output-bundle: "HG20", 5 parts total
1756 bundle2-output-part: "replycaps" 224 bytes payload
1756 bundle2-output-part: "replycaps" 207 bytes payload
1757 bundle2-output-part: "check:phases" 48 bytes payload
1757 bundle2-output-part: "check:phases" 48 bytes payload
1758 bundle2-output-part: "check:updated-heads" streamed payload
1758 bundle2-output-part: "check:updated-heads" streamed payload
1759 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1759 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1760 bundle2-output-part: "phase-heads" 48 bytes payload
1760 bundle2-output-part: "phase-heads" 48 bytes payload
1761 bundle2-input-bundle: with-transaction
1761 bundle2-input-bundle: with-transaction
1762 bundle2-input-part: "replycaps" supported
1762 bundle2-input-part: "replycaps" supported
1763 bundle2-input-part: total payload size 224
1763 bundle2-input-part: total payload size 207
1764 bundle2-input-part: "check:phases" supported
1764 bundle2-input-part: "check:phases" supported
1765 bundle2-input-part: total payload size 48
1765 bundle2-input-part: total payload size 48
1766 bundle2-input-part: "check:updated-heads" supported
1766 bundle2-input-part: "check:updated-heads" supported
1767 bundle2-input-part: total payload size 40
1767 bundle2-input-part: total payload size 40
1768 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1768 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1769 adding changesets
1769 adding changesets
1770 add changeset ef1ea85a6374
1770 add changeset ef1ea85a6374
1771 add changeset f9cafe1212c8
1771 add changeset f9cafe1212c8
1772 add changeset 911600dab2ae
1772 add changeset 911600dab2ae
1773 add changeset e8fc755d4d82
1773 add changeset e8fc755d4d82
1774 adding manifests
1774 adding manifests
1775 adding file changes
1775 adding file changes
1776 adding abc.txt revisions
1776 adding abc.txt revisions
1777 adding foo/Bar/file.txt revisions
1777 adding foo/Bar/file.txt revisions
1778 adding foo/file.txt revisions
1778 adding foo/file.txt revisions
1779 adding quux/file.py revisions
1779 adding quux/file.py revisions
1780 calling hook pretxnchangegroup.acl: hgext.acl.hook
1780 calling hook pretxnchangegroup.acl: hgext.acl.hook
1781 acl: checking access for user "astro"
1781 acl: checking access for user "astro"
1782 acl: acl.allow.branches not enabled
1782 acl: acl.allow.branches not enabled
1783 acl: acl.deny.branches not enabled
1783 acl: acl.deny.branches not enabled
1784 acl: acl.allow not enabled
1784 acl: acl.allow not enabled
1785 acl: acl.deny not enabled
1785 acl: acl.deny not enabled
1786 acl: branch access granted: "ef1ea85a6374" on branch "default"
1786 acl: branch access granted: "ef1ea85a6374" on branch "default"
1787 acl: path access granted: "ef1ea85a6374"
1787 acl: path access granted: "ef1ea85a6374"
1788 acl: branch access granted: "f9cafe1212c8" on branch "default"
1788 acl: branch access granted: "f9cafe1212c8" on branch "default"
1789 acl: path access granted: "f9cafe1212c8"
1789 acl: path access granted: "f9cafe1212c8"
1790 acl: branch access granted: "911600dab2ae" on branch "default"
1790 acl: branch access granted: "911600dab2ae" on branch "default"
1791 acl: path access granted: "911600dab2ae"
1791 acl: path access granted: "911600dab2ae"
1792 acl: branch access granted: "e8fc755d4d82" on branch "foobar"
1792 acl: branch access granted: "e8fc755d4d82" on branch "foobar"
1793 acl: path access granted: "e8fc755d4d82"
1793 acl: path access granted: "e8fc755d4d82"
1794 bundle2-input-part: total payload size 2068
1794 bundle2-input-part: total payload size 2068
1795 bundle2-input-part: "phase-heads" supported
1795 bundle2-input-part: "phase-heads" supported
1796 bundle2-input-part: total payload size 48
1796 bundle2-input-part: total payload size 48
1797 bundle2-input-bundle: 5 parts total
1797 bundle2-input-bundle: 5 parts total
1798 updating the branch cache
1798 updating the branch cache
1799 invalid branch cache (served.hidden): tip differs
1799 invalid branch cache (served.hidden): tip differs
1800 added 4 changesets with 4 changes to 4 files (+1 heads)
1800 added 4 changesets with 4 changes to 4 files (+1 heads)
1801 bundle2-output-bundle: "HG20", 1 parts total
1801 bundle2-output-bundle: "HG20", 1 parts total
1802 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
1802 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
1803 bundle2-input-bundle: no-transaction
1803 bundle2-input-bundle: no-transaction
1804 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
1804 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
1805 bundle2-input-bundle: 1 parts total
1805 bundle2-input-bundle: 1 parts total
1806 listing keys for "phases"
1806 listing keys for "phases"
1807 repository tip rolled back to revision 2 (undo push)
1807 repository tip rolled back to revision 2 (undo push)
1808 2:fb35475503ef
1808 2:fb35475503ef
1809
1809
1810
1810
1811 Branch acl deny test
1811 Branch acl deny test
1812
1812
1813 $ echo "[acl.deny.branches]" >> $config
1813 $ echo "[acl.deny.branches]" >> $config
1814 $ echo "foobar = *" >> $config
1814 $ echo "foobar = *" >> $config
1815 $ do_push astro
1815 $ do_push astro
1816 Pushing as user astro
1816 Pushing as user astro
1817 hgrc = """
1817 hgrc = """
1818 [hooks]
1818 [hooks]
1819 pretxnchangegroup.acl = python:hgext.acl.hook
1819 pretxnchangegroup.acl = python:hgext.acl.hook
1820 prepushkey.acl = python:hgext.acl.hook
1820 prepushkey.acl = python:hgext.acl.hook
1821 [acl]
1821 [acl]
1822 sources = push
1822 sources = push
1823 [extensions]
1823 [extensions]
1824 posixgetuser=$TESTTMP/posixgetuser.py
1824 posixgetuser=$TESTTMP/posixgetuser.py
1825 [acl.deny.branches]
1825 [acl.deny.branches]
1826 foobar = *
1826 foobar = *
1827 """
1827 """
1828 pushing to ../b
1828 pushing to ../b
1829 query 1; heads
1829 query 1; heads
1830 searching for changes
1830 searching for changes
1831 all remote heads known locally
1831 all remote heads known locally
1832 listing keys for "phases"
1832 listing keys for "phases"
1833 checking for updated bookmarks
1833 checking for updated bookmarks
1834 listing keys for "bookmarks"
1834 listing keys for "bookmarks"
1835 listing keys for "bookmarks"
1835 listing keys for "bookmarks"
1836 4 changesets found
1836 4 changesets found
1837 list of changesets:
1837 list of changesets:
1838 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1838 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1839 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1839 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1840 911600dab2ae7a9baff75958b84fe606851ce955
1840 911600dab2ae7a9baff75958b84fe606851ce955
1841 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1841 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1842 bundle2-output-bundle: "HG20", 5 parts total
1842 bundle2-output-bundle: "HG20", 5 parts total
1843 bundle2-output-part: "replycaps" 224 bytes payload
1843 bundle2-output-part: "replycaps" 207 bytes payload
1844 bundle2-output-part: "check:phases" 48 bytes payload
1844 bundle2-output-part: "check:phases" 48 bytes payload
1845 bundle2-output-part: "check:updated-heads" streamed payload
1845 bundle2-output-part: "check:updated-heads" streamed payload
1846 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1846 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1847 bundle2-output-part: "phase-heads" 48 bytes payload
1847 bundle2-output-part: "phase-heads" 48 bytes payload
1848 bundle2-input-bundle: with-transaction
1848 bundle2-input-bundle: with-transaction
1849 bundle2-input-part: "replycaps" supported
1849 bundle2-input-part: "replycaps" supported
1850 bundle2-input-part: total payload size 224
1850 bundle2-input-part: total payload size 207
1851 bundle2-input-part: "check:phases" supported
1851 bundle2-input-part: "check:phases" supported
1852 bundle2-input-part: total payload size 48
1852 bundle2-input-part: total payload size 48
1853 bundle2-input-part: "check:updated-heads" supported
1853 bundle2-input-part: "check:updated-heads" supported
1854 bundle2-input-part: total payload size 40
1854 bundle2-input-part: total payload size 40
1855 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1855 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1856 adding changesets
1856 adding changesets
1857 add changeset ef1ea85a6374
1857 add changeset ef1ea85a6374
1858 add changeset f9cafe1212c8
1858 add changeset f9cafe1212c8
1859 add changeset 911600dab2ae
1859 add changeset 911600dab2ae
1860 add changeset e8fc755d4d82
1860 add changeset e8fc755d4d82
1861 adding manifests
1861 adding manifests
1862 adding file changes
1862 adding file changes
1863 adding abc.txt revisions
1863 adding abc.txt revisions
1864 adding foo/Bar/file.txt revisions
1864 adding foo/Bar/file.txt revisions
1865 adding foo/file.txt revisions
1865 adding foo/file.txt revisions
1866 adding quux/file.py revisions
1866 adding quux/file.py revisions
1867 calling hook pretxnchangegroup.acl: hgext.acl.hook
1867 calling hook pretxnchangegroup.acl: hgext.acl.hook
1868 acl: checking access for user "astro"
1868 acl: checking access for user "astro"
1869 acl: acl.allow.branches not enabled
1869 acl: acl.allow.branches not enabled
1870 acl: acl.deny.branches enabled, 1 entries for user astro
1870 acl: acl.deny.branches enabled, 1 entries for user astro
1871 acl: acl.allow not enabled
1871 acl: acl.allow not enabled
1872 acl: acl.deny not enabled
1872 acl: acl.deny not enabled
1873 acl: branch access granted: "ef1ea85a6374" on branch "default"
1873 acl: branch access granted: "ef1ea85a6374" on branch "default"
1874 acl: path access granted: "ef1ea85a6374"
1874 acl: path access granted: "ef1ea85a6374"
1875 acl: branch access granted: "f9cafe1212c8" on branch "default"
1875 acl: branch access granted: "f9cafe1212c8" on branch "default"
1876 acl: path access granted: "f9cafe1212c8"
1876 acl: path access granted: "f9cafe1212c8"
1877 acl: branch access granted: "911600dab2ae" on branch "default"
1877 acl: branch access granted: "911600dab2ae" on branch "default"
1878 acl: path access granted: "911600dab2ae"
1878 acl: path access granted: "911600dab2ae"
1879 error: pretxnchangegroup.acl hook failed: acl: user "astro" denied on branch "foobar" (changeset "e8fc755d4d82")
1879 error: pretxnchangegroup.acl hook failed: acl: user "astro" denied on branch "foobar" (changeset "e8fc755d4d82")
1880 bundle2-input-part: total payload size 2068
1880 bundle2-input-part: total payload size 2068
1881 bundle2-input-part: total payload size 48
1881 bundle2-input-part: total payload size 48
1882 bundle2-input-bundle: 5 parts total
1882 bundle2-input-bundle: 5 parts total
1883 transaction abort!
1883 transaction abort!
1884 rollback completed
1884 rollback completed
1885 abort: acl: user "astro" denied on branch "foobar" (changeset "e8fc755d4d82")
1885 abort: acl: user "astro" denied on branch "foobar" (changeset "e8fc755d4d82")
1886 no rollback information available
1886 no rollback information available
1887 2:fb35475503ef
1887 2:fb35475503ef
1888
1888
1889
1889
1890 Branch acl empty allow test
1890 Branch acl empty allow test
1891
1891
1892 $ init_config
1892 $ init_config
1893 $ echo "[acl.allow.branches]" >> $config
1893 $ echo "[acl.allow.branches]" >> $config
1894 $ do_push astro
1894 $ do_push astro
1895 Pushing as user astro
1895 Pushing as user astro
1896 hgrc = """
1896 hgrc = """
1897 [hooks]
1897 [hooks]
1898 pretxnchangegroup.acl = python:hgext.acl.hook
1898 pretxnchangegroup.acl = python:hgext.acl.hook
1899 prepushkey.acl = python:hgext.acl.hook
1899 prepushkey.acl = python:hgext.acl.hook
1900 [acl]
1900 [acl]
1901 sources = push
1901 sources = push
1902 [extensions]
1902 [extensions]
1903 posixgetuser=$TESTTMP/posixgetuser.py
1903 posixgetuser=$TESTTMP/posixgetuser.py
1904 [acl.allow.branches]
1904 [acl.allow.branches]
1905 """
1905 """
1906 pushing to ../b
1906 pushing to ../b
1907 query 1; heads
1907 query 1; heads
1908 searching for changes
1908 searching for changes
1909 all remote heads known locally
1909 all remote heads known locally
1910 listing keys for "phases"
1910 listing keys for "phases"
1911 checking for updated bookmarks
1911 checking for updated bookmarks
1912 listing keys for "bookmarks"
1912 listing keys for "bookmarks"
1913 listing keys for "bookmarks"
1913 listing keys for "bookmarks"
1914 4 changesets found
1914 4 changesets found
1915 list of changesets:
1915 list of changesets:
1916 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1916 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1917 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1917 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1918 911600dab2ae7a9baff75958b84fe606851ce955
1918 911600dab2ae7a9baff75958b84fe606851ce955
1919 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1919 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1920 bundle2-output-bundle: "HG20", 5 parts total
1920 bundle2-output-bundle: "HG20", 5 parts total
1921 bundle2-output-part: "replycaps" 224 bytes payload
1921 bundle2-output-part: "replycaps" 207 bytes payload
1922 bundle2-output-part: "check:phases" 48 bytes payload
1922 bundle2-output-part: "check:phases" 48 bytes payload
1923 bundle2-output-part: "check:updated-heads" streamed payload
1923 bundle2-output-part: "check:updated-heads" streamed payload
1924 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1924 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1925 bundle2-output-part: "phase-heads" 48 bytes payload
1925 bundle2-output-part: "phase-heads" 48 bytes payload
1926 bundle2-input-bundle: with-transaction
1926 bundle2-input-bundle: with-transaction
1927 bundle2-input-part: "replycaps" supported
1927 bundle2-input-part: "replycaps" supported
1928 bundle2-input-part: total payload size 224
1928 bundle2-input-part: total payload size 207
1929 bundle2-input-part: "check:phases" supported
1929 bundle2-input-part: "check:phases" supported
1930 bundle2-input-part: total payload size 48
1930 bundle2-input-part: total payload size 48
1931 bundle2-input-part: "check:updated-heads" supported
1931 bundle2-input-part: "check:updated-heads" supported
1932 bundle2-input-part: total payload size 40
1932 bundle2-input-part: total payload size 40
1933 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1933 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1934 adding changesets
1934 adding changesets
1935 add changeset ef1ea85a6374
1935 add changeset ef1ea85a6374
1936 add changeset f9cafe1212c8
1936 add changeset f9cafe1212c8
1937 add changeset 911600dab2ae
1937 add changeset 911600dab2ae
1938 add changeset e8fc755d4d82
1938 add changeset e8fc755d4d82
1939 adding manifests
1939 adding manifests
1940 adding file changes
1940 adding file changes
1941 adding abc.txt revisions
1941 adding abc.txt revisions
1942 adding foo/Bar/file.txt revisions
1942 adding foo/Bar/file.txt revisions
1943 adding foo/file.txt revisions
1943 adding foo/file.txt revisions
1944 adding quux/file.py revisions
1944 adding quux/file.py revisions
1945 calling hook pretxnchangegroup.acl: hgext.acl.hook
1945 calling hook pretxnchangegroup.acl: hgext.acl.hook
1946 acl: checking access for user "astro"
1946 acl: checking access for user "astro"
1947 acl: acl.allow.branches enabled, 0 entries for user astro
1947 acl: acl.allow.branches enabled, 0 entries for user astro
1948 acl: acl.deny.branches not enabled
1948 acl: acl.deny.branches not enabled
1949 acl: acl.allow not enabled
1949 acl: acl.allow not enabled
1950 acl: acl.deny not enabled
1950 acl: acl.deny not enabled
1951 error: pretxnchangegroup.acl hook failed: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
1951 error: pretxnchangegroup.acl hook failed: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
1952 bundle2-input-part: total payload size 2068
1952 bundle2-input-part: total payload size 2068
1953 bundle2-input-part: total payload size 48
1953 bundle2-input-part: total payload size 48
1954 bundle2-input-bundle: 5 parts total
1954 bundle2-input-bundle: 5 parts total
1955 transaction abort!
1955 transaction abort!
1956 rollback completed
1956 rollback completed
1957 abort: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
1957 abort: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
1958 no rollback information available
1958 no rollback information available
1959 2:fb35475503ef
1959 2:fb35475503ef
1960
1960
1961
1961
1962 Branch acl allow other
1962 Branch acl allow other
1963
1963
1964 $ init_config
1964 $ init_config
1965 $ echo "[acl.allow.branches]" >> $config
1965 $ echo "[acl.allow.branches]" >> $config
1966 $ echo "* = george" >> $config
1966 $ echo "* = george" >> $config
1967 $ do_push astro
1967 $ do_push astro
1968 Pushing as user astro
1968 Pushing as user astro
1969 hgrc = """
1969 hgrc = """
1970 [hooks]
1970 [hooks]
1971 pretxnchangegroup.acl = python:hgext.acl.hook
1971 pretxnchangegroup.acl = python:hgext.acl.hook
1972 prepushkey.acl = python:hgext.acl.hook
1972 prepushkey.acl = python:hgext.acl.hook
1973 [acl]
1973 [acl]
1974 sources = push
1974 sources = push
1975 [extensions]
1975 [extensions]
1976 posixgetuser=$TESTTMP/posixgetuser.py
1976 posixgetuser=$TESTTMP/posixgetuser.py
1977 [acl.allow.branches]
1977 [acl.allow.branches]
1978 * = george
1978 * = george
1979 """
1979 """
1980 pushing to ../b
1980 pushing to ../b
1981 query 1; heads
1981 query 1; heads
1982 searching for changes
1982 searching for changes
1983 all remote heads known locally
1983 all remote heads known locally
1984 listing keys for "phases"
1984 listing keys for "phases"
1985 checking for updated bookmarks
1985 checking for updated bookmarks
1986 listing keys for "bookmarks"
1986 listing keys for "bookmarks"
1987 listing keys for "bookmarks"
1987 listing keys for "bookmarks"
1988 4 changesets found
1988 4 changesets found
1989 list of changesets:
1989 list of changesets:
1990 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1990 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1991 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1991 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1992 911600dab2ae7a9baff75958b84fe606851ce955
1992 911600dab2ae7a9baff75958b84fe606851ce955
1993 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1993 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1994 bundle2-output-bundle: "HG20", 5 parts total
1994 bundle2-output-bundle: "HG20", 5 parts total
1995 bundle2-output-part: "replycaps" 224 bytes payload
1995 bundle2-output-part: "replycaps" 207 bytes payload
1996 bundle2-output-part: "check:phases" 48 bytes payload
1996 bundle2-output-part: "check:phases" 48 bytes payload
1997 bundle2-output-part: "check:updated-heads" streamed payload
1997 bundle2-output-part: "check:updated-heads" streamed payload
1998 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1998 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1999 bundle2-output-part: "phase-heads" 48 bytes payload
1999 bundle2-output-part: "phase-heads" 48 bytes payload
2000 bundle2-input-bundle: with-transaction
2000 bundle2-input-bundle: with-transaction
2001 bundle2-input-part: "replycaps" supported
2001 bundle2-input-part: "replycaps" supported
2002 bundle2-input-part: total payload size 224
2002 bundle2-input-part: total payload size 207
2003 bundle2-input-part: "check:phases" supported
2003 bundle2-input-part: "check:phases" supported
2004 bundle2-input-part: total payload size 48
2004 bundle2-input-part: total payload size 48
2005 bundle2-input-part: "check:updated-heads" supported
2005 bundle2-input-part: "check:updated-heads" supported
2006 bundle2-input-part: total payload size 40
2006 bundle2-input-part: total payload size 40
2007 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
2007 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
2008 adding changesets
2008 adding changesets
2009 add changeset ef1ea85a6374
2009 add changeset ef1ea85a6374
2010 add changeset f9cafe1212c8
2010 add changeset f9cafe1212c8
2011 add changeset 911600dab2ae
2011 add changeset 911600dab2ae
2012 add changeset e8fc755d4d82
2012 add changeset e8fc755d4d82
2013 adding manifests
2013 adding manifests
2014 adding file changes
2014 adding file changes
2015 adding abc.txt revisions
2015 adding abc.txt revisions
2016 adding foo/Bar/file.txt revisions
2016 adding foo/Bar/file.txt revisions
2017 adding foo/file.txt revisions
2017 adding foo/file.txt revisions
2018 adding quux/file.py revisions
2018 adding quux/file.py revisions
2019 calling hook pretxnchangegroup.acl: hgext.acl.hook
2019 calling hook pretxnchangegroup.acl: hgext.acl.hook
2020 acl: checking access for user "astro"
2020 acl: checking access for user "astro"
2021 acl: acl.allow.branches enabled, 0 entries for user astro
2021 acl: acl.allow.branches enabled, 0 entries for user astro
2022 acl: acl.deny.branches not enabled
2022 acl: acl.deny.branches not enabled
2023 acl: acl.allow not enabled
2023 acl: acl.allow not enabled
2024 acl: acl.deny not enabled
2024 acl: acl.deny not enabled
2025 error: pretxnchangegroup.acl hook failed: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
2025 error: pretxnchangegroup.acl hook failed: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
2026 bundle2-input-part: total payload size 2068
2026 bundle2-input-part: total payload size 2068
2027 bundle2-input-part: total payload size 48
2027 bundle2-input-part: total payload size 48
2028 bundle2-input-bundle: 5 parts total
2028 bundle2-input-bundle: 5 parts total
2029 transaction abort!
2029 transaction abort!
2030 rollback completed
2030 rollback completed
2031 abort: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
2031 abort: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
2032 no rollback information available
2032 no rollback information available
2033 2:fb35475503ef
2033 2:fb35475503ef
2034
2034
2035 $ do_push george
2035 $ do_push george
2036 Pushing as user george
2036 Pushing as user george
2037 hgrc = """
2037 hgrc = """
2038 [hooks]
2038 [hooks]
2039 pretxnchangegroup.acl = python:hgext.acl.hook
2039 pretxnchangegroup.acl = python:hgext.acl.hook
2040 prepushkey.acl = python:hgext.acl.hook
2040 prepushkey.acl = python:hgext.acl.hook
2041 [acl]
2041 [acl]
2042 sources = push
2042 sources = push
2043 [extensions]
2043 [extensions]
2044 posixgetuser=$TESTTMP/posixgetuser.py
2044 posixgetuser=$TESTTMP/posixgetuser.py
2045 [acl.allow.branches]
2045 [acl.allow.branches]
2046 * = george
2046 * = george
2047 """
2047 """
2048 pushing to ../b
2048 pushing to ../b
2049 query 1; heads
2049 query 1; heads
2050 searching for changes
2050 searching for changes
2051 all remote heads known locally
2051 all remote heads known locally
2052 listing keys for "phases"
2052 listing keys for "phases"
2053 checking for updated bookmarks
2053 checking for updated bookmarks
2054 listing keys for "bookmarks"
2054 listing keys for "bookmarks"
2055 listing keys for "bookmarks"
2055 listing keys for "bookmarks"
2056 4 changesets found
2056 4 changesets found
2057 list of changesets:
2057 list of changesets:
2058 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
2058 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
2059 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
2059 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
2060 911600dab2ae7a9baff75958b84fe606851ce955
2060 911600dab2ae7a9baff75958b84fe606851ce955
2061 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
2061 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
2062 bundle2-output-bundle: "HG20", 5 parts total
2062 bundle2-output-bundle: "HG20", 5 parts total
2063 bundle2-output-part: "replycaps" 224 bytes payload
2063 bundle2-output-part: "replycaps" 207 bytes payload
2064 bundle2-output-part: "check:phases" 48 bytes payload
2064 bundle2-output-part: "check:phases" 48 bytes payload
2065 bundle2-output-part: "check:updated-heads" streamed payload
2065 bundle2-output-part: "check:updated-heads" streamed payload
2066 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
2066 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
2067 bundle2-output-part: "phase-heads" 48 bytes payload
2067 bundle2-output-part: "phase-heads" 48 bytes payload
2068 bundle2-input-bundle: with-transaction
2068 bundle2-input-bundle: with-transaction
2069 bundle2-input-part: "replycaps" supported
2069 bundle2-input-part: "replycaps" supported
2070 bundle2-input-part: total payload size 224
2070 bundle2-input-part: total payload size 207
2071 bundle2-input-part: "check:phases" supported
2071 bundle2-input-part: "check:phases" supported
2072 bundle2-input-part: total payload size 48
2072 bundle2-input-part: total payload size 48
2073 bundle2-input-part: "check:updated-heads" supported
2073 bundle2-input-part: "check:updated-heads" supported
2074 bundle2-input-part: total payload size 40
2074 bundle2-input-part: total payload size 40
2075 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
2075 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
2076 adding changesets
2076 adding changesets
2077 add changeset ef1ea85a6374
2077 add changeset ef1ea85a6374
2078 add changeset f9cafe1212c8
2078 add changeset f9cafe1212c8
2079 add changeset 911600dab2ae
2079 add changeset 911600dab2ae
2080 add changeset e8fc755d4d82
2080 add changeset e8fc755d4d82
2081 adding manifests
2081 adding manifests
2082 adding file changes
2082 adding file changes
2083 adding abc.txt revisions
2083 adding abc.txt revisions
2084 adding foo/Bar/file.txt revisions
2084 adding foo/Bar/file.txt revisions
2085 adding foo/file.txt revisions
2085 adding foo/file.txt revisions
2086 adding quux/file.py revisions
2086 adding quux/file.py revisions
2087 calling hook pretxnchangegroup.acl: hgext.acl.hook
2087 calling hook pretxnchangegroup.acl: hgext.acl.hook
2088 acl: checking access for user "george"
2088 acl: checking access for user "george"
2089 acl: acl.allow.branches enabled, 1 entries for user george
2089 acl: acl.allow.branches enabled, 1 entries for user george
2090 acl: acl.deny.branches not enabled
2090 acl: acl.deny.branches not enabled
2091 acl: acl.allow not enabled
2091 acl: acl.allow not enabled
2092 acl: acl.deny not enabled
2092 acl: acl.deny not enabled
2093 acl: branch access granted: "ef1ea85a6374" on branch "default"
2093 acl: branch access granted: "ef1ea85a6374" on branch "default"
2094 acl: path access granted: "ef1ea85a6374"
2094 acl: path access granted: "ef1ea85a6374"
2095 acl: branch access granted: "f9cafe1212c8" on branch "default"
2095 acl: branch access granted: "f9cafe1212c8" on branch "default"
2096 acl: path access granted: "f9cafe1212c8"
2096 acl: path access granted: "f9cafe1212c8"
2097 acl: branch access granted: "911600dab2ae" on branch "default"
2097 acl: branch access granted: "911600dab2ae" on branch "default"
2098 acl: path access granted: "911600dab2ae"
2098 acl: path access granted: "911600dab2ae"
2099 acl: branch access granted: "e8fc755d4d82" on branch "foobar"
2099 acl: branch access granted: "e8fc755d4d82" on branch "foobar"
2100 acl: path access granted: "e8fc755d4d82"
2100 acl: path access granted: "e8fc755d4d82"
2101 bundle2-input-part: total payload size 2068
2101 bundle2-input-part: total payload size 2068
2102 bundle2-input-part: "phase-heads" supported
2102 bundle2-input-part: "phase-heads" supported
2103 bundle2-input-part: total payload size 48
2103 bundle2-input-part: total payload size 48
2104 bundle2-input-bundle: 5 parts total
2104 bundle2-input-bundle: 5 parts total
2105 updating the branch cache
2105 updating the branch cache
2106 invalid branch cache (served.hidden): tip differs
2106 invalid branch cache (served.hidden): tip differs
2107 added 4 changesets with 4 changes to 4 files (+1 heads)
2107 added 4 changesets with 4 changes to 4 files (+1 heads)
2108 bundle2-output-bundle: "HG20", 1 parts total
2108 bundle2-output-bundle: "HG20", 1 parts total
2109 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
2109 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
2110 bundle2-input-bundle: no-transaction
2110 bundle2-input-bundle: no-transaction
2111 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
2111 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
2112 bundle2-input-bundle: 1 parts total
2112 bundle2-input-bundle: 1 parts total
2113 listing keys for "phases"
2113 listing keys for "phases"
2114 repository tip rolled back to revision 2 (undo push)
2114 repository tip rolled back to revision 2 (undo push)
2115 2:fb35475503ef
2115 2:fb35475503ef
2116
2116
2117
2117
2118 Branch acl conflicting allow
2118 Branch acl conflicting allow
2119 asterisk ends up applying to all branches and allowing george to
2119 asterisk ends up applying to all branches and allowing george to
2120 push foobar into the remote
2120 push foobar into the remote
2121
2121
2122 $ init_config
2122 $ init_config
2123 $ echo "[acl.allow.branches]" >> $config
2123 $ echo "[acl.allow.branches]" >> $config
2124 $ echo "foobar = astro" >> $config
2124 $ echo "foobar = astro" >> $config
2125 $ echo "* = george" >> $config
2125 $ echo "* = george" >> $config
2126 $ do_push george
2126 $ do_push george
2127 Pushing as user george
2127 Pushing as user george
2128 hgrc = """
2128 hgrc = """
2129 [hooks]
2129 [hooks]
2130 pretxnchangegroup.acl = python:hgext.acl.hook
2130 pretxnchangegroup.acl = python:hgext.acl.hook
2131 prepushkey.acl = python:hgext.acl.hook
2131 prepushkey.acl = python:hgext.acl.hook
2132 [acl]
2132 [acl]
2133 sources = push
2133 sources = push
2134 [extensions]
2134 [extensions]
2135 posixgetuser=$TESTTMP/posixgetuser.py
2135 posixgetuser=$TESTTMP/posixgetuser.py
2136 [acl.allow.branches]
2136 [acl.allow.branches]
2137 foobar = astro
2137 foobar = astro
2138 * = george
2138 * = george
2139 """
2139 """
2140 pushing to ../b
2140 pushing to ../b
2141 query 1; heads
2141 query 1; heads
2142 searching for changes
2142 searching for changes
2143 all remote heads known locally
2143 all remote heads known locally
2144 listing keys for "phases"
2144 listing keys for "phases"
2145 checking for updated bookmarks
2145 checking for updated bookmarks
2146 listing keys for "bookmarks"
2146 listing keys for "bookmarks"
2147 listing keys for "bookmarks"
2147 listing keys for "bookmarks"
2148 4 changesets found
2148 4 changesets found
2149 list of changesets:
2149 list of changesets:
2150 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
2150 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
2151 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
2151 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
2152 911600dab2ae7a9baff75958b84fe606851ce955
2152 911600dab2ae7a9baff75958b84fe606851ce955
2153 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
2153 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
2154 bundle2-output-bundle: "HG20", 5 parts total
2154 bundle2-output-bundle: "HG20", 5 parts total
2155 bundle2-output-part: "replycaps" 224 bytes payload
2155 bundle2-output-part: "replycaps" 207 bytes payload
2156 bundle2-output-part: "check:phases" 48 bytes payload
2156 bundle2-output-part: "check:phases" 48 bytes payload
2157 bundle2-output-part: "check:updated-heads" streamed payload
2157 bundle2-output-part: "check:updated-heads" streamed payload
2158 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
2158 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
2159 bundle2-output-part: "phase-heads" 48 bytes payload
2159 bundle2-output-part: "phase-heads" 48 bytes payload
2160 bundle2-input-bundle: with-transaction
2160 bundle2-input-bundle: with-transaction
2161 bundle2-input-part: "replycaps" supported
2161 bundle2-input-part: "replycaps" supported
2162 bundle2-input-part: total payload size 224
2162 bundle2-input-part: total payload size 207
2163 bundle2-input-part: "check:phases" supported
2163 bundle2-input-part: "check:phases" supported
2164 bundle2-input-part: total payload size 48
2164 bundle2-input-part: total payload size 48
2165 bundle2-input-part: "check:updated-heads" supported
2165 bundle2-input-part: "check:updated-heads" supported
2166 bundle2-input-part: total payload size 40
2166 bundle2-input-part: total payload size 40
2167 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
2167 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
2168 adding changesets
2168 adding changesets
2169 add changeset ef1ea85a6374
2169 add changeset ef1ea85a6374
2170 add changeset f9cafe1212c8
2170 add changeset f9cafe1212c8
2171 add changeset 911600dab2ae
2171 add changeset 911600dab2ae
2172 add changeset e8fc755d4d82
2172 add changeset e8fc755d4d82
2173 adding manifests
2173 adding manifests
2174 adding file changes
2174 adding file changes
2175 adding abc.txt revisions
2175 adding abc.txt revisions
2176 adding foo/Bar/file.txt revisions
2176 adding foo/Bar/file.txt revisions
2177 adding foo/file.txt revisions
2177 adding foo/file.txt revisions
2178 adding quux/file.py revisions
2178 adding quux/file.py revisions
2179 calling hook pretxnchangegroup.acl: hgext.acl.hook
2179 calling hook pretxnchangegroup.acl: hgext.acl.hook
2180 acl: checking access for user "george"
2180 acl: checking access for user "george"
2181 acl: acl.allow.branches enabled, 1 entries for user george
2181 acl: acl.allow.branches enabled, 1 entries for user george
2182 acl: acl.deny.branches not enabled
2182 acl: acl.deny.branches not enabled
2183 acl: acl.allow not enabled
2183 acl: acl.allow not enabled
2184 acl: acl.deny not enabled
2184 acl: acl.deny not enabled
2185 acl: branch access granted: "ef1ea85a6374" on branch "default"
2185 acl: branch access granted: "ef1ea85a6374" on branch "default"
2186 acl: path access granted: "ef1ea85a6374"
2186 acl: path access granted: "ef1ea85a6374"
2187 acl: branch access granted: "f9cafe1212c8" on branch "default"
2187 acl: branch access granted: "f9cafe1212c8" on branch "default"
2188 acl: path access granted: "f9cafe1212c8"
2188 acl: path access granted: "f9cafe1212c8"
2189 acl: branch access granted: "911600dab2ae" on branch "default"
2189 acl: branch access granted: "911600dab2ae" on branch "default"
2190 acl: path access granted: "911600dab2ae"
2190 acl: path access granted: "911600dab2ae"
2191 acl: branch access granted: "e8fc755d4d82" on branch "foobar"
2191 acl: branch access granted: "e8fc755d4d82" on branch "foobar"
2192 acl: path access granted: "e8fc755d4d82"
2192 acl: path access granted: "e8fc755d4d82"
2193 bundle2-input-part: total payload size 2068
2193 bundle2-input-part: total payload size 2068
2194 bundle2-input-part: "phase-heads" supported
2194 bundle2-input-part: "phase-heads" supported
2195 bundle2-input-part: total payload size 48
2195 bundle2-input-part: total payload size 48
2196 bundle2-input-bundle: 5 parts total
2196 bundle2-input-bundle: 5 parts total
2197 updating the branch cache
2197 updating the branch cache
2198 invalid branch cache (served.hidden): tip differs
2198 invalid branch cache (served.hidden): tip differs
2199 added 4 changesets with 4 changes to 4 files (+1 heads)
2199 added 4 changesets with 4 changes to 4 files (+1 heads)
2200 bundle2-output-bundle: "HG20", 1 parts total
2200 bundle2-output-bundle: "HG20", 1 parts total
2201 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
2201 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
2202 bundle2-input-bundle: no-transaction
2202 bundle2-input-bundle: no-transaction
2203 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
2203 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
2204 bundle2-input-bundle: 1 parts total
2204 bundle2-input-bundle: 1 parts total
2205 listing keys for "phases"
2205 listing keys for "phases"
2206 repository tip rolled back to revision 2 (undo push)
2206 repository tip rolled back to revision 2 (undo push)
2207 2:fb35475503ef
2207 2:fb35475503ef
2208
2208
2209 Branch acl conflicting deny
2209 Branch acl conflicting deny
2210
2210
2211 $ init_config
2211 $ init_config
2212 $ echo "[acl.deny.branches]" >> $config
2212 $ echo "[acl.deny.branches]" >> $config
2213 $ echo "foobar = astro" >> $config
2213 $ echo "foobar = astro" >> $config
2214 $ echo "default = astro" >> $config
2214 $ echo "default = astro" >> $config
2215 $ echo "* = george" >> $config
2215 $ echo "* = george" >> $config
2216 $ do_push george
2216 $ do_push george
2217 Pushing as user george
2217 Pushing as user george
2218 hgrc = """
2218 hgrc = """
2219 [hooks]
2219 [hooks]
2220 pretxnchangegroup.acl = python:hgext.acl.hook
2220 pretxnchangegroup.acl = python:hgext.acl.hook
2221 prepushkey.acl = python:hgext.acl.hook
2221 prepushkey.acl = python:hgext.acl.hook
2222 [acl]
2222 [acl]
2223 sources = push
2223 sources = push
2224 [extensions]
2224 [extensions]
2225 posixgetuser=$TESTTMP/posixgetuser.py
2225 posixgetuser=$TESTTMP/posixgetuser.py
2226 [acl.deny.branches]
2226 [acl.deny.branches]
2227 foobar = astro
2227 foobar = astro
2228 default = astro
2228 default = astro
2229 * = george
2229 * = george
2230 """
2230 """
2231 pushing to ../b
2231 pushing to ../b
2232 query 1; heads
2232 query 1; heads
2233 searching for changes
2233 searching for changes
2234 all remote heads known locally
2234 all remote heads known locally
2235 listing keys for "phases"
2235 listing keys for "phases"
2236 checking for updated bookmarks
2236 checking for updated bookmarks
2237 listing keys for "bookmarks"
2237 listing keys for "bookmarks"
2238 listing keys for "bookmarks"
2238 listing keys for "bookmarks"
2239 4 changesets found
2239 4 changesets found
2240 list of changesets:
2240 list of changesets:
2241 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
2241 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
2242 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
2242 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
2243 911600dab2ae7a9baff75958b84fe606851ce955
2243 911600dab2ae7a9baff75958b84fe606851ce955
2244 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
2244 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
2245 bundle2-output-bundle: "HG20", 5 parts total
2245 bundle2-output-bundle: "HG20", 5 parts total
2246 bundle2-output-part: "replycaps" 224 bytes payload
2246 bundle2-output-part: "replycaps" 207 bytes payload
2247 bundle2-output-part: "check:phases" 48 bytes payload
2247 bundle2-output-part: "check:phases" 48 bytes payload
2248 bundle2-output-part: "check:updated-heads" streamed payload
2248 bundle2-output-part: "check:updated-heads" streamed payload
2249 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
2249 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
2250 bundle2-output-part: "phase-heads" 48 bytes payload
2250 bundle2-output-part: "phase-heads" 48 bytes payload
2251 bundle2-input-bundle: with-transaction
2251 bundle2-input-bundle: with-transaction
2252 bundle2-input-part: "replycaps" supported
2252 bundle2-input-part: "replycaps" supported
2253 bundle2-input-part: total payload size 224
2253 bundle2-input-part: total payload size 207
2254 bundle2-input-part: "check:phases" supported
2254 bundle2-input-part: "check:phases" supported
2255 bundle2-input-part: total payload size 48
2255 bundle2-input-part: total payload size 48
2256 bundle2-input-part: "check:updated-heads" supported
2256 bundle2-input-part: "check:updated-heads" supported
2257 bundle2-input-part: total payload size 40
2257 bundle2-input-part: total payload size 40
2258 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
2258 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
2259 adding changesets
2259 adding changesets
2260 add changeset ef1ea85a6374
2260 add changeset ef1ea85a6374
2261 add changeset f9cafe1212c8
2261 add changeset f9cafe1212c8
2262 add changeset 911600dab2ae
2262 add changeset 911600dab2ae
2263 add changeset e8fc755d4d82
2263 add changeset e8fc755d4d82
2264 adding manifests
2264 adding manifests
2265 adding file changes
2265 adding file changes
2266 adding abc.txt revisions
2266 adding abc.txt revisions
2267 adding foo/Bar/file.txt revisions
2267 adding foo/Bar/file.txt revisions
2268 adding foo/file.txt revisions
2268 adding foo/file.txt revisions
2269 adding quux/file.py revisions
2269 adding quux/file.py revisions
2270 calling hook pretxnchangegroup.acl: hgext.acl.hook
2270 calling hook pretxnchangegroup.acl: hgext.acl.hook
2271 acl: checking access for user "george"
2271 acl: checking access for user "george"
2272 acl: acl.allow.branches not enabled
2272 acl: acl.allow.branches not enabled
2273 acl: acl.deny.branches enabled, 1 entries for user george
2273 acl: acl.deny.branches enabled, 1 entries for user george
2274 acl: acl.allow not enabled
2274 acl: acl.allow not enabled
2275 acl: acl.deny not enabled
2275 acl: acl.deny not enabled
2276 error: pretxnchangegroup.acl hook failed: acl: user "george" denied on branch "default" (changeset "ef1ea85a6374")
2276 error: pretxnchangegroup.acl hook failed: acl: user "george" denied on branch "default" (changeset "ef1ea85a6374")
2277 bundle2-input-part: total payload size 2068
2277 bundle2-input-part: total payload size 2068
2278 bundle2-input-part: total payload size 48
2278 bundle2-input-part: total payload size 48
2279 bundle2-input-bundle: 5 parts total
2279 bundle2-input-bundle: 5 parts total
2280 transaction abort!
2280 transaction abort!
2281 rollback completed
2281 rollback completed
2282 abort: acl: user "george" denied on branch "default" (changeset "ef1ea85a6374")
2282 abort: acl: user "george" denied on branch "default" (changeset "ef1ea85a6374")
2283 no rollback information available
2283 no rollback information available
2284 2:fb35475503ef
2284 2:fb35475503ef
2285
2285
2286 User 'astro' must not be denied
2286 User 'astro' must not be denied
2287
2287
2288 $ init_config
2288 $ init_config
2289 $ echo "[acl.deny.branches]" >> $config
2289 $ echo "[acl.deny.branches]" >> $config
2290 $ echo "default = !astro" >> $config
2290 $ echo "default = !astro" >> $config
2291 $ do_push astro
2291 $ do_push astro
2292 Pushing as user astro
2292 Pushing as user astro
2293 hgrc = """
2293 hgrc = """
2294 [hooks]
2294 [hooks]
2295 pretxnchangegroup.acl = python:hgext.acl.hook
2295 pretxnchangegroup.acl = python:hgext.acl.hook
2296 prepushkey.acl = python:hgext.acl.hook
2296 prepushkey.acl = python:hgext.acl.hook
2297 [acl]
2297 [acl]
2298 sources = push
2298 sources = push
2299 [extensions]
2299 [extensions]
2300 posixgetuser=$TESTTMP/posixgetuser.py
2300 posixgetuser=$TESTTMP/posixgetuser.py
2301 [acl.deny.branches]
2301 [acl.deny.branches]
2302 default = !astro
2302 default = !astro
2303 """
2303 """
2304 pushing to ../b
2304 pushing to ../b
2305 query 1; heads
2305 query 1; heads
2306 searching for changes
2306 searching for changes
2307 all remote heads known locally
2307 all remote heads known locally
2308 listing keys for "phases"
2308 listing keys for "phases"
2309 checking for updated bookmarks
2309 checking for updated bookmarks
2310 listing keys for "bookmarks"
2310 listing keys for "bookmarks"
2311 listing keys for "bookmarks"
2311 listing keys for "bookmarks"
2312 4 changesets found
2312 4 changesets found
2313 list of changesets:
2313 list of changesets:
2314 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
2314 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
2315 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
2315 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
2316 911600dab2ae7a9baff75958b84fe606851ce955
2316 911600dab2ae7a9baff75958b84fe606851ce955
2317 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
2317 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
2318 bundle2-output-bundle: "HG20", 5 parts total
2318 bundle2-output-bundle: "HG20", 5 parts total
2319 bundle2-output-part: "replycaps" 224 bytes payload
2319 bundle2-output-part: "replycaps" 207 bytes payload
2320 bundle2-output-part: "check:phases" 48 bytes payload
2320 bundle2-output-part: "check:phases" 48 bytes payload
2321 bundle2-output-part: "check:updated-heads" streamed payload
2321 bundle2-output-part: "check:updated-heads" streamed payload
2322 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
2322 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
2323 bundle2-output-part: "phase-heads" 48 bytes payload
2323 bundle2-output-part: "phase-heads" 48 bytes payload
2324 bundle2-input-bundle: with-transaction
2324 bundle2-input-bundle: with-transaction
2325 bundle2-input-part: "replycaps" supported
2325 bundle2-input-part: "replycaps" supported
2326 bundle2-input-part: total payload size 224
2326 bundle2-input-part: total payload size 207
2327 bundle2-input-part: "check:phases" supported
2327 bundle2-input-part: "check:phases" supported
2328 bundle2-input-part: total payload size 48
2328 bundle2-input-part: total payload size 48
2329 bundle2-input-part: "check:updated-heads" supported
2329 bundle2-input-part: "check:updated-heads" supported
2330 bundle2-input-part: total payload size 40
2330 bundle2-input-part: total payload size 40
2331 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
2331 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
2332 adding changesets
2332 adding changesets
2333 add changeset ef1ea85a6374
2333 add changeset ef1ea85a6374
2334 add changeset f9cafe1212c8
2334 add changeset f9cafe1212c8
2335 add changeset 911600dab2ae
2335 add changeset 911600dab2ae
2336 add changeset e8fc755d4d82
2336 add changeset e8fc755d4d82
2337 adding manifests
2337 adding manifests
2338 adding file changes
2338 adding file changes
2339 adding abc.txt revisions
2339 adding abc.txt revisions
2340 adding foo/Bar/file.txt revisions
2340 adding foo/Bar/file.txt revisions
2341 adding foo/file.txt revisions
2341 adding foo/file.txt revisions
2342 adding quux/file.py revisions
2342 adding quux/file.py revisions
2343 calling hook pretxnchangegroup.acl: hgext.acl.hook
2343 calling hook pretxnchangegroup.acl: hgext.acl.hook
2344 acl: checking access for user "astro"
2344 acl: checking access for user "astro"
2345 acl: acl.allow.branches not enabled
2345 acl: acl.allow.branches not enabled
2346 acl: acl.deny.branches enabled, 0 entries for user astro
2346 acl: acl.deny.branches enabled, 0 entries for user astro
2347 acl: acl.allow not enabled
2347 acl: acl.allow not enabled
2348 acl: acl.deny not enabled
2348 acl: acl.deny not enabled
2349 acl: branch access granted: "ef1ea85a6374" on branch "default"
2349 acl: branch access granted: "ef1ea85a6374" on branch "default"
2350 acl: path access granted: "ef1ea85a6374"
2350 acl: path access granted: "ef1ea85a6374"
2351 acl: branch access granted: "f9cafe1212c8" on branch "default"
2351 acl: branch access granted: "f9cafe1212c8" on branch "default"
2352 acl: path access granted: "f9cafe1212c8"
2352 acl: path access granted: "f9cafe1212c8"
2353 acl: branch access granted: "911600dab2ae" on branch "default"
2353 acl: branch access granted: "911600dab2ae" on branch "default"
2354 acl: path access granted: "911600dab2ae"
2354 acl: path access granted: "911600dab2ae"
2355 acl: branch access granted: "e8fc755d4d82" on branch "foobar"
2355 acl: branch access granted: "e8fc755d4d82" on branch "foobar"
2356 acl: path access granted: "e8fc755d4d82"
2356 acl: path access granted: "e8fc755d4d82"
2357 bundle2-input-part: total payload size 2068
2357 bundle2-input-part: total payload size 2068
2358 bundle2-input-part: "phase-heads" supported
2358 bundle2-input-part: "phase-heads" supported
2359 bundle2-input-part: total payload size 48
2359 bundle2-input-part: total payload size 48
2360 bundle2-input-bundle: 5 parts total
2360 bundle2-input-bundle: 5 parts total
2361 updating the branch cache
2361 updating the branch cache
2362 invalid branch cache (served.hidden): tip differs
2362 invalid branch cache (served.hidden): tip differs
2363 added 4 changesets with 4 changes to 4 files (+1 heads)
2363 added 4 changesets with 4 changes to 4 files (+1 heads)
2364 bundle2-output-bundle: "HG20", 1 parts total
2364 bundle2-output-bundle: "HG20", 1 parts total
2365 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
2365 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
2366 bundle2-input-bundle: no-transaction
2366 bundle2-input-bundle: no-transaction
2367 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
2367 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
2368 bundle2-input-bundle: 1 parts total
2368 bundle2-input-bundle: 1 parts total
2369 listing keys for "phases"
2369 listing keys for "phases"
2370 repository tip rolled back to revision 2 (undo push)
2370 repository tip rolled back to revision 2 (undo push)
2371 2:fb35475503ef
2371 2:fb35475503ef
2372
2372
2373
2373
2374 Non-astro users must be denied
2374 Non-astro users must be denied
2375
2375
2376 $ do_push george
2376 $ do_push george
2377 Pushing as user george
2377 Pushing as user george
2378 hgrc = """
2378 hgrc = """
2379 [hooks]
2379 [hooks]
2380 pretxnchangegroup.acl = python:hgext.acl.hook
2380 pretxnchangegroup.acl = python:hgext.acl.hook
2381 prepushkey.acl = python:hgext.acl.hook
2381 prepushkey.acl = python:hgext.acl.hook
2382 [acl]
2382 [acl]
2383 sources = push
2383 sources = push
2384 [extensions]
2384 [extensions]
2385 posixgetuser=$TESTTMP/posixgetuser.py
2385 posixgetuser=$TESTTMP/posixgetuser.py
2386 [acl.deny.branches]
2386 [acl.deny.branches]
2387 default = !astro
2387 default = !astro
2388 """
2388 """
2389 pushing to ../b
2389 pushing to ../b
2390 query 1; heads
2390 query 1; heads
2391 searching for changes
2391 searching for changes
2392 all remote heads known locally
2392 all remote heads known locally
2393 listing keys for "phases"
2393 listing keys for "phases"
2394 checking for updated bookmarks
2394 checking for updated bookmarks
2395 listing keys for "bookmarks"
2395 listing keys for "bookmarks"
2396 listing keys for "bookmarks"
2396 listing keys for "bookmarks"
2397 4 changesets found
2397 4 changesets found
2398 list of changesets:
2398 list of changesets:
2399 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
2399 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
2400 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
2400 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
2401 911600dab2ae7a9baff75958b84fe606851ce955
2401 911600dab2ae7a9baff75958b84fe606851ce955
2402 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
2402 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
2403 bundle2-output-bundle: "HG20", 5 parts total
2403 bundle2-output-bundle: "HG20", 5 parts total
2404 bundle2-output-part: "replycaps" 224 bytes payload
2404 bundle2-output-part: "replycaps" 207 bytes payload
2405 bundle2-output-part: "check:phases" 48 bytes payload
2405 bundle2-output-part: "check:phases" 48 bytes payload
2406 bundle2-output-part: "check:updated-heads" streamed payload
2406 bundle2-output-part: "check:updated-heads" streamed payload
2407 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
2407 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
2408 bundle2-output-part: "phase-heads" 48 bytes payload
2408 bundle2-output-part: "phase-heads" 48 bytes payload
2409 bundle2-input-bundle: with-transaction
2409 bundle2-input-bundle: with-transaction
2410 bundle2-input-part: "replycaps" supported
2410 bundle2-input-part: "replycaps" supported
2411 bundle2-input-part: total payload size 224
2411 bundle2-input-part: total payload size 207
2412 bundle2-input-part: "check:phases" supported
2412 bundle2-input-part: "check:phases" supported
2413 bundle2-input-part: total payload size 48
2413 bundle2-input-part: total payload size 48
2414 bundle2-input-part: "check:updated-heads" supported
2414 bundle2-input-part: "check:updated-heads" supported
2415 bundle2-input-part: total payload size 40
2415 bundle2-input-part: total payload size 40
2416 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
2416 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
2417 adding changesets
2417 adding changesets
2418 add changeset ef1ea85a6374
2418 add changeset ef1ea85a6374
2419 add changeset f9cafe1212c8
2419 add changeset f9cafe1212c8
2420 add changeset 911600dab2ae
2420 add changeset 911600dab2ae
2421 add changeset e8fc755d4d82
2421 add changeset e8fc755d4d82
2422 adding manifests
2422 adding manifests
2423 adding file changes
2423 adding file changes
2424 adding abc.txt revisions
2424 adding abc.txt revisions
2425 adding foo/Bar/file.txt revisions
2425 adding foo/Bar/file.txt revisions
2426 adding foo/file.txt revisions
2426 adding foo/file.txt revisions
2427 adding quux/file.py revisions
2427 adding quux/file.py revisions
2428 calling hook pretxnchangegroup.acl: hgext.acl.hook
2428 calling hook pretxnchangegroup.acl: hgext.acl.hook
2429 acl: checking access for user "george"
2429 acl: checking access for user "george"
2430 acl: acl.allow.branches not enabled
2430 acl: acl.allow.branches not enabled
2431 acl: acl.deny.branches enabled, 1 entries for user george
2431 acl: acl.deny.branches enabled, 1 entries for user george
2432 acl: acl.allow not enabled
2432 acl: acl.allow not enabled
2433 acl: acl.deny not enabled
2433 acl: acl.deny not enabled
2434 error: pretxnchangegroup.acl hook failed: acl: user "george" denied on branch "default" (changeset "ef1ea85a6374")
2434 error: pretxnchangegroup.acl hook failed: acl: user "george" denied on branch "default" (changeset "ef1ea85a6374")
2435 bundle2-input-part: total payload size 2068
2435 bundle2-input-part: total payload size 2068
2436 bundle2-input-part: total payload size 48
2436 bundle2-input-part: total payload size 48
2437 bundle2-input-bundle: 5 parts total
2437 bundle2-input-bundle: 5 parts total
2438 transaction abort!
2438 transaction abort!
2439 rollback completed
2439 rollback completed
2440 abort: acl: user "george" denied on branch "default" (changeset "ef1ea85a6374")
2440 abort: acl: user "george" denied on branch "default" (changeset "ef1ea85a6374")
2441 no rollback information available
2441 no rollback information available
2442 2:fb35475503ef
2442 2:fb35475503ef
2443
2443
2444
2444
@@ -1,1396 +1,1396 b''
1 #testcases b2-pushkey b2-binary
1 #testcases b2-pushkey b2-binary
2
2
3 #if b2-pushkey
3 #if b2-pushkey
4 $ cat << EOF >> $HGRCPATH
4 $ cat << EOF >> $HGRCPATH
5 > [devel]
5 > [devel]
6 > legacy.exchange=bookmarks
6 > legacy.exchange=bookmarks
7 > EOF
7 > EOF
8 #endif
8 #endif
9
9
10 #require serve
10 #require serve
11
11
12 $ cat << EOF >> $HGRCPATH
12 $ cat << EOF >> $HGRCPATH
13 > [command-templates]
13 > [command-templates]
14 > log={rev}:{node|short} {desc|firstline}
14 > log={rev}:{node|short} {desc|firstline}
15 > [phases]
15 > [phases]
16 > publish=False
16 > publish=False
17 > [experimental]
17 > [experimental]
18 > evolution.createmarkers=True
18 > evolution.createmarkers=True
19 > evolution.exchange=True
19 > evolution.exchange=True
20 > EOF
20 > EOF
21
21
22 $ cat > $TESTTMP/hook.sh <<'EOF'
22 $ cat > $TESTTMP/hook.sh <<'EOF'
23 > echo "test-hook-bookmark: $HG_BOOKMARK: $HG_OLDNODE -> $HG_NODE"
23 > echo "test-hook-bookmark: $HG_BOOKMARK: $HG_OLDNODE -> $HG_NODE"
24 > EOF
24 > EOF
25 $ TESTHOOK="hooks.txnclose-bookmark.test=sh $TESTTMP/hook.sh"
25 $ TESTHOOK="hooks.txnclose-bookmark.test=sh $TESTTMP/hook.sh"
26
26
27 initialize
27 initialize
28
28
29 $ hg init a
29 $ hg init a
30 $ cd a
30 $ cd a
31 $ echo 'test' > test
31 $ echo 'test' > test
32 $ hg commit -Am'test'
32 $ hg commit -Am'test'
33 adding test
33 adding test
34
34
35 set bookmarks
35 set bookmarks
36
36
37 $ hg bookmark X
37 $ hg bookmark X
38 $ hg bookmark Y
38 $ hg bookmark Y
39 $ hg bookmark Z
39 $ hg bookmark Z
40
40
41 import bookmark by name
41 import bookmark by name
42
42
43 $ hg init ../b
43 $ hg init ../b
44 $ cd ../b
44 $ cd ../b
45 $ hg book Y
45 $ hg book Y
46 $ hg book
46 $ hg book
47 * Y -1:000000000000
47 * Y -1:000000000000
48 $ hg pull ../a --config "$TESTHOOK"
48 $ hg pull ../a --config "$TESTHOOK"
49 pulling from ../a
49 pulling from ../a
50 requesting all changes
50 requesting all changes
51 adding changesets
51 adding changesets
52 adding manifests
52 adding manifests
53 adding file changes
53 adding file changes
54 adding remote bookmark X
54 adding remote bookmark X
55 updating bookmark Y
55 updating bookmark Y
56 adding remote bookmark Z
56 adding remote bookmark Z
57 added 1 changesets with 1 changes to 1 files
57 added 1 changesets with 1 changes to 1 files
58 new changesets 4e3505fd9583 (1 drafts)
58 new changesets 4e3505fd9583 (1 drafts)
59 test-hook-bookmark: X: -> 4e3505fd95835d721066b76e75dbb8cc554d7f77
59 test-hook-bookmark: X: -> 4e3505fd95835d721066b76e75dbb8cc554d7f77
60 test-hook-bookmark: Y: 0000000000000000000000000000000000000000 -> 4e3505fd95835d721066b76e75dbb8cc554d7f77
60 test-hook-bookmark: Y: 0000000000000000000000000000000000000000 -> 4e3505fd95835d721066b76e75dbb8cc554d7f77
61 test-hook-bookmark: Z: -> 4e3505fd95835d721066b76e75dbb8cc554d7f77
61 test-hook-bookmark: Z: -> 4e3505fd95835d721066b76e75dbb8cc554d7f77
62 (run 'hg update' to get a working copy)
62 (run 'hg update' to get a working copy)
63 $ hg bookmarks
63 $ hg bookmarks
64 X 0:4e3505fd9583
64 X 0:4e3505fd9583
65 * Y 0:4e3505fd9583
65 * Y 0:4e3505fd9583
66 Z 0:4e3505fd9583
66 Z 0:4e3505fd9583
67 $ hg debugpushkey ../a namespaces
67 $ hg debugpushkey ../a namespaces
68 bookmarks
68 bookmarks
69 namespaces
69 namespaces
70 obsolete
70 obsolete
71 phases
71 phases
72 $ hg debugpushkey ../a bookmarks
72 $ hg debugpushkey ../a bookmarks
73 X 4e3505fd95835d721066b76e75dbb8cc554d7f77
73 X 4e3505fd95835d721066b76e75dbb8cc554d7f77
74 Y 4e3505fd95835d721066b76e75dbb8cc554d7f77
74 Y 4e3505fd95835d721066b76e75dbb8cc554d7f77
75 Z 4e3505fd95835d721066b76e75dbb8cc554d7f77
75 Z 4e3505fd95835d721066b76e75dbb8cc554d7f77
76
76
77 delete the bookmark to re-pull it
77 delete the bookmark to re-pull it
78
78
79 $ hg book -d X
79 $ hg book -d X
80 $ hg pull -B X ../a
80 $ hg pull -B X ../a
81 pulling from ../a
81 pulling from ../a
82 no changes found
82 no changes found
83 adding remote bookmark X
83 adding remote bookmark X
84
84
85 finally no-op pull
85 finally no-op pull
86
86
87 $ hg pull -B X ../a
87 $ hg pull -B X ../a
88 pulling from ../a
88 pulling from ../a
89 no changes found
89 no changes found
90 $ hg bookmark
90 $ hg bookmark
91 X 0:4e3505fd9583
91 X 0:4e3505fd9583
92 * Y 0:4e3505fd9583
92 * Y 0:4e3505fd9583
93 Z 0:4e3505fd9583
93 Z 0:4e3505fd9583
94
94
95 export bookmark by name
95 export bookmark by name
96
96
97 $ hg bookmark W
97 $ hg bookmark W
98 $ hg bookmark foo
98 $ hg bookmark foo
99 $ hg bookmark foobar
99 $ hg bookmark foobar
100 $ hg push -B W ../a
100 $ hg push -B W ../a
101 pushing to ../a
101 pushing to ../a
102 searching for changes
102 searching for changes
103 no changes found
103 no changes found
104 exporting bookmark W
104 exporting bookmark W
105 [1]
105 [1]
106 $ hg -R ../a bookmarks
106 $ hg -R ../a bookmarks
107 W -1:000000000000
107 W -1:000000000000
108 X 0:4e3505fd9583
108 X 0:4e3505fd9583
109 Y 0:4e3505fd9583
109 Y 0:4e3505fd9583
110 * Z 0:4e3505fd9583
110 * Z 0:4e3505fd9583
111
111
112 delete a remote bookmark
112 delete a remote bookmark
113
113
114 $ hg book -d W
114 $ hg book -d W
115
115
116 #if b2-pushkey
116 #if b2-pushkey
117
117
118 $ hg push -B W ../a --config "$TESTHOOK" --debug --config devel.bundle2.debug=yes
118 $ hg push -B W ../a --config "$TESTHOOK" --debug --config devel.bundle2.debug=yes
119 pushing to ../a
119 pushing to ../a
120 query 1; heads
120 query 1; heads
121 searching for changes
121 searching for changes
122 all remote heads known locally
122 all remote heads known locally
123 listing keys for "phases"
123 listing keys for "phases"
124 checking for updated bookmarks
124 checking for updated bookmarks
125 listing keys for "bookmarks"
125 listing keys for "bookmarks"
126 no changes found
126 no changes found
127 bundle2-output-bundle: "HG20", 4 parts total
127 bundle2-output-bundle: "HG20", 4 parts total
128 bundle2-output: start emission of HG20 stream
128 bundle2-output: start emission of HG20 stream
129 bundle2-output: bundle parameter:
129 bundle2-output: bundle parameter:
130 bundle2-output: start of parts
130 bundle2-output: start of parts
131 bundle2-output: bundle part: "replycaps"
131 bundle2-output: bundle part: "replycaps"
132 bundle2-output-part: "replycaps" 241 bytes payload
132 bundle2-output-part: "replycaps" 224 bytes payload
133 bundle2-output: part 0: "REPLYCAPS"
133 bundle2-output: part 0: "REPLYCAPS"
134 bundle2-output: header chunk size: 16
134 bundle2-output: header chunk size: 16
135 bundle2-output: payload chunk size: 241
135 bundle2-output: payload chunk size: 224
136 bundle2-output: closing payload chunk
136 bundle2-output: closing payload chunk
137 bundle2-output: bundle part: "check:bookmarks"
137 bundle2-output: bundle part: "check:bookmarks"
138 bundle2-output-part: "check:bookmarks" 23 bytes payload
138 bundle2-output-part: "check:bookmarks" 23 bytes payload
139 bundle2-output: part 1: "CHECK:BOOKMARKS"
139 bundle2-output: part 1: "CHECK:BOOKMARKS"
140 bundle2-output: header chunk size: 22
140 bundle2-output: header chunk size: 22
141 bundle2-output: payload chunk size: 23
141 bundle2-output: payload chunk size: 23
142 bundle2-output: closing payload chunk
142 bundle2-output: closing payload chunk
143 bundle2-output: bundle part: "check:phases"
143 bundle2-output: bundle part: "check:phases"
144 bundle2-output-part: "check:phases" 24 bytes payload
144 bundle2-output-part: "check:phases" 24 bytes payload
145 bundle2-output: part 2: "CHECK:PHASES"
145 bundle2-output: part 2: "CHECK:PHASES"
146 bundle2-output: header chunk size: 19
146 bundle2-output: header chunk size: 19
147 bundle2-output: payload chunk size: 24
147 bundle2-output: payload chunk size: 24
148 bundle2-output: closing payload chunk
148 bundle2-output: closing payload chunk
149 bundle2-output: bundle part: "pushkey"
149 bundle2-output: bundle part: "pushkey"
150 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
150 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
151 bundle2-output: part 3: "PUSHKEY"
151 bundle2-output: part 3: "PUSHKEY"
152 bundle2-output: header chunk size: 90
152 bundle2-output: header chunk size: 90
153 bundle2-output: closing payload chunk
153 bundle2-output: closing payload chunk
154 bundle2-output: end of bundle
154 bundle2-output: end of bundle
155 bundle2-input: start processing of HG20 stream
155 bundle2-input: start processing of HG20 stream
156 bundle2-input: reading bundle2 stream parameters
156 bundle2-input: reading bundle2 stream parameters
157 bundle2-input-bundle: with-transaction
157 bundle2-input-bundle: with-transaction
158 bundle2-input: start extraction of bundle2 parts
158 bundle2-input: start extraction of bundle2 parts
159 bundle2-input: part header size: 16
159 bundle2-input: part header size: 16
160 bundle2-input: part type: "REPLYCAPS"
160 bundle2-input: part type: "REPLYCAPS"
161 bundle2-input: part id: "0"
161 bundle2-input: part id: "0"
162 bundle2-input: part parameters: 0
162 bundle2-input: part parameters: 0
163 bundle2-input: found a handler for part replycaps
163 bundle2-input: found a handler for part replycaps
164 bundle2-input-part: "replycaps" supported
164 bundle2-input-part: "replycaps" supported
165 bundle2-input: payload chunk size: 241
165 bundle2-input: payload chunk size: 224
166 bundle2-input: payload chunk size: 0
166 bundle2-input: payload chunk size: 0
167 bundle2-input-part: total payload size 241
167 bundle2-input-part: total payload size 224
168 bundle2-input: part header size: 22
168 bundle2-input: part header size: 22
169 bundle2-input: part type: "CHECK:BOOKMARKS"
169 bundle2-input: part type: "CHECK:BOOKMARKS"
170 bundle2-input: part id: "1"
170 bundle2-input: part id: "1"
171 bundle2-input: part parameters: 0
171 bundle2-input: part parameters: 0
172 bundle2-input: found a handler for part check:bookmarks
172 bundle2-input: found a handler for part check:bookmarks
173 bundle2-input-part: "check:bookmarks" supported
173 bundle2-input-part: "check:bookmarks" supported
174 bundle2-input: payload chunk size: 23
174 bundle2-input: payload chunk size: 23
175 bundle2-input: payload chunk size: 0
175 bundle2-input: payload chunk size: 0
176 bundle2-input-part: total payload size 23
176 bundle2-input-part: total payload size 23
177 bundle2-input: part header size: 19
177 bundle2-input: part header size: 19
178 bundle2-input: part type: "CHECK:PHASES"
178 bundle2-input: part type: "CHECK:PHASES"
179 bundle2-input: part id: "2"
179 bundle2-input: part id: "2"
180 bundle2-input: part parameters: 0
180 bundle2-input: part parameters: 0
181 bundle2-input: found a handler for part check:phases
181 bundle2-input: found a handler for part check:phases
182 bundle2-input-part: "check:phases" supported
182 bundle2-input-part: "check:phases" supported
183 bundle2-input: payload chunk size: 24
183 bundle2-input: payload chunk size: 24
184 bundle2-input: payload chunk size: 0
184 bundle2-input: payload chunk size: 0
185 bundle2-input-part: total payload size 24
185 bundle2-input-part: total payload size 24
186 bundle2-input: part header size: 90
186 bundle2-input: part header size: 90
187 bundle2-input: part type: "PUSHKEY"
187 bundle2-input: part type: "PUSHKEY"
188 bundle2-input: part id: "3"
188 bundle2-input: part id: "3"
189 bundle2-input: part parameters: 4
189 bundle2-input: part parameters: 4
190 bundle2-input: found a handler for part pushkey
190 bundle2-input: found a handler for part pushkey
191 bundle2-input-part: "pushkey" (params: 4 mandatory) supported
191 bundle2-input-part: "pushkey" (params: 4 mandatory) supported
192 pushing key for "bookmarks:W"
192 pushing key for "bookmarks:W"
193 bundle2-input: payload chunk size: 0
193 bundle2-input: payload chunk size: 0
194 bundle2-input: part header size: 0
194 bundle2-input: part header size: 0
195 bundle2-input: end of bundle2 stream
195 bundle2-input: end of bundle2 stream
196 bundle2-input-bundle: 4 parts total
196 bundle2-input-bundle: 4 parts total
197 running hook txnclose-bookmark.test: sh $TESTTMP/hook.sh
197 running hook txnclose-bookmark.test: sh $TESTTMP/hook.sh
198 test-hook-bookmark: W: 0000000000000000000000000000000000000000 ->
198 test-hook-bookmark: W: 0000000000000000000000000000000000000000 ->
199 bundle2-output-bundle: "HG20", 1 parts total
199 bundle2-output-bundle: "HG20", 1 parts total
200 bundle2-output: start emission of HG20 stream
200 bundle2-output: start emission of HG20 stream
201 bundle2-output: bundle parameter:
201 bundle2-output: bundle parameter:
202 bundle2-output: start of parts
202 bundle2-output: start of parts
203 bundle2-output: bundle part: "reply:pushkey"
203 bundle2-output: bundle part: "reply:pushkey"
204 bundle2-output-part: "reply:pushkey" (params: 0 advisory) empty payload
204 bundle2-output-part: "reply:pushkey" (params: 0 advisory) empty payload
205 bundle2-output: part 0: "REPLY:PUSHKEY"
205 bundle2-output: part 0: "REPLY:PUSHKEY"
206 bundle2-output: header chunk size: 43
206 bundle2-output: header chunk size: 43
207 bundle2-output: closing payload chunk
207 bundle2-output: closing payload chunk
208 bundle2-output: end of bundle
208 bundle2-output: end of bundle
209 bundle2-input: start processing of HG20 stream
209 bundle2-input: start processing of HG20 stream
210 bundle2-input: reading bundle2 stream parameters
210 bundle2-input: reading bundle2 stream parameters
211 bundle2-input-bundle: no-transaction
211 bundle2-input-bundle: no-transaction
212 bundle2-input: start extraction of bundle2 parts
212 bundle2-input: start extraction of bundle2 parts
213 bundle2-input: part header size: 43
213 bundle2-input: part header size: 43
214 bundle2-input: part type: "REPLY:PUSHKEY"
214 bundle2-input: part type: "REPLY:PUSHKEY"
215 bundle2-input: part id: "0"
215 bundle2-input: part id: "0"
216 bundle2-input: part parameters: 2
216 bundle2-input: part parameters: 2
217 bundle2-input: found a handler for part reply:pushkey
217 bundle2-input: found a handler for part reply:pushkey
218 bundle2-input-part: "reply:pushkey" (params: 0 advisory) supported
218 bundle2-input-part: "reply:pushkey" (params: 0 advisory) supported
219 bundle2-input: payload chunk size: 0
219 bundle2-input: payload chunk size: 0
220 bundle2-input: part header size: 0
220 bundle2-input: part header size: 0
221 bundle2-input: end of bundle2 stream
221 bundle2-input: end of bundle2 stream
222 bundle2-input-bundle: 1 parts total
222 bundle2-input-bundle: 1 parts total
223 deleting remote bookmark W
223 deleting remote bookmark W
224 listing keys for "phases"
224 listing keys for "phases"
225 [1]
225 [1]
226
226
227 #endif
227 #endif
228 #if b2-binary
228 #if b2-binary
229
229
230 $ hg push -B W ../a --config "$TESTHOOK" --debug --config devel.bundle2.debug=yes
230 $ hg push -B W ../a --config "$TESTHOOK" --debug --config devel.bundle2.debug=yes
231 pushing to ../a
231 pushing to ../a
232 query 1; heads
232 query 1; heads
233 searching for changes
233 searching for changes
234 all remote heads known locally
234 all remote heads known locally
235 listing keys for "phases"
235 listing keys for "phases"
236 checking for updated bookmarks
236 checking for updated bookmarks
237 listing keys for "bookmarks"
237 listing keys for "bookmarks"
238 no changes found
238 no changes found
239 bundle2-output-bundle: "HG20", 4 parts total
239 bundle2-output-bundle: "HG20", 4 parts total
240 bundle2-output: start emission of HG20 stream
240 bundle2-output: start emission of HG20 stream
241 bundle2-output: bundle parameter:
241 bundle2-output: bundle parameter:
242 bundle2-output: start of parts
242 bundle2-output: start of parts
243 bundle2-output: bundle part: "replycaps"
243 bundle2-output: bundle part: "replycaps"
244 bundle2-output-part: "replycaps" 241 bytes payload
244 bundle2-output-part: "replycaps" 224 bytes payload
245 bundle2-output: part 0: "REPLYCAPS"
245 bundle2-output: part 0: "REPLYCAPS"
246 bundle2-output: header chunk size: 16
246 bundle2-output: header chunk size: 16
247 bundle2-output: payload chunk size: 241
247 bundle2-output: payload chunk size: 224
248 bundle2-output: closing payload chunk
248 bundle2-output: closing payload chunk
249 bundle2-output: bundle part: "check:bookmarks"
249 bundle2-output: bundle part: "check:bookmarks"
250 bundle2-output-part: "check:bookmarks" 23 bytes payload
250 bundle2-output-part: "check:bookmarks" 23 bytes payload
251 bundle2-output: part 1: "CHECK:BOOKMARKS"
251 bundle2-output: part 1: "CHECK:BOOKMARKS"
252 bundle2-output: header chunk size: 22
252 bundle2-output: header chunk size: 22
253 bundle2-output: payload chunk size: 23
253 bundle2-output: payload chunk size: 23
254 bundle2-output: closing payload chunk
254 bundle2-output: closing payload chunk
255 bundle2-output: bundle part: "check:phases"
255 bundle2-output: bundle part: "check:phases"
256 bundle2-output-part: "check:phases" 24 bytes payload
256 bundle2-output-part: "check:phases" 24 bytes payload
257 bundle2-output: part 2: "CHECK:PHASES"
257 bundle2-output: part 2: "CHECK:PHASES"
258 bundle2-output: header chunk size: 19
258 bundle2-output: header chunk size: 19
259 bundle2-output: payload chunk size: 24
259 bundle2-output: payload chunk size: 24
260 bundle2-output: closing payload chunk
260 bundle2-output: closing payload chunk
261 bundle2-output: bundle part: "bookmarks"
261 bundle2-output: bundle part: "bookmarks"
262 bundle2-output-part: "bookmarks" 23 bytes payload
262 bundle2-output-part: "bookmarks" 23 bytes payload
263 bundle2-output: part 3: "BOOKMARKS"
263 bundle2-output: part 3: "BOOKMARKS"
264 bundle2-output: header chunk size: 16
264 bundle2-output: header chunk size: 16
265 bundle2-output: payload chunk size: 23
265 bundle2-output: payload chunk size: 23
266 bundle2-output: closing payload chunk
266 bundle2-output: closing payload chunk
267 bundle2-output: end of bundle
267 bundle2-output: end of bundle
268 bundle2-input: start processing of HG20 stream
268 bundle2-input: start processing of HG20 stream
269 bundle2-input: reading bundle2 stream parameters
269 bundle2-input: reading bundle2 stream parameters
270 bundle2-input-bundle: with-transaction
270 bundle2-input-bundle: with-transaction
271 bundle2-input: start extraction of bundle2 parts
271 bundle2-input: start extraction of bundle2 parts
272 bundle2-input: part header size: 16
272 bundle2-input: part header size: 16
273 bundle2-input: part type: "REPLYCAPS"
273 bundle2-input: part type: "REPLYCAPS"
274 bundle2-input: part id: "0"
274 bundle2-input: part id: "0"
275 bundle2-input: part parameters: 0
275 bundle2-input: part parameters: 0
276 bundle2-input: found a handler for part replycaps
276 bundle2-input: found a handler for part replycaps
277 bundle2-input-part: "replycaps" supported
277 bundle2-input-part: "replycaps" supported
278 bundle2-input: payload chunk size: 241
278 bundle2-input: payload chunk size: 224
279 bundle2-input: payload chunk size: 0
279 bundle2-input: payload chunk size: 0
280 bundle2-input-part: total payload size 241
280 bundle2-input-part: total payload size 224
281 bundle2-input: part header size: 22
281 bundle2-input: part header size: 22
282 bundle2-input: part type: "CHECK:BOOKMARKS"
282 bundle2-input: part type: "CHECK:BOOKMARKS"
283 bundle2-input: part id: "1"
283 bundle2-input: part id: "1"
284 bundle2-input: part parameters: 0
284 bundle2-input: part parameters: 0
285 bundle2-input: found a handler for part check:bookmarks
285 bundle2-input: found a handler for part check:bookmarks
286 bundle2-input-part: "check:bookmarks" supported
286 bundle2-input-part: "check:bookmarks" supported
287 bundle2-input: payload chunk size: 23
287 bundle2-input: payload chunk size: 23
288 bundle2-input: payload chunk size: 0
288 bundle2-input: payload chunk size: 0
289 bundle2-input-part: total payload size 23
289 bundle2-input-part: total payload size 23
290 bundle2-input: part header size: 19
290 bundle2-input: part header size: 19
291 bundle2-input: part type: "CHECK:PHASES"
291 bundle2-input: part type: "CHECK:PHASES"
292 bundle2-input: part id: "2"
292 bundle2-input: part id: "2"
293 bundle2-input: part parameters: 0
293 bundle2-input: part parameters: 0
294 bundle2-input: found a handler for part check:phases
294 bundle2-input: found a handler for part check:phases
295 bundle2-input-part: "check:phases" supported
295 bundle2-input-part: "check:phases" supported
296 bundle2-input: payload chunk size: 24
296 bundle2-input: payload chunk size: 24
297 bundle2-input: payload chunk size: 0
297 bundle2-input: payload chunk size: 0
298 bundle2-input-part: total payload size 24
298 bundle2-input-part: total payload size 24
299 bundle2-input: part header size: 16
299 bundle2-input: part header size: 16
300 bundle2-input: part type: "BOOKMARKS"
300 bundle2-input: part type: "BOOKMARKS"
301 bundle2-input: part id: "3"
301 bundle2-input: part id: "3"
302 bundle2-input: part parameters: 0
302 bundle2-input: part parameters: 0
303 bundle2-input: found a handler for part bookmarks
303 bundle2-input: found a handler for part bookmarks
304 bundle2-input-part: "bookmarks" supported
304 bundle2-input-part: "bookmarks" supported
305 bundle2-input: payload chunk size: 23
305 bundle2-input: payload chunk size: 23
306 bundle2-input: payload chunk size: 0
306 bundle2-input: payload chunk size: 0
307 bundle2-input-part: total payload size 23
307 bundle2-input-part: total payload size 23
308 bundle2-input: part header size: 0
308 bundle2-input: part header size: 0
309 bundle2-input: end of bundle2 stream
309 bundle2-input: end of bundle2 stream
310 bundle2-input-bundle: 4 parts total
310 bundle2-input-bundle: 4 parts total
311 running hook txnclose-bookmark.test: sh $TESTTMP/hook.sh
311 running hook txnclose-bookmark.test: sh $TESTTMP/hook.sh
312 test-hook-bookmark: W: 0000000000000000000000000000000000000000 ->
312 test-hook-bookmark: W: 0000000000000000000000000000000000000000 ->
313 bundle2-output-bundle: "HG20", 0 parts total
313 bundle2-output-bundle: "HG20", 0 parts total
314 bundle2-output: start emission of HG20 stream
314 bundle2-output: start emission of HG20 stream
315 bundle2-output: bundle parameter:
315 bundle2-output: bundle parameter:
316 bundle2-output: start of parts
316 bundle2-output: start of parts
317 bundle2-output: end of bundle
317 bundle2-output: end of bundle
318 bundle2-input: start processing of HG20 stream
318 bundle2-input: start processing of HG20 stream
319 bundle2-input: reading bundle2 stream parameters
319 bundle2-input: reading bundle2 stream parameters
320 bundle2-input-bundle: no-transaction
320 bundle2-input-bundle: no-transaction
321 bundle2-input: start extraction of bundle2 parts
321 bundle2-input: start extraction of bundle2 parts
322 bundle2-input: part header size: 0
322 bundle2-input: part header size: 0
323 bundle2-input: end of bundle2 stream
323 bundle2-input: end of bundle2 stream
324 bundle2-input-bundle: 0 parts total
324 bundle2-input-bundle: 0 parts total
325 deleting remote bookmark W
325 deleting remote bookmark W
326 listing keys for "phases"
326 listing keys for "phases"
327 [1]
327 [1]
328
328
329 #endif
329 #endif
330
330
331 Divergent bookmark cannot be exported
331 Divergent bookmark cannot be exported
332
332
333 $ hg book W@default
333 $ hg book W@default
334 $ hg push -B W@default ../a
334 $ hg push -B W@default ../a
335 pushing to ../a
335 pushing to ../a
336 searching for changes
336 searching for changes
337 cannot push divergent bookmark W@default!
337 cannot push divergent bookmark W@default!
338 no changes found
338 no changes found
339 [2]
339 [2]
340 $ hg book -d W@default
340 $ hg book -d W@default
341
341
342 export the active bookmark
342 export the active bookmark
343
343
344 $ hg bookmark V
344 $ hg bookmark V
345 $ hg push -B . ../a
345 $ hg push -B . ../a
346 pushing to ../a
346 pushing to ../a
347 searching for changes
347 searching for changes
348 no changes found
348 no changes found
349 exporting bookmark V
349 exporting bookmark V
350 [1]
350 [1]
351
351
352 exporting the active bookmark with 'push -B .'
352 exporting the active bookmark with 'push -B .'
353 demand that one of the bookmarks is activated
353 demand that one of the bookmarks is activated
354
354
355 $ hg update -r default
355 $ hg update -r default
356 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
356 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
357 (leaving bookmark V)
357 (leaving bookmark V)
358 $ hg push -B . ../a
358 $ hg push -B . ../a
359 abort: no active bookmark
359 abort: no active bookmark
360 [255]
360 [255]
361 $ hg update -r V
361 $ hg update -r V
362 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
362 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
363 (activating bookmark V)
363 (activating bookmark V)
364
364
365 delete the bookmark
365 delete the bookmark
366
366
367 $ hg book -d V
367 $ hg book -d V
368 $ hg push -B V ../a
368 $ hg push -B V ../a
369 pushing to ../a
369 pushing to ../a
370 searching for changes
370 searching for changes
371 no changes found
371 no changes found
372 deleting remote bookmark V
372 deleting remote bookmark V
373 [1]
373 [1]
374 $ hg up foobar
374 $ hg up foobar
375 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
375 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
376 (activating bookmark foobar)
376 (activating bookmark foobar)
377
377
378 push/pull name that doesn't exist
378 push/pull name that doesn't exist
379
379
380 $ hg push -B badname ../a
380 $ hg push -B badname ../a
381 pushing to ../a
381 pushing to ../a
382 searching for changes
382 searching for changes
383 bookmark badname does not exist on the local or remote repository!
383 bookmark badname does not exist on the local or remote repository!
384 no changes found
384 no changes found
385 [2]
385 [2]
386 $ hg pull -B anotherbadname ../a
386 $ hg pull -B anotherbadname ../a
387 pulling from ../a
387 pulling from ../a
388 abort: remote bookmark anotherbadname not found!
388 abort: remote bookmark anotherbadname not found!
389 [10]
389 [10]
390
390
391 divergent bookmarks
391 divergent bookmarks
392
392
393 $ cd ../a
393 $ cd ../a
394 $ echo c1 > f1
394 $ echo c1 > f1
395 $ hg ci -Am1
395 $ hg ci -Am1
396 adding f1
396 adding f1
397 $ hg book -f @
397 $ hg book -f @
398 $ hg book -f X
398 $ hg book -f X
399 $ hg book
399 $ hg book
400 @ 1:0d2164f0ce0d
400 @ 1:0d2164f0ce0d
401 * X 1:0d2164f0ce0d
401 * X 1:0d2164f0ce0d
402 Y 0:4e3505fd9583
402 Y 0:4e3505fd9583
403 Z 1:0d2164f0ce0d
403 Z 1:0d2164f0ce0d
404
404
405 $ cd ../b
405 $ cd ../b
406 $ hg up
406 $ hg up
407 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
407 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
408 updating bookmark foobar
408 updating bookmark foobar
409 $ echo c2 > f2
409 $ echo c2 > f2
410 $ hg ci -Am2
410 $ hg ci -Am2
411 adding f2
411 adding f2
412 $ hg book -if @
412 $ hg book -if @
413 $ hg book -if X
413 $ hg book -if X
414 $ hg book
414 $ hg book
415 @ 1:9b140be10808
415 @ 1:9b140be10808
416 X 1:9b140be10808
416 X 1:9b140be10808
417 Y 0:4e3505fd9583
417 Y 0:4e3505fd9583
418 Z 0:4e3505fd9583
418 Z 0:4e3505fd9583
419 foo -1:000000000000
419 foo -1:000000000000
420 * foobar 1:9b140be10808
420 * foobar 1:9b140be10808
421
421
422 $ hg pull --config paths.foo=../a foo --config "$TESTHOOK"
422 $ hg pull --config paths.foo=../a foo --config "$TESTHOOK"
423 pulling from $TESTTMP/a
423 pulling from $TESTTMP/a
424 searching for changes
424 searching for changes
425 adding changesets
425 adding changesets
426 adding manifests
426 adding manifests
427 adding file changes
427 adding file changes
428 divergent bookmark @ stored as @foo
428 divergent bookmark @ stored as @foo
429 divergent bookmark X stored as X@foo
429 divergent bookmark X stored as X@foo
430 updating bookmark Z
430 updating bookmark Z
431 added 1 changesets with 1 changes to 1 files (+1 heads)
431 added 1 changesets with 1 changes to 1 files (+1 heads)
432 new changesets 0d2164f0ce0d (1 drafts)
432 new changesets 0d2164f0ce0d (1 drafts)
433 test-hook-bookmark: @foo: -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
433 test-hook-bookmark: @foo: -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
434 test-hook-bookmark: X@foo: -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
434 test-hook-bookmark: X@foo: -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
435 test-hook-bookmark: Z: 4e3505fd95835d721066b76e75dbb8cc554d7f77 -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
435 test-hook-bookmark: Z: 4e3505fd95835d721066b76e75dbb8cc554d7f77 -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
436 (run 'hg heads' to see heads, 'hg merge' to merge)
436 (run 'hg heads' to see heads, 'hg merge' to merge)
437 $ hg book
437 $ hg book
438 @ 1:9b140be10808
438 @ 1:9b140be10808
439 @foo 2:0d2164f0ce0d
439 @foo 2:0d2164f0ce0d
440 X 1:9b140be10808
440 X 1:9b140be10808
441 X@foo 2:0d2164f0ce0d
441 X@foo 2:0d2164f0ce0d
442 Y 0:4e3505fd9583
442 Y 0:4e3505fd9583
443 Z 2:0d2164f0ce0d
443 Z 2:0d2164f0ce0d
444 foo -1:000000000000
444 foo -1:000000000000
445 * foobar 1:9b140be10808
445 * foobar 1:9b140be10808
446
446
447 (test that too many divergence of bookmark)
447 (test that too many divergence of bookmark)
448
448
449 $ "$PYTHON" $TESTDIR/seq.py 1 100 | while read i; do hg bookmarks -r 000000000000 "X@${i}"; done
449 $ "$PYTHON" $TESTDIR/seq.py 1 100 | while read i; do hg bookmarks -r 000000000000 "X@${i}"; done
450 $ hg pull ../a
450 $ hg pull ../a
451 pulling from ../a
451 pulling from ../a
452 searching for changes
452 searching for changes
453 no changes found
453 no changes found
454 warning: failed to assign numbered name to divergent bookmark X
454 warning: failed to assign numbered name to divergent bookmark X
455 divergent bookmark @ stored as @1
455 divergent bookmark @ stored as @1
456 $ hg bookmarks | grep '^ X' | grep -v ':000000000000'
456 $ hg bookmarks | grep '^ X' | grep -v ':000000000000'
457 X 1:9b140be10808
457 X 1:9b140be10808
458 X@foo 2:0d2164f0ce0d
458 X@foo 2:0d2164f0ce0d
459
459
460 (test that remotely diverged bookmarks are reused if they aren't changed)
460 (test that remotely diverged bookmarks are reused if they aren't changed)
461
461
462 $ hg bookmarks | grep '^ @'
462 $ hg bookmarks | grep '^ @'
463 @ 1:9b140be10808
463 @ 1:9b140be10808
464 @1 2:0d2164f0ce0d
464 @1 2:0d2164f0ce0d
465 @foo 2:0d2164f0ce0d
465 @foo 2:0d2164f0ce0d
466 $ hg pull ../a
466 $ hg pull ../a
467 pulling from ../a
467 pulling from ../a
468 searching for changes
468 searching for changes
469 no changes found
469 no changes found
470 warning: failed to assign numbered name to divergent bookmark X
470 warning: failed to assign numbered name to divergent bookmark X
471 divergent bookmark @ stored as @1
471 divergent bookmark @ stored as @1
472 $ hg bookmarks | grep '^ @'
472 $ hg bookmarks | grep '^ @'
473 @ 1:9b140be10808
473 @ 1:9b140be10808
474 @1 2:0d2164f0ce0d
474 @1 2:0d2164f0ce0d
475 @foo 2:0d2164f0ce0d
475 @foo 2:0d2164f0ce0d
476
476
477 $ "$PYTHON" $TESTDIR/seq.py 1 100 | while read i; do hg bookmarks -d "X@${i}"; done
477 $ "$PYTHON" $TESTDIR/seq.py 1 100 | while read i; do hg bookmarks -d "X@${i}"; done
478 $ hg bookmarks -d "@1"
478 $ hg bookmarks -d "@1"
479
479
480 $ hg push -f ../a
480 $ hg push -f ../a
481 pushing to ../a
481 pushing to ../a
482 searching for changes
482 searching for changes
483 adding changesets
483 adding changesets
484 adding manifests
484 adding manifests
485 adding file changes
485 adding file changes
486 added 1 changesets with 1 changes to 1 files (+1 heads)
486 added 1 changesets with 1 changes to 1 files (+1 heads)
487 $ hg -R ../a book
487 $ hg -R ../a book
488 @ 1:0d2164f0ce0d
488 @ 1:0d2164f0ce0d
489 * X 1:0d2164f0ce0d
489 * X 1:0d2164f0ce0d
490 Y 0:4e3505fd9583
490 Y 0:4e3505fd9583
491 Z 1:0d2164f0ce0d
491 Z 1:0d2164f0ce0d
492
492
493 explicit pull should overwrite the local version (issue4439)
493 explicit pull should overwrite the local version (issue4439)
494
494
495 $ hg update -r X
495 $ hg update -r X
496 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
496 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
497 (activating bookmark X)
497 (activating bookmark X)
498 $ hg pull --config paths.foo=../a foo -B . --config "$TESTHOOK"
498 $ hg pull --config paths.foo=../a foo -B . --config "$TESTHOOK"
499 pulling from $TESTTMP/a
499 pulling from $TESTTMP/a
500 no changes found
500 no changes found
501 divergent bookmark @ stored as @foo
501 divergent bookmark @ stored as @foo
502 importing bookmark X
502 importing bookmark X
503 test-hook-bookmark: @foo: 0d2164f0ce0d8f1d6f94351eba04b794909be66c -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
503 test-hook-bookmark: @foo: 0d2164f0ce0d8f1d6f94351eba04b794909be66c -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
504 test-hook-bookmark: X: 9b140be1080824d768c5a4691a564088eede71f9 -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
504 test-hook-bookmark: X: 9b140be1080824d768c5a4691a564088eede71f9 -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
505
505
506 reinstall state for further testing:
506 reinstall state for further testing:
507
507
508 $ hg book -fr 9b140be10808 X
508 $ hg book -fr 9b140be10808 X
509
509
510 revsets should not ignore divergent bookmarks
510 revsets should not ignore divergent bookmarks
511
511
512 $ hg bookmark -fr 1 Z
512 $ hg bookmark -fr 1 Z
513 $ hg log -r 'bookmark()' --template '{rev}:{node|short} {bookmarks}\n'
513 $ hg log -r 'bookmark()' --template '{rev}:{node|short} {bookmarks}\n'
514 0:4e3505fd9583 Y
514 0:4e3505fd9583 Y
515 1:9b140be10808 @ X Z foobar
515 1:9b140be10808 @ X Z foobar
516 2:0d2164f0ce0d @foo X@foo
516 2:0d2164f0ce0d @foo X@foo
517 $ hg log -r 'bookmark("X@foo")' --template '{rev}:{node|short} {bookmarks}\n'
517 $ hg log -r 'bookmark("X@foo")' --template '{rev}:{node|short} {bookmarks}\n'
518 2:0d2164f0ce0d @foo X@foo
518 2:0d2164f0ce0d @foo X@foo
519 $ hg log -r 'bookmark("re:X@foo")' --template '{rev}:{node|short} {bookmarks}\n'
519 $ hg log -r 'bookmark("re:X@foo")' --template '{rev}:{node|short} {bookmarks}\n'
520 2:0d2164f0ce0d @foo X@foo
520 2:0d2164f0ce0d @foo X@foo
521
521
522 update a remote bookmark from a non-head to a head
522 update a remote bookmark from a non-head to a head
523
523
524 $ hg up -q Y
524 $ hg up -q Y
525 $ echo c3 > f2
525 $ echo c3 > f2
526 $ hg ci -Am3
526 $ hg ci -Am3
527 adding f2
527 adding f2
528 created new head
528 created new head
529 $ hg push ../a --config "$TESTHOOK"
529 $ hg push ../a --config "$TESTHOOK"
530 pushing to ../a
530 pushing to ../a
531 searching for changes
531 searching for changes
532 adding changesets
532 adding changesets
533 adding manifests
533 adding manifests
534 adding file changes
534 adding file changes
535 added 1 changesets with 1 changes to 1 files (+1 heads)
535 added 1 changesets with 1 changes to 1 files (+1 heads)
536 test-hook-bookmark: Y: 4e3505fd95835d721066b76e75dbb8cc554d7f77 -> f6fc62dde3c0771e29704af56ba4d8af77abcc2f
536 test-hook-bookmark: Y: 4e3505fd95835d721066b76e75dbb8cc554d7f77 -> f6fc62dde3c0771e29704af56ba4d8af77abcc2f
537 updating bookmark Y
537 updating bookmark Y
538 $ hg -R ../a book
538 $ hg -R ../a book
539 @ 1:0d2164f0ce0d
539 @ 1:0d2164f0ce0d
540 * X 1:0d2164f0ce0d
540 * X 1:0d2164f0ce0d
541 Y 3:f6fc62dde3c0
541 Y 3:f6fc62dde3c0
542 Z 1:0d2164f0ce0d
542 Z 1:0d2164f0ce0d
543
543
544 update a bookmark in the middle of a client pulling changes
544 update a bookmark in the middle of a client pulling changes
545
545
546 $ cd ..
546 $ cd ..
547 $ hg clone -q a pull-race
547 $ hg clone -q a pull-race
548
548
549 We want to use http because it is stateless and therefore more susceptible to
549 We want to use http because it is stateless and therefore more susceptible to
550 race conditions
550 race conditions
551
551
552 $ hg serve -R pull-race -p $HGPORT -d --pid-file=pull-race.pid -E main-error.log
552 $ hg serve -R pull-race -p $HGPORT -d --pid-file=pull-race.pid -E main-error.log
553 $ cat pull-race.pid >> $DAEMON_PIDS
553 $ cat pull-race.pid >> $DAEMON_PIDS
554
554
555 $ cat <<EOF > $TESTTMP/out_makecommit.sh
555 $ cat <<EOF > $TESTTMP/out_makecommit.sh
556 > #!/bin/sh
556 > #!/bin/sh
557 > hg ci -Am5
557 > hg ci -Am5
558 > echo committed in pull-race
558 > echo committed in pull-race
559 > EOF
559 > EOF
560
560
561 $ hg clone -q http://localhost:$HGPORT/ pull-race2 --config "$TESTHOOK"
561 $ hg clone -q http://localhost:$HGPORT/ pull-race2 --config "$TESTHOOK"
562 test-hook-bookmark: @: -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
562 test-hook-bookmark: @: -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
563 test-hook-bookmark: X: -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
563 test-hook-bookmark: X: -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
564 test-hook-bookmark: Y: -> f6fc62dde3c0771e29704af56ba4d8af77abcc2f
564 test-hook-bookmark: Y: -> f6fc62dde3c0771e29704af56ba4d8af77abcc2f
565 test-hook-bookmark: Z: -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
565 test-hook-bookmark: Z: -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
566 $ cd pull-race
566 $ cd pull-race
567 $ hg up -q Y
567 $ hg up -q Y
568 $ echo c4 > f2
568 $ echo c4 > f2
569 $ hg ci -Am4
569 $ hg ci -Am4
570 $ echo c5 > f3
570 $ echo c5 > f3
571 $ cat <<EOF > .hg/hgrc
571 $ cat <<EOF > .hg/hgrc
572 > [hooks]
572 > [hooks]
573 > outgoing.makecommit = sh $TESTTMP/out_makecommit.sh
573 > outgoing.makecommit = sh $TESTTMP/out_makecommit.sh
574 > EOF
574 > EOF
575
575
576 (new config needs a server restart)
576 (new config needs a server restart)
577
577
578 $ cd ..
578 $ cd ..
579 $ killdaemons.py
579 $ killdaemons.py
580 $ hg serve -R pull-race -p $HGPORT -d --pid-file=pull-race.pid -E main-error.log
580 $ hg serve -R pull-race -p $HGPORT -d --pid-file=pull-race.pid -E main-error.log
581 $ cat pull-race.pid >> $DAEMON_PIDS
581 $ cat pull-race.pid >> $DAEMON_PIDS
582 $ cd pull-race2
582 $ cd pull-race2
583 $ hg -R $TESTTMP/pull-race book
583 $ hg -R $TESTTMP/pull-race book
584 @ 1:0d2164f0ce0d
584 @ 1:0d2164f0ce0d
585 X 1:0d2164f0ce0d
585 X 1:0d2164f0ce0d
586 * Y 4:b0a5eff05604
586 * Y 4:b0a5eff05604
587 Z 1:0d2164f0ce0d
587 Z 1:0d2164f0ce0d
588 $ hg pull
588 $ hg pull
589 pulling from http://localhost:$HGPORT/
589 pulling from http://localhost:$HGPORT/
590 searching for changes
590 searching for changes
591 adding changesets
591 adding changesets
592 adding manifests
592 adding manifests
593 adding file changes
593 adding file changes
594 updating bookmark Y
594 updating bookmark Y
595 added 1 changesets with 1 changes to 1 files
595 added 1 changesets with 1 changes to 1 files
596 new changesets b0a5eff05604 (1 drafts)
596 new changesets b0a5eff05604 (1 drafts)
597 (run 'hg update' to get a working copy)
597 (run 'hg update' to get a working copy)
598 $ hg book
598 $ hg book
599 * @ 1:0d2164f0ce0d
599 * @ 1:0d2164f0ce0d
600 X 1:0d2164f0ce0d
600 X 1:0d2164f0ce0d
601 Y 4:b0a5eff05604
601 Y 4:b0a5eff05604
602 Z 1:0d2164f0ce0d
602 Z 1:0d2164f0ce0d
603
603
604 Update a bookmark right after the initial lookup -B (issue4689)
604 Update a bookmark right after the initial lookup -B (issue4689)
605
605
606 $ echo c6 > ../pull-race/f3 # to be committed during the race
606 $ echo c6 > ../pull-race/f3 # to be committed during the race
607 $ cat <<EOF > $TESTTMP/listkeys_makecommit.sh
607 $ cat <<EOF > $TESTTMP/listkeys_makecommit.sh
608 > #!/bin/sh
608 > #!/bin/sh
609 > if hg st | grep -q M; then
609 > if hg st | grep -q M; then
610 > hg commit -m race
610 > hg commit -m race
611 > echo committed in pull-race
611 > echo committed in pull-race
612 > else
612 > else
613 > exit 0
613 > exit 0
614 > fi
614 > fi
615 > EOF
615 > EOF
616 $ cat <<EOF > ../pull-race/.hg/hgrc
616 $ cat <<EOF > ../pull-race/.hg/hgrc
617 > [hooks]
617 > [hooks]
618 > # If anything to commit, commit it right after the first key listing used
618 > # If anything to commit, commit it right after the first key listing used
619 > # during lookup. This makes the commit appear before the actual getbundle
619 > # during lookup. This makes the commit appear before the actual getbundle
620 > # call.
620 > # call.
621 > listkeys.makecommit= sh $TESTTMP/listkeys_makecommit.sh
621 > listkeys.makecommit= sh $TESTTMP/listkeys_makecommit.sh
622 > EOF
622 > EOF
623 $ restart_server() {
623 $ restart_server() {
624 > "$TESTDIR/killdaemons.py" $DAEMON_PIDS
624 > "$TESTDIR/killdaemons.py" $DAEMON_PIDS
625 > hg serve -R ../pull-race -p $HGPORT -d --pid-file=../pull-race.pid -E main-error.log
625 > hg serve -R ../pull-race -p $HGPORT -d --pid-file=../pull-race.pid -E main-error.log
626 > cat ../pull-race.pid >> $DAEMON_PIDS
626 > cat ../pull-race.pid >> $DAEMON_PIDS
627 > }
627 > }
628 $ restart_server # new config need server restart
628 $ restart_server # new config need server restart
629 $ hg -R $TESTTMP/pull-race book
629 $ hg -R $TESTTMP/pull-race book
630 @ 1:0d2164f0ce0d
630 @ 1:0d2164f0ce0d
631 X 1:0d2164f0ce0d
631 X 1:0d2164f0ce0d
632 * Y 5:35d1ef0a8d1b
632 * Y 5:35d1ef0a8d1b
633 Z 1:0d2164f0ce0d
633 Z 1:0d2164f0ce0d
634 $ hg update -r Y
634 $ hg update -r Y
635 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
635 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
636 (activating bookmark Y)
636 (activating bookmark Y)
637 $ hg pull -B .
637 $ hg pull -B .
638 pulling from http://localhost:$HGPORT/
638 pulling from http://localhost:$HGPORT/
639 searching for changes
639 searching for changes
640 adding changesets
640 adding changesets
641 adding manifests
641 adding manifests
642 adding file changes
642 adding file changes
643 updating bookmark Y
643 updating bookmark Y
644 added 1 changesets with 1 changes to 1 files
644 added 1 changesets with 1 changes to 1 files
645 new changesets 35d1ef0a8d1b (1 drafts)
645 new changesets 35d1ef0a8d1b (1 drafts)
646 (run 'hg update' to get a working copy)
646 (run 'hg update' to get a working copy)
647 $ hg book
647 $ hg book
648 @ 1:0d2164f0ce0d
648 @ 1:0d2164f0ce0d
649 X 1:0d2164f0ce0d
649 X 1:0d2164f0ce0d
650 * Y 5:35d1ef0a8d1b
650 * Y 5:35d1ef0a8d1b
651 Z 1:0d2164f0ce0d
651 Z 1:0d2164f0ce0d
652
652
653 Update a bookmark right after the initial lookup -r (issue4700)
653 Update a bookmark right after the initial lookup -r (issue4700)
654
654
655 $ echo c7 > ../pull-race/f3 # to be committed during the race
655 $ echo c7 > ../pull-race/f3 # to be committed during the race
656 $ cat <<EOF > ../lookuphook.py
656 $ cat <<EOF > ../lookuphook.py
657 > """small extensions adding a hook after wireprotocol lookup to test race"""
657 > """small extensions adding a hook after wireprotocol lookup to test race"""
658 > import functools
658 > import functools
659 > from mercurial import wireprotov1server, wireprotov2server
659 > from mercurial import wireprotov1server, wireprotov2server
660 >
660 >
661 > def wrappedlookup(orig, repo, *args, **kwargs):
661 > def wrappedlookup(orig, repo, *args, **kwargs):
662 > ret = orig(repo, *args, **kwargs)
662 > ret = orig(repo, *args, **kwargs)
663 > repo.hook(b'lookup')
663 > repo.hook(b'lookup')
664 > return ret
664 > return ret
665 > for table in [wireprotov1server.commands, wireprotov2server.COMMANDS]:
665 > for table in [wireprotov1server.commands, wireprotov2server.COMMANDS]:
666 > table[b'lookup'].func = functools.partial(wrappedlookup, table[b'lookup'].func)
666 > table[b'lookup'].func = functools.partial(wrappedlookup, table[b'lookup'].func)
667 > EOF
667 > EOF
668 $ cat <<EOF > ../pull-race/.hg/hgrc
668 $ cat <<EOF > ../pull-race/.hg/hgrc
669 > [extensions]
669 > [extensions]
670 > lookuphook=$TESTTMP/lookuphook.py
670 > lookuphook=$TESTTMP/lookuphook.py
671 > [hooks]
671 > [hooks]
672 > lookup.makecommit= sh $TESTTMP/listkeys_makecommit.sh
672 > lookup.makecommit= sh $TESTTMP/listkeys_makecommit.sh
673 > EOF
673 > EOF
674 $ restart_server # new config need server restart
674 $ restart_server # new config need server restart
675 $ hg -R $TESTTMP/pull-race book
675 $ hg -R $TESTTMP/pull-race book
676 @ 1:0d2164f0ce0d
676 @ 1:0d2164f0ce0d
677 X 1:0d2164f0ce0d
677 X 1:0d2164f0ce0d
678 * Y 6:0d60821d2197
678 * Y 6:0d60821d2197
679 Z 1:0d2164f0ce0d
679 Z 1:0d2164f0ce0d
680 $ hg pull -r Y
680 $ hg pull -r Y
681 pulling from http://localhost:$HGPORT/
681 pulling from http://localhost:$HGPORT/
682 searching for changes
682 searching for changes
683 adding changesets
683 adding changesets
684 adding manifests
684 adding manifests
685 adding file changes
685 adding file changes
686 updating bookmark Y
686 updating bookmark Y
687 added 1 changesets with 1 changes to 1 files
687 added 1 changesets with 1 changes to 1 files
688 new changesets 0d60821d2197 (1 drafts)
688 new changesets 0d60821d2197 (1 drafts)
689 (run 'hg update' to get a working copy)
689 (run 'hg update' to get a working copy)
690 $ hg book
690 $ hg book
691 @ 1:0d2164f0ce0d
691 @ 1:0d2164f0ce0d
692 X 1:0d2164f0ce0d
692 X 1:0d2164f0ce0d
693 * Y 6:0d60821d2197
693 * Y 6:0d60821d2197
694 Z 1:0d2164f0ce0d
694 Z 1:0d2164f0ce0d
695 $ hg -R $TESTTMP/pull-race book
695 $ hg -R $TESTTMP/pull-race book
696 @ 1:0d2164f0ce0d
696 @ 1:0d2164f0ce0d
697 X 1:0d2164f0ce0d
697 X 1:0d2164f0ce0d
698 * Y 7:714424d9e8b8
698 * Y 7:714424d9e8b8
699 Z 1:0d2164f0ce0d
699 Z 1:0d2164f0ce0d
700
700
701 (done with this section of the test)
701 (done with this section of the test)
702
702
703 $ killdaemons.py
703 $ killdaemons.py
704 $ cd ../b
704 $ cd ../b
705
705
706 diverging a remote bookmark fails
706 diverging a remote bookmark fails
707
707
708 $ hg up -q 4e3505fd9583
708 $ hg up -q 4e3505fd9583
709 $ echo c4 > f2
709 $ echo c4 > f2
710 $ hg ci -Am4
710 $ hg ci -Am4
711 adding f2
711 adding f2
712 created new head
712 created new head
713 $ echo c5 > f2
713 $ echo c5 > f2
714 $ hg ci -Am5
714 $ hg ci -Am5
715 $ hg log -G
715 $ hg log -G
716 @ 5:c922c0139ca0 5
716 @ 5:c922c0139ca0 5
717 |
717 |
718 o 4:4efff6d98829 4
718 o 4:4efff6d98829 4
719 |
719 |
720 | o 3:f6fc62dde3c0 3
720 | o 3:f6fc62dde3c0 3
721 |/
721 |/
722 | o 2:0d2164f0ce0d 1
722 | o 2:0d2164f0ce0d 1
723 |/
723 |/
724 | o 1:9b140be10808 2
724 | o 1:9b140be10808 2
725 |/
725 |/
726 o 0:4e3505fd9583 test
726 o 0:4e3505fd9583 test
727
727
728
728
729 $ hg book -f Y
729 $ hg book -f Y
730
730
731 $ cat <<EOF > ../a/.hg/hgrc
731 $ cat <<EOF > ../a/.hg/hgrc
732 > [web]
732 > [web]
733 > push_ssl = false
733 > push_ssl = false
734 > allow_push = *
734 > allow_push = *
735 > EOF
735 > EOF
736
736
737 $ hg serve -R ../a -p $HGPORT2 -d --pid-file=../hg2.pid
737 $ hg serve -R ../a -p $HGPORT2 -d --pid-file=../hg2.pid
738 $ cat ../hg2.pid >> $DAEMON_PIDS
738 $ cat ../hg2.pid >> $DAEMON_PIDS
739
739
740 $ hg push http://localhost:$HGPORT2/
740 $ hg push http://localhost:$HGPORT2/
741 pushing to http://localhost:$HGPORT2/
741 pushing to http://localhost:$HGPORT2/
742 searching for changes
742 searching for changes
743 abort: push creates new remote head c922c0139ca0 with bookmark 'Y'
743 abort: push creates new remote head c922c0139ca0 with bookmark 'Y'
744 (merge or see 'hg help push' for details about pushing new heads)
744 (merge or see 'hg help push' for details about pushing new heads)
745 [20]
745 [20]
746 $ hg -R ../a book
746 $ hg -R ../a book
747 @ 1:0d2164f0ce0d
747 @ 1:0d2164f0ce0d
748 * X 1:0d2164f0ce0d
748 * X 1:0d2164f0ce0d
749 Y 3:f6fc62dde3c0
749 Y 3:f6fc62dde3c0
750 Z 1:0d2164f0ce0d
750 Z 1:0d2164f0ce0d
751
751
752
752
753 Unrelated marker does not alter the decision
753 Unrelated marker does not alter the decision
754
754
755 $ hg debugobsolete aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
755 $ hg debugobsolete aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
756 1 new obsolescence markers
756 1 new obsolescence markers
757 $ hg push http://localhost:$HGPORT2/
757 $ hg push http://localhost:$HGPORT2/
758 pushing to http://localhost:$HGPORT2/
758 pushing to http://localhost:$HGPORT2/
759 searching for changes
759 searching for changes
760 abort: push creates new remote head c922c0139ca0 with bookmark 'Y'
760 abort: push creates new remote head c922c0139ca0 with bookmark 'Y'
761 (merge or see 'hg help push' for details about pushing new heads)
761 (merge or see 'hg help push' for details about pushing new heads)
762 [20]
762 [20]
763 $ hg -R ../a book
763 $ hg -R ../a book
764 @ 1:0d2164f0ce0d
764 @ 1:0d2164f0ce0d
765 * X 1:0d2164f0ce0d
765 * X 1:0d2164f0ce0d
766 Y 3:f6fc62dde3c0
766 Y 3:f6fc62dde3c0
767 Z 1:0d2164f0ce0d
767 Z 1:0d2164f0ce0d
768
768
769 Update to a successor works
769 Update to a successor works
770
770
771 $ hg id --debug -r 3
771 $ hg id --debug -r 3
772 f6fc62dde3c0771e29704af56ba4d8af77abcc2f
772 f6fc62dde3c0771e29704af56ba4d8af77abcc2f
773 $ hg id --debug -r 4
773 $ hg id --debug -r 4
774 4efff6d98829d9c824c621afd6e3f01865f5439f
774 4efff6d98829d9c824c621afd6e3f01865f5439f
775 $ hg id --debug -r 5
775 $ hg id --debug -r 5
776 c922c0139ca03858f655e4a2af4dd02796a63969 tip Y
776 c922c0139ca03858f655e4a2af4dd02796a63969 tip Y
777 $ hg debugobsolete f6fc62dde3c0771e29704af56ba4d8af77abcc2f cccccccccccccccccccccccccccccccccccccccc
777 $ hg debugobsolete f6fc62dde3c0771e29704af56ba4d8af77abcc2f cccccccccccccccccccccccccccccccccccccccc
778 1 new obsolescence markers
778 1 new obsolescence markers
779 obsoleted 1 changesets
779 obsoleted 1 changesets
780 $ hg debugobsolete cccccccccccccccccccccccccccccccccccccccc 4efff6d98829d9c824c621afd6e3f01865f5439f
780 $ hg debugobsolete cccccccccccccccccccccccccccccccccccccccc 4efff6d98829d9c824c621afd6e3f01865f5439f
781 1 new obsolescence markers
781 1 new obsolescence markers
782 $ hg push http://localhost:$HGPORT2/
782 $ hg push http://localhost:$HGPORT2/
783 pushing to http://localhost:$HGPORT2/
783 pushing to http://localhost:$HGPORT2/
784 searching for changes
784 searching for changes
785 remote: adding changesets
785 remote: adding changesets
786 remote: adding manifests
786 remote: adding manifests
787 remote: adding file changes
787 remote: adding file changes
788 remote: added 2 changesets with 2 changes to 1 files (+1 heads)
788 remote: added 2 changesets with 2 changes to 1 files (+1 heads)
789 remote: 2 new obsolescence markers
789 remote: 2 new obsolescence markers
790 remote: obsoleted 1 changesets
790 remote: obsoleted 1 changesets
791 updating bookmark Y
791 updating bookmark Y
792 $ hg -R ../a book
792 $ hg -R ../a book
793 @ 1:0d2164f0ce0d
793 @ 1:0d2164f0ce0d
794 * X 1:0d2164f0ce0d
794 * X 1:0d2164f0ce0d
795 Y 5:c922c0139ca0
795 Y 5:c922c0139ca0
796 Z 1:0d2164f0ce0d
796 Z 1:0d2164f0ce0d
797
797
798 hgweb
798 hgweb
799
799
800 $ cat <<EOF > .hg/hgrc
800 $ cat <<EOF > .hg/hgrc
801 > [web]
801 > [web]
802 > push_ssl = false
802 > push_ssl = false
803 > allow_push = *
803 > allow_push = *
804 > EOF
804 > EOF
805
805
806 $ hg serve -p $HGPORT -d --pid-file=../hg.pid -E errors.log
806 $ hg serve -p $HGPORT -d --pid-file=../hg.pid -E errors.log
807 $ cat ../hg.pid >> $DAEMON_PIDS
807 $ cat ../hg.pid >> $DAEMON_PIDS
808 $ cd ../a
808 $ cd ../a
809
809
810 $ hg debugpushkey http://localhost:$HGPORT/ namespaces
810 $ hg debugpushkey http://localhost:$HGPORT/ namespaces
811 bookmarks
811 bookmarks
812 namespaces
812 namespaces
813 obsolete
813 obsolete
814 phases
814 phases
815 $ hg debugpushkey http://localhost:$HGPORT/ bookmarks
815 $ hg debugpushkey http://localhost:$HGPORT/ bookmarks
816 @ 9b140be1080824d768c5a4691a564088eede71f9
816 @ 9b140be1080824d768c5a4691a564088eede71f9
817 X 9b140be1080824d768c5a4691a564088eede71f9
817 X 9b140be1080824d768c5a4691a564088eede71f9
818 Y c922c0139ca03858f655e4a2af4dd02796a63969
818 Y c922c0139ca03858f655e4a2af4dd02796a63969
819 Z 9b140be1080824d768c5a4691a564088eede71f9
819 Z 9b140be1080824d768c5a4691a564088eede71f9
820 foo 0000000000000000000000000000000000000000
820 foo 0000000000000000000000000000000000000000
821 foobar 9b140be1080824d768c5a4691a564088eede71f9
821 foobar 9b140be1080824d768c5a4691a564088eede71f9
822 $ hg out -B http://localhost:$HGPORT/
822 $ hg out -B http://localhost:$HGPORT/
823 comparing with http://localhost:$HGPORT/
823 comparing with http://localhost:$HGPORT/
824 searching for changed bookmarks
824 searching for changed bookmarks
825 @ 0d2164f0ce0d
825 @ 0d2164f0ce0d
826 X 0d2164f0ce0d
826 X 0d2164f0ce0d
827 Z 0d2164f0ce0d
827 Z 0d2164f0ce0d
828 foo
828 foo
829 foobar
829 foobar
830 $ hg push -B Z http://localhost:$HGPORT/
830 $ hg push -B Z http://localhost:$HGPORT/
831 pushing to http://localhost:$HGPORT/
831 pushing to http://localhost:$HGPORT/
832 searching for changes
832 searching for changes
833 no changes found
833 no changes found
834 updating bookmark Z
834 updating bookmark Z
835 [1]
835 [1]
836 $ hg book -d Z
836 $ hg book -d Z
837 $ hg in -B http://localhost:$HGPORT/
837 $ hg in -B http://localhost:$HGPORT/
838 comparing with http://localhost:$HGPORT/
838 comparing with http://localhost:$HGPORT/
839 searching for changed bookmarks
839 searching for changed bookmarks
840 @ 9b140be10808
840 @ 9b140be10808
841 X 9b140be10808
841 X 9b140be10808
842 Z 0d2164f0ce0d
842 Z 0d2164f0ce0d
843 foo 000000000000
843 foo 000000000000
844 foobar 9b140be10808
844 foobar 9b140be10808
845 $ hg pull -B Z http://localhost:$HGPORT/
845 $ hg pull -B Z http://localhost:$HGPORT/
846 pulling from http://localhost:$HGPORT/
846 pulling from http://localhost:$HGPORT/
847 no changes found
847 no changes found
848 divergent bookmark @ stored as @1
848 divergent bookmark @ stored as @1
849 divergent bookmark X stored as X@1
849 divergent bookmark X stored as X@1
850 adding remote bookmark Z
850 adding remote bookmark Z
851 adding remote bookmark foo
851 adding remote bookmark foo
852 adding remote bookmark foobar
852 adding remote bookmark foobar
853 $ hg clone http://localhost:$HGPORT/ cloned-bookmarks
853 $ hg clone http://localhost:$HGPORT/ cloned-bookmarks
854 requesting all changes
854 requesting all changes
855 adding changesets
855 adding changesets
856 adding manifests
856 adding manifests
857 adding file changes
857 adding file changes
858 added 5 changesets with 5 changes to 3 files (+2 heads)
858 added 5 changesets with 5 changes to 3 files (+2 heads)
859 2 new obsolescence markers
859 2 new obsolescence markers
860 new changesets 4e3505fd9583:c922c0139ca0 (5 drafts)
860 new changesets 4e3505fd9583:c922c0139ca0 (5 drafts)
861 updating to bookmark @
861 updating to bookmark @
862 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
862 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
863 $ hg -R cloned-bookmarks bookmarks
863 $ hg -R cloned-bookmarks bookmarks
864 * @ 1:9b140be10808
864 * @ 1:9b140be10808
865 X 1:9b140be10808
865 X 1:9b140be10808
866 Y 4:c922c0139ca0
866 Y 4:c922c0139ca0
867 Z 2:0d2164f0ce0d
867 Z 2:0d2164f0ce0d
868 foo -1:000000000000
868 foo -1:000000000000
869 foobar 1:9b140be10808
869 foobar 1:9b140be10808
870
870
871 $ cd ..
871 $ cd ..
872
872
873 Test to show result of bookmarks comparison
873 Test to show result of bookmarks comparison
874
874
875 $ mkdir bmcomparison
875 $ mkdir bmcomparison
876 $ cd bmcomparison
876 $ cd bmcomparison
877
877
878 $ hg init source
878 $ hg init source
879 $ hg -R source debugbuilddag '+2*2*3*4'
879 $ hg -R source debugbuilddag '+2*2*3*4'
880 $ hg -R source log -G --template '{rev}:{node|short}'
880 $ hg -R source log -G --template '{rev}:{node|short}'
881 o 4:e7bd5218ca15
881 o 4:e7bd5218ca15
882 |
882 |
883 | o 3:6100d3090acf
883 | o 3:6100d3090acf
884 |/
884 |/
885 | o 2:fa942426a6fd
885 | o 2:fa942426a6fd
886 |/
886 |/
887 | o 1:66f7d451a68b
887 | o 1:66f7d451a68b
888 |/
888 |/
889 o 0:1ea73414a91b
889 o 0:1ea73414a91b
890
890
891 $ hg -R source bookmarks -r 0 SAME
891 $ hg -R source bookmarks -r 0 SAME
892 $ hg -R source bookmarks -r 0 ADV_ON_REPO1
892 $ hg -R source bookmarks -r 0 ADV_ON_REPO1
893 $ hg -R source bookmarks -r 0 ADV_ON_REPO2
893 $ hg -R source bookmarks -r 0 ADV_ON_REPO2
894 $ hg -R source bookmarks -r 0 DIFF_ADV_ON_REPO1
894 $ hg -R source bookmarks -r 0 DIFF_ADV_ON_REPO1
895 $ hg -R source bookmarks -r 0 DIFF_ADV_ON_REPO2
895 $ hg -R source bookmarks -r 0 DIFF_ADV_ON_REPO2
896 $ hg -R source bookmarks -r 1 DIVERGED
896 $ hg -R source bookmarks -r 1 DIVERGED
897
897
898 $ hg clone -U source repo1
898 $ hg clone -U source repo1
899
899
900 (test that incoming/outgoing exit with 1, if there is no bookmark to
900 (test that incoming/outgoing exit with 1, if there is no bookmark to
901 be exchanged)
901 be exchanged)
902
902
903 $ hg -R repo1 incoming -B
903 $ hg -R repo1 incoming -B
904 comparing with $TESTTMP/bmcomparison/source
904 comparing with $TESTTMP/bmcomparison/source
905 searching for changed bookmarks
905 searching for changed bookmarks
906 no changed bookmarks found
906 no changed bookmarks found
907 [1]
907 [1]
908 $ hg -R repo1 outgoing -B
908 $ hg -R repo1 outgoing -B
909 comparing with $TESTTMP/bmcomparison/source
909 comparing with $TESTTMP/bmcomparison/source
910 searching for changed bookmarks
910 searching for changed bookmarks
911 no changed bookmarks found
911 no changed bookmarks found
912 [1]
912 [1]
913
913
914 $ hg -R repo1 bookmarks -f -r 1 ADD_ON_REPO1
914 $ hg -R repo1 bookmarks -f -r 1 ADD_ON_REPO1
915 $ hg -R repo1 bookmarks -f -r 2 ADV_ON_REPO1
915 $ hg -R repo1 bookmarks -f -r 2 ADV_ON_REPO1
916 $ hg -R repo1 bookmarks -f -r 3 DIFF_ADV_ON_REPO1
916 $ hg -R repo1 bookmarks -f -r 3 DIFF_ADV_ON_REPO1
917 $ hg -R repo1 bookmarks -f -r 3 DIFF_DIVERGED
917 $ hg -R repo1 bookmarks -f -r 3 DIFF_DIVERGED
918 $ hg -R repo1 -q --config extensions.mq= strip 4
918 $ hg -R repo1 -q --config extensions.mq= strip 4
919 $ hg -R repo1 log -G --template '{node|short} ({bookmarks})'
919 $ hg -R repo1 log -G --template '{node|short} ({bookmarks})'
920 o 6100d3090acf (DIFF_ADV_ON_REPO1 DIFF_DIVERGED)
920 o 6100d3090acf (DIFF_ADV_ON_REPO1 DIFF_DIVERGED)
921 |
921 |
922 | o fa942426a6fd (ADV_ON_REPO1)
922 | o fa942426a6fd (ADV_ON_REPO1)
923 |/
923 |/
924 | o 66f7d451a68b (ADD_ON_REPO1 DIVERGED)
924 | o 66f7d451a68b (ADD_ON_REPO1 DIVERGED)
925 |/
925 |/
926 o 1ea73414a91b (ADV_ON_REPO2 DIFF_ADV_ON_REPO2 SAME)
926 o 1ea73414a91b (ADV_ON_REPO2 DIFF_ADV_ON_REPO2 SAME)
927
927
928
928
929 $ hg clone -U source repo2
929 $ hg clone -U source repo2
930 $ hg -R repo2 bookmarks -f -r 1 ADD_ON_REPO2
930 $ hg -R repo2 bookmarks -f -r 1 ADD_ON_REPO2
931 $ hg -R repo2 bookmarks -f -r 1 ADV_ON_REPO2
931 $ hg -R repo2 bookmarks -f -r 1 ADV_ON_REPO2
932 $ hg -R repo2 bookmarks -f -r 2 DIVERGED
932 $ hg -R repo2 bookmarks -f -r 2 DIVERGED
933 $ hg -R repo2 bookmarks -f -r 4 DIFF_ADV_ON_REPO2
933 $ hg -R repo2 bookmarks -f -r 4 DIFF_ADV_ON_REPO2
934 $ hg -R repo2 bookmarks -f -r 4 DIFF_DIVERGED
934 $ hg -R repo2 bookmarks -f -r 4 DIFF_DIVERGED
935 $ hg -R repo2 -q --config extensions.mq= strip 3
935 $ hg -R repo2 -q --config extensions.mq= strip 3
936 $ hg -R repo2 log -G --template '{node|short} ({bookmarks})'
936 $ hg -R repo2 log -G --template '{node|short} ({bookmarks})'
937 o e7bd5218ca15 (DIFF_ADV_ON_REPO2 DIFF_DIVERGED)
937 o e7bd5218ca15 (DIFF_ADV_ON_REPO2 DIFF_DIVERGED)
938 |
938 |
939 | o fa942426a6fd (DIVERGED)
939 | o fa942426a6fd (DIVERGED)
940 |/
940 |/
941 | o 66f7d451a68b (ADD_ON_REPO2 ADV_ON_REPO2)
941 | o 66f7d451a68b (ADD_ON_REPO2 ADV_ON_REPO2)
942 |/
942 |/
943 o 1ea73414a91b (ADV_ON_REPO1 DIFF_ADV_ON_REPO1 SAME)
943 o 1ea73414a91b (ADV_ON_REPO1 DIFF_ADV_ON_REPO1 SAME)
944
944
945
945
946 (test that difference of bookmarks between repositories are fully shown)
946 (test that difference of bookmarks between repositories are fully shown)
947
947
948 $ hg -R repo1 incoming -B repo2 -v
948 $ hg -R repo1 incoming -B repo2 -v
949 comparing with repo2
949 comparing with repo2
950 searching for changed bookmarks
950 searching for changed bookmarks
951 ADD_ON_REPO2 66f7d451a68b added
951 ADD_ON_REPO2 66f7d451a68b added
952 ADV_ON_REPO2 66f7d451a68b advanced
952 ADV_ON_REPO2 66f7d451a68b advanced
953 DIFF_ADV_ON_REPO2 e7bd5218ca15 changed
953 DIFF_ADV_ON_REPO2 e7bd5218ca15 changed
954 DIFF_DIVERGED e7bd5218ca15 changed
954 DIFF_DIVERGED e7bd5218ca15 changed
955 DIVERGED fa942426a6fd diverged
955 DIVERGED fa942426a6fd diverged
956 $ hg -R repo1 outgoing -B repo2 -v
956 $ hg -R repo1 outgoing -B repo2 -v
957 comparing with repo2
957 comparing with repo2
958 searching for changed bookmarks
958 searching for changed bookmarks
959 ADD_ON_REPO1 66f7d451a68b added
959 ADD_ON_REPO1 66f7d451a68b added
960 ADD_ON_REPO2 deleted
960 ADD_ON_REPO2 deleted
961 ADV_ON_REPO1 fa942426a6fd advanced
961 ADV_ON_REPO1 fa942426a6fd advanced
962 DIFF_ADV_ON_REPO1 6100d3090acf advanced
962 DIFF_ADV_ON_REPO1 6100d3090acf advanced
963 DIFF_ADV_ON_REPO2 1ea73414a91b changed
963 DIFF_ADV_ON_REPO2 1ea73414a91b changed
964 DIFF_DIVERGED 6100d3090acf changed
964 DIFF_DIVERGED 6100d3090acf changed
965 DIVERGED 66f7d451a68b diverged
965 DIVERGED 66f7d451a68b diverged
966
966
967 $ hg -R repo2 incoming -B repo1 -v
967 $ hg -R repo2 incoming -B repo1 -v
968 comparing with repo1
968 comparing with repo1
969 searching for changed bookmarks
969 searching for changed bookmarks
970 ADD_ON_REPO1 66f7d451a68b added
970 ADD_ON_REPO1 66f7d451a68b added
971 ADV_ON_REPO1 fa942426a6fd advanced
971 ADV_ON_REPO1 fa942426a6fd advanced
972 DIFF_ADV_ON_REPO1 6100d3090acf changed
972 DIFF_ADV_ON_REPO1 6100d3090acf changed
973 DIFF_DIVERGED 6100d3090acf changed
973 DIFF_DIVERGED 6100d3090acf changed
974 DIVERGED 66f7d451a68b diverged
974 DIVERGED 66f7d451a68b diverged
975 $ hg -R repo2 outgoing -B repo1 -v
975 $ hg -R repo2 outgoing -B repo1 -v
976 comparing with repo1
976 comparing with repo1
977 searching for changed bookmarks
977 searching for changed bookmarks
978 ADD_ON_REPO1 deleted
978 ADD_ON_REPO1 deleted
979 ADD_ON_REPO2 66f7d451a68b added
979 ADD_ON_REPO2 66f7d451a68b added
980 ADV_ON_REPO2 66f7d451a68b advanced
980 ADV_ON_REPO2 66f7d451a68b advanced
981 DIFF_ADV_ON_REPO1 1ea73414a91b changed
981 DIFF_ADV_ON_REPO1 1ea73414a91b changed
982 DIFF_ADV_ON_REPO2 e7bd5218ca15 advanced
982 DIFF_ADV_ON_REPO2 e7bd5218ca15 advanced
983 DIFF_DIVERGED e7bd5218ca15 changed
983 DIFF_DIVERGED e7bd5218ca15 changed
984 DIVERGED fa942426a6fd diverged
984 DIVERGED fa942426a6fd diverged
985
985
986 $ cd ..
986 $ cd ..
987
987
988 Pushing a bookmark should only push the changes required by that
988 Pushing a bookmark should only push the changes required by that
989 bookmark, not all outgoing changes:
989 bookmark, not all outgoing changes:
990 $ hg clone http://localhost:$HGPORT/ addmarks
990 $ hg clone http://localhost:$HGPORT/ addmarks
991 requesting all changes
991 requesting all changes
992 adding changesets
992 adding changesets
993 adding manifests
993 adding manifests
994 adding file changes
994 adding file changes
995 added 5 changesets with 5 changes to 3 files (+2 heads)
995 added 5 changesets with 5 changes to 3 files (+2 heads)
996 2 new obsolescence markers
996 2 new obsolescence markers
997 new changesets 4e3505fd9583:c922c0139ca0 (5 drafts)
997 new changesets 4e3505fd9583:c922c0139ca0 (5 drafts)
998 updating to bookmark @
998 updating to bookmark @
999 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
999 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1000 $ cd addmarks
1000 $ cd addmarks
1001 $ echo foo > foo
1001 $ echo foo > foo
1002 $ hg add foo
1002 $ hg add foo
1003 $ hg commit -m 'add foo'
1003 $ hg commit -m 'add foo'
1004 $ echo bar > bar
1004 $ echo bar > bar
1005 $ hg add bar
1005 $ hg add bar
1006 $ hg commit -m 'add bar'
1006 $ hg commit -m 'add bar'
1007 $ hg co "tip^"
1007 $ hg co "tip^"
1008 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1008 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1009 (leaving bookmark @)
1009 (leaving bookmark @)
1010 $ hg book add-foo
1010 $ hg book add-foo
1011 $ hg book -r tip add-bar
1011 $ hg book -r tip add-bar
1012 Note: this push *must* push only a single changeset, as that's the point
1012 Note: this push *must* push only a single changeset, as that's the point
1013 of this test.
1013 of this test.
1014 $ hg push -B add-foo --traceback
1014 $ hg push -B add-foo --traceback
1015 pushing to http://localhost:$HGPORT/
1015 pushing to http://localhost:$HGPORT/
1016 searching for changes
1016 searching for changes
1017 remote: adding changesets
1017 remote: adding changesets
1018 remote: adding manifests
1018 remote: adding manifests
1019 remote: adding file changes
1019 remote: adding file changes
1020 remote: added 1 changesets with 1 changes to 1 files
1020 remote: added 1 changesets with 1 changes to 1 files
1021 exporting bookmark add-foo
1021 exporting bookmark add-foo
1022
1022
1023 pushing a new bookmark on a new head does not require -f if -B is specified
1023 pushing a new bookmark on a new head does not require -f if -B is specified
1024
1024
1025 $ hg up -q X
1025 $ hg up -q X
1026 $ hg book W
1026 $ hg book W
1027 $ echo c5 > f2
1027 $ echo c5 > f2
1028 $ hg ci -Am5
1028 $ hg ci -Am5
1029 created new head
1029 created new head
1030 $ hg push -B .
1030 $ hg push -B .
1031 pushing to http://localhost:$HGPORT/
1031 pushing to http://localhost:$HGPORT/
1032 searching for changes
1032 searching for changes
1033 remote: adding changesets
1033 remote: adding changesets
1034 remote: adding manifests
1034 remote: adding manifests
1035 remote: adding file changes
1035 remote: adding file changes
1036 remote: added 1 changesets with 1 changes to 1 files (+1 heads)
1036 remote: added 1 changesets with 1 changes to 1 files (+1 heads)
1037 exporting bookmark W
1037 exporting bookmark W
1038 $ hg -R ../b id -r W
1038 $ hg -R ../b id -r W
1039 cc978a373a53 tip W
1039 cc978a373a53 tip W
1040
1040
1041 pushing an existing but divergent bookmark with -B still requires -f
1041 pushing an existing but divergent bookmark with -B still requires -f
1042
1042
1043 $ hg clone -q . ../r
1043 $ hg clone -q . ../r
1044 $ hg up -q X
1044 $ hg up -q X
1045 $ echo 1 > f2
1045 $ echo 1 > f2
1046 $ hg ci -qAml
1046 $ hg ci -qAml
1047
1047
1048 $ cd ../r
1048 $ cd ../r
1049 $ hg up -q X
1049 $ hg up -q X
1050 $ echo 2 > f2
1050 $ echo 2 > f2
1051 $ hg ci -qAmr
1051 $ hg ci -qAmr
1052 $ hg push -B X
1052 $ hg push -B X
1053 pushing to $TESTTMP/addmarks
1053 pushing to $TESTTMP/addmarks
1054 searching for changes
1054 searching for changes
1055 remote has heads on branch 'default' that are not known locally: a2a606d9ff1b
1055 remote has heads on branch 'default' that are not known locally: a2a606d9ff1b
1056 abort: push creates new remote head 54694f811df9 with bookmark 'X'
1056 abort: push creates new remote head 54694f811df9 with bookmark 'X'
1057 (pull and merge or see 'hg help push' for details about pushing new heads)
1057 (pull and merge or see 'hg help push' for details about pushing new heads)
1058 [20]
1058 [20]
1059 $ cd ../addmarks
1059 $ cd ../addmarks
1060
1060
1061 Check summary output for incoming/outgoing bookmarks
1061 Check summary output for incoming/outgoing bookmarks
1062
1062
1063 $ hg bookmarks -d X
1063 $ hg bookmarks -d X
1064 $ hg bookmarks -d Y
1064 $ hg bookmarks -d Y
1065 $ hg summary --remote | grep '^remote:'
1065 $ hg summary --remote | grep '^remote:'
1066 remote: *, 2 incoming bookmarks, 1 outgoing bookmarks (glob)
1066 remote: *, 2 incoming bookmarks, 1 outgoing bookmarks (glob)
1067
1067
1068 $ cd ..
1068 $ cd ..
1069
1069
1070 pushing an unchanged bookmark should result in no changes
1070 pushing an unchanged bookmark should result in no changes
1071
1071
1072 $ hg init unchanged-a
1072 $ hg init unchanged-a
1073 $ hg init unchanged-b
1073 $ hg init unchanged-b
1074 $ cd unchanged-a
1074 $ cd unchanged-a
1075 $ echo initial > foo
1075 $ echo initial > foo
1076 $ hg commit -A -m initial
1076 $ hg commit -A -m initial
1077 adding foo
1077 adding foo
1078 $ hg bookmark @
1078 $ hg bookmark @
1079 $ hg push -B @ ../unchanged-b
1079 $ hg push -B @ ../unchanged-b
1080 pushing to ../unchanged-b
1080 pushing to ../unchanged-b
1081 searching for changes
1081 searching for changes
1082 adding changesets
1082 adding changesets
1083 adding manifests
1083 adding manifests
1084 adding file changes
1084 adding file changes
1085 added 1 changesets with 1 changes to 1 files
1085 added 1 changesets with 1 changes to 1 files
1086 exporting bookmark @
1086 exporting bookmark @
1087
1087
1088 $ hg push -B @ ../unchanged-b
1088 $ hg push -B @ ../unchanged-b
1089 pushing to ../unchanged-b
1089 pushing to ../unchanged-b
1090 searching for changes
1090 searching for changes
1091 no changes found
1091 no changes found
1092 [1]
1092 [1]
1093
1093
1094 Pushing a really long bookmark should work fine (issue5165)
1094 Pushing a really long bookmark should work fine (issue5165)
1095 ===============================================
1095 ===============================================
1096
1096
1097 #if b2-binary
1097 #if b2-binary
1098 >>> with open('longname', 'w') as f:
1098 >>> with open('longname', 'w') as f:
1099 ... f.write('wat' * 100) and None
1099 ... f.write('wat' * 100) and None
1100 $ hg book `cat longname`
1100 $ hg book `cat longname`
1101 $ hg push -B `cat longname` ../unchanged-b
1101 $ hg push -B `cat longname` ../unchanged-b
1102 pushing to ../unchanged-b
1102 pushing to ../unchanged-b
1103 searching for changes
1103 searching for changes
1104 no changes found
1104 no changes found
1105 exporting bookmark (wat){100} (re)
1105 exporting bookmark (wat){100} (re)
1106 [1]
1106 [1]
1107 $ hg -R ../unchanged-b book --delete `cat longname`
1107 $ hg -R ../unchanged-b book --delete `cat longname`
1108
1108
1109 Test again but forcing bundle2 exchange to make sure that doesn't regress.
1109 Test again but forcing bundle2 exchange to make sure that doesn't regress.
1110
1110
1111 $ hg push -B `cat longname` ../unchanged-b --config devel.legacy.exchange=bundle1
1111 $ hg push -B `cat longname` ../unchanged-b --config devel.legacy.exchange=bundle1
1112 pushing to ../unchanged-b
1112 pushing to ../unchanged-b
1113 searching for changes
1113 searching for changes
1114 no changes found
1114 no changes found
1115 exporting bookmark (wat){100} (re)
1115 exporting bookmark (wat){100} (re)
1116 [1]
1116 [1]
1117 $ hg -R ../unchanged-b book --delete `cat longname`
1117 $ hg -R ../unchanged-b book --delete `cat longname`
1118 $ hg book --delete `cat longname`
1118 $ hg book --delete `cat longname`
1119 $ hg co @
1119 $ hg co @
1120 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1120 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1121 (activating bookmark @)
1121 (activating bookmark @)
1122 #endif
1122 #endif
1123
1123
1124 Check hook preventing push (issue4455)
1124 Check hook preventing push (issue4455)
1125 ======================================
1125 ======================================
1126
1126
1127 $ hg bookmarks
1127 $ hg bookmarks
1128 * @ 0:55482a6fb4b1
1128 * @ 0:55482a6fb4b1
1129 $ hg log -G
1129 $ hg log -G
1130 @ 0:55482a6fb4b1 initial
1130 @ 0:55482a6fb4b1 initial
1131
1131
1132 $ hg init ../issue4455-dest
1132 $ hg init ../issue4455-dest
1133 $ hg push ../issue4455-dest # changesets only
1133 $ hg push ../issue4455-dest # changesets only
1134 pushing to ../issue4455-dest
1134 pushing to ../issue4455-dest
1135 searching for changes
1135 searching for changes
1136 adding changesets
1136 adding changesets
1137 adding manifests
1137 adding manifests
1138 adding file changes
1138 adding file changes
1139 added 1 changesets with 1 changes to 1 files
1139 added 1 changesets with 1 changes to 1 files
1140 $ cat >> .hg/hgrc << EOF
1140 $ cat >> .hg/hgrc << EOF
1141 > [paths]
1141 > [paths]
1142 > local=../issue4455-dest/
1142 > local=../issue4455-dest/
1143 > ssh=ssh://user@dummy/issue4455-dest
1143 > ssh=ssh://user@dummy/issue4455-dest
1144 > http=http://localhost:$HGPORT/
1144 > http=http://localhost:$HGPORT/
1145 > [ui]
1145 > [ui]
1146 > ssh="$PYTHON" "$TESTDIR/dummyssh"
1146 > ssh="$PYTHON" "$TESTDIR/dummyssh"
1147 > EOF
1147 > EOF
1148 $ cat >> ../issue4455-dest/.hg/hgrc << EOF
1148 $ cat >> ../issue4455-dest/.hg/hgrc << EOF
1149 > [hooks]
1149 > [hooks]
1150 > prepushkey=false
1150 > prepushkey=false
1151 > [web]
1151 > [web]
1152 > push_ssl = false
1152 > push_ssl = false
1153 > allow_push = *
1153 > allow_push = *
1154 > EOF
1154 > EOF
1155 $ killdaemons.py
1155 $ killdaemons.py
1156 $ hg serve -R ../issue4455-dest -p $HGPORT -d --pid-file=../issue4455.pid -E ../issue4455-error.log
1156 $ hg serve -R ../issue4455-dest -p $HGPORT -d --pid-file=../issue4455.pid -E ../issue4455-error.log
1157 $ cat ../issue4455.pid >> $DAEMON_PIDS
1157 $ cat ../issue4455.pid >> $DAEMON_PIDS
1158
1158
1159 Local push
1159 Local push
1160 ----------
1160 ----------
1161
1161
1162 #if b2-pushkey
1162 #if b2-pushkey
1163
1163
1164 $ hg push -B @ local
1164 $ hg push -B @ local
1165 pushing to $TESTTMP/issue4455-dest
1165 pushing to $TESTTMP/issue4455-dest
1166 searching for changes
1166 searching for changes
1167 no changes found
1167 no changes found
1168 pushkey-abort: prepushkey hook exited with status 1
1168 pushkey-abort: prepushkey hook exited with status 1
1169 abort: exporting bookmark @ failed
1169 abort: exporting bookmark @ failed
1170 [255]
1170 [255]
1171
1171
1172 #endif
1172 #endif
1173 #if b2-binary
1173 #if b2-binary
1174
1174
1175 $ hg push -B @ local
1175 $ hg push -B @ local
1176 pushing to $TESTTMP/issue4455-dest
1176 pushing to $TESTTMP/issue4455-dest
1177 searching for changes
1177 searching for changes
1178 no changes found
1178 no changes found
1179 abort: prepushkey hook exited with status 1
1179 abort: prepushkey hook exited with status 1
1180 [40]
1180 [40]
1181
1181
1182 #endif
1182 #endif
1183
1183
1184 $ hg -R ../issue4455-dest/ bookmarks
1184 $ hg -R ../issue4455-dest/ bookmarks
1185 no bookmarks set
1185 no bookmarks set
1186
1186
1187 Using ssh
1187 Using ssh
1188 ---------
1188 ---------
1189
1189
1190 #if b2-pushkey
1190 #if b2-pushkey
1191
1191
1192 $ hg push -B @ ssh # bundle2+
1192 $ hg push -B @ ssh # bundle2+
1193 pushing to ssh://user@dummy/issue4455-dest
1193 pushing to ssh://user@dummy/issue4455-dest
1194 searching for changes
1194 searching for changes
1195 no changes found
1195 no changes found
1196 remote: pushkey-abort: prepushkey hook exited with status 1
1196 remote: pushkey-abort: prepushkey hook exited with status 1
1197 abort: exporting bookmark @ failed
1197 abort: exporting bookmark @ failed
1198 [255]
1198 [255]
1199
1199
1200 $ hg -R ../issue4455-dest/ bookmarks
1200 $ hg -R ../issue4455-dest/ bookmarks
1201 no bookmarks set
1201 no bookmarks set
1202
1202
1203 $ hg push -B @ ssh --config devel.legacy.exchange=bundle1
1203 $ hg push -B @ ssh --config devel.legacy.exchange=bundle1
1204 pushing to ssh://user@dummy/issue4455-dest
1204 pushing to ssh://user@dummy/issue4455-dest
1205 searching for changes
1205 searching for changes
1206 no changes found
1206 no changes found
1207 remote: pushkey-abort: prepushkey hook exited with status 1
1207 remote: pushkey-abort: prepushkey hook exited with status 1
1208 exporting bookmark @ failed
1208 exporting bookmark @ failed
1209 [1]
1209 [1]
1210
1210
1211 #endif
1211 #endif
1212 #if b2-binary
1212 #if b2-binary
1213
1213
1214 $ hg push -B @ ssh # bundle2+
1214 $ hg push -B @ ssh # bundle2+
1215 pushing to ssh://user@dummy/issue4455-dest
1215 pushing to ssh://user@dummy/issue4455-dest
1216 searching for changes
1216 searching for changes
1217 no changes found
1217 no changes found
1218 remote: prepushkey hook exited with status 1
1218 remote: prepushkey hook exited with status 1
1219 abort: push failed on remote
1219 abort: push failed on remote
1220 [255]
1220 [255]
1221
1221
1222 #endif
1222 #endif
1223
1223
1224 $ hg -R ../issue4455-dest/ bookmarks
1224 $ hg -R ../issue4455-dest/ bookmarks
1225 no bookmarks set
1225 no bookmarks set
1226
1226
1227 Using http
1227 Using http
1228 ----------
1228 ----------
1229
1229
1230 #if b2-pushkey
1230 #if b2-pushkey
1231 $ hg push -B @ http # bundle2+
1231 $ hg push -B @ http # bundle2+
1232 pushing to http://localhost:$HGPORT/
1232 pushing to http://localhost:$HGPORT/
1233 searching for changes
1233 searching for changes
1234 no changes found
1234 no changes found
1235 remote: pushkey-abort: prepushkey hook exited with status 1
1235 remote: pushkey-abort: prepushkey hook exited with status 1
1236 abort: exporting bookmark @ failed
1236 abort: exporting bookmark @ failed
1237 [255]
1237 [255]
1238
1238
1239 $ hg -R ../issue4455-dest/ bookmarks
1239 $ hg -R ../issue4455-dest/ bookmarks
1240 no bookmarks set
1240 no bookmarks set
1241
1241
1242 $ hg push -B @ http --config devel.legacy.exchange=bundle1
1242 $ hg push -B @ http --config devel.legacy.exchange=bundle1
1243 pushing to http://localhost:$HGPORT/
1243 pushing to http://localhost:$HGPORT/
1244 searching for changes
1244 searching for changes
1245 no changes found
1245 no changes found
1246 remote: pushkey-abort: prepushkey hook exited with status 1
1246 remote: pushkey-abort: prepushkey hook exited with status 1
1247 exporting bookmark @ failed
1247 exporting bookmark @ failed
1248 [1]
1248 [1]
1249
1249
1250 #endif
1250 #endif
1251
1251
1252 #if b2-binary
1252 #if b2-binary
1253
1253
1254 $ hg push -B @ ssh # bundle2+
1254 $ hg push -B @ ssh # bundle2+
1255 pushing to ssh://user@dummy/issue4455-dest
1255 pushing to ssh://user@dummy/issue4455-dest
1256 searching for changes
1256 searching for changes
1257 no changes found
1257 no changes found
1258 remote: prepushkey hook exited with status 1
1258 remote: prepushkey hook exited with status 1
1259 abort: push failed on remote
1259 abort: push failed on remote
1260 [255]
1260 [255]
1261
1261
1262 #endif
1262 #endif
1263
1263
1264 $ hg -R ../issue4455-dest/ bookmarks
1264 $ hg -R ../issue4455-dest/ bookmarks
1265 no bookmarks set
1265 no bookmarks set
1266
1266
1267 $ cd ..
1267 $ cd ..
1268
1268
1269 Test that pre-pushkey compat for bookmark works as expected (issue5777)
1269 Test that pre-pushkey compat for bookmark works as expected (issue5777)
1270
1270
1271 $ cat << EOF >> $HGRCPATH
1271 $ cat << EOF >> $HGRCPATH
1272 > [ui]
1272 > [ui]
1273 > ssh="$PYTHON" "$TESTDIR/dummyssh"
1273 > ssh="$PYTHON" "$TESTDIR/dummyssh"
1274 > [server]
1274 > [server]
1275 > bookmarks-pushkey-compat = yes
1275 > bookmarks-pushkey-compat = yes
1276 > EOF
1276 > EOF
1277
1277
1278 $ hg init server
1278 $ hg init server
1279 $ echo foo > server/a
1279 $ echo foo > server/a
1280 $ hg -R server book foo
1280 $ hg -R server book foo
1281 $ hg -R server commit -Am a
1281 $ hg -R server commit -Am a
1282 adding a
1282 adding a
1283 $ hg clone ssh://user@dummy/server client
1283 $ hg clone ssh://user@dummy/server client
1284 requesting all changes
1284 requesting all changes
1285 adding changesets
1285 adding changesets
1286 adding manifests
1286 adding manifests
1287 adding file changes
1287 adding file changes
1288 added 1 changesets with 1 changes to 1 files
1288 added 1 changesets with 1 changes to 1 files
1289 new changesets 79513d0d7716 (1 drafts)
1289 new changesets 79513d0d7716 (1 drafts)
1290 updating to branch default
1290 updating to branch default
1291 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1291 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1292
1292
1293 Forbid bookmark move on the server
1293 Forbid bookmark move on the server
1294
1294
1295 $ cat << EOF >> $TESTTMP/no-bm-move.sh
1295 $ cat << EOF >> $TESTTMP/no-bm-move.sh
1296 > #!/bin/sh
1296 > #!/bin/sh
1297 > echo \$HG_NAMESPACE | grep -v bookmarks
1297 > echo \$HG_NAMESPACE | grep -v bookmarks
1298 > EOF
1298 > EOF
1299 $ cat << EOF >> server/.hg/hgrc
1299 $ cat << EOF >> server/.hg/hgrc
1300 > [hooks]
1300 > [hooks]
1301 > prepushkey.no-bm-move= sh $TESTTMP/no-bm-move.sh
1301 > prepushkey.no-bm-move= sh $TESTTMP/no-bm-move.sh
1302 > EOF
1302 > EOF
1303
1303
1304 pushing changeset is okay
1304 pushing changeset is okay
1305
1305
1306 $ echo bar >> client/a
1306 $ echo bar >> client/a
1307 $ hg -R client commit -m b
1307 $ hg -R client commit -m b
1308 $ hg -R client push
1308 $ hg -R client push
1309 pushing to ssh://user@dummy/server
1309 pushing to ssh://user@dummy/server
1310 searching for changes
1310 searching for changes
1311 remote: adding changesets
1311 remote: adding changesets
1312 remote: adding manifests
1312 remote: adding manifests
1313 remote: adding file changes
1313 remote: adding file changes
1314 remote: added 1 changesets with 1 changes to 1 files
1314 remote: added 1 changesets with 1 changes to 1 files
1315
1315
1316 attempt to move the bookmark is rejected
1316 attempt to move the bookmark is rejected
1317
1317
1318 $ hg -R client book foo -r .
1318 $ hg -R client book foo -r .
1319 moving bookmark 'foo' forward from 79513d0d7716
1319 moving bookmark 'foo' forward from 79513d0d7716
1320
1320
1321 #if b2-pushkey
1321 #if b2-pushkey
1322 $ hg -R client push
1322 $ hg -R client push
1323 pushing to ssh://user@dummy/server
1323 pushing to ssh://user@dummy/server
1324 searching for changes
1324 searching for changes
1325 no changes found
1325 no changes found
1326 remote: pushkey-abort: prepushkey.no-bm-move hook exited with status 1
1326 remote: pushkey-abort: prepushkey.no-bm-move hook exited with status 1
1327 abort: updating bookmark foo failed
1327 abort: updating bookmark foo failed
1328 [255]
1328 [255]
1329 #endif
1329 #endif
1330 #if b2-binary
1330 #if b2-binary
1331 $ hg -R client push
1331 $ hg -R client push
1332 pushing to ssh://user@dummy/server
1332 pushing to ssh://user@dummy/server
1333 searching for changes
1333 searching for changes
1334 no changes found
1334 no changes found
1335 remote: prepushkey.no-bm-move hook exited with status 1
1335 remote: prepushkey.no-bm-move hook exited with status 1
1336 abort: push failed on remote
1336 abort: push failed on remote
1337 [255]
1337 [255]
1338 #endif
1338 #endif
1339
1339
1340 -- test for pushing bookmarks pointing to secret changesets
1340 -- test for pushing bookmarks pointing to secret changesets
1341
1341
1342 Set up a "remote" repo
1342 Set up a "remote" repo
1343 $ hg init issue6159remote
1343 $ hg init issue6159remote
1344 $ cd issue6159remote
1344 $ cd issue6159remote
1345 $ echo a > a
1345 $ echo a > a
1346 $ hg add a
1346 $ hg add a
1347 $ hg commit -m_
1347 $ hg commit -m_
1348 $ hg bookmark foo
1348 $ hg bookmark foo
1349 $ cd ..
1349 $ cd ..
1350
1350
1351 Clone a local repo
1351 Clone a local repo
1352 $ hg clone -q issue6159remote issue6159local
1352 $ hg clone -q issue6159remote issue6159local
1353 $ cd issue6159local
1353 $ cd issue6159local
1354 $ hg up -qr foo
1354 $ hg up -qr foo
1355 $ echo b > b
1355 $ echo b > b
1356
1356
1357 Move the bookmark "foo" to point at a secret changeset
1357 Move the bookmark "foo" to point at a secret changeset
1358 $ hg commit -qAm_ --config phases.new-commit=secret
1358 $ hg commit -qAm_ --config phases.new-commit=secret
1359
1359
1360 Pushing the bookmark "foo" now fails as it contains a secret changeset
1360 Pushing the bookmark "foo" now fails as it contains a secret changeset
1361 $ hg push -r foo
1361 $ hg push -r foo
1362 pushing to $TESTTMP/issue6159remote
1362 pushing to $TESTTMP/issue6159remote
1363 searching for changes
1363 searching for changes
1364 no changes found (ignored 1 secret changesets)
1364 no changes found (ignored 1 secret changesets)
1365 abort: cannot push bookmark foo as it points to a secret changeset
1365 abort: cannot push bookmark foo as it points to a secret changeset
1366 [255]
1366 [255]
1367
1367
1368 Test pushing all bookmarks
1368 Test pushing all bookmarks
1369
1369
1370 $ hg init $TESTTMP/ab1
1370 $ hg init $TESTTMP/ab1
1371 $ cd $TESTTMP/ab1
1371 $ cd $TESTTMP/ab1
1372 $ "$PYTHON" $TESTDIR/seq.py 1 5 | while read i; do
1372 $ "$PYTHON" $TESTDIR/seq.py 1 5 | while read i; do
1373 > echo $i > test && hg ci -Am test
1373 > echo $i > test && hg ci -Am test
1374 > done
1374 > done
1375 adding test
1375 adding test
1376 $ hg clone -U . ../ab2
1376 $ hg clone -U . ../ab2
1377 $ hg book -r 1 A; hg book -r 2 B; hg book -r 3 C
1377 $ hg book -r 1 A; hg book -r 2 B; hg book -r 3 C
1378 $ hg push ../ab2
1378 $ hg push ../ab2
1379 pushing to ../ab2
1379 pushing to ../ab2
1380 searching for changes
1380 searching for changes
1381 no changes found
1381 no changes found
1382 [1]
1382 [1]
1383 $ hg push --all-bookmarks -r 1 ../ab2
1383 $ hg push --all-bookmarks -r 1 ../ab2
1384 abort: cannot specify both --all-bookmarks and --rev
1384 abort: cannot specify both --all-bookmarks and --rev
1385 [10]
1385 [10]
1386 $ hg push --all-bookmarks -B A ../ab2
1386 $ hg push --all-bookmarks -B A ../ab2
1387 abort: cannot specify both --all-bookmarks and --bookmark
1387 abort: cannot specify both --all-bookmarks and --bookmark
1388 [10]
1388 [10]
1389 $ hg push --all-bookmarks ../ab2
1389 $ hg push --all-bookmarks ../ab2
1390 pushing to ../ab2
1390 pushing to ../ab2
1391 searching for changes
1391 searching for changes
1392 no changes found
1392 no changes found
1393 exporting bookmark A
1393 exporting bookmark A
1394 exporting bookmark B
1394 exporting bookmark B
1395 exporting bookmark C
1395 exporting bookmark C
1396 [1]
1396 [1]
@@ -1,582 +1,580 b''
1 #require serve no-reposimplestore no-chg
1 #require serve no-reposimplestore no-chg
2
2
3 #testcases stream-legacy stream-bundle2
3 #testcases stream-legacy stream-bundle2
4
4
5 #if stream-legacy
5 #if stream-legacy
6 $ cat << EOF >> $HGRCPATH
6 $ cat << EOF >> $HGRCPATH
7 > [server]
7 > [server]
8 > bundle2.stream = no
8 > bundle2.stream = no
9 > EOF
9 > EOF
10 #endif
10 #endif
11
11
12 Initialize repository
12 Initialize repository
13 the status call is to check for issue5130
13 the status call is to check for issue5130
14
14
15 $ hg init server
15 $ hg init server
16 $ cd server
16 $ cd server
17 $ touch foo
17 $ touch foo
18 $ hg -q commit -A -m initial
18 $ hg -q commit -A -m initial
19 >>> for i in range(1024):
19 >>> for i in range(1024):
20 ... with open(str(i), 'wb') as fh:
20 ... with open(str(i), 'wb') as fh:
21 ... fh.write(b"%d" % i) and None
21 ... fh.write(b"%d" % i) and None
22 $ hg -q commit -A -m 'add a lot of files'
22 $ hg -q commit -A -m 'add a lot of files'
23 $ hg st
23 $ hg st
24 $ hg --config server.uncompressed=false serve -p $HGPORT -d --pid-file=hg.pid
24 $ hg --config server.uncompressed=false serve -p $HGPORT -d --pid-file=hg.pid
25 $ cat hg.pid > $DAEMON_PIDS
25 $ cat hg.pid > $DAEMON_PIDS
26 $ cd ..
26 $ cd ..
27
27
28 Cannot stream clone when server.uncompressed is set
28 Cannot stream clone when server.uncompressed is set
29
29
30 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=stream_out'
30 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=stream_out'
31 200 Script output follows
31 200 Script output follows
32
32
33 1
33 1
34
34
35 #if stream-legacy
35 #if stream-legacy
36 $ hg debugcapabilities http://localhost:$HGPORT
36 $ hg debugcapabilities http://localhost:$HGPORT
37 Main capabilities:
37 Main capabilities:
38 batch
38 batch
39 branchmap
39 branchmap
40 $USUAL_BUNDLE2_CAPS_SERVER$
40 $USUAL_BUNDLE2_CAPS_SERVER$
41 changegroupsubset
41 changegroupsubset
42 compression=$BUNDLE2_COMPRESSIONS$
42 compression=$BUNDLE2_COMPRESSIONS$
43 getbundle
43 getbundle
44 httpheader=1024
44 httpheader=1024
45 httpmediatype=0.1rx,0.1tx,0.2tx
45 httpmediatype=0.1rx,0.1tx,0.2tx
46 known
46 known
47 lookup
47 lookup
48 pushkey
48 pushkey
49 unbundle=HG10GZ,HG10BZ,HG10UN
49 unbundle=HG10GZ,HG10BZ,HG10UN
50 unbundlehash
50 unbundlehash
51 Bundle2 capabilities:
51 Bundle2 capabilities:
52 HG20
52 HG20
53 bookmarks
53 bookmarks
54 changegroup
54 changegroup
55 01
55 01
56 02
56 02
57 checkheads
57 checkheads
58 related
58 related
59 digests
59 digests
60 md5
60 md5
61 sha1
61 sha1
62 sha512
62 sha512
63 error
63 error
64 abort
64 abort
65 unsupportedcontent
65 unsupportedcontent
66 pushraced
66 pushraced
67 pushkey
67 pushkey
68 hgtagsfnodes
68 hgtagsfnodes
69 listkeys
69 listkeys
70 phases
70 phases
71 heads
71 heads
72 pushkey
72 pushkey
73 remote-changegroup
73 remote-changegroup
74 http
74 http
75 https
75 https
76 rev-branch-cache
77
76
78 $ hg clone --stream -U http://localhost:$HGPORT server-disabled
77 $ hg clone --stream -U http://localhost:$HGPORT server-disabled
79 warning: stream clone requested but server has them disabled
78 warning: stream clone requested but server has them disabled
80 requesting all changes
79 requesting all changes
81 adding changesets
80 adding changesets
82 adding manifests
81 adding manifests
83 adding file changes
82 adding file changes
84 added 2 changesets with 1025 changes to 1025 files
83 added 2 changesets with 1025 changes to 1025 files
85 new changesets 96ee1d7354c4:c17445101a72
84 new changesets 96ee1d7354c4:c17445101a72
86
85
87 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=getbundle' content-type --bodyfile body --hgproto 0.2 --requestheader "x-hgarg-1=bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Aphases%253Dheads%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps&cg=0&common=0000000000000000000000000000000000000000&heads=c17445101a72edac06facd130d14808dfbd5c7c2&stream=1"
86 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=getbundle' content-type --bodyfile body --hgproto 0.2 --requestheader "x-hgarg-1=bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Aphases%253Dheads%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps&cg=0&common=0000000000000000000000000000000000000000&heads=c17445101a72edac06facd130d14808dfbd5c7c2&stream=1"
88 200 Script output follows
87 200 Script output follows
89 content-type: application/mercurial-0.2
88 content-type: application/mercurial-0.2
90
89
91
90
92 $ f --size body --hexdump --bytes 100
91 $ f --size body --hexdump --bytes 100
93 body: size=232
92 body: size=232
94 0000: 04 6e 6f 6e 65 48 47 32 30 00 00 00 00 00 00 00 |.noneHG20.......|
93 0000: 04 6e 6f 6e 65 48 47 32 30 00 00 00 00 00 00 00 |.noneHG20.......|
95 0010: cf 0b 45 52 52 4f 52 3a 41 42 4f 52 54 00 00 00 |..ERROR:ABORT...|
94 0010: cf 0b 45 52 52 4f 52 3a 41 42 4f 52 54 00 00 00 |..ERROR:ABORT...|
96 0020: 00 01 01 07 3c 04 72 6d 65 73 73 61 67 65 73 74 |....<.rmessagest|
95 0020: 00 01 01 07 3c 04 72 6d 65 73 73 61 67 65 73 74 |....<.rmessagest|
97 0030: 72 65 61 6d 20 64 61 74 61 20 72 65 71 75 65 73 |ream data reques|
96 0030: 72 65 61 6d 20 64 61 74 61 20 72 65 71 75 65 73 |ream data reques|
98 0040: 74 65 64 20 62 75 74 20 73 65 72 76 65 72 20 64 |ted but server d|
97 0040: 74 65 64 20 62 75 74 20 73 65 72 76 65 72 20 64 |ted but server d|
99 0050: 6f 65 73 20 6e 6f 74 20 61 6c 6c 6f 77 20 74 68 |oes not allow th|
98 0050: 6f 65 73 20 6e 6f 74 20 61 6c 6c 6f 77 20 74 68 |oes not allow th|
100 0060: 69 73 20 66 |is f|
99 0060: 69 73 20 66 |is f|
101
100
102 #endif
101 #endif
103 #if stream-bundle2
102 #if stream-bundle2
104 $ hg debugcapabilities http://localhost:$HGPORT
103 $ hg debugcapabilities http://localhost:$HGPORT
105 Main capabilities:
104 Main capabilities:
106 batch
105 batch
107 branchmap
106 branchmap
108 $USUAL_BUNDLE2_CAPS_SERVER$
107 $USUAL_BUNDLE2_CAPS_SERVER$
109 changegroupsubset
108 changegroupsubset
110 compression=$BUNDLE2_COMPRESSIONS$
109 compression=$BUNDLE2_COMPRESSIONS$
111 getbundle
110 getbundle
112 httpheader=1024
111 httpheader=1024
113 httpmediatype=0.1rx,0.1tx,0.2tx
112 httpmediatype=0.1rx,0.1tx,0.2tx
114 known
113 known
115 lookup
114 lookup
116 pushkey
115 pushkey
117 unbundle=HG10GZ,HG10BZ,HG10UN
116 unbundle=HG10GZ,HG10BZ,HG10UN
118 unbundlehash
117 unbundlehash
119 Bundle2 capabilities:
118 Bundle2 capabilities:
120 HG20
119 HG20
121 bookmarks
120 bookmarks
122 changegroup
121 changegroup
123 01
122 01
124 02
123 02
125 checkheads
124 checkheads
126 related
125 related
127 digests
126 digests
128 md5
127 md5
129 sha1
128 sha1
130 sha512
129 sha512
131 error
130 error
132 abort
131 abort
133 unsupportedcontent
132 unsupportedcontent
134 pushraced
133 pushraced
135 pushkey
134 pushkey
136 hgtagsfnodes
135 hgtagsfnodes
137 listkeys
136 listkeys
138 phases
137 phases
139 heads
138 heads
140 pushkey
139 pushkey
141 remote-changegroup
140 remote-changegroup
142 http
141 http
143 https
142 https
144 rev-branch-cache
145
143
146 $ hg clone --stream -U http://localhost:$HGPORT server-disabled
144 $ hg clone --stream -U http://localhost:$HGPORT server-disabled
147 warning: stream clone requested but server has them disabled
145 warning: stream clone requested but server has them disabled
148 requesting all changes
146 requesting all changes
149 adding changesets
147 adding changesets
150 adding manifests
148 adding manifests
151 adding file changes
149 adding file changes
152 added 2 changesets with 1025 changes to 1025 files
150 added 2 changesets with 1025 changes to 1025 files
153 new changesets 96ee1d7354c4:c17445101a72
151 new changesets 96ee1d7354c4:c17445101a72
154
152
155 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=getbundle' content-type --bodyfile body --hgproto 0.2 --requestheader "x-hgarg-1=bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Aphases%253Dheads%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps&cg=0&common=0000000000000000000000000000000000000000&heads=c17445101a72edac06facd130d14808dfbd5c7c2&stream=1"
153 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=getbundle' content-type --bodyfile body --hgproto 0.2 --requestheader "x-hgarg-1=bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Aphases%253Dheads%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps&cg=0&common=0000000000000000000000000000000000000000&heads=c17445101a72edac06facd130d14808dfbd5c7c2&stream=1"
156 200 Script output follows
154 200 Script output follows
157 content-type: application/mercurial-0.2
155 content-type: application/mercurial-0.2
158
156
159
157
160 $ f --size body --hexdump --bytes 100
158 $ f --size body --hexdump --bytes 100
161 body: size=232
159 body: size=232
162 0000: 04 6e 6f 6e 65 48 47 32 30 00 00 00 00 00 00 00 |.noneHG20.......|
160 0000: 04 6e 6f 6e 65 48 47 32 30 00 00 00 00 00 00 00 |.noneHG20.......|
163 0010: cf 0b 45 52 52 4f 52 3a 41 42 4f 52 54 00 00 00 |..ERROR:ABORT...|
161 0010: cf 0b 45 52 52 4f 52 3a 41 42 4f 52 54 00 00 00 |..ERROR:ABORT...|
164 0020: 00 01 01 07 3c 04 72 6d 65 73 73 61 67 65 73 74 |....<.rmessagest|
162 0020: 00 01 01 07 3c 04 72 6d 65 73 73 61 67 65 73 74 |....<.rmessagest|
165 0030: 72 65 61 6d 20 64 61 74 61 20 72 65 71 75 65 73 |ream data reques|
163 0030: 72 65 61 6d 20 64 61 74 61 20 72 65 71 75 65 73 |ream data reques|
166 0040: 74 65 64 20 62 75 74 20 73 65 72 76 65 72 20 64 |ted but server d|
164 0040: 74 65 64 20 62 75 74 20 73 65 72 76 65 72 20 64 |ted but server d|
167 0050: 6f 65 73 20 6e 6f 74 20 61 6c 6c 6f 77 20 74 68 |oes not allow th|
165 0050: 6f 65 73 20 6e 6f 74 20 61 6c 6c 6f 77 20 74 68 |oes not allow th|
168 0060: 69 73 20 66 |is f|
166 0060: 69 73 20 66 |is f|
169
167
170 #endif
168 #endif
171
169
172 $ killdaemons.py
170 $ killdaemons.py
173 $ cd server
171 $ cd server
174 $ hg serve -p $HGPORT -d --pid-file=hg.pid
172 $ hg serve -p $HGPORT -d --pid-file=hg.pid
175 $ cat hg.pid > $DAEMON_PIDS
173 $ cat hg.pid > $DAEMON_PIDS
176 $ cd ..
174 $ cd ..
177
175
178 Basic clone
176 Basic clone
179
177
180 #if stream-legacy
178 #if stream-legacy
181 $ hg clone --stream -U http://localhost:$HGPORT clone1
179 $ hg clone --stream -U http://localhost:$HGPORT clone1
182 streaming all changes
180 streaming all changes
183 1027 files to transfer, 96.3 KB of data
181 1027 files to transfer, 96.3 KB of data
184 transferred 96.3 KB in * seconds (*/sec) (glob)
182 transferred 96.3 KB in * seconds (*/sec) (glob)
185 searching for changes
183 searching for changes
186 no changes found
184 no changes found
187 #endif
185 #endif
188 #if stream-bundle2
186 #if stream-bundle2
189 $ hg clone --stream -U http://localhost:$HGPORT clone1
187 $ hg clone --stream -U http://localhost:$HGPORT clone1
190 streaming all changes
188 streaming all changes
191 1030 files to transfer, 96.5 KB of data
189 1030 files to transfer, 96.5 KB of data
192 transferred 96.5 KB in * seconds (* */sec) (glob)
190 transferred 96.5 KB in * seconds (* */sec) (glob)
193
191
194 $ ls -1 clone1/.hg/cache
192 $ ls -1 clone1/.hg/cache
195 branch2-base
193 branch2-base
196 branch2-immutable
194 branch2-immutable
197 branch2-served
195 branch2-served
198 branch2-served.hidden
196 branch2-served.hidden
199 branch2-visible
197 branch2-visible
200 branch2-visible-hidden
198 branch2-visible-hidden
201 hgtagsfnodes1
199 hgtagsfnodes1
202 rbc-names-v1
200 rbc-names-v1
203 rbc-revs-v1
201 rbc-revs-v1
204 tags2
202 tags2
205 tags2-served
203 tags2-served
206 #endif
204 #endif
207
205
208 getbundle requests with stream=1 are uncompressed
206 getbundle requests with stream=1 are uncompressed
209
207
210 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=getbundle' content-type --bodyfile body --hgproto '0.1 0.2 comp=zlib,none' --requestheader "x-hgarg-1=bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Aphases%253Dheads%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps&cg=0&common=0000000000000000000000000000000000000000&heads=c17445101a72edac06facd130d14808dfbd5c7c2&stream=1"
208 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=getbundle' content-type --bodyfile body --hgproto '0.1 0.2 comp=zlib,none' --requestheader "x-hgarg-1=bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Aphases%253Dheads%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps&cg=0&common=0000000000000000000000000000000000000000&heads=c17445101a72edac06facd130d14808dfbd5c7c2&stream=1"
211 200 Script output follows
209 200 Script output follows
212 content-type: application/mercurial-0.2
210 content-type: application/mercurial-0.2
213
211
214
212
215 $ f --size --hex --bytes 256 body
213 $ f --size --hex --bytes 256 body
216 body: size=112262
214 body: size=112262
217 0000: 04 6e 6f 6e 65 48 47 32 30 00 00 00 00 00 00 00 |.noneHG20.......|
215 0000: 04 6e 6f 6e 65 48 47 32 30 00 00 00 00 00 00 00 |.noneHG20.......|
218 0010: 7f 07 53 54 52 45 41 4d 32 00 00 00 00 03 00 09 |..STREAM2.......|
216 0010: 7f 07 53 54 52 45 41 4d 32 00 00 00 00 03 00 09 |..STREAM2.......|
219 0020: 05 09 04 0c 44 62 79 74 65 63 6f 75 6e 74 39 38 |....Dbytecount98|
217 0020: 05 09 04 0c 44 62 79 74 65 63 6f 75 6e 74 39 38 |....Dbytecount98|
220 0030: 37 37 35 66 69 6c 65 63 6f 75 6e 74 31 30 33 30 |775filecount1030|
218 0030: 37 37 35 66 69 6c 65 63 6f 75 6e 74 31 30 33 30 |775filecount1030|
221 0040: 72 65 71 75 69 72 65 6d 65 6e 74 73 64 6f 74 65 |requirementsdote|
219 0040: 72 65 71 75 69 72 65 6d 65 6e 74 73 64 6f 74 65 |requirementsdote|
222 0050: 6e 63 6f 64 65 25 32 43 66 6e 63 61 63 68 65 25 |ncode%2Cfncache%|
220 0050: 6e 63 6f 64 65 25 32 43 66 6e 63 61 63 68 65 25 |ncode%2Cfncache%|
223 0060: 32 43 67 65 6e 65 72 61 6c 64 65 6c 74 61 25 32 |2Cgeneraldelta%2|
221 0060: 32 43 67 65 6e 65 72 61 6c 64 65 6c 74 61 25 32 |2Cgeneraldelta%2|
224 0070: 43 72 65 76 6c 6f 67 76 31 25 32 43 73 70 61 72 |Crevlogv1%2Cspar|
222 0070: 43 72 65 76 6c 6f 67 76 31 25 32 43 73 70 61 72 |Crevlogv1%2Cspar|
225 0080: 73 65 72 65 76 6c 6f 67 25 32 43 73 74 6f 72 65 |serevlog%2Cstore|
223 0080: 73 65 72 65 76 6c 6f 67 25 32 43 73 74 6f 72 65 |serevlog%2Cstore|
226 0090: 00 00 80 00 73 08 42 64 61 74 61 2f 30 2e 69 00 |....s.Bdata/0.i.|
224 0090: 00 00 80 00 73 08 42 64 61 74 61 2f 30 2e 69 00 |....s.Bdata/0.i.|
227 00a0: 03 00 01 00 00 00 00 00 00 00 02 00 00 00 01 00 |................|
225 00a0: 03 00 01 00 00 00 00 00 00 00 02 00 00 00 01 00 |................|
228 00b0: 00 00 00 00 00 00 01 ff ff ff ff ff ff ff ff 80 |................|
226 00b0: 00 00 00 00 00 00 01 ff ff ff ff ff ff ff ff 80 |................|
229 00c0: 29 63 a0 49 d3 23 87 bf ce fe 56 67 92 67 2c 69 |)c.I.#....Vg.g,i|
227 00c0: 29 63 a0 49 d3 23 87 bf ce fe 56 67 92 67 2c 69 |)c.I.#....Vg.g,i|
230 00d0: d1 ec 39 00 00 00 00 00 00 00 00 00 00 00 00 75 |..9............u|
228 00d0: d1 ec 39 00 00 00 00 00 00 00 00 00 00 00 00 75 |..9............u|
231 00e0: 30 73 08 42 64 61 74 61 2f 31 2e 69 00 03 00 01 |0s.Bdata/1.i....|
229 00e0: 30 73 08 42 64 61 74 61 2f 31 2e 69 00 03 00 01 |0s.Bdata/1.i....|
232 00f0: 00 00 00 00 00 00 00 02 00 00 00 01 00 00 00 00 |................|
230 00f0: 00 00 00 00 00 00 00 02 00 00 00 01 00 00 00 00 |................|
233
231
234 --uncompressed is an alias to --stream
232 --uncompressed is an alias to --stream
235
233
236 #if stream-legacy
234 #if stream-legacy
237 $ hg clone --uncompressed -U http://localhost:$HGPORT clone1-uncompressed
235 $ hg clone --uncompressed -U http://localhost:$HGPORT clone1-uncompressed
238 streaming all changes
236 streaming all changes
239 1027 files to transfer, 96.3 KB of data
237 1027 files to transfer, 96.3 KB of data
240 transferred 96.3 KB in * seconds (*/sec) (glob)
238 transferred 96.3 KB in * seconds (*/sec) (glob)
241 searching for changes
239 searching for changes
242 no changes found
240 no changes found
243 #endif
241 #endif
244 #if stream-bundle2
242 #if stream-bundle2
245 $ hg clone --uncompressed -U http://localhost:$HGPORT clone1-uncompressed
243 $ hg clone --uncompressed -U http://localhost:$HGPORT clone1-uncompressed
246 streaming all changes
244 streaming all changes
247 1030 files to transfer, 96.5 KB of data
245 1030 files to transfer, 96.5 KB of data
248 transferred 96.5 KB in * seconds (* */sec) (glob)
246 transferred 96.5 KB in * seconds (* */sec) (glob)
249 #endif
247 #endif
250
248
251 Clone with background file closing enabled
249 Clone with background file closing enabled
252
250
253 #if stream-legacy
251 #if stream-legacy
254 $ hg --debug --config worker.backgroundclose=true --config worker.backgroundcloseminfilecount=1 clone --stream -U http://localhost:$HGPORT clone-background | grep -v adding
252 $ hg --debug --config worker.backgroundclose=true --config worker.backgroundcloseminfilecount=1 clone --stream -U http://localhost:$HGPORT clone-background | grep -v adding
255 using http://localhost:$HGPORT/
253 using http://localhost:$HGPORT/
256 sending capabilities command
254 sending capabilities command
257 sending branchmap command
255 sending branchmap command
258 streaming all changes
256 streaming all changes
259 sending stream_out command
257 sending stream_out command
260 1027 files to transfer, 96.3 KB of data
258 1027 files to transfer, 96.3 KB of data
261 starting 4 threads for background file closing
259 starting 4 threads for background file closing
262 updating the branch cache
260 updating the branch cache
263 transferred 96.3 KB in * seconds (*/sec) (glob)
261 transferred 96.3 KB in * seconds (*/sec) (glob)
264 query 1; heads
262 query 1; heads
265 sending batch command
263 sending batch command
266 searching for changes
264 searching for changes
267 all remote heads known locally
265 all remote heads known locally
268 no changes found
266 no changes found
269 sending getbundle command
267 sending getbundle command
270 bundle2-input-bundle: with-transaction
268 bundle2-input-bundle: with-transaction
271 bundle2-input-part: "listkeys" (params: 1 mandatory) supported
269 bundle2-input-part: "listkeys" (params: 1 mandatory) supported
272 bundle2-input-part: "phase-heads" supported
270 bundle2-input-part: "phase-heads" supported
273 bundle2-input-part: total payload size 24
271 bundle2-input-part: total payload size 24
274 bundle2-input-bundle: 2 parts total
272 bundle2-input-bundle: 2 parts total
275 checking for updated bookmarks
273 checking for updated bookmarks
276 updating the branch cache
274 updating the branch cache
277 (sent 5 HTTP requests and * bytes; received * bytes in responses) (glob)
275 (sent 5 HTTP requests and * bytes; received * bytes in responses) (glob)
278 #endif
276 #endif
279 #if stream-bundle2
277 #if stream-bundle2
280 $ hg --debug --config worker.backgroundclose=true --config worker.backgroundcloseminfilecount=1 clone --stream -U http://localhost:$HGPORT clone-background | grep -v adding
278 $ hg --debug --config worker.backgroundclose=true --config worker.backgroundcloseminfilecount=1 clone --stream -U http://localhost:$HGPORT clone-background | grep -v adding
281 using http://localhost:$HGPORT/
279 using http://localhost:$HGPORT/
282 sending capabilities command
280 sending capabilities command
283 query 1; heads
281 query 1; heads
284 sending batch command
282 sending batch command
285 streaming all changes
283 streaming all changes
286 sending getbundle command
284 sending getbundle command
287 bundle2-input-bundle: with-transaction
285 bundle2-input-bundle: with-transaction
288 bundle2-input-part: "stream2" (params: 3 mandatory) supported
286 bundle2-input-part: "stream2" (params: 3 mandatory) supported
289 applying stream bundle
287 applying stream bundle
290 1030 files to transfer, 96.5 KB of data
288 1030 files to transfer, 96.5 KB of data
291 starting 4 threads for background file closing
289 starting 4 threads for background file closing
292 starting 4 threads for background file closing
290 starting 4 threads for background file closing
293 updating the branch cache
291 updating the branch cache
294 transferred 96.5 KB in * seconds (* */sec) (glob)
292 transferred 96.5 KB in * seconds (* */sec) (glob)
295 bundle2-input-part: total payload size 112094
293 bundle2-input-part: total payload size 112094
296 bundle2-input-part: "listkeys" (params: 1 mandatory) supported
294 bundle2-input-part: "listkeys" (params: 1 mandatory) supported
297 bundle2-input-bundle: 2 parts total
295 bundle2-input-bundle: 2 parts total
298 checking for updated bookmarks
296 checking for updated bookmarks
299 updating the branch cache
297 updating the branch cache
300 (sent 3 HTTP requests and * bytes; received * bytes in responses) (glob)
298 (sent 3 HTTP requests and * bytes; received * bytes in responses) (glob)
301 #endif
299 #endif
302
300
303 Cannot stream clone when there are secret changesets
301 Cannot stream clone when there are secret changesets
304
302
305 $ hg -R server phase --force --secret -r tip
303 $ hg -R server phase --force --secret -r tip
306 $ hg clone --stream -U http://localhost:$HGPORT secret-denied
304 $ hg clone --stream -U http://localhost:$HGPORT secret-denied
307 warning: stream clone requested but server has them disabled
305 warning: stream clone requested but server has them disabled
308 requesting all changes
306 requesting all changes
309 adding changesets
307 adding changesets
310 adding manifests
308 adding manifests
311 adding file changes
309 adding file changes
312 added 1 changesets with 1 changes to 1 files
310 added 1 changesets with 1 changes to 1 files
313 new changesets 96ee1d7354c4
311 new changesets 96ee1d7354c4
314
312
315 $ killdaemons.py
313 $ killdaemons.py
316
314
317 Streaming of secrets can be overridden by server config
315 Streaming of secrets can be overridden by server config
318
316
319 $ cd server
317 $ cd server
320 $ hg serve --config server.uncompressedallowsecret=true -p $HGPORT -d --pid-file=hg.pid
318 $ hg serve --config server.uncompressedallowsecret=true -p $HGPORT -d --pid-file=hg.pid
321 $ cat hg.pid > $DAEMON_PIDS
319 $ cat hg.pid > $DAEMON_PIDS
322 $ cd ..
320 $ cd ..
323
321
324 #if stream-legacy
322 #if stream-legacy
325 $ hg clone --stream -U http://localhost:$HGPORT secret-allowed
323 $ hg clone --stream -U http://localhost:$HGPORT secret-allowed
326 streaming all changes
324 streaming all changes
327 1027 files to transfer, 96.3 KB of data
325 1027 files to transfer, 96.3 KB of data
328 transferred 96.3 KB in * seconds (*/sec) (glob)
326 transferred 96.3 KB in * seconds (*/sec) (glob)
329 searching for changes
327 searching for changes
330 no changes found
328 no changes found
331 #endif
329 #endif
332 #if stream-bundle2
330 #if stream-bundle2
333 $ hg clone --stream -U http://localhost:$HGPORT secret-allowed
331 $ hg clone --stream -U http://localhost:$HGPORT secret-allowed
334 streaming all changes
332 streaming all changes
335 1030 files to transfer, 96.5 KB of data
333 1030 files to transfer, 96.5 KB of data
336 transferred 96.5 KB in * seconds (* */sec) (glob)
334 transferred 96.5 KB in * seconds (* */sec) (glob)
337 #endif
335 #endif
338
336
339 $ killdaemons.py
337 $ killdaemons.py
340
338
341 Verify interaction between preferuncompressed and secret presence
339 Verify interaction between preferuncompressed and secret presence
342
340
343 $ cd server
341 $ cd server
344 $ hg serve --config server.preferuncompressed=true -p $HGPORT -d --pid-file=hg.pid
342 $ hg serve --config server.preferuncompressed=true -p $HGPORT -d --pid-file=hg.pid
345 $ cat hg.pid > $DAEMON_PIDS
343 $ cat hg.pid > $DAEMON_PIDS
346 $ cd ..
344 $ cd ..
347
345
348 $ hg clone -U http://localhost:$HGPORT preferuncompressed-secret
346 $ hg clone -U http://localhost:$HGPORT preferuncompressed-secret
349 requesting all changes
347 requesting all changes
350 adding changesets
348 adding changesets
351 adding manifests
349 adding manifests
352 adding file changes
350 adding file changes
353 added 1 changesets with 1 changes to 1 files
351 added 1 changesets with 1 changes to 1 files
354 new changesets 96ee1d7354c4
352 new changesets 96ee1d7354c4
355
353
356 $ killdaemons.py
354 $ killdaemons.py
357
355
358 Clone not allowed when full bundles disabled and can't serve secrets
356 Clone not allowed when full bundles disabled and can't serve secrets
359
357
360 $ cd server
358 $ cd server
361 $ hg serve --config server.disablefullbundle=true -p $HGPORT -d --pid-file=hg.pid
359 $ hg serve --config server.disablefullbundle=true -p $HGPORT -d --pid-file=hg.pid
362 $ cat hg.pid > $DAEMON_PIDS
360 $ cat hg.pid > $DAEMON_PIDS
363 $ cd ..
361 $ cd ..
364
362
365 $ hg clone --stream http://localhost:$HGPORT secret-full-disabled
363 $ hg clone --stream http://localhost:$HGPORT secret-full-disabled
366 warning: stream clone requested but server has them disabled
364 warning: stream clone requested but server has them disabled
367 requesting all changes
365 requesting all changes
368 remote: abort: server has pull-based clones disabled
366 remote: abort: server has pull-based clones disabled
369 abort: pull failed on remote
367 abort: pull failed on remote
370 (remove --pull if specified or upgrade Mercurial)
368 (remove --pull if specified or upgrade Mercurial)
371 [255]
369 [255]
372
370
373 Local stream clone with secrets involved
371 Local stream clone with secrets involved
374 (This is just a test over behavior: if you have access to the repo's files,
372 (This is just a test over behavior: if you have access to the repo's files,
375 there is no security so it isn't important to prevent a clone here.)
373 there is no security so it isn't important to prevent a clone here.)
376
374
377 $ hg clone -U --stream server local-secret
375 $ hg clone -U --stream server local-secret
378 warning: stream clone requested but server has them disabled
376 warning: stream clone requested but server has them disabled
379 requesting all changes
377 requesting all changes
380 adding changesets
378 adding changesets
381 adding manifests
379 adding manifests
382 adding file changes
380 adding file changes
383 added 1 changesets with 1 changes to 1 files
381 added 1 changesets with 1 changes to 1 files
384 new changesets 96ee1d7354c4
382 new changesets 96ee1d7354c4
385
383
386 Stream clone while repo is changing:
384 Stream clone while repo is changing:
387
385
388 $ mkdir changing
386 $ mkdir changing
389 $ cd changing
387 $ cd changing
390
388
391 extension for delaying the server process so we reliably can modify the repo
389 extension for delaying the server process so we reliably can modify the repo
392 while cloning
390 while cloning
393
391
394 $ cat > delayer.py <<EOF
392 $ cat > delayer.py <<EOF
395 > import time
393 > import time
396 > from mercurial import extensions, vfs
394 > from mercurial import extensions, vfs
397 > def __call__(orig, self, path, *args, **kwargs):
395 > def __call__(orig, self, path, *args, **kwargs):
398 > if path == 'data/f1.i':
396 > if path == 'data/f1.i':
399 > time.sleep(2)
397 > time.sleep(2)
400 > return orig(self, path, *args, **kwargs)
398 > return orig(self, path, *args, **kwargs)
401 > extensions.wrapfunction(vfs.vfs, '__call__', __call__)
399 > extensions.wrapfunction(vfs.vfs, '__call__', __call__)
402 > EOF
400 > EOF
403
401
404 prepare repo with small and big file to cover both code paths in emitrevlogdata
402 prepare repo with small and big file to cover both code paths in emitrevlogdata
405
403
406 $ hg init repo
404 $ hg init repo
407 $ touch repo/f1
405 $ touch repo/f1
408 $ $TESTDIR/seq.py 50000 > repo/f2
406 $ $TESTDIR/seq.py 50000 > repo/f2
409 $ hg -R repo ci -Aqm "0"
407 $ hg -R repo ci -Aqm "0"
410 $ hg serve -R repo -p $HGPORT1 -d --pid-file=hg.pid --config extensions.delayer=delayer.py
408 $ hg serve -R repo -p $HGPORT1 -d --pid-file=hg.pid --config extensions.delayer=delayer.py
411 $ cat hg.pid >> $DAEMON_PIDS
409 $ cat hg.pid >> $DAEMON_PIDS
412
410
413 clone while modifying the repo between stating file with write lock and
411 clone while modifying the repo between stating file with write lock and
414 actually serving file content
412 actually serving file content
415
413
416 $ hg clone -q --stream -U http://localhost:$HGPORT1 clone &
414 $ hg clone -q --stream -U http://localhost:$HGPORT1 clone &
417 $ sleep 1
415 $ sleep 1
418 $ echo >> repo/f1
416 $ echo >> repo/f1
419 $ echo >> repo/f2
417 $ echo >> repo/f2
420 $ hg -R repo ci -m "1" --config ui.timeout.warn=-1
418 $ hg -R repo ci -m "1" --config ui.timeout.warn=-1
421 $ wait
419 $ wait
422 $ hg -R clone id
420 $ hg -R clone id
423 000000000000
421 000000000000
424 $ cd ..
422 $ cd ..
425
423
426 Stream repository with bookmarks
424 Stream repository with bookmarks
427 --------------------------------
425 --------------------------------
428
426
429 (revert introduction of secret changeset)
427 (revert introduction of secret changeset)
430
428
431 $ hg -R server phase --draft 'secret()'
429 $ hg -R server phase --draft 'secret()'
432
430
433 add a bookmark
431 add a bookmark
434
432
435 $ hg -R server bookmark -r tip some-bookmark
433 $ hg -R server bookmark -r tip some-bookmark
436
434
437 clone it
435 clone it
438
436
439 #if stream-legacy
437 #if stream-legacy
440 $ hg clone --stream http://localhost:$HGPORT with-bookmarks
438 $ hg clone --stream http://localhost:$HGPORT with-bookmarks
441 streaming all changes
439 streaming all changes
442 1027 files to transfer, 96.3 KB of data
440 1027 files to transfer, 96.3 KB of data
443 transferred 96.3 KB in * seconds (*) (glob)
441 transferred 96.3 KB in * seconds (*) (glob)
444 searching for changes
442 searching for changes
445 no changes found
443 no changes found
446 updating to branch default
444 updating to branch default
447 1025 files updated, 0 files merged, 0 files removed, 0 files unresolved
445 1025 files updated, 0 files merged, 0 files removed, 0 files unresolved
448 #endif
446 #endif
449 #if stream-bundle2
447 #if stream-bundle2
450 $ hg clone --stream http://localhost:$HGPORT with-bookmarks
448 $ hg clone --stream http://localhost:$HGPORT with-bookmarks
451 streaming all changes
449 streaming all changes
452 1033 files to transfer, 96.6 KB of data
450 1033 files to transfer, 96.6 KB of data
453 transferred 96.6 KB in * seconds (* */sec) (glob)
451 transferred 96.6 KB in * seconds (* */sec) (glob)
454 updating to branch default
452 updating to branch default
455 1025 files updated, 0 files merged, 0 files removed, 0 files unresolved
453 1025 files updated, 0 files merged, 0 files removed, 0 files unresolved
456 #endif
454 #endif
457 $ hg -R with-bookmarks bookmarks
455 $ hg -R with-bookmarks bookmarks
458 some-bookmark 1:c17445101a72
456 some-bookmark 1:c17445101a72
459
457
460 Stream repository with phases
458 Stream repository with phases
461 -----------------------------
459 -----------------------------
462
460
463 Clone as publishing
461 Clone as publishing
464
462
465 $ hg -R server phase -r 'all()'
463 $ hg -R server phase -r 'all()'
466 0: draft
464 0: draft
467 1: draft
465 1: draft
468
466
469 #if stream-legacy
467 #if stream-legacy
470 $ hg clone --stream http://localhost:$HGPORT phase-publish
468 $ hg clone --stream http://localhost:$HGPORT phase-publish
471 streaming all changes
469 streaming all changes
472 1027 files to transfer, 96.3 KB of data
470 1027 files to transfer, 96.3 KB of data
473 transferred 96.3 KB in * seconds (*) (glob)
471 transferred 96.3 KB in * seconds (*) (glob)
474 searching for changes
472 searching for changes
475 no changes found
473 no changes found
476 updating to branch default
474 updating to branch default
477 1025 files updated, 0 files merged, 0 files removed, 0 files unresolved
475 1025 files updated, 0 files merged, 0 files removed, 0 files unresolved
478 #endif
476 #endif
479 #if stream-bundle2
477 #if stream-bundle2
480 $ hg clone --stream http://localhost:$HGPORT phase-publish
478 $ hg clone --stream http://localhost:$HGPORT phase-publish
481 streaming all changes
479 streaming all changes
482 1033 files to transfer, 96.6 KB of data
480 1033 files to transfer, 96.6 KB of data
483 transferred 96.6 KB in * seconds (* */sec) (glob)
481 transferred 96.6 KB in * seconds (* */sec) (glob)
484 updating to branch default
482 updating to branch default
485 1025 files updated, 0 files merged, 0 files removed, 0 files unresolved
483 1025 files updated, 0 files merged, 0 files removed, 0 files unresolved
486 #endif
484 #endif
487 $ hg -R phase-publish phase -r 'all()'
485 $ hg -R phase-publish phase -r 'all()'
488 0: public
486 0: public
489 1: public
487 1: public
490
488
491 Clone as non publishing
489 Clone as non publishing
492
490
493 $ cat << EOF >> server/.hg/hgrc
491 $ cat << EOF >> server/.hg/hgrc
494 > [phases]
492 > [phases]
495 > publish = False
493 > publish = False
496 > EOF
494 > EOF
497 $ killdaemons.py
495 $ killdaemons.py
498 $ hg -R server serve -p $HGPORT -d --pid-file=hg.pid
496 $ hg -R server serve -p $HGPORT -d --pid-file=hg.pid
499 $ cat hg.pid > $DAEMON_PIDS
497 $ cat hg.pid > $DAEMON_PIDS
500
498
501 #if stream-legacy
499 #if stream-legacy
502
500
503 With v1 of the stream protocol, changeset are always cloned as public. It make
501 With v1 of the stream protocol, changeset are always cloned as public. It make
504 stream v1 unsuitable for non-publishing repository.
502 stream v1 unsuitable for non-publishing repository.
505
503
506 $ hg clone --stream http://localhost:$HGPORT phase-no-publish
504 $ hg clone --stream http://localhost:$HGPORT phase-no-publish
507 streaming all changes
505 streaming all changes
508 1027 files to transfer, 96.3 KB of data
506 1027 files to transfer, 96.3 KB of data
509 transferred 96.3 KB in * seconds (*) (glob)
507 transferred 96.3 KB in * seconds (*) (glob)
510 searching for changes
508 searching for changes
511 no changes found
509 no changes found
512 updating to branch default
510 updating to branch default
513 1025 files updated, 0 files merged, 0 files removed, 0 files unresolved
511 1025 files updated, 0 files merged, 0 files removed, 0 files unresolved
514 $ hg -R phase-no-publish phase -r 'all()'
512 $ hg -R phase-no-publish phase -r 'all()'
515 0: public
513 0: public
516 1: public
514 1: public
517 #endif
515 #endif
518 #if stream-bundle2
516 #if stream-bundle2
519 $ hg clone --stream http://localhost:$HGPORT phase-no-publish
517 $ hg clone --stream http://localhost:$HGPORT phase-no-publish
520 streaming all changes
518 streaming all changes
521 1034 files to transfer, 96.7 KB of data
519 1034 files to transfer, 96.7 KB of data
522 transferred 96.7 KB in * seconds (* */sec) (glob)
520 transferred 96.7 KB in * seconds (* */sec) (glob)
523 updating to branch default
521 updating to branch default
524 1025 files updated, 0 files merged, 0 files removed, 0 files unresolved
522 1025 files updated, 0 files merged, 0 files removed, 0 files unresolved
525 $ hg -R phase-no-publish phase -r 'all()'
523 $ hg -R phase-no-publish phase -r 'all()'
526 0: draft
524 0: draft
527 1: draft
525 1: draft
528 #endif
526 #endif
529
527
530 $ killdaemons.py
528 $ killdaemons.py
531
529
532 #if stream-legacy
530 #if stream-legacy
533
531
534 With v1 of the stream protocol, changeset are always cloned as public. There's
532 With v1 of the stream protocol, changeset are always cloned as public. There's
535 no obsolescence markers exchange in stream v1.
533 no obsolescence markers exchange in stream v1.
536
534
537 #endif
535 #endif
538 #if stream-bundle2
536 #if stream-bundle2
539
537
540 Stream repository with obsolescence
538 Stream repository with obsolescence
541 -----------------------------------
539 -----------------------------------
542
540
543 Clone non-publishing with obsolescence
541 Clone non-publishing with obsolescence
544
542
545 $ cat >> $HGRCPATH << EOF
543 $ cat >> $HGRCPATH << EOF
546 > [experimental]
544 > [experimental]
547 > evolution=all
545 > evolution=all
548 > EOF
546 > EOF
549
547
550 $ cd server
548 $ cd server
551 $ echo foo > foo
549 $ echo foo > foo
552 $ hg -q commit -m 'about to be pruned'
550 $ hg -q commit -m 'about to be pruned'
553 $ hg debugobsolete `hg log -r . -T '{node}'` -d '0 0' -u test --record-parents
551 $ hg debugobsolete `hg log -r . -T '{node}'` -d '0 0' -u test --record-parents
554 1 new obsolescence markers
552 1 new obsolescence markers
555 obsoleted 1 changesets
553 obsoleted 1 changesets
556 $ hg up null -q
554 $ hg up null -q
557 $ hg log -T '{rev}: {phase}\n'
555 $ hg log -T '{rev}: {phase}\n'
558 1: draft
556 1: draft
559 0: draft
557 0: draft
560 $ hg serve -p $HGPORT -d --pid-file=hg.pid
558 $ hg serve -p $HGPORT -d --pid-file=hg.pid
561 $ cat hg.pid > $DAEMON_PIDS
559 $ cat hg.pid > $DAEMON_PIDS
562 $ cd ..
560 $ cd ..
563
561
564 $ hg clone -U --stream http://localhost:$HGPORT with-obsolescence
562 $ hg clone -U --stream http://localhost:$HGPORT with-obsolescence
565 streaming all changes
563 streaming all changes
566 1035 files to transfer, 97.1 KB of data
564 1035 files to transfer, 97.1 KB of data
567 transferred 97.1 KB in * seconds (* */sec) (glob)
565 transferred 97.1 KB in * seconds (* */sec) (glob)
568 $ hg -R with-obsolescence log -T '{rev}: {phase}\n'
566 $ hg -R with-obsolescence log -T '{rev}: {phase}\n'
569 1: draft
567 1: draft
570 0: draft
568 0: draft
571 $ hg debugobsolete -R with-obsolescence
569 $ hg debugobsolete -R with-obsolescence
572 50382b884f66690b7045cac93a540cba4d4c906f 0 {c17445101a72edac06facd130d14808dfbd5c7c2} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
570 50382b884f66690b7045cac93a540cba4d4c906f 0 {c17445101a72edac06facd130d14808dfbd5c7c2} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
573
571
574 $ hg clone -U --stream --config experimental.evolution=0 http://localhost:$HGPORT with-obsolescence-no-evolution
572 $ hg clone -U --stream --config experimental.evolution=0 http://localhost:$HGPORT with-obsolescence-no-evolution
575 streaming all changes
573 streaming all changes
576 remote: abort: server has obsolescence markers, but client cannot receive them via stream clone
574 remote: abort: server has obsolescence markers, but client cannot receive them via stream clone
577 abort: pull failed on remote
575 abort: pull failed on remote
578 [255]
576 [255]
579
577
580 $ killdaemons.py
578 $ killdaemons.py
581
579
582 #endif
580 #endif
@@ -1,640 +1,638 b''
1 #require no-reposimplestore no-chg
1 #require no-reposimplestore no-chg
2
2
3 Set up a server
3 Set up a server
4
4
5 $ hg init server
5 $ hg init server
6 $ cd server
6 $ cd server
7 $ cat >> .hg/hgrc << EOF
7 $ cat >> .hg/hgrc << EOF
8 > [extensions]
8 > [extensions]
9 > clonebundles =
9 > clonebundles =
10 > EOF
10 > EOF
11
11
12 $ touch foo
12 $ touch foo
13 $ hg -q commit -A -m 'add foo'
13 $ hg -q commit -A -m 'add foo'
14 $ touch bar
14 $ touch bar
15 $ hg -q commit -A -m 'add bar'
15 $ hg -q commit -A -m 'add bar'
16
16
17 $ hg serve -d -p $HGPORT --pid-file hg.pid --accesslog access.log
17 $ hg serve -d -p $HGPORT --pid-file hg.pid --accesslog access.log
18 $ cat hg.pid >> $DAEMON_PIDS
18 $ cat hg.pid >> $DAEMON_PIDS
19 $ cd ..
19 $ cd ..
20
20
21 Missing manifest should not result in server lookup
21 Missing manifest should not result in server lookup
22
22
23 $ hg --verbose clone -U http://localhost:$HGPORT no-manifest
23 $ hg --verbose clone -U http://localhost:$HGPORT no-manifest
24 requesting all changes
24 requesting all changes
25 adding changesets
25 adding changesets
26 adding manifests
26 adding manifests
27 adding file changes
27 adding file changes
28 added 2 changesets with 2 changes to 2 files
28 added 2 changesets with 2 changes to 2 files
29 new changesets 53245c60e682:aaff8d2ffbbf
29 new changesets 53245c60e682:aaff8d2ffbbf
30 (sent 3 HTTP requests and * bytes; received * bytes in responses) (glob)
30 (sent 3 HTTP requests and * bytes; received * bytes in responses) (glob)
31
31
32 $ cat server/access.log
32 $ cat server/access.log
33 * - - [*] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
33 * - - [*] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
34 $LOCALIP - - [$LOGDATE$] "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
34 $LOCALIP - - [$LOGDATE$] "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
35 $LOCALIP - - [$LOGDATE$] "GET /?cmd=getbundle HTTP/1.1" 200 - x-hgarg-1:bookmarks=1&$USUAL_BUNDLE_CAPS$&cg=1&common=0000000000000000000000000000000000000000&heads=aaff8d2ffbbf07a46dd1f05d8ae7877e3f56e2a2&listkeys=bookmarks&phases=1 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
35 $LOCALIP - - [$LOGDATE$] "GET /?cmd=getbundle HTTP/1.1" 200 - x-hgarg-1:bookmarks=1&$USUAL_BUNDLE_CAPS$&cg=1&common=0000000000000000000000000000000000000000&heads=aaff8d2ffbbf07a46dd1f05d8ae7877e3f56e2a2&listkeys=bookmarks&phases=1 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
36
36
37 Empty manifest file results in retrieval
37 Empty manifest file results in retrieval
38 (the extension only checks if the manifest file exists)
38 (the extension only checks if the manifest file exists)
39
39
40 $ touch server/.hg/clonebundles.manifest
40 $ touch server/.hg/clonebundles.manifest
41 $ hg --verbose clone -U http://localhost:$HGPORT empty-manifest
41 $ hg --verbose clone -U http://localhost:$HGPORT empty-manifest
42 no clone bundles available on remote; falling back to regular clone
42 no clone bundles available on remote; falling back to regular clone
43 requesting all changes
43 requesting all changes
44 adding changesets
44 adding changesets
45 adding manifests
45 adding manifests
46 adding file changes
46 adding file changes
47 added 2 changesets with 2 changes to 2 files
47 added 2 changesets with 2 changes to 2 files
48 new changesets 53245c60e682:aaff8d2ffbbf
48 new changesets 53245c60e682:aaff8d2ffbbf
49 (sent 4 HTTP requests and * bytes; received * bytes in responses) (glob)
49 (sent 4 HTTP requests and * bytes; received * bytes in responses) (glob)
50
50
51 Manifest file with invalid URL aborts
51 Manifest file with invalid URL aborts
52
52
53 $ echo 'http://does.not.exist/bundle.hg' > server/.hg/clonebundles.manifest
53 $ echo 'http://does.not.exist/bundle.hg' > server/.hg/clonebundles.manifest
54 $ hg clone http://localhost:$HGPORT 404-url
54 $ hg clone http://localhost:$HGPORT 404-url
55 applying clone bundle from http://does.not.exist/bundle.hg
55 applying clone bundle from http://does.not.exist/bundle.hg
56 error fetching bundle: (.* not known|(\[Errno -?\d+] )?([Nn]o address associated with (host)?name|Temporary failure in name resolution|Name does not resolve)) (re) (no-windows !)
56 error fetching bundle: (.* not known|(\[Errno -?\d+] )?([Nn]o address associated with (host)?name|Temporary failure in name resolution|Name does not resolve)) (re) (no-windows !)
57 error fetching bundle: [Errno 1100*] getaddrinfo failed (glob) (windows !)
57 error fetching bundle: [Errno 1100*] getaddrinfo failed (glob) (windows !)
58 abort: error applying bundle
58 abort: error applying bundle
59 (if this error persists, consider contacting the server operator or disable clone bundles via "--config ui.clonebundles=false")
59 (if this error persists, consider contacting the server operator or disable clone bundles via "--config ui.clonebundles=false")
60 [255]
60 [255]
61
61
62 Server is not running aborts
62 Server is not running aborts
63
63
64 $ echo "http://localhost:$HGPORT1/bundle.hg" > server/.hg/clonebundles.manifest
64 $ echo "http://localhost:$HGPORT1/bundle.hg" > server/.hg/clonebundles.manifest
65 $ hg clone http://localhost:$HGPORT server-not-runner
65 $ hg clone http://localhost:$HGPORT server-not-runner
66 applying clone bundle from http://localhost:$HGPORT1/bundle.hg
66 applying clone bundle from http://localhost:$HGPORT1/bundle.hg
67 error fetching bundle: (.* refused.*|Protocol not supported|(.* )?\$EADDRNOTAVAIL\$|.* No route to host) (re)
67 error fetching bundle: (.* refused.*|Protocol not supported|(.* )?\$EADDRNOTAVAIL\$|.* No route to host) (re)
68 abort: error applying bundle
68 abort: error applying bundle
69 (if this error persists, consider contacting the server operator or disable clone bundles via "--config ui.clonebundles=false")
69 (if this error persists, consider contacting the server operator or disable clone bundles via "--config ui.clonebundles=false")
70 [255]
70 [255]
71
71
72 Server returns 404
72 Server returns 404
73
73
74 $ "$PYTHON" $TESTDIR/dumbhttp.py -p $HGPORT1 --pid http.pid
74 $ "$PYTHON" $TESTDIR/dumbhttp.py -p $HGPORT1 --pid http.pid
75 $ cat http.pid >> $DAEMON_PIDS
75 $ cat http.pid >> $DAEMON_PIDS
76 $ hg clone http://localhost:$HGPORT running-404
76 $ hg clone http://localhost:$HGPORT running-404
77 applying clone bundle from http://localhost:$HGPORT1/bundle.hg
77 applying clone bundle from http://localhost:$HGPORT1/bundle.hg
78 HTTP error fetching bundle: HTTP Error 404: File not found
78 HTTP error fetching bundle: HTTP Error 404: File not found
79 abort: error applying bundle
79 abort: error applying bundle
80 (if this error persists, consider contacting the server operator or disable clone bundles via "--config ui.clonebundles=false")
80 (if this error persists, consider contacting the server operator or disable clone bundles via "--config ui.clonebundles=false")
81 [255]
81 [255]
82
82
83 We can override failure to fall back to regular clone
83 We can override failure to fall back to regular clone
84
84
85 $ hg --config ui.clonebundlefallback=true clone -U http://localhost:$HGPORT 404-fallback
85 $ hg --config ui.clonebundlefallback=true clone -U http://localhost:$HGPORT 404-fallback
86 applying clone bundle from http://localhost:$HGPORT1/bundle.hg
86 applying clone bundle from http://localhost:$HGPORT1/bundle.hg
87 HTTP error fetching bundle: HTTP Error 404: File not found
87 HTTP error fetching bundle: HTTP Error 404: File not found
88 falling back to normal clone
88 falling back to normal clone
89 requesting all changes
89 requesting all changes
90 adding changesets
90 adding changesets
91 adding manifests
91 adding manifests
92 adding file changes
92 adding file changes
93 added 2 changesets with 2 changes to 2 files
93 added 2 changesets with 2 changes to 2 files
94 new changesets 53245c60e682:aaff8d2ffbbf
94 new changesets 53245c60e682:aaff8d2ffbbf
95
95
96 Bundle with partial content works
96 Bundle with partial content works
97
97
98 $ hg -R server bundle --type gzip-v1 --base null -r 53245c60e682 partial.hg
98 $ hg -R server bundle --type gzip-v1 --base null -r 53245c60e682 partial.hg
99 1 changesets found
99 1 changesets found
100
100
101 We verify exact bundle content as an extra check against accidental future
101 We verify exact bundle content as an extra check against accidental future
102 changes. If this output changes, we could break old clients.
102 changes. If this output changes, we could break old clients.
103
103
104 $ f --size --hexdump partial.hg
104 $ f --size --hexdump partial.hg
105 partial.hg: size=207
105 partial.hg: size=207
106 0000: 48 47 31 30 47 5a 78 9c 63 60 60 98 17 ac 12 93 |HG10GZx.c``.....|
106 0000: 48 47 31 30 47 5a 78 9c 63 60 60 98 17 ac 12 93 |HG10GZx.c``.....|
107 0010: f0 ac a9 23 45 70 cb bf 0d 5f 59 4e 4a 7f 79 21 |...#Ep..._YNJ.y!|
107 0010: f0 ac a9 23 45 70 cb bf 0d 5f 59 4e 4a 7f 79 21 |...#Ep..._YNJ.y!|
108 0020: 9b cc 40 24 20 a0 d7 ce 2c d1 38 25 cd 24 25 d5 |..@$ ...,.8%.$%.|
108 0020: 9b cc 40 24 20 a0 d7 ce 2c d1 38 25 cd 24 25 d5 |..@$ ...,.8%.$%.|
109 0030: d8 c2 22 cd 38 d9 24 cd 22 d5 c8 22 cd 24 cd 32 |..".8.$."..".$.2|
109 0030: d8 c2 22 cd 38 d9 24 cd 22 d5 c8 22 cd 24 cd 32 |..".8.$."..".$.2|
110 0040: d1 c2 d0 c4 c8 d2 32 d1 38 39 29 c9 34 cd d4 80 |......2.89).4...|
110 0040: d1 c2 d0 c4 c8 d2 32 d1 38 39 29 c9 34 cd d4 80 |......2.89).4...|
111 0050: ab 24 b5 b8 84 cb 40 c1 80 2b 2d 3f 9f 8b 2b 31 |.$....@..+-?..+1|
111 0050: ab 24 b5 b8 84 cb 40 c1 80 2b 2d 3f 9f 8b 2b 31 |.$....@..+-?..+1|
112 0060: 25 45 01 c8 80 9a d2 9b 65 fb e5 9e 45 bf 8d 7f |%E......e...E...|
112 0060: 25 45 01 c8 80 9a d2 9b 65 fb e5 9e 45 bf 8d 7f |%E......e...E...|
113 0070: 9f c6 97 9f 2b 44 34 67 d9 ec 8e 0f a0 92 0b 75 |....+D4g.......u|
113 0070: 9f c6 97 9f 2b 44 34 67 d9 ec 8e 0f a0 92 0b 75 |....+D4g.......u|
114 0080: 41 d6 24 59 18 a4 a4 9a a6 18 1a 5b 98 9b 5a 98 |A.$Y.......[..Z.|
114 0080: 41 d6 24 59 18 a4 a4 9a a6 18 1a 5b 98 9b 5a 98 |A.$Y.......[..Z.|
115 0090: 9a 18 26 9b a6 19 98 1a 99 99 26 a6 18 9a 98 24 |..&.......&....$|
115 0090: 9a 18 26 9b a6 19 98 1a 99 99 26 a6 18 9a 98 24 |..&.......&....$|
116 00a0: 26 59 a6 25 5a 98 a5 18 a6 24 71 41 35 b1 43 dc |&Y.%Z....$qA5.C.|
116 00a0: 26 59 a6 25 5a 98 a5 18 a6 24 71 41 35 b1 43 dc |&Y.%Z....$qA5.C.|
117 00b0: 16 b2 83 f7 e9 45 8b d2 56 c7 a3 1f 82 52 d7 8a |.....E..V....R..|
117 00b0: 16 b2 83 f7 e9 45 8b d2 56 c7 a3 1f 82 52 d7 8a |.....E..V....R..|
118 00c0: 78 ed fc d5 76 f1 36 35 dc 05 00 36 ed 5e c7 |x...v.65...6.^.|
118 00c0: 78 ed fc d5 76 f1 36 35 dc 05 00 36 ed 5e c7 |x...v.65...6.^.|
119
119
120 $ echo "http://localhost:$HGPORT1/partial.hg" > server/.hg/clonebundles.manifest
120 $ echo "http://localhost:$HGPORT1/partial.hg" > server/.hg/clonebundles.manifest
121 $ hg clone -U http://localhost:$HGPORT partial-bundle
121 $ hg clone -U http://localhost:$HGPORT partial-bundle
122 applying clone bundle from http://localhost:$HGPORT1/partial.hg
122 applying clone bundle from http://localhost:$HGPORT1/partial.hg
123 adding changesets
123 adding changesets
124 adding manifests
124 adding manifests
125 adding file changes
125 adding file changes
126 added 1 changesets with 1 changes to 1 files
126 added 1 changesets with 1 changes to 1 files
127 finished applying clone bundle
127 finished applying clone bundle
128 searching for changes
128 searching for changes
129 adding changesets
129 adding changesets
130 adding manifests
130 adding manifests
131 adding file changes
131 adding file changes
132 added 1 changesets with 1 changes to 1 files
132 added 1 changesets with 1 changes to 1 files
133 new changesets aaff8d2ffbbf
133 new changesets aaff8d2ffbbf
134 1 local changesets published
134 1 local changesets published
135
135
136 Incremental pull doesn't fetch bundle
136 Incremental pull doesn't fetch bundle
137
137
138 $ hg clone -r 53245c60e682 -U http://localhost:$HGPORT partial-clone
138 $ hg clone -r 53245c60e682 -U http://localhost:$HGPORT partial-clone
139 adding changesets
139 adding changesets
140 adding manifests
140 adding manifests
141 adding file changes
141 adding file changes
142 added 1 changesets with 1 changes to 1 files
142 added 1 changesets with 1 changes to 1 files
143 new changesets 53245c60e682
143 new changesets 53245c60e682
144
144
145 $ cd partial-clone
145 $ cd partial-clone
146 $ hg pull
146 $ hg pull
147 pulling from http://localhost:$HGPORT/
147 pulling from http://localhost:$HGPORT/
148 searching for changes
148 searching for changes
149 adding changesets
149 adding changesets
150 adding manifests
150 adding manifests
151 adding file changes
151 adding file changes
152 added 1 changesets with 1 changes to 1 files
152 added 1 changesets with 1 changes to 1 files
153 new changesets aaff8d2ffbbf
153 new changesets aaff8d2ffbbf
154 (run 'hg update' to get a working copy)
154 (run 'hg update' to get a working copy)
155 $ cd ..
155 $ cd ..
156
156
157 Bundle with full content works
157 Bundle with full content works
158
158
159 $ hg -R server bundle --type gzip-v2 --base null -r tip full.hg
159 $ hg -R server bundle --type gzip-v2 --base null -r tip full.hg
160 2 changesets found
160 2 changesets found
161
161
162 Again, we perform an extra check against bundle content changes. If this content
162 Again, we perform an extra check against bundle content changes. If this content
163 changes, clone bundles produced by new Mercurial versions may not be readable
163 changes, clone bundles produced by new Mercurial versions may not be readable
164 by old clients.
164 by old clients.
165
165
166 $ f --size --hexdump full.hg
166 $ f --size --hexdump full.hg
167 full.hg: size=442
167 full.hg: size=442
168 0000: 48 47 32 30 00 00 00 0e 43 6f 6d 70 72 65 73 73 |HG20....Compress|
168 0000: 48 47 32 30 00 00 00 0e 43 6f 6d 70 72 65 73 73 |HG20....Compress|
169 0010: 69 6f 6e 3d 47 5a 78 9c 63 60 60 d0 e4 76 f6 70 |ion=GZx.c``..v.p|
169 0010: 69 6f 6e 3d 47 5a 78 9c 63 60 60 d0 e4 76 f6 70 |ion=GZx.c``..v.p|
170 0020: f4 73 77 75 0f f2 0f 0d 60 00 02 46 46 76 26 4e |.swu....`..FFv&N|
170 0020: f4 73 77 75 0f f2 0f 0d 60 00 02 46 46 76 26 4e |.swu....`..FFv&N|
171 0030: c6 b2 d4 a2 e2 cc fc 3c 03 a3 bc a4 e4 8c c4 bc |.......<........|
171 0030: c6 b2 d4 a2 e2 cc fc 3c 03 a3 bc a4 e4 8c c4 bc |.......<........|
172 0040: f4 d4 62 23 06 06 e6 19 40 f9 4d c1 2a 31 09 cf |..b#....@.M.*1..|
172 0040: f4 d4 62 23 06 06 e6 19 40 f9 4d c1 2a 31 09 cf |..b#....@.M.*1..|
173 0050: 9a 3a 52 04 b7 fc db f0 95 e5 a4 f4 97 17 b2 c9 |.:R.............|
173 0050: 9a 3a 52 04 b7 fc db f0 95 e5 a4 f4 97 17 b2 c9 |.:R.............|
174 0060: 0c 14 00 02 e6 d9 99 25 1a a7 a4 99 a4 a4 1a 5b |.......%.......[|
174 0060: 0c 14 00 02 e6 d9 99 25 1a a7 a4 99 a4 a4 1a 5b |.......%.......[|
175 0070: 58 a4 19 27 9b a4 59 a4 1a 59 a4 99 a4 59 26 5a |X..'..Y..Y...Y&Z|
175 0070: 58 a4 19 27 9b a4 59 a4 1a 59 a4 99 a4 59 26 5a |X..'..Y..Y...Y&Z|
176 0080: 18 9a 18 59 5a 26 1a 27 27 25 99 a6 99 1a 70 95 |...YZ&.''%....p.|
176 0080: 18 9a 18 59 5a 26 1a 27 27 25 99 a6 99 1a 70 95 |...YZ&.''%....p.|
177 0090: a4 16 97 70 19 28 18 70 a5 e5 e7 73 71 25 a6 a4 |...p.(.p...sq%..|
177 0090: a4 16 97 70 19 28 18 70 a5 e5 e7 73 71 25 a6 a4 |...p.(.p...sq%..|
178 00a0: 28 00 19 20 17 af fa df ab ff 7b 3f fb 92 dc 8b |(.. ......{?....|
178 00a0: 28 00 19 20 17 af fa df ab ff 7b 3f fb 92 dc 8b |(.. ......{?....|
179 00b0: 1f 62 bb 9e b7 d7 d9 87 3d 5a 44 89 2f b0 99 87 |.b......=ZD./...|
179 00b0: 1f 62 bb 9e b7 d7 d9 87 3d 5a 44 89 2f b0 99 87 |.b......=ZD./...|
180 00c0: ec e2 54 63 43 e3 b4 64 43 73 23 33 43 53 0b 63 |..TcC..dCs#3CS.c|
180 00c0: ec e2 54 63 43 e3 b4 64 43 73 23 33 43 53 0b 63 |..TcC..dCs#3CS.c|
181 00d0: d3 14 23 03 a0 fb 2c 2c 0c d3 80 1e 30 49 49 b1 |..#...,,....0II.|
181 00d0: d3 14 23 03 a0 fb 2c 2c 0c d3 80 1e 30 49 49 b1 |..#...,,....0II.|
182 00e0: 4c 4a 32 48 33 30 b0 34 42 b8 38 29 b1 08 e2 62 |LJ2H30.4B.8)...b|
182 00e0: 4c 4a 32 48 33 30 b0 34 42 b8 38 29 b1 08 e2 62 |LJ2H30.4B.8)...b|
183 00f0: 20 03 6a ca c2 2c db 2f f7 2c fa 6d fc fb 34 be | .j..,./.,.m..4.|
183 00f0: 20 03 6a ca c2 2c db 2f f7 2c fa 6d fc fb 34 be | .j..,./.,.m..4.|
184 0100: fc 5c 21 a2 39 cb 66 77 7c 00 0d c3 59 17 14 58 |.\!.9.fw|...Y..X|
184 0100: fc 5c 21 a2 39 cb 66 77 7c 00 0d c3 59 17 14 58 |.\!.9.fw|...Y..X|
185 0110: 49 16 06 29 a9 a6 29 86 c6 16 e6 a6 16 a6 26 86 |I..)..).......&.|
185 0110: 49 16 06 29 a9 a6 29 86 c6 16 e6 a6 16 a6 26 86 |I..)..).......&.|
186 0120: c9 a6 69 06 a6 46 66 a6 89 29 86 26 26 89 49 96 |..i..Ff..).&&.I.|
186 0120: c9 a6 69 06 a6 46 66 a6 89 29 86 26 26 89 49 96 |..i..Ff..).&&.I.|
187 0130: 69 89 16 66 29 86 29 49 5c 20 07 3e 16 fe 23 ae |i..f).)I\ .>..#.|
187 0130: 69 89 16 66 29 86 29 49 5c 20 07 3e 16 fe 23 ae |i..f).)I\ .>..#.|
188 0140: 26 da 1c ab 10 1f d1 f8 e3 b3 ef cd dd fc 0c 93 |&...............|
188 0140: 26 da 1c ab 10 1f d1 f8 e3 b3 ef cd dd fc 0c 93 |&...............|
189 0150: 88 75 34 36 75 04 82 55 17 14 36 a4 38 10 04 d8 |.u46u..U..6.8...|
189 0150: 88 75 34 36 75 04 82 55 17 14 36 a4 38 10 04 d8 |.u46u..U..6.8...|
190 0160: 21 01 9a b1 83 f7 e9 45 8b d2 56 c7 a3 1f 82 52 |!......E..V....R|
190 0160: 21 01 9a b1 83 f7 e9 45 8b d2 56 c7 a3 1f 82 52 |!......E..V....R|
191 0170: d7 8a 78 ed fc d5 76 f1 36 25 81 89 c7 ad ec 90 |..x...v.6%......|
191 0170: d7 8a 78 ed fc d5 76 f1 36 25 81 89 c7 ad ec 90 |..x...v.6%......|
192 0180: 54 47 75 2b 89 48 b1 b2 62 c9 89 c9 19 a9 56 45 |TGu+.H..b.....VE|
192 0180: 54 47 75 2b 89 48 b1 b2 62 c9 89 c9 19 a9 56 45 |TGu+.H..b.....VE|
193 0190: a9 65 ba 49 45 89 79 c9 19 ba 60 01 a0 14 23 58 |.e.IE.y...`...#X|
193 0190: a9 65 ba 49 45 89 79 c9 19 ba 60 01 a0 14 23 58 |.e.IE.y...`...#X|
194 01a0: 81 35 c8 7d 40 cc 04 e2 a4 a4 a6 25 96 e6 94 60 |.5.}@......%...`|
194 01a0: 81 35 c8 7d 40 cc 04 e2 a4 a4 a6 25 96 e6 94 60 |.5.}@......%...`|
195 01b0: 33 17 5f 54 00 00 d3 1b 0d 4c |3._T.....L|
195 01b0: 33 17 5f 54 00 00 d3 1b 0d 4c |3._T.....L|
196
196
197 $ echo "http://localhost:$HGPORT1/full.hg" > server/.hg/clonebundles.manifest
197 $ echo "http://localhost:$HGPORT1/full.hg" > server/.hg/clonebundles.manifest
198 $ hg clone -U http://localhost:$HGPORT full-bundle
198 $ hg clone -U http://localhost:$HGPORT full-bundle
199 applying clone bundle from http://localhost:$HGPORT1/full.hg
199 applying clone bundle from http://localhost:$HGPORT1/full.hg
200 adding changesets
200 adding changesets
201 adding manifests
201 adding manifests
202 adding file changes
202 adding file changes
203 added 2 changesets with 2 changes to 2 files
203 added 2 changesets with 2 changes to 2 files
204 finished applying clone bundle
204 finished applying clone bundle
205 searching for changes
205 searching for changes
206 no changes found
206 no changes found
207 2 local changesets published
207 2 local changesets published
208
208
209 Feature works over SSH
209 Feature works over SSH
210
210
211 $ hg clone -U -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" ssh://user@dummy/server ssh-full-clone
211 $ hg clone -U -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" ssh://user@dummy/server ssh-full-clone
212 applying clone bundle from http://localhost:$HGPORT1/full.hg
212 applying clone bundle from http://localhost:$HGPORT1/full.hg
213 adding changesets
213 adding changesets
214 adding manifests
214 adding manifests
215 adding file changes
215 adding file changes
216 added 2 changesets with 2 changes to 2 files
216 added 2 changesets with 2 changes to 2 files
217 finished applying clone bundle
217 finished applying clone bundle
218 searching for changes
218 searching for changes
219 no changes found
219 no changes found
220 2 local changesets published
220 2 local changesets published
221
221
222 Entry with unknown BUNDLESPEC is filtered and not used
222 Entry with unknown BUNDLESPEC is filtered and not used
223
223
224 $ cat > server/.hg/clonebundles.manifest << EOF
224 $ cat > server/.hg/clonebundles.manifest << EOF
225 > http://bad.entry1 BUNDLESPEC=UNKNOWN
225 > http://bad.entry1 BUNDLESPEC=UNKNOWN
226 > http://bad.entry2 BUNDLESPEC=xz-v1
226 > http://bad.entry2 BUNDLESPEC=xz-v1
227 > http://bad.entry3 BUNDLESPEC=none-v100
227 > http://bad.entry3 BUNDLESPEC=none-v100
228 > http://localhost:$HGPORT1/full.hg BUNDLESPEC=gzip-v2
228 > http://localhost:$HGPORT1/full.hg BUNDLESPEC=gzip-v2
229 > EOF
229 > EOF
230
230
231 $ hg clone -U http://localhost:$HGPORT filter-unknown-type
231 $ hg clone -U http://localhost:$HGPORT filter-unknown-type
232 applying clone bundle from http://localhost:$HGPORT1/full.hg
232 applying clone bundle from http://localhost:$HGPORT1/full.hg
233 adding changesets
233 adding changesets
234 adding manifests
234 adding manifests
235 adding file changes
235 adding file changes
236 added 2 changesets with 2 changes to 2 files
236 added 2 changesets with 2 changes to 2 files
237 finished applying clone bundle
237 finished applying clone bundle
238 searching for changes
238 searching for changes
239 no changes found
239 no changes found
240 2 local changesets published
240 2 local changesets published
241
241
242 Automatic fallback when all entries are filtered
242 Automatic fallback when all entries are filtered
243
243
244 $ cat > server/.hg/clonebundles.manifest << EOF
244 $ cat > server/.hg/clonebundles.manifest << EOF
245 > http://bad.entry BUNDLESPEC=UNKNOWN
245 > http://bad.entry BUNDLESPEC=UNKNOWN
246 > EOF
246 > EOF
247
247
248 $ hg clone -U http://localhost:$HGPORT filter-all
248 $ hg clone -U http://localhost:$HGPORT filter-all
249 no compatible clone bundles available on server; falling back to regular clone
249 no compatible clone bundles available on server; falling back to regular clone
250 (you may want to report this to the server operator)
250 (you may want to report this to the server operator)
251 requesting all changes
251 requesting all changes
252 adding changesets
252 adding changesets
253 adding manifests
253 adding manifests
254 adding file changes
254 adding file changes
255 added 2 changesets with 2 changes to 2 files
255 added 2 changesets with 2 changes to 2 files
256 new changesets 53245c60e682:aaff8d2ffbbf
256 new changesets 53245c60e682:aaff8d2ffbbf
257
257
258 We require a Python version that supports SNI. Therefore, URLs requiring SNI
258 We require a Python version that supports SNI. Therefore, URLs requiring SNI
259 are not filtered.
259 are not filtered.
260
260
261 $ cp full.hg sni.hg
261 $ cp full.hg sni.hg
262 $ cat > server/.hg/clonebundles.manifest << EOF
262 $ cat > server/.hg/clonebundles.manifest << EOF
263 > http://localhost:$HGPORT1/sni.hg REQUIRESNI=true
263 > http://localhost:$HGPORT1/sni.hg REQUIRESNI=true
264 > http://localhost:$HGPORT1/full.hg
264 > http://localhost:$HGPORT1/full.hg
265 > EOF
265 > EOF
266
266
267 $ hg clone -U http://localhost:$HGPORT sni-supported
267 $ hg clone -U http://localhost:$HGPORT sni-supported
268 applying clone bundle from http://localhost:$HGPORT1/sni.hg
268 applying clone bundle from http://localhost:$HGPORT1/sni.hg
269 adding changesets
269 adding changesets
270 adding manifests
270 adding manifests
271 adding file changes
271 adding file changes
272 added 2 changesets with 2 changes to 2 files
272 added 2 changesets with 2 changes to 2 files
273 finished applying clone bundle
273 finished applying clone bundle
274 searching for changes
274 searching for changes
275 no changes found
275 no changes found
276 2 local changesets published
276 2 local changesets published
277
277
278 Stream clone bundles are supported
278 Stream clone bundles are supported
279
279
280 $ hg -R server debugcreatestreamclonebundle packed.hg
280 $ hg -R server debugcreatestreamclonebundle packed.hg
281 writing 613 bytes for 4 files
281 writing 613 bytes for 4 files
282 bundle requirements: generaldelta, revlogv1, sparserevlog
282 bundle requirements: generaldelta, revlogv1, sparserevlog
283
283
284 No bundle spec should work
284 No bundle spec should work
285
285
286 $ cat > server/.hg/clonebundles.manifest << EOF
286 $ cat > server/.hg/clonebundles.manifest << EOF
287 > http://localhost:$HGPORT1/packed.hg
287 > http://localhost:$HGPORT1/packed.hg
288 > EOF
288 > EOF
289
289
290 $ hg clone -U http://localhost:$HGPORT stream-clone-no-spec
290 $ hg clone -U http://localhost:$HGPORT stream-clone-no-spec
291 applying clone bundle from http://localhost:$HGPORT1/packed.hg
291 applying clone bundle from http://localhost:$HGPORT1/packed.hg
292 4 files to transfer, 613 bytes of data
292 4 files to transfer, 613 bytes of data
293 transferred 613 bytes in *.* seconds (*) (glob)
293 transferred 613 bytes in *.* seconds (*) (glob)
294 finished applying clone bundle
294 finished applying clone bundle
295 searching for changes
295 searching for changes
296 no changes found
296 no changes found
297
297
298 Bundle spec without parameters should work
298 Bundle spec without parameters should work
299
299
300 $ cat > server/.hg/clonebundles.manifest << EOF
300 $ cat > server/.hg/clonebundles.manifest << EOF
301 > http://localhost:$HGPORT1/packed.hg BUNDLESPEC=none-packed1
301 > http://localhost:$HGPORT1/packed.hg BUNDLESPEC=none-packed1
302 > EOF
302 > EOF
303
303
304 $ hg clone -U http://localhost:$HGPORT stream-clone-vanilla-spec
304 $ hg clone -U http://localhost:$HGPORT stream-clone-vanilla-spec
305 applying clone bundle from http://localhost:$HGPORT1/packed.hg
305 applying clone bundle from http://localhost:$HGPORT1/packed.hg
306 4 files to transfer, 613 bytes of data
306 4 files to transfer, 613 bytes of data
307 transferred 613 bytes in *.* seconds (*) (glob)
307 transferred 613 bytes in *.* seconds (*) (glob)
308 finished applying clone bundle
308 finished applying clone bundle
309 searching for changes
309 searching for changes
310 no changes found
310 no changes found
311
311
312 Bundle spec with format requirements should work
312 Bundle spec with format requirements should work
313
313
314 $ cat > server/.hg/clonebundles.manifest << EOF
314 $ cat > server/.hg/clonebundles.manifest << EOF
315 > http://localhost:$HGPORT1/packed.hg BUNDLESPEC=none-packed1;requirements%3Drevlogv1
315 > http://localhost:$HGPORT1/packed.hg BUNDLESPEC=none-packed1;requirements%3Drevlogv1
316 > EOF
316 > EOF
317
317
318 $ hg clone -U http://localhost:$HGPORT stream-clone-supported-requirements
318 $ hg clone -U http://localhost:$HGPORT stream-clone-supported-requirements
319 applying clone bundle from http://localhost:$HGPORT1/packed.hg
319 applying clone bundle from http://localhost:$HGPORT1/packed.hg
320 4 files to transfer, 613 bytes of data
320 4 files to transfer, 613 bytes of data
321 transferred 613 bytes in *.* seconds (*) (glob)
321 transferred 613 bytes in *.* seconds (*) (glob)
322 finished applying clone bundle
322 finished applying clone bundle
323 searching for changes
323 searching for changes
324 no changes found
324 no changes found
325
325
326 Stream bundle spec with unknown requirements should be filtered out
326 Stream bundle spec with unknown requirements should be filtered out
327
327
328 $ cat > server/.hg/clonebundles.manifest << EOF
328 $ cat > server/.hg/clonebundles.manifest << EOF
329 > http://localhost:$HGPORT1/packed.hg BUNDLESPEC=none-packed1;requirements%3Drevlogv42
329 > http://localhost:$HGPORT1/packed.hg BUNDLESPEC=none-packed1;requirements%3Drevlogv42
330 > EOF
330 > EOF
331
331
332 $ hg clone -U http://localhost:$HGPORT stream-clone-unsupported-requirements
332 $ hg clone -U http://localhost:$HGPORT stream-clone-unsupported-requirements
333 no compatible clone bundles available on server; falling back to regular clone
333 no compatible clone bundles available on server; falling back to regular clone
334 (you may want to report this to the server operator)
334 (you may want to report this to the server operator)
335 requesting all changes
335 requesting all changes
336 adding changesets
336 adding changesets
337 adding manifests
337 adding manifests
338 adding file changes
338 adding file changes
339 added 2 changesets with 2 changes to 2 files
339 added 2 changesets with 2 changes to 2 files
340 new changesets 53245c60e682:aaff8d2ffbbf
340 new changesets 53245c60e682:aaff8d2ffbbf
341
341
342 Set up manifest for testing preferences
342 Set up manifest for testing preferences
343 (Remember, the TYPE does not have to match reality - the URL is
343 (Remember, the TYPE does not have to match reality - the URL is
344 important)
344 important)
345
345
346 $ cp full.hg gz-a.hg
346 $ cp full.hg gz-a.hg
347 $ cp full.hg gz-b.hg
347 $ cp full.hg gz-b.hg
348 $ cp full.hg bz2-a.hg
348 $ cp full.hg bz2-a.hg
349 $ cp full.hg bz2-b.hg
349 $ cp full.hg bz2-b.hg
350 $ cat > server/.hg/clonebundles.manifest << EOF
350 $ cat > server/.hg/clonebundles.manifest << EOF
351 > http://localhost:$HGPORT1/gz-a.hg BUNDLESPEC=gzip-v2 extra=a
351 > http://localhost:$HGPORT1/gz-a.hg BUNDLESPEC=gzip-v2 extra=a
352 > http://localhost:$HGPORT1/bz2-a.hg BUNDLESPEC=bzip2-v2 extra=a
352 > http://localhost:$HGPORT1/bz2-a.hg BUNDLESPEC=bzip2-v2 extra=a
353 > http://localhost:$HGPORT1/gz-b.hg BUNDLESPEC=gzip-v2 extra=b
353 > http://localhost:$HGPORT1/gz-b.hg BUNDLESPEC=gzip-v2 extra=b
354 > http://localhost:$HGPORT1/bz2-b.hg BUNDLESPEC=bzip2-v2 extra=b
354 > http://localhost:$HGPORT1/bz2-b.hg BUNDLESPEC=bzip2-v2 extra=b
355 > EOF
355 > EOF
356
356
357 Preferring an undefined attribute will take first entry
357 Preferring an undefined attribute will take first entry
358
358
359 $ hg --config ui.clonebundleprefers=foo=bar clone -U http://localhost:$HGPORT prefer-foo
359 $ hg --config ui.clonebundleprefers=foo=bar clone -U http://localhost:$HGPORT prefer-foo
360 applying clone bundle from http://localhost:$HGPORT1/gz-a.hg
360 applying clone bundle from http://localhost:$HGPORT1/gz-a.hg
361 adding changesets
361 adding changesets
362 adding manifests
362 adding manifests
363 adding file changes
363 adding file changes
364 added 2 changesets with 2 changes to 2 files
364 added 2 changesets with 2 changes to 2 files
365 finished applying clone bundle
365 finished applying clone bundle
366 searching for changes
366 searching for changes
367 no changes found
367 no changes found
368 2 local changesets published
368 2 local changesets published
369
369
370 Preferring bz2 type will download first entry of that type
370 Preferring bz2 type will download first entry of that type
371
371
372 $ hg --config ui.clonebundleprefers=COMPRESSION=bzip2 clone -U http://localhost:$HGPORT prefer-bz
372 $ hg --config ui.clonebundleprefers=COMPRESSION=bzip2 clone -U http://localhost:$HGPORT prefer-bz
373 applying clone bundle from http://localhost:$HGPORT1/bz2-a.hg
373 applying clone bundle from http://localhost:$HGPORT1/bz2-a.hg
374 adding changesets
374 adding changesets
375 adding manifests
375 adding manifests
376 adding file changes
376 adding file changes
377 added 2 changesets with 2 changes to 2 files
377 added 2 changesets with 2 changes to 2 files
378 finished applying clone bundle
378 finished applying clone bundle
379 searching for changes
379 searching for changes
380 no changes found
380 no changes found
381 2 local changesets published
381 2 local changesets published
382
382
383 Preferring multiple values of an option works
383 Preferring multiple values of an option works
384
384
385 $ hg --config ui.clonebundleprefers=COMPRESSION=unknown,COMPRESSION=bzip2 clone -U http://localhost:$HGPORT prefer-multiple-bz
385 $ hg --config ui.clonebundleprefers=COMPRESSION=unknown,COMPRESSION=bzip2 clone -U http://localhost:$HGPORT prefer-multiple-bz
386 applying clone bundle from http://localhost:$HGPORT1/bz2-a.hg
386 applying clone bundle from http://localhost:$HGPORT1/bz2-a.hg
387 adding changesets
387 adding changesets
388 adding manifests
388 adding manifests
389 adding file changes
389 adding file changes
390 added 2 changesets with 2 changes to 2 files
390 added 2 changesets with 2 changes to 2 files
391 finished applying clone bundle
391 finished applying clone bundle
392 searching for changes
392 searching for changes
393 no changes found
393 no changes found
394 2 local changesets published
394 2 local changesets published
395
395
396 Sorting multiple values should get us back to original first entry
396 Sorting multiple values should get us back to original first entry
397
397
398 $ hg --config ui.clonebundleprefers=BUNDLESPEC=unknown,BUNDLESPEC=gzip-v2,BUNDLESPEC=bzip2-v2 clone -U http://localhost:$HGPORT prefer-multiple-gz
398 $ hg --config ui.clonebundleprefers=BUNDLESPEC=unknown,BUNDLESPEC=gzip-v2,BUNDLESPEC=bzip2-v2 clone -U http://localhost:$HGPORT prefer-multiple-gz
399 applying clone bundle from http://localhost:$HGPORT1/gz-a.hg
399 applying clone bundle from http://localhost:$HGPORT1/gz-a.hg
400 adding changesets
400 adding changesets
401 adding manifests
401 adding manifests
402 adding file changes
402 adding file changes
403 added 2 changesets with 2 changes to 2 files
403 added 2 changesets with 2 changes to 2 files
404 finished applying clone bundle
404 finished applying clone bundle
405 searching for changes
405 searching for changes
406 no changes found
406 no changes found
407 2 local changesets published
407 2 local changesets published
408
408
409 Preferring multiple attributes has correct order
409 Preferring multiple attributes has correct order
410
410
411 $ hg --config ui.clonebundleprefers=extra=b,BUNDLESPEC=bzip2-v2 clone -U http://localhost:$HGPORT prefer-separate-attributes
411 $ hg --config ui.clonebundleprefers=extra=b,BUNDLESPEC=bzip2-v2 clone -U http://localhost:$HGPORT prefer-separate-attributes
412 applying clone bundle from http://localhost:$HGPORT1/bz2-b.hg
412 applying clone bundle from http://localhost:$HGPORT1/bz2-b.hg
413 adding changesets
413 adding changesets
414 adding manifests
414 adding manifests
415 adding file changes
415 adding file changes
416 added 2 changesets with 2 changes to 2 files
416 added 2 changesets with 2 changes to 2 files
417 finished applying clone bundle
417 finished applying clone bundle
418 searching for changes
418 searching for changes
419 no changes found
419 no changes found
420 2 local changesets published
420 2 local changesets published
421
421
422 Test where attribute is missing from some entries
422 Test where attribute is missing from some entries
423
423
424 $ cat > server/.hg/clonebundles.manifest << EOF
424 $ cat > server/.hg/clonebundles.manifest << EOF
425 > http://localhost:$HGPORT1/gz-a.hg BUNDLESPEC=gzip-v2
425 > http://localhost:$HGPORT1/gz-a.hg BUNDLESPEC=gzip-v2
426 > http://localhost:$HGPORT1/bz2-a.hg BUNDLESPEC=bzip2-v2
426 > http://localhost:$HGPORT1/bz2-a.hg BUNDLESPEC=bzip2-v2
427 > http://localhost:$HGPORT1/gz-b.hg BUNDLESPEC=gzip-v2 extra=b
427 > http://localhost:$HGPORT1/gz-b.hg BUNDLESPEC=gzip-v2 extra=b
428 > http://localhost:$HGPORT1/bz2-b.hg BUNDLESPEC=bzip2-v2 extra=b
428 > http://localhost:$HGPORT1/bz2-b.hg BUNDLESPEC=bzip2-v2 extra=b
429 > EOF
429 > EOF
430
430
431 $ hg --config ui.clonebundleprefers=extra=b clone -U http://localhost:$HGPORT prefer-partially-defined-attribute
431 $ hg --config ui.clonebundleprefers=extra=b clone -U http://localhost:$HGPORT prefer-partially-defined-attribute
432 applying clone bundle from http://localhost:$HGPORT1/gz-b.hg
432 applying clone bundle from http://localhost:$HGPORT1/gz-b.hg
433 adding changesets
433 adding changesets
434 adding manifests
434 adding manifests
435 adding file changes
435 adding file changes
436 added 2 changesets with 2 changes to 2 files
436 added 2 changesets with 2 changes to 2 files
437 finished applying clone bundle
437 finished applying clone bundle
438 searching for changes
438 searching for changes
439 no changes found
439 no changes found
440 2 local changesets published
440 2 local changesets published
441
441
442 Test a bad attribute list
442 Test a bad attribute list
443
443
444 $ hg --config ui.clonebundleprefers=bad clone -U http://localhost:$HGPORT bad-input
444 $ hg --config ui.clonebundleprefers=bad clone -U http://localhost:$HGPORT bad-input
445 abort: invalid ui.clonebundleprefers item: bad
445 abort: invalid ui.clonebundleprefers item: bad
446 (each comma separated item should be key=value pairs)
446 (each comma separated item should be key=value pairs)
447 [255]
447 [255]
448 $ hg --config ui.clonebundleprefers=key=val,bad,key2=val2 clone \
448 $ hg --config ui.clonebundleprefers=key=val,bad,key2=val2 clone \
449 > -U http://localhost:$HGPORT bad-input
449 > -U http://localhost:$HGPORT bad-input
450 abort: invalid ui.clonebundleprefers item: bad
450 abort: invalid ui.clonebundleprefers item: bad
451 (each comma separated item should be key=value pairs)
451 (each comma separated item should be key=value pairs)
452 [255]
452 [255]
453
453
454
454
455 Test interaction between clone bundles and --stream
455 Test interaction between clone bundles and --stream
456
456
457 A manifest with just a gzip bundle
457 A manifest with just a gzip bundle
458
458
459 $ cat > server/.hg/clonebundles.manifest << EOF
459 $ cat > server/.hg/clonebundles.manifest << EOF
460 > http://localhost:$HGPORT1/gz-a.hg BUNDLESPEC=gzip-v2
460 > http://localhost:$HGPORT1/gz-a.hg BUNDLESPEC=gzip-v2
461 > EOF
461 > EOF
462
462
463 $ hg clone -U --stream http://localhost:$HGPORT uncompressed-gzip
463 $ hg clone -U --stream http://localhost:$HGPORT uncompressed-gzip
464 no compatible clone bundles available on server; falling back to regular clone
464 no compatible clone bundles available on server; falling back to regular clone
465 (you may want to report this to the server operator)
465 (you may want to report this to the server operator)
466 streaming all changes
466 streaming all changes
467 9 files to transfer, 816 bytes of data
467 9 files to transfer, 816 bytes of data
468 transferred 816 bytes in * seconds (*) (glob)
468 transferred 816 bytes in * seconds (*) (glob)
469
469
470 A manifest with a stream clone but no BUNDLESPEC
470 A manifest with a stream clone but no BUNDLESPEC
471
471
472 $ cat > server/.hg/clonebundles.manifest << EOF
472 $ cat > server/.hg/clonebundles.manifest << EOF
473 > http://localhost:$HGPORT1/packed.hg
473 > http://localhost:$HGPORT1/packed.hg
474 > EOF
474 > EOF
475
475
476 $ hg clone -U --stream http://localhost:$HGPORT uncompressed-no-bundlespec
476 $ hg clone -U --stream http://localhost:$HGPORT uncompressed-no-bundlespec
477 no compatible clone bundles available on server; falling back to regular clone
477 no compatible clone bundles available on server; falling back to regular clone
478 (you may want to report this to the server operator)
478 (you may want to report this to the server operator)
479 streaming all changes
479 streaming all changes
480 9 files to transfer, 816 bytes of data
480 9 files to transfer, 816 bytes of data
481 transferred 816 bytes in * seconds (*) (glob)
481 transferred 816 bytes in * seconds (*) (glob)
482
482
483 A manifest with a gzip bundle and a stream clone
483 A manifest with a gzip bundle and a stream clone
484
484
485 $ cat > server/.hg/clonebundles.manifest << EOF
485 $ cat > server/.hg/clonebundles.manifest << EOF
486 > http://localhost:$HGPORT1/gz-a.hg BUNDLESPEC=gzip-v2
486 > http://localhost:$HGPORT1/gz-a.hg BUNDLESPEC=gzip-v2
487 > http://localhost:$HGPORT1/packed.hg BUNDLESPEC=none-packed1
487 > http://localhost:$HGPORT1/packed.hg BUNDLESPEC=none-packed1
488 > EOF
488 > EOF
489
489
490 $ hg clone -U --stream http://localhost:$HGPORT uncompressed-gzip-packed
490 $ hg clone -U --stream http://localhost:$HGPORT uncompressed-gzip-packed
491 applying clone bundle from http://localhost:$HGPORT1/packed.hg
491 applying clone bundle from http://localhost:$HGPORT1/packed.hg
492 4 files to transfer, 613 bytes of data
492 4 files to transfer, 613 bytes of data
493 transferred 613 bytes in * seconds (*) (glob)
493 transferred 613 bytes in * seconds (*) (glob)
494 finished applying clone bundle
494 finished applying clone bundle
495 searching for changes
495 searching for changes
496 no changes found
496 no changes found
497
497
498 A manifest with a gzip bundle and stream clone with supported requirements
498 A manifest with a gzip bundle and stream clone with supported requirements
499
499
500 $ cat > server/.hg/clonebundles.manifest << EOF
500 $ cat > server/.hg/clonebundles.manifest << EOF
501 > http://localhost:$HGPORT1/gz-a.hg BUNDLESPEC=gzip-v2
501 > http://localhost:$HGPORT1/gz-a.hg BUNDLESPEC=gzip-v2
502 > http://localhost:$HGPORT1/packed.hg BUNDLESPEC=none-packed1;requirements%3Drevlogv1
502 > http://localhost:$HGPORT1/packed.hg BUNDLESPEC=none-packed1;requirements%3Drevlogv1
503 > EOF
503 > EOF
504
504
505 $ hg clone -U --stream http://localhost:$HGPORT uncompressed-gzip-packed-requirements
505 $ hg clone -U --stream http://localhost:$HGPORT uncompressed-gzip-packed-requirements
506 applying clone bundle from http://localhost:$HGPORT1/packed.hg
506 applying clone bundle from http://localhost:$HGPORT1/packed.hg
507 4 files to transfer, 613 bytes of data
507 4 files to transfer, 613 bytes of data
508 transferred 613 bytes in * seconds (*) (glob)
508 transferred 613 bytes in * seconds (*) (glob)
509 finished applying clone bundle
509 finished applying clone bundle
510 searching for changes
510 searching for changes
511 no changes found
511 no changes found
512
512
513 A manifest with a gzip bundle and a stream clone with unsupported requirements
513 A manifest with a gzip bundle and a stream clone with unsupported requirements
514
514
515 $ cat > server/.hg/clonebundles.manifest << EOF
515 $ cat > server/.hg/clonebundles.manifest << EOF
516 > http://localhost:$HGPORT1/gz-a.hg BUNDLESPEC=gzip-v2
516 > http://localhost:$HGPORT1/gz-a.hg BUNDLESPEC=gzip-v2
517 > http://localhost:$HGPORT1/packed.hg BUNDLESPEC=none-packed1;requirements%3Drevlogv42
517 > http://localhost:$HGPORT1/packed.hg BUNDLESPEC=none-packed1;requirements%3Drevlogv42
518 > EOF
518 > EOF
519
519
520 $ hg clone -U --stream http://localhost:$HGPORT uncompressed-gzip-packed-unsupported-requirements
520 $ hg clone -U --stream http://localhost:$HGPORT uncompressed-gzip-packed-unsupported-requirements
521 no compatible clone bundles available on server; falling back to regular clone
521 no compatible clone bundles available on server; falling back to regular clone
522 (you may want to report this to the server operator)
522 (you may want to report this to the server operator)
523 streaming all changes
523 streaming all changes
524 9 files to transfer, 816 bytes of data
524 9 files to transfer, 816 bytes of data
525 transferred 816 bytes in * seconds (*) (glob)
525 transferred 816 bytes in * seconds (*) (glob)
526
526
527 Test clone bundle retrieved through bundle2
527 Test clone bundle retrieved through bundle2
528
528
529 $ cat << EOF >> $HGRCPATH
529 $ cat << EOF >> $HGRCPATH
530 > [extensions]
530 > [extensions]
531 > largefiles=
531 > largefiles=
532 > EOF
532 > EOF
533 $ killdaemons.py
533 $ killdaemons.py
534 $ hg -R server serve -d -p $HGPORT --pid-file hg.pid --accesslog access.log
534 $ hg -R server serve -d -p $HGPORT --pid-file hg.pid --accesslog access.log
535 $ cat hg.pid >> $DAEMON_PIDS
535 $ cat hg.pid >> $DAEMON_PIDS
536
536
537 $ hg -R server debuglfput gz-a.hg
537 $ hg -R server debuglfput gz-a.hg
538 1f74b3d08286b9b3a16fb3fa185dd29219cbc6ae
538 1f74b3d08286b9b3a16fb3fa185dd29219cbc6ae
539
539
540 $ cat > server/.hg/clonebundles.manifest << EOF
540 $ cat > server/.hg/clonebundles.manifest << EOF
541 > largefile://1f74b3d08286b9b3a16fb3fa185dd29219cbc6ae BUNDLESPEC=gzip-v2
541 > largefile://1f74b3d08286b9b3a16fb3fa185dd29219cbc6ae BUNDLESPEC=gzip-v2
542 > EOF
542 > EOF
543
543
544 $ hg clone -U http://localhost:$HGPORT largefile-provided --traceback
544 $ hg clone -U http://localhost:$HGPORT largefile-provided --traceback
545 applying clone bundle from largefile://1f74b3d08286b9b3a16fb3fa185dd29219cbc6ae
545 applying clone bundle from largefile://1f74b3d08286b9b3a16fb3fa185dd29219cbc6ae
546 adding changesets
546 adding changesets
547 adding manifests
547 adding manifests
548 adding file changes
548 adding file changes
549 added 2 changesets with 2 changes to 2 files
549 added 2 changesets with 2 changes to 2 files
550 finished applying clone bundle
550 finished applying clone bundle
551 searching for changes
551 searching for changes
552 no changes found
552 no changes found
553 2 local changesets published
553 2 local changesets published
554 $ killdaemons.py
554 $ killdaemons.py
555
555
556 A manifest with a gzip bundle requiring too much memory for a 16MB system and working
556 A manifest with a gzip bundle requiring too much memory for a 16MB system and working
557 on a 32MB system.
557 on a 32MB system.
558
558
559 $ "$PYTHON" $TESTDIR/dumbhttp.py -p $HGPORT1 --pid http.pid
559 $ "$PYTHON" $TESTDIR/dumbhttp.py -p $HGPORT1 --pid http.pid
560 $ cat http.pid >> $DAEMON_PIDS
560 $ cat http.pid >> $DAEMON_PIDS
561 $ hg -R server serve -d -p $HGPORT --pid-file hg.pid --accesslog access.log
561 $ hg -R server serve -d -p $HGPORT --pid-file hg.pid --accesslog access.log
562 $ cat hg.pid >> $DAEMON_PIDS
562 $ cat hg.pid >> $DAEMON_PIDS
563
563
564 $ cat > server/.hg/clonebundles.manifest << EOF
564 $ cat > server/.hg/clonebundles.manifest << EOF
565 > http://localhost:$HGPORT1/gz-a.hg BUNDLESPEC=gzip-v2 REQUIREDRAM=12MB
565 > http://localhost:$HGPORT1/gz-a.hg BUNDLESPEC=gzip-v2 REQUIREDRAM=12MB
566 > EOF
566 > EOF
567
567
568 $ hg clone -U --debug --config ui.available-memory=16MB http://localhost:$HGPORT gzip-too-large
568 $ hg clone -U --debug --config ui.available-memory=16MB http://localhost:$HGPORT gzip-too-large
569 using http://localhost:$HGPORT/
569 using http://localhost:$HGPORT/
570 sending capabilities command
570 sending capabilities command
571 sending clonebundles command
571 sending clonebundles command
572 filtering http://localhost:$HGPORT1/gz-a.hg as it needs more than 2/3 of system memory
572 filtering http://localhost:$HGPORT1/gz-a.hg as it needs more than 2/3 of system memory
573 no compatible clone bundles available on server; falling back to regular clone
573 no compatible clone bundles available on server; falling back to regular clone
574 (you may want to report this to the server operator)
574 (you may want to report this to the server operator)
575 query 1; heads
575 query 1; heads
576 sending batch command
576 sending batch command
577 requesting all changes
577 requesting all changes
578 sending getbundle command
578 sending getbundle command
579 bundle2-input-bundle: with-transaction
579 bundle2-input-bundle: with-transaction
580 bundle2-input-part: "changegroup" (params: 1 mandatory 1 advisory) supported
580 bundle2-input-part: "changegroup" (params: 1 mandatory 1 advisory) supported
581 adding changesets
581 adding changesets
582 add changeset 53245c60e682
582 add changeset 53245c60e682
583 add changeset aaff8d2ffbbf
583 add changeset aaff8d2ffbbf
584 adding manifests
584 adding manifests
585 adding file changes
585 adding file changes
586 adding bar revisions
586 adding bar revisions
587 adding foo revisions
587 adding foo revisions
588 bundle2-input-part: total payload size 920
588 bundle2-input-part: total payload size 920
589 bundle2-input-part: "listkeys" (params: 1 mandatory) supported
589 bundle2-input-part: "listkeys" (params: 1 mandatory) supported
590 bundle2-input-part: "phase-heads" supported
590 bundle2-input-part: "phase-heads" supported
591 bundle2-input-part: total payload size 24
591 bundle2-input-part: total payload size 24
592 bundle2-input-part: "cache:rev-branch-cache" (advisory) supported
592 bundle2-input-bundle: 3 parts total
593 bundle2-input-part: total payload size 59
594 bundle2-input-bundle: 4 parts total
595 checking for updated bookmarks
593 checking for updated bookmarks
596 updating the branch cache
594 updating the branch cache
597 added 2 changesets with 2 changes to 2 files
595 added 2 changesets with 2 changes to 2 files
598 new changesets 53245c60e682:aaff8d2ffbbf
596 new changesets 53245c60e682:aaff8d2ffbbf
599 calling hook changegroup.lfiles: hgext.largefiles.reposetup.checkrequireslfiles
597 calling hook changegroup.lfiles: hgext.largefiles.reposetup.checkrequireslfiles
600 updating the branch cache
598 updating the branch cache
601 (sent 4 HTTP requests and * bytes; received * bytes in responses) (glob)
599 (sent 4 HTTP requests and * bytes; received * bytes in responses) (glob)
602
600
603 $ hg clone -U --debug --config ui.available-memory=32MB http://localhost:$HGPORT gzip-too-large2
601 $ hg clone -U --debug --config ui.available-memory=32MB http://localhost:$HGPORT gzip-too-large2
604 using http://localhost:$HGPORT/
602 using http://localhost:$HGPORT/
605 sending capabilities command
603 sending capabilities command
606 sending clonebundles command
604 sending clonebundles command
607 applying clone bundle from http://localhost:$HGPORT1/gz-a.hg
605 applying clone bundle from http://localhost:$HGPORT1/gz-a.hg
608 bundle2-input-bundle: 1 params with-transaction
606 bundle2-input-bundle: 1 params with-transaction
609 bundle2-input-part: "changegroup" (params: 1 mandatory 1 advisory) supported
607 bundle2-input-part: "changegroup" (params: 1 mandatory 1 advisory) supported
610 adding changesets
608 adding changesets
611 add changeset 53245c60e682
609 add changeset 53245c60e682
612 add changeset aaff8d2ffbbf
610 add changeset aaff8d2ffbbf
613 adding manifests
611 adding manifests
614 adding file changes
612 adding file changes
615 adding bar revisions
613 adding bar revisions
616 adding foo revisions
614 adding foo revisions
617 bundle2-input-part: total payload size 920
615 bundle2-input-part: total payload size 920
618 bundle2-input-part: "cache:rev-branch-cache" (advisory) supported
616 bundle2-input-part: "cache:rev-branch-cache" (advisory) supported
619 bundle2-input-part: total payload size 59
617 bundle2-input-part: total payload size 59
620 bundle2-input-bundle: 2 parts total
618 bundle2-input-bundle: 2 parts total
621 updating the branch cache
619 updating the branch cache
622 added 2 changesets with 2 changes to 2 files
620 added 2 changesets with 2 changes to 2 files
623 finished applying clone bundle
621 finished applying clone bundle
624 query 1; heads
622 query 1; heads
625 sending batch command
623 sending batch command
626 searching for changes
624 searching for changes
627 all remote heads known locally
625 all remote heads known locally
628 no changes found
626 no changes found
629 sending getbundle command
627 sending getbundle command
630 bundle2-input-bundle: with-transaction
628 bundle2-input-bundle: with-transaction
631 bundle2-input-part: "listkeys" (params: 1 mandatory) supported
629 bundle2-input-part: "listkeys" (params: 1 mandatory) supported
632 bundle2-input-part: "phase-heads" supported
630 bundle2-input-part: "phase-heads" supported
633 bundle2-input-part: total payload size 24
631 bundle2-input-part: total payload size 24
634 bundle2-input-bundle: 2 parts total
632 bundle2-input-bundle: 2 parts total
635 checking for updated bookmarks
633 checking for updated bookmarks
636 2 local changesets published
634 2 local changesets published
637 calling hook changegroup.lfiles: hgext.largefiles.reposetup.checkrequireslfiles
635 calling hook changegroup.lfiles: hgext.largefiles.reposetup.checkrequireslfiles
638 updating the branch cache
636 updating the branch cache
639 (sent 4 HTTP requests and * bytes; received * bytes in responses) (glob)
637 (sent 4 HTTP requests and * bytes; received * bytes in responses) (glob)
640 $ killdaemons.py
638 $ killdaemons.py
@@ -1,665 +1,664 b''
1 $ cat << EOF >> $HGRCPATH
1 $ cat << EOF >> $HGRCPATH
2 > [ui]
2 > [ui]
3 > interactive=yes
3 > interactive=yes
4 > EOF
4 > EOF
5
5
6 $ hg init debugrevlog
6 $ hg init debugrevlog
7 $ cd debugrevlog
7 $ cd debugrevlog
8 $ echo a > a
8 $ echo a > a
9 $ hg ci -Am adda
9 $ hg ci -Am adda
10 adding a
10 adding a
11 $ hg rm .
11 $ hg rm .
12 removing a
12 removing a
13 $ hg ci -Am make-it-empty
13 $ hg ci -Am make-it-empty
14 $ hg revert --all -r 0
14 $ hg revert --all -r 0
15 adding a
15 adding a
16 $ hg ci -Am make-it-full
16 $ hg ci -Am make-it-full
17 #if reporevlogstore
17 #if reporevlogstore
18 $ hg debugrevlog -c
18 $ hg debugrevlog -c
19 format : 1
19 format : 1
20 flags : inline
20 flags : inline
21
21
22 revisions : 3
22 revisions : 3
23 merges : 0 ( 0.00%)
23 merges : 0 ( 0.00%)
24 normal : 3 (100.00%)
24 normal : 3 (100.00%)
25 revisions : 3
25 revisions : 3
26 empty : 0 ( 0.00%)
26 empty : 0 ( 0.00%)
27 text : 0 (100.00%)
27 text : 0 (100.00%)
28 delta : 0 (100.00%)
28 delta : 0 (100.00%)
29 snapshot : 3 (100.00%)
29 snapshot : 3 (100.00%)
30 lvl-0 : 3 (100.00%)
30 lvl-0 : 3 (100.00%)
31 deltas : 0 ( 0.00%)
31 deltas : 0 ( 0.00%)
32 revision size : 191
32 revision size : 191
33 snapshot : 191 (100.00%)
33 snapshot : 191 (100.00%)
34 lvl-0 : 191 (100.00%)
34 lvl-0 : 191 (100.00%)
35 deltas : 0 ( 0.00%)
35 deltas : 0 ( 0.00%)
36
36
37 chunks : 3
37 chunks : 3
38 0x75 (u) : 3 (100.00%)
38 0x75 (u) : 3 (100.00%)
39 chunks size : 191
39 chunks size : 191
40 0x75 (u) : 191 (100.00%)
40 0x75 (u) : 191 (100.00%)
41
41
42 avg chain length : 0
42 avg chain length : 0
43 max chain length : 0
43 max chain length : 0
44 max chain reach : 67
44 max chain reach : 67
45 compression ratio : 0
45 compression ratio : 0
46
46
47 uncompressed data size (min/max/avg) : 57 / 66 / 62
47 uncompressed data size (min/max/avg) : 57 / 66 / 62
48 full revision size (min/max/avg) : 58 / 67 / 63
48 full revision size (min/max/avg) : 58 / 67 / 63
49 inter-snapshot size (min/max/avg) : 0 / 0 / 0
49 inter-snapshot size (min/max/avg) : 0 / 0 / 0
50 delta size (min/max/avg) : 0 / 0 / 0
50 delta size (min/max/avg) : 0 / 0 / 0
51 $ hg debugrevlog -m
51 $ hg debugrevlog -m
52 format : 1
52 format : 1
53 flags : inline, generaldelta
53 flags : inline, generaldelta
54
54
55 revisions : 3
55 revisions : 3
56 merges : 0 ( 0.00%)
56 merges : 0 ( 0.00%)
57 normal : 3 (100.00%)
57 normal : 3 (100.00%)
58 revisions : 3
58 revisions : 3
59 empty : 1 (33.33%)
59 empty : 1 (33.33%)
60 text : 1 (100.00%)
60 text : 1 (100.00%)
61 delta : 0 ( 0.00%)
61 delta : 0 ( 0.00%)
62 snapshot : 2 (66.67%)
62 snapshot : 2 (66.67%)
63 lvl-0 : 2 (66.67%)
63 lvl-0 : 2 (66.67%)
64 deltas : 0 ( 0.00%)
64 deltas : 0 ( 0.00%)
65 revision size : 88
65 revision size : 88
66 snapshot : 88 (100.00%)
66 snapshot : 88 (100.00%)
67 lvl-0 : 88 (100.00%)
67 lvl-0 : 88 (100.00%)
68 deltas : 0 ( 0.00%)
68 deltas : 0 ( 0.00%)
69
69
70 chunks : 3
70 chunks : 3
71 empty : 1 (33.33%)
71 empty : 1 (33.33%)
72 0x75 (u) : 2 (66.67%)
72 0x75 (u) : 2 (66.67%)
73 chunks size : 88
73 chunks size : 88
74 empty : 0 ( 0.00%)
74 empty : 0 ( 0.00%)
75 0x75 (u) : 88 (100.00%)
75 0x75 (u) : 88 (100.00%)
76
76
77 avg chain length : 0
77 avg chain length : 0
78 max chain length : 0
78 max chain length : 0
79 max chain reach : 44
79 max chain reach : 44
80 compression ratio : 0
80 compression ratio : 0
81
81
82 uncompressed data size (min/max/avg) : 0 / 43 / 28
82 uncompressed data size (min/max/avg) : 0 / 43 / 28
83 full revision size (min/max/avg) : 44 / 44 / 44
83 full revision size (min/max/avg) : 44 / 44 / 44
84 inter-snapshot size (min/max/avg) : 0 / 0 / 0
84 inter-snapshot size (min/max/avg) : 0 / 0 / 0
85 delta size (min/max/avg) : 0 / 0 / 0
85 delta size (min/max/avg) : 0 / 0 / 0
86 $ hg debugrevlog a
86 $ hg debugrevlog a
87 format : 1
87 format : 1
88 flags : inline, generaldelta
88 flags : inline, generaldelta
89
89
90 revisions : 1
90 revisions : 1
91 merges : 0 ( 0.00%)
91 merges : 0 ( 0.00%)
92 normal : 1 (100.00%)
92 normal : 1 (100.00%)
93 revisions : 1
93 revisions : 1
94 empty : 0 ( 0.00%)
94 empty : 0 ( 0.00%)
95 text : 0 (100.00%)
95 text : 0 (100.00%)
96 delta : 0 (100.00%)
96 delta : 0 (100.00%)
97 snapshot : 1 (100.00%)
97 snapshot : 1 (100.00%)
98 lvl-0 : 1 (100.00%)
98 lvl-0 : 1 (100.00%)
99 deltas : 0 ( 0.00%)
99 deltas : 0 ( 0.00%)
100 revision size : 3
100 revision size : 3
101 snapshot : 3 (100.00%)
101 snapshot : 3 (100.00%)
102 lvl-0 : 3 (100.00%)
102 lvl-0 : 3 (100.00%)
103 deltas : 0 ( 0.00%)
103 deltas : 0 ( 0.00%)
104
104
105 chunks : 1
105 chunks : 1
106 0x75 (u) : 1 (100.00%)
106 0x75 (u) : 1 (100.00%)
107 chunks size : 3
107 chunks size : 3
108 0x75 (u) : 3 (100.00%)
108 0x75 (u) : 3 (100.00%)
109
109
110 avg chain length : 0
110 avg chain length : 0
111 max chain length : 0
111 max chain length : 0
112 max chain reach : 3
112 max chain reach : 3
113 compression ratio : 0
113 compression ratio : 0
114
114
115 uncompressed data size (min/max/avg) : 2 / 2 / 2
115 uncompressed data size (min/max/avg) : 2 / 2 / 2
116 full revision size (min/max/avg) : 3 / 3 / 3
116 full revision size (min/max/avg) : 3 / 3 / 3
117 inter-snapshot size (min/max/avg) : 0 / 0 / 0
117 inter-snapshot size (min/max/avg) : 0 / 0 / 0
118 delta size (min/max/avg) : 0 / 0 / 0
118 delta size (min/max/avg) : 0 / 0 / 0
119 #endif
119 #endif
120
120
121 Test debugindex, with and without the --verbose/--debug flag
121 Test debugindex, with and without the --verbose/--debug flag
122 $ hg debugrevlogindex a
122 $ hg debugrevlogindex a
123 rev linkrev nodeid p1 p2
123 rev linkrev nodeid p1 p2
124 0 0 b789fdd96dc2 000000000000 000000000000
124 0 0 b789fdd96dc2 000000000000 000000000000
125
125
126 #if no-reposimplestore
126 #if no-reposimplestore
127 $ hg --verbose debugrevlogindex a
127 $ hg --verbose debugrevlogindex a
128 rev offset length linkrev nodeid p1 p2
128 rev offset length linkrev nodeid p1 p2
129 0 0 3 0 b789fdd96dc2 000000000000 000000000000
129 0 0 3 0 b789fdd96dc2 000000000000 000000000000
130
130
131 $ hg --debug debugrevlogindex a
131 $ hg --debug debugrevlogindex a
132 rev offset length linkrev nodeid p1 p2
132 rev offset length linkrev nodeid p1 p2
133 0 0 3 0 b789fdd96dc2f3bd229c1dd8eedf0fc60e2b68e3 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000
133 0 0 3 0 b789fdd96dc2f3bd229c1dd8eedf0fc60e2b68e3 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000
134 #endif
134 #endif
135
135
136 $ hg debugrevlogindex -f 1 a
136 $ hg debugrevlogindex -f 1 a
137 rev flag size link p1 p2 nodeid
137 rev flag size link p1 p2 nodeid
138 0 0000 2 0 -1 -1 b789fdd96dc2
138 0 0000 2 0 -1 -1 b789fdd96dc2
139
139
140 #if no-reposimplestore
140 #if no-reposimplestore
141 $ hg --verbose debugrevlogindex -f 1 a
141 $ hg --verbose debugrevlogindex -f 1 a
142 rev flag offset length size link p1 p2 nodeid
142 rev flag offset length size link p1 p2 nodeid
143 0 0000 0 3 2 0 -1 -1 b789fdd96dc2
143 0 0000 0 3 2 0 -1 -1 b789fdd96dc2
144
144
145 $ hg --debug debugrevlogindex -f 1 a
145 $ hg --debug debugrevlogindex -f 1 a
146 rev flag offset length size link p1 p2 nodeid
146 rev flag offset length size link p1 p2 nodeid
147 0 0000 0 3 2 0 -1 -1 b789fdd96dc2f3bd229c1dd8eedf0fc60e2b68e3
147 0 0000 0 3 2 0 -1 -1 b789fdd96dc2f3bd229c1dd8eedf0fc60e2b68e3
148 #endif
148 #endif
149
149
150 $ hg debugindex -c
150 $ hg debugindex -c
151 rev linkrev nodeid p1 p2
151 rev linkrev nodeid p1 p2
152 0 0 07f494440405 000000000000 000000000000
152 0 0 07f494440405 000000000000 000000000000
153 1 1 8cccb4b5fec2 07f494440405 000000000000
153 1 1 8cccb4b5fec2 07f494440405 000000000000
154 2 2 b1e228c512c5 8cccb4b5fec2 000000000000
154 2 2 b1e228c512c5 8cccb4b5fec2 000000000000
155 $ hg debugindex -c --debug
155 $ hg debugindex -c --debug
156 rev linkrev nodeid p1 p2
156 rev linkrev nodeid p1 p2
157 0 0 07f4944404050f47db2e5c5071e0e84e7a27bba9 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000
157 0 0 07f4944404050f47db2e5c5071e0e84e7a27bba9 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000
158 1 1 8cccb4b5fec20cafeb99dd01c26d4dee8ea4388a 07f4944404050f47db2e5c5071e0e84e7a27bba9 0000000000000000000000000000000000000000
158 1 1 8cccb4b5fec20cafeb99dd01c26d4dee8ea4388a 07f4944404050f47db2e5c5071e0e84e7a27bba9 0000000000000000000000000000000000000000
159 2 2 b1e228c512c5d7066d70562ed839c3323a62d6d2 8cccb4b5fec20cafeb99dd01c26d4dee8ea4388a 0000000000000000000000000000000000000000
159 2 2 b1e228c512c5d7066d70562ed839c3323a62d6d2 8cccb4b5fec20cafeb99dd01c26d4dee8ea4388a 0000000000000000000000000000000000000000
160 $ hg debugindex -m
160 $ hg debugindex -m
161 rev linkrev nodeid p1 p2
161 rev linkrev nodeid p1 p2
162 0 0 a0c8bcbbb45c 000000000000 000000000000
162 0 0 a0c8bcbbb45c 000000000000 000000000000
163 1 1 57faf8a737ae a0c8bcbbb45c 000000000000
163 1 1 57faf8a737ae a0c8bcbbb45c 000000000000
164 2 2 a35b10320954 57faf8a737ae 000000000000
164 2 2 a35b10320954 57faf8a737ae 000000000000
165 $ hg debugindex -m --debug
165 $ hg debugindex -m --debug
166 rev linkrev nodeid p1 p2
166 rev linkrev nodeid p1 p2
167 0 0 a0c8bcbbb45c63b90b70ad007bf38961f64f2af0 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000
167 0 0 a0c8bcbbb45c63b90b70ad007bf38961f64f2af0 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000
168 1 1 57faf8a737ae7faf490582941a82319ba6529dca a0c8bcbbb45c63b90b70ad007bf38961f64f2af0 0000000000000000000000000000000000000000
168 1 1 57faf8a737ae7faf490582941a82319ba6529dca a0c8bcbbb45c63b90b70ad007bf38961f64f2af0 0000000000000000000000000000000000000000
169 2 2 a35b103209548032201c16c7688cb2657f037a38 57faf8a737ae7faf490582941a82319ba6529dca 0000000000000000000000000000000000000000
169 2 2 a35b103209548032201c16c7688cb2657f037a38 57faf8a737ae7faf490582941a82319ba6529dca 0000000000000000000000000000000000000000
170 $ hg debugindex a
170 $ hg debugindex a
171 rev linkrev nodeid p1 p2
171 rev linkrev nodeid p1 p2
172 0 0 b789fdd96dc2 000000000000 000000000000
172 0 0 b789fdd96dc2 000000000000 000000000000
173 $ hg debugindex --debug a
173 $ hg debugindex --debug a
174 rev linkrev nodeid p1 p2
174 rev linkrev nodeid p1 p2
175 0 0 b789fdd96dc2f3bd229c1dd8eedf0fc60e2b68e3 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000
175 0 0 b789fdd96dc2f3bd229c1dd8eedf0fc60e2b68e3 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000
176
176
177 debugdelta chain basic output
177 debugdelta chain basic output
178
178
179 #if reporevlogstore pure
179 #if reporevlogstore pure
180 $ hg debugindexstats
180 $ hg debugindexstats
181 abort: debugindexstats only works with native code
181 abort: debugindexstats only works with native code
182 [255]
182 [255]
183 #endif
183 #endif
184 #if reporevlogstore no-pure
184 #if reporevlogstore no-pure
185 $ hg debugindexstats
185 $ hg debugindexstats
186 node trie capacity: 4
186 node trie capacity: 4
187 node trie count: 2
187 node trie count: 2
188 node trie depth: 1
188 node trie depth: 1
189 node trie last rev scanned: -1
189 node trie last rev scanned: -1
190 node trie lookups: 4
190 node trie lookups: 4
191 node trie misses: 1
191 node trie misses: 1
192 node trie splits: 1
192 node trie splits: 1
193 revs in memory: 3
193 revs in memory: 3
194 #endif
194 #endif
195
195
196 #if reporevlogstore no-pure
196 #if reporevlogstore no-pure
197 $ hg debugdeltachain -m
197 $ hg debugdeltachain -m
198 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio readsize largestblk rddensity srchunks
198 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio readsize largestblk rddensity srchunks
199 0 1 1 -1 base 44 43 44 1.02326 44 0 0.00000 44 44 1.00000 1
199 0 1 1 -1 base 44 43 44 1.02326 44 0 0.00000 44 44 1.00000 1
200 1 2 1 -1 base 0 0 0 0.00000 0 0 0.00000 0 0 1.00000 1
200 1 2 1 -1 base 0 0 0 0.00000 0 0 0.00000 0 0 1.00000 1
201 2 3 1 -1 base 44 43 44 1.02326 44 0 0.00000 44 44 1.00000 1
201 2 3 1 -1 base 44 43 44 1.02326 44 0 0.00000 44 44 1.00000 1
202
202
203 $ hg debugdeltachain -m -T '{rev} {chainid} {chainlen}\n'
203 $ hg debugdeltachain -m -T '{rev} {chainid} {chainlen}\n'
204 0 1 1
204 0 1 1
205 1 2 1
205 1 2 1
206 2 3 1
206 2 3 1
207
207
208 $ hg debugdeltachain -m -Tjson
208 $ hg debugdeltachain -m -Tjson
209 [
209 [
210 {
210 {
211 "chainid": 1,
211 "chainid": 1,
212 "chainlen": 1,
212 "chainlen": 1,
213 "chainratio": 1.02325581395, (no-py3 !)
213 "chainratio": 1.02325581395, (no-py3 !)
214 "chainratio": 1.0232558139534884, (py3 !)
214 "chainratio": 1.0232558139534884, (py3 !)
215 "chainsize": 44,
215 "chainsize": 44,
216 "compsize": 44,
216 "compsize": 44,
217 "deltatype": "base",
217 "deltatype": "base",
218 "extradist": 0,
218 "extradist": 0,
219 "extraratio": 0.0,
219 "extraratio": 0.0,
220 "largestblock": 44,
220 "largestblock": 44,
221 "lindist": 44,
221 "lindist": 44,
222 "prevrev": -1,
222 "prevrev": -1,
223 "readdensity": 1.0,
223 "readdensity": 1.0,
224 "readsize": 44,
224 "readsize": 44,
225 "rev": 0,
225 "rev": 0,
226 "srchunks": 1,
226 "srchunks": 1,
227 "uncompsize": 43
227 "uncompsize": 43
228 },
228 },
229 {
229 {
230 "chainid": 2,
230 "chainid": 2,
231 "chainlen": 1,
231 "chainlen": 1,
232 "chainratio": 0,
232 "chainratio": 0,
233 "chainsize": 0,
233 "chainsize": 0,
234 "compsize": 0,
234 "compsize": 0,
235 "deltatype": "base",
235 "deltatype": "base",
236 "extradist": 0,
236 "extradist": 0,
237 "extraratio": 0,
237 "extraratio": 0,
238 "largestblock": 0,
238 "largestblock": 0,
239 "lindist": 0,
239 "lindist": 0,
240 "prevrev": -1,
240 "prevrev": -1,
241 "readdensity": 1,
241 "readdensity": 1,
242 "readsize": 0,
242 "readsize": 0,
243 "rev": 1,
243 "rev": 1,
244 "srchunks": 1,
244 "srchunks": 1,
245 "uncompsize": 0
245 "uncompsize": 0
246 },
246 },
247 {
247 {
248 "chainid": 3,
248 "chainid": 3,
249 "chainlen": 1,
249 "chainlen": 1,
250 "chainratio": 1.02325581395, (no-py3 !)
250 "chainratio": 1.02325581395, (no-py3 !)
251 "chainratio": 1.0232558139534884, (py3 !)
251 "chainratio": 1.0232558139534884, (py3 !)
252 "chainsize": 44,
252 "chainsize": 44,
253 "compsize": 44,
253 "compsize": 44,
254 "deltatype": "base",
254 "deltatype": "base",
255 "extradist": 0,
255 "extradist": 0,
256 "extraratio": 0.0,
256 "extraratio": 0.0,
257 "largestblock": 44,
257 "largestblock": 44,
258 "lindist": 44,
258 "lindist": 44,
259 "prevrev": -1,
259 "prevrev": -1,
260 "readdensity": 1.0,
260 "readdensity": 1.0,
261 "readsize": 44,
261 "readsize": 44,
262 "rev": 2,
262 "rev": 2,
263 "srchunks": 1,
263 "srchunks": 1,
264 "uncompsize": 43
264 "uncompsize": 43
265 }
265 }
266 ]
266 ]
267
267
268 debugdelta chain with sparse read enabled
268 debugdelta chain with sparse read enabled
269
269
270 $ cat >> $HGRCPATH <<EOF
270 $ cat >> $HGRCPATH <<EOF
271 > [experimental]
271 > [experimental]
272 > sparse-read = True
272 > sparse-read = True
273 > EOF
273 > EOF
274 $ hg debugdeltachain -m
274 $ hg debugdeltachain -m
275 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio readsize largestblk rddensity srchunks
275 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio readsize largestblk rddensity srchunks
276 0 1 1 -1 base 44 43 44 1.02326 44 0 0.00000 44 44 1.00000 1
276 0 1 1 -1 base 44 43 44 1.02326 44 0 0.00000 44 44 1.00000 1
277 1 2 1 -1 base 0 0 0 0.00000 0 0 0.00000 0 0 1.00000 1
277 1 2 1 -1 base 0 0 0 0.00000 0 0 0.00000 0 0 1.00000 1
278 2 3 1 -1 base 44 43 44 1.02326 44 0 0.00000 44 44 1.00000 1
278 2 3 1 -1 base 44 43 44 1.02326 44 0 0.00000 44 44 1.00000 1
279
279
280 $ hg debugdeltachain -m -T '{rev} {chainid} {chainlen} {readsize} {largestblock} {readdensity}\n'
280 $ hg debugdeltachain -m -T '{rev} {chainid} {chainlen} {readsize} {largestblock} {readdensity}\n'
281 0 1 1 44 44 1.0
281 0 1 1 44 44 1.0
282 1 2 1 0 0 1
282 1 2 1 0 0 1
283 2 3 1 44 44 1.0
283 2 3 1 44 44 1.0
284
284
285 $ hg debugdeltachain -m -Tjson
285 $ hg debugdeltachain -m -Tjson
286 [
286 [
287 {
287 {
288 "chainid": 1,
288 "chainid": 1,
289 "chainlen": 1,
289 "chainlen": 1,
290 "chainratio": 1.02325581395, (no-py3 !)
290 "chainratio": 1.02325581395, (no-py3 !)
291 "chainratio": 1.0232558139534884, (py3 !)
291 "chainratio": 1.0232558139534884, (py3 !)
292 "chainsize": 44,
292 "chainsize": 44,
293 "compsize": 44,
293 "compsize": 44,
294 "deltatype": "base",
294 "deltatype": "base",
295 "extradist": 0,
295 "extradist": 0,
296 "extraratio": 0.0,
296 "extraratio": 0.0,
297 "largestblock": 44,
297 "largestblock": 44,
298 "lindist": 44,
298 "lindist": 44,
299 "prevrev": -1,
299 "prevrev": -1,
300 "readdensity": 1.0,
300 "readdensity": 1.0,
301 "readsize": 44,
301 "readsize": 44,
302 "rev": 0,
302 "rev": 0,
303 "srchunks": 1,
303 "srchunks": 1,
304 "uncompsize": 43
304 "uncompsize": 43
305 },
305 },
306 {
306 {
307 "chainid": 2,
307 "chainid": 2,
308 "chainlen": 1,
308 "chainlen": 1,
309 "chainratio": 0,
309 "chainratio": 0,
310 "chainsize": 0,
310 "chainsize": 0,
311 "compsize": 0,
311 "compsize": 0,
312 "deltatype": "base",
312 "deltatype": "base",
313 "extradist": 0,
313 "extradist": 0,
314 "extraratio": 0,
314 "extraratio": 0,
315 "largestblock": 0,
315 "largestblock": 0,
316 "lindist": 0,
316 "lindist": 0,
317 "prevrev": -1,
317 "prevrev": -1,
318 "readdensity": 1,
318 "readdensity": 1,
319 "readsize": 0,
319 "readsize": 0,
320 "rev": 1,
320 "rev": 1,
321 "srchunks": 1,
321 "srchunks": 1,
322 "uncompsize": 0
322 "uncompsize": 0
323 },
323 },
324 {
324 {
325 "chainid": 3,
325 "chainid": 3,
326 "chainlen": 1,
326 "chainlen": 1,
327 "chainratio": 1.02325581395, (no-py3 !)
327 "chainratio": 1.02325581395, (no-py3 !)
328 "chainratio": 1.0232558139534884, (py3 !)
328 "chainratio": 1.0232558139534884, (py3 !)
329 "chainsize": 44,
329 "chainsize": 44,
330 "compsize": 44,
330 "compsize": 44,
331 "deltatype": "base",
331 "deltatype": "base",
332 "extradist": 0,
332 "extradist": 0,
333 "extraratio": 0.0,
333 "extraratio": 0.0,
334 "largestblock": 44,
334 "largestblock": 44,
335 "lindist": 44,
335 "lindist": 44,
336 "prevrev": -1,
336 "prevrev": -1,
337 "readdensity": 1.0,
337 "readdensity": 1.0,
338 "readsize": 44,
338 "readsize": 44,
339 "rev": 2,
339 "rev": 2,
340 "srchunks": 1,
340 "srchunks": 1,
341 "uncompsize": 43
341 "uncompsize": 43
342 }
342 }
343 ]
343 ]
344
344
345 $ printf "This test checks things.\n" >> a
345 $ printf "This test checks things.\n" >> a
346 $ hg ci -m a
346 $ hg ci -m a
347 $ hg branch other
347 $ hg branch other
348 marked working directory as branch other
348 marked working directory as branch other
349 (branches are permanent and global, did you want a bookmark?)
349 (branches are permanent and global, did you want a bookmark?)
350 $ for i in `$TESTDIR/seq.py 5`; do
350 $ for i in `$TESTDIR/seq.py 5`; do
351 > printf "shorter ${i}" >> a
351 > printf "shorter ${i}" >> a
352 > hg ci -m "a other:$i"
352 > hg ci -m "a other:$i"
353 > hg up -q default
353 > hg up -q default
354 > printf "for the branch default we want longer chains: ${i}" >> a
354 > printf "for the branch default we want longer chains: ${i}" >> a
355 > hg ci -m "a default:$i"
355 > hg ci -m "a default:$i"
356 > hg up -q other
356 > hg up -q other
357 > done
357 > done
358 $ hg debugdeltachain a -T '{rev} {srchunks}\n' \
358 $ hg debugdeltachain a -T '{rev} {srchunks}\n' \
359 > --config experimental.sparse-read.density-threshold=0.50 \
359 > --config experimental.sparse-read.density-threshold=0.50 \
360 > --config experimental.sparse-read.min-gap-size=0
360 > --config experimental.sparse-read.min-gap-size=0
361 0 1
361 0 1
362 1 1
362 1 1
363 2 1
363 2 1
364 3 1
364 3 1
365 4 1
365 4 1
366 5 1
366 5 1
367 6 1
367 6 1
368 7 1
368 7 1
369 8 1
369 8 1
370 9 1
370 9 1
371 10 2
371 10 2
372 11 1
372 11 1
373 $ hg --config extensions.strip= strip --no-backup -r 1
373 $ hg --config extensions.strip= strip --no-backup -r 1
374 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
374 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
375
375
376 Test max chain len
376 Test max chain len
377 $ cat >> $HGRCPATH << EOF
377 $ cat >> $HGRCPATH << EOF
378 > [format]
378 > [format]
379 > maxchainlen=4
379 > maxchainlen=4
380 > EOF
380 > EOF
381
381
382 $ printf "This test checks if maxchainlen config value is respected also it can serve as basic test for debugrevlog -d <file>.\n" >> a
382 $ printf "This test checks if maxchainlen config value is respected also it can serve as basic test for debugrevlog -d <file>.\n" >> a
383 $ hg ci -m a
383 $ hg ci -m a
384 $ printf "b\n" >> a
384 $ printf "b\n" >> a
385 $ hg ci -m a
385 $ hg ci -m a
386 $ printf "c\n" >> a
386 $ printf "c\n" >> a
387 $ hg ci -m a
387 $ hg ci -m a
388 $ printf "d\n" >> a
388 $ printf "d\n" >> a
389 $ hg ci -m a
389 $ hg ci -m a
390 $ printf "e\n" >> a
390 $ printf "e\n" >> a
391 $ hg ci -m a
391 $ hg ci -m a
392 $ printf "f\n" >> a
392 $ printf "f\n" >> a
393 $ hg ci -m a
393 $ hg ci -m a
394 $ printf 'g\n' >> a
394 $ printf 'g\n' >> a
395 $ hg ci -m a
395 $ hg ci -m a
396 $ printf 'h\n' >> a
396 $ printf 'h\n' >> a
397 $ hg ci -m a
397 $ hg ci -m a
398
398
399 $ hg debugrevlog -d a
399 $ hg debugrevlog -d a
400 # rev p1rev p2rev start end deltastart base p1 p2 rawsize totalsize compression heads chainlen
400 # rev p1rev p2rev start end deltastart base p1 p2 rawsize totalsize compression heads chainlen
401 0 -1 -1 0 ??? 0 0 0 0 ??? ???? ? 1 0 (glob)
401 0 -1 -1 0 ??? 0 0 0 0 ??? ???? ? 1 0 (glob)
402 1 0 -1 ??? ??? 0 0 0 0 ??? ???? ? 1 1 (glob)
402 1 0 -1 ??? ??? 0 0 0 0 ??? ???? ? 1 1 (glob)
403 2 1 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 2 (glob)
403 2 1 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 2 (glob)
404 3 2 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 3 (glob)
404 3 2 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 3 (glob)
405 4 3 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 4 (glob)
405 4 3 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 4 (glob)
406 5 4 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 0 (glob)
406 5 4 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 0 (glob)
407 6 5 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 1 (glob)
407 6 5 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 1 (glob)
408 7 6 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 2 (glob)
408 7 6 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 2 (glob)
409 8 7 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 3 (glob)
409 8 7 -1 ??? ??? ??? ??? ??? 0 ??? ???? ? 1 3 (glob)
410 #endif
410 #endif
411
411
412 Test debuglocks command:
412 Test debuglocks command:
413
413
414 $ hg debuglocks
414 $ hg debuglocks
415 lock: free
415 lock: free
416 wlock: free
416 wlock: free
417
417
418 * Test setting the lock
418 * Test setting the lock
419
419
420 waitlock <file> will wait for file to be created. If it isn't in a reasonable
420 waitlock <file> will wait for file to be created. If it isn't in a reasonable
421 amount of time, displays error message and returns 1
421 amount of time, displays error message and returns 1
422 $ waitlock() {
422 $ waitlock() {
423 > start=`date +%s`
423 > start=`date +%s`
424 > timeout=5
424 > timeout=5
425 > while [ \( ! -f $1 \) -a \( ! -L $1 \) ]; do
425 > while [ \( ! -f $1 \) -a \( ! -L $1 \) ]; do
426 > now=`date +%s`
426 > now=`date +%s`
427 > if [ "`expr $now - $start`" -gt $timeout ]; then
427 > if [ "`expr $now - $start`" -gt $timeout ]; then
428 > echo "timeout: $1 was not created in $timeout seconds"
428 > echo "timeout: $1 was not created in $timeout seconds"
429 > return 1
429 > return 1
430 > fi
430 > fi
431 > sleep 0.1
431 > sleep 0.1
432 > done
432 > done
433 > }
433 > }
434 $ dolock() {
434 $ dolock() {
435 > {
435 > {
436 > waitlock .hg/unlock
436 > waitlock .hg/unlock
437 > rm -f .hg/unlock
437 > rm -f .hg/unlock
438 > echo y
438 > echo y
439 > } | hg debuglocks "$@" > /dev/null
439 > } | hg debuglocks "$@" > /dev/null
440 > }
440 > }
441 $ dolock -s &
441 $ dolock -s &
442 $ waitlock .hg/store/lock
442 $ waitlock .hg/store/lock
443
443
444 $ hg debuglocks
444 $ hg debuglocks
445 lock: user *, process * (*s) (glob)
445 lock: user *, process * (*s) (glob)
446 wlock: free
446 wlock: free
447 [1]
447 [1]
448 $ touch .hg/unlock
448 $ touch .hg/unlock
449 $ wait
449 $ wait
450 $ [ -f .hg/store/lock ] || echo "There is no lock"
450 $ [ -f .hg/store/lock ] || echo "There is no lock"
451 There is no lock
451 There is no lock
452
452
453 * Test setting the wlock
453 * Test setting the wlock
454
454
455 $ dolock -S &
455 $ dolock -S &
456 $ waitlock .hg/wlock
456 $ waitlock .hg/wlock
457
457
458 $ hg debuglocks
458 $ hg debuglocks
459 lock: free
459 lock: free
460 wlock: user *, process * (*s) (glob)
460 wlock: user *, process * (*s) (glob)
461 [1]
461 [1]
462 $ touch .hg/unlock
462 $ touch .hg/unlock
463 $ wait
463 $ wait
464 $ [ -f .hg/wlock ] || echo "There is no wlock"
464 $ [ -f .hg/wlock ] || echo "There is no wlock"
465 There is no wlock
465 There is no wlock
466
466
467 * Test setting both locks
467 * Test setting both locks
468
468
469 $ dolock -Ss &
469 $ dolock -Ss &
470 $ waitlock .hg/wlock && waitlock .hg/store/lock
470 $ waitlock .hg/wlock && waitlock .hg/store/lock
471
471
472 $ hg debuglocks
472 $ hg debuglocks
473 lock: user *, process * (*s) (glob)
473 lock: user *, process * (*s) (glob)
474 wlock: user *, process * (*s) (glob)
474 wlock: user *, process * (*s) (glob)
475 [2]
475 [2]
476
476
477 * Test failing to set a lock
477 * Test failing to set a lock
478
478
479 $ hg debuglocks -s
479 $ hg debuglocks -s
480 abort: lock is already held
480 abort: lock is already held
481 [255]
481 [255]
482
482
483 $ hg debuglocks -S
483 $ hg debuglocks -S
484 abort: wlock is already held
484 abort: wlock is already held
485 [255]
485 [255]
486
486
487 $ touch .hg/unlock
487 $ touch .hg/unlock
488 $ wait
488 $ wait
489
489
490 $ hg debuglocks
490 $ hg debuglocks
491 lock: free
491 lock: free
492 wlock: free
492 wlock: free
493
493
494 * Test forcing the lock
494 * Test forcing the lock
495
495
496 $ dolock -s &
496 $ dolock -s &
497 $ waitlock .hg/store/lock
497 $ waitlock .hg/store/lock
498
498
499 $ hg debuglocks
499 $ hg debuglocks
500 lock: user *, process * (*s) (glob)
500 lock: user *, process * (*s) (glob)
501 wlock: free
501 wlock: free
502 [1]
502 [1]
503
503
504 $ hg debuglocks -L
504 $ hg debuglocks -L
505
505
506 $ hg debuglocks
506 $ hg debuglocks
507 lock: free
507 lock: free
508 wlock: free
508 wlock: free
509
509
510 $ touch .hg/unlock
510 $ touch .hg/unlock
511 $ wait
511 $ wait
512
512
513 * Test forcing the wlock
513 * Test forcing the wlock
514
514
515 $ dolock -S &
515 $ dolock -S &
516 $ waitlock .hg/wlock
516 $ waitlock .hg/wlock
517
517
518 $ hg debuglocks
518 $ hg debuglocks
519 lock: free
519 lock: free
520 wlock: user *, process * (*s) (glob)
520 wlock: user *, process * (*s) (glob)
521 [1]
521 [1]
522
522
523 $ hg debuglocks -W
523 $ hg debuglocks -W
524
524
525 $ hg debuglocks
525 $ hg debuglocks
526 lock: free
526 lock: free
527 wlock: free
527 wlock: free
528
528
529 $ touch .hg/unlock
529 $ touch .hg/unlock
530 $ wait
530 $ wait
531
531
532 Test WdirUnsupported exception
532 Test WdirUnsupported exception
533
533
534 $ hg debugdata -c ffffffffffffffffffffffffffffffffffffffff
534 $ hg debugdata -c ffffffffffffffffffffffffffffffffffffffff
535 abort: working directory revision cannot be specified
535 abort: working directory revision cannot be specified
536 [255]
536 [255]
537
537
538 Test cache warming command
538 Test cache warming command
539
539
540 $ rm -rf .hg/cache/
540 $ rm -rf .hg/cache/
541 $ hg debugupdatecaches --debug
541 $ hg debugupdatecaches --debug
542 updating the branch cache
542 updating the branch cache
543 $ ls -r .hg/cache/*
543 $ ls -r .hg/cache/*
544 .hg/cache/tags2-served
544 .hg/cache/tags2-served
545 .hg/cache/tags2
545 .hg/cache/tags2
546 .hg/cache/rbc-revs-v1
546 .hg/cache/rbc-revs-v1
547 .hg/cache/rbc-names-v1
547 .hg/cache/rbc-names-v1
548 .hg/cache/hgtagsfnodes1
548 .hg/cache/hgtagsfnodes1
549 .hg/cache/branch2-visible-hidden
549 .hg/cache/branch2-visible-hidden
550 .hg/cache/branch2-visible
550 .hg/cache/branch2-visible
551 .hg/cache/branch2-served.hidden
551 .hg/cache/branch2-served.hidden
552 .hg/cache/branch2-served
552 .hg/cache/branch2-served
553 .hg/cache/branch2-immutable
553 .hg/cache/branch2-immutable
554 .hg/cache/branch2-base
554 .hg/cache/branch2-base
555
555
556 Test debugcolor
556 Test debugcolor
557
557
558 #if no-windows
558 #if no-windows
559 $ hg debugcolor --style --color always | egrep 'mode|style|log\.'
559 $ hg debugcolor --style --color always | egrep 'mode|style|log\.'
560 color mode: 'ansi'
560 color mode: 'ansi'
561 available style:
561 available style:
562 \x1b[0;33mlog.changeset\x1b[0m: \x1b[0;33myellow\x1b[0m (esc)
562 \x1b[0;33mlog.changeset\x1b[0m: \x1b[0;33myellow\x1b[0m (esc)
563 #endif
563 #endif
564
564
565 $ hg debugcolor --style --color never
565 $ hg debugcolor --style --color never
566 color mode: None
566 color mode: None
567 available style:
567 available style:
568
568
569 $ cd ..
569 $ cd ..
570
570
571 Test internal debugstacktrace command
571 Test internal debugstacktrace command
572
572
573 $ cat > debugstacktrace.py << EOF
573 $ cat > debugstacktrace.py << EOF
574 > from __future__ import absolute_import
574 > from __future__ import absolute_import
575 > from mercurial import (
575 > from mercurial import (
576 > util,
576 > util,
577 > )
577 > )
578 > from mercurial.utils import (
578 > from mercurial.utils import (
579 > procutil,
579 > procutil,
580 > )
580 > )
581 > def f():
581 > def f():
582 > util.debugstacktrace(f=procutil.stdout)
582 > util.debugstacktrace(f=procutil.stdout)
583 > g()
583 > g()
584 > def g():
584 > def g():
585 > util.dst(b'hello from g\\n', skip=1)
585 > util.dst(b'hello from g\\n', skip=1)
586 > h()
586 > h()
587 > def h():
587 > def h():
588 > util.dst(b'hi ...\\nfrom h hidden in g', 1, depth=2)
588 > util.dst(b'hi ...\\nfrom h hidden in g', 1, depth=2)
589 > f()
589 > f()
590 > EOF
590 > EOF
591 $ "$PYTHON" debugstacktrace.py
591 $ "$PYTHON" debugstacktrace.py
592 stacktrace at:
592 stacktrace at:
593 *debugstacktrace.py:16 in * (glob)
593 *debugstacktrace.py:16 in * (glob)
594 *debugstacktrace.py:9 in f (glob)
594 *debugstacktrace.py:9 in f (glob)
595 hello from g at:
595 hello from g at:
596 *debugstacktrace.py:16 in * (glob)
596 *debugstacktrace.py:16 in * (glob)
597 *debugstacktrace.py:10 in f (glob)
597 *debugstacktrace.py:10 in f (glob)
598 hi ...
598 hi ...
599 from h hidden in g at:
599 from h hidden in g at:
600 *debugstacktrace.py:10 in f (glob)
600 *debugstacktrace.py:10 in f (glob)
601 *debugstacktrace.py:13 in g (glob)
601 *debugstacktrace.py:13 in g (glob)
602
602
603 Test debugcapabilities command:
603 Test debugcapabilities command:
604
604
605 $ hg debugcapabilities ./debugrevlog/
605 $ hg debugcapabilities ./debugrevlog/
606 Main capabilities:
606 Main capabilities:
607 branchmap
607 branchmap
608 $USUAL_BUNDLE2_CAPS$
608 $USUAL_BUNDLE2_CAPS$
609 getbundle
609 getbundle
610 known
610 known
611 lookup
611 lookup
612 pushkey
612 pushkey
613 unbundle
613 unbundle
614 Bundle2 capabilities:
614 Bundle2 capabilities:
615 HG20
615 HG20
616 bookmarks
616 bookmarks
617 changegroup
617 changegroup
618 01
618 01
619 02
619 02
620 checkheads
620 checkheads
621 related
621 related
622 digests
622 digests
623 md5
623 md5
624 sha1
624 sha1
625 sha512
625 sha512
626 error
626 error
627 abort
627 abort
628 unsupportedcontent
628 unsupportedcontent
629 pushraced
629 pushraced
630 pushkey
630 pushkey
631 hgtagsfnodes
631 hgtagsfnodes
632 listkeys
632 listkeys
633 phases
633 phases
634 heads
634 heads
635 pushkey
635 pushkey
636 remote-changegroup
636 remote-changegroup
637 http
637 http
638 https
638 https
639 rev-branch-cache
640 stream
639 stream
641 v2
640 v2
642
641
643 Test debugpeer
642 Test debugpeer
644
643
645 $ hg --config ui.ssh="\"$PYTHON\" \"$TESTDIR/dummyssh\"" debugpeer ssh://user@dummy/debugrevlog
644 $ hg --config ui.ssh="\"$PYTHON\" \"$TESTDIR/dummyssh\"" debugpeer ssh://user@dummy/debugrevlog
646 url: ssh://user@dummy/debugrevlog
645 url: ssh://user@dummy/debugrevlog
647 local: no
646 local: no
648 pushable: yes
647 pushable: yes
649
648
650 $ hg --config ui.ssh="\"$PYTHON\" \"$TESTDIR/dummyssh\"" --debug debugpeer ssh://user@dummy/debugrevlog
649 $ hg --config ui.ssh="\"$PYTHON\" \"$TESTDIR/dummyssh\"" --debug debugpeer ssh://user@dummy/debugrevlog
651 running "*" "*/tests/dummyssh" 'user@dummy' 'hg -R debugrevlog serve --stdio' (glob) (no-windows !)
650 running "*" "*/tests/dummyssh" 'user@dummy' 'hg -R debugrevlog serve --stdio' (glob) (no-windows !)
652 running "*" "*\tests/dummyssh" "user@dummy" "hg -R debugrevlog serve --stdio" (glob) (windows !)
651 running "*" "*\tests/dummyssh" "user@dummy" "hg -R debugrevlog serve --stdio" (glob) (windows !)
653 devel-peer-request: hello+between
652 devel-peer-request: hello+between
654 devel-peer-request: pairs: 81 bytes
653 devel-peer-request: pairs: 81 bytes
655 sending hello command
654 sending hello command
656 sending between command
655 sending between command
657 remote: 463
656 remote: 444
658 remote: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
657 remote: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
659 remote: 1
658 remote: 1
660 devel-peer-request: protocaps
659 devel-peer-request: protocaps
661 devel-peer-request: caps: * bytes (glob)
660 devel-peer-request: caps: * bytes (glob)
662 sending protocaps command
661 sending protocaps command
663 url: ssh://user@dummy/debugrevlog
662 url: ssh://user@dummy/debugrevlog
664 local: no
663 local: no
665 pushable: yes
664 pushable: yes
@@ -1,1306 +1,1285 b''
1 #require serve zstd
1 #require serve zstd
2
2
3 Client version is embedded in HTTP request and is effectively dynamic. Pin the
3 Client version is embedded in HTTP request and is effectively dynamic. Pin the
4 version so behavior is deterministic.
4 version so behavior is deterministic.
5
5
6 $ cat > fakeversion.py << EOF
6 $ cat > fakeversion.py << EOF
7 > from mercurial import util
7 > from mercurial import util
8 > util.version = lambda: b'4.2'
8 > util.version = lambda: b'4.2'
9 > EOF
9 > EOF
10
10
11 $ cat >> $HGRCPATH << EOF
11 $ cat >> $HGRCPATH << EOF
12 > [extensions]
12 > [extensions]
13 > fakeversion = `pwd`/fakeversion.py
13 > fakeversion = `pwd`/fakeversion.py
14 > [format]
14 > [format]
15 > sparse-revlog = no
15 > sparse-revlog = no
16 > [devel]
16 > [devel]
17 > legacy.exchange = phases
17 > legacy.exchange = phases
18 > [server]
18 > [server]
19 > concurrent-push-mode = strict
19 > concurrent-push-mode = strict
20 > EOF
20 > EOF
21
21
22 $ hg init server0
22 $ hg init server0
23 $ cd server0
23 $ cd server0
24 $ touch foo
24 $ touch foo
25 $ hg -q commit -A -m initial
25 $ hg -q commit -A -m initial
26
26
27 Also disable compression because zstd is optional and causes output to vary
27 Also disable compression because zstd is optional and causes output to vary
28 and because debugging partial responses is hard when compression is involved
28 and because debugging partial responses is hard when compression is involved
29
29
30 $ cat > .hg/hgrc << EOF
30 $ cat > .hg/hgrc << EOF
31 > [extensions]
31 > [extensions]
32 > badserver = $TESTDIR/badserverext.py
32 > badserver = $TESTDIR/badserverext.py
33 > [server]
33 > [server]
34 > compressionengines = none
34 > compressionengines = none
35 > EOF
35 > EOF
36
36
37 Failure to accept() socket should result in connection related error message
37 Failure to accept() socket should result in connection related error message
38
38
39 $ hg serve --config badserver.closebeforeaccept=true -p $HGPORT -d --pid-file=hg.pid
39 $ hg serve --config badserver.closebeforeaccept=true -p $HGPORT -d --pid-file=hg.pid
40 $ cat hg.pid > $DAEMON_PIDS
40 $ cat hg.pid > $DAEMON_PIDS
41
41
42 $ hg clone http://localhost:$HGPORT/ clone
42 $ hg clone http://localhost:$HGPORT/ clone
43 abort: error: (\$ECONNRESET\$|\$EADDRNOTAVAIL\$) (re)
43 abort: error: (\$ECONNRESET\$|\$EADDRNOTAVAIL\$) (re)
44 [100]
44 [100]
45
45
46 (The server exits on its own, but there is a race between that and starting a new server.
46 (The server exits on its own, but there is a race between that and starting a new server.
47 So ensure the process is dead.)
47 So ensure the process is dead.)
48
48
49 $ killdaemons.py $DAEMON_PIDS
49 $ killdaemons.py $DAEMON_PIDS
50
50
51 Failure immediately after accept() should yield connection related error message
51 Failure immediately after accept() should yield connection related error message
52
52
53 $ hg serve --config badserver.closeafteraccept=true -p $HGPORT -d --pid-file=hg.pid
53 $ hg serve --config badserver.closeafteraccept=true -p $HGPORT -d --pid-file=hg.pid
54 $ cat hg.pid > $DAEMON_PIDS
54 $ cat hg.pid > $DAEMON_PIDS
55
55
56 TODO: this usually outputs good results, but sometimes emits abort:
56 TODO: this usually outputs good results, but sometimes emits abort:
57 error: '' on FreeBSD and OS X.
57 error: '' on FreeBSD and OS X.
58 What we ideally want are:
58 What we ideally want are:
59
59
60 abort: error: $ECONNRESET$
60 abort: error: $ECONNRESET$
61
61
62 The flakiness in this output was observable easily with
62 The flakiness in this output was observable easily with
63 --runs-per-test=20 on macOS 10.12 during the freeze for 4.2.
63 --runs-per-test=20 on macOS 10.12 during the freeze for 4.2.
64 $ hg clone http://localhost:$HGPORT/ clone
64 $ hg clone http://localhost:$HGPORT/ clone
65 abort: error: * (glob)
65 abort: error: * (glob)
66 [100]
66 [100]
67
67
68 $ killdaemons.py $DAEMON_PIDS
68 $ killdaemons.py $DAEMON_PIDS
69
69
70 Failure to read all bytes in initial HTTP request should yield connection related error message
70 Failure to read all bytes in initial HTTP request should yield connection related error message
71
71
72 $ hg serve --config badserver.closeafterrecvbytes=1 -p $HGPORT -d --pid-file=hg.pid -E error.log
72 $ hg serve --config badserver.closeafterrecvbytes=1 -p $HGPORT -d --pid-file=hg.pid -E error.log
73 $ cat hg.pid > $DAEMON_PIDS
73 $ cat hg.pid > $DAEMON_PIDS
74
74
75 $ hg clone http://localhost:$HGPORT/ clone
75 $ hg clone http://localhost:$HGPORT/ clone
76 abort: error: bad HTTP status line: * (glob)
76 abort: error: bad HTTP status line: * (glob)
77 [100]
77 [100]
78
78
79 $ killdaemons.py $DAEMON_PIDS
79 $ killdaemons.py $DAEMON_PIDS
80
80
81 $ cat error.log
81 $ cat error.log
82 readline(1 from 65537) -> (1) G
82 readline(1 from 65537) -> (1) G
83 read limit reached; closing socket
83 read limit reached; closing socket
84
84
85 $ rm -f error.log
85 $ rm -f error.log
86
86
87 Same failure, but server reads full HTTP request line
87 Same failure, but server reads full HTTP request line
88
88
89 $ hg serve --config badserver.closeafterrecvbytes=40 -p $HGPORT -d --pid-file=hg.pid -E error.log
89 $ hg serve --config badserver.closeafterrecvbytes=40 -p $HGPORT -d --pid-file=hg.pid -E error.log
90 $ cat hg.pid > $DAEMON_PIDS
90 $ cat hg.pid > $DAEMON_PIDS
91 $ hg clone http://localhost:$HGPORT/ clone
91 $ hg clone http://localhost:$HGPORT/ clone
92 abort: error: bad HTTP status line: * (glob)
92 abort: error: bad HTTP status line: * (glob)
93 [100]
93 [100]
94
94
95 $ killdaemons.py $DAEMON_PIDS
95 $ killdaemons.py $DAEMON_PIDS
96
96
97 $ cat error.log
97 $ cat error.log
98 readline(40 from 65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
98 readline(40 from 65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
99 readline(7 from *) -> (7) Accept- (glob)
99 readline(7 from *) -> (7) Accept- (glob)
100 read limit reached; closing socket
100 read limit reached; closing socket
101
101
102 $ rm -f error.log
102 $ rm -f error.log
103
103
104 Failure on subsequent HTTP request on the same socket (cmd?batch)
104 Failure on subsequent HTTP request on the same socket (cmd?batch)
105
105
106 $ hg serve --config badserver.closeafterrecvbytes=210,223 -p $HGPORT -d --pid-file=hg.pid -E error.log
106 $ hg serve --config badserver.closeafterrecvbytes=210,223 -p $HGPORT -d --pid-file=hg.pid -E error.log
107 $ cat hg.pid > $DAEMON_PIDS
107 $ cat hg.pid > $DAEMON_PIDS
108 $ hg clone http://localhost:$HGPORT/ clone
108 $ hg clone http://localhost:$HGPORT/ clone
109 abort: error: bad HTTP status line: * (glob)
109 abort: error: bad HTTP status line: * (glob)
110 [100]
110 [100]
111
111
112 $ killdaemons.py $DAEMON_PIDS
112 $ killdaemons.py $DAEMON_PIDS
113
113
114 $ cat error.log
114 $ cat error.log
115 readline(210 from 65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
115 readline(210 from 65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
116 readline(177 from *) -> (27) Accept-Encoding: identity\r\n (glob)
116 readline(177 from *) -> (27) Accept-Encoding: identity\r\n (glob)
117 readline(150 from *) -> (35) accept: application/mercurial-0.1\r\n (glob)
117 readline(150 from *) -> (35) accept: application/mercurial-0.1\r\n (glob)
118 readline(115 from *) -> (*) host: localhost:$HGPORT\r\n (glob)
118 readline(115 from *) -> (*) host: localhost:$HGPORT\r\n (glob)
119 readline(* from *) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n (glob)
119 readline(* from *) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n (glob)
120 readline(* from *) -> (2) \r\n (glob)
120 readline(* from *) -> (2) \r\n (glob)
121 sendall(160) -> HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 450\r\n\r\n (py36 !)
121 sendall(160) -> HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 431\r\n\r\n (py36 !)
122 sendall(450) -> batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (py36 !)
122 sendall(431) -> batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (py36 !)
123 write(160) -> HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 450\r\n\r\n (py3 no-py36 !)
123 write(160) -> HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 431\r\n\r\n (py3 no-py36 !)
124 write(450) -> batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (py3 no-py36 !)
124 write(431) -> batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (py3 no-py36 !)
125 write(36) -> HTTP/1.1 200 Script output follows\r\n (no-py3 !)
125 write(36) -> HTTP/1.1 200 Script output follows\r\n (no-py3 !)
126 write(23) -> Server: badhttpserver\r\n (no-py3 !)
126 write(23) -> Server: badhttpserver\r\n (no-py3 !)
127 write(37) -> Date: $HTTP_DATE$\r\n (no-py3 !)
127 write(37) -> Date: $HTTP_DATE$\r\n (no-py3 !)
128 write(41) -> Content-Type: application/mercurial-0.1\r\n (no-py3 !)
128 write(41) -> Content-Type: application/mercurial-0.1\r\n (no-py3 !)
129 write(21) -> Content-Length: 450\r\n (no-py3 !)
129 write(21) -> Content-Length: 431\r\n (no-py3 !)
130 write(2) -> \r\n (no-py3 !)
130 write(2) -> \r\n (no-py3 !)
131 write(450) -> batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (no-py3 !)
131 write(431) -> batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (no-py3 !)
132 readline(4? from 65537) -> (26) GET /?cmd=batch HTTP/1.1\r\n (glob)
132 readline(4? from 65537) -> (26) GET /?cmd=batch HTTP/1.1\r\n (glob)
133 readline(1? from *) -> (1?) Accept-Encoding* (glob)
133 readline(1? from *) -> (1?) Accept-Encoding* (glob)
134 read limit reached; closing socket
134 read limit reached; closing socket
135 readline(223 from 65537) -> (26) GET /?cmd=batch HTTP/1.1\r\n
135 readline(223 from 65537) -> (26) GET /?cmd=batch HTTP/1.1\r\n
136 readline(197 from *) -> (27) Accept-Encoding: identity\r\n (glob)
136 readline(197 from *) -> (27) Accept-Encoding: identity\r\n (glob)
137 readline(170 from *) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n (glob)
137 readline(170 from *) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n (glob)
138 readline(141 from *) -> (41) x-hgarg-1: cmds=heads+%3Bknown+nodes%3D\r\n (glob)
138 readline(141 from *) -> (41) x-hgarg-1: cmds=heads+%3Bknown+nodes%3D\r\n (glob)
139 readline(100 from *) -> (61) x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n (glob)
139 readline(100 from *) -> (61) x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n (glob)
140 readline(39 from *) -> (35) accept: application/mercurial-0.1\r\n (glob)
140 readline(39 from *) -> (35) accept: application/mercurial-0.1\r\n (glob)
141 readline(4 from *) -> (4) host (glob)
141 readline(4 from *) -> (4) host (glob)
142 read limit reached; closing socket
142 read limit reached; closing socket
143
143
144 $ rm -f error.log
144 $ rm -f error.log
145
145
146 Failure to read getbundle HTTP request
146 Failure to read getbundle HTTP request
147
147
148 $ hg serve --config badserver.closeafterrecvbytes=308,317,304 -p $HGPORT -d --pid-file=hg.pid -E error.log
148 $ hg serve --config badserver.closeafterrecvbytes=308,317,304 -p $HGPORT -d --pid-file=hg.pid -E error.log
149 $ cat hg.pid > $DAEMON_PIDS
149 $ cat hg.pid > $DAEMON_PIDS
150 $ hg clone http://localhost:$HGPORT/ clone
150 $ hg clone http://localhost:$HGPORT/ clone
151 requesting all changes
151 requesting all changes
152 abort: error: bad HTTP status line: * (glob)
152 abort: error: bad HTTP status line: * (glob)
153 [100]
153 [100]
154
154
155 $ killdaemons.py $DAEMON_PIDS
155 $ killdaemons.py $DAEMON_PIDS
156
156
157 $ cat error.log
157 $ cat error.log
158 readline(1 from -1) -> (1) x (?)
158 readline(1 from -1) -> (1) x (?)
159 readline(1 from -1) -> (1) x (?)
159 readline(1 from -1) -> (1) x (?)
160 readline(308 from 65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
160 readline(308 from 65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
161 readline(275 from *) -> (27) Accept-Encoding: identity\r\n (glob)
161 readline(275 from *) -> (27) Accept-Encoding: identity\r\n (glob)
162 readline(248 from *) -> (35) accept: application/mercurial-0.1\r\n (glob)
162 readline(248 from *) -> (35) accept: application/mercurial-0.1\r\n (glob)
163 readline(213 from *) -> (*) host: localhost:$HGPORT\r\n (glob)
163 readline(213 from *) -> (*) host: localhost:$HGPORT\r\n (glob)
164 readline(* from *) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n (glob)
164 readline(* from *) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n (glob)
165 readline(* from *) -> (2) \r\n (glob)
165 readline(* from *) -> (2) \r\n (glob)
166 sendall(160) -> HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 450\r\n\r\n (py36 !)
166 sendall(160) -> HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 431\r\n\r\n (py36 !)
167 sendall(450) -> batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (py36 !)
167 sendall(431) -> batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (py36 !)
168 write(160) -> HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 450\r\n\r\n (py3 no-py36 !)
168 write(160) -> HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 431\r\n\r\n (py3 no-py36 !)
169 write(450) -> batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (py3 no-py36 !)
169 write(431) -> batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (py3 no-py36 !)
170 write(36) -> HTTP/1.1 200 Script output follows\r\n (no-py3 !)
170 write(36) -> HTTP/1.1 200 Script output follows\r\n (no-py3 !)
171 write(23) -> Server: badhttpserver\r\n (no-py3 !)
171 write(23) -> Server: badhttpserver\r\n (no-py3 !)
172 write(37) -> Date: $HTTP_DATE$\r\n (no-py3 !)
172 write(37) -> Date: $HTTP_DATE$\r\n (no-py3 !)
173 write(41) -> Content-Type: application/mercurial-0.1\r\n (no-py3 !)
173 write(41) -> Content-Type: application/mercurial-0.1\r\n (no-py3 !)
174 write(21) -> Content-Length: 450\r\n (no-py3 !)
174 write(21) -> Content-Length: 431\r\n (no-py3 !)
175 write(2) -> \r\n (no-py3 !)
175 write(2) -> \r\n (no-py3 !)
176 write(450) -> batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (no-py3 !)
176 write(431) -> batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (no-py3 !)
177 readline(13? from 65537) -> (26) GET /?cmd=batch HTTP/1.1\r\n (glob)
177 readline(13? from 65537) -> (26) GET /?cmd=batch HTTP/1.1\r\n (glob)
178 readline(1?? from *) -> (27) Accept-Encoding: identity\r\n (glob)
178 readline(1?? from *) -> (27) Accept-Encoding: identity\r\n (glob)
179 readline(8? from *) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n (glob)
179 readline(8? from *) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n (glob)
180 readline(5? from *) -> (41) x-hgarg-1: cmds=heads+%3Bknown+nodes%3D\r\n (glob)
180 readline(5? from *) -> (41) x-hgarg-1: cmds=heads+%3Bknown+nodes%3D\r\n (glob)
181 readline(1? from *) -> (1?) x-hgproto-1:* (glob)
181 readline(1? from *) -> (1?) x-hgproto-1:* (glob)
182 read limit reached; closing socket
182 read limit reached; closing socket
183 readline(317 from 65537) -> (26) GET /?cmd=batch HTTP/1.1\r\n
183 readline(317 from 65537) -> (26) GET /?cmd=batch HTTP/1.1\r\n
184 readline(291 from *) -> (27) Accept-Encoding: identity\r\n (glob)
184 readline(291 from *) -> (27) Accept-Encoding: identity\r\n (glob)
185 readline(264 from *) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n (glob)
185 readline(264 from *) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n (glob)
186 readline(235 from *) -> (41) x-hgarg-1: cmds=heads+%3Bknown+nodes%3D\r\n (glob)
186 readline(235 from *) -> (41) x-hgarg-1: cmds=heads+%3Bknown+nodes%3D\r\n (glob)
187 readline(194 from *) -> (61) x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n (glob)
187 readline(194 from *) -> (61) x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n (glob)
188 readline(133 from *) -> (35) accept: application/mercurial-0.1\r\n (glob)
188 readline(133 from *) -> (35) accept: application/mercurial-0.1\r\n (glob)
189 readline(98 from *) -> (*) host: localhost:$HGPORT\r\n (glob)
189 readline(98 from *) -> (*) host: localhost:$HGPORT\r\n (glob)
190 readline(* from *) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n (glob)
190 readline(* from *) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n (glob)
191 readline(* from *) -> (2) \r\n (glob)
191 readline(* from *) -> (2) \r\n (glob)
192 sendall(159) -> HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 42\r\n\r\n (py36 !)
192 sendall(159) -> HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 42\r\n\r\n (py36 !)
193 sendall(42) -> 96ee1d7354c4ad7372047672c36a1f561e3a6a4c\n; (py36 !)
193 sendall(42) -> 96ee1d7354c4ad7372047672c36a1f561e3a6a4c\n; (py36 !)
194 write(159) -> HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 42\r\n\r\n (py3 no-py36 !)
194 write(159) -> HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 42\r\n\r\n (py3 no-py36 !)
195 write(42) -> 96ee1d7354c4ad7372047672c36a1f561e3a6a4c\n; (py3 no-py36 !)
195 write(42) -> 96ee1d7354c4ad7372047672c36a1f561e3a6a4c\n; (py3 no-py36 !)
196 write(36) -> HTTP/1.1 200 Script output follows\r\n (no-py3 !)
196 write(36) -> HTTP/1.1 200 Script output follows\r\n (no-py3 !)
197 write(23) -> Server: badhttpserver\r\n (no-py3 !)
197 write(23) -> Server: badhttpserver\r\n (no-py3 !)
198 write(37) -> Date: $HTTP_DATE$\r\n (no-py3 !)
198 write(37) -> Date: $HTTP_DATE$\r\n (no-py3 !)
199 write(41) -> Content-Type: application/mercurial-0.1\r\n (no-py3 !)
199 write(41) -> Content-Type: application/mercurial-0.1\r\n (no-py3 !)
200 write(20) -> Content-Length: 42\r\n (no-py3 !)
200 write(20) -> Content-Length: 42\r\n (no-py3 !)
201 write(2) -> \r\n (no-py3 !)
201 write(2) -> \r\n (no-py3 !)
202 write(42) -> 96ee1d7354c4ad7372047672c36a1f561e3a6a4c\n; (no-py3 !)
202 write(42) -> 96ee1d7354c4ad7372047672c36a1f561e3a6a4c\n; (no-py3 !)
203 readline(* from 65537) -> (*) GET /?cmd=getbundle HTTP* (glob)
203 readline(* from 65537) -> (*) GET /?cmd=getbundle HTTP* (glob)
204 read limit reached; closing socket
204 read limit reached; closing socket
205 readline(304 from 65537) -> (30) GET /?cmd=getbundle HTTP/1.1\r\n
205 readline(304 from 65537) -> (30) GET /?cmd=getbundle HTTP/1.1\r\n
206 readline(274 from *) -> (27) Accept-Encoding: identity\r\n (glob)
206 readline(274 from *) -> (27) Accept-Encoding: identity\r\n (glob)
207 readline(247 from *) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n (glob)
207 readline(247 from *) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n (glob)
208 readline(218 from *) -> (218) x-hgarg-1: bookmarks=1&bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtag (glob)
208 readline(218 from *) -> (218) x-hgarg-1: bookmarks=1&bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtag (glob)
209 read limit reached; closing socket
209 read limit reached; closing socket
210
210
211 $ rm -f error.log
211 $ rm -f error.log
212
212
213 Now do a variation using POST to send arguments
213 Now do a variation using POST to send arguments
214
214
215 $ hg serve --config experimental.httppostargs=true --config badserver.closeafterrecvbytes=329,344 -p $HGPORT -d --pid-file=hg.pid -E error.log
215 $ hg serve --config experimental.httppostargs=true --config badserver.closeafterrecvbytes=329,344 -p $HGPORT -d --pid-file=hg.pid -E error.log
216 $ cat hg.pid > $DAEMON_PIDS
216 $ cat hg.pid > $DAEMON_PIDS
217
217
218 $ hg clone http://localhost:$HGPORT/ clone
218 $ hg clone http://localhost:$HGPORT/ clone
219 abort: error: bad HTTP status line: * (glob)
219 abort: error: bad HTTP status line: * (glob)
220 [100]
220 [100]
221
221
222 $ killdaemons.py $DAEMON_PIDS
222 $ killdaemons.py $DAEMON_PIDS
223
223
224 $ cat error.log | "$PYTHON" $TESTDIR/filtertraceback.py
224 $ cat error.log | "$PYTHON" $TESTDIR/filtertraceback.py
225 readline(329 from 65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
225 readline(329 from 65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
226 readline(296 from *) -> (27) Accept-Encoding: identity\r\n (glob)
226 readline(296 from *) -> (27) Accept-Encoding: identity\r\n (glob)
227 readline(269 from *) -> (35) accept: application/mercurial-0.1\r\n (glob)
227 readline(269 from *) -> (35) accept: application/mercurial-0.1\r\n (glob)
228 readline(234 from *) -> (2?) host: localhost:$HGPORT\r\n (glob)
228 readline(234 from *) -> (2?) host: localhost:$HGPORT\r\n (glob)
229 readline(* from *) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n (glob)
229 readline(* from *) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n (glob)
230 readline(* from *) -> (2) \r\n (glob)
230 readline(* from *) -> (2) \r\n (glob)
231 sendall(160) -> HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 463\r\n\r\n (py36 !)
231 sendall(160) -> HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 444\r\n\r\n (py36 !)
232 sendall(463) -> batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx httppostargs known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (py36 !)
232 sendall(444) -> batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx httppostargs known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (py36 !)
233 write(160) -> HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 463\r\n\r\n (py3 no-py36 !)
233 write(160) -> HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 444\r\n\r\n (py3 no-py36 !)
234 write(463) -> batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx httppostargs known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (py3 no-py36 !)
234 write(444) -> batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx httppostargs known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (py3 no-py36 !)
235 write(36) -> HTTP/1.1 200 Script output follows\r\n (no-py3 !)
235 write(36) -> HTTP/1.1 200 Script output follows\r\n (no-py3 !)
236 write(23) -> Server: badhttpserver\r\n (no-py3 !)
236 write(23) -> Server: badhttpserver\r\n (no-py3 !)
237 write(37) -> Date: $HTTP_DATE$\r\n (no-py3 !)
237 write(37) -> Date: $HTTP_DATE$\r\n (no-py3 !)
238 write(41) -> Content-Type: application/mercurial-0.1\r\n (no-py3 !)
238 write(41) -> Content-Type: application/mercurial-0.1\r\n (no-py3 !)
239 write(21) -> Content-Length: 463\r\n (no-py3 !)
239 write(21) -> Content-Length: 444\r\n (no-py3 !)
240 write(2) -> \r\n (no-py3 !)
240 write(2) -> \r\n (no-py3 !)
241 write(463) -> batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx httppostargs known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (no-py3 !)
241 write(444) -> batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx httppostargs known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (no-py3 !)
242 readline(1?? from 65537) -> (27) POST /?cmd=batch HTTP/1.1\r\n (glob)
242 readline(1?? from 65537) -> (27) POST /?cmd=batch HTTP/1.1\r\n (glob)
243 readline(1?? from *) -> (27) Accept-Encoding: identity\r\n (glob)
243 readline(1?? from *) -> (27) Accept-Encoding: identity\r\n (glob)
244 readline(1?? from *) -> (41) content-type: application/mercurial-0.1\r\n (glob)
244 readline(1?? from *) -> (41) content-type: application/mercurial-0.1\r\n (glob)
245 readline(6? from *) -> (33) vary: X-HgArgs-Post,X-HgProto-1\r\n (glob)
245 readline(6? from *) -> (33) vary: X-HgArgs-Post,X-HgProto-1\r\n (glob)
246 readline(3? from *) -> (19) x-hgargs-post: 28\r\n (glob)
246 readline(3? from *) -> (19) x-hgargs-post: 28\r\n (glob)
247 readline(1? from *) -> (1?) x-hgproto-1: * (glob)
247 readline(1? from *) -> (1?) x-hgproto-1: * (glob)
248 read limit reached; closing socket
248 read limit reached; closing socket
249 readline(344 from 65537) -> (27) POST /?cmd=batch HTTP/1.1\r\n
249 readline(344 from 65537) -> (27) POST /?cmd=batch HTTP/1.1\r\n
250 readline(317 from *) -> (27) Accept-Encoding: identity\r\n (glob)
250 readline(317 from *) -> (27) Accept-Encoding: identity\r\n (glob)
251 readline(290 from *) -> (41) content-type: application/mercurial-0.1\r\n (glob)
251 readline(290 from *) -> (41) content-type: application/mercurial-0.1\r\n (glob)
252 readline(249 from *) -> (33) vary: X-HgArgs-Post,X-HgProto-1\r\n (glob)
252 readline(249 from *) -> (33) vary: X-HgArgs-Post,X-HgProto-1\r\n (glob)
253 readline(216 from *) -> (19) x-hgargs-post: 28\r\n (glob)
253 readline(216 from *) -> (19) x-hgargs-post: 28\r\n (glob)
254 readline(197 from *) -> (61) x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n (glob)
254 readline(197 from *) -> (61) x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n (glob)
255 readline(136 from *) -> (35) accept: application/mercurial-0.1\r\n (glob)
255 readline(136 from *) -> (35) accept: application/mercurial-0.1\r\n (glob)
256 readline(101 from *) -> (20) content-length: 28\r\n (glob)
256 readline(101 from *) -> (20) content-length: 28\r\n (glob)
257 readline(81 from *) -> (*) host: localhost:$HGPORT\r\n (glob)
257 readline(81 from *) -> (*) host: localhost:$HGPORT\r\n (glob)
258 readline(* from *) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n (glob)
258 readline(* from *) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n (glob)
259 readline(* from *) -> (2) \r\n (glob)
259 readline(* from *) -> (2) \r\n (glob)
260 read(* from 28) -> (*) cmds=* (glob)
260 read(* from 28) -> (*) cmds=* (glob)
261 read limit reached, closing socket
261 read limit reached, closing socket
262 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=batch': (glob)
262 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=batch': (glob)
263 Traceback (most recent call last):
263 Traceback (most recent call last):
264 Exception: connection closed after receiving N bytes
264 Exception: connection closed after receiving N bytes
265
265
266 write(126) -> HTTP/1.1 500 Internal Server Error\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nTransfer-Encoding: chunked\r\n\r\n (py3 no-py36 !)
266 write(126) -> HTTP/1.1 500 Internal Server Error\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nTransfer-Encoding: chunked\r\n\r\n (py3 no-py36 !)
267 write(36) -> HTTP/1.1 500 Internal Server Error\r\n (no-py3 !)
267 write(36) -> HTTP/1.1 500 Internal Server Error\r\n (no-py3 !)
268
268
269 $ rm -f error.log
269 $ rm -f error.log
270
270
271 Now move on to partial server responses
271 Now move on to partial server responses
272
272
273 Server sends a single character from the HTTP response line
273 Server sends a single character from the HTTP response line
274
274
275 $ hg serve --config badserver.closeaftersendbytes=1 -p $HGPORT -d --pid-file=hg.pid -E error.log
275 $ hg serve --config badserver.closeaftersendbytes=1 -p $HGPORT -d --pid-file=hg.pid -E error.log
276 $ cat hg.pid > $DAEMON_PIDS
276 $ cat hg.pid > $DAEMON_PIDS
277
277
278 $ hg clone http://localhost:$HGPORT/ clone
278 $ hg clone http://localhost:$HGPORT/ clone
279 abort: error: bad HTTP status line: H
279 abort: error: bad HTTP status line: H
280 [100]
280 [100]
281
281
282 $ killdaemons.py $DAEMON_PIDS
282 $ killdaemons.py $DAEMON_PIDS
283
283
284 $ cat error.log | "$PYTHON" $TESTDIR/filtertraceback.py
284 $ cat error.log | "$PYTHON" $TESTDIR/filtertraceback.py
285 readline(65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
285 readline(65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
286 readline(*) -> (27) Accept-Encoding: identity\r\n (glob)
286 readline(*) -> (27) Accept-Encoding: identity\r\n (glob)
287 readline(*) -> (35) accept: application/mercurial-0.1\r\n (glob)
287 readline(*) -> (35) accept: application/mercurial-0.1\r\n (glob)
288 readline(*) -> (2?) host: localhost:$HGPORT\r\n (glob)
288 readline(*) -> (2?) host: localhost:$HGPORT\r\n (glob)
289 readline(*) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n (glob)
289 readline(*) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n (glob)
290 readline(*) -> (2) \r\n (glob)
290 readline(*) -> (2) \r\n (glob)
291 sendall(1 from 160) -> (0) H (py36 !)
291 sendall(1 from 160) -> (0) H (py36 !)
292 write(1 from 160) -> (0) H (py3 no-py36 !)
292 write(1 from 160) -> (0) H (py3 no-py36 !)
293 write(1 from 36) -> (0) H (no-py3 !)
293 write(1 from 36) -> (0) H (no-py3 !)
294 write limit reached; closing socket
294 write limit reached; closing socket
295 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=capabilities': (glob)
295 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=capabilities': (glob)
296 Traceback (most recent call last):
296 Traceback (most recent call last):
297 Exception: connection closed after sending N bytes
297 Exception: connection closed after sending N bytes
298
298
299 write(286) -> HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 450\r\n\r\nHTTP/1.1 500 Internal Server Error\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nTransfer-Encoding: chunked\r\n\r\n (py3 no-py36 !)
299 write(286) -> HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 431\r\n\r\nHTTP/1.1 500 Internal Server Error\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nTransfer-Encoding: chunked\r\n\r\n (py3 no-py36 !)
300 write(36) -> HTTP/1.1 500 Internal Server Error\r\n (no-py3 !)
300 write(36) -> HTTP/1.1 500 Internal Server Error\r\n (no-py3 !)
301
301
302 $ rm -f error.log
302 $ rm -f error.log
303
303
304 Server sends an incomplete capabilities response body
304 Server sends an incomplete capabilities response body
305
305
306 $ hg serve --config badserver.closeaftersendbytes=180 -p $HGPORT -d --pid-file=hg.pid -E error.log
306 $ hg serve --config badserver.closeaftersendbytes=180 -p $HGPORT -d --pid-file=hg.pid -E error.log
307 $ cat hg.pid > $DAEMON_PIDS
307 $ cat hg.pid > $DAEMON_PIDS
308
308
309 $ hg clone http://localhost:$HGPORT/ clone
309 $ hg clone http://localhost:$HGPORT/ clone
310 abort: HTTP request error (incomplete response; expected 450 bytes got 20)
310 abort: HTTP request error (incomplete response; expected 431 bytes got 20)
311 (this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
311 (this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
312 [255]
312 [255]
313
313
314 $ killdaemons.py $DAEMON_PIDS
314 $ killdaemons.py $DAEMON_PIDS
315
315
316 $ cat error.log | "$PYTHON" $TESTDIR/filtertraceback.py
316 $ cat error.log | "$PYTHON" $TESTDIR/filtertraceback.py
317 readline(65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
317 readline(65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
318 readline(*) -> (27) Accept-Encoding: identity\r\n (glob)
318 readline(*) -> (27) Accept-Encoding: identity\r\n (glob)
319 readline(*) -> (35) accept: application/mercurial-0.1\r\n (glob)
319 readline(*) -> (35) accept: application/mercurial-0.1\r\n (glob)
320 readline(*) -> (2?) host: localhost:$HGPORT\r\n (glob)
320 readline(*) -> (2?) host: localhost:$HGPORT\r\n (glob)
321 readline(*) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n (glob)
321 readline(*) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n (glob)
322 readline(*) -> (2) \r\n (glob)
322 readline(*) -> (2) \r\n (glob)
323 sendall(160 from 160) -> (20) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 450\r\n\r\n (py36 !)
323 sendall(160 from 160) -> (20) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 431\r\n\r\n (py36 !)
324 sendall(20 from 450) -> (0) batch branchmap bund (py36 !)
324 sendall(20 from 431) -> (0) batch branchmap bund (py36 !)
325 write(160 from 160) -> (20) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 450\r\n\r\n (py3 no-py36 !)
325 write(160 from 160) -> (20) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 431\r\n\r\n (py3 no-py36 !)
326 write(20 from 450) -> (0) batch branchmap bund (py3 no-py36 !)
326 write(20 from 431) -> (0) batch branchmap bund (py3 no-py36 !)
327 write(36 from 36) -> (144) HTTP/1.1 200 Script output follows\r\n (no-py3 !)
327 write(36 from 36) -> (144) HTTP/1.1 200 Script output follows\r\n (no-py3 !)
328 write(23 from 23) -> (121) Server: badhttpserver\r\n (no-py3 !)
328 write(23 from 23) -> (121) Server: badhttpserver\r\n (no-py3 !)
329 write(37 from 37) -> (84) Date: $HTTP_DATE$\r\n (no-py3 !)
329 write(37 from 37) -> (84) Date: $HTTP_DATE$\r\n (no-py3 !)
330 write(41 from 41) -> (43) Content-Type: application/mercurial-0.1\r\n (no-py3 !)
330 write(41 from 41) -> (43) Content-Type: application/mercurial-0.1\r\n (no-py3 !)
331 write(21 from 21) -> (22) Content-Length: 450\r\n (no-py3 !)
331 write(21 from 21) -> (22) Content-Length: 431\r\n (no-py3 !)
332 write(2 from 2) -> (20) \r\n (no-py3 !)
332 write(2 from 2) -> (20) \r\n (no-py3 !)
333 write(20 from 450) -> (0) batch branchmap bund (no-py3 !)
333 write(20 from 431) -> (0) batch branchmap bund (no-py3 !)
334 write limit reached; closing socket
334 write limit reached; closing socket
335 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=capabilities': (glob)
335 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=capabilities': (glob)
336 Traceback (most recent call last):
336 Traceback (most recent call last):
337 Exception: connection closed after sending N bytes
337 Exception: connection closed after sending N bytes
338
338
339
339
340 $ rm -f error.log
340 $ rm -f error.log
341
341
342 Server sends incomplete headers for batch request
342 Server sends incomplete headers for batch request
343
343
344 $ hg serve --config badserver.closeaftersendbytes=728 -p $HGPORT -d --pid-file=hg.pid -E error.log
344 $ hg serve --config badserver.closeaftersendbytes=709 -p $HGPORT -d --pid-file=hg.pid -E error.log
345 $ cat hg.pid > $DAEMON_PIDS
345 $ cat hg.pid > $DAEMON_PIDS
346
346
347 TODO this output is horrible
347 TODO this output is horrible
348
348
349 $ hg clone http://localhost:$HGPORT/ clone
349 $ hg clone http://localhost:$HGPORT/ clone
350 abort: 'http://localhost:$HGPORT/' does not appear to be an hg repository:
350 abort: 'http://localhost:$HGPORT/' does not appear to be an hg repository:
351 ---%<--- (applicat)
351 ---%<--- (applicat)
352
352
353 ---%<---
353 ---%<---
354
354
355 [255]
355 [255]
356
356
357 $ killdaemons.py $DAEMON_PIDS
357 $ killdaemons.py $DAEMON_PIDS
358
358
359 $ cat error.log | "$PYTHON" $TESTDIR/filtertraceback.py
359 $ cat error.log | "$PYTHON" $TESTDIR/filtertraceback.py
360 readline(65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
360 readline(65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
361 readline(*) -> (27) Accept-Encoding: identity\r\n (glob)
361 readline(*) -> (27) Accept-Encoding: identity\r\n (glob)
362 readline(*) -> (35) accept: application/mercurial-0.1\r\n (glob)
362 readline(*) -> (35) accept: application/mercurial-0.1\r\n (glob)
363 readline(*) -> (2?) host: localhost:$HGPORT\r\n (glob)
363 readline(*) -> (2?) host: localhost:$HGPORT\r\n (glob)
364 readline(*) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n (glob)
364 readline(*) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n (glob)
365 readline(*) -> (2) \r\n (glob)
365 readline(*) -> (2) \r\n (glob)
366 sendall(160 from 160) -> (568) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 450\r\n\r\n (py36 !)
366 sendall(160 from 160) -> (549) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 431\r\n\r\n (py36 !)
367 sendall(450 from 450) -> (118) batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (py36 !)
367 sendall(431 from 431) -> (118) batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (py36 !)
368 write(160 from 160) -> (568) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 450\r\n\r\n (py3 no-py36 !)
368 write(160 from 160) -> (568) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 431\r\n\r\n (py3 no-py36 !)
369 write(450 from 450) -> (118) batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (py3 no-py36 !)
369 write(431 from 431) -> (118) batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (py3 no-py36 !)
370 write(36 from 36) -> (692) HTTP/1.1 200 Script output follows\r\n (no-py3 !)
370 write(36 from 36) -> (673) HTTP/1.1 200 Script output follows\r\n (no-py3 !)
371 write(23 from 23) -> (669) Server: badhttpserver\r\n (no-py3 !)
371 write(23 from 23) -> (650) Server: badhttpserver\r\n (no-py3 !)
372 write(37 from 37) -> (632) Date: $HTTP_DATE$\r\n (no-py3 !)
372 write(37 from 37) -> (613) Date: $HTTP_DATE$\r\n (no-py3 !)
373 write(41 from 41) -> (591) Content-Type: application/mercurial-0.1\r\n (no-py3 !)
373 write(41 from 41) -> (572) Content-Type: application/mercurial-0.1\r\n (no-py3 !)
374 write(21 from 21) -> (570) Content-Length: 450\r\n (no-py3 !)
374 write(21 from 21) -> (551) Content-Length: 431\r\n (no-py3 !)
375 write(2 from 2) -> (568) \r\n (no-py3 !)
375 write(2 from 2) -> (549) \r\n (no-py3 !)
376 write(450 from 450) -> (118) batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (no-py3 !)
376 write(431 from 431) -> (118) batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (no-py3 !)
377 readline(65537) -> (26) GET /?cmd=batch HTTP/1.1\r\n
377 readline(65537) -> (26) GET /?cmd=batch HTTP/1.1\r\n
378 readline(*) -> (27) Accept-Encoding: identity\r\n (glob)
378 readline(*) -> (27) Accept-Encoding: identity\r\n (glob)
379 readline(*) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n (glob)
379 readline(*) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n (glob)
380 readline(*) -> (41) x-hgarg-1: cmds=heads+%3Bknown+nodes%3D\r\n (glob)
380 readline(*) -> (41) x-hgarg-1: cmds=heads+%3Bknown+nodes%3D\r\n (glob)
381 readline(*) -> (61) x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n (glob)
381 readline(*) -> (61) x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n (glob)
382 readline(*) -> (35) accept: application/mercurial-0.1\r\n (glob)
382 readline(*) -> (35) accept: application/mercurial-0.1\r\n (glob)
383 readline(*) -> (2?) host: localhost:$HGPORT\r\n (glob)
383 readline(*) -> (2?) host: localhost:$HGPORT\r\n (glob)
384 readline(*) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n (glob)
384 readline(*) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n (glob)
385 readline(*) -> (2) \r\n (glob)
385 readline(*) -> (2) \r\n (glob)
386 sendall(118 from 159) -> (0) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: applicat (py36 !)
386 sendall(118 from 159) -> (0) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: applicat (py36 !)
387 write(118 from 159) -> (0) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: applicat (py3 no-py36 !)
387 write(118 from 159) -> (0) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: applicat (py3 no-py36 !)
388 write(36 from 36) -> (82) HTTP/1.1 200 Script output follows\r\n (no-py3 !)
388 write(36 from 36) -> (82) HTTP/1.1 200 Script output follows\r\n (no-py3 !)
389 write(23 from 23) -> (59) Server: badhttpserver\r\n (no-py3 !)
389 write(23 from 23) -> (59) Server: badhttpserver\r\n (no-py3 !)
390 write(37 from 37) -> (22) Date: $HTTP_DATE$\r\n (no-py3 !)
390 write(37 from 37) -> (22) Date: $HTTP_DATE$\r\n (no-py3 !)
391 write(22 from 41) -> (0) Content-Type: applicat (no-py3 !)
391 write(22 from 41) -> (0) Content-Type: applicat (no-py3 !)
392 write limit reached; closing socket
392 write limit reached; closing socket
393 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=batch': (glob)
393 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=batch': (glob)
394 Traceback (most recent call last):
394 Traceback (most recent call last):
395 Exception: connection closed after sending N bytes
395 Exception: connection closed after sending N bytes
396
396
397 write(285) -> HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 42\r\n\r\nHTTP/1.1 500 Internal Server Error\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nTransfer-Encoding: chunked\r\n\r\n (py3 no-py36 !)
397 write(285) -> HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 42\r\n\r\nHTTP/1.1 500 Internal Server Error\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nTransfer-Encoding: chunked\r\n\r\n (py3 no-py36 !)
398 write(36) -> HTTP/1.1 500 Internal Server Error\r\n (no-py3 !)
398 write(36) -> HTTP/1.1 500 Internal Server Error\r\n (no-py3 !)
399
399
400 $ rm -f error.log
400 $ rm -f error.log
401
401
402 Server sends an incomplete HTTP response body to batch request
402 Server sends an incomplete HTTP response body to batch request
403
403
404 $ hg serve --config badserver.closeaftersendbytes=793 -p $HGPORT -d --pid-file=hg.pid -E error.log
404 $ hg serve --config badserver.closeaftersendbytes=774 -p $HGPORT -d --pid-file=hg.pid -E error.log
405 $ cat hg.pid > $DAEMON_PIDS
405 $ cat hg.pid > $DAEMON_PIDS
406
406
407 TODO client spews a stack due to uncaught ValueError in batch.results()
407 TODO client spews a stack due to uncaught ValueError in batch.results()
408 #if no-chg
408 #if no-chg
409 $ hg clone http://localhost:$HGPORT/ clone 2> /dev/null
409 $ hg clone http://localhost:$HGPORT/ clone 2> /dev/null
410 [1]
410 [1]
411 #else
411 #else
412 $ hg clone http://localhost:$HGPORT/ clone 2> /dev/null
412 $ hg clone http://localhost:$HGPORT/ clone 2> /dev/null
413 [255]
413 [255]
414 #endif
414 #endif
415
415
416 $ killdaemons.py $DAEMON_PIDS
416 $ killdaemons.py $DAEMON_PIDS
417
417
418 $ cat error.log | "$PYTHON" $TESTDIR/filtertraceback.py
418 $ cat error.log | "$PYTHON" $TESTDIR/filtertraceback.py
419 readline(65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
419 readline(65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
420 readline(*) -> (27) Accept-Encoding: identity\r\n (glob)
420 readline(*) -> (27) Accept-Encoding: identity\r\n (glob)
421 readline(*) -> (35) accept: application/mercurial-0.1\r\n (glob)
421 readline(*) -> (35) accept: application/mercurial-0.1\r\n (glob)
422 readline(*) -> (2?) host: localhost:$HGPORT\r\n (glob)
422 readline(*) -> (2?) host: localhost:$HGPORT\r\n (glob)
423 readline(*) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n (glob)
423 readline(*) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n (glob)
424 readline(*) -> (2) \r\n (glob)
424 readline(*) -> (2) \r\n (glob)
425 sendall(160 from 160) -> (633) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 450\r\n\r\n (py36 !)
425 sendall(160 from 160) -> (614) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 431\r\n\r\n (py36 !)
426 sendall(450 from 450) -> (183) batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (py36 !)
426 sendall(431 from 431) -> (183) batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (py36 !)
427 write(160 from 160) -> (633) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 450\r\n\r\n (py3 no-py36 !)
427 write(160 from 160) -> (633) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 431\r\n\r\n (py3 no-py36 !)
428 write(450 from 450) -> (183) batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (py3 no-py36 !)
428 write(431 from 431) -> (183) batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (py3 no-py36 !)
429 write(36 from 36) -> (757) HTTP/1.1 200 Script output follows\r\n (no-py3 !)
429 write(36 from 36) -> (738) HTTP/1.1 200 Script output follows\r\n (no-py3 !)
430 write(23 from 23) -> (734) Server: badhttpserver\r\n (no-py3 !)
430 write(23 from 23) -> (715) Server: badhttpserver\r\n (no-py3 !)
431 write(37 from 37) -> (697) Date: $HTTP_DATE$\r\n (no-py3 !)
431 write(37 from 37) -> (678) Date: $HTTP_DATE$\r\n (no-py3 !)
432 write(41 from 41) -> (656) Content-Type: application/mercurial-0.1\r\n (no-py3 !)
432 write(41 from 41) -> (637) Content-Type: application/mercurial-0.1\r\n (no-py3 !)
433 write(21 from 21) -> (635) Content-Length: 450\r\n (no-py3 !)
433 write(21 from 21) -> (616) Content-Length: 431\r\n (no-py3 !)
434 write(2 from 2) -> (633) \r\n (no-py3 !)
434 write(2 from 2) -> (614) \r\n (no-py3 !)
435 write(450 from 450) -> (183) batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (no-py3 !)
435 write(431 from 431) -> (183) batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (no-py3 !)
436 readline(65537) -> (26) GET /?cmd=batch HTTP/1.1\r\n
436 readline(65537) -> (26) GET /?cmd=batch HTTP/1.1\r\n
437 readline(*) -> (27) Accept-Encoding: identity\r\n (glob)
437 readline(*) -> (27) Accept-Encoding: identity\r\n (glob)
438 readline(*) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n (glob)
438 readline(*) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n (glob)
439 readline(*) -> (41) x-hgarg-1: cmds=heads+%3Bknown+nodes%3D\r\n (glob)
439 readline(*) -> (41) x-hgarg-1: cmds=heads+%3Bknown+nodes%3D\r\n (glob)
440 readline(*) -> (61) x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n (glob)
440 readline(*) -> (61) x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n (glob)
441 readline(*) -> (35) accept: application/mercurial-0.1\r\n (glob)
441 readline(*) -> (35) accept: application/mercurial-0.1\r\n (glob)
442 readline(*) -> (2?) host: localhost:$HGPORT\r\n (glob)
442 readline(*) -> (2?) host: localhost:$HGPORT\r\n (glob)
443 readline(*) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n (glob)
443 readline(*) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n (glob)
444 readline(*) -> (2) \r\n (glob)
444 readline(*) -> (2) \r\n (glob)
445 sendall(159 from 159) -> (24) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 42\r\n\r\n (py36 !)
445 sendall(159 from 159) -> (24) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 42\r\n\r\n (py36 !)
446 sendall(24 from 42) -> (0) 96ee1d7354c4ad7372047672 (py36 !)
446 sendall(24 from 42) -> (0) 96ee1d7354c4ad7372047672 (py36 !)
447 write(159 from 159) -> (24) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 42\r\n\r\n (py3 no-py36 !)
447 write(159 from 159) -> (24) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 42\r\n\r\n (py3 no-py36 !)
448 write(24 from 42) -> (0) 96ee1d7354c4ad7372047672 (py3 no-py36 !)
448 write(24 from 42) -> (0) 96ee1d7354c4ad7372047672 (py3 no-py36 !)
449 write(36 from 36) -> (147) HTTP/1.1 200 Script output follows\r\n (no-py3 !)
449 write(36 from 36) -> (147) HTTP/1.1 200 Script output follows\r\n (no-py3 !)
450 write(23 from 23) -> (124) Server: badhttpserver\r\n (no-py3 !)
450 write(23 from 23) -> (124) Server: badhttpserver\r\n (no-py3 !)
451 write(37 from 37) -> (87) Date: $HTTP_DATE$\r\n (no-py3 !)
451 write(37 from 37) -> (87) Date: $HTTP_DATE$\r\n (no-py3 !)
452 write(41 from 41) -> (46) Content-Type: application/mercurial-0.1\r\n (no-py3 !)
452 write(41 from 41) -> (46) Content-Type: application/mercurial-0.1\r\n (no-py3 !)
453 write(20 from 20) -> (26) Content-Length: 42\r\n (no-py3 !)
453 write(20 from 20) -> (26) Content-Length: 42\r\n (no-py3 !)
454 write(2 from 2) -> (24) \r\n (no-py3 !)
454 write(2 from 2) -> (24) \r\n (no-py3 !)
455 write(24 from 42) -> (0) 96ee1d7354c4ad7372047672 (no-py3 !)
455 write(24 from 42) -> (0) 96ee1d7354c4ad7372047672 (no-py3 !)
456 write limit reached; closing socket
456 write limit reached; closing socket
457 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=batch': (glob)
457 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=batch': (glob)
458 Traceback (most recent call last):
458 Traceback (most recent call last):
459 Exception: connection closed after sending N bytes
459 Exception: connection closed after sending N bytes
460
460
461
461
462 $ rm -f error.log
462 $ rm -f error.log
463
463
464 Server sends incomplete headers for getbundle response
464 Server sends incomplete headers for getbundle response
465
465
466 $ hg serve --config badserver.closeaftersendbytes=940 -p $HGPORT -d --pid-file=hg.pid -E error.log
466 $ hg serve --config badserver.closeaftersendbytes=921 -p $HGPORT -d --pid-file=hg.pid -E error.log
467 $ cat hg.pid > $DAEMON_PIDS
467 $ cat hg.pid > $DAEMON_PIDS
468
468
469 TODO this output is terrible
469 TODO this output is terrible
470
470
471 $ hg clone http://localhost:$HGPORT/ clone
471 $ hg clone http://localhost:$HGPORT/ clone
472 requesting all changes
472 requesting all changes
473 abort: 'http://localhost:$HGPORT/' does not appear to be an hg repository:
473 abort: 'http://localhost:$HGPORT/' does not appear to be an hg repository:
474 ---%<--- (application/mercuri)
474 ---%<--- (application/mercuri)
475
475
476 ---%<---
476 ---%<---
477
477
478 [255]
478 [255]
479
479
480 $ killdaemons.py $DAEMON_PIDS
480 $ killdaemons.py $DAEMON_PIDS
481
481
482 $ cat error.log | "$PYTHON" $TESTDIR/filtertraceback.py
482 $ cat error.log | "$PYTHON" $TESTDIR/filtertraceback.py
483 readline(65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
483 readline(65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
484 readline(*) -> (27) Accept-Encoding: identity\r\n (glob)
484 readline(*) -> (27) Accept-Encoding: identity\r\n (glob)
485 readline(*) -> (35) accept: application/mercurial-0.1\r\n (glob)
485 readline(*) -> (35) accept: application/mercurial-0.1\r\n (glob)
486 readline(*) -> (2?) host: localhost:$HGPORT\r\n (glob)
486 readline(*) -> (2?) host: localhost:$HGPORT\r\n (glob)
487 readline(*) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n (glob)
487 readline(*) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n (glob)
488 readline(*) -> (2) \r\n (glob)
488 readline(*) -> (2) \r\n (glob)
489 sendall(160 from 160) -> (780) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 450\r\n\r\n (py36 !)
489 sendall(160 from 160) -> (761) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 431\r\n\r\n (py36 !)
490 sendall(450 from 450) -> (330) batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (py36 !)
490 sendall(431 from 431) -> (330) batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (py36 !)
491 write(160 from 160) -> (780) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 450\r\n\r\n (py3 no-py36 !)
491 write(160 from 160) -> (780) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 431\r\n\r\n (py3 no-py36 !)
492 write(450 from 450) -> (330) batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (py3 no-py36 !)
492 write(431 from 431) -> (330) batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (py3 no-py36 !)
493 write(36 from 36) -> (904) HTTP/1.1 200 Script output follows\r\n (no-py3 !)
493 write(36 from 36) -> (885) HTTP/1.1 200 Script output follows\r\n (no-py3 !)
494 write(23 from 23) -> (881) Server: badhttpserver\r\n (no-py3 !)
494 write(23 from 23) -> (862) Server: badhttpserver\r\n (no-py3 !)
495 write(37 from 37) -> (844) Date: $HTTP_DATE$\r\n (no-py3 !)
495 write(37 from 37) -> (825) Date: $HTTP_DATE$\r\n (no-py3 !)
496 write(41 from 41) -> (803) Content-Type: application/mercurial-0.1\r\n (no-py3 !)
496 write(41 from 41) -> (784) Content-Type: application/mercurial-0.1\r\n (no-py3 !)
497 write(21 from 21) -> (782) Content-Length: 450\r\n (no-py3 !)
497 write(21 from 21) -> (763) Content-Length: 431\r\n (no-py3 !)
498 write(2 from 2) -> (780) \r\n (no-py3 !)
498 write(2 from 2) -> (761) \r\n (no-py3 !)
499 write(450 from 450) -> (330) batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (no-py3 !)
499 write(431 from 431) -> (330) batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (no-py3 !)
500 readline(65537) -> (26) GET /?cmd=batch HTTP/1.1\r\n
500 readline(65537) -> (26) GET /?cmd=batch HTTP/1.1\r\n
501 readline(*) -> (27) Accept-Encoding: identity\r\n (glob)
501 readline(*) -> (27) Accept-Encoding: identity\r\n (glob)
502 readline(*) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n (glob)
502 readline(*) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n (glob)
503 readline(*) -> (41) x-hgarg-1: cmds=heads+%3Bknown+nodes%3D\r\n (glob)
503 readline(*) -> (41) x-hgarg-1: cmds=heads+%3Bknown+nodes%3D\r\n (glob)
504 readline(*) -> (61) x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n (glob)
504 readline(*) -> (61) x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n (glob)
505 readline(*) -> (35) accept: application/mercurial-0.1\r\n (glob)
505 readline(*) -> (35) accept: application/mercurial-0.1\r\n (glob)
506 readline(*) -> (2?) host: localhost:$HGPORT\r\n (glob)
506 readline(*) -> (2?) host: localhost:$HGPORT\r\n (glob)
507 readline(*) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n (glob)
507 readline(*) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n (glob)
508 readline(*) -> (2) \r\n (glob)
508 readline(*) -> (2) \r\n (glob)
509 sendall(159 from 159) -> (171) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 42\r\n\r\n (py36 !)
509 sendall(159 from 159) -> (171) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 42\r\n\r\n (py36 !)
510 sendall(42 from 42) -> (129) 96ee1d7354c4ad7372047672c36a1f561e3a6a4c\n; (py36 !)
510 sendall(42 from 42) -> (129) 96ee1d7354c4ad7372047672c36a1f561e3a6a4c\n; (py36 !)
511 write(159 from 159) -> (171) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 42\r\n\r\n (py3 no-py36 !)
511 write(159 from 159) -> (171) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 42\r\n\r\n (py3 no-py36 !)
512 write(42 from 42) -> (129) 96ee1d7354c4ad7372047672c36a1f561e3a6a4c\n; (py3 no-py36 !)
512 write(42 from 42) -> (129) 96ee1d7354c4ad7372047672c36a1f561e3a6a4c\n; (py3 no-py36 !)
513 write(36 from 36) -> (294) HTTP/1.1 200 Script output follows\r\n (no-py3 !)
513 write(36 from 36) -> (294) HTTP/1.1 200 Script output follows\r\n (no-py3 !)
514 write(23 from 23) -> (271) Server: badhttpserver\r\n (no-py3 !)
514 write(23 from 23) -> (271) Server: badhttpserver\r\n (no-py3 !)
515 write(37 from 37) -> (234) Date: $HTTP_DATE$\r\n (no-py3 !)
515 write(37 from 37) -> (234) Date: $HTTP_DATE$\r\n (no-py3 !)
516 write(41 from 41) -> (193) Content-Type: application/mercurial-0.1\r\n (no-py3 !)
516 write(41 from 41) -> (193) Content-Type: application/mercurial-0.1\r\n (no-py3 !)
517 write(20 from 20) -> (173) Content-Length: 42\r\n (no-py3 !)
517 write(20 from 20) -> (173) Content-Length: 42\r\n (no-py3 !)
518 write(2 from 2) -> (171) \r\n (no-py3 !)
518 write(2 from 2) -> (171) \r\n (no-py3 !)
519 write(42 from 42) -> (129) 96ee1d7354c4ad7372047672c36a1f561e3a6a4c\n; (no-py3 !)
519 write(42 from 42) -> (129) 96ee1d7354c4ad7372047672c36a1f561e3a6a4c\n; (no-py3 !)
520 readline(65537) -> (30) GET /?cmd=getbundle HTTP/1.1\r\n
520 readline(65537) -> (30) GET /?cmd=getbundle HTTP/1.1\r\n
521 readline(*) -> (27) Accept-Encoding: identity\r\n (glob)
521 readline(*) -> (27) Accept-Encoding: identity\r\n (glob)
522 readline(*) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n (glob)
522 readline(*) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n (glob)
523 readline(*) -> (461) x-hgarg-1: bookmarks=1&bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps%250Arev-branch-cache%250Astream%253Dv2&cg=1&common=0000000000000000000000000000000000000000&heads=96ee1d7354c4ad7372047672c36a1f561e3a6a4c&listkeys=phases%2Cbookmarks\r\n (glob)
523 readline(*) -> (440) x-hgarg-1: bookmarks=1&bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps%250Astream%253Dv2&cg=1&common=0000000000000000000000000000000000000000&heads=96ee1d7354c4ad7372047672c36a1f561e3a6a4c&listkeys=phases%2Cbookmarks\r\n (glob)
524 readline(*) -> (61) x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n (glob)
524 readline(*) -> (61) x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n (glob)
525 readline(*) -> (35) accept: application/mercurial-0.1\r\n (glob)
525 readline(*) -> (35) accept: application/mercurial-0.1\r\n (glob)
526 readline(*) -> (2?) host: localhost:$HGPORT\r\n (glob)
526 readline(*) -> (2?) host: localhost:$HGPORT\r\n (glob)
527 readline(*) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n (glob)
527 readline(*) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n (glob)
528 readline(*) -> (2) \r\n (glob)
528 readline(*) -> (2) \r\n (glob)
529 sendall(129 from 167) -> (0) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercuri (py36 !)
529 sendall(129 from 167) -> (0) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercuri (py36 !)
530 write(129 from 167) -> (0) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercuri (py3 no-py36 !)
530 write(129 from 167) -> (0) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercuri (py3 no-py36 !)
531 write(36 from 36) -> (93) HTTP/1.1 200 Script output follows\r\n (no-py3 !)
531 write(36 from 36) -> (93) HTTP/1.1 200 Script output follows\r\n (no-py3 !)
532 write(23 from 23) -> (70) Server: badhttpserver\r\n (no-py3 !)
532 write(23 from 23) -> (70) Server: badhttpserver\r\n (no-py3 !)
533 write(37 from 37) -> (33) Date: $HTTP_DATE$\r\n (no-py3 !)
533 write(37 from 37) -> (33) Date: $HTTP_DATE$\r\n (no-py3 !)
534 write(33 from 41) -> (0) Content-Type: application/mercuri (no-py3 !)
534 write(33 from 41) -> (0) Content-Type: application/mercuri (no-py3 !)
535 write limit reached; closing socket
535 write limit reached; closing socket
536 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=getbundle': (glob)
536 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=getbundle': (glob)
537 Traceback (most recent call last):
537 Traceback (most recent call last):
538 Exception: connection closed after sending N bytes
538 Exception: connection closed after sending N bytes
539
539
540 write(293) -> HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.2\r\nTransfer-Encoding: chunked\r\n\r\nHTTP/1.1 500 Internal Server Error\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nTransfer-Encoding: chunked\r\n\r\n (py3 no-py36 !)
540 write(293) -> HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.2\r\nTransfer-Encoding: chunked\r\n\r\nHTTP/1.1 500 Internal Server Error\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nTransfer-Encoding: chunked\r\n\r\n (py3 no-py36 !)
541 write(36) -> HTTP/1.1 500 Internal Server Error\r\n (no-py3 !)
541 write(36) -> HTTP/1.1 500 Internal Server Error\r\n (no-py3 !)
542
542
543 $ rm -f error.log
543 $ rm -f error.log
544
544
545 Server stops before it sends transfer encoding
545 Server stops before it sends transfer encoding
546
546
547 $ hg serve --config badserver.closeaftersendbytes=973 -p $HGPORT -d --pid-file=hg.pid -E error.log
547 $ hg serve --config badserver.closeaftersendbytes=954 -p $HGPORT -d --pid-file=hg.pid -E error.log
548 $ cat hg.pid > $DAEMON_PIDS
548 $ cat hg.pid > $DAEMON_PIDS
549
549
550 $ hg clone http://localhost:$HGPORT/ clone
550 $ hg clone http://localhost:$HGPORT/ clone
551 requesting all changes
551 requesting all changes
552 abort: stream ended unexpectedly (got 0 bytes, expected 1)
552 abort: stream ended unexpectedly (got 0 bytes, expected 1)
553 [255]
553 [255]
554
554
555 $ killdaemons.py $DAEMON_PIDS
555 $ killdaemons.py $DAEMON_PIDS
556
556
557 #if py36
557 #if py36
558 $ "$PYTHON" $TESTDIR/filtertraceback.py < error.log | tail -3
558 $ "$PYTHON" $TESTDIR/filtertraceback.py < error.log | tail -3
559 Traceback (most recent call last):
559 Traceback (most recent call last):
560 Exception: connection closed after sending N bytes
560 Exception: connection closed after sending N bytes
561
561
562
562
563 #else
563 #else
564 $ "$PYTHON" $TESTDIR/filtertraceback.py < error.log | tail -4
564 $ "$PYTHON" $TESTDIR/filtertraceback.py < error.log | tail -4
565 Traceback (most recent call last):
565 Traceback (most recent call last):
566 Exception: connection closed after sending N bytes
566 Exception: connection closed after sending N bytes
567
567
568 write(293) -> HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.2\r\nTransfer-Encoding: chunked\r\n\r\nHTTP/1.1 500 Internal Server Error\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nTransfer-Encoding: chunked\r\n\r\n (py3 !)
568 write(293) -> HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.2\r\nTransfer-Encoding: chunked\r\n\r\nHTTP/1.1 500 Internal Server Error\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nTransfer-Encoding: chunked\r\n\r\n (py3 !)
569 write(36) -> HTTP/1.1 500 Internal Server Error\r\n (no-py3 !)
569 write(36) -> HTTP/1.1 500 Internal Server Error\r\n (no-py3 !)
570 #endif
570 #endif
571
571
572 $ rm -f error.log
572 $ rm -f error.log
573
573
574 Server sends empty HTTP body for getbundle
574 Server sends empty HTTP body for getbundle
575
575
576 $ hg serve --config badserver.closeaftersendbytes=978 -p $HGPORT -d --pid-file=hg.pid -E error.log
576 $ hg serve --config badserver.closeaftersendbytes=959 -p $HGPORT -d --pid-file=hg.pid -E error.log
577 $ cat hg.pid > $DAEMON_PIDS
577 $ cat hg.pid > $DAEMON_PIDS
578
578
579 $ hg clone http://localhost:$HGPORT/ clone
579 $ hg clone http://localhost:$HGPORT/ clone
580 requesting all changes
580 requesting all changes
581 abort: HTTP request error (incomplete response)
581 abort: HTTP request error (incomplete response)
582 (this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
582 (this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
583 [255]
583 [255]
584
584
585 $ killdaemons.py $DAEMON_PIDS
585 $ killdaemons.py $DAEMON_PIDS
586
586
587 $ cat error.log | "$PYTHON" $TESTDIR/filtertraceback.py
587 $ cat error.log | "$PYTHON" $TESTDIR/filtertraceback.py
588 readline(65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
588 readline(65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
589 readline(*) -> (27) Accept-Encoding: identity\r\n (glob)
589 readline(*) -> (27) Accept-Encoding: identity\r\n (glob)
590 readline(*) -> (35) accept: application/mercurial-0.1\r\n (glob)
590 readline(*) -> (35) accept: application/mercurial-0.1\r\n (glob)
591 readline(*) -> (2?) host: localhost:$HGPORT\r\n (glob)
591 readline(*) -> (2?) host: localhost:$HGPORT\r\n (glob)
592 readline(*) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n (glob)
592 readline(*) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n (glob)
593 readline(*) -> (2) \r\n (glob)
593 readline(*) -> (2) \r\n (glob)
594 sendall(160 from 160) -> (818) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 450\r\n\r\n (py36 !)
594 sendall(160 from 160) -> (799) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 431\r\n\r\n (py36 !)
595 sendall(450 from 450) -> (368) batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (py36 !)
595 sendall(431 from 431) -> (368) batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (py36 !)
596 write(160 from 160) -> (818) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 450\r\n\r\n (py3 no-py36 !)
596 write(160 from 160) -> (818) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 431\r\n\r\n (py3 no-py36 !)
597 write(450 from 450) -> (368) batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (py3 no-py36 !)
597 write(431 from 431) -> (368) batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (py3 no-py36 !)
598 write(36 from 36) -> (942) HTTP/1.1 200 Script output follows\r\n (no-py3 !)
598 write(36 from 36) -> (923) HTTP/1.1 200 Script output follows\r\n (no-py3 !)
599 write(23 from 23) -> (919) Server: badhttpserver\r\n (no-py3 !)
599 write(23 from 23) -> (900) Server: badhttpserver\r\n (no-py3 !)
600 write(37 from 37) -> (882) Date: $HTTP_DATE$\r\n (no-py3 !)
600 write(37 from 37) -> (863) Date: $HTTP_DATE$\r\n (no-py3 !)
601 write(41 from 41) -> (841) Content-Type: application/mercurial-0.1\r\n (no-py3 !)
601 write(41 from 41) -> (822) Content-Type: application/mercurial-0.1\r\n (no-py3 !)
602 write(21 from 21) -> (820) Content-Length: 450\r\n (no-py3 !)
602 write(21 from 21) -> (801) Content-Length: 431\r\n (no-py3 !)
603 write(2 from 2) -> (818) \r\n (no-py3 !)
603 write(2 from 2) -> (799) \r\n (no-py3 !)
604 write(450 from 450) -> (368) batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (no-py3 !)
604 write(431 from 431) -> (368) batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (no-py3 !)
605 readline(65537) -> (26) GET /?cmd=batch HTTP/1.1\r\n
605 readline(65537) -> (26) GET /?cmd=batch HTTP/1.1\r\n
606 readline(*) -> (27) Accept-Encoding: identity\r\n (glob)
606 readline(*) -> (27) Accept-Encoding: identity\r\n (glob)
607 readline(*) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n (glob)
607 readline(*) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n (glob)
608 readline(*) -> (41) x-hgarg-1: cmds=heads+%3Bknown+nodes%3D\r\n (glob)
608 readline(*) -> (41) x-hgarg-1: cmds=heads+%3Bknown+nodes%3D\r\n (glob)
609 readline(*) -> (61) x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n (glob)
609 readline(*) -> (61) x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n (glob)
610 readline(*) -> (35) accept: application/mercurial-0.1\r\n (glob)
610 readline(*) -> (35) accept: application/mercurial-0.1\r\n (glob)
611 readline(*) -> (2?) host: localhost:$HGPORT\r\n (glob)
611 readline(*) -> (2?) host: localhost:$HGPORT\r\n (glob)
612 readline(*) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n (glob)
612 readline(*) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n (glob)
613 readline(*) -> (2) \r\n (glob)
613 readline(*) -> (2) \r\n (glob)
614 sendall(159 from 159) -> (209) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 42\r\n\r\n (py36 !)
614 sendall(159 from 159) -> (209) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 42\r\n\r\n (py36 !)
615 sendall(42 from 42) -> (167) 96ee1d7354c4ad7372047672c36a1f561e3a6a4c\n; (py36 !)
615 sendall(42 from 42) -> (167) 96ee1d7354c4ad7372047672c36a1f561e3a6a4c\n; (py36 !)
616 write(159 from 159) -> (209) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 42\r\n\r\n (py3 no-py36 !)
616 write(159 from 159) -> (209) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 42\r\n\r\n (py3 no-py36 !)
617 write(42 from 42) -> (167) 96ee1d7354c4ad7372047672c36a1f561e3a6a4c\n; (py3 no-py36 !)
617 write(42 from 42) -> (167) 96ee1d7354c4ad7372047672c36a1f561e3a6a4c\n; (py3 no-py36 !)
618 write(36 from 36) -> (332) HTTP/1.1 200 Script output follows\r\n (no-py3 !)
618 write(36 from 36) -> (332) HTTP/1.1 200 Script output follows\r\n (no-py3 !)
619 write(23 from 23) -> (309) Server: badhttpserver\r\n (no-py3 !)
619 write(23 from 23) -> (309) Server: badhttpserver\r\n (no-py3 !)
620 write(37 from 37) -> (272) Date: $HTTP_DATE$\r\n (no-py3 !)
620 write(37 from 37) -> (272) Date: $HTTP_DATE$\r\n (no-py3 !)
621 write(41 from 41) -> (231) Content-Type: application/mercurial-0.1\r\n (no-py3 !)
621 write(41 from 41) -> (231) Content-Type: application/mercurial-0.1\r\n (no-py3 !)
622 write(20 from 20) -> (211) Content-Length: 42\r\n (no-py3 !)
622 write(20 from 20) -> (211) Content-Length: 42\r\n (no-py3 !)
623 write(2 from 2) -> (209) \r\n (no-py3 !)
623 write(2 from 2) -> (209) \r\n (no-py3 !)
624 write(42 from 42) -> (167) 96ee1d7354c4ad7372047672c36a1f561e3a6a4c\n; (no-py3 !)
624 write(42 from 42) -> (167) 96ee1d7354c4ad7372047672c36a1f561e3a6a4c\n; (no-py3 !)
625 readline(65537) -> (30) GET /?cmd=getbundle HTTP/1.1\r\n
625 readline(65537) -> (30) GET /?cmd=getbundle HTTP/1.1\r\n
626 readline(*) -> (27) Accept-Encoding: identity\r\n (glob)
626 readline(*) -> (27) Accept-Encoding: identity\r\n (glob)
627 readline(*) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n (glob)
627 readline(*) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n (glob)
628 readline(*) -> (461) x-hgarg-1: bookmarks=1&bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps%250Arev-branch-cache%250Astream%253Dv2&cg=1&common=0000000000000000000000000000000000000000&heads=96ee1d7354c4ad7372047672c36a1f561e3a6a4c&listkeys=phases%2Cbookmarks\r\n (glob)
628 readline(*) -> (440) x-hgarg-1: bookmarks=1&bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps%250Astream%253Dv2&cg=1&common=0000000000000000000000000000000000000000&heads=96ee1d7354c4ad7372047672c36a1f561e3a6a4c&listkeys=phases%2Cbookmarks\r\n (glob)
629 readline(*) -> (61) x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n (glob)
629 readline(*) -> (61) x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n (glob)
630 readline(*) -> (35) accept: application/mercurial-0.1\r\n (glob)
630 readline(*) -> (35) accept: application/mercurial-0.1\r\n (glob)
631 readline(*) -> (2?) host: localhost:$HGPORT\r\n (glob)
631 readline(*) -> (2?) host: localhost:$HGPORT\r\n (glob)
632 readline(*) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n (glob)
632 readline(*) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n (glob)
633 readline(*) -> (2) \r\n (glob)
633 readline(*) -> (2) \r\n (glob)
634 sendall(167 from 167) -> (0) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.2\r\nTransfer-Encoding: chunked\r\n\r\n (py36 !)
634 sendall(167 from 167) -> (0) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.2\r\nTransfer-Encoding: chunked\r\n\r\n (py36 !)
635 write(167 from 167) -> (0) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.2\r\nTransfer-Encoding: chunked\r\n\r\n (py3 no-py36 !)
635 write(167 from 167) -> (0) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.2\r\nTransfer-Encoding: chunked\r\n\r\n (py3 no-py36 !)
636 write(36 from 36) -> (131) HTTP/1.1 200 Script output follows\r\n (no-py3 !)
636 write(36 from 36) -> (131) HTTP/1.1 200 Script output follows\r\n (no-py3 !)
637 write(23 from 23) -> (108) Server: badhttpserver\r\n (no-py3 !)
637 write(23 from 23) -> (108) Server: badhttpserver\r\n (no-py3 !)
638 write(37 from 37) -> (71) Date: $HTTP_DATE$\r\n (no-py3 !)
638 write(37 from 37) -> (71) Date: $HTTP_DATE$\r\n (no-py3 !)
639 write(41 from 41) -> (30) Content-Type: application/mercurial-0.2\r\n (no-py3 !)
639 write(41 from 41) -> (30) Content-Type: application/mercurial-0.2\r\n (no-py3 !)
640 write(28 from 28) -> (2) Transfer-Encoding: chunked\r\n (no-py3 !)
640 write(28 from 28) -> (2) Transfer-Encoding: chunked\r\n (no-py3 !)
641 write(2 from 2) -> (0) \r\n (no-py3 !)
641 write(2 from 2) -> (0) \r\n (no-py3 !)
642 write limit reached; closing socket
642 write limit reached; closing socket
643 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=getbundle': (glob)
643 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=getbundle': (glob)
644 Traceback (most recent call last):
644 Traceback (most recent call last):
645 Exception: connection closed after sending N bytes
645 Exception: connection closed after sending N bytes
646
646
647 write(293) -> HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.2\r\nTransfer-Encoding: chunked\r\n\r\nHTTP/1.1 500 Internal Server Error\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nTransfer-Encoding: chunked\r\n\r\n (py3 no-py36 !)
647 write(293) -> HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.2\r\nTransfer-Encoding: chunked\r\n\r\nHTTP/1.1 500 Internal Server Error\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nTransfer-Encoding: chunked\r\n\r\n (py3 no-py36 !)
648 write(36) -> HTTP/1.1 500 Internal Server Error\r\n (no-py3 !)
648 write(36) -> HTTP/1.1 500 Internal Server Error\r\n (no-py3 !)
649
649
650 $ rm -f error.log
650 $ rm -f error.log
651
651
652 Server sends partial compression string
652 Server sends partial compression string
653
653
654 $ hg serve --config badserver.closeaftersendbytes=1002 -p $HGPORT -d --pid-file=hg.pid -E error.log
654 $ hg serve --config badserver.closeaftersendbytes=983 -p $HGPORT -d --pid-file=hg.pid -E error.log
655 $ cat hg.pid > $DAEMON_PIDS
655 $ cat hg.pid > $DAEMON_PIDS
656
656
657 $ hg clone http://localhost:$HGPORT/ clone
657 $ hg clone http://localhost:$HGPORT/ clone
658 requesting all changes
658 requesting all changes
659 abort: HTTP request error (incomplete response)
659 abort: HTTP request error (incomplete response)
660 (this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
660 (this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
661 [255]
661 [255]
662
662
663 $ killdaemons.py $DAEMON_PIDS
663 $ killdaemons.py $DAEMON_PIDS
664
664
665 $ cat error.log | "$PYTHON" $TESTDIR/filtertraceback.py
665 $ cat error.log | "$PYTHON" $TESTDIR/filtertraceback.py
666 readline(65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
666 readline(65537) -> (33) GET /?cmd=capabilities HTTP/1.1\r\n
667 readline(*) -> (27) Accept-Encoding: identity\r\n (glob)
667 readline(*) -> (27) Accept-Encoding: identity\r\n (glob)
668 readline(*) -> (35) accept: application/mercurial-0.1\r\n (glob)
668 readline(*) -> (35) accept: application/mercurial-0.1\r\n (glob)
669 readline(*) -> (2?) host: localhost:$HGPORT\r\n (glob)
669 readline(*) -> (2?) host: localhost:$HGPORT\r\n (glob)
670 readline(*) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n (glob)
670 readline(*) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n (glob)
671 readline(*) -> (2) \r\n (glob)
671 readline(*) -> (2) \r\n (glob)
672 sendall(160 from 160) -> (842) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 450\r\n\r\n (py36 !)
672 sendall(160 from 160) -> (823) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 431\r\n\r\n (py36 !)
673 sendall(450 from 450) -> (392) batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (py36 !)
673 sendall(431 from 431) -> (392) batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (py36 !)
674 write(160 from 160) -> (842) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 450\r\n\r\n (py3 no-py36 !)
674 write(160 from 160) -> (842) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 431\r\n\r\n (py3 no-py36 !)
675 write(450 from 450) -> (392) batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (py3 no-py36 !)
675 write(431 from 431) -> (392) batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (py3 no-py36 !)
676 write(36 from 36) -> (966) HTTP/1.1 200 Script output follows\r\n (no-py3 !)
676 write(36 from 36) -> (947) HTTP/1.1 200 Script output follows\r\n (no-py3 !)
677 write(23 from 23) -> (943) Server: badhttpserver\r\n (no-py3 !)
677 write(23 from 23) -> (924) Server: badhttpserver\r\n (no-py3 !)
678 write(37 from 37) -> (906) Date: $HTTP_DATE$\r\n (no-py3 !)
678 write(37 from 37) -> (887) Date: $HTTP_DATE$\r\n (no-py3 !)
679 write(41 from 41) -> (865) Content-Type: application/mercurial-0.1\r\n (no-py3 !)
679 write(41 from 41) -> (846) Content-Type: application/mercurial-0.1\r\n (no-py3 !)
680 write(21 from 21) -> (844) Content-Length: 450\r\n (no-py3 !)
680 write(21 from 21) -> (825) Content-Length: 431\r\n (no-py3 !)
681 write(2 from 2) -> (842) \r\n (no-py3 !)
681 write(2 from 2) -> (823) \r\n (no-py3 !)
682 write(450 from 450) -> (392) batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (no-py3 !)
682 write(431 from 431) -> (392) batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (no-py3 !)
683 readline(65537) -> (26) GET /?cmd=batch HTTP/1.1\r\n
683 readline(65537) -> (26) GET /?cmd=batch HTTP/1.1\r\n
684 readline(*) -> (27) Accept-Encoding: identity\r\n (glob)
684 readline(*) -> (27) Accept-Encoding: identity\r\n (glob)
685 readline(*) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n (glob)
685 readline(*) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n (glob)
686 readline(*) -> (41) x-hgarg-1: cmds=heads+%3Bknown+nodes%3D\r\n (glob)
686 readline(*) -> (41) x-hgarg-1: cmds=heads+%3Bknown+nodes%3D\r\n (glob)
687 readline(*) -> (61) x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n (glob)
687 readline(*) -> (61) x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n (glob)
688 readline(*) -> (35) accept: application/mercurial-0.1\r\n (glob)
688 readline(*) -> (35) accept: application/mercurial-0.1\r\n (glob)
689 readline(*) -> (2?) host: localhost:$HGPORT\r\n (glob)
689 readline(*) -> (2?) host: localhost:$HGPORT\r\n (glob)
690 readline(*) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n (glob)
690 readline(*) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n (glob)
691 readline(*) -> (2) \r\n (glob)
691 readline(*) -> (2) \r\n (glob)
692 sendall(159 from 159) -> (233) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 42\r\n\r\n (py36 !)
692 sendall(159 from 159) -> (233) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 42\r\n\r\n (py36 !)
693 sendall(42 from 42) -> (191) 96ee1d7354c4ad7372047672c36a1f561e3a6a4c\n; (py36 !)
693 sendall(42 from 42) -> (191) 96ee1d7354c4ad7372047672c36a1f561e3a6a4c\n; (py36 !)
694 write(159 from 159) -> (233) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 42\r\n\r\n (py3 no-py36 !)
694 write(159 from 159) -> (233) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 42\r\n\r\n (py3 no-py36 !)
695 write(36 from 36) -> (356) HTTP/1.1 200 Script output follows\r\n (no-py3 !)
695 write(36 from 36) -> (356) HTTP/1.1 200 Script output follows\r\n (no-py3 !)
696 write(23 from 23) -> (333) Server: badhttpserver\r\n (no-py3 !)
696 write(23 from 23) -> (333) Server: badhttpserver\r\n (no-py3 !)
697 write(37 from 37) -> (296) Date: $HTTP_DATE$\r\n (no-py3 !)
697 write(37 from 37) -> (296) Date: $HTTP_DATE$\r\n (no-py3 !)
698 write(41 from 41) -> (255) Content-Type: application/mercurial-0.1\r\n (no-py3 !)
698 write(41 from 41) -> (255) Content-Type: application/mercurial-0.1\r\n (no-py3 !)
699 write(20 from 20) -> (235) Content-Length: 42\r\n (no-py3 !)
699 write(20 from 20) -> (235) Content-Length: 42\r\n (no-py3 !)
700 write(2 from 2) -> (233) \r\n (no-py3 !)
700 write(2 from 2) -> (233) \r\n (no-py3 !)
701 write(42 from 42) -> (191) 96ee1d7354c4ad7372047672c36a1f561e3a6a4c\n; (no-py3 !)
701 write(42 from 42) -> (191) 96ee1d7354c4ad7372047672c36a1f561e3a6a4c\n; (no-py3 !)
702 readline(65537) -> (30) GET /?cmd=getbundle HTTP/1.1\r\n
702 readline(65537) -> (30) GET /?cmd=getbundle HTTP/1.1\r\n
703 readline(*) -> (27) Accept-Encoding: identity\r\n (glob)
703 readline(*) -> (27) Accept-Encoding: identity\r\n (glob)
704 readline(*) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n (glob)
704 readline(*) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n (glob)
705 readline(*) -> (461) x-hgarg-1: bookmarks=1&bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps%250Arev-branch-cache%250Astream%253Dv2&cg=1&common=0000000000000000000000000000000000000000&heads=96ee1d7354c4ad7372047672c36a1f561e3a6a4c&listkeys=phases%2Cbookmarks\r\n (glob)
705 readline(*) -> (440) x-hgarg-1: bookmarks=1&bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps%250Astream%253Dv2&cg=1&common=0000000000000000000000000000000000000000&heads=96ee1d7354c4ad7372047672c36a1f561e3a6a4c&listkeys=phases%2Cbookmarks\r\n (glob)
706 readline(*) -> (61) x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n (glob)
706 readline(*) -> (61) x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n (glob)
707 readline(*) -> (35) accept: application/mercurial-0.1\r\n (glob)
707 readline(*) -> (35) accept: application/mercurial-0.1\r\n (glob)
708 readline(*) -> (2?) host: localhost:$HGPORT\r\n (glob)
708 readline(*) -> (2?) host: localhost:$HGPORT\r\n (glob)
709 readline(*) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n (glob)
709 readline(*) -> (49) user-agent: mercurial/proto-1.0 (Mercurial 4.2)\r\n (glob)
710 readline(*) -> (2) \r\n (glob)
710 readline(*) -> (2) \r\n (glob)
711 sendall(167 from 167) -> (24) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.2\r\nTransfer-Encoding: chunked\r\n\r\n (py36 !)
711 sendall(167 from 167) -> (24) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.2\r\nTransfer-Encoding: chunked\r\n\r\n (py36 !)
712 sendall(6 from 6) -> (18) 1\\r\\n\x04\\r\\n (esc) (py36 !)
712 sendall(6 from 6) -> (18) 1\\r\\n\x04\\r\\n (esc) (py36 !)
713 sendall(9 from 9) -> (9) 4\r\nnone\r\n (py36 !)
713 sendall(9 from 9) -> (9) 4\r\nnone\r\n (py36 !)
714 sendall(9 from 9) -> (0) 4\r\nHG20\r\n (py36 !)
714 sendall(9 from 9) -> (0) 4\r\nHG20\r\n (py36 !)
715 write(167 from 167) -> (24) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.2\r\nTransfer-Encoding: chunked\r\n\r\n (py3 no-py36 !)
715 write(167 from 167) -> (24) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.2\r\nTransfer-Encoding: chunked\r\n\r\n (py3 no-py36 !)
716 write(36 from 36) -> (155) HTTP/1.1 200 Script output follows\r\n (no-py3 !)
716 write(36 from 36) -> (155) HTTP/1.1 200 Script output follows\r\n (no-py3 !)
717 write(23 from 23) -> (132) Server: badhttpserver\r\n (no-py3 !)
717 write(23 from 23) -> (132) Server: badhttpserver\r\n (no-py3 !)
718 write(37 from 37) -> (95) Date: $HTTP_DATE$\r\n (no-py3 !)
718 write(37 from 37) -> (95) Date: $HTTP_DATE$\r\n (no-py3 !)
719 write(41 from 41) -> (54) Content-Type: application/mercurial-0.2\r\n (no-py3 !)
719 write(41 from 41) -> (54) Content-Type: application/mercurial-0.2\r\n (no-py3 !)
720 write(28 from 28) -> (26) Transfer-Encoding: chunked\r\n (no-py3 !)
720 write(28 from 28) -> (26) Transfer-Encoding: chunked\r\n (no-py3 !)
721 write(2 from 2) -> (24) \r\n (no-py3 !)
721 write(2 from 2) -> (24) \r\n (no-py3 !)
722 write(6 from 6) -> (18) 1\\r\\n\x04\\r\\n (esc) (no-py3 !)
722 write(6 from 6) -> (18) 1\\r\\n\x04\\r\\n (esc) (no-py3 !)
723 write(9 from 9) -> (9) 4\r\nnone\r\n (no-py3 !)
723 write(9 from 9) -> (9) 4\r\nnone\r\n (no-py3 !)
724 write(9 from 9) -> (0) 4\r\nHG20\r\n (no-py3 !)
724 write(9 from 9) -> (0) 4\r\nHG20\r\n (no-py3 !)
725 write limit reached; closing socket
725 write limit reached; closing socket
726 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=getbundle': (glob)
726 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=getbundle': (glob)
727 Traceback (most recent call last):
727 Traceback (most recent call last):
728 Exception: connection closed after sending N bytes
728 Exception: connection closed after sending N bytes
729
729
730 write(27) -> 15\r\nInternal Server Error\r\n (no-py3 !)
730 write(27) -> 15\r\nInternal Server Error\r\n (no-py3 !)
731
731
732 $ rm -f error.log
732 $ rm -f error.log
733
733
734 Server sends partial bundle2 header magic
734 Server sends partial bundle2 header magic
735
735
736 $ hg serve --config badserver.closeaftersendbytes=999 -p $HGPORT -d --pid-file=hg.pid -E error.log
736 $ hg serve --config badserver.closeaftersendbytes=980 -p $HGPORT -d --pid-file=hg.pid -E error.log
737 $ cat hg.pid > $DAEMON_PIDS
737 $ cat hg.pid > $DAEMON_PIDS
738
738
739 $ hg clone http://localhost:$HGPORT/ clone
739 $ hg clone http://localhost:$HGPORT/ clone
740 requesting all changes
740 requesting all changes
741 abort: HTTP request error (incomplete response) (py3 !)
741 abort: HTTP request error (incomplete response) (py3 !)
742 abort: HTTP request error (incomplete response; expected 4 bytes got 3) (no-py3 !)
742 abort: HTTP request error (incomplete response; expected 4 bytes got 3) (no-py3 !)
743 (this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
743 (this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
744 [255]
744 [255]
745
745
746 $ killdaemons.py $DAEMON_PIDS
746 $ killdaemons.py $DAEMON_PIDS
747
747
748 #if py36
748 #if py36
749 $ "$PYTHON" $TESTDIR/filtertraceback.py < error.log | tail -9
749 $ "$PYTHON" $TESTDIR/filtertraceback.py < error.log | tail -9
750 sendall(167 from 167) -> (21) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.2\r\nTransfer-Encoding: chunked\r\n\r\n
750 sendall(167 from 167) -> (21) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.2\r\nTransfer-Encoding: chunked\r\n\r\n
751 sendall(6 from 6) -> (15) 1\\r\\n\x04\\r\\n (esc)
751 sendall(6 from 6) -> (15) 1\\r\\n\x04\\r\\n (esc)
752 sendall(9 from 9) -> (6) 4\r\nnone\r\n
752 sendall(9 from 9) -> (6) 4\r\nnone\r\n
753 sendall(6 from 9) -> (0) 4\r\nHG2
753 sendall(6 from 9) -> (0) 4\r\nHG2
754 write limit reached; closing socket
754 write limit reached; closing socket
755 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=getbundle': (glob)
755 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=getbundle': (glob)
756 Traceback (most recent call last):
756 Traceback (most recent call last):
757 Exception: connection closed after sending N bytes
757 Exception: connection closed after sending N bytes
758
758
759
759
760 #else
760 #else
761 $ "$PYTHON" $TESTDIR/filtertraceback.py < error.log | tail -11
761 $ "$PYTHON" $TESTDIR/filtertraceback.py < error.log | tail -11
762 readline(65537) -> (2) \r\n (py3 !)
762 readline(65537) -> (2) \r\n (py3 !)
763 write(167 from 167) -> (21) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.2\r\nTransfer-Encoding: chunked\r\n\r\n (py3 !)
763 write(167 from 167) -> (21) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.2\r\nTransfer-Encoding: chunked\r\n\r\n (py3 !)
764 write(28 from 28) -> (23) Transfer-Encoding: chunked\r\n (no-py3 !)
764 write(28 from 28) -> (23) Transfer-Encoding: chunked\r\n (no-py3 !)
765 write(2 from 2) -> (21) \r\n (no-py3 !)
765 write(2 from 2) -> (21) \r\n (no-py3 !)
766 write(6 from 6) -> (15) 1\\r\\n\x04\\r\\n (esc)
766 write(6 from 6) -> (15) 1\\r\\n\x04\\r\\n (esc)
767 write(9 from 9) -> (6) 4\r\nnone\r\n
767 write(9 from 9) -> (6) 4\r\nnone\r\n
768 write(6 from 9) -> (0) 4\r\nHG2
768 write(6 from 9) -> (0) 4\r\nHG2
769 write limit reached; closing socket
769 write limit reached; closing socket
770 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=getbundle': (glob)
770 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=getbundle': (glob)
771 Traceback (most recent call last):
771 Traceback (most recent call last):
772 Exception: connection closed after sending N bytes
772 Exception: connection closed after sending N bytes
773
773
774 write(27) -> 15\r\nInternal Server Error\r\n
774 write(27) -> 15\r\nInternal Server Error\r\n
775 #endif
775 #endif
776
776
777 $ rm -f error.log
777 $ rm -f error.log
778
778
779 Server sends incomplete bundle2 stream params length
779 Server sends incomplete bundle2 stream params length
780
780
781 $ hg serve --config badserver.closeaftersendbytes=1008 -p $HGPORT -d --pid-file=hg.pid -E error.log
781 $ hg serve --config badserver.closeaftersendbytes=989 -p $HGPORT -d --pid-file=hg.pid -E error.log
782 $ cat hg.pid > $DAEMON_PIDS
782 $ cat hg.pid > $DAEMON_PIDS
783
783
784 $ hg clone http://localhost:$HGPORT/ clone
784 $ hg clone http://localhost:$HGPORT/ clone
785 requesting all changes
785 requesting all changes
786 abort: HTTP request error (incomplete response) (py3 !)
786 abort: HTTP request error (incomplete response) (py3 !)
787 abort: HTTP request error (incomplete response; expected 4 bytes got 3) (no-py3 !)
787 abort: HTTP request error (incomplete response; expected 4 bytes got 3) (no-py3 !)
788 (this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
788 (this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
789 [255]
789 [255]
790
790
791 $ killdaemons.py $DAEMON_PIDS
791 $ killdaemons.py $DAEMON_PIDS
792
792
793 #if py36
793 #if py36
794 $ "$PYTHON" $TESTDIR/filtertraceback.py < error.log | tail -10
794 $ "$PYTHON" $TESTDIR/filtertraceback.py < error.log | tail -10
795 sendall(167 from 167) -> (30) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.2\r\nTransfer-Encoding: chunked\r\n\r\n
795 sendall(167 from 167) -> (30) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.2\r\nTransfer-Encoding: chunked\r\n\r\n
796 sendall(6 from 6) -> (24) 1\\r\\n\x04\\r\\n (esc)
796 sendall(6 from 6) -> (24) 1\\r\\n\x04\\r\\n (esc)
797 sendall(9 from 9) -> (15) 4\r\nnone\r\n
797 sendall(9 from 9) -> (15) 4\r\nnone\r\n
798 sendall(9 from 9) -> (6) 4\r\nHG20\r\n
798 sendall(9 from 9) -> (6) 4\r\nHG20\r\n
799 sendall(6 from 9) -> (0) 4\\r\\n\x00\x00\x00 (esc)
799 sendall(6 from 9) -> (0) 4\\r\\n\x00\x00\x00 (esc)
800 write limit reached; closing socket
800 write limit reached; closing socket
801 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=getbundle': (glob)
801 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=getbundle': (glob)
802 Traceback (most recent call last):
802 Traceback (most recent call last):
803 Exception: connection closed after sending N bytes
803 Exception: connection closed after sending N bytes
804
804
805
805
806 #else
806 #else
807 $ "$PYTHON" $TESTDIR/filtertraceback.py < error.log | tail -12
807 $ "$PYTHON" $TESTDIR/filtertraceback.py < error.log | tail -12
808 readline(65537) -> (2) \r\n (py3 !)
808 readline(65537) -> (2) \r\n (py3 !)
809 write(167 from 167) -> (30) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.2\r\nTransfer-Encoding: chunked\r\n\r\n (py3 !)
809 write(167 from 167) -> (30) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.2\r\nTransfer-Encoding: chunked\r\n\r\n (py3 !)
810 write(28 from 28) -> (32) Transfer-Encoding: chunked\r\n (no-py3 !)
810 write(28 from 28) -> (32) Transfer-Encoding: chunked\r\n (no-py3 !)
811 write(2 from 2) -> (30) \r\n (no-py3 !)
811 write(2 from 2) -> (30) \r\n (no-py3 !)
812 write(6 from 6) -> (24) 1\\r\\n\x04\\r\\n (esc)
812 write(6 from 6) -> (24) 1\\r\\n\x04\\r\\n (esc)
813 write(9 from 9) -> (15) 4\r\nnone\r\n
813 write(9 from 9) -> (15) 4\r\nnone\r\n
814 write(9 from 9) -> (6) 4\r\nHG20\r\n
814 write(9 from 9) -> (6) 4\r\nHG20\r\n
815 write(6 from 9) -> (0) 4\\r\\n\x00\x00\x00 (esc)
815 write(6 from 9) -> (0) 4\\r\\n\x00\x00\x00 (esc)
816 write limit reached; closing socket
816 write limit reached; closing socket
817 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=getbundle': (glob)
817 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=getbundle': (glob)
818 Traceback (most recent call last):
818 Traceback (most recent call last):
819 Exception: connection closed after sending N bytes
819 Exception: connection closed after sending N bytes
820
820
821 write(27) -> 15\r\nInternal Server Error\r\n
821 write(27) -> 15\r\nInternal Server Error\r\n
822 #endif
822 #endif
823
823
824 $ rm -f error.log
824 $ rm -f error.log
825
825
826 Servers stops after bundle2 stream params header
826 Servers stops after bundle2 stream params header
827
827
828 $ hg serve --config badserver.closeaftersendbytes=1011 -p $HGPORT -d --pid-file=hg.pid -E error.log
828 $ hg serve --config badserver.closeaftersendbytes=992 -p $HGPORT -d --pid-file=hg.pid -E error.log
829 $ cat hg.pid > $DAEMON_PIDS
829 $ cat hg.pid > $DAEMON_PIDS
830
830
831 $ hg clone http://localhost:$HGPORT/ clone
831 $ hg clone http://localhost:$HGPORT/ clone
832 requesting all changes
832 requesting all changes
833 abort: HTTP request error (incomplete response)
833 abort: HTTP request error (incomplete response)
834 (this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
834 (this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
835 [255]
835 [255]
836
836
837 $ killdaemons.py $DAEMON_PIDS
837 $ killdaemons.py $DAEMON_PIDS
838
838
839 #if py36
839 #if py36
840 $ "$PYTHON" $TESTDIR/filtertraceback.py < error.log | tail -10
840 $ "$PYTHON" $TESTDIR/filtertraceback.py < error.log | tail -10
841 sendall(167 from 167) -> (33) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.2\r\nTransfer-Encoding: chunked\r\n\r\n
841 sendall(167 from 167) -> (33) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.2\r\nTransfer-Encoding: chunked\r\n\r\n
842 sendall(6 from 6) -> (27) 1\\r\\n\x04\\r\\n (esc)
842 sendall(6 from 6) -> (27) 1\\r\\n\x04\\r\\n (esc)
843 sendall(9 from 9) -> (18) 4\r\nnone\r\n
843 sendall(9 from 9) -> (18) 4\r\nnone\r\n
844 sendall(9 from 9) -> (9) 4\r\nHG20\r\n
844 sendall(9 from 9) -> (9) 4\r\nHG20\r\n
845 sendall(9 from 9) -> (0) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
845 sendall(9 from 9) -> (0) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
846 write limit reached; closing socket
846 write limit reached; closing socket
847 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=getbundle': (glob)
847 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=getbundle': (glob)
848 Traceback (most recent call last):
848 Traceback (most recent call last):
849 Exception: connection closed after sending N bytes
849 Exception: connection closed after sending N bytes
850
850
851
851
852 #else
852 #else
853 $ "$PYTHON" $TESTDIR/filtertraceback.py < error.log | tail -12
853 $ "$PYTHON" $TESTDIR/filtertraceback.py < error.log | tail -12
854 readline(65537) -> (2) \r\n (py3 !)
854 readline(65537) -> (2) \r\n (py3 !)
855 write(167 from 167) -> (33) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.2\r\nTransfer-Encoding: chunked\r\n\r\n (py3 !)
855 write(167 from 167) -> (33) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.2\r\nTransfer-Encoding: chunked\r\n\r\n (py3 !)
856 write(28 from 28) -> (35) Transfer-Encoding: chunked\r\n (no-py3 !)
856 write(28 from 28) -> (35) Transfer-Encoding: chunked\r\n (no-py3 !)
857 write(2 from 2) -> (33) \r\n (no-py3 !)
857 write(2 from 2) -> (33) \r\n (no-py3 !)
858 write(6 from 6) -> (27) 1\\r\\n\x04\\r\\n (esc)
858 write(6 from 6) -> (27) 1\\r\\n\x04\\r\\n (esc)
859 write(9 from 9) -> (18) 4\r\nnone\r\n
859 write(9 from 9) -> (18) 4\r\nnone\r\n
860 write(9 from 9) -> (9) 4\r\nHG20\r\n
860 write(9 from 9) -> (9) 4\r\nHG20\r\n
861 write(9 from 9) -> (0) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
861 write(9 from 9) -> (0) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
862 write limit reached; closing socket
862 write limit reached; closing socket
863 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=getbundle': (glob)
863 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=getbundle': (glob)
864 Traceback (most recent call last):
864 Traceback (most recent call last):
865 Exception: connection closed after sending N bytes
865 Exception: connection closed after sending N bytes
866
866
867 write(27) -> 15\r\nInternal Server Error\r\n
867 write(27) -> 15\r\nInternal Server Error\r\n
868 #endif
868 #endif
869
869
870 $ rm -f error.log
870 $ rm -f error.log
871
871
872 Server stops sending after bundle2 part header length
872 Server stops sending after bundle2 part header length
873
873
874 $ hg serve --config badserver.closeaftersendbytes=1020 -p $HGPORT -d --pid-file=hg.pid -E error.log
874 $ hg serve --config badserver.closeaftersendbytes=1001 -p $HGPORT -d --pid-file=hg.pid -E error.log
875 $ cat hg.pid > $DAEMON_PIDS
875 $ cat hg.pid > $DAEMON_PIDS
876
876
877 $ hg clone http://localhost:$HGPORT/ clone
877 $ hg clone http://localhost:$HGPORT/ clone
878 requesting all changes
878 requesting all changes
879 abort: HTTP request error (incomplete response)
879 abort: HTTP request error (incomplete response)
880 (this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
880 (this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
881 [255]
881 [255]
882
882
883 $ killdaemons.py $DAEMON_PIDS
883 $ killdaemons.py $DAEMON_PIDS
884
884
885 #if py36
885 #if py36
886 $ "$PYTHON" $TESTDIR/filtertraceback.py < error.log | tail -11
886 $ "$PYTHON" $TESTDIR/filtertraceback.py < error.log | tail -11
887 sendall(167 from 167) -> (42) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.2\r\nTransfer-Encoding: chunked\r\n\r\n
887 sendall(167 from 167) -> (42) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.2\r\nTransfer-Encoding: chunked\r\n\r\n
888 sendall(6 from 6) -> (36) 1\\r\\n\x04\\r\\n (esc)
888 sendall(6 from 6) -> (36) 1\\r\\n\x04\\r\\n (esc)
889 sendall(9 from 9) -> (27) 4\r\nnone\r\n
889 sendall(9 from 9) -> (27) 4\r\nnone\r\n
890 sendall(9 from 9) -> (18) 4\r\nHG20\r\n
890 sendall(9 from 9) -> (18) 4\r\nHG20\r\n
891 sendall(9 from 9) -> (9) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
891 sendall(9 from 9) -> (9) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
892 sendall(9 from 9) -> (0) 4\\r\\n\x00\x00\x00)\\r\\n (esc)
892 sendall(9 from 9) -> (0) 4\\r\\n\x00\x00\x00)\\r\\n (esc)
893 write limit reached; closing socket
893 write limit reached; closing socket
894 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=getbundle': (glob)
894 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=getbundle': (glob)
895 Traceback (most recent call last):
895 Traceback (most recent call last):
896 Exception: connection closed after sending N bytes
896 Exception: connection closed after sending N bytes
897
897
898
898
899 #else
899 #else
900
900
901 $ "$PYTHON" $TESTDIR/filtertraceback.py < error.log | tail -13
901 $ "$PYTHON" $TESTDIR/filtertraceback.py < error.log | tail -13
902 readline(65537) -> (2) \r\n (py3 !)
902 readline(65537) -> (2) \r\n (py3 !)
903 write(167 from 167) -> (42) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.2\r\nTransfer-Encoding: chunked\r\n\r\n (py3 !)
903 write(167 from 167) -> (42) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.2\r\nTransfer-Encoding: chunked\r\n\r\n (py3 !)
904 write(28 from 28) -> (44) Transfer-Encoding: chunked\r\n (no-py3 !)
904 write(28 from 28) -> (44) Transfer-Encoding: chunked\r\n (no-py3 !)
905 write(2 from 2) -> (42) \r\n (no-py3 !)
905 write(2 from 2) -> (42) \r\n (no-py3 !)
906 write(6 from 6) -> (36) 1\\r\\n\x04\\r\\n (esc)
906 write(6 from 6) -> (36) 1\\r\\n\x04\\r\\n (esc)
907 write(9 from 9) -> (27) 4\r\nnone\r\n
907 write(9 from 9) -> (27) 4\r\nnone\r\n
908 write(9 from 9) -> (18) 4\r\nHG20\r\n
908 write(9 from 9) -> (18) 4\r\nHG20\r\n
909 write(9 from 9) -> (9) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
909 write(9 from 9) -> (9) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
910 write(9 from 9) -> (0) 4\\r\\n\x00\x00\x00)\\r\\n (esc)
910 write(9 from 9) -> (0) 4\\r\\n\x00\x00\x00)\\r\\n (esc)
911 write limit reached; closing socket
911 write limit reached; closing socket
912 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=getbundle': (glob)
912 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=getbundle': (glob)
913 Traceback (most recent call last):
913 Traceback (most recent call last):
914 Exception: connection closed after sending N bytes
914 Exception: connection closed after sending N bytes
915
915
916 write(27) -> 15\r\nInternal Server Error\r\n
916 write(27) -> 15\r\nInternal Server Error\r\n
917 #endif
917 #endif
918
918
919 $ rm -f error.log
919 $ rm -f error.log
920
920
921 Server stops sending after bundle2 part header
921 Server stops sending after bundle2 part header
922
922
923 $ hg serve --config badserver.closeaftersendbytes=1067 -p $HGPORT -d --pid-file=hg.pid -E error.log
923 $ hg serve --config badserver.closeaftersendbytes=1048 -p $HGPORT -d --pid-file=hg.pid -E error.log
924 $ cat hg.pid > $DAEMON_PIDS
924 $ cat hg.pid > $DAEMON_PIDS
925
925
926 $ hg clone http://localhost:$HGPORT/ clone
926 $ hg clone http://localhost:$HGPORT/ clone
927 requesting all changes
927 requesting all changes
928 adding changesets
928 adding changesets
929 transaction abort!
929 transaction abort!
930 rollback completed
930 rollback completed
931 abort: HTTP request error (incomplete response)
931 abort: HTTP request error (incomplete response)
932 (this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
932 (this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
933 [255]
933 [255]
934
934
935 $ killdaemons.py $DAEMON_PIDS
935 $ killdaemons.py $DAEMON_PIDS
936
936
937 #if py36
937 #if py36
938 $ "$PYTHON" $TESTDIR/filtertraceback.py < error.log | tail -12
938 $ "$PYTHON" $TESTDIR/filtertraceback.py < error.log | tail -12
939 sendall(167 from 167) -> (89) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.2\r\nTransfer-Encoding: chunked\r\n\r\n
939 sendall(167 from 167) -> (89) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.2\r\nTransfer-Encoding: chunked\r\n\r\n
940 sendall(6 from 6) -> (83) 1\\r\\n\x04\\r\\n (esc)
940 sendall(6 from 6) -> (83) 1\\r\\n\x04\\r\\n (esc)
941 sendall(9 from 9) -> (74) 4\r\nnone\r\n
941 sendall(9 from 9) -> (74) 4\r\nnone\r\n
942 sendall(9 from 9) -> (65) 4\r\nHG20\r\n
942 sendall(9 from 9) -> (65) 4\r\nHG20\r\n
943 sendall(9 from 9) -> (56) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
943 sendall(9 from 9) -> (56) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
944 sendall(9 from 9) -> (47) 4\\r\\n\x00\x00\x00)\\r\\n (esc)
944 sendall(9 from 9) -> (47) 4\\r\\n\x00\x00\x00)\\r\\n (esc)
945 sendall(47 from 47) -> (0) 29\\r\\n\x0bCHANGEGROUP\x00\x00\x00\x00\x01\x01\x07\x02 \x01version02nbchanges1\\r\\n (esc)
945 sendall(47 from 47) -> (0) 29\\r\\n\x0bCHANGEGROUP\x00\x00\x00\x00\x01\x01\x07\x02 \x01version02nbchanges1\\r\\n (esc)
946 write limit reached; closing socket
946 write limit reached; closing socket
947 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=getbundle': (glob)
947 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=getbundle': (glob)
948 Traceback (most recent call last):
948 Traceback (most recent call last):
949 Exception: connection closed after sending N bytes
949 Exception: connection closed after sending N bytes
950
950
951
951
952 #else
952 #else
953 $ "$PYTHON" $TESTDIR/filtertraceback.py < error.log | tail -14
953 $ "$PYTHON" $TESTDIR/filtertraceback.py < error.log | tail -14
954 readline(65537) -> (2) \r\n (py3 !)
954 readline(65537) -> (2) \r\n (py3 !)
955 write(167 from 167) -> (89) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.2\r\nTransfer-Encoding: chunked\r\n\r\n (py3 !)
955 write(167 from 167) -> (89) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.2\r\nTransfer-Encoding: chunked\r\n\r\n (py3 !)
956 write(28 from 28) -> (91) Transfer-Encoding: chunked\r\n (no-py3 !)
956 write(28 from 28) -> (91) Transfer-Encoding: chunked\r\n (no-py3 !)
957 write(2 from 2) -> (89) \r\n (no-py3 !)
957 write(2 from 2) -> (89) \r\n (no-py3 !)
958 write(6 from 6) -> (83) 1\\r\\n\x04\\r\\n (esc)
958 write(6 from 6) -> (83) 1\\r\\n\x04\\r\\n (esc)
959 write(9 from 9) -> (74) 4\r\nnone\r\n
959 write(9 from 9) -> (74) 4\r\nnone\r\n
960 write(9 from 9) -> (65) 4\r\nHG20\r\n
960 write(9 from 9) -> (65) 4\r\nHG20\r\n
961 write(9 from 9) -> (56) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
961 write(9 from 9) -> (56) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
962 write(9 from 9) -> (47) 4\\r\\n\x00\x00\x00)\\r\\n (esc)
962 write(9 from 9) -> (47) 4\\r\\n\x00\x00\x00)\\r\\n (esc)
963 write(47 from 47) -> (0) 29\\r\\n\x0bCHANGEGROUP\x00\x00\x00\x00\x01\x01\x07\x02 \x01version02nbchanges1\\r\\n (esc)
963 write(47 from 47) -> (0) 29\\r\\n\x0bCHANGEGROUP\x00\x00\x00\x00\x01\x01\x07\x02 \x01version02nbchanges1\\r\\n (esc)
964 write limit reached; closing socket
964 write limit reached; closing socket
965 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=getbundle': (glob)
965 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=getbundle': (glob)
966 Traceback (most recent call last):
966 Traceback (most recent call last):
967 Exception: connection closed after sending N bytes
967 Exception: connection closed after sending N bytes
968
968
969 write(27) -> 15\r\nInternal Server Error\r\n
969 write(27) -> 15\r\nInternal Server Error\r\n
970 #endif
970 #endif
971
971
972 $ rm -f error.log
972 $ rm -f error.log
973
973
974 Server stops after bundle2 part payload chunk size
974 Server stops after bundle2 part payload chunk size
975
975
976 $ hg serve --config badserver.closeaftersendbytes=1088 -p $HGPORT -d --pid-file=hg.pid -E error.log
976 $ hg serve --config badserver.closeaftersendbytes=1069 -p $HGPORT -d --pid-file=hg.pid -E error.log
977 $ cat hg.pid > $DAEMON_PIDS
977 $ cat hg.pid > $DAEMON_PIDS
978
978
979 $ hg clone http://localhost:$HGPORT/ clone
979 $ hg clone http://localhost:$HGPORT/ clone
980 requesting all changes
980 requesting all changes
981 adding changesets
981 adding changesets
982 transaction abort!
982 transaction abort!
983 rollback completed
983 rollback completed
984 abort: HTTP request error (incomplete response) (py3 !)
984 abort: HTTP request error (incomplete response) (py3 !)
985 abort: HTTP request error (incomplete response; expected 466 bytes got 7) (no-py3 !)
985 abort: HTTP request error (incomplete response; expected 466 bytes got 7) (no-py3 !)
986 (this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
986 (this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
987 [255]
987 [255]
988
988
989 $ killdaemons.py $DAEMON_PIDS
989 $ killdaemons.py $DAEMON_PIDS
990
990
991 #if py36
991 #if py36
992 $ "$PYTHON" $TESTDIR/filtertraceback.py < error.log | tail -14
992 $ "$PYTHON" $TESTDIR/filtertraceback.py < error.log | tail -14
993 sendall(167 from 167) -> (110) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.2\r\nTransfer-Encoding: chunked\r\n\r\n
993 sendall(167 from 167) -> (110) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.2\r\nTransfer-Encoding: chunked\r\n\r\n
994 sendall(6 from 6) -> (104) 1\\r\\n\x04\\r\\n (esc)
994 sendall(6 from 6) -> (104) 1\\r\\n\x04\\r\\n (esc)
995 sendall(9 from 9) -> (95) 4\r\nnone\r\n
995 sendall(9 from 9) -> (95) 4\r\nnone\r\n
996 sendall(9 from 9) -> (86) 4\r\nHG20\r\n
996 sendall(9 from 9) -> (86) 4\r\nHG20\r\n
997 sendall(9 from 9) -> (77) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
997 sendall(9 from 9) -> (77) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
998 sendall(9 from 9) -> (68) 4\\r\\n\x00\x00\x00)\\r\\n (esc)
998 sendall(9 from 9) -> (68) 4\\r\\n\x00\x00\x00)\\r\\n (esc)
999 sendall(47 from 47) -> (21) 29\\r\\n\x0bCHANGEGROUP\x00\x00\x00\x00\x01\x01\x07\x02 \x01version02nbchanges1\\r\\n (esc)
999 sendall(47 from 47) -> (21) 29\\r\\n\x0bCHANGEGROUP\x00\x00\x00\x00\x01\x01\x07\x02 \x01version02nbchanges1\\r\\n (esc)
1000 sendall(9 from 9) -> (12) 4\\r\\n\x00\x00\x01\xd2\\r\\n (esc)
1000 sendall(9 from 9) -> (12) 4\\r\\n\x00\x00\x01\xd2\\r\\n (esc)
1001 sendall(12 from 473) -> (0) 1d2\\r\\n\x00\x00\x00\xb2\x96\xee\x1d (esc)
1001 sendall(12 from 473) -> (0) 1d2\\r\\n\x00\x00\x00\xb2\x96\xee\x1d (esc)
1002 write limit reached; closing socket
1002 write limit reached; closing socket
1003 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=getbundle': (glob)
1003 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=getbundle': (glob)
1004 Traceback (most recent call last):
1004 Traceback (most recent call last):
1005 Exception: connection closed after sending N bytes
1005 Exception: connection closed after sending N bytes
1006
1006
1007
1007
1008 #else
1008 #else
1009 $ "$PYTHON" $TESTDIR/filtertraceback.py < error.log | tail -15
1009 $ "$PYTHON" $TESTDIR/filtertraceback.py < error.log | tail -15
1010 write(167 from 167) -> (110) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.2\r\nTransfer-Encoding: chunked\r\n\r\n (py3 !)
1010 write(167 from 167) -> (110) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.2\r\nTransfer-Encoding: chunked\r\n\r\n (py3 !)
1011 write(2 from 2) -> (110) \r\n (no-py3 !)
1011 write(2 from 2) -> (110) \r\n (no-py3 !)
1012 write(6 from 6) -> (104) 1\\r\\n\x04\\r\\n (esc)
1012 write(6 from 6) -> (104) 1\\r\\n\x04\\r\\n (esc)
1013 write(9 from 9) -> (95) 4\r\nnone\r\n
1013 write(9 from 9) -> (95) 4\r\nnone\r\n
1014 write(9 from 9) -> (86) 4\r\nHG20\r\n
1014 write(9 from 9) -> (86) 4\r\nHG20\r\n
1015 write(9 from 9) -> (77) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
1015 write(9 from 9) -> (77) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
1016 write(9 from 9) -> (68) 4\\r\\n\x00\x00\x00)\\r\\n (esc)
1016 write(9 from 9) -> (68) 4\\r\\n\x00\x00\x00)\\r\\n (esc)
1017 write(47 from 47) -> (21) 29\\r\\n\x0bCHANGEGROUP\x00\x00\x00\x00\x01\x01\x07\x02 \x01version02nbchanges1\\r\\n (esc)
1017 write(47 from 47) -> (21) 29\\r\\n\x0bCHANGEGROUP\x00\x00\x00\x00\x01\x01\x07\x02 \x01version02nbchanges1\\r\\n (esc)
1018 write(9 from 9) -> (12) 4\\r\\n\x00\x00\x01\xd2\\r\\n (esc)
1018 write(9 from 9) -> (12) 4\\r\\n\x00\x00\x01\xd2\\r\\n (esc)
1019 write(12 from 473) -> (0) 1d2\\r\\n\x00\x00\x00\xb2\x96\xee\x1d (esc)
1019 write(12 from 473) -> (0) 1d2\\r\\n\x00\x00\x00\xb2\x96\xee\x1d (esc)
1020 write limit reached; closing socket
1020 write limit reached; closing socket
1021 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=getbundle': (glob)
1021 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=getbundle': (glob)
1022 Traceback (most recent call last):
1022 Traceback (most recent call last):
1023 Exception: connection closed after sending N bytes
1023 Exception: connection closed after sending N bytes
1024
1024
1025 write(27) -> 15\r\nInternal Server Error\r\n
1025 write(27) -> 15\r\nInternal Server Error\r\n
1026 #endif
1026 #endif
1027
1027
1028 $ rm -f error.log
1028 $ rm -f error.log
1029
1029
1030 Server stops sending in middle of bundle2 payload chunk
1030 Server stops sending in middle of bundle2 payload chunk
1031
1031
1032 $ hg serve --config badserver.closeaftersendbytes=1549 -p $HGPORT -d --pid-file=hg.pid -E error.log
1032 $ hg serve --config badserver.closeaftersendbytes=1530 -p $HGPORT -d --pid-file=hg.pid -E error.log
1033 $ cat hg.pid > $DAEMON_PIDS
1033 $ cat hg.pid > $DAEMON_PIDS
1034
1034
1035 $ hg clone http://localhost:$HGPORT/ clone
1035 $ hg clone http://localhost:$HGPORT/ clone
1036 requesting all changes
1036 requesting all changes
1037 adding changesets
1037 adding changesets
1038 transaction abort!
1038 transaction abort!
1039 rollback completed
1039 rollback completed
1040 abort: HTTP request error (incomplete response)
1040 abort: HTTP request error (incomplete response)
1041 (this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
1041 (this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
1042 [255]
1042 [255]
1043
1043
1044 $ killdaemons.py $DAEMON_PIDS
1044 $ killdaemons.py $DAEMON_PIDS
1045
1045
1046 #if py36
1046 #if py36
1047 $ "$PYTHON" $TESTDIR/filtertraceback.py < error.log | tail -14
1047 $ "$PYTHON" $TESTDIR/filtertraceback.py < error.log | tail -14
1048 sendall(167 from 167) -> (571) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.2\r\nTransfer-Encoding: chunked\r\n\r\n
1048 sendall(167 from 167) -> (571) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.2\r\nTransfer-Encoding: chunked\r\n\r\n
1049 sendall(6 from 6) -> (565) 1\\r\\n\x04\\r\\n (esc)
1049 sendall(6 from 6) -> (565) 1\\r\\n\x04\\r\\n (esc)
1050 sendall(9 from 9) -> (556) 4\r\nnone\r\n
1050 sendall(9 from 9) -> (556) 4\r\nnone\r\n
1051 sendall(9 from 9) -> (547) 4\r\nHG20\r\n
1051 sendall(9 from 9) -> (547) 4\r\nHG20\r\n
1052 sendall(9 from 9) -> (538) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
1052 sendall(9 from 9) -> (538) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
1053 sendall(9 from 9) -> (529) 4\\r\\n\x00\x00\x00)\\r\\n (esc)
1053 sendall(9 from 9) -> (529) 4\\r\\n\x00\x00\x00)\\r\\n (esc)
1054 sendall(47 from 47) -> (482) 29\\r\\n\x0bCHANGEGROUP\x00\x00\x00\x00\x01\x01\x07\x02 \x01version02nbchanges1\\r\\n (esc)
1054 sendall(47 from 47) -> (482) 29\\r\\n\x0bCHANGEGROUP\x00\x00\x00\x00\x01\x01\x07\x02 \x01version02nbchanges1\\r\\n (esc)
1055 sendall(9 from 9) -> (473) 4\\r\\n\x00\x00\x01\xd2\\r\\n (esc)
1055 sendall(9 from 9) -> (473) 4\\r\\n\x00\x00\x01\xd2\\r\\n (esc)
1056 sendall(473 from 473) -> (0) 1d2\\r\\n\x00\x00\x00\xb2\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>6a3df4de388f3c4f8e28f4f9a814299a3cbb5f50\\ntest\\n0 0\\nfoo\\n\\ninitial\x00\x00\x00\x00\x00\x00\x00\xa1j=\xf4\xde8\x8f<O\x8e(\xf4\xf9\xa8\x14)\x9a<\xbb_P\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00b80de5d138758541c5f05265ad144ab9fa86d1db\\n\x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00h\xb8\\r\xe5\xd18u\x85A\xc5\xf0Re\xad\x14J\xb9\xfa\x86\xd1\xdb\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\\r\\n (esc)
1056 sendall(473 from 473) -> (0) 1d2\\r\\n\x00\x00\x00\xb2\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>6a3df4de388f3c4f8e28f4f9a814299a3cbb5f50\\ntest\\n0 0\\nfoo\\n\\ninitial\x00\x00\x00\x00\x00\x00\x00\xa1j=\xf4\xde8\x8f<O\x8e(\xf4\xf9\xa8\x14)\x9a<\xbb_P\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00b80de5d138758541c5f05265ad144ab9fa86d1db\\n\x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00h\xb8\\r\xe5\xd18u\x85A\xc5\xf0Re\xad\x14J\xb9\xfa\x86\xd1\xdb\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\\r\\n (esc)
1057 write limit reached; closing socket
1057 write limit reached; closing socket
1058 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=getbundle': (glob)
1058 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=getbundle': (glob)
1059 Traceback (most recent call last):
1059 Traceback (most recent call last):
1060 Exception: connection closed after sending N bytes
1060 Exception: connection closed after sending N bytes
1061
1061
1062
1062
1063 #else
1063 #else
1064 $ "$PYTHON" $TESTDIR/filtertraceback.py < error.log | tail -16
1064 $ "$PYTHON" $TESTDIR/filtertraceback.py < error.log | tail -16
1065 readline(65537) -> (2) \r\n (py3 !)
1065 readline(65537) -> (2) \r\n (py3 !)
1066 write(167 from 167) -> (571) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.2\r\nTransfer-Encoding: chunked\r\n\r\n (py3 !)
1066 write(167 from 167) -> (571) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.2\r\nTransfer-Encoding: chunked\r\n\r\n (py3 !)
1067 write(28 from 28) -> (573) Transfer-Encoding: chunked\r\n (no-py3 !)
1067 write(28 from 28) -> (573) Transfer-Encoding: chunked\r\n (no-py3 !)
1068 write(2 from 2) -> (571) \r\n (no-py3 !)
1068 write(2 from 2) -> (571) \r\n (no-py3 !)
1069 write(6 from 6) -> (565) 1\\r\\n\x04\\r\\n (esc)
1069 write(6 from 6) -> (565) 1\\r\\n\x04\\r\\n (esc)
1070 write(9 from 9) -> (556) 4\r\nnone\r\n
1070 write(9 from 9) -> (556) 4\r\nnone\r\n
1071 write(9 from 9) -> (547) 4\r\nHG20\r\n
1071 write(9 from 9) -> (547) 4\r\nHG20\r\n
1072 write(9 from 9) -> (538) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
1072 write(9 from 9) -> (538) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
1073 write(9 from 9) -> (529) 4\\r\\n\x00\x00\x00)\\r\\n (esc)
1073 write(9 from 9) -> (529) 4\\r\\n\x00\x00\x00)\\r\\n (esc)
1074 write(47 from 47) -> (482) 29\\r\\n\x0bCHANGEGROUP\x00\x00\x00\x00\x01\x01\x07\x02 \x01version02nbchanges1\\r\\n (esc)
1074 write(47 from 47) -> (482) 29\\r\\n\x0bCHANGEGROUP\x00\x00\x00\x00\x01\x01\x07\x02 \x01version02nbchanges1\\r\\n (esc)
1075 write(9 from 9) -> (473) 4\\r\\n\x00\x00\x01\xd2\\r\\n (esc)
1075 write(9 from 9) -> (473) 4\\r\\n\x00\x00\x01\xd2\\r\\n (esc)
1076 write(473 from 473) -> (0) 1d2\\r\\n\x00\x00\x00\xb2\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>6a3df4de388f3c4f8e28f4f9a814299a3cbb5f50\\ntest\\n0 0\\nfoo\\n\\ninitial\x00\x00\x00\x00\x00\x00\x00\xa1j=\xf4\xde8\x8f<O\x8e(\xf4\xf9\xa8\x14)\x9a<\xbb_P\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00b80de5d138758541c5f05265ad144ab9fa86d1db\\n\x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00h\xb8\\r\xe5\xd18u\x85A\xc5\xf0Re\xad\x14J\xb9\xfa\x86\xd1\xdb\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\\r\\n (esc)
1076 write(473 from 473) -> (0) 1d2\\r\\n\x00\x00\x00\xb2\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>6a3df4de388f3c4f8e28f4f9a814299a3cbb5f50\\ntest\\n0 0\\nfoo\\n\\ninitial\x00\x00\x00\x00\x00\x00\x00\xa1j=\xf4\xde8\x8f<O\x8e(\xf4\xf9\xa8\x14)\x9a<\xbb_P\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00b80de5d138758541c5f05265ad144ab9fa86d1db\\n\x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00h\xb8\\r\xe5\xd18u\x85A\xc5\xf0Re\xad\x14J\xb9\xfa\x86\xd1\xdb\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\\r\\n (esc)
1077 write limit reached; closing socket
1077 write limit reached; closing socket
1078 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=getbundle': (glob)
1078 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=getbundle': (glob)
1079 Traceback (most recent call last):
1079 Traceback (most recent call last):
1080 Exception: connection closed after sending N bytes
1080 Exception: connection closed after sending N bytes
1081
1081
1082 write(27) -> 15\r\nInternal Server Error\r\n
1082 write(27) -> 15\r\nInternal Server Error\r\n
1083 #endif
1083 #endif
1084
1084
1085 $ rm -f error.log
1085 $ rm -f error.log
1086
1086
1087 Server stops sending after 0 length payload chunk size
1087 Server stops sending after 0 length payload chunk size
1088
1088
1089 $ hg serve --config badserver.closeaftersendbytes=1580 -p $HGPORT -d --pid-file=hg.pid -E error.log
1089 $ hg serve --config badserver.closeaftersendbytes=1561 -p $HGPORT -d --pid-file=hg.pid -E error.log
1090 $ cat hg.pid > $DAEMON_PIDS
1090 $ cat hg.pid > $DAEMON_PIDS
1091
1091
1092 $ hg clone http://localhost:$HGPORT/ clone
1092 $ hg clone http://localhost:$HGPORT/ clone
1093 requesting all changes
1093 requesting all changes
1094 adding changesets
1094 adding changesets
1095 adding manifests
1095 adding manifests
1096 adding file changes
1096 adding file changes
1097 transaction abort!
1097 transaction abort!
1098 rollback completed
1098 rollback completed
1099 abort: HTTP request error (incomplete response) (py3 !)
1099 abort: HTTP request error (incomplete response) (py3 !)
1100 abort: HTTP request error (incomplete response; expected 32 bytes got 9) (no-py3 !)
1100 abort: HTTP request error (incomplete response; expected 32 bytes got 9) (no-py3 !)
1101 (this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
1101 (this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
1102 [255]
1102 [255]
1103
1103
1104 $ killdaemons.py $DAEMON_PIDS
1104 $ killdaemons.py $DAEMON_PIDS
1105
1105
1106 #if py36
1106 #if py36
1107 $ "$PYTHON" $TESTDIR/filtertraceback.py < error.log | tail -16
1107 $ "$PYTHON" $TESTDIR/filtertraceback.py < error.log | tail -16
1108 sendall(6 from 6) -> (596) 1\\r\\n\x04\\r\\n (esc)
1108 sendall(6 from 6) -> (596) 1\\r\\n\x04\\r\\n (esc)
1109 sendall(9 from 9) -> (587) 4\r\nnone\r\n
1109 sendall(9 from 9) -> (587) 4\r\nnone\r\n
1110 sendall(9 from 9) -> (578) 4\r\nHG20\r\n
1110 sendall(9 from 9) -> (578) 4\r\nHG20\r\n
1111 sendall(9 from 9) -> (569) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
1111 sendall(9 from 9) -> (569) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
1112 sendall(9 from 9) -> (560) 4\\r\\n\x00\x00\x00)\\r\\n (esc)
1112 sendall(9 from 9) -> (560) 4\\r\\n\x00\x00\x00)\\r\\n (esc)
1113 sendall(47 from 47) -> (513) 29\\r\\n\x0bCHANGEGROUP\x00\x00\x00\x00\x01\x01\x07\x02 \x01version02nbchanges1\\r\\n (esc)
1113 sendall(47 from 47) -> (513) 29\\r\\n\x0bCHANGEGROUP\x00\x00\x00\x00\x01\x01\x07\x02 \x01version02nbchanges1\\r\\n (esc)
1114 sendall(9 from 9) -> (504) 4\\r\\n\x00\x00\x01\xd2\\r\\n (esc)
1114 sendall(9 from 9) -> (504) 4\\r\\n\x00\x00\x01\xd2\\r\\n (esc)
1115 sendall(473 from 473) -> (31) 1d2\\r\\n\x00\x00\x00\xb2\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>6a3df4de388f3c4f8e28f4f9a814299a3cbb5f50\\ntest\\n0 0\\nfoo\\n\\ninitial\x00\x00\x00\x00\x00\x00\x00\xa1j=\xf4\xde8\x8f<O\x8e(\xf4\xf9\xa8\x14)\x9a<\xbb_P\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00b80de5d138758541c5f05265ad144ab9fa86d1db\\n\x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00h\xb8\\r\xe5\xd18u\x85A\xc5\xf0Re\xad\x14J\xb9\xfa\x86\xd1\xdb\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\\r\\n (esc)
1115 sendall(473 from 473) -> (31) 1d2\\r\\n\x00\x00\x00\xb2\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>6a3df4de388f3c4f8e28f4f9a814299a3cbb5f50\\ntest\\n0 0\\nfoo\\n\\ninitial\x00\x00\x00\x00\x00\x00\x00\xa1j=\xf4\xde8\x8f<O\x8e(\xf4\xf9\xa8\x14)\x9a<\xbb_P\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00b80de5d138758541c5f05265ad144ab9fa86d1db\\n\x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00h\xb8\\r\xe5\xd18u\x85A\xc5\xf0Re\xad\x14J\xb9\xfa\x86\xd1\xdb\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\\r\\n (esc)
1116 sendall(9 from 9) -> (22) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
1116 sendall(9 from 9) -> (22) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
1117 sendall(9 from 9) -> (13) 4\\r\\n\x00\x00\x00 \\r\\n (esc)
1117 sendall(9 from 9) -> (13) 4\\r\\n\x00\x00\x00 \\r\\n (esc)
1118 sendall(13 from 38) -> (0) 20\\r\\n\x08LISTKEYS (esc)
1118 sendall(13 from 38) -> (0) 20\\r\\n\x08LISTKEYS (esc)
1119 write limit reached; closing socket
1119 write limit reached; closing socket
1120 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=getbundle': (glob)
1120 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=getbundle': (glob)
1121 Traceback (most recent call last):
1121 Traceback (most recent call last):
1122 Exception: connection closed after sending N bytes
1122 Exception: connection closed after sending N bytes
1123
1123
1124
1124
1125 #else
1125 #else
1126 $ "$PYTHON" $TESTDIR/filtertraceback.py < error.log | tail -17
1126 $ "$PYTHON" $TESTDIR/filtertraceback.py < error.log | tail -17
1127 write(6 from 6) -> (596) 1\\r\\n\x04\\r\\n (esc)
1127 write(6 from 6) -> (596) 1\\r\\n\x04\\r\\n (esc)
1128 write(9 from 9) -> (587) 4\r\nnone\r\n
1128 write(9 from 9) -> (587) 4\r\nnone\r\n
1129 write(9 from 9) -> (578) 4\r\nHG20\r\n
1129 write(9 from 9) -> (578) 4\r\nHG20\r\n
1130 write(9 from 9) -> (569) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
1130 write(9 from 9) -> (569) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
1131 write(9 from 9) -> (560) 4\\r\\n\x00\x00\x00)\\r\\n (esc)
1131 write(9 from 9) -> (560) 4\\r\\n\x00\x00\x00)\\r\\n (esc)
1132 write(47 from 47) -> (513) 29\\r\\n\x0bCHANGEGROUP\x00\x00\x00\x00\x01\x01\x07\x02 \x01version02nbchanges1\\r\\n (esc)
1132 write(47 from 47) -> (513) 29\\r\\n\x0bCHANGEGROUP\x00\x00\x00\x00\x01\x01\x07\x02 \x01version02nbchanges1\\r\\n (esc)
1133 write(9 from 9) -> (504) 4\\r\\n\x00\x00\x01\xd2\\r\\n (esc)
1133 write(9 from 9) -> (504) 4\\r\\n\x00\x00\x01\xd2\\r\\n (esc)
1134 write(473 from 473) -> (31) 1d2\\r\\n\x00\x00\x00\xb2\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>6a3df4de388f3c4f8e28f4f9a814299a3cbb5f50\\ntest\\n0 0\\nfoo\\n\\ninitial\x00\x00\x00\x00\x00\x00\x00\xa1j=\xf4\xde8\x8f<O\x8e(\xf4\xf9\xa8\x14)\x9a<\xbb_P\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00b80de5d138758541c5f05265ad144ab9fa86d1db\\n\x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00h\xb8\\r\xe5\xd18u\x85A\xc5\xf0Re\xad\x14J\xb9\xfa\x86\xd1\xdb\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\\r\\n (esc)
1134 write(473 from 473) -> (31) 1d2\\r\\n\x00\x00\x00\xb2\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>6a3df4de388f3c4f8e28f4f9a814299a3cbb5f50\\ntest\\n0 0\\nfoo\\n\\ninitial\x00\x00\x00\x00\x00\x00\x00\xa1j=\xf4\xde8\x8f<O\x8e(\xf4\xf9\xa8\x14)\x9a<\xbb_P\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00b80de5d138758541c5f05265ad144ab9fa86d1db\\n\x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00h\xb8\\r\xe5\xd18u\x85A\xc5\xf0Re\xad\x14J\xb9\xfa\x86\xd1\xdb\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\\r\\n (esc)
1135 write(9 from 9) -> (22) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
1135 write(9 from 9) -> (22) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
1136 write(9 from 9) -> (13) 4\\r\\n\x00\x00\x00 \\r\\n (esc)
1136 write(9 from 9) -> (13) 4\\r\\n\x00\x00\x00 \\r\\n (esc)
1137 write(13 from 38) -> (0) 20\\r\\n\x08LISTKEYS (esc)
1137 write(13 from 38) -> (0) 20\\r\\n\x08LISTKEYS (esc)
1138 write limit reached; closing socket
1138 write limit reached; closing socket
1139 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=getbundle': (glob)
1139 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=getbundle': (glob)
1140 Traceback (most recent call last):
1140 Traceback (most recent call last):
1141 Exception: connection closed after sending N bytes
1141 Exception: connection closed after sending N bytes
1142
1142
1143 write(27) -> 15\r\nInternal Server Error\r\n
1143 write(27) -> 15\r\nInternal Server Error\r\n
1144 #endif
1144 #endif
1145
1145
1146 $ rm -f error.log
1146 $ rm -f error.log
1147
1147
1148 Server stops sending after 0 part bundle part header (indicating end of bundle2 payload)
1148 Server stops sending after 0 part bundle part header (indicating end of bundle2 payload)
1149 This is before the 0 size chunked transfer part that signals end of HTTP response.
1149 This is before the 0 size chunked transfer part that signals end of HTTP response.
1150
1150
1151 # $ hg serve --config badserver.closeaftersendbytes=1755 -p $HGPORT -d --pid-file=hg.pid -E error.log
1151 $ hg serve --config badserver.closeaftersendbytes=1736 -p $HGPORT -d --pid-file=hg.pid -E error.log
1152 $ hg serve --config badserver.closeaftersendbytes=1862 -p $HGPORT -d --pid-file=hg.pid -E error.log
1153 $ cat hg.pid > $DAEMON_PIDS
1152 $ cat hg.pid > $DAEMON_PIDS
1154
1153
1155 $ hg clone http://localhost:$HGPORT/ clone
1154 $ hg clone http://localhost:$HGPORT/ clone
1156 requesting all changes
1155 requesting all changes
1157 adding changesets
1156 adding changesets
1158 adding manifests
1157 adding manifests
1159 adding file changes
1158 adding file changes
1160 added 1 changesets with 1 changes to 1 files
1159 added 1 changesets with 1 changes to 1 files
1161 new changesets 96ee1d7354c4
1160 new changesets 96ee1d7354c4
1162 updating to branch default
1161 updating to branch default
1163 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1162 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1164
1163
1165 $ killdaemons.py $DAEMON_PIDS
1164 $ killdaemons.py $DAEMON_PIDS
1166
1165
1167 #if py36
1166 #if py36
1168 $ "$PYTHON" $TESTDIR/filtertraceback.py < error.log | tail -25
1167 $ "$PYTHON" $TESTDIR/filtertraceback.py < error.log | tail -20
1169 sendall(9 from 9) -> (851) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
1168 sendall(9 from 9) -> (744) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
1170 sendall(9 from 9) -> (842) 4\\r\\n\x00\x00\x00)\\r\\n (esc)
1169 sendall(9 from 9) -> (735) 4\\r\\n\x00\x00\x00)\\r\\n (esc)
1171 sendall(47 from 47) -> (795) 29\\r\\n\x0bCHANGEGROUP\x00\x00\x00\x00\x01\x01\x07\x02 \x01version02nbchanges1\\r\\n (esc)
1170 sendall(47 from 47) -> (688) 29\\r\\n\x0bCHANGEGROUP\x00\x00\x00\x00\x01\x01\x07\x02 \x01version02nbchanges1\\r\\n (esc)
1172 sendall(9 from 9) -> (786) 4\\r\\n\x00\x00\x01\xd2\\r\\n (esc)
1171 sendall(9 from 9) -> (679) 4\\r\\n\x00\x00\x01\xd2\\r\\n (esc)
1173 sendall(473 from 473) -> (313) 1d2\\r\\n\x00\x00\x00\xb2\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>6a3df4de388f3c4f8e28f4f9a814299a3cbb5f50\\ntest\\n0 0\\nfoo\\n\\ninitial\x00\x00\x00\x00\x00\x00\x00\xa1j=\xf4\xde8\x8f<O\x8e(\xf4\xf9\xa8\x14)\x9a<\xbb_P\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00b80de5d138758541c5f05265ad144ab9fa86d1db\\n\x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00h\xb8\\r\xe5\xd18u\x85A\xc5\xf0Re\xad\x14J\xb9\xfa\x86\xd1\xdb\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\\r\\n (esc)
1172 sendall(473 from 473) -> (206) 1d2\\r\\n\x00\x00\x00\xb2\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>6a3df4de388f3c4f8e28f4f9a814299a3cbb5f50\\ntest\\n0 0\\nfoo\\n\\ninitial\x00\x00\x00\x00\x00\x00\x00\xa1j=\xf4\xde8\x8f<O\x8e(\xf4\xf9\xa8\x14)\x9a<\xbb_P\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00b80de5d138758541c5f05265ad144ab9fa86d1db\\n\x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00h\xb8\\r\xe5\xd18u\x85A\xc5\xf0Re\xad\x14J\xb9\xfa\x86\xd1\xdb\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\\r\\n (esc)
1174 sendall(9 from 9) -> (304) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
1173 sendall(9 from 9) -> (197) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
1175 sendall(9 from 9) -> (295) 4\\r\\n\x00\x00\x00 \\r\\n (esc)
1174 sendall(9 from 9) -> (188) 4\\r\\n\x00\x00\x00 \\r\\n (esc)
1176 sendall(38 from 38) -> (257) 20\\r\\n\x08LISTKEYS\x00\x00\x00\x01\x01\x00 \x06namespacephases\\r\\n (esc)
1175 sendall(38 from 38) -> (150) 20\\r\\n\x08LISTKEYS\x00\x00\x00\x01\x01\x00 \x06namespacephases\\r\\n (esc)
1177 sendall(9 from 9) -> (248) 4\\r\\n\x00\x00\x00:\\r\\n (esc)
1176 sendall(9 from 9) -> (141) 4\\r\\n\x00\x00\x00:\\r\\n (esc)
1178 sendall(64 from 64) -> (184) 3a\r\n96ee1d7354c4ad7372047672c36a1f561e3a6a4c 1\npublishing True\r\n
1177 sendall(64 from 64) -> (77) 3a\r\n96ee1d7354c4ad7372047672c36a1f561e3a6a4c 1\npublishing True\r\n
1179 sendall(9 from 9) -> (175) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
1178 sendall(9 from 9) -> (68) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
1180 sendall(9 from 9) -> (166) 4\\r\\n\x00\x00\x00#\\r\\n (esc)
1179 sendall(9 from 9) -> (59) 4\\r\\n\x00\x00\x00#\\r\\n (esc)
1181 sendall(41 from 41) -> (125) 23\\r\\n\x08LISTKEYS\x00\x00\x00\x02\x01\x00 namespacebookmarks\\r\\n (esc)
1180 sendall(41 from 41) -> (18) 23\\r\\n\x08LISTKEYS\x00\x00\x00\x02\x01\x00 namespacebookmarks\\r\\n (esc)
1182 sendall(9 from 9) -> (116) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
1183 sendall(9 from 9) -> (107) 4\\r\\n\x00\x00\x00\x1d\\r\\n (esc)
1184 sendall(35 from 35) -> (72) 1d\\r\\n\x16cache:rev-branch-cache\x00\x00\x00\x03\x00\x00\\r\\n (esc)
1185 sendall(9 from 9) -> (63) 4\\r\\n\x00\x00\x00'\\r\\n (esc)
1186 sendall(45 from 45) -> (18) 27\\r\\n\x00\x00\x00\x07\x00\x00\x00\x01\x00\x00\x00\x00default\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\\r\\n (esc)
1187 sendall(9 from 9) -> (9) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
1181 sendall(9 from 9) -> (9) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
1188 sendall(9 from 9) -> (0) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
1182 sendall(9 from 9) -> (0) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
1189 write limit reached; closing socket
1183 write limit reached; closing socket
1190 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=getbundle': (glob)
1184 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=getbundle': (glob)
1191 Traceback (most recent call last):
1185 Traceback (most recent call last):
1192 Exception: connection closed after sending N bytes
1186 Exception: connection closed after sending N bytes
1193
1187
1194
1188
1195 #else
1189 #else
1196 $ "$PYTHON" $TESTDIR/filtertraceback.py < error.log | tail -26
1190 $ "$PYTHON" $TESTDIR/filtertraceback.py < error.log | tail -21
1197 write(9 from 9) -> (851) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
1191 write(9 from 9) -> (744) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
1198 write(9 from 9) -> (842) 4\\r\\n\x00\x00\x00)\\r\\n (esc)
1192 write(9 from 9) -> (735) 4\\r\\n\x00\x00\x00)\\r\\n (esc)
1199 write(47 from 47) -> (795) 29\\r\\n\x0bCHANGEGROUP\x00\x00\x00\x00\x01\x01\x07\x02 \x01version02nbchanges1\\r\\n (esc)
1193 write(47 from 47) -> (688) 29\\r\\n\x0bCHANGEGROUP\x00\x00\x00\x00\x01\x01\x07\x02 \x01version02nbchanges1\\r\\n (esc)
1200 write(9 from 9) -> (786) 4\\r\\n\x00\x00\x01\xd2\\r\\n (esc)
1194 write(9 from 9) -> (679) 4\\r\\n\x00\x00\x01\xd2\\r\\n (esc)
1201 write(473 from 473) -> (313) 1d2\\r\\n\x00\x00\x00\xb2\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>6a3df4de388f3c4f8e28f4f9a814299a3cbb5f50\\ntest\\n0 0\\nfoo\\n\\ninitial\x00\x00\x00\x00\x00\x00\x00\xa1j=\xf4\xde8\x8f<O\x8e(\xf4\xf9\xa8\x14)\x9a<\xbb_P\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00b80de5d138758541c5f05265ad144ab9fa86d1db\\n\x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00h\xb8\\r\xe5\xd18u\x85A\xc5\xf0Re\xad\x14J\xb9\xfa\x86\xd1\xdb\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\\r\\n (esc)
1195 write(473 from 473) -> (206) 1d2\\r\\n\x00\x00\x00\xb2\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>6a3df4de388f3c4f8e28f4f9a814299a3cbb5f50\\ntest\\n0 0\\nfoo\\n\\ninitial\x00\x00\x00\x00\x00\x00\x00\xa1j=\xf4\xde8\x8f<O\x8e(\xf4\xf9\xa8\x14)\x9a<\xbb_P\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00b80de5d138758541c5f05265ad144ab9fa86d1db\\n\x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00h\xb8\\r\xe5\xd18u\x85A\xc5\xf0Re\xad\x14J\xb9\xfa\x86\xd1\xdb\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\\r\\n (esc)
1202 write(9 from 9) -> (304) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
1196 write(9 from 9) -> (197) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
1203 write(9 from 9) -> (295) 4\\r\\n\x00\x00\x00 \\r\\n (esc)
1197 write(9 from 9) -> (188) 4\\r\\n\x00\x00\x00 \\r\\n (esc)
1204 write(38 from 38) -> (257) 20\\r\\n\x08LISTKEYS\x00\x00\x00\x01\x01\x00 \x06namespacephases\\r\\n (esc)
1198 write(38 from 38) -> (150) 20\\r\\n\x08LISTKEYS\x00\x00\x00\x01\x01\x00 \x06namespacephases\\r\\n (esc)
1205 write(9 from 9) -> (248) 4\\r\\n\x00\x00\x00:\\r\\n (esc)
1199 write(9 from 9) -> (141) 4\\r\\n\x00\x00\x00:\\r\\n (esc)
1206 write(64 from 64) -> (184) 3a\r\n96ee1d7354c4ad7372047672c36a1f561e3a6a4c 1\npublishing True\r\n
1200 write(64 from 64) -> (77) 3a\r\n96ee1d7354c4ad7372047672c36a1f561e3a6a4c 1\npublishing True\r\n
1207 write(9 from 9) -> (175) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
1201 write(9 from 9) -> (68) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
1208 write(9 from 9) -> (166) 4\\r\\n\x00\x00\x00#\\r\\n (esc)
1202 write(9 from 9) -> (59) 4\\r\\n\x00\x00\x00#\\r\\n (esc)
1209 write(41 from 41) -> (125) 23\\r\\n\x08LISTKEYS\x00\x00\x00\x02\x01\x00 namespacebookmarks\\r\\n (esc)
1203 write(41 from 41) -> (18) 23\\r\\n\x08LISTKEYS\x00\x00\x00\x02\x01\x00 namespacebookmarks\\r\\n (esc)
1210 write(9 from 9) -> (116) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
1211 write(9 from 9) -> (107) 4\\r\\n\x00\x00\x00\x1d\\r\\n (esc)
1212 write(35 from 35) -> (72) 1d\\r\\n\x16cache:rev-branch-cache\x00\x00\x00\x03\x00\x00\\r\\n (esc)
1213 write(9 from 9) -> (63) 4\\r\\n\x00\x00\x00'\\r\\n (esc)
1214 write(45 from 45) -> (18) 27\\r\\n\x00\x00\x00\x07\x00\x00\x00\x01\x00\x00\x00\x00default\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\\r\\n (esc)
1215 write(9 from 9) -> (9) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
1204 write(9 from 9) -> (9) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
1216 write(9 from 9) -> (0) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
1205 write(9 from 9) -> (0) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
1217 write limit reached; closing socket
1206 write limit reached; closing socket
1218 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=getbundle': (glob)
1207 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=getbundle': (glob)
1219 Traceback (most recent call last):
1208 Traceback (most recent call last):
1220 Exception: connection closed after sending N bytes
1209 Exception: connection closed after sending N bytes
1221
1210
1222 write(27) -> 15\r\nInternal Server Error\r\n
1211 write(27) -> 15\r\nInternal Server Error\r\n
1223 #endif
1212 #endif
1224
1213
1225 $ rm -f error.log
1214 $ rm -f error.log
1226 $ rm -rf clone
1215 $ rm -rf clone
1227
1216
1228 Server sends a size 0 chunked-transfer size without terminating \r\n
1217 Server sends a size 0 chunked-transfer size without terminating \r\n
1229
1218
1230 $ hg serve --config badserver.closeaftersendbytes=1865 -p $HGPORT -d --pid-file=hg.pid -E error.log
1219 $ hg serve --config badserver.closeaftersendbytes=1739 -p $HGPORT -d --pid-file=hg.pid -E error.log
1231 $ cat hg.pid > $DAEMON_PIDS
1220 $ cat hg.pid > $DAEMON_PIDS
1232
1221
1233 $ hg clone http://localhost:$HGPORT/ clone
1222 $ hg clone http://localhost:$HGPORT/ clone
1234 requesting all changes
1223 requesting all changes
1235 adding changesets
1224 adding changesets
1236 adding manifests
1225 adding manifests
1237 adding file changes
1226 adding file changes
1238 added 1 changesets with 1 changes to 1 files
1227 added 1 changesets with 1 changes to 1 files
1239 new changesets 96ee1d7354c4
1228 new changesets 96ee1d7354c4
1240 updating to branch default
1229 updating to branch default
1241 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1230 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1242
1231
1243 $ killdaemons.py $DAEMON_PIDS
1232 $ killdaemons.py $DAEMON_PIDS
1244
1233
1245 #if py36
1234 #if py36
1246 $ "$PYTHON" $TESTDIR/filtertraceback.py < error.log | tail -26
1235 $ "$PYTHON" $TESTDIR/filtertraceback.py < error.log | tail -21
1247 sendall(9 from 9) -> (854) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
1236 sendall(9 from 9) -> (747) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
1248 sendall(9 from 9) -> (845) 4\\r\\n\x00\x00\x00)\\r\\n (esc)
1237 sendall(9 from 9) -> (738) 4\\r\\n\x00\x00\x00)\\r\\n (esc)
1249 sendall(47 from 47) -> (798) 29\\r\\n\x0bCHANGEGROUP\x00\x00\x00\x00\x01\x01\x07\x02 \x01version02nbchanges1\\r\\n (esc)
1238 sendall(47 from 47) -> (691) 29\\r\\n\x0bCHANGEGROUP\x00\x00\x00\x00\x01\x01\x07\x02 \x01version02nbchanges1\\r\\n (esc)
1250 sendall(9 from 9) -> (789) 4\\r\\n\x00\x00\x01\xd2\\r\\n (esc)
1239 sendall(9 from 9) -> (682) 4\\r\\n\x00\x00\x01\xd2\\r\\n (esc)
1251 sendall(473 from 473) -> (316) 1d2\\r\\n\x00\x00\x00\xb2\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>6a3df4de388f3c4f8e28f4f9a814299a3cbb5f50\\ntest\\n0 0\\nfoo\\n\\ninitial\x00\x00\x00\x00\x00\x00\x00\xa1j=\xf4\xde8\x8f<O\x8e(\xf4\xf9\xa8\x14)\x9a<\xbb_P\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00b80de5d138758541c5f05265ad144ab9fa86d1db\\n\x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00h\xb8\\r\xe5\xd18u\x85A\xc5\xf0Re\xad\x14J\xb9\xfa\x86\xd1\xdb\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\\r\\n (esc)
1240 sendall(473 from 473) -> (209) 1d2\\r\\n\x00\x00\x00\xb2\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>6a3df4de388f3c4f8e28f4f9a814299a3cbb5f50\\ntest\\n0 0\\nfoo\\n\\ninitial\x00\x00\x00\x00\x00\x00\x00\xa1j=\xf4\xde8\x8f<O\x8e(\xf4\xf9\xa8\x14)\x9a<\xbb_P\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00b80de5d138758541c5f05265ad144ab9fa86d1db\\n\x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00h\xb8\\r\xe5\xd18u\x85A\xc5\xf0Re\xad\x14J\xb9\xfa\x86\xd1\xdb\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\\r\\n (esc)
1252 sendall(9 from 9) -> (307) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
1241 sendall(9 from 9) -> (200) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
1253 sendall(9 from 9) -> (298) 4\\r\\n\x00\x00\x00 \\r\\n (esc)
1242 sendall(9 from 9) -> (191) 4\\r\\n\x00\x00\x00 \\r\\n (esc)
1254 sendall(38 from 38) -> (260) 20\\r\\n\x08LISTKEYS\x00\x00\x00\x01\x01\x00 \x06namespacephases\\r\\n (esc)
1243 sendall(38 from 38) -> (153) 20\\r\\n\x08LISTKEYS\x00\x00\x00\x01\x01\x00 \x06namespacephases\\r\\n (esc)
1255 sendall(9 from 9) -> (251) 4\\r\\n\x00\x00\x00:\\r\\n (esc)
1244 sendall(9 from 9) -> (144) 4\\r\\n\x00\x00\x00:\\r\\n (esc)
1256 sendall(64 from 64) -> (187) 3a\r\n96ee1d7354c4ad7372047672c36a1f561e3a6a4c 1\npublishing True\r\n
1245 sendall(64 from 64) -> (80) 3a\r\n96ee1d7354c4ad7372047672c36a1f561e3a6a4c 1\npublishing True\r\n
1257 sendall(9 from 9) -> (178) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
1246 sendall(9 from 9) -> (71) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
1258 sendall(9 from 9) -> (169) 4\\r\\n\x00\x00\x00#\\r\\n (esc)
1247 sendall(9 from 9) -> (62) 4\\r\\n\x00\x00\x00#\\r\\n (esc)
1259 sendall(41 from 41) -> (128) 23\\r\\n\x08LISTKEYS\x00\x00\x00\x02\x01\x00 namespacebookmarks\\r\\n (esc)
1248 sendall(41 from 41) -> (21) 23\\r\\n\x08LISTKEYS\x00\x00\x00\x02\x01\x00 namespacebookmarks\\r\\n (esc)
1260 sendall(9 from 9) -> (119) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
1261 sendall(9 from 9) -> (110) 4\\r\\n\x00\x00\x00\x1d\\r\\n (esc)
1262 sendall(35 from 35) -> (75) 1d\\r\\n\x16cache:rev-branch-cache\x00\x00\x00\x03\x00\x00\\r\\n (esc)
1263 sendall(9 from 9) -> (66) 4\\r\\n\x00\x00\x00'\\r\\n (esc)
1264 sendall(45 from 45) -> (21) 27\\r\\n\x00\x00\x00\x07\x00\x00\x00\x01\x00\x00\x00\x00default\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\\r\\n (esc)
1265 sendall(9 from 9) -> (12) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
1249 sendall(9 from 9) -> (12) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
1266 sendall(9 from 9) -> (3) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
1250 sendall(9 from 9) -> (3) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
1267 sendall(3 from 5) -> (0) 0\r\n
1251 sendall(3 from 5) -> (0) 0\r\n
1268 write limit reached; closing socket
1252 write limit reached; closing socket
1269 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=getbundle': (glob)
1253 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=getbundle': (glob)
1270 Traceback (most recent call last):
1254 Traceback (most recent call last):
1271 Exception: connection closed after sending N bytes
1255 Exception: connection closed after sending N bytes
1272
1256
1273
1257
1274 #else
1258 #else
1275 $ "$PYTHON" $TESTDIR/filtertraceback.py < error.log | tail -27
1259 $ "$PYTHON" $TESTDIR/filtertraceback.py < error.log | tail -22
1276 write(9 from 9) -> (854) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
1260 write(9 from 9) -> (747) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
1277 write(9 from 9) -> (845) 4\\r\\n\x00\x00\x00)\\r\\n (esc)
1261 write(9 from 9) -> (738) 4\\r\\n\x00\x00\x00)\\r\\n (esc)
1278 write(47 from 47) -> (798) 29\\r\\n\x0bCHANGEGROUP\x00\x00\x00\x00\x01\x01\x07\x02 \x01version02nbchanges1\\r\\n (esc)
1262 write(47 from 47) -> (691) 29\\r\\n\x0bCHANGEGROUP\x00\x00\x00\x00\x01\x01\x07\x02 \x01version02nbchanges1\\r\\n (esc)
1279 write(9 from 9) -> (789) 4\\r\\n\x00\x00\x01\xd2\\r\\n (esc)
1263 write(9 from 9) -> (682) 4\\r\\n\x00\x00\x01\xd2\\r\\n (esc)
1280 write(473 from 473) -> (316) 1d2\\r\\n\x00\x00\x00\xb2\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>6a3df4de388f3c4f8e28f4f9a814299a3cbb5f50\\ntest\\n0 0\\nfoo\\n\\ninitial\x00\x00\x00\x00\x00\x00\x00\xa1j=\xf4\xde8\x8f<O\x8e(\xf4\xf9\xa8\x14)\x9a<\xbb_P\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00b80de5d138758541c5f05265ad144ab9fa86d1db\\n\x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00h\xb8\\r\xe5\xd18u\x85A\xc5\xf0Re\xad\x14J\xb9\xfa\x86\xd1\xdb\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\\r\\n (esc)
1264 write(473 from 473) -> (209) 1d2\\r\\n\x00\x00\x00\xb2\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>6a3df4de388f3c4f8e28f4f9a814299a3cbb5f50\\ntest\\n0 0\\nfoo\\n\\ninitial\x00\x00\x00\x00\x00\x00\x00\xa1j=\xf4\xde8\x8f<O\x8e(\xf4\xf9\xa8\x14)\x9a<\xbb_P\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00b80de5d138758541c5f05265ad144ab9fa86d1db\\n\x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00h\xb8\\r\xe5\xd18u\x85A\xc5\xf0Re\xad\x14J\xb9\xfa\x86\xd1\xdb\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\x00\x00\x00\x00\x00\x00\x00\x00\\r\\n (esc)
1281 write(9 from 9) -> (307) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
1265 write(9 from 9) -> (200) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
1282 write(9 from 9) -> (298) 4\\r\\n\x00\x00\x00 \\r\\n (esc)
1266 write(9 from 9) -> (191) 4\\r\\n\x00\x00\x00 \\r\\n (esc)
1283 write(38 from 38) -> (260) 20\\r\\n\x08LISTKEYS\x00\x00\x00\x01\x01\x00 \x06namespacephases\\r\\n (esc)
1267 write(38 from 38) -> (153) 20\\r\\n\x08LISTKEYS\x00\x00\x00\x01\x01\x00 \x06namespacephases\\r\\n (esc)
1284 write(9 from 9) -> (251) 4\\r\\n\x00\x00\x00:\\r\\n (esc)
1268 write(9 from 9) -> (144) 4\\r\\n\x00\x00\x00:\\r\\n (esc)
1285 write(64 from 64) -> (187) 3a\r\n96ee1d7354c4ad7372047672c36a1f561e3a6a4c 1\npublishing True\r\n
1269 write(64 from 64) -> (80) 3a\r\n96ee1d7354c4ad7372047672c36a1f561e3a6a4c 1\npublishing True\r\n
1286 write(9 from 9) -> (178) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
1270 write(9 from 9) -> (71) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
1287 write(9 from 9) -> (169) 4\\r\\n\x00\x00\x00#\\r\\n (esc)
1271 write(9 from 9) -> (62) 4\\r\\n\x00\x00\x00#\\r\\n (esc)
1288 write(41 from 41) -> (128) 23\\r\\n\x08LISTKEYS\x00\x00\x00\x02\x01\x00 namespacebookmarks\\r\\n (esc)
1272 write(41 from 41) -> (21) 23\\r\\n\x08LISTKEYS\x00\x00\x00\x02\x01\x00 namespacebookmarks\\r\\n (esc)
1289 write(9 from 9) -> (119) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
1290 write(9 from 9) -> (110) 4\\r\\n\x00\x00\x00\x1d\\r\\n (esc)
1291 write(35 from 35) -> (75) 1d\\r\\n\x16cache:rev-branch-cache\x00\x00\x00\x03\x00\x00\\r\\n (esc)
1292 write(9 from 9) -> (66) 4\\r\\n\x00\x00\x00'\\r\\n (esc)
1293 write(45 from 45) -> (21) 27\\r\\n\x00\x00\x00\x07\x00\x00\x00\x01\x00\x00\x00\x00default\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL\\r\\n (esc)
1294 write(9 from 9) -> (12) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
1273 write(9 from 9) -> (12) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
1295 write(9 from 9) -> (3) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
1274 write(9 from 9) -> (3) 4\\r\\n\x00\x00\x00\x00\\r\\n (esc)
1296 write(3 from 5) -> (0) 0\r\n
1275 write(3 from 5) -> (0) 0\r\n
1297 write limit reached; closing socket
1276 write limit reached; closing socket
1298 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=getbundle': (glob)
1277 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=getbundle': (glob)
1299 Traceback (most recent call last):
1278 Traceback (most recent call last):
1300 Exception: connection closed after sending N bytes
1279 Exception: connection closed after sending N bytes
1301
1280
1302 write(27) -> 15\r\nInternal Server Error\r\n
1281 write(27) -> 15\r\nInternal Server Error\r\n
1303 #endif
1282 #endif
1304
1283
1305 $ rm -f error.log
1284 $ rm -f error.log
1306 $ rm -rf clone
1285 $ rm -rf clone
@@ -1,773 +1,773 b''
1 #require no-chg
1 #require no-chg
2
2
3 $ . $TESTDIR/wireprotohelpers.sh
3 $ . $TESTDIR/wireprotohelpers.sh
4
4
5 $ cat >> $HGRCPATH << EOF
5 $ cat >> $HGRCPATH << EOF
6 > [web]
6 > [web]
7 > push_ssl = false
7 > push_ssl = false
8 > allow_push = *
8 > allow_push = *
9 > EOF
9 > EOF
10
10
11 $ hg init server
11 $ hg init server
12 $ cd server
12 $ cd server
13 $ touch a
13 $ touch a
14 $ hg -q commit -A -m initial
14 $ hg -q commit -A -m initial
15 $ cd ..
15 $ cd ..
16
16
17 $ hg serve -R server -p $HGPORT -d --pid-file hg.pid
17 $ hg serve -R server -p $HGPORT -d --pid-file hg.pid
18 $ cat hg.pid >> $DAEMON_PIDS
18 $ cat hg.pid >> $DAEMON_PIDS
19
19
20 compression formats are advertised in compression capability
20 compression formats are advertised in compression capability
21
21
22 #if zstd
22 #if zstd
23 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=capabilities' | tr ' ' '\n' | grep '^compression=zstd,zlib$' > /dev/null
23 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=capabilities' | tr ' ' '\n' | grep '^compression=zstd,zlib$' > /dev/null
24 #else
24 #else
25 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=capabilities' | tr ' ' '\n' | grep '^compression=zlib$' > /dev/null
25 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=capabilities' | tr ' ' '\n' | grep '^compression=zlib$' > /dev/null
26 #endif
26 #endif
27
27
28 $ killdaemons.py
28 $ killdaemons.py
29
29
30 server.compressionengines can replace engines list wholesale
30 server.compressionengines can replace engines list wholesale
31
31
32 $ hg serve --config server.compressionengines=none -R server -p $HGPORT -d --pid-file hg.pid
32 $ hg serve --config server.compressionengines=none -R server -p $HGPORT -d --pid-file hg.pid
33 $ cat hg.pid > $DAEMON_PIDS
33 $ cat hg.pid > $DAEMON_PIDS
34 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=capabilities' | tr ' ' '\n' | grep '^compression=none$' > /dev/null
34 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=capabilities' | tr ' ' '\n' | grep '^compression=none$' > /dev/null
35
35
36 $ killdaemons.py
36 $ killdaemons.py
37
37
38 Order of engines can also change
38 Order of engines can also change
39
39
40 $ hg serve --config server.compressionengines=none,zlib -R server -p $HGPORT -d --pid-file hg.pid
40 $ hg serve --config server.compressionengines=none,zlib -R server -p $HGPORT -d --pid-file hg.pid
41 $ cat hg.pid > $DAEMON_PIDS
41 $ cat hg.pid > $DAEMON_PIDS
42 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=capabilities' | tr ' ' '\n' | grep '^compression=none,zlib$' > /dev/null
42 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=capabilities' | tr ' ' '\n' | grep '^compression=none,zlib$' > /dev/null
43
43
44 $ killdaemons.py
44 $ killdaemons.py
45
45
46 Start a default server again
46 Start a default server again
47
47
48 $ hg serve -R server -p $HGPORT -d --pid-file hg.pid
48 $ hg serve -R server -p $HGPORT -d --pid-file hg.pid
49 $ cat hg.pid > $DAEMON_PIDS
49 $ cat hg.pid > $DAEMON_PIDS
50
50
51 Server should send application/mercurial-0.1 to clients if no Accept is used
51 Server should send application/mercurial-0.1 to clients if no Accept is used
52
52
53 $ get-with-headers.py --headeronly $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' -
53 $ get-with-headers.py --headeronly $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' -
54 200 Script output follows
54 200 Script output follows
55 content-type: application/mercurial-0.1
55 content-type: application/mercurial-0.1
56 date: $HTTP_DATE$
56 date: $HTTP_DATE$
57 server: testing stub value
57 server: testing stub value
58 transfer-encoding: chunked
58 transfer-encoding: chunked
59
59
60 Server should send application/mercurial-0.1 when client says it wants it
60 Server should send application/mercurial-0.1 when client says it wants it
61
61
62 $ get-with-headers.py --hgproto '0.1' --headeronly $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' -
62 $ get-with-headers.py --hgproto '0.1' --headeronly $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' -
63 200 Script output follows
63 200 Script output follows
64 content-type: application/mercurial-0.1
64 content-type: application/mercurial-0.1
65 date: $HTTP_DATE$
65 date: $HTTP_DATE$
66 server: testing stub value
66 server: testing stub value
67 transfer-encoding: chunked
67 transfer-encoding: chunked
68
68
69 Server should send application/mercurial-0.2 when client says it wants it
69 Server should send application/mercurial-0.2 when client says it wants it
70
70
71 $ get-with-headers.py --hgproto '0.2' --headeronly $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' -
71 $ get-with-headers.py --hgproto '0.2' --headeronly $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' -
72 200 Script output follows
72 200 Script output follows
73 content-type: application/mercurial-0.2
73 content-type: application/mercurial-0.2
74 date: $HTTP_DATE$
74 date: $HTTP_DATE$
75 server: testing stub value
75 server: testing stub value
76 transfer-encoding: chunked
76 transfer-encoding: chunked
77
77
78 $ get-with-headers.py --hgproto '0.1 0.2' --headeronly $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' -
78 $ get-with-headers.py --hgproto '0.1 0.2' --headeronly $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' -
79 200 Script output follows
79 200 Script output follows
80 content-type: application/mercurial-0.2
80 content-type: application/mercurial-0.2
81 date: $HTTP_DATE$
81 date: $HTTP_DATE$
82 server: testing stub value
82 server: testing stub value
83 transfer-encoding: chunked
83 transfer-encoding: chunked
84
84
85 Requesting a compression format that server doesn't support results will fall back to 0.1
85 Requesting a compression format that server doesn't support results will fall back to 0.1
86
86
87 $ get-with-headers.py --hgproto '0.2 comp=aa' --headeronly $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' -
87 $ get-with-headers.py --hgproto '0.2 comp=aa' --headeronly $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' -
88 200 Script output follows
88 200 Script output follows
89 content-type: application/mercurial-0.1
89 content-type: application/mercurial-0.1
90 date: $HTTP_DATE$
90 date: $HTTP_DATE$
91 server: testing stub value
91 server: testing stub value
92 transfer-encoding: chunked
92 transfer-encoding: chunked
93
93
94 #if zstd
94 #if zstd
95 zstd is used if available
95 zstd is used if available
96
96
97 $ get-with-headers.py --hgproto '0.2 comp=zstd' $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' > resp
97 $ get-with-headers.py --hgproto '0.2 comp=zstd' $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' > resp
98 $ f --size --hexdump --bytes 36 --sha1 resp
98 $ f --size --hexdump --bytes 36 --sha1 resp
99 resp: size=248, sha1=f11b5c098c638068b3d5fe2f9e6241bf5228
99 resp: size=248, sha1=f11b5c098c638068b3d5fe2f9e6241bf5228
100 0000: 32 30 30 20 53 63 72 69 70 74 20 6f 75 74 70 75 |200 Script outpu|
100 0000: 32 30 30 20 53 63 72 69 70 74 20 6f 75 74 70 75 |200 Script outpu|
101 0010: 74 20 66 6f 6c 6c 6f 77 73 0a 0a 04 7a 73 74 64 |t follows...zstd|
101 0010: 74 20 66 6f 6c 6c 6f 77 73 0a 0a 04 7a 73 74 64 |t follows...zstd|
102 0020: 28 b5 2f fd |(./.|
102 0020: 28 b5 2f fd |(./.|
103
103
104 #endif
104 #endif
105
105
106 application/mercurial-0.2 is not yet used on non-streaming responses
106 application/mercurial-0.2 is not yet used on non-streaming responses
107
107
108 $ get-with-headers.py --hgproto '0.2' $LOCALIP:$HGPORT '?cmd=heads' -
108 $ get-with-headers.py --hgproto '0.2' $LOCALIP:$HGPORT '?cmd=heads' -
109 200 Script output follows
109 200 Script output follows
110 content-length: 41
110 content-length: 41
111 content-type: application/mercurial-0.1
111 content-type: application/mercurial-0.1
112 date: $HTTP_DATE$
112 date: $HTTP_DATE$
113 server: testing stub value
113 server: testing stub value
114
114
115 e93700bd72895c5addab234c56d4024b487a362f
115 e93700bd72895c5addab234c56d4024b487a362f
116
116
117 Now test protocol preference usage
117 Now test protocol preference usage
118
118
119 $ killdaemons.py
119 $ killdaemons.py
120 $ hg serve --config server.compressionengines=none,zlib -R server -p $HGPORT -d --pid-file hg.pid
120 $ hg serve --config server.compressionengines=none,zlib -R server -p $HGPORT -d --pid-file hg.pid
121 $ cat hg.pid > $DAEMON_PIDS
121 $ cat hg.pid > $DAEMON_PIDS
122
122
123 No Accept will send 0.1+zlib, even though "none" is preferred b/c "none" isn't supported on 0.1
123 No Accept will send 0.1+zlib, even though "none" is preferred b/c "none" isn't supported on 0.1
124
124
125 $ get-with-headers.py --headeronly $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' Content-Type
125 $ get-with-headers.py --headeronly $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' Content-Type
126 200 Script output follows
126 200 Script output follows
127 content-type: application/mercurial-0.1
127 content-type: application/mercurial-0.1
128
128
129 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' > resp
129 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' > resp
130 $ f --size --hexdump --bytes 28 --sha1 resp
130 $ f --size --hexdump --bytes 28 --sha1 resp
131 resp: size=227, sha1=35a4c074da74f32f5440da3cbf04
131 resp: size=227, sha1=35a4c074da74f32f5440da3cbf04
132 0000: 32 30 30 20 53 63 72 69 70 74 20 6f 75 74 70 75 |200 Script outpu|
132 0000: 32 30 30 20 53 63 72 69 70 74 20 6f 75 74 70 75 |200 Script outpu|
133 0010: 74 20 66 6f 6c 6c 6f 77 73 0a 0a 78 |t follows..x|
133 0010: 74 20 66 6f 6c 6c 6f 77 73 0a 0a 78 |t follows..x|
134
134
135 Explicit 0.1 will send zlib because "none" isn't supported on 0.1
135 Explicit 0.1 will send zlib because "none" isn't supported on 0.1
136
136
137 $ get-with-headers.py --hgproto '0.1' $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' > resp
137 $ get-with-headers.py --hgproto '0.1' $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' > resp
138 $ f --size --hexdump --bytes 28 --sha1 resp
138 $ f --size --hexdump --bytes 28 --sha1 resp
139 resp: size=227, sha1=35a4c074da74f32f5440da3cbf04
139 resp: size=227, sha1=35a4c074da74f32f5440da3cbf04
140 0000: 32 30 30 20 53 63 72 69 70 74 20 6f 75 74 70 75 |200 Script outpu|
140 0000: 32 30 30 20 53 63 72 69 70 74 20 6f 75 74 70 75 |200 Script outpu|
141 0010: 74 20 66 6f 6c 6c 6f 77 73 0a 0a 78 |t follows..x|
141 0010: 74 20 66 6f 6c 6c 6f 77 73 0a 0a 78 |t follows..x|
142
142
143 0.2 with no compression will get "none" because that is server's preference
143 0.2 with no compression will get "none" because that is server's preference
144 (spec says ZL and UN are implicitly supported)
144 (spec says ZL and UN are implicitly supported)
145
145
146 $ get-with-headers.py --hgproto '0.2' $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' > resp
146 $ get-with-headers.py --hgproto '0.2' $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' > resp
147 $ f --size --hexdump --bytes 32 --sha1 resp
147 $ f --size --hexdump --bytes 32 --sha1 resp
148 resp: size=432, sha1=ac931b412ec185a02e0e5bcff98dac83
148 resp: size=432, sha1=ac931b412ec185a02e0e5bcff98dac83
149 0000: 32 30 30 20 53 63 72 69 70 74 20 6f 75 74 70 75 |200 Script outpu|
149 0000: 32 30 30 20 53 63 72 69 70 74 20 6f 75 74 70 75 |200 Script outpu|
150 0010: 74 20 66 6f 6c 6c 6f 77 73 0a 0a 04 6e 6f 6e 65 |t follows...none|
150 0010: 74 20 66 6f 6c 6c 6f 77 73 0a 0a 04 6e 6f 6e 65 |t follows...none|
151
151
152 Client receives server preference even if local order doesn't match
152 Client receives server preference even if local order doesn't match
153
153
154 $ get-with-headers.py --hgproto '0.2 comp=zlib,none' $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' > resp
154 $ get-with-headers.py --hgproto '0.2 comp=zlib,none' $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' > resp
155 $ f --size --hexdump --bytes 32 --sha1 resp
155 $ f --size --hexdump --bytes 32 --sha1 resp
156 resp: size=432, sha1=ac931b412ec185a02e0e5bcff98dac83
156 resp: size=432, sha1=ac931b412ec185a02e0e5bcff98dac83
157 0000: 32 30 30 20 53 63 72 69 70 74 20 6f 75 74 70 75 |200 Script outpu|
157 0000: 32 30 30 20 53 63 72 69 70 74 20 6f 75 74 70 75 |200 Script outpu|
158 0010: 74 20 66 6f 6c 6c 6f 77 73 0a 0a 04 6e 6f 6e 65 |t follows...none|
158 0010: 74 20 66 6f 6c 6c 6f 77 73 0a 0a 04 6e 6f 6e 65 |t follows...none|
159
159
160 Client receives only supported format even if not server preferred format
160 Client receives only supported format even if not server preferred format
161
161
162 $ get-with-headers.py --hgproto '0.2 comp=zlib' $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' > resp
162 $ get-with-headers.py --hgproto '0.2 comp=zlib' $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' > resp
163 $ f --size --hexdump --bytes 33 --sha1 resp
163 $ f --size --hexdump --bytes 33 --sha1 resp
164 resp: size=232, sha1=a1c727f0c9693ca15742a75c30419bc36
164 resp: size=232, sha1=a1c727f0c9693ca15742a75c30419bc36
165 0000: 32 30 30 20 53 63 72 69 70 74 20 6f 75 74 70 75 |200 Script outpu|
165 0000: 32 30 30 20 53 63 72 69 70 74 20 6f 75 74 70 75 |200 Script outpu|
166 0010: 74 20 66 6f 6c 6c 6f 77 73 0a 0a 04 7a 6c 69 62 |t follows...zlib|
166 0010: 74 20 66 6f 6c 6c 6f 77 73 0a 0a 04 7a 6c 69 62 |t follows...zlib|
167 0020: 78 |x|
167 0020: 78 |x|
168
168
169 $ killdaemons.py
169 $ killdaemons.py
170 $ cd ..
170 $ cd ..
171
171
172 Test listkeys for listing namespaces
172 Test listkeys for listing namespaces
173
173
174 $ hg init empty
174 $ hg init empty
175 $ hg -R empty serve -p $HGPORT -d --pid-file hg.pid
175 $ hg -R empty serve -p $HGPORT -d --pid-file hg.pid
176 $ cat hg.pid > $DAEMON_PIDS
176 $ cat hg.pid > $DAEMON_PIDS
177
177
178 $ hg --verbose debugwireproto http://$LOCALIP:$HGPORT << EOF
178 $ hg --verbose debugwireproto http://$LOCALIP:$HGPORT << EOF
179 > command listkeys
179 > command listkeys
180 > namespace namespaces
180 > namespace namespaces
181 > EOF
181 > EOF
182 s> setsockopt(6, 1, 1) -> None (?)
182 s> setsockopt(6, 1, 1) -> None (?)
183 s> GET /?cmd=capabilities HTTP/1.1\r\n
183 s> GET /?cmd=capabilities HTTP/1.1\r\n
184 s> Accept-Encoding: identity\r\n
184 s> Accept-Encoding: identity\r\n
185 s> accept: application/mercurial-0.1\r\n
185 s> accept: application/mercurial-0.1\r\n
186 s> host: $LOCALIP:$HGPORT\r\n (glob)
186 s> host: $LOCALIP:$HGPORT\r\n (glob)
187 s> user-agent: Mercurial debugwireproto\r\n
187 s> user-agent: Mercurial debugwireproto\r\n
188 s> \r\n
188 s> \r\n
189 s> makefile('rb', None)
189 s> makefile('rb', None)
190 s> HTTP/1.1 200 Script output follows\r\n
190 s> HTTP/1.1 200 Script output follows\r\n
191 s> Server: testing stub value\r\n
191 s> Server: testing stub value\r\n
192 s> Date: $HTTP_DATE$\r\n
192 s> Date: $HTTP_DATE$\r\n
193 s> Content-Type: application/mercurial-0.1\r\n
193 s> Content-Type: application/mercurial-0.1\r\n
194 s> Content-Length: *\r\n (glob)
194 s> Content-Length: *\r\n (glob)
195 s> \r\n
195 s> \r\n
196 s> batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
196 s> batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
197 sending listkeys command
197 sending listkeys command
198 s> setsockopt(6, 1, 1) -> None (?)
198 s> setsockopt(6, 1, 1) -> None (?)
199 s> GET /?cmd=listkeys HTTP/1.1\r\n
199 s> GET /?cmd=listkeys HTTP/1.1\r\n
200 s> Accept-Encoding: identity\r\n
200 s> Accept-Encoding: identity\r\n
201 s> vary: X-HgArg-1,X-HgProto-1\r\n
201 s> vary: X-HgArg-1,X-HgProto-1\r\n
202 s> x-hgarg-1: namespace=namespaces\r\n
202 s> x-hgarg-1: namespace=namespaces\r\n
203 s> x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n
203 s> x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n
204 s> accept: application/mercurial-0.1\r\n
204 s> accept: application/mercurial-0.1\r\n
205 s> host: $LOCALIP:$HGPORT\r\n (glob)
205 s> host: $LOCALIP:$HGPORT\r\n (glob)
206 s> user-agent: Mercurial debugwireproto\r\n
206 s> user-agent: Mercurial debugwireproto\r\n
207 s> \r\n
207 s> \r\n
208 s> makefile('rb', None)
208 s> makefile('rb', None)
209 s> HTTP/1.1 200 Script output follows\r\n
209 s> HTTP/1.1 200 Script output follows\r\n
210 s> Server: testing stub value\r\n
210 s> Server: testing stub value\r\n
211 s> Date: $HTTP_DATE$\r\n
211 s> Date: $HTTP_DATE$\r\n
212 s> Content-Type: application/mercurial-0.1\r\n
212 s> Content-Type: application/mercurial-0.1\r\n
213 s> Content-Length: 30\r\n
213 s> Content-Length: 30\r\n
214 s> \r\n
214 s> \r\n
215 s> bookmarks\t\n
215 s> bookmarks\t\n
216 s> namespaces\t\n
216 s> namespaces\t\n
217 s> phases\t
217 s> phases\t
218 response: {
218 response: {
219 b'bookmarks': b'',
219 b'bookmarks': b'',
220 b'namespaces': b'',
220 b'namespaces': b'',
221 b'phases': b''
221 b'phases': b''
222 }
222 }
223 (sent 2 HTTP requests and * bytes; received * bytes in responses) (glob)
223 (sent 2 HTTP requests and * bytes; received * bytes in responses) (glob)
224
224
225 Same thing, but with "httprequest" command
225 Same thing, but with "httprequest" command
226
226
227 $ hg --verbose debugwireproto --peer raw http://$LOCALIP:$HGPORT << EOF
227 $ hg --verbose debugwireproto --peer raw http://$LOCALIP:$HGPORT << EOF
228 > httprequest GET ?cmd=listkeys
228 > httprequest GET ?cmd=listkeys
229 > user-agent: test
229 > user-agent: test
230 > x-hgarg-1: namespace=namespaces
230 > x-hgarg-1: namespace=namespaces
231 > EOF
231 > EOF
232 using raw connection to peer
232 using raw connection to peer
233 s> setsockopt(6, 1, 1) -> None (?)
233 s> setsockopt(6, 1, 1) -> None (?)
234 s> GET /?cmd=listkeys HTTP/1.1\r\n
234 s> GET /?cmd=listkeys HTTP/1.1\r\n
235 s> Accept-Encoding: identity\r\n
235 s> Accept-Encoding: identity\r\n
236 s> user-agent: test\r\n
236 s> user-agent: test\r\n
237 s> x-hgarg-1: namespace=namespaces\r\n
237 s> x-hgarg-1: namespace=namespaces\r\n
238 s> host: $LOCALIP:$HGPORT\r\n (glob)
238 s> host: $LOCALIP:$HGPORT\r\n (glob)
239 s> \r\n
239 s> \r\n
240 s> makefile('rb', None)
240 s> makefile('rb', None)
241 s> HTTP/1.1 200 Script output follows\r\n
241 s> HTTP/1.1 200 Script output follows\r\n
242 s> Server: testing stub value\r\n
242 s> Server: testing stub value\r\n
243 s> Date: $HTTP_DATE$\r\n
243 s> Date: $HTTP_DATE$\r\n
244 s> Content-Type: application/mercurial-0.1\r\n
244 s> Content-Type: application/mercurial-0.1\r\n
245 s> Content-Length: 30\r\n
245 s> Content-Length: 30\r\n
246 s> \r\n
246 s> \r\n
247 s> bookmarks\t\n
247 s> bookmarks\t\n
248 s> namespaces\t\n
248 s> namespaces\t\n
249 s> phases\t
249 s> phases\t
250
250
251 Client with HTTPv2 enabled advertises that and gets old capabilities response from old server
251 Client with HTTPv2 enabled advertises that and gets old capabilities response from old server
252
252
253 $ hg --config experimental.httppeer.advertise-v2=true --verbose debugwireproto http://$LOCALIP:$HGPORT << EOF
253 $ hg --config experimental.httppeer.advertise-v2=true --verbose debugwireproto http://$LOCALIP:$HGPORT << EOF
254 > command heads
254 > command heads
255 > EOF
255 > EOF
256 s> setsockopt(6, 1, 1) -> None (?)
256 s> setsockopt(6, 1, 1) -> None (?)
257 s> GET /?cmd=capabilities HTTP/1.1\r\n
257 s> GET /?cmd=capabilities HTTP/1.1\r\n
258 s> Accept-Encoding: identity\r\n
258 s> Accept-Encoding: identity\r\n
259 s> vary: X-HgProto-1,X-HgUpgrade-1\r\n
259 s> vary: X-HgProto-1,X-HgUpgrade-1\r\n
260 s> x-hgproto-1: cbor\r\n
260 s> x-hgproto-1: cbor\r\n
261 s> x-hgupgrade-1: exp-http-v2-0003\r\n
261 s> x-hgupgrade-1: exp-http-v2-0003\r\n
262 s> accept: application/mercurial-0.1\r\n
262 s> accept: application/mercurial-0.1\r\n
263 s> host: $LOCALIP:$HGPORT\r\n (glob)
263 s> host: $LOCALIP:$HGPORT\r\n (glob)
264 s> user-agent: Mercurial debugwireproto\r\n
264 s> user-agent: Mercurial debugwireproto\r\n
265 s> \r\n
265 s> \r\n
266 s> makefile('rb', None)
266 s> makefile('rb', None)
267 s> HTTP/1.1 200 Script output follows\r\n
267 s> HTTP/1.1 200 Script output follows\r\n
268 s> Server: testing stub value\r\n
268 s> Server: testing stub value\r\n
269 s> Date: $HTTP_DATE$\r\n
269 s> Date: $HTTP_DATE$\r\n
270 s> Content-Type: application/mercurial-0.1\r\n
270 s> Content-Type: application/mercurial-0.1\r\n
271 s> Content-Length: *\r\n (glob)
271 s> Content-Length: *\r\n (glob)
272 s> \r\n
272 s> \r\n
273 s> batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
273 s> batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
274 sending heads command
274 sending heads command
275 s> setsockopt(6, 1, 1) -> None (?)
275 s> setsockopt(6, 1, 1) -> None (?)
276 s> GET /?cmd=heads HTTP/1.1\r\n
276 s> GET /?cmd=heads HTTP/1.1\r\n
277 s> Accept-Encoding: identity\r\n
277 s> Accept-Encoding: identity\r\n
278 s> vary: X-HgProto-1\r\n
278 s> vary: X-HgProto-1\r\n
279 s> x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n
279 s> x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n
280 s> accept: application/mercurial-0.1\r\n
280 s> accept: application/mercurial-0.1\r\n
281 s> host: $LOCALIP:$HGPORT\r\n (glob)
281 s> host: $LOCALIP:$HGPORT\r\n (glob)
282 s> user-agent: Mercurial debugwireproto\r\n
282 s> user-agent: Mercurial debugwireproto\r\n
283 s> \r\n
283 s> \r\n
284 s> makefile('rb', None)
284 s> makefile('rb', None)
285 s> HTTP/1.1 200 Script output follows\r\n
285 s> HTTP/1.1 200 Script output follows\r\n
286 s> Server: testing stub value\r\n
286 s> Server: testing stub value\r\n
287 s> Date: $HTTP_DATE$\r\n
287 s> Date: $HTTP_DATE$\r\n
288 s> Content-Type: application/mercurial-0.1\r\n
288 s> Content-Type: application/mercurial-0.1\r\n
289 s> Content-Length: 41\r\n
289 s> Content-Length: 41\r\n
290 s> \r\n
290 s> \r\n
291 s> 0000000000000000000000000000000000000000\n
291 s> 0000000000000000000000000000000000000000\n
292 response: [
292 response: [
293 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
293 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
294 ]
294 ]
295 (sent 2 HTTP requests and * bytes; received * bytes in responses) (glob)
295 (sent 2 HTTP requests and * bytes; received * bytes in responses) (glob)
296
296
297 $ killdaemons.py
297 $ killdaemons.py
298 $ enablehttpv2 empty
298 $ enablehttpv2 empty
299 $ hg --config server.compressionengines=zlib -R empty serve -p $HGPORT -d --pid-file hg.pid
299 $ hg --config server.compressionengines=zlib -R empty serve -p $HGPORT -d --pid-file hg.pid
300 $ cat hg.pid > $DAEMON_PIDS
300 $ cat hg.pid > $DAEMON_PIDS
301
301
302 Client with HTTPv2 enabled automatically upgrades if the server supports it
302 Client with HTTPv2 enabled automatically upgrades if the server supports it
303
303
304 $ hg --config experimental.httppeer.advertise-v2=true --config experimental.httppeer.v2-encoder-order=identity --verbose debugwireproto http://$LOCALIP:$HGPORT << EOF
304 $ hg --config experimental.httppeer.advertise-v2=true --config experimental.httppeer.v2-encoder-order=identity --verbose debugwireproto http://$LOCALIP:$HGPORT << EOF
305 > command heads
305 > command heads
306 > EOF
306 > EOF
307 s> setsockopt(6, 1, 1) -> None (?)
307 s> setsockopt(6, 1, 1) -> None (?)
308 s> GET /?cmd=capabilities HTTP/1.1\r\n
308 s> GET /?cmd=capabilities HTTP/1.1\r\n
309 s> Accept-Encoding: identity\r\n
309 s> Accept-Encoding: identity\r\n
310 s> vary: X-HgProto-1,X-HgUpgrade-1\r\n
310 s> vary: X-HgProto-1,X-HgUpgrade-1\r\n
311 s> x-hgproto-1: cbor\r\n
311 s> x-hgproto-1: cbor\r\n
312 s> x-hgupgrade-1: exp-http-v2-0003\r\n
312 s> x-hgupgrade-1: exp-http-v2-0003\r\n
313 s> accept: application/mercurial-0.1\r\n
313 s> accept: application/mercurial-0.1\r\n
314 s> host: $LOCALIP:$HGPORT\r\n (glob)
314 s> host: $LOCALIP:$HGPORT\r\n (glob)
315 s> user-agent: Mercurial debugwireproto\r\n
315 s> user-agent: Mercurial debugwireproto\r\n
316 s> \r\n
316 s> \r\n
317 s> makefile('rb', None)
317 s> makefile('rb', None)
318 s> HTTP/1.1 200 OK\r\n
318 s> HTTP/1.1 200 OK\r\n
319 s> Server: testing stub value\r\n
319 s> Server: testing stub value\r\n
320 s> Date: $HTTP_DATE$\r\n
320 s> Date: $HTTP_DATE$\r\n
321 s> Content-Type: application/mercurial-cbor\r\n
321 s> Content-Type: application/mercurial-cbor\r\n
322 s> Content-Length: *\r\n (glob)
322 s> Content-Length: *\r\n (glob)
323 s> \r\n
323 s> \r\n
324 s> \xa3GapibaseDapi/Dapis\xa1Pexp-http-v2-0003\xa4Hcommands\xacIbranchmap\xa2Dargs\xa0Kpermissions\x81DpullLcapabilities\xa2Dargs\xa0Kpermissions\x81DpullMchangesetdata\xa2Dargs\xa2Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x84IbookmarksGparentsEphaseHrevisionIrevisions\xa2Hrequired\xf5DtypeDlistKpermissions\x81DpullHfiledata\xa2Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x83HlinknodeGparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolEnodes\xa2Hrequired\xf5DtypeDlistDpath\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullIfilesdata\xa3Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x84NfirstchangesetHlinknodeGparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolJpathfilter\xa3Gdefault\xf6Hrequired\xf4DtypeDdictIrevisions\xa2Hrequired\xf5DtypeDlistKpermissions\x81DpullTrecommendedbatchsize\x19\xc3PEheads\xa2Dargs\xa1Jpubliconly\xa3Gdefault\xf4Hrequired\xf4DtypeDboolKpermissions\x81DpullEknown\xa2Dargs\xa1Enodes\xa3Gdefault\x80Hrequired\xf4DtypeDlistKpermissions\x81DpullHlistkeys\xa2Dargs\xa1Inamespace\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullFlookup\xa2Dargs\xa1Ckey\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullLmanifestdata\xa3Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x82GparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolEnodes\xa2Hrequired\xf5DtypeDlistDtree\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullTrecommendedbatchsize\x1a\x00\x01\x86\xa0Gpushkey\xa2Dargs\xa4Ckey\xa2Hrequired\xf5DtypeEbytesInamespace\xa2Hrequired\xf5DtypeEbytesCnew\xa2Hrequired\xf5DtypeEbytesCold\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpushPrawstorefiledata\xa2Dargs\xa2Efiles\xa2Hrequired\xf5DtypeDlistJpathfilter\xa3Gdefault\xf6Hrequired\xf4DtypeDlistKpermissions\x81DpullQframingmediatypes\x81X&application/mercurial-exp-framing-0006Rpathfilterprefixes\xd9\x01\x02\x82Epath:Lrootfilesin:Nrawrepoformats\x83LgeneraldeltaHrevlogv1LsparserevlogNv1capabilitiesY\x01\xf7batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
324 s> \xa3GapibaseDapi/Dapis\xa1Pexp-http-v2-0003\xa4Hcommands\xacIbranchmap\xa2Dargs\xa0Kpermissions\x81DpullLcapabilities\xa2Dargs\xa0Kpermissions\x81DpullMchangesetdata\xa2Dargs\xa2Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x84IbookmarksGparentsEphaseHrevisionIrevisions\xa2Hrequired\xf5DtypeDlistKpermissions\x81DpullHfiledata\xa2Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x83HlinknodeGparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolEnodes\xa2Hrequired\xf5DtypeDlistDpath\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullIfilesdata\xa3Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x84NfirstchangesetHlinknodeGparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolJpathfilter\xa3Gdefault\xf6Hrequired\xf4DtypeDdictIrevisions\xa2Hrequired\xf5DtypeDlistKpermissions\x81DpullTrecommendedbatchsize\x19\xc3PEheads\xa2Dargs\xa1Jpubliconly\xa3Gdefault\xf4Hrequired\xf4DtypeDboolKpermissions\x81DpullEknown\xa2Dargs\xa1Enodes\xa3Gdefault\x80Hrequired\xf4DtypeDlistKpermissions\x81DpullHlistkeys\xa2Dargs\xa1Inamespace\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullFlookup\xa2Dargs\xa1Ckey\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullLmanifestdata\xa3Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x82GparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolEnodes\xa2Hrequired\xf5DtypeDlistDtree\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullTrecommendedbatchsize\x1a\x00\x01\x86\xa0Gpushkey\xa2Dargs\xa4Ckey\xa2Hrequired\xf5DtypeEbytesInamespace\xa2Hrequired\xf5DtypeEbytesCnew\xa2Hrequired\xf5DtypeEbytesCold\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpushPrawstorefiledata\xa2Dargs\xa2Efiles\xa2Hrequired\xf5DtypeDlistJpathfilter\xa3Gdefault\xf6Hrequired\xf4DtypeDlistKpermissions\x81DpullQframingmediatypes\x81X&application/mercurial-exp-framing-0006Rpathfilterprefixes\xd9\x01\x02\x82Epath:Lrootfilesin:Nrawrepoformats\x83LgeneraldeltaHrevlogv1LsparserevlogNv1capabilitiesY\x01\xe4batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
325 sending heads command
325 sending heads command
326 s> setsockopt(6, 1, 1) -> None (?)
326 s> setsockopt(6, 1, 1) -> None (?)
327 s> POST /api/exp-http-v2-0003/ro/heads HTTP/1.1\r\n
327 s> POST /api/exp-http-v2-0003/ro/heads HTTP/1.1\r\n
328 s> Accept-Encoding: identity\r\n
328 s> Accept-Encoding: identity\r\n
329 s> accept: application/mercurial-exp-framing-0006\r\n
329 s> accept: application/mercurial-exp-framing-0006\r\n
330 s> content-type: application/mercurial-exp-framing-0006\r\n
330 s> content-type: application/mercurial-exp-framing-0006\r\n
331 s> content-length: 56\r\n
331 s> content-length: 56\r\n
332 s> host: $LOCALIP:$HGPORT\r\n (glob)
332 s> host: $LOCALIP:$HGPORT\r\n (glob)
333 s> user-agent: Mercurial debugwireproto\r\n
333 s> user-agent: Mercurial debugwireproto\r\n
334 s> \r\n
334 s> \r\n
335 s> \x1c\x00\x00\x01\x00\x01\x01\x82\xa1Pcontentencodings\x81Hidentity\x0c\x00\x00\x01\x00\x01\x00\x11\xa1DnameEheads
335 s> \x1c\x00\x00\x01\x00\x01\x01\x82\xa1Pcontentencodings\x81Hidentity\x0c\x00\x00\x01\x00\x01\x00\x11\xa1DnameEheads
336 s> makefile('rb', None)
336 s> makefile('rb', None)
337 s> HTTP/1.1 200 OK\r\n
337 s> HTTP/1.1 200 OK\r\n
338 s> Server: testing stub value\r\n
338 s> Server: testing stub value\r\n
339 s> Date: $HTTP_DATE$\r\n
339 s> Date: $HTTP_DATE$\r\n
340 s> Content-Type: application/mercurial-exp-framing-0006\r\n
340 s> Content-Type: application/mercurial-exp-framing-0006\r\n
341 s> Transfer-Encoding: chunked\r\n
341 s> Transfer-Encoding: chunked\r\n
342 s> \r\n
342 s> \r\n
343 s> 11\r\n
343 s> 11\r\n
344 s> \t\x00\x00\x01\x00\x02\x01\x92
344 s> \t\x00\x00\x01\x00\x02\x01\x92
345 s> Hidentity
345 s> Hidentity
346 s> \r\n
346 s> \r\n
347 s> 13\r\n
347 s> 13\r\n
348 s> \x0b\x00\x00\x01\x00\x02\x041
348 s> \x0b\x00\x00\x01\x00\x02\x041
349 s> \xa1FstatusBok
349 s> \xa1FstatusBok
350 s> \r\n
350 s> \r\n
351 s> 1e\r\n
351 s> 1e\r\n
352 s> \x16\x00\x00\x01\x00\x02\x041
352 s> \x16\x00\x00\x01\x00\x02\x041
353 s> \x81T\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
353 s> \x81T\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
354 s> \r\n
354 s> \r\n
355 s> 8\r\n
355 s> 8\r\n
356 s> \x00\x00\x00\x01\x00\x02\x002
356 s> \x00\x00\x00\x01\x00\x02\x002
357 s> \r\n
357 s> \r\n
358 s> 0\r\n
358 s> 0\r\n
359 s> \r\n
359 s> \r\n
360 response: [
360 response: [
361 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
361 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
362 ]
362 ]
363 (sent 2 HTTP requests and * bytes; received * bytes in responses) (glob)
363 (sent 2 HTTP requests and * bytes; received * bytes in responses) (glob)
364
364
365 $ killdaemons.py
365 $ killdaemons.py
366
366
367 HTTP client follows HTTP redirect on handshake to new repo
367 HTTP client follows HTTP redirect on handshake to new repo
368
368
369 $ cd $TESTTMP
369 $ cd $TESTTMP
370
370
371 $ hg init redirector
371 $ hg init redirector
372 $ hg init redirected
372 $ hg init redirected
373 $ cd redirected
373 $ cd redirected
374 $ touch foo
374 $ touch foo
375 $ hg -q commit -A -m initial
375 $ hg -q commit -A -m initial
376 $ cd ..
376 $ cd ..
377
377
378 $ cat > paths.conf << EOF
378 $ cat > paths.conf << EOF
379 > [paths]
379 > [paths]
380 > / = $TESTTMP/*
380 > / = $TESTTMP/*
381 > EOF
381 > EOF
382
382
383 $ cat > redirectext.py << EOF
383 $ cat > redirectext.py << EOF
384 > from mercurial import extensions, wireprotoserver
384 > from mercurial import extensions, wireprotoserver
385 > def wrappedcallhttp(orig, repo, req, res, proto, cmd):
385 > def wrappedcallhttp(orig, repo, req, res, proto, cmd):
386 > path = req.advertisedurl[len(req.advertisedbaseurl):]
386 > path = req.advertisedurl[len(req.advertisedbaseurl):]
387 > if not path.startswith(b'/redirector'):
387 > if not path.startswith(b'/redirector'):
388 > return orig(repo, req, res, proto, cmd)
388 > return orig(repo, req, res, proto, cmd)
389 > relpath = path[len(b'/redirector'):]
389 > relpath = path[len(b'/redirector'):]
390 > res.status = b'301 Redirect'
390 > res.status = b'301 Redirect'
391 > newurl = b'%s/redirected%s' % (req.baseurl, relpath)
391 > newurl = b'%s/redirected%s' % (req.baseurl, relpath)
392 > if not repo.ui.configbool(b'testing', b'redirectqs', True) and b'?' in newurl:
392 > if not repo.ui.configbool(b'testing', b'redirectqs', True) and b'?' in newurl:
393 > newurl = newurl[0:newurl.index(b'?')]
393 > newurl = newurl[0:newurl.index(b'?')]
394 > res.headers[b'Location'] = newurl
394 > res.headers[b'Location'] = newurl
395 > res.headers[b'Content-Type'] = b'text/plain'
395 > res.headers[b'Content-Type'] = b'text/plain'
396 > res.setbodybytes(b'redirected')
396 > res.setbodybytes(b'redirected')
397 > return True
397 > return True
398 >
398 >
399 > extensions.wrapfunction(wireprotoserver, '_callhttp', wrappedcallhttp)
399 > extensions.wrapfunction(wireprotoserver, '_callhttp', wrappedcallhttp)
400 > EOF
400 > EOF
401
401
402 $ hg --config extensions.redirect=$TESTTMP/redirectext.py \
402 $ hg --config extensions.redirect=$TESTTMP/redirectext.py \
403 > --config server.compressionengines=zlib \
403 > --config server.compressionengines=zlib \
404 > serve --web-conf paths.conf --pid-file hg.pid -p $HGPORT -d
404 > serve --web-conf paths.conf --pid-file hg.pid -p $HGPORT -d
405 $ cat hg.pid > $DAEMON_PIDS
405 $ cat hg.pid > $DAEMON_PIDS
406
406
407 Verify our HTTP 301 is served properly
407 Verify our HTTP 301 is served properly
408
408
409 $ hg --verbose debugwireproto --peer raw http://$LOCALIP:$HGPORT << EOF
409 $ hg --verbose debugwireproto --peer raw http://$LOCALIP:$HGPORT << EOF
410 > httprequest GET /redirector?cmd=capabilities
410 > httprequest GET /redirector?cmd=capabilities
411 > user-agent: test
411 > user-agent: test
412 > EOF
412 > EOF
413 using raw connection to peer
413 using raw connection to peer
414 s> setsockopt(6, 1, 1) -> None (?)
414 s> setsockopt(6, 1, 1) -> None (?)
415 s> GET /redirector?cmd=capabilities HTTP/1.1\r\n
415 s> GET /redirector?cmd=capabilities HTTP/1.1\r\n
416 s> Accept-Encoding: identity\r\n
416 s> Accept-Encoding: identity\r\n
417 s> user-agent: test\r\n
417 s> user-agent: test\r\n
418 s> host: $LOCALIP:$HGPORT\r\n (glob)
418 s> host: $LOCALIP:$HGPORT\r\n (glob)
419 s> \r\n
419 s> \r\n
420 s> makefile('rb', None)
420 s> makefile('rb', None)
421 s> HTTP/1.1 301 Redirect\r\n
421 s> HTTP/1.1 301 Redirect\r\n
422 s> Server: testing stub value\r\n
422 s> Server: testing stub value\r\n
423 s> Date: $HTTP_DATE$\r\n
423 s> Date: $HTTP_DATE$\r\n
424 s> Location: http://$LOCALIP:$HGPORT/redirected?cmd=capabilities\r\n (glob)
424 s> Location: http://$LOCALIP:$HGPORT/redirected?cmd=capabilities\r\n (glob)
425 s> Content-Type: text/plain\r\n
425 s> Content-Type: text/plain\r\n
426 s> Content-Length: 10\r\n
426 s> Content-Length: 10\r\n
427 s> \r\n
427 s> \r\n
428 s> redirected
428 s> redirected
429 s> setsockopt(6, 1, 1) -> None (?)
429 s> setsockopt(6, 1, 1) -> None (?)
430 s> GET /redirected?cmd=capabilities HTTP/1.1\r\n
430 s> GET /redirected?cmd=capabilities HTTP/1.1\r\n
431 s> Accept-Encoding: identity\r\n
431 s> Accept-Encoding: identity\r\n
432 s> user-agent: test\r\n
432 s> user-agent: test\r\n
433 s> host: $LOCALIP:$HGPORT\r\n (glob)
433 s> host: $LOCALIP:$HGPORT\r\n (glob)
434 s> \r\n
434 s> \r\n
435 s> makefile('rb', None)
435 s> makefile('rb', None)
436 s> HTTP/1.1 200 Script output follows\r\n
436 s> HTTP/1.1 200 Script output follows\r\n
437 s> Server: testing stub value\r\n
437 s> Server: testing stub value\r\n
438 s> Date: $HTTP_DATE$\r\n
438 s> Date: $HTTP_DATE$\r\n
439 s> Content-Type: application/mercurial-0.1\r\n
439 s> Content-Type: application/mercurial-0.1\r\n
440 s> Content-Length: 503\r\n
440 s> Content-Length: 484\r\n
441 s> \r\n
441 s> \r\n
442 s> batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
442 s> batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
443
443
444 Test with the HTTP peer
444 Test with the HTTP peer
445
445
446 $ hg --verbose debugwireproto http://$LOCALIP:$HGPORT/redirector << EOF
446 $ hg --verbose debugwireproto http://$LOCALIP:$HGPORT/redirector << EOF
447 > command heads
447 > command heads
448 > EOF
448 > EOF
449 s> setsockopt(6, 1, 1) -> None (?)
449 s> setsockopt(6, 1, 1) -> None (?)
450 s> GET /redirector?cmd=capabilities HTTP/1.1\r\n
450 s> GET /redirector?cmd=capabilities HTTP/1.1\r\n
451 s> Accept-Encoding: identity\r\n
451 s> Accept-Encoding: identity\r\n
452 s> accept: application/mercurial-0.1\r\n
452 s> accept: application/mercurial-0.1\r\n
453 s> host: $LOCALIP:$HGPORT\r\n (glob)
453 s> host: $LOCALIP:$HGPORT\r\n (glob)
454 s> user-agent: Mercurial debugwireproto\r\n
454 s> user-agent: Mercurial debugwireproto\r\n
455 s> \r\n
455 s> \r\n
456 s> makefile('rb', None)
456 s> makefile('rb', None)
457 s> HTTP/1.1 301 Redirect\r\n
457 s> HTTP/1.1 301 Redirect\r\n
458 s> Server: testing stub value\r\n
458 s> Server: testing stub value\r\n
459 s> Date: $HTTP_DATE$\r\n
459 s> Date: $HTTP_DATE$\r\n
460 s> Location: http://$LOCALIP:$HGPORT/redirected?cmd=capabilities\r\n (glob)
460 s> Location: http://$LOCALIP:$HGPORT/redirected?cmd=capabilities\r\n (glob)
461 s> Content-Type: text/plain\r\n
461 s> Content-Type: text/plain\r\n
462 s> Content-Length: 10\r\n
462 s> Content-Length: 10\r\n
463 s> \r\n
463 s> \r\n
464 s> redirected
464 s> redirected
465 s> setsockopt(6, 1, 1) -> None (?)
465 s> setsockopt(6, 1, 1) -> None (?)
466 s> GET /redirected?cmd=capabilities HTTP/1.1\r\n
466 s> GET /redirected?cmd=capabilities HTTP/1.1\r\n
467 s> Accept-Encoding: identity\r\n
467 s> Accept-Encoding: identity\r\n
468 s> accept: application/mercurial-0.1\r\n
468 s> accept: application/mercurial-0.1\r\n
469 s> host: $LOCALIP:$HGPORT\r\n (glob)
469 s> host: $LOCALIP:$HGPORT\r\n (glob)
470 s> user-agent: Mercurial debugwireproto\r\n
470 s> user-agent: Mercurial debugwireproto\r\n
471 s> \r\n
471 s> \r\n
472 s> makefile('rb', None)
472 s> makefile('rb', None)
473 s> HTTP/1.1 200 Script output follows\r\n
473 s> HTTP/1.1 200 Script output follows\r\n
474 s> Server: testing stub value\r\n
474 s> Server: testing stub value\r\n
475 s> Date: $HTTP_DATE$\r\n
475 s> Date: $HTTP_DATE$\r\n
476 s> Content-Type: application/mercurial-0.1\r\n
476 s> Content-Type: application/mercurial-0.1\r\n
477 s> Content-Length: 503\r\n
477 s> Content-Length: 484\r\n
478 s> \r\n
478 s> \r\n
479 real URL is http://$LOCALIP:$HGPORT/redirected (glob)
479 real URL is http://$LOCALIP:$HGPORT/redirected (glob)
480 s> batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
480 s> batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
481 sending heads command
481 sending heads command
482 s> setsockopt(6, 1, 1) -> None (?)
482 s> setsockopt(6, 1, 1) -> None (?)
483 s> GET /redirected?cmd=heads HTTP/1.1\r\n
483 s> GET /redirected?cmd=heads HTTP/1.1\r\n
484 s> Accept-Encoding: identity\r\n
484 s> Accept-Encoding: identity\r\n
485 s> vary: X-HgProto-1\r\n
485 s> vary: X-HgProto-1\r\n
486 s> x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n
486 s> x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n
487 s> accept: application/mercurial-0.1\r\n
487 s> accept: application/mercurial-0.1\r\n
488 s> host: $LOCALIP:$HGPORT\r\n (glob)
488 s> host: $LOCALIP:$HGPORT\r\n (glob)
489 s> user-agent: Mercurial debugwireproto\r\n
489 s> user-agent: Mercurial debugwireproto\r\n
490 s> \r\n
490 s> \r\n
491 s> makefile('rb', None)
491 s> makefile('rb', None)
492 s> HTTP/1.1 200 Script output follows\r\n
492 s> HTTP/1.1 200 Script output follows\r\n
493 s> Server: testing stub value\r\n
493 s> Server: testing stub value\r\n
494 s> Date: $HTTP_DATE$\r\n
494 s> Date: $HTTP_DATE$\r\n
495 s> Content-Type: application/mercurial-0.1\r\n
495 s> Content-Type: application/mercurial-0.1\r\n
496 s> Content-Length: 41\r\n
496 s> Content-Length: 41\r\n
497 s> \r\n
497 s> \r\n
498 s> 96ee1d7354c4ad7372047672c36a1f561e3a6a4c\n
498 s> 96ee1d7354c4ad7372047672c36a1f561e3a6a4c\n
499 response: [
499 response: [
500 b'\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL'
500 b'\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL'
501 ]
501 ]
502 (sent 3 HTTP requests and * bytes; received * bytes in responses) (glob)
502 (sent 3 HTTP requests and * bytes; received * bytes in responses) (glob)
503
503
504 $ killdaemons.py
504 $ killdaemons.py
505
505
506 Now test a variation where we strip the query string from the redirect URL.
506 Now test a variation where we strip the query string from the redirect URL.
507 (SCM Manager apparently did this and clients would recover from it)
507 (SCM Manager apparently did this and clients would recover from it)
508
508
509 $ hg --config extensions.redirect=$TESTTMP/redirectext.py \
509 $ hg --config extensions.redirect=$TESTTMP/redirectext.py \
510 > --config server.compressionengines=zlib \
510 > --config server.compressionengines=zlib \
511 > --config testing.redirectqs=false \
511 > --config testing.redirectqs=false \
512 > serve --web-conf paths.conf --pid-file hg.pid -p $HGPORT -d
512 > serve --web-conf paths.conf --pid-file hg.pid -p $HGPORT -d
513 $ cat hg.pid > $DAEMON_PIDS
513 $ cat hg.pid > $DAEMON_PIDS
514
514
515 $ hg --verbose debugwireproto --peer raw http://$LOCALIP:$HGPORT << EOF
515 $ hg --verbose debugwireproto --peer raw http://$LOCALIP:$HGPORT << EOF
516 > httprequest GET /redirector?cmd=capabilities
516 > httprequest GET /redirector?cmd=capabilities
517 > user-agent: test
517 > user-agent: test
518 > EOF
518 > EOF
519 using raw connection to peer
519 using raw connection to peer
520 s> setsockopt(6, 1, 1) -> None (?)
520 s> setsockopt(6, 1, 1) -> None (?)
521 s> GET /redirector?cmd=capabilities HTTP/1.1\r\n
521 s> GET /redirector?cmd=capabilities HTTP/1.1\r\n
522 s> Accept-Encoding: identity\r\n
522 s> Accept-Encoding: identity\r\n
523 s> user-agent: test\r\n
523 s> user-agent: test\r\n
524 s> host: $LOCALIP:$HGPORT\r\n (glob)
524 s> host: $LOCALIP:$HGPORT\r\n (glob)
525 s> \r\n
525 s> \r\n
526 s> makefile('rb', None)
526 s> makefile('rb', None)
527 s> HTTP/1.1 301 Redirect\r\n
527 s> HTTP/1.1 301 Redirect\r\n
528 s> Server: testing stub value\r\n
528 s> Server: testing stub value\r\n
529 s> Date: $HTTP_DATE$\r\n
529 s> Date: $HTTP_DATE$\r\n
530 s> Location: http://$LOCALIP:$HGPORT/redirected\r\n (glob)
530 s> Location: http://$LOCALIP:$HGPORT/redirected\r\n (glob)
531 s> Content-Type: text/plain\r\n
531 s> Content-Type: text/plain\r\n
532 s> Content-Length: 10\r\n
532 s> Content-Length: 10\r\n
533 s> \r\n
533 s> \r\n
534 s> redirected
534 s> redirected
535 s> setsockopt(6, 1, 1) -> None (?)
535 s> setsockopt(6, 1, 1) -> None (?)
536 s> GET /redirected HTTP/1.1\r\n
536 s> GET /redirected HTTP/1.1\r\n
537 s> Accept-Encoding: identity\r\n
537 s> Accept-Encoding: identity\r\n
538 s> user-agent: test\r\n
538 s> user-agent: test\r\n
539 s> host: $LOCALIP:$HGPORT\r\n (glob)
539 s> host: $LOCALIP:$HGPORT\r\n (glob)
540 s> \r\n
540 s> \r\n
541 s> makefile('rb', None)
541 s> makefile('rb', None)
542 s> HTTP/1.1 200 Script output follows\r\n
542 s> HTTP/1.1 200 Script output follows\r\n
543 s> Server: testing stub value\r\n
543 s> Server: testing stub value\r\n
544 s> Date: $HTTP_DATE$\r\n
544 s> Date: $HTTP_DATE$\r\n
545 s> ETag: W/"*"\r\n (glob)
545 s> ETag: W/"*"\r\n (glob)
546 s> Content-Type: text/html; charset=ascii\r\n
546 s> Content-Type: text/html; charset=ascii\r\n
547 s> Transfer-Encoding: chunked\r\n
547 s> Transfer-Encoding: chunked\r\n
548 s> \r\n
548 s> \r\n
549 s> 414\r\n
549 s> 414\r\n
550 s> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">\n
550 s> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">\n
551 s> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">\n
551 s> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">\n
552 s> <head>\n
552 s> <head>\n
553 s> <link rel="icon" href="/redirected/static/hgicon.png" type="image/png" />\n
553 s> <link rel="icon" href="/redirected/static/hgicon.png" type="image/png" />\n
554 s> <meta name="robots" content="index, nofollow" />\n
554 s> <meta name="robots" content="index, nofollow" />\n
555 s> <link rel="stylesheet" href="/redirected/static/style-paper.css" type="text/css" />\n
555 s> <link rel="stylesheet" href="/redirected/static/style-paper.css" type="text/css" />\n
556 s> <script type="text/javascript" src="/redirected/static/mercurial.js"></script>\n
556 s> <script type="text/javascript" src="/redirected/static/mercurial.js"></script>\n
557 s> \n
557 s> \n
558 s> <title>redirected: log</title>\n
558 s> <title>redirected: log</title>\n
559 s> <link rel="alternate" type="application/atom+xml"\n
559 s> <link rel="alternate" type="application/atom+xml"\n
560 s> href="/redirected/atom-log" title="Atom feed for redirected" />\n
560 s> href="/redirected/atom-log" title="Atom feed for redirected" />\n
561 s> <link rel="alternate" type="application/rss+xml"\n
561 s> <link rel="alternate" type="application/rss+xml"\n
562 s> href="/redirected/rss-log" title="RSS feed for redirected" />\n
562 s> href="/redirected/rss-log" title="RSS feed for redirected" />\n
563 s> </head>\n
563 s> </head>\n
564 s> <body>\n
564 s> <body>\n
565 s> \n
565 s> \n
566 s> <div class="container">\n
566 s> <div class="container">\n
567 s> <div class="menu">\n
567 s> <div class="menu">\n
568 s> <div class="logo">\n
568 s> <div class="logo">\n
569 s> <a href="https://mercurial-scm.org/">\n
569 s> <a href="https://mercurial-scm.org/">\n
570 s> <img src="/redirected/static/hglogo.png" alt="mercurial" /></a>\n
570 s> <img src="/redirected/static/hglogo.png" alt="mercurial" /></a>\n
571 s> </div>\n
571 s> </div>\n
572 s> <ul>\n
572 s> <ul>\n
573 s> <li class="active">log</li>\n
573 s> <li class="active">log</li>\n
574 s> <li><a href="/redirected/graph/tip">graph</a></li>\n
574 s> <li><a href="/redirected/graph/tip">graph</a></li>\n
575 s> <li><a href="/redirected/tags">tags</a></li>\n
575 s> <li><a href="/redirected/tags">tags</a></li>\n
576 s> <li><a href="
576 s> <li><a href="
577 s> \r\n
577 s> \r\n
578 s> 810\r\n
578 s> 810\r\n
579 s> /redirected/bookmarks">bookmarks</a></li>\n
579 s> /redirected/bookmarks">bookmarks</a></li>\n
580 s> <li><a href="/redirected/branches">branches</a></li>\n
580 s> <li><a href="/redirected/branches">branches</a></li>\n
581 s> </ul>\n
581 s> </ul>\n
582 s> <ul>\n
582 s> <ul>\n
583 s> <li><a href="/redirected/rev/tip">changeset</a></li>\n
583 s> <li><a href="/redirected/rev/tip">changeset</a></li>\n
584 s> <li><a href="/redirected/file/tip">browse</a></li>\n
584 s> <li><a href="/redirected/file/tip">browse</a></li>\n
585 s> </ul>\n
585 s> </ul>\n
586 s> <ul>\n
586 s> <ul>\n
587 s> \n
587 s> \n
588 s> </ul>\n
588 s> </ul>\n
589 s> <ul>\n
589 s> <ul>\n
590 s> <li><a href="/redirected/help">help</a></li>\n
590 s> <li><a href="/redirected/help">help</a></li>\n
591 s> </ul>\n
591 s> </ul>\n
592 s> <div class="atom-logo">\n
592 s> <div class="atom-logo">\n
593 s> <a href="/redirected/atom-log" title="subscribe to atom feed">\n
593 s> <a href="/redirected/atom-log" title="subscribe to atom feed">\n
594 s> <img class="atom-logo" src="/redirected/static/feed-icon-14x14.png" alt="atom feed" />\n
594 s> <img class="atom-logo" src="/redirected/static/feed-icon-14x14.png" alt="atom feed" />\n
595 s> </a>\n
595 s> </a>\n
596 s> </div>\n
596 s> </div>\n
597 s> </div>\n
597 s> </div>\n
598 s> \n
598 s> \n
599 s> <div class="main">\n
599 s> <div class="main">\n
600 s> <h2 class="breadcrumb"><a href="/">Mercurial</a> &gt; <a href="/redirected">redirected</a> </h2>\n
600 s> <h2 class="breadcrumb"><a href="/">Mercurial</a> &gt; <a href="/redirected">redirected</a> </h2>\n
601 s> <h3>log</h3>\n
601 s> <h3>log</h3>\n
602 s> \n
602 s> \n
603 s> \n
603 s> \n
604 s> <form class="search" action="/redirected/log">\n
604 s> <form class="search" action="/redirected/log">\n
605 s> \n
605 s> \n
606 s> <p><input name="rev" id="search1" type="text" size="30" value="" /></p>\n
606 s> <p><input name="rev" id="search1" type="text" size="30" value="" /></p>\n
607 s> <div id="hint">Find changesets by keywords (author, files, the commit message), revision\n
607 s> <div id="hint">Find changesets by keywords (author, files, the commit message), revision\n
608 s> number or hash, or <a href="/redirected/help/revsets">revset expression</a>.</div>\n
608 s> number or hash, or <a href="/redirected/help/revsets">revset expression</a>.</div>\n
609 s> </form>\n
609 s> </form>\n
610 s> \n
610 s> \n
611 s> <div class="navigate">\n
611 s> <div class="navigate">\n
612 s> <a href="/redirected/shortlog/tip?revcount=30">less</a>\n
612 s> <a href="/redirected/shortlog/tip?revcount=30">less</a>\n
613 s> <a href="/redirected/shortlog/tip?revcount=120">more</a>\n
613 s> <a href="/redirected/shortlog/tip?revcount=120">more</a>\n
614 s> | rev 0: <a href="/redirected/shortlog/96ee1d7354c4">(0)</a> <a href="/redirected/shortlog/tip">tip</a> \n
614 s> | rev 0: <a href="/redirected/shortlog/96ee1d7354c4">(0)</a> <a href="/redirected/shortlog/tip">tip</a> \n
615 s> </div>\n
615 s> </div>\n
616 s> \n
616 s> \n
617 s> <table class="bigtable">\n
617 s> <table class="bigtable">\n
618 s> <thead>\n
618 s> <thead>\n
619 s> <tr>\n
619 s> <tr>\n
620 s> <th class="age">age</th>\n
620 s> <th class="age">age</th>\n
621 s> <th class="author">author</th>\n
621 s> <th class="author">author</th>\n
622 s> <th class="description">description</th>\n
622 s> <th class="description">description</th>\n
623 s> </tr>\n
623 s> </tr>\n
624 s> </thead>\n
624 s> </thead>\n
625 s> <tbody class="stripes2">\n
625 s> <tbody class="stripes2">\n
626 s> <tr>\n
626 s> <tr>\n
627 s> <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td>\n
627 s> <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td>\n
628 s> <td class="author">test</td>\n
628 s> <td class="author">test</td>\n
629 s> <td class="description">\n
629 s> <td class="description">\n
630 s> <a href="/redirected/rev/96ee1d7354c4">initial</a>\n
630 s> <a href="/redirected/rev/96ee1d7354c4">initial</a>\n
631 s> <span class="phase">draft</span> <span class="branchhead">default</span> <span class="tag">tip</span> \n
631 s> <span class="phase">draft</span> <span class="branchhead">default</span> <span class="tag">tip</span> \n
632 s> </td>\n
632 s> </td>\n
633 s> </tr>\n
633 s> </tr>\n
634 s> \n
634 s> \n
635 s> </tbody>\n
635 s> </tbody>\n
636 s> </table>\n
636 s> </table>\n
637 s> \n
637 s> \n
638 s> <div class="navigate">\n
638 s> <div class="navigate">\n
639 s> <a href="/redirected/shortlog/tip?revcount=30">less</a>\n
639 s> <a href="/redirected/shortlog/tip?revcount=30">less</a>\n
640 s> <a href="/redirected/shortlog/tip?revcount=120">more</a>\n
640 s> <a href="/redirected/shortlog/tip?revcount=120">more</a>\n
641 s> | rev 0: <a href="/redirected/shortlog/96ee1d7354c4">(0)</a> <a href="/redirected/shortlog/tip">tip</a> \n
641 s> | rev 0: <a href="/redirected/shortlog/96ee1d7354c4">(0)</a> <a href="/redirected/shortlog/tip">tip</a> \n
642 s> </div>\n
642 s> </div>\n
643 s> \n
643 s> \n
644 s> <script type="text/javascript">\n
644 s> <script type="text/javascript">\n
645 s> ajaxScrollInit(\n
645 s> ajaxScrollInit(\n
646 s> \'/redirected/shortlog/%next%\',\n
646 s> \'/redirected/shortlog/%next%\',\n
647 s> \'\', <!-- NEXTHASH\n
647 s> \'\', <!-- NEXTHASH\n
648 s> function (htmlText) {
648 s> function (htmlText) {
649 s> \r\n
649 s> \r\n
650 s> 14a\r\n
650 s> 14a\r\n
651 s> \n
651 s> \n
652 s> var m = htmlText.match(/\'(\\w+)\', <!-- NEXTHASH/);\n
652 s> var m = htmlText.match(/\'(\\w+)\', <!-- NEXTHASH/);\n
653 s> return m ? m[1] : null;\n
653 s> return m ? m[1] : null;\n
654 s> },\n
654 s> },\n
655 s> \'.bigtable > tbody\',\n
655 s> \'.bigtable > tbody\',\n
656 s> \'<tr class="%class%">\\\n
656 s> \'<tr class="%class%">\\\n
657 s> <td colspan="3" style="text-align: center;">%text%</td>\\\n
657 s> <td colspan="3" style="text-align: center;">%text%</td>\\\n
658 s> </tr>\'\n
658 s> </tr>\'\n
659 s> );\n
659 s> );\n
660 s> </script>\n
660 s> </script>\n
661 s> \n
661 s> \n
662 s> </div>\n
662 s> </div>\n
663 s> </div>\n
663 s> </div>\n
664 s> \n
664 s> \n
665 s> \n
665 s> \n
666 s> \n
666 s> \n
667 s> </body>\n
667 s> </body>\n
668 s> </html>\n
668 s> </html>\n
669 s> \n
669 s> \n
670 s> \r\n
670 s> \r\n
671 s> 0\r\n
671 s> 0\r\n
672 s> \r\n
672 s> \r\n
673
673
674 $ hg --verbose debugwireproto http://$LOCALIP:$HGPORT/redirector << EOF
674 $ hg --verbose debugwireproto http://$LOCALIP:$HGPORT/redirector << EOF
675 > command heads
675 > command heads
676 > EOF
676 > EOF
677 s> setsockopt(6, 1, 1) -> None (?)
677 s> setsockopt(6, 1, 1) -> None (?)
678 s> GET /redirector?cmd=capabilities HTTP/1.1\r\n
678 s> GET /redirector?cmd=capabilities HTTP/1.1\r\n
679 s> Accept-Encoding: identity\r\n
679 s> Accept-Encoding: identity\r\n
680 s> accept: application/mercurial-0.1\r\n
680 s> accept: application/mercurial-0.1\r\n
681 s> host: $LOCALIP:$HGPORT\r\n (glob)
681 s> host: $LOCALIP:$HGPORT\r\n (glob)
682 s> user-agent: Mercurial debugwireproto\r\n
682 s> user-agent: Mercurial debugwireproto\r\n
683 s> \r\n
683 s> \r\n
684 s> makefile('rb', None)
684 s> makefile('rb', None)
685 s> HTTP/1.1 301 Redirect\r\n
685 s> HTTP/1.1 301 Redirect\r\n
686 s> Server: testing stub value\r\n
686 s> Server: testing stub value\r\n
687 s> Date: $HTTP_DATE$\r\n
687 s> Date: $HTTP_DATE$\r\n
688 s> Location: http://$LOCALIP:$HGPORT/redirected\r\n (glob)
688 s> Location: http://$LOCALIP:$HGPORT/redirected\r\n (glob)
689 s> Content-Type: text/plain\r\n
689 s> Content-Type: text/plain\r\n
690 s> Content-Length: 10\r\n
690 s> Content-Length: 10\r\n
691 s> \r\n
691 s> \r\n
692 s> redirected
692 s> redirected
693 s> setsockopt(6, 1, 1) -> None (?)
693 s> setsockopt(6, 1, 1) -> None (?)
694 s> GET /redirected HTTP/1.1\r\n
694 s> GET /redirected HTTP/1.1\r\n
695 s> Accept-Encoding: identity\r\n
695 s> Accept-Encoding: identity\r\n
696 s> accept: application/mercurial-0.1\r\n
696 s> accept: application/mercurial-0.1\r\n
697 s> host: $LOCALIP:$HGPORT\r\n (glob)
697 s> host: $LOCALIP:$HGPORT\r\n (glob)
698 s> user-agent: Mercurial debugwireproto\r\n
698 s> user-agent: Mercurial debugwireproto\r\n
699 s> \r\n
699 s> \r\n
700 s> makefile('rb', None)
700 s> makefile('rb', None)
701 s> HTTP/1.1 200 Script output follows\r\n
701 s> HTTP/1.1 200 Script output follows\r\n
702 s> Server: testing stub value\r\n
702 s> Server: testing stub value\r\n
703 s> Date: $HTTP_DATE$\r\n
703 s> Date: $HTTP_DATE$\r\n
704 s> ETag: W/"*"\r\n (glob)
704 s> ETag: W/"*"\r\n (glob)
705 s> Content-Type: text/html; charset=ascii\r\n
705 s> Content-Type: text/html; charset=ascii\r\n
706 s> Transfer-Encoding: chunked\r\n
706 s> Transfer-Encoding: chunked\r\n
707 s> \r\n
707 s> \r\n
708 real URL is http://$LOCALIP:$HGPORT/redirected (glob)
708 real URL is http://$LOCALIP:$HGPORT/redirected (glob)
709 s> 414\r\n
709 s> 414\r\n
710 s> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">\n
710 s> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">\n
711 s> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">\n
711 s> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">\n
712 s> <head>\n
712 s> <head>\n
713 s> <link rel="icon" href="/redirected/static/hgicon.png" type="image/png" />\n
713 s> <link rel="icon" href="/redirected/static/hgicon.png" type="image/png" />\n
714 s> <meta name="robots" content="index, nofollow" />\n
714 s> <meta name="robots" content="index, nofollow" />\n
715 s> <link rel="stylesheet" href="/redirected/static/style-paper.css" type="text/css" />\n
715 s> <link rel="stylesheet" href="/redirected/static/style-paper.css" type="text/css" />\n
716 s> <script type="text/javascript" src="/redirected/static/mercurial.js"></script>\n
716 s> <script type="text/javascript" src="/redirected/static/mercurial.js"></script>\n
717 s> \n
717 s> \n
718 s> <title>redirected: log</title>\n
718 s> <title>redirected: log</title>\n
719 s> <link rel="alternate" type="application/atom+xml"\n
719 s> <link rel="alternate" type="application/atom+xml"\n
720 s> href="/redirected/atom-log" title="Atom feed for redirected" />\n
720 s> href="/redirected/atom-log" title="Atom feed for redirected" />\n
721 s> <link rel="alternate" type="application/rss+xml"\n
721 s> <link rel="alternate" type="application/rss+xml"\n
722 s> href="/redirected/rss-log" title="RSS feed for redirected" />\n
722 s> href="/redirected/rss-log" title="RSS feed for redirected" />\n
723 s> </head>\n
723 s> </head>\n
724 s> <body>\n
724 s> <body>\n
725 s> \n
725 s> \n
726 s> <div class="container">\n
726 s> <div class="container">\n
727 s> <div class="menu">\n
727 s> <div class="menu">\n
728 s> <div class="logo">\n
728 s> <div class="logo">\n
729 s> <a href="https://mercurial-scm.org/">\n
729 s> <a href="https://mercurial-scm.org/">\n
730 s> <img src="/redirected/static/hglogo.png" alt="mercurial" /></a>\n
730 s> <img src="/redirected/static/hglogo.png" alt="mercurial" /></a>\n
731 s> </div>\n
731 s> </div>\n
732 s> <ul>\n
732 s> <ul>\n
733 s> <li class="active">log</li>\n
733 s> <li class="active">log</li>\n
734 s> <li><a href="/redirected/graph/tip">graph</a></li>\n
734 s> <li><a href="/redirected/graph/tip">graph</a></li>\n
735 s> <li><a href="/redirected/tags">tags</a
735 s> <li><a href="/redirected/tags">tags</a
736 s> setsockopt(6, 1, 1) -> None (?)
736 s> setsockopt(6, 1, 1) -> None (?)
737 s> GET /redirected?cmd=capabilities HTTP/1.1\r\n
737 s> GET /redirected?cmd=capabilities HTTP/1.1\r\n
738 s> Accept-Encoding: identity\r\n
738 s> Accept-Encoding: identity\r\n
739 s> accept: application/mercurial-0.1\r\n
739 s> accept: application/mercurial-0.1\r\n
740 s> host: $LOCALIP:$HGPORT\r\n (glob)
740 s> host: $LOCALIP:$HGPORT\r\n (glob)
741 s> user-agent: Mercurial debugwireproto\r\n
741 s> user-agent: Mercurial debugwireproto\r\n
742 s> \r\n
742 s> \r\n
743 s> makefile('rb', None)
743 s> makefile('rb', None)
744 s> HTTP/1.1 200 Script output follows\r\n
744 s> HTTP/1.1 200 Script output follows\r\n
745 s> Server: testing stub value\r\n
745 s> Server: testing stub value\r\n
746 s> Date: $HTTP_DATE$\r\n
746 s> Date: $HTTP_DATE$\r\n
747 s> Content-Type: application/mercurial-0.1\r\n
747 s> Content-Type: application/mercurial-0.1\r\n
748 s> Content-Length: 503\r\n
748 s> Content-Length: 484\r\n
749 s> \r\n
749 s> \r\n
750 real URL is http://$LOCALIP:$HGPORT/redirected (glob)
750 real URL is http://$LOCALIP:$HGPORT/redirected (glob)
751 s> batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
751 s> batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
752 sending heads command
752 sending heads command
753 s> setsockopt(6, 1, 1) -> None (?)
753 s> setsockopt(6, 1, 1) -> None (?)
754 s> GET /redirected?cmd=heads HTTP/1.1\r\n
754 s> GET /redirected?cmd=heads HTTP/1.1\r\n
755 s> Accept-Encoding: identity\r\n
755 s> Accept-Encoding: identity\r\n
756 s> vary: X-HgProto-1\r\n
756 s> vary: X-HgProto-1\r\n
757 s> x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n
757 s> x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n
758 s> accept: application/mercurial-0.1\r\n
758 s> accept: application/mercurial-0.1\r\n
759 s> host: $LOCALIP:$HGPORT\r\n (glob)
759 s> host: $LOCALIP:$HGPORT\r\n (glob)
760 s> user-agent: Mercurial debugwireproto\r\n
760 s> user-agent: Mercurial debugwireproto\r\n
761 s> \r\n
761 s> \r\n
762 s> makefile('rb', None)
762 s> makefile('rb', None)
763 s> HTTP/1.1 200 Script output follows\r\n
763 s> HTTP/1.1 200 Script output follows\r\n
764 s> Server: testing stub value\r\n
764 s> Server: testing stub value\r\n
765 s> Date: $HTTP_DATE$\r\n
765 s> Date: $HTTP_DATE$\r\n
766 s> Content-Type: application/mercurial-0.1\r\n
766 s> Content-Type: application/mercurial-0.1\r\n
767 s> Content-Length: 41\r\n
767 s> Content-Length: 41\r\n
768 s> \r\n
768 s> \r\n
769 s> 96ee1d7354c4ad7372047672c36a1f561e3a6a4c\n
769 s> 96ee1d7354c4ad7372047672c36a1f561e3a6a4c\n
770 response: [
770 response: [
771 b'\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL'
771 b'\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL'
772 ]
772 ]
773 (sent 4 HTTP requests and * bytes; received * bytes in responses) (glob)
773 (sent 4 HTTP requests and * bytes; received * bytes in responses) (glob)
@@ -1,615 +1,615 b''
1 #require serve
1 #require serve
2
2
3 $ hg init test
3 $ hg init test
4 $ cd test
4 $ cd test
5 $ echo foo>foo
5 $ echo foo>foo
6 $ mkdir foo.d foo.d/bAr.hg.d foo.d/baR.d.hg
6 $ mkdir foo.d foo.d/bAr.hg.d foo.d/baR.d.hg
7 $ echo foo>foo.d/foo
7 $ echo foo>foo.d/foo
8 $ echo bar>foo.d/bAr.hg.d/BaR
8 $ echo bar>foo.d/bAr.hg.d/BaR
9 $ echo bar>foo.d/baR.d.hg/bAR
9 $ echo bar>foo.d/baR.d.hg/bAR
10 $ hg commit -A -m 1
10 $ hg commit -A -m 1
11 adding foo
11 adding foo
12 adding foo.d/bAr.hg.d/BaR
12 adding foo.d/bAr.hg.d/BaR
13 adding foo.d/baR.d.hg/bAR
13 adding foo.d/baR.d.hg/bAR
14 adding foo.d/foo
14 adding foo.d/foo
15 $ hg serve -p $HGPORT -d --pid-file=../hg1.pid -E ../error.log
15 $ hg serve -p $HGPORT -d --pid-file=../hg1.pid -E ../error.log
16 $ hg serve --config server.uncompressed=False -p $HGPORT1 -d --pid-file=../hg2.pid
16 $ hg serve --config server.uncompressed=False -p $HGPORT1 -d --pid-file=../hg2.pid
17
17
18 Test server address cannot be reused
18 Test server address cannot be reused
19
19
20 $ hg serve -p $HGPORT1 2>&1
20 $ hg serve -p $HGPORT1 2>&1
21 abort: cannot start server at 'localhost:$HGPORT1': $EADDRINUSE$
21 abort: cannot start server at 'localhost:$HGPORT1': $EADDRINUSE$
22 [255]
22 [255]
23
23
24 $ cd ..
24 $ cd ..
25 $ cat hg1.pid hg2.pid >> $DAEMON_PIDS
25 $ cat hg1.pid hg2.pid >> $DAEMON_PIDS
26
26
27 clone via stream
27 clone via stream
28
28
29 #if no-reposimplestore
29 #if no-reposimplestore
30 $ hg clone --stream http://localhost:$HGPORT/ copy 2>&1
30 $ hg clone --stream http://localhost:$HGPORT/ copy 2>&1
31 streaming all changes
31 streaming all changes
32 9 files to transfer, 715 bytes of data
32 9 files to transfer, 715 bytes of data
33 transferred * bytes in * seconds (*/sec) (glob)
33 transferred * bytes in * seconds (*/sec) (glob)
34 updating to branch default
34 updating to branch default
35 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
35 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
36 $ hg verify -R copy
36 $ hg verify -R copy
37 checking changesets
37 checking changesets
38 checking manifests
38 checking manifests
39 crosschecking files in changesets and manifests
39 crosschecking files in changesets and manifests
40 checking files
40 checking files
41 checked 1 changesets with 4 changes to 4 files
41 checked 1 changesets with 4 changes to 4 files
42 #endif
42 #endif
43
43
44 try to clone via stream, should use pull instead
44 try to clone via stream, should use pull instead
45
45
46 $ hg clone --stream http://localhost:$HGPORT1/ copy2
46 $ hg clone --stream http://localhost:$HGPORT1/ copy2
47 warning: stream clone requested but server has them disabled
47 warning: stream clone requested but server has them disabled
48 requesting all changes
48 requesting all changes
49 adding changesets
49 adding changesets
50 adding manifests
50 adding manifests
51 adding file changes
51 adding file changes
52 added 1 changesets with 4 changes to 4 files
52 added 1 changesets with 4 changes to 4 files
53 new changesets 8b6053c928fe
53 new changesets 8b6053c928fe
54 updating to branch default
54 updating to branch default
55 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
55 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
56
56
57 try to clone via stream but missing requirements, so should use pull instead
57 try to clone via stream but missing requirements, so should use pull instead
58
58
59 $ cat > $TESTTMP/removesupportedformat.py << EOF
59 $ cat > $TESTTMP/removesupportedformat.py << EOF
60 > from mercurial import localrepo
60 > from mercurial import localrepo
61 > def extsetup(ui):
61 > def extsetup(ui):
62 > localrepo.localrepository.supportedformats.remove(b'generaldelta')
62 > localrepo.localrepository.supportedformats.remove(b'generaldelta')
63 > EOF
63 > EOF
64
64
65 $ hg clone --config extensions.rsf=$TESTTMP/removesupportedformat.py --stream http://localhost:$HGPORT/ copy3
65 $ hg clone --config extensions.rsf=$TESTTMP/removesupportedformat.py --stream http://localhost:$HGPORT/ copy3
66 warning: stream clone requested but client is missing requirements: generaldelta
66 warning: stream clone requested but client is missing requirements: generaldelta
67 (see https://www.mercurial-scm.org/wiki/MissingRequirement for more information)
67 (see https://www.mercurial-scm.org/wiki/MissingRequirement for more information)
68 requesting all changes
68 requesting all changes
69 adding changesets
69 adding changesets
70 adding manifests
70 adding manifests
71 adding file changes
71 adding file changes
72 added 1 changesets with 4 changes to 4 files
72 added 1 changesets with 4 changes to 4 files
73 new changesets 8b6053c928fe
73 new changesets 8b6053c928fe
74 updating to branch default
74 updating to branch default
75 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
75 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
76
76
77 clone via pull
77 clone via pull
78
78
79 $ hg clone http://localhost:$HGPORT1/ copy-pull
79 $ hg clone http://localhost:$HGPORT1/ copy-pull
80 requesting all changes
80 requesting all changes
81 adding changesets
81 adding changesets
82 adding manifests
82 adding manifests
83 adding file changes
83 adding file changes
84 added 1 changesets with 4 changes to 4 files
84 added 1 changesets with 4 changes to 4 files
85 new changesets 8b6053c928fe
85 new changesets 8b6053c928fe
86 updating to branch default
86 updating to branch default
87 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
87 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
88 $ hg verify -R copy-pull
88 $ hg verify -R copy-pull
89 checking changesets
89 checking changesets
90 checking manifests
90 checking manifests
91 crosschecking files in changesets and manifests
91 crosschecking files in changesets and manifests
92 checking files
92 checking files
93 checked 1 changesets with 4 changes to 4 files
93 checked 1 changesets with 4 changes to 4 files
94 $ cd test
94 $ cd test
95 $ echo bar > bar
95 $ echo bar > bar
96 $ hg commit -A -d '1 0' -m 2
96 $ hg commit -A -d '1 0' -m 2
97 adding bar
97 adding bar
98 $ cd ..
98 $ cd ..
99
99
100 clone over http with --update
100 clone over http with --update
101
101
102 $ hg clone http://localhost:$HGPORT1/ updated --update 0
102 $ hg clone http://localhost:$HGPORT1/ updated --update 0
103 requesting all changes
103 requesting all changes
104 adding changesets
104 adding changesets
105 adding manifests
105 adding manifests
106 adding file changes
106 adding file changes
107 added 2 changesets with 5 changes to 5 files
107 added 2 changesets with 5 changes to 5 files
108 new changesets 8b6053c928fe:5fed3813f7f5
108 new changesets 8b6053c928fe:5fed3813f7f5
109 updating to branch default
109 updating to branch default
110 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
110 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
111 $ hg log -r . -R updated
111 $ hg log -r . -R updated
112 changeset: 0:8b6053c928fe
112 changeset: 0:8b6053c928fe
113 user: test
113 user: test
114 date: Thu Jan 01 00:00:00 1970 +0000
114 date: Thu Jan 01 00:00:00 1970 +0000
115 summary: 1
115 summary: 1
116
116
117 $ rm -rf updated
117 $ rm -rf updated
118
118
119 incoming via HTTP
119 incoming via HTTP
120
120
121 $ hg clone http://localhost:$HGPORT1/ --rev 0 partial
121 $ hg clone http://localhost:$HGPORT1/ --rev 0 partial
122 adding changesets
122 adding changesets
123 adding manifests
123 adding manifests
124 adding file changes
124 adding file changes
125 added 1 changesets with 4 changes to 4 files
125 added 1 changesets with 4 changes to 4 files
126 new changesets 8b6053c928fe
126 new changesets 8b6053c928fe
127 updating to branch default
127 updating to branch default
128 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
128 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
129 $ cd partial
129 $ cd partial
130 $ touch LOCAL
130 $ touch LOCAL
131 $ hg ci -qAm LOCAL
131 $ hg ci -qAm LOCAL
132 $ hg incoming http://localhost:$HGPORT1/ --template '{desc}\n'
132 $ hg incoming http://localhost:$HGPORT1/ --template '{desc}\n'
133 comparing with http://localhost:$HGPORT1/
133 comparing with http://localhost:$HGPORT1/
134 searching for changes
134 searching for changes
135 2
135 2
136 $ cd ..
136 $ cd ..
137
137
138 pull
138 pull
139
139
140 $ cd copy-pull
140 $ cd copy-pull
141 $ cat >> .hg/hgrc <<EOF
141 $ cat >> .hg/hgrc <<EOF
142 > [hooks]
142 > [hooks]
143 > changegroup = sh -c "printenv.py --line changegroup"
143 > changegroup = sh -c "printenv.py --line changegroup"
144 > EOF
144 > EOF
145 $ hg pull
145 $ hg pull
146 pulling from http://localhost:$HGPORT1/
146 pulling from http://localhost:$HGPORT1/
147 searching for changes
147 searching for changes
148 adding changesets
148 adding changesets
149 adding manifests
149 adding manifests
150 adding file changes
150 adding file changes
151 added 1 changesets with 1 changes to 1 files
151 added 1 changesets with 1 changes to 1 files
152 new changesets 5fed3813f7f5
152 new changesets 5fed3813f7f5
153 changegroup hook: HG_HOOKNAME=changegroup
153 changegroup hook: HG_HOOKNAME=changegroup
154 HG_HOOKTYPE=changegroup
154 HG_HOOKTYPE=changegroup
155 HG_NODE=5fed3813f7f5e1824344fdc9cf8f63bb662c292d
155 HG_NODE=5fed3813f7f5e1824344fdc9cf8f63bb662c292d
156 HG_NODE_LAST=5fed3813f7f5e1824344fdc9cf8f63bb662c292d
156 HG_NODE_LAST=5fed3813f7f5e1824344fdc9cf8f63bb662c292d
157 HG_SOURCE=pull
157 HG_SOURCE=pull
158 HG_TXNID=TXN:$ID$
158 HG_TXNID=TXN:$ID$
159 HG_TXNNAME=pull
159 HG_TXNNAME=pull
160 http://localhost:$HGPORT1/
160 http://localhost:$HGPORT1/
161 HG_URL=http://localhost:$HGPORT1/
161 HG_URL=http://localhost:$HGPORT1/
162
162
163 (run 'hg update' to get a working copy)
163 (run 'hg update' to get a working copy)
164 $ cd ..
164 $ cd ..
165
165
166 clone from invalid URL
166 clone from invalid URL
167
167
168 $ hg clone http://localhost:$HGPORT/bad
168 $ hg clone http://localhost:$HGPORT/bad
169 abort: HTTP Error 404: Not Found
169 abort: HTTP Error 404: Not Found
170 [100]
170 [100]
171
171
172 test http authentication
172 test http authentication
173 + use the same server to test server side streaming preference
173 + use the same server to test server side streaming preference
174
174
175 $ cd test
175 $ cd test
176
176
177 $ hg serve --config extensions.x=$TESTDIR/httpserverauth.py -p $HGPORT2 -d \
177 $ hg serve --config extensions.x=$TESTDIR/httpserverauth.py -p $HGPORT2 -d \
178 > --pid-file=pid --config server.preferuncompressed=True -E ../errors2.log \
178 > --pid-file=pid --config server.preferuncompressed=True -E ../errors2.log \
179 > --config web.push_ssl=False --config web.allow_push=* -A ../access.log
179 > --config web.push_ssl=False --config web.allow_push=* -A ../access.log
180 $ cat pid >> $DAEMON_PIDS
180 $ cat pid >> $DAEMON_PIDS
181
181
182 $ cat << EOF > get_pass.py
182 $ cat << EOF > get_pass.py
183 > import getpass
183 > import getpass
184 > def newgetpass(arg):
184 > def newgetpass(arg):
185 > return "pass"
185 > return "pass"
186 > getpass.getpass = newgetpass
186 > getpass.getpass = newgetpass
187 > EOF
187 > EOF
188
188
189 $ hg id http://localhost:$HGPORT2/
189 $ hg id http://localhost:$HGPORT2/
190 abort: http authorization required for http://localhost:$HGPORT2/
190 abort: http authorization required for http://localhost:$HGPORT2/
191 [255]
191 [255]
192 $ hg id http://localhost:$HGPORT2/
192 $ hg id http://localhost:$HGPORT2/
193 abort: http authorization required for http://localhost:$HGPORT2/
193 abort: http authorization required for http://localhost:$HGPORT2/
194 [255]
194 [255]
195 $ hg id --config ui.interactive=true --debug http://localhost:$HGPORT2/
195 $ hg id --config ui.interactive=true --debug http://localhost:$HGPORT2/
196 using http://localhost:$HGPORT2/
196 using http://localhost:$HGPORT2/
197 sending capabilities command
197 sending capabilities command
198 http authorization required for http://localhost:$HGPORT2/
198 http authorization required for http://localhost:$HGPORT2/
199 realm: mercurial
199 realm: mercurial
200 user: abort: response expected
200 user: abort: response expected
201 [255]
201 [255]
202 $ cat <<'EOF' | hg id --config ui.interactive=true --config ui.nontty=true --debug http://localhost:$HGPORT2/
202 $ cat <<'EOF' | hg id --config ui.interactive=true --config ui.nontty=true --debug http://localhost:$HGPORT2/
203 >
203 >
204 > EOF
204 > EOF
205 using http://localhost:$HGPORT2/
205 using http://localhost:$HGPORT2/
206 sending capabilities command
206 sending capabilities command
207 http authorization required for http://localhost:$HGPORT2/
207 http authorization required for http://localhost:$HGPORT2/
208 realm: mercurial
208 realm: mercurial
209 user:
209 user:
210 password: abort: response expected
210 password: abort: response expected
211 [255]
211 [255]
212 $ cat <<'EOF' | hg id --config ui.interactive=true --config ui.nontty=true --debug http://localhost:$HGPORT2/
212 $ cat <<'EOF' | hg id --config ui.interactive=true --config ui.nontty=true --debug http://localhost:$HGPORT2/
213 >
213 >
214 >
214 >
215 > EOF
215 > EOF
216 using http://localhost:$HGPORT2/
216 using http://localhost:$HGPORT2/
217 sending capabilities command
217 sending capabilities command
218 http authorization required for http://localhost:$HGPORT2/
218 http authorization required for http://localhost:$HGPORT2/
219 realm: mercurial
219 realm: mercurial
220 user:
220 user:
221 password: abort: authorization failed
221 password: abort: authorization failed
222 [255]
222 [255]
223 $ hg id --config ui.interactive=true --config extensions.getpass=get_pass.py http://user@localhost:$HGPORT2/
223 $ hg id --config ui.interactive=true --config extensions.getpass=get_pass.py http://user@localhost:$HGPORT2/
224 http authorization required for http://localhost:$HGPORT2/
224 http authorization required for http://localhost:$HGPORT2/
225 realm: mercurial
225 realm: mercurial
226 user: user
226 user: user
227 password: 5fed3813f7f5
227 password: 5fed3813f7f5
228 $ hg id http://user:pass@localhost:$HGPORT2/
228 $ hg id http://user:pass@localhost:$HGPORT2/
229 5fed3813f7f5
229 5fed3813f7f5
230 $ echo '[auth]' >> .hg/hgrc
230 $ echo '[auth]' >> .hg/hgrc
231 $ echo 'l.schemes=http' >> .hg/hgrc
231 $ echo 'l.schemes=http' >> .hg/hgrc
232 $ echo 'l.prefix=lo' >> .hg/hgrc
232 $ echo 'l.prefix=lo' >> .hg/hgrc
233 $ echo 'l.username=user' >> .hg/hgrc
233 $ echo 'l.username=user' >> .hg/hgrc
234 $ echo 'l.password=pass' >> .hg/hgrc
234 $ echo 'l.password=pass' >> .hg/hgrc
235 $ hg id http://localhost:$HGPORT2/
235 $ hg id http://localhost:$HGPORT2/
236 5fed3813f7f5
236 5fed3813f7f5
237 $ hg id http://localhost:$HGPORT2/
237 $ hg id http://localhost:$HGPORT2/
238 5fed3813f7f5
238 5fed3813f7f5
239 $ hg id http://user@localhost:$HGPORT2/
239 $ hg id http://user@localhost:$HGPORT2/
240 5fed3813f7f5
240 5fed3813f7f5
241
241
242 $ cat > use_digests.py << EOF
242 $ cat > use_digests.py << EOF
243 > from mercurial import (
243 > from mercurial import (
244 > exthelper,
244 > exthelper,
245 > url,
245 > url,
246 > )
246 > )
247 >
247 >
248 > eh = exthelper.exthelper()
248 > eh = exthelper.exthelper()
249 > uisetup = eh.finaluisetup
249 > uisetup = eh.finaluisetup
250 >
250 >
251 > @eh.wrapfunction(url, 'opener')
251 > @eh.wrapfunction(url, 'opener')
252 > def urlopener(orig, *args, **kwargs):
252 > def urlopener(orig, *args, **kwargs):
253 > opener = orig(*args, **kwargs)
253 > opener = orig(*args, **kwargs)
254 > opener.addheaders.append((r'X-HgTest-AuthType', r'Digest'))
254 > opener.addheaders.append((r'X-HgTest-AuthType', r'Digest'))
255 > return opener
255 > return opener
256 > EOF
256 > EOF
257
257
258 $ hg id http://localhost:$HGPORT2/ --config extensions.x=use_digests.py
258 $ hg id http://localhost:$HGPORT2/ --config extensions.x=use_digests.py
259 5fed3813f7f5
259 5fed3813f7f5
260
260
261 #if no-reposimplestore
261 #if no-reposimplestore
262 $ hg clone http://user:pass@localhost:$HGPORT2/ dest 2>&1
262 $ hg clone http://user:pass@localhost:$HGPORT2/ dest 2>&1
263 streaming all changes
263 streaming all changes
264 10 files to transfer, 1.01 KB of data
264 10 files to transfer, 1.01 KB of data
265 transferred * KB in * seconds (*/sec) (glob)
265 transferred * KB in * seconds (*/sec) (glob)
266 updating to branch default
266 updating to branch default
267 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
267 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
268 #endif
268 #endif
269
269
270 --pull should override server's preferuncompressed
270 --pull should override server's preferuncompressed
271 $ hg clone --pull http://user:pass@localhost:$HGPORT2/ dest-pull 2>&1
271 $ hg clone --pull http://user:pass@localhost:$HGPORT2/ dest-pull 2>&1
272 requesting all changes
272 requesting all changes
273 adding changesets
273 adding changesets
274 adding manifests
274 adding manifests
275 adding file changes
275 adding file changes
276 added 2 changesets with 5 changes to 5 files
276 added 2 changesets with 5 changes to 5 files
277 new changesets 8b6053c928fe:5fed3813f7f5
277 new changesets 8b6053c928fe:5fed3813f7f5
278 updating to branch default
278 updating to branch default
279 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
279 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
280
280
281 $ hg id http://user2@localhost:$HGPORT2/
281 $ hg id http://user2@localhost:$HGPORT2/
282 abort: http authorization required for http://localhost:$HGPORT2/
282 abort: http authorization required for http://localhost:$HGPORT2/
283 [255]
283 [255]
284 $ hg id http://user:pass2@localhost:$HGPORT2/
284 $ hg id http://user:pass2@localhost:$HGPORT2/
285 abort: HTTP Error 403: no
285 abort: HTTP Error 403: no
286 [100]
286 [100]
287
287
288 $ hg -R dest-pull tag -r tip top
288 $ hg -R dest-pull tag -r tip top
289 $ hg -R dest-pull push http://user:pass@localhost:$HGPORT2/
289 $ hg -R dest-pull push http://user:pass@localhost:$HGPORT2/
290 pushing to http://user:***@localhost:$HGPORT2/
290 pushing to http://user:***@localhost:$HGPORT2/
291 searching for changes
291 searching for changes
292 remote: adding changesets
292 remote: adding changesets
293 remote: adding manifests
293 remote: adding manifests
294 remote: adding file changes
294 remote: adding file changes
295 remote: added 1 changesets with 1 changes to 1 files
295 remote: added 1 changesets with 1 changes to 1 files
296 $ hg rollback -q
296 $ hg rollback -q
297 $ hg -R dest-pull push http://user:pass@localhost:$HGPORT2/ --debug --config devel.debug.peer-request=yes
297 $ hg -R dest-pull push http://user:pass@localhost:$HGPORT2/ --debug --config devel.debug.peer-request=yes
298 pushing to http://user:***@localhost:$HGPORT2/
298 pushing to http://user:***@localhost:$HGPORT2/
299 using http://localhost:$HGPORT2/
299 using http://localhost:$HGPORT2/
300 http auth: user user, password ****
300 http auth: user user, password ****
301 sending capabilities command
301 sending capabilities command
302 devel-peer-request: GET http://localhost:$HGPORT2/?cmd=capabilities
302 devel-peer-request: GET http://localhost:$HGPORT2/?cmd=capabilities
303 http auth: user user, password ****
303 http auth: user user, password ****
304 devel-peer-request: finished in *.???? seconds (200) (glob)
304 devel-peer-request: finished in *.???? seconds (200) (glob)
305 query 1; heads
305 query 1; heads
306 devel-peer-request: batched-content
306 devel-peer-request: batched-content
307 devel-peer-request: - heads (0 arguments)
307 devel-peer-request: - heads (0 arguments)
308 devel-peer-request: - known (1 arguments)
308 devel-peer-request: - known (1 arguments)
309 sending batch command
309 sending batch command
310 devel-peer-request: GET http://localhost:$HGPORT2/?cmd=batch
310 devel-peer-request: GET http://localhost:$HGPORT2/?cmd=batch
311 devel-peer-request: Vary X-HgArg-1,X-HgProto-1
311 devel-peer-request: Vary X-HgArg-1,X-HgProto-1
312 devel-peer-request: X-hgproto-1 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
312 devel-peer-request: X-hgproto-1 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
313 devel-peer-request: 68 bytes of commands arguments in headers
313 devel-peer-request: 68 bytes of commands arguments in headers
314 devel-peer-request: finished in *.???? seconds (200) (glob)
314 devel-peer-request: finished in *.???? seconds (200) (glob)
315 searching for changes
315 searching for changes
316 all remote heads known locally
316 all remote heads known locally
317 preparing listkeys for "phases"
317 preparing listkeys for "phases"
318 sending listkeys command
318 sending listkeys command
319 devel-peer-request: GET http://localhost:$HGPORT2/?cmd=listkeys
319 devel-peer-request: GET http://localhost:$HGPORT2/?cmd=listkeys
320 devel-peer-request: Vary X-HgArg-1,X-HgProto-1
320 devel-peer-request: Vary X-HgArg-1,X-HgProto-1
321 devel-peer-request: X-hgproto-1 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
321 devel-peer-request: X-hgproto-1 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
322 devel-peer-request: 16 bytes of commands arguments in headers
322 devel-peer-request: 16 bytes of commands arguments in headers
323 devel-peer-request: finished in *.???? seconds (200) (glob)
323 devel-peer-request: finished in *.???? seconds (200) (glob)
324 received listkey for "phases": 58 bytes
324 received listkey for "phases": 58 bytes
325 checking for updated bookmarks
325 checking for updated bookmarks
326 preparing listkeys for "bookmarks"
326 preparing listkeys for "bookmarks"
327 sending listkeys command
327 sending listkeys command
328 devel-peer-request: GET http://localhost:$HGPORT2/?cmd=listkeys
328 devel-peer-request: GET http://localhost:$HGPORT2/?cmd=listkeys
329 devel-peer-request: Vary X-HgArg-1,X-HgProto-1
329 devel-peer-request: Vary X-HgArg-1,X-HgProto-1
330 devel-peer-request: X-hgproto-1 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
330 devel-peer-request: X-hgproto-1 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
331 devel-peer-request: 19 bytes of commands arguments in headers
331 devel-peer-request: 19 bytes of commands arguments in headers
332 devel-peer-request: finished in *.???? seconds (200) (glob)
332 devel-peer-request: finished in *.???? seconds (200) (glob)
333 received listkey for "bookmarks": 0 bytes
333 received listkey for "bookmarks": 0 bytes
334 sending branchmap command
334 sending branchmap command
335 devel-peer-request: GET http://localhost:$HGPORT2/?cmd=branchmap
335 devel-peer-request: GET http://localhost:$HGPORT2/?cmd=branchmap
336 devel-peer-request: Vary X-HgProto-1
336 devel-peer-request: Vary X-HgProto-1
337 devel-peer-request: X-hgproto-1 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
337 devel-peer-request: X-hgproto-1 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
338 devel-peer-request: finished in *.???? seconds (200) (glob)
338 devel-peer-request: finished in *.???? seconds (200) (glob)
339 preparing listkeys for "bookmarks"
339 preparing listkeys for "bookmarks"
340 sending listkeys command
340 sending listkeys command
341 devel-peer-request: GET http://localhost:$HGPORT2/?cmd=listkeys
341 devel-peer-request: GET http://localhost:$HGPORT2/?cmd=listkeys
342 devel-peer-request: Vary X-HgArg-1,X-HgProto-1
342 devel-peer-request: Vary X-HgArg-1,X-HgProto-1
343 devel-peer-request: X-hgproto-1 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
343 devel-peer-request: X-hgproto-1 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
344 devel-peer-request: 19 bytes of commands arguments in headers
344 devel-peer-request: 19 bytes of commands arguments in headers
345 devel-peer-request: finished in *.???? seconds (200) (glob)
345 devel-peer-request: finished in *.???? seconds (200) (glob)
346 received listkey for "bookmarks": 0 bytes
346 received listkey for "bookmarks": 0 bytes
347 1 changesets found
347 1 changesets found
348 list of changesets:
348 list of changesets:
349 7f4e523d01f2cc3765ac8934da3d14db775ff872
349 7f4e523d01f2cc3765ac8934da3d14db775ff872
350 bundle2-output-bundle: "HG20", 5 parts total
350 bundle2-output-bundle: "HG20", 5 parts total
351 bundle2-output-part: "replycaps" 224 bytes payload
351 bundle2-output-part: "replycaps" 207 bytes payload
352 bundle2-output-part: "check:phases" 24 bytes payload
352 bundle2-output-part: "check:phases" 24 bytes payload
353 bundle2-output-part: "check:updated-heads" streamed payload
353 bundle2-output-part: "check:updated-heads" streamed payload
354 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
354 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
355 bundle2-output-part: "phase-heads" 24 bytes payload
355 bundle2-output-part: "phase-heads" 24 bytes payload
356 sending unbundle command
356 sending unbundle command
357 sending 1040 bytes
357 sending 1023 bytes
358 devel-peer-request: POST http://localhost:$HGPORT2/?cmd=unbundle
358 devel-peer-request: POST http://localhost:$HGPORT2/?cmd=unbundle
359 devel-peer-request: Content-length 1040
359 devel-peer-request: Content-length 1023
360 devel-peer-request: Content-type application/mercurial-0.1
360 devel-peer-request: Content-type application/mercurial-0.1
361 devel-peer-request: Vary X-HgArg-1,X-HgProto-1
361 devel-peer-request: Vary X-HgArg-1,X-HgProto-1
362 devel-peer-request: X-hgproto-1 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
362 devel-peer-request: X-hgproto-1 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
363 devel-peer-request: 16 bytes of commands arguments in headers
363 devel-peer-request: 16 bytes of commands arguments in headers
364 devel-peer-request: 1040 bytes of data
364 devel-peer-request: 1023 bytes of data
365 devel-peer-request: finished in *.???? seconds (200) (glob)
365 devel-peer-request: finished in *.???? seconds (200) (glob)
366 bundle2-input-bundle: no-transaction
366 bundle2-input-bundle: no-transaction
367 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
367 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
368 bundle2-input-part: "output" (advisory) (params: 0 advisory) supported
368 bundle2-input-part: "output" (advisory) (params: 0 advisory) supported
369 bundle2-input-part: total payload size 55
369 bundle2-input-part: total payload size 55
370 remote: adding changesets
370 remote: adding changesets
371 remote: adding manifests
371 remote: adding manifests
372 remote: adding file changes
372 remote: adding file changes
373 bundle2-input-part: "output" (advisory) supported
373 bundle2-input-part: "output" (advisory) supported
374 bundle2-input-part: total payload size 45
374 bundle2-input-part: total payload size 45
375 remote: added 1 changesets with 1 changes to 1 files
375 remote: added 1 changesets with 1 changes to 1 files
376 bundle2-input-bundle: 3 parts total
376 bundle2-input-bundle: 3 parts total
377 preparing listkeys for "phases"
377 preparing listkeys for "phases"
378 sending listkeys command
378 sending listkeys command
379 devel-peer-request: GET http://localhost:$HGPORT2/?cmd=listkeys
379 devel-peer-request: GET http://localhost:$HGPORT2/?cmd=listkeys
380 devel-peer-request: Vary X-HgArg-1,X-HgProto-1
380 devel-peer-request: Vary X-HgArg-1,X-HgProto-1
381 devel-peer-request: X-hgproto-1 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
381 devel-peer-request: X-hgproto-1 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
382 devel-peer-request: 16 bytes of commands arguments in headers
382 devel-peer-request: 16 bytes of commands arguments in headers
383 devel-peer-request: finished in *.???? seconds (200) (glob)
383 devel-peer-request: finished in *.???? seconds (200) (glob)
384 received listkey for "phases": 15 bytes
384 received listkey for "phases": 15 bytes
385 $ hg rollback -q
385 $ hg rollback -q
386
386
387 $ sed 's/.*] "/"/' < ../access.log
387 $ sed 's/.*] "/"/' < ../access.log
388 "GET /?cmd=capabilities HTTP/1.1" 401 -
388 "GET /?cmd=capabilities HTTP/1.1" 401 -
389 "GET /?cmd=capabilities HTTP/1.1" 401 -
389 "GET /?cmd=capabilities HTTP/1.1" 401 -
390 "GET /?cmd=capabilities HTTP/1.1" 401 -
390 "GET /?cmd=capabilities HTTP/1.1" 401 -
391 "GET /?cmd=capabilities HTTP/1.1" 401 -
391 "GET /?cmd=capabilities HTTP/1.1" 401 -
392 "GET /?cmd=capabilities HTTP/1.1" 401 -
392 "GET /?cmd=capabilities HTTP/1.1" 401 -
393 "GET /?cmd=capabilities HTTP/1.1" 401 -
393 "GET /?cmd=capabilities HTTP/1.1" 401 -
394 "GET /?cmd=capabilities HTTP/1.1" 200 -
394 "GET /?cmd=capabilities HTTP/1.1" 200 -
395 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
395 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
396 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
396 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
397 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
397 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
398 "GET /?cmd=capabilities HTTP/1.1" 401 -
398 "GET /?cmd=capabilities HTTP/1.1" 401 -
399 "GET /?cmd=capabilities HTTP/1.1" 200 -
399 "GET /?cmd=capabilities HTTP/1.1" 200 -
400 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
400 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
401 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
401 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
402 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
402 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
403 "GET /?cmd=capabilities HTTP/1.1" 401 -
403 "GET /?cmd=capabilities HTTP/1.1" 401 -
404 "GET /?cmd=capabilities HTTP/1.1" 200 -
404 "GET /?cmd=capabilities HTTP/1.1" 200 -
405 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
405 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
406 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
406 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
407 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
407 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
408 "GET /?cmd=capabilities HTTP/1.1" 401 -
408 "GET /?cmd=capabilities HTTP/1.1" 401 -
409 "GET /?cmd=capabilities HTTP/1.1" 200 -
409 "GET /?cmd=capabilities HTTP/1.1" 200 -
410 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
410 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
411 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
411 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
412 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
412 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
413 "GET /?cmd=capabilities HTTP/1.1" 401 -
413 "GET /?cmd=capabilities HTTP/1.1" 401 -
414 "GET /?cmd=capabilities HTTP/1.1" 200 -
414 "GET /?cmd=capabilities HTTP/1.1" 200 -
415 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
415 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
416 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
416 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
417 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
417 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
418 "GET /?cmd=capabilities HTTP/1.1" 401 - x-hgtest-authtype:Digest
418 "GET /?cmd=capabilities HTTP/1.1" 401 - x-hgtest-authtype:Digest
419 "GET /?cmd=capabilities HTTP/1.1" 200 - x-hgtest-authtype:Digest
419 "GET /?cmd=capabilities HTTP/1.1" 200 - x-hgtest-authtype:Digest
420 "GET /?cmd=lookup HTTP/1.1" 401 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest
420 "GET /?cmd=lookup HTTP/1.1" 401 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest
421 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest
421 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest
422 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest
422 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest
423 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest
423 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest
424 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest
424 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest
425 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest
425 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest
426 "GET /?cmd=capabilities HTTP/1.1" 401 - (no-reposimplestore !)
426 "GET /?cmd=capabilities HTTP/1.1" 401 - (no-reposimplestore !)
427 "GET /?cmd=capabilities HTTP/1.1" 200 - (no-reposimplestore !)
427 "GET /?cmd=capabilities HTTP/1.1" 200 - (no-reposimplestore !)
428 "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (no-reposimplestore !)
428 "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (no-reposimplestore !)
429 "GET /?cmd=getbundle HTTP/1.1" 200 - x-hgarg-1:bookmarks=1&$USUAL_BUNDLE_CAPS$&cg=0&common=0000000000000000000000000000000000000000&heads=5fed3813f7f5e1824344fdc9cf8f63bb662c292d&listkeys=bookmarks&stream=1 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (no-reposimplestore !)
429 "GET /?cmd=getbundle HTTP/1.1" 200 - x-hgarg-1:bookmarks=1&$USUAL_BUNDLE_CAPS$&cg=0&common=0000000000000000000000000000000000000000&heads=5fed3813f7f5e1824344fdc9cf8f63bb662c292d&listkeys=bookmarks&stream=1 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (no-reposimplestore !)
430 "GET /?cmd=capabilities HTTP/1.1" 401 - (no-reposimplestore !)
430 "GET /?cmd=capabilities HTTP/1.1" 401 - (no-reposimplestore !)
431 "GET /?cmd=capabilities HTTP/1.1" 200 - (no-reposimplestore !)
431 "GET /?cmd=capabilities HTTP/1.1" 200 - (no-reposimplestore !)
432 "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
432 "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
433 "GET /?cmd=getbundle HTTP/1.1" 200 - x-hgarg-1:bookmarks=1&$USUAL_BUNDLE_CAPS$&cg=1&common=0000000000000000000000000000000000000000&heads=5fed3813f7f5e1824344fdc9cf8f63bb662c292d&listkeys=bookmarks&phases=1 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
433 "GET /?cmd=getbundle HTTP/1.1" 200 - x-hgarg-1:bookmarks=1&$USUAL_BUNDLE_CAPS$&cg=1&common=0000000000000000000000000000000000000000&heads=5fed3813f7f5e1824344fdc9cf8f63bb662c292d&listkeys=bookmarks&phases=1 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
434 "GET /?cmd=capabilities HTTP/1.1" 401 -
434 "GET /?cmd=capabilities HTTP/1.1" 401 -
435 "GET /?cmd=capabilities HTTP/1.1" 401 -
435 "GET /?cmd=capabilities HTTP/1.1" 401 -
436 "GET /?cmd=capabilities HTTP/1.1" 403 -
436 "GET /?cmd=capabilities HTTP/1.1" 403 -
437 "GET /?cmd=capabilities HTTP/1.1" 401 -
437 "GET /?cmd=capabilities HTTP/1.1" 401 -
438 "GET /?cmd=capabilities HTTP/1.1" 200 -
438 "GET /?cmd=capabilities HTTP/1.1" 200 -
439 "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D7f4e523d01f2cc3765ac8934da3d14db775ff872 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
439 "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D7f4e523d01f2cc3765ac8934da3d14db775ff872 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
440 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
440 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
441 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
441 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
442 "GET /?cmd=branchmap HTTP/1.1" 200 - x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
442 "GET /?cmd=branchmap HTTP/1.1" 200 - x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
443 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
443 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
444 "POST /?cmd=unbundle HTTP/1.1" 200 - x-hgarg-1:heads=666f726365* (glob)
444 "POST /?cmd=unbundle HTTP/1.1" 200 - x-hgarg-1:heads=666f726365* (glob)
445 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
445 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
446 "GET /?cmd=capabilities HTTP/1.1" 401 -
446 "GET /?cmd=capabilities HTTP/1.1" 401 -
447 "GET /?cmd=capabilities HTTP/1.1" 200 -
447 "GET /?cmd=capabilities HTTP/1.1" 200 -
448 "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D7f4e523d01f2cc3765ac8934da3d14db775ff872 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
448 "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D7f4e523d01f2cc3765ac8934da3d14db775ff872 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
449 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
449 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
450 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
450 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
451 "GET /?cmd=branchmap HTTP/1.1" 200 - x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
451 "GET /?cmd=branchmap HTTP/1.1" 200 - x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
452 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
452 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
453 "POST /?cmd=unbundle HTTP/1.1" 200 - x-hgarg-1:heads=666f726365 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
453 "POST /?cmd=unbundle HTTP/1.1" 200 - x-hgarg-1:heads=666f726365 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
454 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
454 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
455
455
456 $ cd ..
456 $ cd ..
457
457
458 clone of serve with repo in root and unserved subrepo (issue2970)
458 clone of serve with repo in root and unserved subrepo (issue2970)
459
459
460 $ hg --cwd test init sub
460 $ hg --cwd test init sub
461 $ echo empty > test/sub/empty
461 $ echo empty > test/sub/empty
462 $ hg --cwd test/sub add empty
462 $ hg --cwd test/sub add empty
463 $ hg --cwd test/sub commit -qm 'add empty'
463 $ hg --cwd test/sub commit -qm 'add empty'
464 $ hg --cwd test/sub tag -r 0 something
464 $ hg --cwd test/sub tag -r 0 something
465 $ echo sub = sub > test/.hgsub
465 $ echo sub = sub > test/.hgsub
466 $ hg --cwd test add .hgsub
466 $ hg --cwd test add .hgsub
467 $ hg --cwd test commit -qm 'add subrepo'
467 $ hg --cwd test commit -qm 'add subrepo'
468 $ hg clone http://localhost:$HGPORT noslash-clone
468 $ hg clone http://localhost:$HGPORT noslash-clone
469 requesting all changes
469 requesting all changes
470 adding changesets
470 adding changesets
471 adding manifests
471 adding manifests
472 adding file changes
472 adding file changes
473 added 3 changesets with 7 changes to 7 files
473 added 3 changesets with 7 changes to 7 files
474 new changesets 8b6053c928fe:56f9bc90cce6
474 new changesets 8b6053c928fe:56f9bc90cce6
475 updating to branch default
475 updating to branch default
476 cloning subrepo sub from http://localhost:$HGPORT/sub
476 cloning subrepo sub from http://localhost:$HGPORT/sub
477 abort: HTTP Error 404: Not Found
477 abort: HTTP Error 404: Not Found
478 [100]
478 [100]
479 $ hg clone http://localhost:$HGPORT/ slash-clone
479 $ hg clone http://localhost:$HGPORT/ slash-clone
480 requesting all changes
480 requesting all changes
481 adding changesets
481 adding changesets
482 adding manifests
482 adding manifests
483 adding file changes
483 adding file changes
484 added 3 changesets with 7 changes to 7 files
484 added 3 changesets with 7 changes to 7 files
485 new changesets 8b6053c928fe:56f9bc90cce6
485 new changesets 8b6053c928fe:56f9bc90cce6
486 updating to branch default
486 updating to branch default
487 cloning subrepo sub from http://localhost:$HGPORT/sub
487 cloning subrepo sub from http://localhost:$HGPORT/sub
488 abort: HTTP Error 404: Not Found
488 abort: HTTP Error 404: Not Found
489 [100]
489 [100]
490
490
491 check error log
491 check error log
492
492
493 $ cat error.log
493 $ cat error.log
494
494
495 $ cat errors2.log
495 $ cat errors2.log
496
496
497 check abort error reporting while pulling/cloning
497 check abort error reporting while pulling/cloning
498
498
499 $ $RUNTESTDIR/killdaemons.py
499 $ $RUNTESTDIR/killdaemons.py
500 $ hg serve -R test -p $HGPORT -d --pid-file=hg3.pid -E error.log --config extensions.crash=${TESTDIR}/crashgetbundler.py
500 $ hg serve -R test -p $HGPORT -d --pid-file=hg3.pid -E error.log --config extensions.crash=${TESTDIR}/crashgetbundler.py
501 $ cat hg3.pid >> $DAEMON_PIDS
501 $ cat hg3.pid >> $DAEMON_PIDS
502 $ hg clone http://localhost:$HGPORT/ abort-clone
502 $ hg clone http://localhost:$HGPORT/ abort-clone
503 requesting all changes
503 requesting all changes
504 remote: abort: this is an exercise
504 remote: abort: this is an exercise
505 abort: pull failed on remote
505 abort: pull failed on remote
506 [255]
506 [255]
507 $ cat error.log
507 $ cat error.log
508
508
509 disable pull-based clones
509 disable pull-based clones
510
510
511 $ hg serve -R test -p $HGPORT1 -d --pid-file=hg4.pid -E error.log --config server.disablefullbundle=True
511 $ hg serve -R test -p $HGPORT1 -d --pid-file=hg4.pid -E error.log --config server.disablefullbundle=True
512 $ cat hg4.pid >> $DAEMON_PIDS
512 $ cat hg4.pid >> $DAEMON_PIDS
513 $ hg clone http://localhost:$HGPORT1/ disable-pull-clone
513 $ hg clone http://localhost:$HGPORT1/ disable-pull-clone
514 requesting all changes
514 requesting all changes
515 remote: abort: server has pull-based clones disabled
515 remote: abort: server has pull-based clones disabled
516 abort: pull failed on remote
516 abort: pull failed on remote
517 (remove --pull if specified or upgrade Mercurial)
517 (remove --pull if specified or upgrade Mercurial)
518 [255]
518 [255]
519
519
520 #if no-reposimplestore
520 #if no-reposimplestore
521 ... but keep stream clones working
521 ... but keep stream clones working
522
522
523 $ hg clone --stream --noupdate http://localhost:$HGPORT1/ test-stream-clone
523 $ hg clone --stream --noupdate http://localhost:$HGPORT1/ test-stream-clone
524 streaming all changes
524 streaming all changes
525 * files to transfer, * of data (glob)
525 * files to transfer, * of data (glob)
526 transferred * in * seconds (*/sec) (glob)
526 transferred * in * seconds (*/sec) (glob)
527 $ cat error.log
527 $ cat error.log
528 #endif
528 #endif
529
529
530 ... and also keep partial clones and pulls working
530 ... and also keep partial clones and pulls working
531 $ hg clone http://localhost:$HGPORT1 --rev 0 test/partial/clone
531 $ hg clone http://localhost:$HGPORT1 --rev 0 test/partial/clone
532 adding changesets
532 adding changesets
533 adding manifests
533 adding manifests
534 adding file changes
534 adding file changes
535 added 1 changesets with 4 changes to 4 files
535 added 1 changesets with 4 changes to 4 files
536 new changesets 8b6053c928fe
536 new changesets 8b6053c928fe
537 updating to branch default
537 updating to branch default
538 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
538 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
539 $ hg pull -R test/partial/clone
539 $ hg pull -R test/partial/clone
540 pulling from http://localhost:$HGPORT1/
540 pulling from http://localhost:$HGPORT1/
541 searching for changes
541 searching for changes
542 adding changesets
542 adding changesets
543 adding manifests
543 adding manifests
544 adding file changes
544 adding file changes
545 added 2 changesets with 3 changes to 3 files
545 added 2 changesets with 3 changes to 3 files
546 new changesets 5fed3813f7f5:56f9bc90cce6
546 new changesets 5fed3813f7f5:56f9bc90cce6
547 (run 'hg update' to get a working copy)
547 (run 'hg update' to get a working copy)
548
548
549 $ hg clone -U -r 0 test/partial/clone test/another/clone
549 $ hg clone -U -r 0 test/partial/clone test/another/clone
550 adding changesets
550 adding changesets
551 adding manifests
551 adding manifests
552 adding file changes
552 adding file changes
553 added 1 changesets with 4 changes to 4 files
553 added 1 changesets with 4 changes to 4 files
554 new changesets 8b6053c928fe
554 new changesets 8b6053c928fe
555
555
556 corrupt cookies file should yield a warning
556 corrupt cookies file should yield a warning
557
557
558 $ cat > $TESTTMP/cookies.txt << EOF
558 $ cat > $TESTTMP/cookies.txt << EOF
559 > bad format
559 > bad format
560 > EOF
560 > EOF
561
561
562 $ hg --config auth.cookiefile=$TESTTMP/cookies.txt id http://localhost:$HGPORT/
562 $ hg --config auth.cookiefile=$TESTTMP/cookies.txt id http://localhost:$HGPORT/
563 (error loading cookie file $TESTTMP/cookies.txt: '*/cookies.txt' does not look like a Netscape format cookies file; continuing without cookies) (glob)
563 (error loading cookie file $TESTTMP/cookies.txt: '*/cookies.txt' does not look like a Netscape format cookies file; continuing without cookies) (glob)
564 56f9bc90cce6
564 56f9bc90cce6
565
565
566 $ killdaemons.py
566 $ killdaemons.py
567
567
568 Create dummy authentication handler that looks for cookies. It doesn't do anything
568 Create dummy authentication handler that looks for cookies. It doesn't do anything
569 useful. It just raises an HTTP 500 with details about the Cookie request header.
569 useful. It just raises an HTTP 500 with details about the Cookie request header.
570 We raise HTTP 500 because its message is printed in the abort message.
570 We raise HTTP 500 because its message is printed in the abort message.
571
571
572 $ cat > cookieauth.py << EOF
572 $ cat > cookieauth.py << EOF
573 > from mercurial import util
573 > from mercurial import util
574 > from mercurial.hgweb import common
574 > from mercurial.hgweb import common
575 > def perform_authentication(hgweb, req, op):
575 > def perform_authentication(hgweb, req, op):
576 > cookie = req.headers.get(b'Cookie')
576 > cookie = req.headers.get(b'Cookie')
577 > if not cookie:
577 > if not cookie:
578 > raise common.ErrorResponse(common.HTTP_SERVER_ERROR, b'no-cookie')
578 > raise common.ErrorResponse(common.HTTP_SERVER_ERROR, b'no-cookie')
579 > raise common.ErrorResponse(common.HTTP_SERVER_ERROR, b'Cookie: %s' % cookie)
579 > raise common.ErrorResponse(common.HTTP_SERVER_ERROR, b'Cookie: %s' % cookie)
580 > def extsetup(ui):
580 > def extsetup(ui):
581 > common.permhooks.insert(0, perform_authentication)
581 > common.permhooks.insert(0, perform_authentication)
582 > EOF
582 > EOF
583
583
584 $ hg serve --config extensions.cookieauth=cookieauth.py -R test -p $HGPORT -d --pid-file=pid
584 $ hg serve --config extensions.cookieauth=cookieauth.py -R test -p $HGPORT -d --pid-file=pid
585 $ cat pid > $DAEMON_PIDS
585 $ cat pid > $DAEMON_PIDS
586
586
587 Request without cookie sent should fail due to lack of cookie
587 Request without cookie sent should fail due to lack of cookie
588
588
589 $ hg id http://localhost:$HGPORT
589 $ hg id http://localhost:$HGPORT
590 abort: HTTP Error 500: no-cookie
590 abort: HTTP Error 500: no-cookie
591 [100]
591 [100]
592
592
593 Populate a cookies file
593 Populate a cookies file
594
594
595 $ cat > cookies.txt << EOF
595 $ cat > cookies.txt << EOF
596 > # HTTP Cookie File
596 > # HTTP Cookie File
597 > # Expiration is 2030-01-01 at midnight
597 > # Expiration is 2030-01-01 at midnight
598 > .example.com TRUE / FALSE 1893456000 hgkey examplevalue
598 > .example.com TRUE / FALSE 1893456000 hgkey examplevalue
599 > EOF
599 > EOF
600
600
601 Should not send a cookie for another domain
601 Should not send a cookie for another domain
602
602
603 $ hg --config auth.cookiefile=cookies.txt id http://localhost:$HGPORT/
603 $ hg --config auth.cookiefile=cookies.txt id http://localhost:$HGPORT/
604 abort: HTTP Error 500: no-cookie
604 abort: HTTP Error 500: no-cookie
605 [100]
605 [100]
606
606
607 Add a cookie entry for our test server and verify it is sent
607 Add a cookie entry for our test server and verify it is sent
608
608
609 $ cat >> cookies.txt << EOF
609 $ cat >> cookies.txt << EOF
610 > localhost.local FALSE / FALSE 1893456000 hgkey localhostvalue
610 > localhost.local FALSE / FALSE 1893456000 hgkey localhostvalue
611 > EOF
611 > EOF
612
612
613 $ hg --config auth.cookiefile=cookies.txt id http://localhost:$HGPORT/
613 $ hg --config auth.cookiefile=cookies.txt id http://localhost:$HGPORT/
614 abort: HTTP Error 500: Cookie: hgkey=localhostvalue
614 abort: HTTP Error 500: Cookie: hgkey=localhostvalue
615 [100]
615 [100]
@@ -1,514 +1,512 b''
1 #require serve no-reposimplestore no-chg
1 #require serve no-reposimplestore no-chg
2
2
3 $ cat >> $HGRCPATH <<EOF
3 $ cat >> $HGRCPATH <<EOF
4 > [extensions]
4 > [extensions]
5 > lfs=
5 > lfs=
6 > [lfs]
6 > [lfs]
7 > track=all()
7 > track=all()
8 > [web]
8 > [web]
9 > push_ssl = False
9 > push_ssl = False
10 > allow-push = *
10 > allow-push = *
11 > EOF
11 > EOF
12
12
13 Serving LFS files can experimentally be turned off. The long term solution is
13 Serving LFS files can experimentally be turned off. The long term solution is
14 to support the 'verify' action in both client and server, so that the server can
14 to support the 'verify' action in both client and server, so that the server can
15 tell the client to store files elsewhere.
15 tell the client to store files elsewhere.
16
16
17 $ hg init server
17 $ hg init server
18 $ hg --config "lfs.usercache=$TESTTMP/servercache" \
18 $ hg --config "lfs.usercache=$TESTTMP/servercache" \
19 > --config experimental.lfs.serve=False -R server serve -d \
19 > --config experimental.lfs.serve=False -R server serve -d \
20 > --config experimental.lfs.worker-enable=False \
20 > --config experimental.lfs.worker-enable=False \
21 > -p $HGPORT --pid-file=hg.pid -A $TESTTMP/access.log -E $TESTTMP/errors.log
21 > -p $HGPORT --pid-file=hg.pid -A $TESTTMP/access.log -E $TESTTMP/errors.log
22 $ cat hg.pid >> $DAEMON_PIDS
22 $ cat hg.pid >> $DAEMON_PIDS
23
23
24 Uploads fail...
24 Uploads fail...
25
25
26 $ hg init client
26 $ hg init client
27 $ echo 'this-is-an-lfs-file' > client/lfs.bin
27 $ echo 'this-is-an-lfs-file' > client/lfs.bin
28 $ hg -R client ci -Am 'initial commit'
28 $ hg -R client ci -Am 'initial commit'
29 adding lfs.bin
29 adding lfs.bin
30 $ hg -R client push http://localhost:$HGPORT
30 $ hg -R client push http://localhost:$HGPORT
31 pushing to http://localhost:$HGPORT/
31 pushing to http://localhost:$HGPORT/
32 searching for changes
32 searching for changes
33 abort: LFS HTTP error: HTTP Error 400: no such method: .git
33 abort: LFS HTTP error: HTTP Error 400: no such method: .git
34 (check that lfs serving is enabled on http://localhost:$HGPORT/.git/info/lfs and "upload" is supported)
34 (check that lfs serving is enabled on http://localhost:$HGPORT/.git/info/lfs and "upload" is supported)
35 [50]
35 [50]
36
36
37 ... so do a local push to make the data available. Remove the blob from the
37 ... so do a local push to make the data available. Remove the blob from the
38 default cache, so it attempts to download.
38 default cache, so it attempts to download.
39 $ hg --config "lfs.usercache=$TESTTMP/servercache" \
39 $ hg --config "lfs.usercache=$TESTTMP/servercache" \
40 > --config "lfs.url=null://" \
40 > --config "lfs.url=null://" \
41 > -R client push -q server
41 > -R client push -q server
42 $ mv `hg config lfs.usercache` $TESTTMP/servercache
42 $ mv `hg config lfs.usercache` $TESTTMP/servercache
43
43
44 Downloads fail...
44 Downloads fail...
45
45
46 $ hg clone http://localhost:$HGPORT httpclone
46 $ hg clone http://localhost:$HGPORT httpclone
47 (remote is using large file support (lfs); lfs will be enabled for this repository)
47 (remote is using large file support (lfs); lfs will be enabled for this repository)
48 requesting all changes
48 requesting all changes
49 adding changesets
49 adding changesets
50 adding manifests
50 adding manifests
51 adding file changes
51 adding file changes
52 added 1 changesets with 1 changes to 1 files
52 added 1 changesets with 1 changes to 1 files
53 new changesets 525251863cad
53 new changesets 525251863cad
54 updating to branch default
54 updating to branch default
55 abort: LFS HTTP error: HTTP Error 400: no such method: .git
55 abort: LFS HTTP error: HTTP Error 400: no such method: .git
56 (check that lfs serving is enabled on http://localhost:$HGPORT/.git/info/lfs and "download" is supported)
56 (check that lfs serving is enabled on http://localhost:$HGPORT/.git/info/lfs and "download" is supported)
57 [50]
57 [50]
58
58
59 $ "$PYTHON" $RUNTESTDIR/killdaemons.py $DAEMON_PIDS
59 $ "$PYTHON" $RUNTESTDIR/killdaemons.py $DAEMON_PIDS
60
60
61 $ cat $TESTTMP/access.log $TESTTMP/errors.log
61 $ cat $TESTTMP/access.log $TESTTMP/errors.log
62 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
62 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
63 $LOCALIP - - [$LOGDATE$] "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D525251863cad618e55d483555f3d00a2ca99597e x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
63 $LOCALIP - - [$LOGDATE$] "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D525251863cad618e55d483555f3d00a2ca99597e x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
64 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
64 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
65 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
65 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
66 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 400 - (glob)
66 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 400 - (glob)
67 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
67 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
68 $LOCALIP - - [$LOGDATE$] "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
68 $LOCALIP - - [$LOGDATE$] "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
69 $LOCALIP - - [$LOGDATE$] "GET /?cmd=getbundle HTTP/1.1" 200 - x-hgarg-1:bookmarks=1&bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%252C03%250Acheckheads%253Drelated%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Aphases%253Dheads%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps%250Arev-branch-cache%250Astream%253Dv2&cg=1&common=0000000000000000000000000000000000000000&heads=525251863cad618e55d483555f3d00a2ca99597e&listkeys=bookmarks&phases=1 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
69 $LOCALIP - - [$LOGDATE$] "GET /?cmd=getbundle HTTP/1.1" 200 - x-hgarg-1:bookmarks=1&bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%252C03%250Acheckheads%253Drelated%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Aphases%253Dheads%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps%250Astream%253Dv2&cg=1&common=0000000000000000000000000000000000000000&heads=525251863cad618e55d483555f3d00a2ca99597e&listkeys=bookmarks&phases=1 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
70 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 400 - (glob)
70 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 400 - (glob)
71
71
72 $ rm -f $TESTTMP/access.log $TESTTMP/errors.log
72 $ rm -f $TESTTMP/access.log $TESTTMP/errors.log
73 $ hg --config "lfs.usercache=$TESTTMP/servercache" -R server serve -d \
73 $ hg --config "lfs.usercache=$TESTTMP/servercache" -R server serve -d \
74 > -p $HGPORT --pid-file=hg.pid --prefix=subdir/mount/point \
74 > -p $HGPORT --pid-file=hg.pid --prefix=subdir/mount/point \
75 > -A $TESTTMP/access.log -E $TESTTMP/errors.log
75 > -A $TESTTMP/access.log -E $TESTTMP/errors.log
76 $ cat hg.pid >> $DAEMON_PIDS
76 $ cat hg.pid >> $DAEMON_PIDS
77
77
78 Reasonable hint for a misconfigured blob server
78 Reasonable hint for a misconfigured blob server
79
79
80 $ hg -R httpclone update default --config lfs.url=http://localhost:$HGPORT/missing
80 $ hg -R httpclone update default --config lfs.url=http://localhost:$HGPORT/missing
81 abort: LFS HTTP error: HTTP Error 404: Not Found
81 abort: LFS HTTP error: HTTP Error 404: Not Found
82 (the "lfs.url" config may be used to override http://localhost:$HGPORT/missing)
82 (the "lfs.url" config may be used to override http://localhost:$HGPORT/missing)
83 [50]
83 [50]
84
84
85 $ hg -R httpclone update default --config lfs.url=http://localhost:$HGPORT2/missing
85 $ hg -R httpclone update default --config lfs.url=http://localhost:$HGPORT2/missing
86 abort: LFS error: *onnection *refused* (glob) (?)
86 abort: LFS error: *onnection *refused* (glob) (?)
87 abort: LFS error: $EADDRNOTAVAIL$ (glob) (?)
87 abort: LFS error: $EADDRNOTAVAIL$ (glob) (?)
88 abort: LFS error: No route to host (?)
88 abort: LFS error: No route to host (?)
89 (the "lfs.url" config may be used to override http://localhost:$HGPORT2/missing)
89 (the "lfs.url" config may be used to override http://localhost:$HGPORT2/missing)
90 [50]
90 [50]
91
91
92 Blob URIs are correct when --prefix is used
92 Blob URIs are correct when --prefix is used
93
93
94 $ hg clone --debug http://localhost:$HGPORT/subdir/mount/point cloned2
94 $ hg clone --debug http://localhost:$HGPORT/subdir/mount/point cloned2
95 using http://localhost:$HGPORT/subdir/mount/point
95 using http://localhost:$HGPORT/subdir/mount/point
96 sending capabilities command
96 sending capabilities command
97 (remote is using large file support (lfs); lfs will be enabled for this repository)
97 (remote is using large file support (lfs); lfs will be enabled for this repository)
98 query 1; heads
98 query 1; heads
99 sending batch command
99 sending batch command
100 requesting all changes
100 requesting all changes
101 sending getbundle command
101 sending getbundle command
102 bundle2-input-bundle: with-transaction
102 bundle2-input-bundle: with-transaction
103 bundle2-input-part: "changegroup" (params: 1 mandatory 1 advisory) supported
103 bundle2-input-part: "changegroup" (params: 1 mandatory 1 advisory) supported
104 adding changesets
104 adding changesets
105 add changeset 525251863cad
105 add changeset 525251863cad
106 adding manifests
106 adding manifests
107 adding file changes
107 adding file changes
108 adding lfs.bin revisions
108 adding lfs.bin revisions
109 bundle2-input-part: total payload size 648
109 bundle2-input-part: total payload size 648
110 bundle2-input-part: "listkeys" (params: 1 mandatory) supported
110 bundle2-input-part: "listkeys" (params: 1 mandatory) supported
111 bundle2-input-part: "phase-heads" supported
111 bundle2-input-part: "phase-heads" supported
112 bundle2-input-part: total payload size 24
112 bundle2-input-part: total payload size 24
113 bundle2-input-part: "cache:rev-branch-cache" (advisory) supported
113 bundle2-input-bundle: 3 parts total
114 bundle2-input-part: total payload size 39
115 bundle2-input-bundle: 4 parts total
116 checking for updated bookmarks
114 checking for updated bookmarks
117 updating the branch cache
115 updating the branch cache
118 added 1 changesets with 1 changes to 1 files
116 added 1 changesets with 1 changes to 1 files
119 new changesets 525251863cad
117 new changesets 525251863cad
120 updating to branch default
118 updating to branch default
121 resolving manifests
119 resolving manifests
122 branchmerge: False, force: False, partial: False
120 branchmerge: False, force: False, partial: False
123 ancestor: 000000000000, local: 000000000000+, remote: 525251863cad
121 ancestor: 000000000000, local: 000000000000+, remote: 525251863cad
124 lfs: assuming remote store: http://localhost:$HGPORT/subdir/mount/point/.git/info/lfs
122 lfs: assuming remote store: http://localhost:$HGPORT/subdir/mount/point/.git/info/lfs
125 Status: 200
123 Status: 200
126 Content-Length: 371
124 Content-Length: 371
127 Content-Type: application/vnd.git-lfs+json
125 Content-Type: application/vnd.git-lfs+json
128 Date: $HTTP_DATE$
126 Date: $HTTP_DATE$
129 Server: testing stub value
127 Server: testing stub value
130 {
128 {
131 "objects": [
129 "objects": [
132 {
130 {
133 "actions": {
131 "actions": {
134 "download": {
132 "download": {
135 "expires_at": "$ISO_8601_DATE_TIME$"
133 "expires_at": "$ISO_8601_DATE_TIME$"
136 "header": {
134 "header": {
137 "Accept": "application/vnd.git-lfs"
135 "Accept": "application/vnd.git-lfs"
138 }
136 }
139 "href": "http://localhost:$HGPORT/subdir/mount/point/.hg/lfs/objects/f03217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e"
137 "href": "http://localhost:$HGPORT/subdir/mount/point/.hg/lfs/objects/f03217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e"
140 }
138 }
141 }
139 }
142 "oid": "f03217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e"
140 "oid": "f03217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e"
143 "size": 20
141 "size": 20
144 }
142 }
145 ]
143 ]
146 "transfer": "basic"
144 "transfer": "basic"
147 }
145 }
148 lfs: downloading f03217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e (20 bytes)
146 lfs: downloading f03217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e (20 bytes)
149 Status: 200
147 Status: 200
150 Content-Length: 20
148 Content-Length: 20
151 Content-Type: application/octet-stream
149 Content-Type: application/octet-stream
152 Date: $HTTP_DATE$
150 Date: $HTTP_DATE$
153 Server: testing stub value
151 Server: testing stub value
154 lfs: adding f03217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e to the usercache
152 lfs: adding f03217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e to the usercache
155 lfs: processed: f03217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e
153 lfs: processed: f03217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e
156 lfs: downloaded 1 files (20 bytes)
154 lfs: downloaded 1 files (20 bytes)
157 lfs.bin: remote created -> g
155 lfs.bin: remote created -> g
158 getting lfs.bin
156 getting lfs.bin
159 lfs: found f03217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e in the local lfs store
157 lfs: found f03217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e in the local lfs store
160 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
158 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
161 updating the branch cache
159 updating the branch cache
162 (sent 3 HTTP requests and * bytes; received * bytes in responses) (glob)
160 (sent 3 HTTP requests and * bytes; received * bytes in responses) (glob)
163
161
164 $ "$PYTHON" $RUNTESTDIR/killdaemons.py $DAEMON_PIDS
162 $ "$PYTHON" $RUNTESTDIR/killdaemons.py $DAEMON_PIDS
165
163
166 $ cat $TESTTMP/access.log $TESTTMP/errors.log
164 $ cat $TESTTMP/access.log $TESTTMP/errors.log
167 $LOCALIP - - [$LOGDATE$] "POST /missing/objects/batch HTTP/1.1" 404 - (glob)
165 $LOCALIP - - [$LOGDATE$] "POST /missing/objects/batch HTTP/1.1" 404 - (glob)
168 $LOCALIP - - [$LOGDATE$] "GET /subdir/mount/point?cmd=capabilities HTTP/1.1" 200 - (glob)
166 $LOCALIP - - [$LOGDATE$] "GET /subdir/mount/point?cmd=capabilities HTTP/1.1" 200 - (glob)
169 $LOCALIP - - [$LOGDATE$] "GET /subdir/mount/point?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
167 $LOCALIP - - [$LOGDATE$] "GET /subdir/mount/point?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
170 $LOCALIP - - [$LOGDATE$] "GET /subdir/mount/point?cmd=getbundle HTTP/1.1" 200 - x-hgarg-1:bookmarks=1&bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%252C03%250Acheckheads%253Drelated%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Aphases%253Dheads%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps%250Arev-branch-cache%250Astream%253Dv2&cg=1&common=0000000000000000000000000000000000000000&heads=525251863cad618e55d483555f3d00a2ca99597e&listkeys=bookmarks&phases=1 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
168 $LOCALIP - - [$LOGDATE$] "GET /subdir/mount/point?cmd=getbundle HTTP/1.1" 200 - x-hgarg-1:bookmarks=1&bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%252C03%250Acheckheads%253Drelated%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Aphases%253Dheads%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps%250Astream%253Dv2&cg=1&common=0000000000000000000000000000000000000000&heads=525251863cad618e55d483555f3d00a2ca99597e&listkeys=bookmarks&phases=1 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
171 $LOCALIP - - [$LOGDATE$] "POST /subdir/mount/point/.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
169 $LOCALIP - - [$LOGDATE$] "POST /subdir/mount/point/.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
172 $LOCALIP - - [$LOGDATE$] "GET /subdir/mount/point/.hg/lfs/objects/f03217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e HTTP/1.1" 200 - (glob)
170 $LOCALIP - - [$LOGDATE$] "GET /subdir/mount/point/.hg/lfs/objects/f03217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e HTTP/1.1" 200 - (glob)
173
171
174 Blobs that already exist in the usercache are linked into the repo store, even
172 Blobs that already exist in the usercache are linked into the repo store, even
175 though the client doesn't send the blob.
173 though the client doesn't send the blob.
176
174
177 $ hg init server2
175 $ hg init server2
178 $ hg --config "lfs.usercache=$TESTTMP/servercache" -R server2 serve -d \
176 $ hg --config "lfs.usercache=$TESTTMP/servercache" -R server2 serve -d \
179 > -p $HGPORT --pid-file=hg.pid \
177 > -p $HGPORT --pid-file=hg.pid \
180 > -A $TESTTMP/access.log -E $TESTTMP/errors.log
178 > -A $TESTTMP/access.log -E $TESTTMP/errors.log
181 $ cat hg.pid >> $DAEMON_PIDS
179 $ cat hg.pid >> $DAEMON_PIDS
182
180
183 $ hg --config "lfs.usercache=$TESTTMP/servercache" -R cloned2 --debug \
181 $ hg --config "lfs.usercache=$TESTTMP/servercache" -R cloned2 --debug \
184 > push http://localhost:$HGPORT | grep '^[{} ]'
182 > push http://localhost:$HGPORT | grep '^[{} ]'
185 {
183 {
186 "objects": [
184 "objects": [
187 {
185 {
188 "oid": "f03217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e"
186 "oid": "f03217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e"
189 "size": 20
187 "size": 20
190 }
188 }
191 ]
189 ]
192 "transfer": "basic"
190 "transfer": "basic"
193 }
191 }
194 $ find server2/.hg/store/lfs/objects | sort
192 $ find server2/.hg/store/lfs/objects | sort
195 server2/.hg/store/lfs/objects
193 server2/.hg/store/lfs/objects
196 server2/.hg/store/lfs/objects/f0
194 server2/.hg/store/lfs/objects/f0
197 server2/.hg/store/lfs/objects/f0/3217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e
195 server2/.hg/store/lfs/objects/f0/3217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e
198 $ "$PYTHON" $RUNTESTDIR/killdaemons.py $DAEMON_PIDS
196 $ "$PYTHON" $RUNTESTDIR/killdaemons.py $DAEMON_PIDS
199 $ cat $TESTTMP/errors.log
197 $ cat $TESTTMP/errors.log
200
198
201 $ cat >> $TESTTMP/lfsstoreerror.py <<EOF
199 $ cat >> $TESTTMP/lfsstoreerror.py <<EOF
202 > import errno
200 > import errno
203 > from hgext.lfs import blobstore
201 > from hgext.lfs import blobstore
204 >
202 >
205 > _numverifies = 0
203 > _numverifies = 0
206 > _readerr = True
204 > _readerr = True
207 >
205 >
208 > def reposetup(ui, repo):
206 > def reposetup(ui, repo):
209 > # Nothing to do with a remote repo
207 > # Nothing to do with a remote repo
210 > if not repo.local():
208 > if not repo.local():
211 > return
209 > return
212 >
210 >
213 > store = repo.svfs.lfslocalblobstore
211 > store = repo.svfs.lfslocalblobstore
214 > class badstore(store.__class__):
212 > class badstore(store.__class__):
215 > def download(self, oid, src, contentlength):
213 > def download(self, oid, src, contentlength):
216 > '''Called in the server to handle reading from the client in a
214 > '''Called in the server to handle reading from the client in a
217 > PUT request.'''
215 > PUT request.'''
218 > origread = src.read
216 > origread = src.read
219 > def _badread(nbytes):
217 > def _badread(nbytes):
220 > # Simulate bad data/checksum failure from the client
218 > # Simulate bad data/checksum failure from the client
221 > return b'0' * len(origread(nbytes))
219 > return b'0' * len(origread(nbytes))
222 > src.read = _badread
220 > src.read = _badread
223 > super(badstore, self).download(oid, src, contentlength)
221 > super(badstore, self).download(oid, src, contentlength)
224 >
222 >
225 > def _read(self, vfs, oid, verify):
223 > def _read(self, vfs, oid, verify):
226 > '''Called in the server to read data for a GET request, and then
224 > '''Called in the server to read data for a GET request, and then
227 > calls self._verify() on it before returning.'''
225 > calls self._verify() on it before returning.'''
228 > global _readerr
226 > global _readerr
229 > # One time simulation of a read error
227 > # One time simulation of a read error
230 > if _readerr:
228 > if _readerr:
231 > _readerr = False
229 > _readerr = False
232 > raise IOError(errno.EIO, r'%s: I/O error' % oid.decode("utf-8"))
230 > raise IOError(errno.EIO, r'%s: I/O error' % oid.decode("utf-8"))
233 > # Simulate corrupt content on client download
231 > # Simulate corrupt content on client download
234 > blobstore._verify(oid, b'dummy content')
232 > blobstore._verify(oid, b'dummy content')
235 >
233 >
236 > def verify(self, oid):
234 > def verify(self, oid):
237 > '''Called in the server to populate the Batch API response,
235 > '''Called in the server to populate the Batch API response,
238 > letting the client re-upload if the file is corrupt.'''
236 > letting the client re-upload if the file is corrupt.'''
239 > # Fail verify in Batch API for one clone command and one push
237 > # Fail verify in Batch API for one clone command and one push
240 > # command with an IOError. Then let it through to access other
238 > # command with an IOError. Then let it through to access other
241 > # functions. Checksum failure is tested elsewhere.
239 > # functions. Checksum failure is tested elsewhere.
242 > global _numverifies
240 > global _numverifies
243 > _numverifies += 1
241 > _numverifies += 1
244 > if _numverifies <= 2:
242 > if _numverifies <= 2:
245 > raise IOError(errno.EIO, r'%s: I/O error' % oid.decode("utf-8"))
243 > raise IOError(errno.EIO, r'%s: I/O error' % oid.decode("utf-8"))
246 > return super(badstore, self).verify(oid)
244 > return super(badstore, self).verify(oid)
247 >
245 >
248 > store.__class__ = badstore
246 > store.__class__ = badstore
249 > EOF
247 > EOF
250
248
251 $ rm -rf `hg config lfs.usercache`
249 $ rm -rf `hg config lfs.usercache`
252 $ rm -f $TESTTMP/access.log $TESTTMP/errors.log
250 $ rm -f $TESTTMP/access.log $TESTTMP/errors.log
253 $ hg --config "lfs.usercache=$TESTTMP/servercache" \
251 $ hg --config "lfs.usercache=$TESTTMP/servercache" \
254 > --config extensions.lfsstoreerror=$TESTTMP/lfsstoreerror.py \
252 > --config extensions.lfsstoreerror=$TESTTMP/lfsstoreerror.py \
255 > -R server serve -d \
253 > -R server serve -d \
256 > -p $HGPORT1 --pid-file=hg.pid -A $TESTTMP/access.log -E $TESTTMP/errors.log
254 > -p $HGPORT1 --pid-file=hg.pid -A $TESTTMP/access.log -E $TESTTMP/errors.log
257 $ cat hg.pid >> $DAEMON_PIDS
255 $ cat hg.pid >> $DAEMON_PIDS
258
256
259 Test an I/O error in localstore.verify() (Batch API) with GET
257 Test an I/O error in localstore.verify() (Batch API) with GET
260
258
261 $ hg clone http://localhost:$HGPORT1 httpclone2
259 $ hg clone http://localhost:$HGPORT1 httpclone2
262 (remote is using large file support (lfs); lfs will be enabled for this repository)
260 (remote is using large file support (lfs); lfs will be enabled for this repository)
263 requesting all changes
261 requesting all changes
264 adding changesets
262 adding changesets
265 adding manifests
263 adding manifests
266 adding file changes
264 adding file changes
267 added 1 changesets with 1 changes to 1 files
265 added 1 changesets with 1 changes to 1 files
268 new changesets 525251863cad
266 new changesets 525251863cad
269 updating to branch default
267 updating to branch default
270 abort: LFS server error for "lfs.bin": Internal server error
268 abort: LFS server error for "lfs.bin": Internal server error
271 [50]
269 [50]
272
270
273 Test an I/O error in localstore.verify() (Batch API) with PUT
271 Test an I/O error in localstore.verify() (Batch API) with PUT
274
272
275 $ echo foo > client/lfs.bin
273 $ echo foo > client/lfs.bin
276 $ hg -R client ci -m 'mod lfs'
274 $ hg -R client ci -m 'mod lfs'
277 $ hg -R client push http://localhost:$HGPORT1
275 $ hg -R client push http://localhost:$HGPORT1
278 pushing to http://localhost:$HGPORT1/
276 pushing to http://localhost:$HGPORT1/
279 searching for changes
277 searching for changes
280 abort: LFS server error for "unknown": Internal server error
278 abort: LFS server error for "unknown": Internal server error
281 [50]
279 [50]
282 TODO: figure out how to associate the file name in the error above
280 TODO: figure out how to associate the file name in the error above
283
281
284 Test a bad checksum sent by the client in the transfer API
282 Test a bad checksum sent by the client in the transfer API
285
283
286 $ hg -R client push http://localhost:$HGPORT1
284 $ hg -R client push http://localhost:$HGPORT1
287 pushing to http://localhost:$HGPORT1/
285 pushing to http://localhost:$HGPORT1/
288 searching for changes
286 searching for changes
289 abort: LFS HTTP error: HTTP Error 422: corrupt blob (oid=b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c, action=upload)
287 abort: LFS HTTP error: HTTP Error 422: corrupt blob (oid=b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c, action=upload)
290 [50]
288 [50]
291
289
292 $ echo 'test lfs file' > server/lfs3.bin
290 $ echo 'test lfs file' > server/lfs3.bin
293 $ hg --config experimental.lfs.disableusercache=True \
291 $ hg --config experimental.lfs.disableusercache=True \
294 > -R server ci -Aqm 'another lfs file'
292 > -R server ci -Aqm 'another lfs file'
295 $ hg -R client pull -q http://localhost:$HGPORT1
293 $ hg -R client pull -q http://localhost:$HGPORT1
296
294
297 Test an I/O error during the processing of the GET request
295 Test an I/O error during the processing of the GET request
298
296
299 $ hg --config lfs.url=http://localhost:$HGPORT1/.git/info/lfs \
297 $ hg --config lfs.url=http://localhost:$HGPORT1/.git/info/lfs \
300 > -R client update -r tip
298 > -R client update -r tip
301 abort: LFS HTTP error: HTTP Error 500: Internal Server Error (oid=276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d, action=download)
299 abort: LFS HTTP error: HTTP Error 500: Internal Server Error (oid=276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d, action=download)
302 [50]
300 [50]
303
301
304 Test a checksum failure during the processing of the GET request
302 Test a checksum failure during the processing of the GET request
305
303
306 $ hg --config lfs.url=http://localhost:$HGPORT1/.git/info/lfs \
304 $ hg --config lfs.url=http://localhost:$HGPORT1/.git/info/lfs \
307 > -R client update -r tip
305 > -R client update -r tip
308 abort: LFS HTTP error: HTTP Error 422: corrupt blob (oid=276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d, action=download)
306 abort: LFS HTTP error: HTTP Error 422: corrupt blob (oid=276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d, action=download)
309 [50]
307 [50]
310
308
311 $ "$PYTHON" $RUNTESTDIR/killdaemons.py $DAEMON_PIDS
309 $ "$PYTHON" $RUNTESTDIR/killdaemons.py $DAEMON_PIDS
312
310
313 $ cat $TESTTMP/access.log
311 $ cat $TESTTMP/access.log
314 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
312 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
315 $LOCALIP - - [$LOGDATE$] "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
313 $LOCALIP - - [$LOGDATE$] "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
316 $LOCALIP - - [$LOGDATE$] "GET /?cmd=getbundle HTTP/1.1" 200 - x-hgarg-1:bookmarks=1&bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%252C03%250Acheckheads%253Drelated%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Aphases%253Dheads%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps%250Arev-branch-cache%250Astream%253Dv2&cg=1&common=0000000000000000000000000000000000000000&heads=525251863cad618e55d483555f3d00a2ca99597e&listkeys=bookmarks&phases=1 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
314 $LOCALIP - - [$LOGDATE$] "GET /?cmd=getbundle HTTP/1.1" 200 - x-hgarg-1:bookmarks=1&bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%252C03%250Acheckheads%253Drelated%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Aphases%253Dheads%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps%250Astream%253Dv2&cg=1&common=0000000000000000000000000000000000000000&heads=525251863cad618e55d483555f3d00a2ca99597e&listkeys=bookmarks&phases=1 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
317 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
315 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
318 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
316 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
319 $LOCALIP - - [$LOGDATE$] "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D392c05922088bacf8e68a6939b480017afbf245d x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
317 $LOCALIP - - [$LOGDATE$] "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D392c05922088bacf8e68a6939b480017afbf245d x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
320 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
318 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
321 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
319 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
322 $LOCALIP - - [$LOGDATE$] "GET /?cmd=branchmap HTTP/1.1" 200 - x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
320 $LOCALIP - - [$LOGDATE$] "GET /?cmd=branchmap HTTP/1.1" 200 - x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
323 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
321 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
324 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
322 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
325 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
323 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
326 $LOCALIP - - [$LOGDATE$] "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D392c05922088bacf8e68a6939b480017afbf245d x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
324 $LOCALIP - - [$LOGDATE$] "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D392c05922088bacf8e68a6939b480017afbf245d x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
327 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
325 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
328 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
326 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
329 $LOCALIP - - [$LOGDATE$] "GET /?cmd=branchmap HTTP/1.1" 200 - x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
327 $LOCALIP - - [$LOGDATE$] "GET /?cmd=branchmap HTTP/1.1" 200 - x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
330 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
328 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
331 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
329 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
332 $LOCALIP - - [$LOGDATE$] "PUT /.hg/lfs/objects/b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c HTTP/1.1" 422 - (glob)
330 $LOCALIP - - [$LOGDATE$] "PUT /.hg/lfs/objects/b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c HTTP/1.1" 422 - (glob)
333 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
331 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
334 $LOCALIP - - [$LOGDATE$] "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D392c05922088bacf8e68a6939b480017afbf245d x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
332 $LOCALIP - - [$LOGDATE$] "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D392c05922088bacf8e68a6939b480017afbf245d x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
335 $LOCALIP - - [$LOGDATE$] "GET /?cmd=getbundle HTTP/1.1" 200 - x-hgarg-1:bookmarks=1&bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%252C03%250Acheckheads%253Drelated%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Aphases%253Dheads%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps%250Arev-branch-cache%250Astream%253Dv2&cg=1&common=525251863cad618e55d483555f3d00a2ca99597e&heads=506bf3d83f78c54b89e81c6411adee19fdf02156+525251863cad618e55d483555f3d00a2ca99597e&listkeys=bookmarks&phases=1 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
333 $LOCALIP - - [$LOGDATE$] "GET /?cmd=getbundle HTTP/1.1" 200 - x-hgarg-1:bookmarks=1&bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%252C03%250Acheckheads%253Drelated%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Aphases%253Dheads%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps%250Astream%253Dv2&cg=1&common=525251863cad618e55d483555f3d00a2ca99597e&heads=506bf3d83f78c54b89e81c6411adee19fdf02156+525251863cad618e55d483555f3d00a2ca99597e&listkeys=bookmarks&phases=1 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
336 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
334 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
337 $LOCALIP - - [$LOGDATE$] "GET /.hg/lfs/objects/276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d HTTP/1.1" 500 - (glob)
335 $LOCALIP - - [$LOGDATE$] "GET /.hg/lfs/objects/276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d HTTP/1.1" 500 - (glob)
338 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
336 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
339 $LOCALIP - - [$LOGDATE$] "GET /.hg/lfs/objects/276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d HTTP/1.1" 422 - (glob)
337 $LOCALIP - - [$LOGDATE$] "GET /.hg/lfs/objects/276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d HTTP/1.1" 422 - (glob)
340
338
341 $ grep -v ' File "' $TESTTMP/errors.log
339 $ grep -v ' File "' $TESTTMP/errors.log
342 $LOCALIP - - [$ERRDATE$] HG error: Exception happened while processing request '/.git/info/lfs/objects/batch': (glob)
340 $LOCALIP - - [$ERRDATE$] HG error: Exception happened while processing request '/.git/info/lfs/objects/batch': (glob)
343 $LOCALIP - - [$ERRDATE$] HG error: Traceback (most recent call last): (glob)
341 $LOCALIP - - [$ERRDATE$] HG error: Traceback (most recent call last): (glob)
344 $LOCALIP - - [$ERRDATE$] HG error: verifies = store.verify(oid) (glob)
342 $LOCALIP - - [$ERRDATE$] HG error: verifies = store.verify(oid) (glob)
345 $LOCALIP - - [$ERRDATE$] HG error: raise IOError(errno.EIO, r'%s: I/O error' % oid.decode("utf-8")) (glob)
343 $LOCALIP - - [$ERRDATE$] HG error: raise IOError(errno.EIO, r'%s: I/O error' % oid.decode("utf-8")) (glob)
346 $LOCALIP - - [$ERRDATE$] HG error: *Error: [Errno *] f03217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e: I/O error (glob)
344 $LOCALIP - - [$ERRDATE$] HG error: *Error: [Errno *] f03217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e: I/O error (glob)
347 $LOCALIP - - [$ERRDATE$] HG error: (glob)
345 $LOCALIP - - [$ERRDATE$] HG error: (glob)
348 $LOCALIP - - [$ERRDATE$] HG error: Exception happened while processing request '/.git/info/lfs/objects/batch': (glob)
346 $LOCALIP - - [$ERRDATE$] HG error: Exception happened while processing request '/.git/info/lfs/objects/batch': (glob)
349 $LOCALIP - - [$ERRDATE$] HG error: Traceback (most recent call last): (glob)
347 $LOCALIP - - [$ERRDATE$] HG error: Traceback (most recent call last): (glob)
350 $LOCALIP - - [$ERRDATE$] HG error: verifies = store.verify(oid) (glob)
348 $LOCALIP - - [$ERRDATE$] HG error: verifies = store.verify(oid) (glob)
351 $LOCALIP - - [$ERRDATE$] HG error: raise IOError(errno.EIO, r'%s: I/O error' % oid.decode("utf-8")) (glob)
349 $LOCALIP - - [$ERRDATE$] HG error: raise IOError(errno.EIO, r'%s: I/O error' % oid.decode("utf-8")) (glob)
352 $LOCALIP - - [$ERRDATE$] HG error: *Error: [Errno *] b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c: I/O error (glob)
350 $LOCALIP - - [$ERRDATE$] HG error: *Error: [Errno *] b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c: I/O error (glob)
353 $LOCALIP - - [$ERRDATE$] HG error: (glob)
351 $LOCALIP - - [$ERRDATE$] HG error: (glob)
354 $LOCALIP - - [$ERRDATE$] HG error: Exception happened while processing request '/.hg/lfs/objects/b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c': (glob)
352 $LOCALIP - - [$ERRDATE$] HG error: Exception happened while processing request '/.hg/lfs/objects/b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c': (glob)
355 $LOCALIP - - [$ERRDATE$] HG error: Traceback (most recent call last): (glob)
353 $LOCALIP - - [$ERRDATE$] HG error: Traceback (most recent call last): (glob)
356 $LOCALIP - - [$ERRDATE$] HG error: localstore.download(oid, req.bodyfh, req.headers[b'Content-Length'])
354 $LOCALIP - - [$ERRDATE$] HG error: localstore.download(oid, req.bodyfh, req.headers[b'Content-Length'])
357 $LOCALIP - - [$ERRDATE$] HG error: super(badstore, self).download(oid, src, contentlength)
355 $LOCALIP - - [$ERRDATE$] HG error: super(badstore, self).download(oid, src, contentlength)
358 $LOCALIP - - [$ERRDATE$] HG error: raise LfsCorruptionError( (glob) (py38 !)
356 $LOCALIP - - [$ERRDATE$] HG error: raise LfsCorruptionError( (glob) (py38 !)
359 $LOCALIP - - [$ERRDATE$] HG error: _(b'corrupt remote lfs object: %s') % oid (glob) (no-py38 !)
357 $LOCALIP - - [$ERRDATE$] HG error: _(b'corrupt remote lfs object: %s') % oid (glob) (no-py38 !)
360 $LOCALIP - - [$ERRDATE$] HG error: LfsCorruptionError: corrupt remote lfs object: b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c (no-py3 !)
358 $LOCALIP - - [$ERRDATE$] HG error: LfsCorruptionError: corrupt remote lfs object: b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c (no-py3 !)
361 $LOCALIP - - [$ERRDATE$] HG error: hgext.lfs.blobstore.LfsCorruptionError: corrupt remote lfs object: b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c (py3 !)
359 $LOCALIP - - [$ERRDATE$] HG error: hgext.lfs.blobstore.LfsCorruptionError: corrupt remote lfs object: b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c (py3 !)
362 $LOCALIP - - [$ERRDATE$] HG error: (glob)
360 $LOCALIP - - [$ERRDATE$] HG error: (glob)
363 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/.hg/lfs/objects/276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d': (glob)
361 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/.hg/lfs/objects/276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d': (glob)
364 Traceback (most recent call last):
362 Traceback (most recent call last):
365 self.do_write()
363 self.do_write()
366 self.do_hgweb()
364 self.do_hgweb()
367 for chunk in self.server.application(env, self._start_response):
365 for chunk in self.server.application(env, self._start_response):
368 for r in self._runwsgi(req, res, repo):
366 for r in self._runwsgi(req, res, repo):
369 handled = wireprotoserver.handlewsgirequest( (py38 !)
367 handled = wireprotoserver.handlewsgirequest( (py38 !)
370 return _processbasictransfer( (py38 !)
368 return _processbasictransfer( (py38 !)
371 rctx, req, res, self.check_perm (no-py38 !)
369 rctx, req, res, self.check_perm (no-py38 !)
372 return func(*(args + a), **kw) (no-py3 !)
370 return func(*(args + a), **kw) (no-py3 !)
373 rctx.repo, req, res, lambda perm: checkperm(rctx, req, perm) (no-py38 !)
371 rctx.repo, req, res, lambda perm: checkperm(rctx, req, perm) (no-py38 !)
374 res.setbodybytes(localstore.read(oid))
372 res.setbodybytes(localstore.read(oid))
375 blob = self._read(self.vfs, oid, verify)
373 blob = self._read(self.vfs, oid, verify)
376 raise IOError(errno.EIO, r'%s: I/O error' % oid.decode("utf-8"))
374 raise IOError(errno.EIO, r'%s: I/O error' % oid.decode("utf-8"))
377 *Error: [Errno *] 276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d: I/O error (glob)
375 *Error: [Errno *] 276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d: I/O error (glob)
378
376
379 $LOCALIP - - [$ERRDATE$] HG error: Exception happened while processing request '/.hg/lfs/objects/276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d': (glob)
377 $LOCALIP - - [$ERRDATE$] HG error: Exception happened while processing request '/.hg/lfs/objects/276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d': (glob)
380 $LOCALIP - - [$ERRDATE$] HG error: Traceback (most recent call last): (glob)
378 $LOCALIP - - [$ERRDATE$] HG error: Traceback (most recent call last): (glob)
381 $LOCALIP - - [$ERRDATE$] HG error: res.setbodybytes(localstore.read(oid)) (glob)
379 $LOCALIP - - [$ERRDATE$] HG error: res.setbodybytes(localstore.read(oid)) (glob)
382 $LOCALIP - - [$ERRDATE$] HG error: blob = self._read(self.vfs, oid, verify) (glob)
380 $LOCALIP - - [$ERRDATE$] HG error: blob = self._read(self.vfs, oid, verify) (glob)
383 $LOCALIP - - [$ERRDATE$] HG error: blobstore._verify(oid, b'dummy content') (glob)
381 $LOCALIP - - [$ERRDATE$] HG error: blobstore._verify(oid, b'dummy content') (glob)
384 $LOCALIP - - [$ERRDATE$] HG error: raise LfsCorruptionError( (glob) (py38 !)
382 $LOCALIP - - [$ERRDATE$] HG error: raise LfsCorruptionError( (glob) (py38 !)
385 $LOCALIP - - [$ERRDATE$] HG error: hint=_(b'run hg verify'), (glob) (no-py38 !)
383 $LOCALIP - - [$ERRDATE$] HG error: hint=_(b'run hg verify'), (glob) (no-py38 !)
386 $LOCALIP - - [$ERRDATE$] HG error: LfsCorruptionError: detected corrupt lfs object: 276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d (no-py3 !)
384 $LOCALIP - - [$ERRDATE$] HG error: LfsCorruptionError: detected corrupt lfs object: 276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d (no-py3 !)
387 $LOCALIP - - [$ERRDATE$] HG error: hgext.lfs.blobstore.LfsCorruptionError: detected corrupt lfs object: 276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d (py3 !)
385 $LOCALIP - - [$ERRDATE$] HG error: hgext.lfs.blobstore.LfsCorruptionError: detected corrupt lfs object: 276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d (py3 !)
388 $LOCALIP - - [$ERRDATE$] HG error: (glob)
386 $LOCALIP - - [$ERRDATE$] HG error: (glob)
389
387
390 Basic Authorization headers are returned by the Batch API, and sent back with
388 Basic Authorization headers are returned by the Batch API, and sent back with
391 the GET/PUT request.
389 the GET/PUT request.
392
390
393 $ rm -f $TESTTMP/access.log $TESTTMP/errors.log
391 $ rm -f $TESTTMP/access.log $TESTTMP/errors.log
394
392
395 $ cat >> $HGRCPATH << EOF
393 $ cat >> $HGRCPATH << EOF
396 > [experimental]
394 > [experimental]
397 > lfs.disableusercache = True
395 > lfs.disableusercache = True
398 > [auth]
396 > [auth]
399 > l.schemes=http
397 > l.schemes=http
400 > l.prefix=lo
398 > l.prefix=lo
401 > l.username=user
399 > l.username=user
402 > l.password=pass
400 > l.password=pass
403 > EOF
401 > EOF
404
402
405 $ hg --config extensions.x=$TESTDIR/httpserverauth.py \
403 $ hg --config extensions.x=$TESTDIR/httpserverauth.py \
406 > -R server serve -d -p $HGPORT1 --pid-file=hg.pid \
404 > -R server serve -d -p $HGPORT1 --pid-file=hg.pid \
407 > -A $TESTTMP/access.log -E $TESTTMP/errors.log
405 > -A $TESTTMP/access.log -E $TESTTMP/errors.log
408 $ mv hg.pid $DAEMON_PIDS
406 $ mv hg.pid $DAEMON_PIDS
409
407
410 $ hg clone --debug http://localhost:$HGPORT1 auth_clone | egrep '^[{}]| '
408 $ hg clone --debug http://localhost:$HGPORT1 auth_clone | egrep '^[{}]| '
411 {
409 {
412 "objects": [
410 "objects": [
413 {
411 {
414 "actions": {
412 "actions": {
415 "download": {
413 "download": {
416 "expires_at": "$ISO_8601_DATE_TIME$"
414 "expires_at": "$ISO_8601_DATE_TIME$"
417 "header": {
415 "header": {
418 "Accept": "application/vnd.git-lfs"
416 "Accept": "application/vnd.git-lfs"
419 "Authorization": "Basic dXNlcjpwYXNz"
417 "Authorization": "Basic dXNlcjpwYXNz"
420 }
418 }
421 "href": "http://localhost:$HGPORT1/.hg/lfs/objects/276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d"
419 "href": "http://localhost:$HGPORT1/.hg/lfs/objects/276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d"
422 }
420 }
423 }
421 }
424 "oid": "276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d"
422 "oid": "276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d"
425 "size": 14
423 "size": 14
426 }
424 }
427 ]
425 ]
428 "transfer": "basic"
426 "transfer": "basic"
429 }
427 }
430
428
431 $ echo 'another blob' > auth_clone/lfs.blob
429 $ echo 'another blob' > auth_clone/lfs.blob
432 $ hg -R auth_clone ci -Aqm 'add blob'
430 $ hg -R auth_clone ci -Aqm 'add blob'
433
431
434 $ cat > use_digests.py << EOF
432 $ cat > use_digests.py << EOF
435 > from mercurial import (
433 > from mercurial import (
436 > exthelper,
434 > exthelper,
437 > url,
435 > url,
438 > )
436 > )
439 >
437 >
440 > eh = exthelper.exthelper()
438 > eh = exthelper.exthelper()
441 > uisetup = eh.finaluisetup
439 > uisetup = eh.finaluisetup
442 >
440 >
443 > @eh.wrapfunction(url, 'opener')
441 > @eh.wrapfunction(url, 'opener')
444 > def urlopener(orig, *args, **kwargs):
442 > def urlopener(orig, *args, **kwargs):
445 > opener = orig(*args, **kwargs)
443 > opener = orig(*args, **kwargs)
446 > opener.addheaders.append((r'X-HgTest-AuthType', r'Digest'))
444 > opener.addheaders.append((r'X-HgTest-AuthType', r'Digest'))
447 > return opener
445 > return opener
448 > EOF
446 > EOF
449
447
450 Test that Digest Auth fails gracefully before testing the successful Basic Auth
448 Test that Digest Auth fails gracefully before testing the successful Basic Auth
451
449
452 $ hg -R auth_clone push --config extensions.x=use_digests.py
450 $ hg -R auth_clone push --config extensions.x=use_digests.py
453 pushing to http://localhost:$HGPORT1/
451 pushing to http://localhost:$HGPORT1/
454 searching for changes
452 searching for changes
455 abort: LFS HTTP error: HTTP Error 401: the server must support Basic Authentication
453 abort: LFS HTTP error: HTTP Error 401: the server must support Basic Authentication
456 (api=http://localhost:$HGPORT1/.git/info/lfs/objects/batch, action=upload)
454 (api=http://localhost:$HGPORT1/.git/info/lfs/objects/batch, action=upload)
457 [50]
455 [50]
458
456
459 $ hg -R auth_clone --debug push | egrep '^[{}]| '
457 $ hg -R auth_clone --debug push | egrep '^[{}]| '
460 {
458 {
461 "objects": [
459 "objects": [
462 {
460 {
463 "actions": {
461 "actions": {
464 "upload": {
462 "upload": {
465 "expires_at": "$ISO_8601_DATE_TIME$"
463 "expires_at": "$ISO_8601_DATE_TIME$"
466 "header": {
464 "header": {
467 "Accept": "application/vnd.git-lfs"
465 "Accept": "application/vnd.git-lfs"
468 "Authorization": "Basic dXNlcjpwYXNz"
466 "Authorization": "Basic dXNlcjpwYXNz"
469 }
467 }
470 "href": "http://localhost:$HGPORT1/.hg/lfs/objects/df14287d8d75f076a6459e7a3703ca583ca9fb3f4918caed10c77ac8622d49b3"
468 "href": "http://localhost:$HGPORT1/.hg/lfs/objects/df14287d8d75f076a6459e7a3703ca583ca9fb3f4918caed10c77ac8622d49b3"
471 }
469 }
472 }
470 }
473 "oid": "df14287d8d75f076a6459e7a3703ca583ca9fb3f4918caed10c77ac8622d49b3"
471 "oid": "df14287d8d75f076a6459e7a3703ca583ca9fb3f4918caed10c77ac8622d49b3"
474 "size": 13
472 "size": 13
475 }
473 }
476 ]
474 ]
477 "transfer": "basic"
475 "transfer": "basic"
478 }
476 }
479
477
480 $ "$PYTHON" $RUNTESTDIR/killdaemons.py $DAEMON_PIDS
478 $ "$PYTHON" $RUNTESTDIR/killdaemons.py $DAEMON_PIDS
481
479
482 $ cat $TESTTMP/access.log $TESTTMP/errors.log
480 $ cat $TESTTMP/access.log $TESTTMP/errors.log
483 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 401 - (glob)
481 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 401 - (glob)
484 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
482 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
485 $LOCALIP - - [$LOGDATE$] "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
483 $LOCALIP - - [$LOGDATE$] "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
486 $LOCALIP - - [$LOGDATE$] "GET /?cmd=getbundle HTTP/1.1" 200 - x-hgarg-1:bookmarks=1&bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%252C03%250Acheckheads%253Drelated%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Aphases%253Dheads%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps%250Arev-branch-cache%250Astream%253Dv2&cg=1&common=0000000000000000000000000000000000000000&heads=506bf3d83f78c54b89e81c6411adee19fdf02156+525251863cad618e55d483555f3d00a2ca99597e&listkeys=bookmarks&phases=1 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
484 $LOCALIP - - [$LOGDATE$] "GET /?cmd=getbundle HTTP/1.1" 200 - x-hgarg-1:bookmarks=1&bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%252C03%250Acheckheads%253Drelated%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Aphases%253Dheads%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps%250Astream%253Dv2&cg=1&common=0000000000000000000000000000000000000000&heads=506bf3d83f78c54b89e81c6411adee19fdf02156+525251863cad618e55d483555f3d00a2ca99597e&listkeys=bookmarks&phases=1 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
487 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 401 - (glob)
485 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 401 - (glob)
488 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
486 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
489 $LOCALIP - - [$LOGDATE$] "GET /.hg/lfs/objects/276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d HTTP/1.1" 200 - (glob)
487 $LOCALIP - - [$LOGDATE$] "GET /.hg/lfs/objects/276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d HTTP/1.1" 200 - (glob)
490 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 401 - x-hgtest-authtype:Digest (glob)
488 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 401 - x-hgtest-authtype:Digest (glob)
491 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 200 - x-hgtest-authtype:Digest (glob)
489 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 200 - x-hgtest-authtype:Digest (glob)
492 $LOCALIP - - [$LOGDATE$] "GET /?cmd=batch HTTP/1.1" 401 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D525251863cad618e55d483555f3d00a2ca99597e+4d9397055dc0c205f3132f331f36353ab1a525a3 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest (glob)
490 $LOCALIP - - [$LOGDATE$] "GET /?cmd=batch HTTP/1.1" 401 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D525251863cad618e55d483555f3d00a2ca99597e+4d9397055dc0c205f3132f331f36353ab1a525a3 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest (glob)
493 $LOCALIP - - [$LOGDATE$] "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D525251863cad618e55d483555f3d00a2ca99597e+4d9397055dc0c205f3132f331f36353ab1a525a3 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest (glob)
491 $LOCALIP - - [$LOGDATE$] "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D525251863cad618e55d483555f3d00a2ca99597e+4d9397055dc0c205f3132f331f36353ab1a525a3 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest (glob)
494 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest (glob)
492 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest (glob)
495 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest (glob)
493 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest (glob)
496 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest (glob)
494 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest (glob)
497 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest (glob)
495 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest (glob)
498 $LOCALIP - - [$LOGDATE$] "GET /?cmd=branchmap HTTP/1.1" 401 - x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest (glob)
496 $LOCALIP - - [$LOGDATE$] "GET /?cmd=branchmap HTTP/1.1" 401 - x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest (glob)
499 $LOCALIP - - [$LOGDATE$] "GET /?cmd=branchmap HTTP/1.1" 200 - x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest (glob)
497 $LOCALIP - - [$LOGDATE$] "GET /?cmd=branchmap HTTP/1.1" 200 - x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest (glob)
500 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest (glob)
498 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest (glob)
501 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest (glob)
499 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest (glob)
502 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 401 - x-hgtest-authtype:Digest (glob)
500 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 401 - x-hgtest-authtype:Digest (glob)
503 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 401 - (glob)
501 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 401 - (glob)
504 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
502 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
505 $LOCALIP - - [$LOGDATE$] "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D525251863cad618e55d483555f3d00a2ca99597e+4d9397055dc0c205f3132f331f36353ab1a525a3 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
503 $LOCALIP - - [$LOGDATE$] "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D525251863cad618e55d483555f3d00a2ca99597e+4d9397055dc0c205f3132f331f36353ab1a525a3 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
506 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
504 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
507 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
505 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
508 $LOCALIP - - [$LOGDATE$] "GET /?cmd=branchmap HTTP/1.1" 200 - x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
506 $LOCALIP - - [$LOGDATE$] "GET /?cmd=branchmap HTTP/1.1" 200 - x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
509 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
507 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
510 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 401 - (glob)
508 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 401 - (glob)
511 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
509 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
512 $LOCALIP - - [$LOGDATE$] "PUT /.hg/lfs/objects/df14287d8d75f076a6459e7a3703ca583ca9fb3f4918caed10c77ac8622d49b3 HTTP/1.1" 201 - (glob)
510 $LOCALIP - - [$LOGDATE$] "PUT /.hg/lfs/objects/df14287d8d75f076a6459e7a3703ca583ca9fb3f4918caed10c77ac8622d49b3 HTTP/1.1" 201 - (glob)
513 $LOCALIP - - [$LOGDATE$] "POST /?cmd=unbundle HTTP/1.1" 200 - x-hgarg-1:heads=666f726365 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
511 $LOCALIP - - [$LOGDATE$] "POST /?cmd=unbundle HTTP/1.1" 200 - x-hgarg-1:heads=666f726365 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
514 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
512 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
General Comments 0
You need to be logged in to leave comments. Login now