##// END OF EJS Templates
bundle2: fix an off-by-one in debug message of number of parts...
Martin von Zweigbergk -
r43201:181ee211 default
parent child Browse files
Show More
@@ -1,2333 +1,2333 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 . import (
159 from . import (
160 bookmarks,
160 bookmarks,
161 changegroup,
161 changegroup,
162 encoding,
162 encoding,
163 error,
163 error,
164 node as nodemod,
164 node as nodemod,
165 obsolete,
165 obsolete,
166 phases,
166 phases,
167 pushkey,
167 pushkey,
168 pycompat,
168 pycompat,
169 streamclone,
169 streamclone,
170 tags,
170 tags,
171 url,
171 url,
172 util,
172 util,
173 )
173 )
174 from .utils import (
174 from .utils import (
175 stringutil,
175 stringutil,
176 )
176 )
177
177
178 urlerr = util.urlerr
178 urlerr = util.urlerr
179 urlreq = util.urlreq
179 urlreq = util.urlreq
180
180
181 _pack = struct.pack
181 _pack = struct.pack
182 _unpack = struct.unpack
182 _unpack = struct.unpack
183
183
184 _fstreamparamsize = '>i'
184 _fstreamparamsize = '>i'
185 _fpartheadersize = '>i'
185 _fpartheadersize = '>i'
186 _fparttypesize = '>B'
186 _fparttypesize = '>B'
187 _fpartid = '>I'
187 _fpartid = '>I'
188 _fpayloadsize = '>i'
188 _fpayloadsize = '>i'
189 _fpartparamcount = '>BB'
189 _fpartparamcount = '>BB'
190
190
191 preferedchunksize = 32768
191 preferedchunksize = 32768
192
192
193 _parttypeforbidden = re.compile('[^a-zA-Z0-9_:-]')
193 _parttypeforbidden = re.compile('[^a-zA-Z0-9_:-]')
194
194
195 def outdebug(ui, message):
195 def outdebug(ui, message):
196 """debug regarding output stream (bundling)"""
196 """debug regarding output stream (bundling)"""
197 if ui.configbool('devel', 'bundle2.debug'):
197 if ui.configbool('devel', 'bundle2.debug'):
198 ui.debug('bundle2-output: %s\n' % message)
198 ui.debug('bundle2-output: %s\n' % message)
199
199
200 def indebug(ui, message):
200 def indebug(ui, message):
201 """debug on input stream (unbundling)"""
201 """debug on input stream (unbundling)"""
202 if ui.configbool('devel', 'bundle2.debug'):
202 if ui.configbool('devel', 'bundle2.debug'):
203 ui.debug('bundle2-input: %s\n' % message)
203 ui.debug('bundle2-input: %s\n' % message)
204
204
205 def validateparttype(parttype):
205 def validateparttype(parttype):
206 """raise ValueError if a parttype contains invalid character"""
206 """raise ValueError if a parttype contains invalid character"""
207 if _parttypeforbidden.search(parttype):
207 if _parttypeforbidden.search(parttype):
208 raise ValueError(parttype)
208 raise ValueError(parttype)
209
209
210 def _makefpartparamsizes(nbparams):
210 def _makefpartparamsizes(nbparams):
211 """return a struct format to read part parameter sizes
211 """return a struct format to read part parameter sizes
212
212
213 The number parameters is variable so we need to build that format
213 The number parameters is variable so we need to build that format
214 dynamically.
214 dynamically.
215 """
215 """
216 return '>'+('BB'*nbparams)
216 return '>'+('BB'*nbparams)
217
217
218 parthandlermapping = {}
218 parthandlermapping = {}
219
219
220 def parthandler(parttype, params=()):
220 def parthandler(parttype, params=()):
221 """decorator that register a function as a bundle2 part handler
221 """decorator that register a function as a bundle2 part handler
222
222
223 eg::
223 eg::
224
224
225 @parthandler('myparttype', ('mandatory', 'param', 'handled'))
225 @parthandler('myparttype', ('mandatory', 'param', 'handled'))
226 def myparttypehandler(...):
226 def myparttypehandler(...):
227 '''process a part of type "my part".'''
227 '''process a part of type "my part".'''
228 ...
228 ...
229 """
229 """
230 validateparttype(parttype)
230 validateparttype(parttype)
231 def _decorator(func):
231 def _decorator(func):
232 lparttype = parttype.lower() # enforce lower case matching.
232 lparttype = parttype.lower() # enforce lower case matching.
233 assert lparttype not in parthandlermapping
233 assert lparttype not in parthandlermapping
234 parthandlermapping[lparttype] = func
234 parthandlermapping[lparttype] = func
235 func.params = frozenset(params)
235 func.params = frozenset(params)
236 return func
236 return func
237 return _decorator
237 return _decorator
238
238
239 class unbundlerecords(object):
239 class unbundlerecords(object):
240 """keep record of what happens during and unbundle
240 """keep record of what happens during and unbundle
241
241
242 New records are added using `records.add('cat', obj)`. Where 'cat' is a
242 New records are added using `records.add('cat', obj)`. Where 'cat' is a
243 category of record and obj is an arbitrary object.
243 category of record and obj is an arbitrary object.
244
244
245 `records['cat']` will return all entries of this category 'cat'.
245 `records['cat']` will return all entries of this category 'cat'.
246
246
247 Iterating on the object itself will yield `('category', obj)` tuples
247 Iterating on the object itself will yield `('category', obj)` tuples
248 for all entries.
248 for all entries.
249
249
250 All iterations happens in chronological order.
250 All iterations happens in chronological order.
251 """
251 """
252
252
253 def __init__(self):
253 def __init__(self):
254 self._categories = {}
254 self._categories = {}
255 self._sequences = []
255 self._sequences = []
256 self._replies = {}
256 self._replies = {}
257
257
258 def add(self, category, entry, inreplyto=None):
258 def add(self, category, entry, inreplyto=None):
259 """add a new record of a given category.
259 """add a new record of a given category.
260
260
261 The entry can then be retrieved in the list returned by
261 The entry can then be retrieved in the list returned by
262 self['category']."""
262 self['category']."""
263 self._categories.setdefault(category, []).append(entry)
263 self._categories.setdefault(category, []).append(entry)
264 self._sequences.append((category, entry))
264 self._sequences.append((category, entry))
265 if inreplyto is not None:
265 if inreplyto is not None:
266 self.getreplies(inreplyto).add(category, entry)
266 self.getreplies(inreplyto).add(category, entry)
267
267
268 def getreplies(self, partid):
268 def getreplies(self, partid):
269 """get the records that are replies to a specific part"""
269 """get the records that are replies to a specific part"""
270 return self._replies.setdefault(partid, unbundlerecords())
270 return self._replies.setdefault(partid, unbundlerecords())
271
271
272 def __getitem__(self, cat):
272 def __getitem__(self, cat):
273 return tuple(self._categories.get(cat, ()))
273 return tuple(self._categories.get(cat, ()))
274
274
275 def __iter__(self):
275 def __iter__(self):
276 return iter(self._sequences)
276 return iter(self._sequences)
277
277
278 def __len__(self):
278 def __len__(self):
279 return len(self._sequences)
279 return len(self._sequences)
280
280
281 def __nonzero__(self):
281 def __nonzero__(self):
282 return bool(self._sequences)
282 return bool(self._sequences)
283
283
284 __bool__ = __nonzero__
284 __bool__ = __nonzero__
285
285
286 class bundleoperation(object):
286 class bundleoperation(object):
287 """an object that represents a single bundling process
287 """an object that represents a single bundling process
288
288
289 Its purpose is to carry unbundle-related objects and states.
289 Its purpose is to carry unbundle-related objects and states.
290
290
291 A new object should be created at the beginning of each bundle processing.
291 A new object should be created at the beginning of each bundle processing.
292 The object is to be returned by the processing function.
292 The object is to be returned by the processing function.
293
293
294 The object has very little content now it will ultimately contain:
294 The object has very little content now it will ultimately contain:
295 * an access to the repo the bundle is applied to,
295 * an access to the repo the bundle is applied to,
296 * a ui object,
296 * a ui object,
297 * a way to retrieve a transaction to add changes to the repo,
297 * a way to retrieve a transaction to add changes to the repo,
298 * a way to record the result of processing each part,
298 * a way to record the result of processing each part,
299 * a way to construct a bundle response when applicable.
299 * a way to construct a bundle response when applicable.
300 """
300 """
301
301
302 def __init__(self, repo, transactiongetter, captureoutput=True, source=''):
302 def __init__(self, repo, transactiongetter, captureoutput=True, source=''):
303 self.repo = repo
303 self.repo = repo
304 self.ui = repo.ui
304 self.ui = repo.ui
305 self.records = unbundlerecords()
305 self.records = unbundlerecords()
306 self.reply = None
306 self.reply = None
307 self.captureoutput = captureoutput
307 self.captureoutput = captureoutput
308 self.hookargs = {}
308 self.hookargs = {}
309 self._gettransaction = transactiongetter
309 self._gettransaction = transactiongetter
310 # carries value that can modify part behavior
310 # carries value that can modify part behavior
311 self.modes = {}
311 self.modes = {}
312 self.source = source
312 self.source = source
313
313
314 def gettransaction(self):
314 def gettransaction(self):
315 transaction = self._gettransaction()
315 transaction = self._gettransaction()
316
316
317 if self.hookargs:
317 if self.hookargs:
318 # the ones added to the transaction supercede those added
318 # the ones added to the transaction supercede those added
319 # to the operation.
319 # to the operation.
320 self.hookargs.update(transaction.hookargs)
320 self.hookargs.update(transaction.hookargs)
321 transaction.hookargs = self.hookargs
321 transaction.hookargs = self.hookargs
322
322
323 # mark the hookargs as flushed. further attempts to add to
323 # mark the hookargs as flushed. further attempts to add to
324 # hookargs will result in an abort.
324 # hookargs will result in an abort.
325 self.hookargs = None
325 self.hookargs = None
326
326
327 return transaction
327 return transaction
328
328
329 def addhookargs(self, hookargs):
329 def addhookargs(self, hookargs):
330 if self.hookargs is None:
330 if self.hookargs is None:
331 raise error.ProgrammingError('attempted to add hookargs to '
331 raise error.ProgrammingError('attempted to add hookargs to '
332 'operation after transaction started')
332 'operation after transaction started')
333 self.hookargs.update(hookargs)
333 self.hookargs.update(hookargs)
334
334
335 class TransactionUnavailable(RuntimeError):
335 class TransactionUnavailable(RuntimeError):
336 pass
336 pass
337
337
338 def _notransaction():
338 def _notransaction():
339 """default method to get a transaction while processing a bundle
339 """default method to get a transaction while processing a bundle
340
340
341 Raise an exception to highlight the fact that no transaction was expected
341 Raise an exception to highlight the fact that no transaction was expected
342 to be created"""
342 to be created"""
343 raise TransactionUnavailable()
343 raise TransactionUnavailable()
344
344
345 def applybundle(repo, unbundler, tr, source, url=None, **kwargs):
345 def applybundle(repo, unbundler, tr, source, url=None, **kwargs):
346 # transform me into unbundler.apply() as soon as the freeze is lifted
346 # transform me into unbundler.apply() as soon as the freeze is lifted
347 if isinstance(unbundler, unbundle20):
347 if isinstance(unbundler, unbundle20):
348 tr.hookargs['bundle2'] = '1'
348 tr.hookargs['bundle2'] = '1'
349 if source is not None and 'source' not in tr.hookargs:
349 if source is not None and 'source' not in tr.hookargs:
350 tr.hookargs['source'] = source
350 tr.hookargs['source'] = source
351 if url is not None and 'url' not in tr.hookargs:
351 if url is not None and 'url' not in tr.hookargs:
352 tr.hookargs['url'] = url
352 tr.hookargs['url'] = url
353 return processbundle(repo, unbundler, lambda: tr, source=source)
353 return processbundle(repo, unbundler, lambda: tr, source=source)
354 else:
354 else:
355 # the transactiongetter won't be used, but we might as well set it
355 # the transactiongetter won't be used, but we might as well set it
356 op = bundleoperation(repo, lambda: tr, source=source)
356 op = bundleoperation(repo, lambda: tr, source=source)
357 _processchangegroup(op, unbundler, tr, source, url, **kwargs)
357 _processchangegroup(op, unbundler, tr, source, url, **kwargs)
358 return op
358 return op
359
359
360 class partiterator(object):
360 class partiterator(object):
361 def __init__(self, repo, op, unbundler):
361 def __init__(self, repo, op, unbundler):
362 self.repo = repo
362 self.repo = repo
363 self.op = op
363 self.op = op
364 self.unbundler = unbundler
364 self.unbundler = unbundler
365 self.iterator = None
365 self.iterator = None
366 self.count = 0
366 self.count = 0
367 self.current = None
367 self.current = None
368
368
369 def __enter__(self):
369 def __enter__(self):
370 def func():
370 def func():
371 itr = enumerate(self.unbundler.iterparts())
371 itr = enumerate(self.unbundler.iterparts(), 1)
372 for count, p in itr:
372 for count, p in itr:
373 self.count = count
373 self.count = count
374 self.current = p
374 self.current = p
375 yield p
375 yield p
376 p.consume()
376 p.consume()
377 self.current = None
377 self.current = None
378 self.iterator = func()
378 self.iterator = func()
379 return self.iterator
379 return self.iterator
380
380
381 def __exit__(self, type, exc, tb):
381 def __exit__(self, type, exc, tb):
382 if not self.iterator:
382 if not self.iterator:
383 return
383 return
384
384
385 # Only gracefully abort in a normal exception situation. User aborts
385 # Only gracefully abort in a normal exception situation. User aborts
386 # like Ctrl+C throw a KeyboardInterrupt which is not a base Exception,
386 # like Ctrl+C throw a KeyboardInterrupt which is not a base Exception,
387 # and should not gracefully cleanup.
387 # and should not gracefully cleanup.
388 if isinstance(exc, Exception):
388 if isinstance(exc, Exception):
389 # Any exceptions seeking to the end of the bundle at this point are
389 # Any exceptions seeking to the end of the bundle at this point are
390 # almost certainly related to the underlying stream being bad.
390 # almost certainly related to the underlying stream being bad.
391 # And, chances are that the exception we're handling is related to
391 # And, chances are that the exception we're handling is related to
392 # getting in that bad state. So, we swallow the seeking error and
392 # getting in that bad state. So, we swallow the seeking error and
393 # re-raise the original error.
393 # re-raise the original error.
394 seekerror = False
394 seekerror = False
395 try:
395 try:
396 if self.current:
396 if self.current:
397 # consume the part content to not corrupt the stream.
397 # consume the part content to not corrupt the stream.
398 self.current.consume()
398 self.current.consume()
399
399
400 for part in self.iterator:
400 for part in self.iterator:
401 # consume the bundle content
401 # consume the bundle content
402 part.consume()
402 part.consume()
403 except Exception:
403 except Exception:
404 seekerror = True
404 seekerror = True
405
405
406 # Small hack to let caller code distinguish exceptions from bundle2
406 # Small hack to let caller code distinguish exceptions from bundle2
407 # processing from processing the old format. This is mostly needed
407 # processing from processing the old format. This is mostly needed
408 # to handle different return codes to unbundle according to the type
408 # to handle different return codes to unbundle according to the type
409 # of bundle. We should probably clean up or drop this return code
409 # of bundle. We should probably clean up or drop this return code
410 # craziness in a future version.
410 # craziness in a future version.
411 exc.duringunbundle2 = True
411 exc.duringunbundle2 = True
412 salvaged = []
412 salvaged = []
413 replycaps = None
413 replycaps = None
414 if self.op.reply is not None:
414 if self.op.reply is not None:
415 salvaged = self.op.reply.salvageoutput()
415 salvaged = self.op.reply.salvageoutput()
416 replycaps = self.op.reply.capabilities
416 replycaps = self.op.reply.capabilities
417 exc._replycaps = replycaps
417 exc._replycaps = replycaps
418 exc._bundle2salvagedoutput = salvaged
418 exc._bundle2salvagedoutput = salvaged
419
419
420 # Re-raising from a variable loses the original stack. So only use
420 # Re-raising from a variable loses the original stack. So only use
421 # that form if we need to.
421 # that form if we need to.
422 if seekerror:
422 if seekerror:
423 raise exc
423 raise exc
424
424
425 self.repo.ui.debug('bundle2-input-bundle: %i parts total\n' %
425 self.repo.ui.debug('bundle2-input-bundle: %i parts total\n' %
426 self.count)
426 self.count)
427
427
428 def processbundle(repo, unbundler, transactiongetter=None, op=None, source=''):
428 def processbundle(repo, unbundler, transactiongetter=None, op=None, source=''):
429 """This function process a bundle, apply effect to/from a repo
429 """This function process a bundle, apply effect to/from a repo
430
430
431 It iterates over each part then searches for and uses the proper handling
431 It iterates over each part then searches for and uses the proper handling
432 code to process the part. Parts are processed in order.
432 code to process the part. Parts are processed in order.
433
433
434 Unknown Mandatory part will abort the process.
434 Unknown Mandatory part will abort the process.
435
435
436 It is temporarily possible to provide a prebuilt bundleoperation to the
436 It is temporarily possible to provide a prebuilt bundleoperation to the
437 function. This is used to ensure output is properly propagated in case of
437 function. This is used to ensure output is properly propagated in case of
438 an error during the unbundling. This output capturing part will likely be
438 an error during the unbundling. This output capturing part will likely be
439 reworked and this ability will probably go away in the process.
439 reworked and this ability will probably go away in the process.
440 """
440 """
441 if op is None:
441 if op is None:
442 if transactiongetter is None:
442 if transactiongetter is None:
443 transactiongetter = _notransaction
443 transactiongetter = _notransaction
444 op = bundleoperation(repo, transactiongetter, source=source)
444 op = bundleoperation(repo, transactiongetter, source=source)
445 # todo:
445 # todo:
446 # - replace this is a init function soon.
446 # - replace this is a init function soon.
447 # - exception catching
447 # - exception catching
448 unbundler.params
448 unbundler.params
449 if repo.ui.debugflag:
449 if repo.ui.debugflag:
450 msg = ['bundle2-input-bundle:']
450 msg = ['bundle2-input-bundle:']
451 if unbundler.params:
451 if unbundler.params:
452 msg.append(' %i params' % len(unbundler.params))
452 msg.append(' %i params' % len(unbundler.params))
453 if op._gettransaction is None or op._gettransaction is _notransaction:
453 if op._gettransaction is None or op._gettransaction is _notransaction:
454 msg.append(' no-transaction')
454 msg.append(' no-transaction')
455 else:
455 else:
456 msg.append(' with-transaction')
456 msg.append(' with-transaction')
457 msg.append('\n')
457 msg.append('\n')
458 repo.ui.debug(''.join(msg))
458 repo.ui.debug(''.join(msg))
459
459
460 processparts(repo, op, unbundler)
460 processparts(repo, op, unbundler)
461
461
462 return op
462 return op
463
463
464 def processparts(repo, op, unbundler):
464 def processparts(repo, op, unbundler):
465 with partiterator(repo, op, unbundler) as parts:
465 with partiterator(repo, op, unbundler) as parts:
466 for part in parts:
466 for part in parts:
467 _processpart(op, part)
467 _processpart(op, part)
468
468
469 def _processchangegroup(op, cg, tr, source, url, **kwargs):
469 def _processchangegroup(op, cg, tr, source, url, **kwargs):
470 ret = cg.apply(op.repo, tr, source, url, **kwargs)
470 ret = cg.apply(op.repo, tr, source, url, **kwargs)
471 op.records.add('changegroup', {
471 op.records.add('changegroup', {
472 'return': ret,
472 'return': ret,
473 })
473 })
474 return ret
474 return ret
475
475
476 def _gethandler(op, part):
476 def _gethandler(op, part):
477 status = 'unknown' # used by debug output
477 status = 'unknown' # used by debug output
478 try:
478 try:
479 handler = parthandlermapping.get(part.type)
479 handler = parthandlermapping.get(part.type)
480 if handler is None:
480 if handler is None:
481 status = 'unsupported-type'
481 status = 'unsupported-type'
482 raise error.BundleUnknownFeatureError(parttype=part.type)
482 raise error.BundleUnknownFeatureError(parttype=part.type)
483 indebug(op.ui, 'found a handler for part %s' % part.type)
483 indebug(op.ui, 'found a handler for part %s' % part.type)
484 unknownparams = part.mandatorykeys - handler.params
484 unknownparams = part.mandatorykeys - handler.params
485 if unknownparams:
485 if unknownparams:
486 unknownparams = list(unknownparams)
486 unknownparams = list(unknownparams)
487 unknownparams.sort()
487 unknownparams.sort()
488 status = 'unsupported-params (%s)' % ', '.join(unknownparams)
488 status = 'unsupported-params (%s)' % ', '.join(unknownparams)
489 raise error.BundleUnknownFeatureError(parttype=part.type,
489 raise error.BundleUnknownFeatureError(parttype=part.type,
490 params=unknownparams)
490 params=unknownparams)
491 status = 'supported'
491 status = 'supported'
492 except error.BundleUnknownFeatureError as exc:
492 except error.BundleUnknownFeatureError as exc:
493 if part.mandatory: # mandatory parts
493 if part.mandatory: # mandatory parts
494 raise
494 raise
495 indebug(op.ui, 'ignoring unsupported advisory part %s' % exc)
495 indebug(op.ui, 'ignoring unsupported advisory part %s' % exc)
496 return # skip to part processing
496 return # skip to part processing
497 finally:
497 finally:
498 if op.ui.debugflag:
498 if op.ui.debugflag:
499 msg = ['bundle2-input-part: "%s"' % part.type]
499 msg = ['bundle2-input-part: "%s"' % part.type]
500 if not part.mandatory:
500 if not part.mandatory:
501 msg.append(' (advisory)')
501 msg.append(' (advisory)')
502 nbmp = len(part.mandatorykeys)
502 nbmp = len(part.mandatorykeys)
503 nbap = len(part.params) - nbmp
503 nbap = len(part.params) - nbmp
504 if nbmp or nbap:
504 if nbmp or nbap:
505 msg.append(' (params:')
505 msg.append(' (params:')
506 if nbmp:
506 if nbmp:
507 msg.append(' %i mandatory' % nbmp)
507 msg.append(' %i mandatory' % nbmp)
508 if nbap:
508 if nbap:
509 msg.append(' %i advisory' % nbmp)
509 msg.append(' %i advisory' % nbmp)
510 msg.append(')')
510 msg.append(')')
511 msg.append(' %s\n' % status)
511 msg.append(' %s\n' % status)
512 op.ui.debug(''.join(msg))
512 op.ui.debug(''.join(msg))
513
513
514 return handler
514 return handler
515
515
516 def _processpart(op, part):
516 def _processpart(op, part):
517 """process a single part from a bundle
517 """process a single part from a bundle
518
518
519 The part is guaranteed to have been fully consumed when the function exits
519 The part is guaranteed to have been fully consumed when the function exits
520 (even if an exception is raised)."""
520 (even if an exception is raised)."""
521 handler = _gethandler(op, part)
521 handler = _gethandler(op, part)
522 if handler is None:
522 if handler is None:
523 return
523 return
524
524
525 # handler is called outside the above try block so that we don't
525 # handler is called outside the above try block so that we don't
526 # risk catching KeyErrors from anything other than the
526 # risk catching KeyErrors from anything other than the
527 # parthandlermapping lookup (any KeyError raised by handler()
527 # parthandlermapping lookup (any KeyError raised by handler()
528 # itself represents a defect of a different variety).
528 # itself represents a defect of a different variety).
529 output = None
529 output = None
530 if op.captureoutput and op.reply is not None:
530 if op.captureoutput and op.reply is not None:
531 op.ui.pushbuffer(error=True, subproc=True)
531 op.ui.pushbuffer(error=True, subproc=True)
532 output = ''
532 output = ''
533 try:
533 try:
534 handler(op, part)
534 handler(op, part)
535 finally:
535 finally:
536 if output is not None:
536 if output is not None:
537 output = op.ui.popbuffer()
537 output = op.ui.popbuffer()
538 if output:
538 if output:
539 outpart = op.reply.newpart('output', data=output,
539 outpart = op.reply.newpart('output', data=output,
540 mandatory=False)
540 mandatory=False)
541 outpart.addparam(
541 outpart.addparam(
542 'in-reply-to', pycompat.bytestr(part.id), mandatory=False)
542 'in-reply-to', pycompat.bytestr(part.id), mandatory=False)
543
543
544 def decodecaps(blob):
544 def decodecaps(blob):
545 """decode a bundle2 caps bytes blob into a dictionary
545 """decode a bundle2 caps bytes blob into a dictionary
546
546
547 The blob is a list of capabilities (one per line)
547 The blob is a list of capabilities (one per line)
548 Capabilities may have values using a line of the form::
548 Capabilities may have values using a line of the form::
549
549
550 capability=value1,value2,value3
550 capability=value1,value2,value3
551
551
552 The values are always a list."""
552 The values are always a list."""
553 caps = {}
553 caps = {}
554 for line in blob.splitlines():
554 for line in blob.splitlines():
555 if not line:
555 if not line:
556 continue
556 continue
557 if '=' not in line:
557 if '=' not in line:
558 key, vals = line, ()
558 key, vals = line, ()
559 else:
559 else:
560 key, vals = line.split('=', 1)
560 key, vals = line.split('=', 1)
561 vals = vals.split(',')
561 vals = vals.split(',')
562 key = urlreq.unquote(key)
562 key = urlreq.unquote(key)
563 vals = [urlreq.unquote(v) for v in vals]
563 vals = [urlreq.unquote(v) for v in vals]
564 caps[key] = vals
564 caps[key] = vals
565 return caps
565 return caps
566
566
567 def encodecaps(caps):
567 def encodecaps(caps):
568 """encode a bundle2 caps dictionary into a bytes blob"""
568 """encode a bundle2 caps dictionary into a bytes blob"""
569 chunks = []
569 chunks = []
570 for ca in sorted(caps):
570 for ca in sorted(caps):
571 vals = caps[ca]
571 vals = caps[ca]
572 ca = urlreq.quote(ca)
572 ca = urlreq.quote(ca)
573 vals = [urlreq.quote(v) for v in vals]
573 vals = [urlreq.quote(v) for v in vals]
574 if vals:
574 if vals:
575 ca = "%s=%s" % (ca, ','.join(vals))
575 ca = "%s=%s" % (ca, ','.join(vals))
576 chunks.append(ca)
576 chunks.append(ca)
577 return '\n'.join(chunks)
577 return '\n'.join(chunks)
578
578
579 bundletypes = {
579 bundletypes = {
580 "": ("", 'UN'), # only when using unbundle on ssh and old http servers
580 "": ("", 'UN'), # only when using unbundle on ssh and old http servers
581 # since the unification ssh accepts a header but there
581 # since the unification ssh accepts a header but there
582 # is no capability signaling it.
582 # is no capability signaling it.
583 "HG20": (), # special-cased below
583 "HG20": (), # special-cased below
584 "HG10UN": ("HG10UN", 'UN'),
584 "HG10UN": ("HG10UN", 'UN'),
585 "HG10BZ": ("HG10", 'BZ'),
585 "HG10BZ": ("HG10", 'BZ'),
586 "HG10GZ": ("HG10GZ", 'GZ'),
586 "HG10GZ": ("HG10GZ", 'GZ'),
587 }
587 }
588
588
589 # hgweb uses this list to communicate its preferred type
589 # hgweb uses this list to communicate its preferred type
590 bundlepriority = ['HG10GZ', 'HG10BZ', 'HG10UN']
590 bundlepriority = ['HG10GZ', 'HG10BZ', 'HG10UN']
591
591
592 class bundle20(object):
592 class bundle20(object):
593 """represent an outgoing bundle2 container
593 """represent an outgoing bundle2 container
594
594
595 Use the `addparam` method to add stream level parameter. and `newpart` to
595 Use the `addparam` method to add stream level parameter. and `newpart` to
596 populate it. Then call `getchunks` to retrieve all the binary chunks of
596 populate it. Then call `getchunks` to retrieve all the binary chunks of
597 data that compose the bundle2 container."""
597 data that compose the bundle2 container."""
598
598
599 _magicstring = 'HG20'
599 _magicstring = 'HG20'
600
600
601 def __init__(self, ui, capabilities=()):
601 def __init__(self, ui, capabilities=()):
602 self.ui = ui
602 self.ui = ui
603 self._params = []
603 self._params = []
604 self._parts = []
604 self._parts = []
605 self.capabilities = dict(capabilities)
605 self.capabilities = dict(capabilities)
606 self._compengine = util.compengines.forbundletype('UN')
606 self._compengine = util.compengines.forbundletype('UN')
607 self._compopts = None
607 self._compopts = None
608 # If compression is being handled by a consumer of the raw
608 # If compression is being handled by a consumer of the raw
609 # data (e.g. the wire protocol), unsetting this flag tells
609 # data (e.g. the wire protocol), unsetting this flag tells
610 # consumers that the bundle is best left uncompressed.
610 # consumers that the bundle is best left uncompressed.
611 self.prefercompressed = True
611 self.prefercompressed = True
612
612
613 def setcompression(self, alg, compopts=None):
613 def setcompression(self, alg, compopts=None):
614 """setup core part compression to <alg>"""
614 """setup core part compression to <alg>"""
615 if alg in (None, 'UN'):
615 if alg in (None, 'UN'):
616 return
616 return
617 assert not any(n.lower() == 'compression' for n, v in self._params)
617 assert not any(n.lower() == 'compression' for n, v in self._params)
618 self.addparam('Compression', alg)
618 self.addparam('Compression', alg)
619 self._compengine = util.compengines.forbundletype(alg)
619 self._compengine = util.compengines.forbundletype(alg)
620 self._compopts = compopts
620 self._compopts = compopts
621
621
622 @property
622 @property
623 def nbparts(self):
623 def nbparts(self):
624 """total number of parts added to the bundler"""
624 """total number of parts added to the bundler"""
625 return len(self._parts)
625 return len(self._parts)
626
626
627 # methods used to defines the bundle2 content
627 # methods used to defines the bundle2 content
628 def addparam(self, name, value=None):
628 def addparam(self, name, value=None):
629 """add a stream level parameter"""
629 """add a stream level parameter"""
630 if not name:
630 if not name:
631 raise error.ProgrammingError(b'empty parameter name')
631 raise error.ProgrammingError(b'empty parameter name')
632 if name[0:1] not in pycompat.bytestr(string.ascii_letters):
632 if name[0:1] not in pycompat.bytestr(string.ascii_letters):
633 raise error.ProgrammingError(b'non letter first character: %s'
633 raise error.ProgrammingError(b'non letter first character: %s'
634 % name)
634 % name)
635 self._params.append((name, value))
635 self._params.append((name, value))
636
636
637 def addpart(self, part):
637 def addpart(self, part):
638 """add a new part to the bundle2 container
638 """add a new part to the bundle2 container
639
639
640 Parts contains the actual applicative payload."""
640 Parts contains the actual applicative payload."""
641 assert part.id is None
641 assert part.id is None
642 part.id = len(self._parts) # very cheap counter
642 part.id = len(self._parts) # very cheap counter
643 self._parts.append(part)
643 self._parts.append(part)
644
644
645 def newpart(self, typeid, *args, **kwargs):
645 def newpart(self, typeid, *args, **kwargs):
646 """create a new part and add it to the containers
646 """create a new part and add it to the containers
647
647
648 As the part is directly added to the containers. For now, this means
648 As the part is directly added to the containers. For now, this means
649 that any failure to properly initialize the part after calling
649 that any failure to properly initialize the part after calling
650 ``newpart`` should result in a failure of the whole bundling process.
650 ``newpart`` should result in a failure of the whole bundling process.
651
651
652 You can still fall back to manually create and add if you need better
652 You can still fall back to manually create and add if you need better
653 control."""
653 control."""
654 part = bundlepart(typeid, *args, **kwargs)
654 part = bundlepart(typeid, *args, **kwargs)
655 self.addpart(part)
655 self.addpart(part)
656 return part
656 return part
657
657
658 # methods used to generate the bundle2 stream
658 # methods used to generate the bundle2 stream
659 def getchunks(self):
659 def getchunks(self):
660 if self.ui.debugflag:
660 if self.ui.debugflag:
661 msg = ['bundle2-output-bundle: "%s",' % self._magicstring]
661 msg = ['bundle2-output-bundle: "%s",' % self._magicstring]
662 if self._params:
662 if self._params:
663 msg.append(' (%i params)' % len(self._params))
663 msg.append(' (%i params)' % len(self._params))
664 msg.append(' %i parts total\n' % len(self._parts))
664 msg.append(' %i parts total\n' % len(self._parts))
665 self.ui.debug(''.join(msg))
665 self.ui.debug(''.join(msg))
666 outdebug(self.ui, 'start emission of %s stream' % self._magicstring)
666 outdebug(self.ui, 'start emission of %s stream' % self._magicstring)
667 yield self._magicstring
667 yield self._magicstring
668 param = self._paramchunk()
668 param = self._paramchunk()
669 outdebug(self.ui, 'bundle parameter: %s' % param)
669 outdebug(self.ui, 'bundle parameter: %s' % param)
670 yield _pack(_fstreamparamsize, len(param))
670 yield _pack(_fstreamparamsize, len(param))
671 if param:
671 if param:
672 yield param
672 yield param
673 for chunk in self._compengine.compressstream(self._getcorechunk(),
673 for chunk in self._compengine.compressstream(self._getcorechunk(),
674 self._compopts):
674 self._compopts):
675 yield chunk
675 yield chunk
676
676
677 def _paramchunk(self):
677 def _paramchunk(self):
678 """return a encoded version of all stream parameters"""
678 """return a encoded version of all stream parameters"""
679 blocks = []
679 blocks = []
680 for par, value in self._params:
680 for par, value in self._params:
681 par = urlreq.quote(par)
681 par = urlreq.quote(par)
682 if value is not None:
682 if value is not None:
683 value = urlreq.quote(value)
683 value = urlreq.quote(value)
684 par = '%s=%s' % (par, value)
684 par = '%s=%s' % (par, value)
685 blocks.append(par)
685 blocks.append(par)
686 return ' '.join(blocks)
686 return ' '.join(blocks)
687
687
688 def _getcorechunk(self):
688 def _getcorechunk(self):
689 """yield chunk for the core part of the bundle
689 """yield chunk for the core part of the bundle
690
690
691 (all but headers and parameters)"""
691 (all but headers and parameters)"""
692 outdebug(self.ui, 'start of parts')
692 outdebug(self.ui, 'start of parts')
693 for part in self._parts:
693 for part in self._parts:
694 outdebug(self.ui, 'bundle part: "%s"' % part.type)
694 outdebug(self.ui, 'bundle part: "%s"' % part.type)
695 for chunk in part.getchunks(ui=self.ui):
695 for chunk in part.getchunks(ui=self.ui):
696 yield chunk
696 yield chunk
697 outdebug(self.ui, 'end of bundle')
697 outdebug(self.ui, 'end of bundle')
698 yield _pack(_fpartheadersize, 0)
698 yield _pack(_fpartheadersize, 0)
699
699
700
700
701 def salvageoutput(self):
701 def salvageoutput(self):
702 """return a list with a copy of all output parts in the bundle
702 """return a list with a copy of all output parts in the bundle
703
703
704 This is meant to be used during error handling to make sure we preserve
704 This is meant to be used during error handling to make sure we preserve
705 server output"""
705 server output"""
706 salvaged = []
706 salvaged = []
707 for part in self._parts:
707 for part in self._parts:
708 if part.type.startswith('output'):
708 if part.type.startswith('output'):
709 salvaged.append(part.copy())
709 salvaged.append(part.copy())
710 return salvaged
710 return salvaged
711
711
712
712
713 class unpackermixin(object):
713 class unpackermixin(object):
714 """A mixin to extract bytes and struct data from a stream"""
714 """A mixin to extract bytes and struct data from a stream"""
715
715
716 def __init__(self, fp):
716 def __init__(self, fp):
717 self._fp = fp
717 self._fp = fp
718
718
719 def _unpack(self, format):
719 def _unpack(self, format):
720 """unpack this struct format from the stream
720 """unpack this struct format from the stream
721
721
722 This method is meant for internal usage by the bundle2 protocol only.
722 This method is meant for internal usage by the bundle2 protocol only.
723 They directly manipulate the low level stream including bundle2 level
723 They directly manipulate the low level stream including bundle2 level
724 instruction.
724 instruction.
725
725
726 Do not use it to implement higher-level logic or methods."""
726 Do not use it to implement higher-level logic or methods."""
727 data = self._readexact(struct.calcsize(format))
727 data = self._readexact(struct.calcsize(format))
728 return _unpack(format, data)
728 return _unpack(format, data)
729
729
730 def _readexact(self, size):
730 def _readexact(self, size):
731 """read exactly <size> bytes from the stream
731 """read exactly <size> bytes from the stream
732
732
733 This method is meant for internal usage by the bundle2 protocol only.
733 This method is meant for internal usage by the bundle2 protocol only.
734 They directly manipulate the low level stream including bundle2 level
734 They directly manipulate the low level stream including bundle2 level
735 instruction.
735 instruction.
736
736
737 Do not use it to implement higher-level logic or methods."""
737 Do not use it to implement higher-level logic or methods."""
738 return changegroup.readexactly(self._fp, size)
738 return changegroup.readexactly(self._fp, size)
739
739
740 def getunbundler(ui, fp, magicstring=None):
740 def getunbundler(ui, fp, magicstring=None):
741 """return a valid unbundler object for a given magicstring"""
741 """return a valid unbundler object for a given magicstring"""
742 if magicstring is None:
742 if magicstring is None:
743 magicstring = changegroup.readexactly(fp, 4)
743 magicstring = changegroup.readexactly(fp, 4)
744 magic, version = magicstring[0:2], magicstring[2:4]
744 magic, version = magicstring[0:2], magicstring[2:4]
745 if magic != 'HG':
745 if magic != 'HG':
746 ui.debug(
746 ui.debug(
747 "error: invalid magic: %r (version %r), should be 'HG'\n"
747 "error: invalid magic: %r (version %r), should be 'HG'\n"
748 % (magic, version))
748 % (magic, version))
749 raise error.Abort(_('not a Mercurial bundle'))
749 raise error.Abort(_('not a Mercurial bundle'))
750 unbundlerclass = formatmap.get(version)
750 unbundlerclass = formatmap.get(version)
751 if unbundlerclass is None:
751 if unbundlerclass is None:
752 raise error.Abort(_('unknown bundle version %s') % version)
752 raise error.Abort(_('unknown bundle version %s') % version)
753 unbundler = unbundlerclass(ui, fp)
753 unbundler = unbundlerclass(ui, fp)
754 indebug(ui, 'start processing of %s stream' % magicstring)
754 indebug(ui, 'start processing of %s stream' % magicstring)
755 return unbundler
755 return unbundler
756
756
757 class unbundle20(unpackermixin):
757 class unbundle20(unpackermixin):
758 """interpret a bundle2 stream
758 """interpret a bundle2 stream
759
759
760 This class is fed with a binary stream and yields parts through its
760 This class is fed with a binary stream and yields parts through its
761 `iterparts` methods."""
761 `iterparts` methods."""
762
762
763 _magicstring = 'HG20'
763 _magicstring = 'HG20'
764
764
765 def __init__(self, ui, fp):
765 def __init__(self, ui, fp):
766 """If header is specified, we do not read it out of the stream."""
766 """If header is specified, we do not read it out of the stream."""
767 self.ui = ui
767 self.ui = ui
768 self._compengine = util.compengines.forbundletype('UN')
768 self._compengine = util.compengines.forbundletype('UN')
769 self._compressed = None
769 self._compressed = None
770 super(unbundle20, self).__init__(fp)
770 super(unbundle20, self).__init__(fp)
771
771
772 @util.propertycache
772 @util.propertycache
773 def params(self):
773 def params(self):
774 """dictionary of stream level parameters"""
774 """dictionary of stream level parameters"""
775 indebug(self.ui, 'reading bundle2 stream parameters')
775 indebug(self.ui, 'reading bundle2 stream parameters')
776 params = {}
776 params = {}
777 paramssize = self._unpack(_fstreamparamsize)[0]
777 paramssize = self._unpack(_fstreamparamsize)[0]
778 if paramssize < 0:
778 if paramssize < 0:
779 raise error.BundleValueError('negative bundle param size: %i'
779 raise error.BundleValueError('negative bundle param size: %i'
780 % paramssize)
780 % paramssize)
781 if paramssize:
781 if paramssize:
782 params = self._readexact(paramssize)
782 params = self._readexact(paramssize)
783 params = self._processallparams(params)
783 params = self._processallparams(params)
784 return params
784 return params
785
785
786 def _processallparams(self, paramsblock):
786 def _processallparams(self, paramsblock):
787 """"""
787 """"""
788 params = util.sortdict()
788 params = util.sortdict()
789 for p in paramsblock.split(' '):
789 for p in paramsblock.split(' '):
790 p = p.split('=', 1)
790 p = p.split('=', 1)
791 p = [urlreq.unquote(i) for i in p]
791 p = [urlreq.unquote(i) for i in p]
792 if len(p) < 2:
792 if len(p) < 2:
793 p.append(None)
793 p.append(None)
794 self._processparam(*p)
794 self._processparam(*p)
795 params[p[0]] = p[1]
795 params[p[0]] = p[1]
796 return params
796 return params
797
797
798
798
799 def _processparam(self, name, value):
799 def _processparam(self, name, value):
800 """process a parameter, applying its effect if needed
800 """process a parameter, applying its effect if needed
801
801
802 Parameter starting with a lower case letter are advisory and will be
802 Parameter starting with a lower case letter are advisory and will be
803 ignored when unknown. Those starting with an upper case letter are
803 ignored when unknown. Those starting with an upper case letter are
804 mandatory and will this function will raise a KeyError when unknown.
804 mandatory and will this function will raise a KeyError when unknown.
805
805
806 Note: no option are currently supported. Any input will be either
806 Note: no option are currently supported. Any input will be either
807 ignored or failing.
807 ignored or failing.
808 """
808 """
809 if not name:
809 if not name:
810 raise ValueError(r'empty parameter name')
810 raise ValueError(r'empty parameter name')
811 if name[0:1] not in pycompat.bytestr(string.ascii_letters):
811 if name[0:1] not in pycompat.bytestr(string.ascii_letters):
812 raise ValueError(r'non letter first character: %s' % name)
812 raise ValueError(r'non letter first character: %s' % name)
813 try:
813 try:
814 handler = b2streamparamsmap[name.lower()]
814 handler = b2streamparamsmap[name.lower()]
815 except KeyError:
815 except KeyError:
816 if name[0:1].islower():
816 if name[0:1].islower():
817 indebug(self.ui, "ignoring unknown parameter %s" % name)
817 indebug(self.ui, "ignoring unknown parameter %s" % name)
818 else:
818 else:
819 raise error.BundleUnknownFeatureError(params=(name,))
819 raise error.BundleUnknownFeatureError(params=(name,))
820 else:
820 else:
821 handler(self, name, value)
821 handler(self, name, value)
822
822
823 def _forwardchunks(self):
823 def _forwardchunks(self):
824 """utility to transfer a bundle2 as binary
824 """utility to transfer a bundle2 as binary
825
825
826 This is made necessary by the fact the 'getbundle' command over 'ssh'
826 This is made necessary by the fact the 'getbundle' command over 'ssh'
827 have no way to know then the reply end, relying on the bundle to be
827 have no way to know then the reply end, relying on the bundle to be
828 interpreted to know its end. This is terrible and we are sorry, but we
828 interpreted to know its end. This is terrible and we are sorry, but we
829 needed to move forward to get general delta enabled.
829 needed to move forward to get general delta enabled.
830 """
830 """
831 yield self._magicstring
831 yield self._magicstring
832 assert 'params' not in vars(self)
832 assert 'params' not in vars(self)
833 paramssize = self._unpack(_fstreamparamsize)[0]
833 paramssize = self._unpack(_fstreamparamsize)[0]
834 if paramssize < 0:
834 if paramssize < 0:
835 raise error.BundleValueError('negative bundle param size: %i'
835 raise error.BundleValueError('negative bundle param size: %i'
836 % paramssize)
836 % paramssize)
837 if paramssize:
837 if paramssize:
838 params = self._readexact(paramssize)
838 params = self._readexact(paramssize)
839 self._processallparams(params)
839 self._processallparams(params)
840 # The payload itself is decompressed below, so drop
840 # The payload itself is decompressed below, so drop
841 # the compression parameter passed down to compensate.
841 # the compression parameter passed down to compensate.
842 outparams = []
842 outparams = []
843 for p in params.split(' '):
843 for p in params.split(' '):
844 k, v = p.split('=', 1)
844 k, v = p.split('=', 1)
845 if k.lower() != 'compression':
845 if k.lower() != 'compression':
846 outparams.append(p)
846 outparams.append(p)
847 outparams = ' '.join(outparams)
847 outparams = ' '.join(outparams)
848 yield _pack(_fstreamparamsize, len(outparams))
848 yield _pack(_fstreamparamsize, len(outparams))
849 yield outparams
849 yield outparams
850 else:
850 else:
851 yield _pack(_fstreamparamsize, paramssize)
851 yield _pack(_fstreamparamsize, paramssize)
852 # From there, payload might need to be decompressed
852 # From there, payload might need to be decompressed
853 self._fp = self._compengine.decompressorreader(self._fp)
853 self._fp = self._compengine.decompressorreader(self._fp)
854 emptycount = 0
854 emptycount = 0
855 while emptycount < 2:
855 while emptycount < 2:
856 # so we can brainlessly loop
856 # so we can brainlessly loop
857 assert _fpartheadersize == _fpayloadsize
857 assert _fpartheadersize == _fpayloadsize
858 size = self._unpack(_fpartheadersize)[0]
858 size = self._unpack(_fpartheadersize)[0]
859 yield _pack(_fpartheadersize, size)
859 yield _pack(_fpartheadersize, size)
860 if size:
860 if size:
861 emptycount = 0
861 emptycount = 0
862 else:
862 else:
863 emptycount += 1
863 emptycount += 1
864 continue
864 continue
865 if size == flaginterrupt:
865 if size == flaginterrupt:
866 continue
866 continue
867 elif size < 0:
867 elif size < 0:
868 raise error.BundleValueError('negative chunk size: %i')
868 raise error.BundleValueError('negative chunk size: %i')
869 yield self._readexact(size)
869 yield self._readexact(size)
870
870
871
871
872 def iterparts(self, seekable=False):
872 def iterparts(self, seekable=False):
873 """yield all parts contained in the stream"""
873 """yield all parts contained in the stream"""
874 cls = seekableunbundlepart if seekable else unbundlepart
874 cls = seekableunbundlepart if seekable else unbundlepart
875 # make sure param have been loaded
875 # make sure param have been loaded
876 self.params
876 self.params
877 # From there, payload need to be decompressed
877 # From there, payload need to be decompressed
878 self._fp = self._compengine.decompressorreader(self._fp)
878 self._fp = self._compengine.decompressorreader(self._fp)
879 indebug(self.ui, 'start extraction of bundle2 parts')
879 indebug(self.ui, 'start extraction of bundle2 parts')
880 headerblock = self._readpartheader()
880 headerblock = self._readpartheader()
881 while headerblock is not None:
881 while headerblock is not None:
882 part = cls(self.ui, headerblock, self._fp)
882 part = cls(self.ui, headerblock, self._fp)
883 yield part
883 yield part
884 # Ensure part is fully consumed so we can start reading the next
884 # Ensure part is fully consumed so we can start reading the next
885 # part.
885 # part.
886 part.consume()
886 part.consume()
887
887
888 headerblock = self._readpartheader()
888 headerblock = self._readpartheader()
889 indebug(self.ui, 'end of bundle2 stream')
889 indebug(self.ui, 'end of bundle2 stream')
890
890
891 def _readpartheader(self):
891 def _readpartheader(self):
892 """reads a part header size and return the bytes blob
892 """reads a part header size and return the bytes blob
893
893
894 returns None if empty"""
894 returns None if empty"""
895 headersize = self._unpack(_fpartheadersize)[0]
895 headersize = self._unpack(_fpartheadersize)[0]
896 if headersize < 0:
896 if headersize < 0:
897 raise error.BundleValueError('negative part header size: %i'
897 raise error.BundleValueError('negative part header size: %i'
898 % headersize)
898 % headersize)
899 indebug(self.ui, 'part header size: %i' % headersize)
899 indebug(self.ui, 'part header size: %i' % headersize)
900 if headersize:
900 if headersize:
901 return self._readexact(headersize)
901 return self._readexact(headersize)
902 return None
902 return None
903
903
904 def compressed(self):
904 def compressed(self):
905 self.params # load params
905 self.params # load params
906 return self._compressed
906 return self._compressed
907
907
908 def close(self):
908 def close(self):
909 """close underlying file"""
909 """close underlying file"""
910 if util.safehasattr(self._fp, 'close'):
910 if util.safehasattr(self._fp, 'close'):
911 return self._fp.close()
911 return self._fp.close()
912
912
913 formatmap = {'20': unbundle20}
913 formatmap = {'20': unbundle20}
914
914
915 b2streamparamsmap = {}
915 b2streamparamsmap = {}
916
916
917 def b2streamparamhandler(name):
917 def b2streamparamhandler(name):
918 """register a handler for a stream level parameter"""
918 """register a handler for a stream level parameter"""
919 def decorator(func):
919 def decorator(func):
920 assert name not in formatmap
920 assert name not in formatmap
921 b2streamparamsmap[name] = func
921 b2streamparamsmap[name] = func
922 return func
922 return func
923 return decorator
923 return decorator
924
924
925 @b2streamparamhandler('compression')
925 @b2streamparamhandler('compression')
926 def processcompression(unbundler, param, value):
926 def processcompression(unbundler, param, value):
927 """read compression parameter and install payload decompression"""
927 """read compression parameter and install payload decompression"""
928 if value not in util.compengines.supportedbundletypes:
928 if value not in util.compengines.supportedbundletypes:
929 raise error.BundleUnknownFeatureError(params=(param,),
929 raise error.BundleUnknownFeatureError(params=(param,),
930 values=(value,))
930 values=(value,))
931 unbundler._compengine = util.compengines.forbundletype(value)
931 unbundler._compengine = util.compengines.forbundletype(value)
932 if value is not None:
932 if value is not None:
933 unbundler._compressed = True
933 unbundler._compressed = True
934
934
935 class bundlepart(object):
935 class bundlepart(object):
936 """A bundle2 part contains application level payload
936 """A bundle2 part contains application level payload
937
937
938 The part `type` is used to route the part to the application level
938 The part `type` is used to route the part to the application level
939 handler.
939 handler.
940
940
941 The part payload is contained in ``part.data``. It could be raw bytes or a
941 The part payload is contained in ``part.data``. It could be raw bytes or a
942 generator of byte chunks.
942 generator of byte chunks.
943
943
944 You can add parameters to the part using the ``addparam`` method.
944 You can add parameters to the part using the ``addparam`` method.
945 Parameters can be either mandatory (default) or advisory. Remote side
945 Parameters can be either mandatory (default) or advisory. Remote side
946 should be able to safely ignore the advisory ones.
946 should be able to safely ignore the advisory ones.
947
947
948 Both data and parameters cannot be modified after the generation has begun.
948 Both data and parameters cannot be modified after the generation has begun.
949 """
949 """
950
950
951 def __init__(self, parttype, mandatoryparams=(), advisoryparams=(),
951 def __init__(self, parttype, mandatoryparams=(), advisoryparams=(),
952 data='', mandatory=True):
952 data='', mandatory=True):
953 validateparttype(parttype)
953 validateparttype(parttype)
954 self.id = None
954 self.id = None
955 self.type = parttype
955 self.type = parttype
956 self._data = data
956 self._data = data
957 self._mandatoryparams = list(mandatoryparams)
957 self._mandatoryparams = list(mandatoryparams)
958 self._advisoryparams = list(advisoryparams)
958 self._advisoryparams = list(advisoryparams)
959 # checking for duplicated entries
959 # checking for duplicated entries
960 self._seenparams = set()
960 self._seenparams = set()
961 for pname, __ in self._mandatoryparams + self._advisoryparams:
961 for pname, __ in self._mandatoryparams + self._advisoryparams:
962 if pname in self._seenparams:
962 if pname in self._seenparams:
963 raise error.ProgrammingError('duplicated params: %s' % pname)
963 raise error.ProgrammingError('duplicated params: %s' % pname)
964 self._seenparams.add(pname)
964 self._seenparams.add(pname)
965 # status of the part's generation:
965 # status of the part's generation:
966 # - None: not started,
966 # - None: not started,
967 # - False: currently generated,
967 # - False: currently generated,
968 # - True: generation done.
968 # - True: generation done.
969 self._generated = None
969 self._generated = None
970 self.mandatory = mandatory
970 self.mandatory = mandatory
971
971
972 def __repr__(self):
972 def __repr__(self):
973 cls = "%s.%s" % (self.__class__.__module__, self.__class__.__name__)
973 cls = "%s.%s" % (self.__class__.__module__, self.__class__.__name__)
974 return ('<%s object at %x; id: %s; type: %s; mandatory: %s>'
974 return ('<%s object at %x; id: %s; type: %s; mandatory: %s>'
975 % (cls, id(self), self.id, self.type, self.mandatory))
975 % (cls, id(self), self.id, self.type, self.mandatory))
976
976
977 def copy(self):
977 def copy(self):
978 """return a copy of the part
978 """return a copy of the part
979
979
980 The new part have the very same content but no partid assigned yet.
980 The new part have the very same content but no partid assigned yet.
981 Parts with generated data cannot be copied."""
981 Parts with generated data cannot be copied."""
982 assert not util.safehasattr(self.data, 'next')
982 assert not util.safehasattr(self.data, 'next')
983 return self.__class__(self.type, self._mandatoryparams,
983 return self.__class__(self.type, self._mandatoryparams,
984 self._advisoryparams, self._data, self.mandatory)
984 self._advisoryparams, self._data, self.mandatory)
985
985
986 # methods used to defines the part content
986 # methods used to defines the part content
987 @property
987 @property
988 def data(self):
988 def data(self):
989 return self._data
989 return self._data
990
990
991 @data.setter
991 @data.setter
992 def data(self, data):
992 def data(self, data):
993 if self._generated is not None:
993 if self._generated is not None:
994 raise error.ReadOnlyPartError('part is being generated')
994 raise error.ReadOnlyPartError('part is being generated')
995 self._data = data
995 self._data = data
996
996
997 @property
997 @property
998 def mandatoryparams(self):
998 def mandatoryparams(self):
999 # make it an immutable tuple to force people through ``addparam``
999 # make it an immutable tuple to force people through ``addparam``
1000 return tuple(self._mandatoryparams)
1000 return tuple(self._mandatoryparams)
1001
1001
1002 @property
1002 @property
1003 def advisoryparams(self):
1003 def advisoryparams(self):
1004 # make it an immutable tuple to force people through ``addparam``
1004 # make it an immutable tuple to force people through ``addparam``
1005 return tuple(self._advisoryparams)
1005 return tuple(self._advisoryparams)
1006
1006
1007 def addparam(self, name, value='', mandatory=True):
1007 def addparam(self, name, value='', mandatory=True):
1008 """add a parameter to the part
1008 """add a parameter to the part
1009
1009
1010 If 'mandatory' is set to True, the remote handler must claim support
1010 If 'mandatory' is set to True, the remote handler must claim support
1011 for this parameter or the unbundling will be aborted.
1011 for this parameter or the unbundling will be aborted.
1012
1012
1013 The 'name' and 'value' cannot exceed 255 bytes each.
1013 The 'name' and 'value' cannot exceed 255 bytes each.
1014 """
1014 """
1015 if self._generated is not None:
1015 if self._generated is not None:
1016 raise error.ReadOnlyPartError('part is being generated')
1016 raise error.ReadOnlyPartError('part is being generated')
1017 if name in self._seenparams:
1017 if name in self._seenparams:
1018 raise ValueError('duplicated params: %s' % name)
1018 raise ValueError('duplicated params: %s' % name)
1019 self._seenparams.add(name)
1019 self._seenparams.add(name)
1020 params = self._advisoryparams
1020 params = self._advisoryparams
1021 if mandatory:
1021 if mandatory:
1022 params = self._mandatoryparams
1022 params = self._mandatoryparams
1023 params.append((name, value))
1023 params.append((name, value))
1024
1024
1025 # methods used to generates the bundle2 stream
1025 # methods used to generates the bundle2 stream
1026 def getchunks(self, ui):
1026 def getchunks(self, ui):
1027 if self._generated is not None:
1027 if self._generated is not None:
1028 raise error.ProgrammingError('part can only be consumed once')
1028 raise error.ProgrammingError('part can only be consumed once')
1029 self._generated = False
1029 self._generated = False
1030
1030
1031 if ui.debugflag:
1031 if ui.debugflag:
1032 msg = ['bundle2-output-part: "%s"' % self.type]
1032 msg = ['bundle2-output-part: "%s"' % self.type]
1033 if not self.mandatory:
1033 if not self.mandatory:
1034 msg.append(' (advisory)')
1034 msg.append(' (advisory)')
1035 nbmp = len(self.mandatoryparams)
1035 nbmp = len(self.mandatoryparams)
1036 nbap = len(self.advisoryparams)
1036 nbap = len(self.advisoryparams)
1037 if nbmp or nbap:
1037 if nbmp or nbap:
1038 msg.append(' (params:')
1038 msg.append(' (params:')
1039 if nbmp:
1039 if nbmp:
1040 msg.append(' %i mandatory' % nbmp)
1040 msg.append(' %i mandatory' % nbmp)
1041 if nbap:
1041 if nbap:
1042 msg.append(' %i advisory' % nbmp)
1042 msg.append(' %i advisory' % nbmp)
1043 msg.append(')')
1043 msg.append(')')
1044 if not self.data:
1044 if not self.data:
1045 msg.append(' empty payload')
1045 msg.append(' empty payload')
1046 elif (util.safehasattr(self.data, 'next')
1046 elif (util.safehasattr(self.data, 'next')
1047 or util.safehasattr(self.data, '__next__')):
1047 or util.safehasattr(self.data, '__next__')):
1048 msg.append(' streamed payload')
1048 msg.append(' streamed payload')
1049 else:
1049 else:
1050 msg.append(' %i bytes payload' % len(self.data))
1050 msg.append(' %i bytes payload' % len(self.data))
1051 msg.append('\n')
1051 msg.append('\n')
1052 ui.debug(''.join(msg))
1052 ui.debug(''.join(msg))
1053
1053
1054 #### header
1054 #### header
1055 if self.mandatory:
1055 if self.mandatory:
1056 parttype = self.type.upper()
1056 parttype = self.type.upper()
1057 else:
1057 else:
1058 parttype = self.type.lower()
1058 parttype = self.type.lower()
1059 outdebug(ui, 'part %s: "%s"' % (pycompat.bytestr(self.id), parttype))
1059 outdebug(ui, 'part %s: "%s"' % (pycompat.bytestr(self.id), parttype))
1060 ## parttype
1060 ## parttype
1061 header = [_pack(_fparttypesize, len(parttype)),
1061 header = [_pack(_fparttypesize, len(parttype)),
1062 parttype, _pack(_fpartid, self.id),
1062 parttype, _pack(_fpartid, self.id),
1063 ]
1063 ]
1064 ## parameters
1064 ## parameters
1065 # count
1065 # count
1066 manpar = self.mandatoryparams
1066 manpar = self.mandatoryparams
1067 advpar = self.advisoryparams
1067 advpar = self.advisoryparams
1068 header.append(_pack(_fpartparamcount, len(manpar), len(advpar)))
1068 header.append(_pack(_fpartparamcount, len(manpar), len(advpar)))
1069 # size
1069 # size
1070 parsizes = []
1070 parsizes = []
1071 for key, value in manpar:
1071 for key, value in manpar:
1072 parsizes.append(len(key))
1072 parsizes.append(len(key))
1073 parsizes.append(len(value))
1073 parsizes.append(len(value))
1074 for key, value in advpar:
1074 for key, value in advpar:
1075 parsizes.append(len(key))
1075 parsizes.append(len(key))
1076 parsizes.append(len(value))
1076 parsizes.append(len(value))
1077 paramsizes = _pack(_makefpartparamsizes(len(parsizes) // 2), *parsizes)
1077 paramsizes = _pack(_makefpartparamsizes(len(parsizes) // 2), *parsizes)
1078 header.append(paramsizes)
1078 header.append(paramsizes)
1079 # key, value
1079 # key, value
1080 for key, value in manpar:
1080 for key, value in manpar:
1081 header.append(key)
1081 header.append(key)
1082 header.append(value)
1082 header.append(value)
1083 for key, value in advpar:
1083 for key, value in advpar:
1084 header.append(key)
1084 header.append(key)
1085 header.append(value)
1085 header.append(value)
1086 ## finalize header
1086 ## finalize header
1087 try:
1087 try:
1088 headerchunk = ''.join(header)
1088 headerchunk = ''.join(header)
1089 except TypeError:
1089 except TypeError:
1090 raise TypeError(r'Found a non-bytes trying to '
1090 raise TypeError(r'Found a non-bytes trying to '
1091 r'build bundle part header: %r' % header)
1091 r'build bundle part header: %r' % header)
1092 outdebug(ui, 'header chunk size: %i' % len(headerchunk))
1092 outdebug(ui, 'header chunk size: %i' % len(headerchunk))
1093 yield _pack(_fpartheadersize, len(headerchunk))
1093 yield _pack(_fpartheadersize, len(headerchunk))
1094 yield headerchunk
1094 yield headerchunk
1095 ## payload
1095 ## payload
1096 try:
1096 try:
1097 for chunk in self._payloadchunks():
1097 for chunk in self._payloadchunks():
1098 outdebug(ui, 'payload chunk size: %i' % len(chunk))
1098 outdebug(ui, 'payload chunk size: %i' % len(chunk))
1099 yield _pack(_fpayloadsize, len(chunk))
1099 yield _pack(_fpayloadsize, len(chunk))
1100 yield chunk
1100 yield chunk
1101 except GeneratorExit:
1101 except GeneratorExit:
1102 # GeneratorExit means that nobody is listening for our
1102 # GeneratorExit means that nobody is listening for our
1103 # results anyway, so just bail quickly rather than trying
1103 # results anyway, so just bail quickly rather than trying
1104 # to produce an error part.
1104 # to produce an error part.
1105 ui.debug('bundle2-generatorexit\n')
1105 ui.debug('bundle2-generatorexit\n')
1106 raise
1106 raise
1107 except BaseException as exc:
1107 except BaseException as exc:
1108 bexc = stringutil.forcebytestr(exc)
1108 bexc = stringutil.forcebytestr(exc)
1109 # backup exception data for later
1109 # backup exception data for later
1110 ui.debug('bundle2-input-stream-interrupt: encoding exception %s'
1110 ui.debug('bundle2-input-stream-interrupt: encoding exception %s'
1111 % bexc)
1111 % bexc)
1112 tb = sys.exc_info()[2]
1112 tb = sys.exc_info()[2]
1113 msg = 'unexpected error: %s' % bexc
1113 msg = 'unexpected error: %s' % bexc
1114 interpart = bundlepart('error:abort', [('message', msg)],
1114 interpart = bundlepart('error:abort', [('message', msg)],
1115 mandatory=False)
1115 mandatory=False)
1116 interpart.id = 0
1116 interpart.id = 0
1117 yield _pack(_fpayloadsize, -1)
1117 yield _pack(_fpayloadsize, -1)
1118 for chunk in interpart.getchunks(ui=ui):
1118 for chunk in interpart.getchunks(ui=ui):
1119 yield chunk
1119 yield chunk
1120 outdebug(ui, 'closing payload chunk')
1120 outdebug(ui, 'closing payload chunk')
1121 # abort current part payload
1121 # abort current part payload
1122 yield _pack(_fpayloadsize, 0)
1122 yield _pack(_fpayloadsize, 0)
1123 pycompat.raisewithtb(exc, tb)
1123 pycompat.raisewithtb(exc, tb)
1124 # end of payload
1124 # end of payload
1125 outdebug(ui, 'closing payload chunk')
1125 outdebug(ui, 'closing payload chunk')
1126 yield _pack(_fpayloadsize, 0)
1126 yield _pack(_fpayloadsize, 0)
1127 self._generated = True
1127 self._generated = True
1128
1128
1129 def _payloadchunks(self):
1129 def _payloadchunks(self):
1130 """yield chunks of a the part payload
1130 """yield chunks of a the part payload
1131
1131
1132 Exists to handle the different methods to provide data to a part."""
1132 Exists to handle the different methods to provide data to a part."""
1133 # we only support fixed size data now.
1133 # we only support fixed size data now.
1134 # This will be improved in the future.
1134 # This will be improved in the future.
1135 if (util.safehasattr(self.data, 'next')
1135 if (util.safehasattr(self.data, 'next')
1136 or util.safehasattr(self.data, '__next__')):
1136 or util.safehasattr(self.data, '__next__')):
1137 buff = util.chunkbuffer(self.data)
1137 buff = util.chunkbuffer(self.data)
1138 chunk = buff.read(preferedchunksize)
1138 chunk = buff.read(preferedchunksize)
1139 while chunk:
1139 while chunk:
1140 yield chunk
1140 yield chunk
1141 chunk = buff.read(preferedchunksize)
1141 chunk = buff.read(preferedchunksize)
1142 elif len(self.data):
1142 elif len(self.data):
1143 yield self.data
1143 yield self.data
1144
1144
1145
1145
1146 flaginterrupt = -1
1146 flaginterrupt = -1
1147
1147
1148 class interrupthandler(unpackermixin):
1148 class interrupthandler(unpackermixin):
1149 """read one part and process it with restricted capability
1149 """read one part and process it with restricted capability
1150
1150
1151 This allows to transmit exception raised on the producer size during part
1151 This allows to transmit exception raised on the producer size during part
1152 iteration while the consumer is reading a part.
1152 iteration while the consumer is reading a part.
1153
1153
1154 Part processed in this manner only have access to a ui object,"""
1154 Part processed in this manner only have access to a ui object,"""
1155
1155
1156 def __init__(self, ui, fp):
1156 def __init__(self, ui, fp):
1157 super(interrupthandler, self).__init__(fp)
1157 super(interrupthandler, self).__init__(fp)
1158 self.ui = ui
1158 self.ui = ui
1159
1159
1160 def _readpartheader(self):
1160 def _readpartheader(self):
1161 """reads a part header size and return the bytes blob
1161 """reads a part header size and return the bytes blob
1162
1162
1163 returns None if empty"""
1163 returns None if empty"""
1164 headersize = self._unpack(_fpartheadersize)[0]
1164 headersize = self._unpack(_fpartheadersize)[0]
1165 if headersize < 0:
1165 if headersize < 0:
1166 raise error.BundleValueError('negative part header size: %i'
1166 raise error.BundleValueError('negative part header size: %i'
1167 % headersize)
1167 % headersize)
1168 indebug(self.ui, 'part header size: %i\n' % headersize)
1168 indebug(self.ui, 'part header size: %i\n' % headersize)
1169 if headersize:
1169 if headersize:
1170 return self._readexact(headersize)
1170 return self._readexact(headersize)
1171 return None
1171 return None
1172
1172
1173 def __call__(self):
1173 def __call__(self):
1174
1174
1175 self.ui.debug('bundle2-input-stream-interrupt:'
1175 self.ui.debug('bundle2-input-stream-interrupt:'
1176 ' opening out of band context\n')
1176 ' opening out of band context\n')
1177 indebug(self.ui, 'bundle2 stream interruption, looking for a part.')
1177 indebug(self.ui, 'bundle2 stream interruption, looking for a part.')
1178 headerblock = self._readpartheader()
1178 headerblock = self._readpartheader()
1179 if headerblock is None:
1179 if headerblock is None:
1180 indebug(self.ui, 'no part found during interruption.')
1180 indebug(self.ui, 'no part found during interruption.')
1181 return
1181 return
1182 part = unbundlepart(self.ui, headerblock, self._fp)
1182 part = unbundlepart(self.ui, headerblock, self._fp)
1183 op = interruptoperation(self.ui)
1183 op = interruptoperation(self.ui)
1184 hardabort = False
1184 hardabort = False
1185 try:
1185 try:
1186 _processpart(op, part)
1186 _processpart(op, part)
1187 except (SystemExit, KeyboardInterrupt):
1187 except (SystemExit, KeyboardInterrupt):
1188 hardabort = True
1188 hardabort = True
1189 raise
1189 raise
1190 finally:
1190 finally:
1191 if not hardabort:
1191 if not hardabort:
1192 part.consume()
1192 part.consume()
1193 self.ui.debug('bundle2-input-stream-interrupt:'
1193 self.ui.debug('bundle2-input-stream-interrupt:'
1194 ' closing out of band context\n')
1194 ' closing out of band context\n')
1195
1195
1196 class interruptoperation(object):
1196 class interruptoperation(object):
1197 """A limited operation to be use by part handler during interruption
1197 """A limited operation to be use by part handler during interruption
1198
1198
1199 It only have access to an ui object.
1199 It only have access to an ui object.
1200 """
1200 """
1201
1201
1202 def __init__(self, ui):
1202 def __init__(self, ui):
1203 self.ui = ui
1203 self.ui = ui
1204 self.reply = None
1204 self.reply = None
1205 self.captureoutput = False
1205 self.captureoutput = False
1206
1206
1207 @property
1207 @property
1208 def repo(self):
1208 def repo(self):
1209 raise error.ProgrammingError('no repo access from stream interruption')
1209 raise error.ProgrammingError('no repo access from stream interruption')
1210
1210
1211 def gettransaction(self):
1211 def gettransaction(self):
1212 raise TransactionUnavailable('no repo access from stream interruption')
1212 raise TransactionUnavailable('no repo access from stream interruption')
1213
1213
1214 def decodepayloadchunks(ui, fh):
1214 def decodepayloadchunks(ui, fh):
1215 """Reads bundle2 part payload data into chunks.
1215 """Reads bundle2 part payload data into chunks.
1216
1216
1217 Part payload data consists of framed chunks. This function takes
1217 Part payload data consists of framed chunks. This function takes
1218 a file handle and emits those chunks.
1218 a file handle and emits those chunks.
1219 """
1219 """
1220 dolog = ui.configbool('devel', 'bundle2.debug')
1220 dolog = ui.configbool('devel', 'bundle2.debug')
1221 debug = ui.debug
1221 debug = ui.debug
1222
1222
1223 headerstruct = struct.Struct(_fpayloadsize)
1223 headerstruct = struct.Struct(_fpayloadsize)
1224 headersize = headerstruct.size
1224 headersize = headerstruct.size
1225 unpack = headerstruct.unpack
1225 unpack = headerstruct.unpack
1226
1226
1227 readexactly = changegroup.readexactly
1227 readexactly = changegroup.readexactly
1228 read = fh.read
1228 read = fh.read
1229
1229
1230 chunksize = unpack(readexactly(fh, headersize))[0]
1230 chunksize = unpack(readexactly(fh, headersize))[0]
1231 indebug(ui, 'payload chunk size: %i' % chunksize)
1231 indebug(ui, 'payload chunk size: %i' % chunksize)
1232
1232
1233 # changegroup.readexactly() is inlined below for performance.
1233 # changegroup.readexactly() is inlined below for performance.
1234 while chunksize:
1234 while chunksize:
1235 if chunksize >= 0:
1235 if chunksize >= 0:
1236 s = read(chunksize)
1236 s = read(chunksize)
1237 if len(s) < chunksize:
1237 if len(s) < chunksize:
1238 raise error.Abort(_('stream ended unexpectedly '
1238 raise error.Abort(_('stream ended unexpectedly '
1239 ' (got %d bytes, expected %d)') %
1239 ' (got %d bytes, expected %d)') %
1240 (len(s), chunksize))
1240 (len(s), chunksize))
1241
1241
1242 yield s
1242 yield s
1243 elif chunksize == flaginterrupt:
1243 elif chunksize == flaginterrupt:
1244 # Interrupt "signal" detected. The regular stream is interrupted
1244 # Interrupt "signal" detected. The regular stream is interrupted
1245 # and a bundle2 part follows. Consume it.
1245 # and a bundle2 part follows. Consume it.
1246 interrupthandler(ui, fh)()
1246 interrupthandler(ui, fh)()
1247 else:
1247 else:
1248 raise error.BundleValueError(
1248 raise error.BundleValueError(
1249 'negative payload chunk size: %s' % chunksize)
1249 'negative payload chunk size: %s' % chunksize)
1250
1250
1251 s = read(headersize)
1251 s = read(headersize)
1252 if len(s) < headersize:
1252 if len(s) < headersize:
1253 raise error.Abort(_('stream ended unexpectedly '
1253 raise error.Abort(_('stream ended unexpectedly '
1254 ' (got %d bytes, expected %d)') %
1254 ' (got %d bytes, expected %d)') %
1255 (len(s), chunksize))
1255 (len(s), chunksize))
1256
1256
1257 chunksize = unpack(s)[0]
1257 chunksize = unpack(s)[0]
1258
1258
1259 # indebug() inlined for performance.
1259 # indebug() inlined for performance.
1260 if dolog:
1260 if dolog:
1261 debug('bundle2-input: payload chunk size: %i\n' % chunksize)
1261 debug('bundle2-input: payload chunk size: %i\n' % chunksize)
1262
1262
1263 class unbundlepart(unpackermixin):
1263 class unbundlepart(unpackermixin):
1264 """a bundle part read from a bundle"""
1264 """a bundle part read from a bundle"""
1265
1265
1266 def __init__(self, ui, header, fp):
1266 def __init__(self, ui, header, fp):
1267 super(unbundlepart, self).__init__(fp)
1267 super(unbundlepart, self).__init__(fp)
1268 self._seekable = (util.safehasattr(fp, 'seek') and
1268 self._seekable = (util.safehasattr(fp, 'seek') and
1269 util.safehasattr(fp, 'tell'))
1269 util.safehasattr(fp, 'tell'))
1270 self.ui = ui
1270 self.ui = ui
1271 # unbundle state attr
1271 # unbundle state attr
1272 self._headerdata = header
1272 self._headerdata = header
1273 self._headeroffset = 0
1273 self._headeroffset = 0
1274 self._initialized = False
1274 self._initialized = False
1275 self.consumed = False
1275 self.consumed = False
1276 # part data
1276 # part data
1277 self.id = None
1277 self.id = None
1278 self.type = None
1278 self.type = None
1279 self.mandatoryparams = None
1279 self.mandatoryparams = None
1280 self.advisoryparams = None
1280 self.advisoryparams = None
1281 self.params = None
1281 self.params = None
1282 self.mandatorykeys = ()
1282 self.mandatorykeys = ()
1283 self._readheader()
1283 self._readheader()
1284 self._mandatory = None
1284 self._mandatory = None
1285 self._pos = 0
1285 self._pos = 0
1286
1286
1287 def _fromheader(self, size):
1287 def _fromheader(self, size):
1288 """return the next <size> byte from the header"""
1288 """return the next <size> byte from the header"""
1289 offset = self._headeroffset
1289 offset = self._headeroffset
1290 data = self._headerdata[offset:(offset + size)]
1290 data = self._headerdata[offset:(offset + size)]
1291 self._headeroffset = offset + size
1291 self._headeroffset = offset + size
1292 return data
1292 return data
1293
1293
1294 def _unpackheader(self, format):
1294 def _unpackheader(self, format):
1295 """read given format from header
1295 """read given format from header
1296
1296
1297 This automatically compute the size of the format to read."""
1297 This automatically compute the size of the format to read."""
1298 data = self._fromheader(struct.calcsize(format))
1298 data = self._fromheader(struct.calcsize(format))
1299 return _unpack(format, data)
1299 return _unpack(format, data)
1300
1300
1301 def _initparams(self, mandatoryparams, advisoryparams):
1301 def _initparams(self, mandatoryparams, advisoryparams):
1302 """internal function to setup all logic related parameters"""
1302 """internal function to setup all logic related parameters"""
1303 # make it read only to prevent people touching it by mistake.
1303 # make it read only to prevent people touching it by mistake.
1304 self.mandatoryparams = tuple(mandatoryparams)
1304 self.mandatoryparams = tuple(mandatoryparams)
1305 self.advisoryparams = tuple(advisoryparams)
1305 self.advisoryparams = tuple(advisoryparams)
1306 # user friendly UI
1306 # user friendly UI
1307 self.params = util.sortdict(self.mandatoryparams)
1307 self.params = util.sortdict(self.mandatoryparams)
1308 self.params.update(self.advisoryparams)
1308 self.params.update(self.advisoryparams)
1309 self.mandatorykeys = frozenset(p[0] for p in mandatoryparams)
1309 self.mandatorykeys = frozenset(p[0] for p in mandatoryparams)
1310
1310
1311 def _readheader(self):
1311 def _readheader(self):
1312 """read the header and setup the object"""
1312 """read the header and setup the object"""
1313 typesize = self._unpackheader(_fparttypesize)[0]
1313 typesize = self._unpackheader(_fparttypesize)[0]
1314 self.type = self._fromheader(typesize)
1314 self.type = self._fromheader(typesize)
1315 indebug(self.ui, 'part type: "%s"' % self.type)
1315 indebug(self.ui, 'part type: "%s"' % self.type)
1316 self.id = self._unpackheader(_fpartid)[0]
1316 self.id = self._unpackheader(_fpartid)[0]
1317 indebug(self.ui, 'part id: "%s"' % pycompat.bytestr(self.id))
1317 indebug(self.ui, 'part id: "%s"' % pycompat.bytestr(self.id))
1318 # extract mandatory bit from type
1318 # extract mandatory bit from type
1319 self.mandatory = (self.type != self.type.lower())
1319 self.mandatory = (self.type != self.type.lower())
1320 self.type = self.type.lower()
1320 self.type = self.type.lower()
1321 ## reading parameters
1321 ## reading parameters
1322 # param count
1322 # param count
1323 mancount, advcount = self._unpackheader(_fpartparamcount)
1323 mancount, advcount = self._unpackheader(_fpartparamcount)
1324 indebug(self.ui, 'part parameters: %i' % (mancount + advcount))
1324 indebug(self.ui, 'part parameters: %i' % (mancount + advcount))
1325 # param size
1325 # param size
1326 fparamsizes = _makefpartparamsizes(mancount + advcount)
1326 fparamsizes = _makefpartparamsizes(mancount + advcount)
1327 paramsizes = self._unpackheader(fparamsizes)
1327 paramsizes = self._unpackheader(fparamsizes)
1328 # make it a list of couple again
1328 # make it a list of couple again
1329 paramsizes = list(zip(paramsizes[::2], paramsizes[1::2]))
1329 paramsizes = list(zip(paramsizes[::2], paramsizes[1::2]))
1330 # split mandatory from advisory
1330 # split mandatory from advisory
1331 mansizes = paramsizes[:mancount]
1331 mansizes = paramsizes[:mancount]
1332 advsizes = paramsizes[mancount:]
1332 advsizes = paramsizes[mancount:]
1333 # retrieve param value
1333 # retrieve param value
1334 manparams = []
1334 manparams = []
1335 for key, value in mansizes:
1335 for key, value in mansizes:
1336 manparams.append((self._fromheader(key), self._fromheader(value)))
1336 manparams.append((self._fromheader(key), self._fromheader(value)))
1337 advparams = []
1337 advparams = []
1338 for key, value in advsizes:
1338 for key, value in advsizes:
1339 advparams.append((self._fromheader(key), self._fromheader(value)))
1339 advparams.append((self._fromheader(key), self._fromheader(value)))
1340 self._initparams(manparams, advparams)
1340 self._initparams(manparams, advparams)
1341 ## part payload
1341 ## part payload
1342 self._payloadstream = util.chunkbuffer(self._payloadchunks())
1342 self._payloadstream = util.chunkbuffer(self._payloadchunks())
1343 # we read the data, tell it
1343 # we read the data, tell it
1344 self._initialized = True
1344 self._initialized = True
1345
1345
1346 def _payloadchunks(self):
1346 def _payloadchunks(self):
1347 """Generator of decoded chunks in the payload."""
1347 """Generator of decoded chunks in the payload."""
1348 return decodepayloadchunks(self.ui, self._fp)
1348 return decodepayloadchunks(self.ui, self._fp)
1349
1349
1350 def consume(self):
1350 def consume(self):
1351 """Read the part payload until completion.
1351 """Read the part payload until completion.
1352
1352
1353 By consuming the part data, the underlying stream read offset will
1353 By consuming the part data, the underlying stream read offset will
1354 be advanced to the next part (or end of stream).
1354 be advanced to the next part (or end of stream).
1355 """
1355 """
1356 if self.consumed:
1356 if self.consumed:
1357 return
1357 return
1358
1358
1359 chunk = self.read(32768)
1359 chunk = self.read(32768)
1360 while chunk:
1360 while chunk:
1361 self._pos += len(chunk)
1361 self._pos += len(chunk)
1362 chunk = self.read(32768)
1362 chunk = self.read(32768)
1363
1363
1364 def read(self, size=None):
1364 def read(self, size=None):
1365 """read payload data"""
1365 """read payload data"""
1366 if not self._initialized:
1366 if not self._initialized:
1367 self._readheader()
1367 self._readheader()
1368 if size is None:
1368 if size is None:
1369 data = self._payloadstream.read()
1369 data = self._payloadstream.read()
1370 else:
1370 else:
1371 data = self._payloadstream.read(size)
1371 data = self._payloadstream.read(size)
1372 self._pos += len(data)
1372 self._pos += len(data)
1373 if size is None or len(data) < size:
1373 if size is None or len(data) < size:
1374 if not self.consumed and self._pos:
1374 if not self.consumed and self._pos:
1375 self.ui.debug('bundle2-input-part: total payload size %i\n'
1375 self.ui.debug('bundle2-input-part: total payload size %i\n'
1376 % self._pos)
1376 % self._pos)
1377 self.consumed = True
1377 self.consumed = True
1378 return data
1378 return data
1379
1379
1380 class seekableunbundlepart(unbundlepart):
1380 class seekableunbundlepart(unbundlepart):
1381 """A bundle2 part in a bundle that is seekable.
1381 """A bundle2 part in a bundle that is seekable.
1382
1382
1383 Regular ``unbundlepart`` instances can only be read once. This class
1383 Regular ``unbundlepart`` instances can only be read once. This class
1384 extends ``unbundlepart`` to enable bi-directional seeking within the
1384 extends ``unbundlepart`` to enable bi-directional seeking within the
1385 part.
1385 part.
1386
1386
1387 Bundle2 part data consists of framed chunks. Offsets when seeking
1387 Bundle2 part data consists of framed chunks. Offsets when seeking
1388 refer to the decoded data, not the offsets in the underlying bundle2
1388 refer to the decoded data, not the offsets in the underlying bundle2
1389 stream.
1389 stream.
1390
1390
1391 To facilitate quickly seeking within the decoded data, instances of this
1391 To facilitate quickly seeking within the decoded data, instances of this
1392 class maintain a mapping between offsets in the underlying stream and
1392 class maintain a mapping between offsets in the underlying stream and
1393 the decoded payload. This mapping will consume memory in proportion
1393 the decoded payload. This mapping will consume memory in proportion
1394 to the number of chunks within the payload (which almost certainly
1394 to the number of chunks within the payload (which almost certainly
1395 increases in proportion with the size of the part).
1395 increases in proportion with the size of the part).
1396 """
1396 """
1397 def __init__(self, ui, header, fp):
1397 def __init__(self, ui, header, fp):
1398 # (payload, file) offsets for chunk starts.
1398 # (payload, file) offsets for chunk starts.
1399 self._chunkindex = []
1399 self._chunkindex = []
1400
1400
1401 super(seekableunbundlepart, self).__init__(ui, header, fp)
1401 super(seekableunbundlepart, self).__init__(ui, header, fp)
1402
1402
1403 def _payloadchunks(self, chunknum=0):
1403 def _payloadchunks(self, chunknum=0):
1404 '''seek to specified chunk and start yielding data'''
1404 '''seek to specified chunk and start yielding data'''
1405 if len(self._chunkindex) == 0:
1405 if len(self._chunkindex) == 0:
1406 assert chunknum == 0, 'Must start with chunk 0'
1406 assert chunknum == 0, 'Must start with chunk 0'
1407 self._chunkindex.append((0, self._tellfp()))
1407 self._chunkindex.append((0, self._tellfp()))
1408 else:
1408 else:
1409 assert chunknum < len(self._chunkindex), (
1409 assert chunknum < len(self._chunkindex), (
1410 'Unknown chunk %d' % chunknum)
1410 'Unknown chunk %d' % chunknum)
1411 self._seekfp(self._chunkindex[chunknum][1])
1411 self._seekfp(self._chunkindex[chunknum][1])
1412
1412
1413 pos = self._chunkindex[chunknum][0]
1413 pos = self._chunkindex[chunknum][0]
1414
1414
1415 for chunk in decodepayloadchunks(self.ui, self._fp):
1415 for chunk in decodepayloadchunks(self.ui, self._fp):
1416 chunknum += 1
1416 chunknum += 1
1417 pos += len(chunk)
1417 pos += len(chunk)
1418 if chunknum == len(self._chunkindex):
1418 if chunknum == len(self._chunkindex):
1419 self._chunkindex.append((pos, self._tellfp()))
1419 self._chunkindex.append((pos, self._tellfp()))
1420
1420
1421 yield chunk
1421 yield chunk
1422
1422
1423 def _findchunk(self, pos):
1423 def _findchunk(self, pos):
1424 '''for a given payload position, return a chunk number and offset'''
1424 '''for a given payload position, return a chunk number and offset'''
1425 for chunk, (ppos, fpos) in enumerate(self._chunkindex):
1425 for chunk, (ppos, fpos) in enumerate(self._chunkindex):
1426 if ppos == pos:
1426 if ppos == pos:
1427 return chunk, 0
1427 return chunk, 0
1428 elif ppos > pos:
1428 elif ppos > pos:
1429 return chunk - 1, pos - self._chunkindex[chunk - 1][0]
1429 return chunk - 1, pos - self._chunkindex[chunk - 1][0]
1430 raise ValueError('Unknown chunk')
1430 raise ValueError('Unknown chunk')
1431
1431
1432 def tell(self):
1432 def tell(self):
1433 return self._pos
1433 return self._pos
1434
1434
1435 def seek(self, offset, whence=os.SEEK_SET):
1435 def seek(self, offset, whence=os.SEEK_SET):
1436 if whence == os.SEEK_SET:
1436 if whence == os.SEEK_SET:
1437 newpos = offset
1437 newpos = offset
1438 elif whence == os.SEEK_CUR:
1438 elif whence == os.SEEK_CUR:
1439 newpos = self._pos + offset
1439 newpos = self._pos + offset
1440 elif whence == os.SEEK_END:
1440 elif whence == os.SEEK_END:
1441 if not self.consumed:
1441 if not self.consumed:
1442 # Can't use self.consume() here because it advances self._pos.
1442 # Can't use self.consume() here because it advances self._pos.
1443 chunk = self.read(32768)
1443 chunk = self.read(32768)
1444 while chunk:
1444 while chunk:
1445 chunk = self.read(32768)
1445 chunk = self.read(32768)
1446 newpos = self._chunkindex[-1][0] - offset
1446 newpos = self._chunkindex[-1][0] - offset
1447 else:
1447 else:
1448 raise ValueError('Unknown whence value: %r' % (whence,))
1448 raise ValueError('Unknown whence value: %r' % (whence,))
1449
1449
1450 if newpos > self._chunkindex[-1][0] and not self.consumed:
1450 if newpos > self._chunkindex[-1][0] and not self.consumed:
1451 # Can't use self.consume() here because it advances self._pos.
1451 # Can't use self.consume() here because it advances self._pos.
1452 chunk = self.read(32768)
1452 chunk = self.read(32768)
1453 while chunk:
1453 while chunk:
1454 chunk = self.read(32668)
1454 chunk = self.read(32668)
1455
1455
1456 if not 0 <= newpos <= self._chunkindex[-1][0]:
1456 if not 0 <= newpos <= self._chunkindex[-1][0]:
1457 raise ValueError('Offset out of range')
1457 raise ValueError('Offset out of range')
1458
1458
1459 if self._pos != newpos:
1459 if self._pos != newpos:
1460 chunk, internaloffset = self._findchunk(newpos)
1460 chunk, internaloffset = self._findchunk(newpos)
1461 self._payloadstream = util.chunkbuffer(self._payloadchunks(chunk))
1461 self._payloadstream = util.chunkbuffer(self._payloadchunks(chunk))
1462 adjust = self.read(internaloffset)
1462 adjust = self.read(internaloffset)
1463 if len(adjust) != internaloffset:
1463 if len(adjust) != internaloffset:
1464 raise error.Abort(_('Seek failed\n'))
1464 raise error.Abort(_('Seek failed\n'))
1465 self._pos = newpos
1465 self._pos = newpos
1466
1466
1467 def _seekfp(self, offset, whence=0):
1467 def _seekfp(self, offset, whence=0):
1468 """move the underlying file pointer
1468 """move the underlying file pointer
1469
1469
1470 This method is meant for internal usage by the bundle2 protocol only.
1470 This method is meant for internal usage by the bundle2 protocol only.
1471 They directly manipulate the low level stream including bundle2 level
1471 They directly manipulate the low level stream including bundle2 level
1472 instruction.
1472 instruction.
1473
1473
1474 Do not use it to implement higher-level logic or methods."""
1474 Do not use it to implement higher-level logic or methods."""
1475 if self._seekable:
1475 if self._seekable:
1476 return self._fp.seek(offset, whence)
1476 return self._fp.seek(offset, whence)
1477 else:
1477 else:
1478 raise NotImplementedError(_('File pointer is not seekable'))
1478 raise NotImplementedError(_('File pointer is not seekable'))
1479
1479
1480 def _tellfp(self):
1480 def _tellfp(self):
1481 """return the file offset, or None if file is not seekable
1481 """return the file offset, or None if file is not seekable
1482
1482
1483 This method is meant for internal usage by the bundle2 protocol only.
1483 This method is meant for internal usage by the bundle2 protocol only.
1484 They directly manipulate the low level stream including bundle2 level
1484 They directly manipulate the low level stream including bundle2 level
1485 instruction.
1485 instruction.
1486
1486
1487 Do not use it to implement higher-level logic or methods."""
1487 Do not use it to implement higher-level logic or methods."""
1488 if self._seekable:
1488 if self._seekable:
1489 try:
1489 try:
1490 return self._fp.tell()
1490 return self._fp.tell()
1491 except IOError as e:
1491 except IOError as e:
1492 if e.errno == errno.ESPIPE:
1492 if e.errno == errno.ESPIPE:
1493 self._seekable = False
1493 self._seekable = False
1494 else:
1494 else:
1495 raise
1495 raise
1496 return None
1496 return None
1497
1497
1498 # These are only the static capabilities.
1498 # These are only the static capabilities.
1499 # Check the 'getrepocaps' function for the rest.
1499 # Check the 'getrepocaps' function for the rest.
1500 capabilities = {'HG20': (),
1500 capabilities = {'HG20': (),
1501 'bookmarks': (),
1501 'bookmarks': (),
1502 'error': ('abort', 'unsupportedcontent', 'pushraced',
1502 'error': ('abort', 'unsupportedcontent', 'pushraced',
1503 'pushkey'),
1503 'pushkey'),
1504 'listkeys': (),
1504 'listkeys': (),
1505 'pushkey': (),
1505 'pushkey': (),
1506 'digests': tuple(sorted(util.DIGESTS.keys())),
1506 'digests': tuple(sorted(util.DIGESTS.keys())),
1507 'remote-changegroup': ('http', 'https'),
1507 'remote-changegroup': ('http', 'https'),
1508 'hgtagsfnodes': (),
1508 'hgtagsfnodes': (),
1509 'rev-branch-cache': (),
1509 'rev-branch-cache': (),
1510 'phases': ('heads',),
1510 'phases': ('heads',),
1511 'stream': ('v2',),
1511 'stream': ('v2',),
1512 }
1512 }
1513
1513
1514 def getrepocaps(repo, allowpushback=False, role=None):
1514 def getrepocaps(repo, allowpushback=False, role=None):
1515 """return the bundle2 capabilities for a given repo
1515 """return the bundle2 capabilities for a given repo
1516
1516
1517 Exists to allow extensions (like evolution) to mutate the capabilities.
1517 Exists to allow extensions (like evolution) to mutate the capabilities.
1518
1518
1519 The returned value is used for servers advertising their capabilities as
1519 The returned value is used for servers advertising their capabilities as
1520 well as clients advertising their capabilities to servers as part of
1520 well as clients advertising their capabilities to servers as part of
1521 bundle2 requests. The ``role`` argument specifies which is which.
1521 bundle2 requests. The ``role`` argument specifies which is which.
1522 """
1522 """
1523 if role not in ('client', 'server'):
1523 if role not in ('client', 'server'):
1524 raise error.ProgrammingError('role argument must be client or server')
1524 raise error.ProgrammingError('role argument must be client or server')
1525
1525
1526 caps = capabilities.copy()
1526 caps = capabilities.copy()
1527 caps['changegroup'] = tuple(sorted(
1527 caps['changegroup'] = tuple(sorted(
1528 changegroup.supportedincomingversions(repo)))
1528 changegroup.supportedincomingversions(repo)))
1529 if obsolete.isenabled(repo, obsolete.exchangeopt):
1529 if obsolete.isenabled(repo, obsolete.exchangeopt):
1530 supportedformat = tuple('V%i' % v for v in obsolete.formats)
1530 supportedformat = tuple('V%i' % v for v in obsolete.formats)
1531 caps['obsmarkers'] = supportedformat
1531 caps['obsmarkers'] = supportedformat
1532 if allowpushback:
1532 if allowpushback:
1533 caps['pushback'] = ()
1533 caps['pushback'] = ()
1534 cpmode = repo.ui.config('server', 'concurrent-push-mode')
1534 cpmode = repo.ui.config('server', 'concurrent-push-mode')
1535 if cpmode == 'check-related':
1535 if cpmode == 'check-related':
1536 caps['checkheads'] = ('related',)
1536 caps['checkheads'] = ('related',)
1537 if 'phases' in repo.ui.configlist('devel', 'legacy.exchange'):
1537 if 'phases' in repo.ui.configlist('devel', 'legacy.exchange'):
1538 caps.pop('phases')
1538 caps.pop('phases')
1539
1539
1540 # Don't advertise stream clone support in server mode if not configured.
1540 # Don't advertise stream clone support in server mode if not configured.
1541 if role == 'server':
1541 if role == 'server':
1542 streamsupported = repo.ui.configbool('server', 'uncompressed',
1542 streamsupported = repo.ui.configbool('server', 'uncompressed',
1543 untrusted=True)
1543 untrusted=True)
1544 featuresupported = repo.ui.configbool('server', 'bundle2.stream')
1544 featuresupported = repo.ui.configbool('server', 'bundle2.stream')
1545
1545
1546 if not streamsupported or not featuresupported:
1546 if not streamsupported or not featuresupported:
1547 caps.pop('stream')
1547 caps.pop('stream')
1548 # Else always advertise support on client, because payload support
1548 # Else always advertise support on client, because payload support
1549 # should always be advertised.
1549 # should always be advertised.
1550
1550
1551 return caps
1551 return caps
1552
1552
1553 def bundle2caps(remote):
1553 def bundle2caps(remote):
1554 """return the bundle capabilities of a peer as dict"""
1554 """return the bundle capabilities of a peer as dict"""
1555 raw = remote.capable('bundle2')
1555 raw = remote.capable('bundle2')
1556 if not raw and raw != '':
1556 if not raw and raw != '':
1557 return {}
1557 return {}
1558 capsblob = urlreq.unquote(remote.capable('bundle2'))
1558 capsblob = urlreq.unquote(remote.capable('bundle2'))
1559 return decodecaps(capsblob)
1559 return decodecaps(capsblob)
1560
1560
1561 def obsmarkersversion(caps):
1561 def obsmarkersversion(caps):
1562 """extract the list of supported obsmarkers versions from a bundle2caps dict
1562 """extract the list of supported obsmarkers versions from a bundle2caps dict
1563 """
1563 """
1564 obscaps = caps.get('obsmarkers', ())
1564 obscaps = caps.get('obsmarkers', ())
1565 return [int(c[1:]) for c in obscaps if c.startswith('V')]
1565 return [int(c[1:]) for c in obscaps if c.startswith('V')]
1566
1566
1567 def writenewbundle(ui, repo, source, filename, bundletype, outgoing, opts,
1567 def writenewbundle(ui, repo, source, filename, bundletype, outgoing, opts,
1568 vfs=None, compression=None, compopts=None):
1568 vfs=None, compression=None, compopts=None):
1569 if bundletype.startswith('HG10'):
1569 if bundletype.startswith('HG10'):
1570 cg = changegroup.makechangegroup(repo, outgoing, '01', source)
1570 cg = changegroup.makechangegroup(repo, outgoing, '01', source)
1571 return writebundle(ui, cg, filename, bundletype, vfs=vfs,
1571 return writebundle(ui, cg, filename, bundletype, vfs=vfs,
1572 compression=compression, compopts=compopts)
1572 compression=compression, compopts=compopts)
1573 elif not bundletype.startswith('HG20'):
1573 elif not bundletype.startswith('HG20'):
1574 raise error.ProgrammingError('unknown bundle type: %s' % bundletype)
1574 raise error.ProgrammingError('unknown bundle type: %s' % bundletype)
1575
1575
1576 caps = {}
1576 caps = {}
1577 if 'obsolescence' in opts:
1577 if 'obsolescence' in opts:
1578 caps['obsmarkers'] = ('V1',)
1578 caps['obsmarkers'] = ('V1',)
1579 bundle = bundle20(ui, caps)
1579 bundle = bundle20(ui, caps)
1580 bundle.setcompression(compression, compopts)
1580 bundle.setcompression(compression, compopts)
1581 _addpartsfromopts(ui, repo, bundle, source, outgoing, opts)
1581 _addpartsfromopts(ui, repo, bundle, source, outgoing, opts)
1582 chunkiter = bundle.getchunks()
1582 chunkiter = bundle.getchunks()
1583
1583
1584 return changegroup.writechunks(ui, chunkiter, filename, vfs=vfs)
1584 return changegroup.writechunks(ui, chunkiter, filename, vfs=vfs)
1585
1585
1586 def _addpartsfromopts(ui, repo, bundler, source, outgoing, opts):
1586 def _addpartsfromopts(ui, repo, bundler, source, outgoing, opts):
1587 # We should eventually reconcile this logic with the one behind
1587 # We should eventually reconcile this logic with the one behind
1588 # 'exchange.getbundle2partsgenerator'.
1588 # 'exchange.getbundle2partsgenerator'.
1589 #
1589 #
1590 # The type of input from 'getbundle' and 'writenewbundle' are a bit
1590 # The type of input from 'getbundle' and 'writenewbundle' are a bit
1591 # different right now. So we keep them separated for now for the sake of
1591 # different right now. So we keep them separated for now for the sake of
1592 # simplicity.
1592 # simplicity.
1593
1593
1594 # we might not always want a changegroup in such bundle, for example in
1594 # we might not always want a changegroup in such bundle, for example in
1595 # stream bundles
1595 # stream bundles
1596 if opts.get('changegroup', True):
1596 if opts.get('changegroup', True):
1597 cgversion = opts.get('cg.version')
1597 cgversion = opts.get('cg.version')
1598 if cgversion is None:
1598 if cgversion is None:
1599 cgversion = changegroup.safeversion(repo)
1599 cgversion = changegroup.safeversion(repo)
1600 cg = changegroup.makechangegroup(repo, outgoing, cgversion, source)
1600 cg = changegroup.makechangegroup(repo, outgoing, cgversion, source)
1601 part = bundler.newpart('changegroup', data=cg.getchunks())
1601 part = bundler.newpart('changegroup', data=cg.getchunks())
1602 part.addparam('version', cg.version)
1602 part.addparam('version', cg.version)
1603 if 'clcount' in cg.extras:
1603 if 'clcount' in cg.extras:
1604 part.addparam('nbchanges', '%d' % cg.extras['clcount'],
1604 part.addparam('nbchanges', '%d' % cg.extras['clcount'],
1605 mandatory=False)
1605 mandatory=False)
1606 if opts.get('phases') and repo.revs('%ln and secret()',
1606 if opts.get('phases') and repo.revs('%ln and secret()',
1607 outgoing.missingheads):
1607 outgoing.missingheads):
1608 part.addparam('targetphase', '%d' % phases.secret, mandatory=False)
1608 part.addparam('targetphase', '%d' % phases.secret, mandatory=False)
1609
1609
1610 if opts.get('streamv2', False):
1610 if opts.get('streamv2', False):
1611 addpartbundlestream2(bundler, repo, stream=True)
1611 addpartbundlestream2(bundler, repo, stream=True)
1612
1612
1613 if opts.get('tagsfnodescache', True):
1613 if opts.get('tagsfnodescache', True):
1614 addparttagsfnodescache(repo, bundler, outgoing)
1614 addparttagsfnodescache(repo, bundler, outgoing)
1615
1615
1616 if opts.get('revbranchcache', True):
1616 if opts.get('revbranchcache', True):
1617 addpartrevbranchcache(repo, bundler, outgoing)
1617 addpartrevbranchcache(repo, bundler, outgoing)
1618
1618
1619 if opts.get('obsolescence', False):
1619 if opts.get('obsolescence', False):
1620 obsmarkers = repo.obsstore.relevantmarkers(outgoing.missing)
1620 obsmarkers = repo.obsstore.relevantmarkers(outgoing.missing)
1621 buildobsmarkerspart(bundler, obsmarkers)
1621 buildobsmarkerspart(bundler, obsmarkers)
1622
1622
1623 if opts.get('phases', False):
1623 if opts.get('phases', False):
1624 headsbyphase = phases.subsetphaseheads(repo, outgoing.missing)
1624 headsbyphase = phases.subsetphaseheads(repo, outgoing.missing)
1625 phasedata = phases.binaryencode(headsbyphase)
1625 phasedata = phases.binaryencode(headsbyphase)
1626 bundler.newpart('phase-heads', data=phasedata)
1626 bundler.newpart('phase-heads', data=phasedata)
1627
1627
1628 def addparttagsfnodescache(repo, bundler, outgoing):
1628 def addparttagsfnodescache(repo, bundler, outgoing):
1629 # we include the tags fnode cache for the bundle changeset
1629 # we include the tags fnode cache for the bundle changeset
1630 # (as an optional parts)
1630 # (as an optional parts)
1631 cache = tags.hgtagsfnodescache(repo.unfiltered())
1631 cache = tags.hgtagsfnodescache(repo.unfiltered())
1632 chunks = []
1632 chunks = []
1633
1633
1634 # .hgtags fnodes are only relevant for head changesets. While we could
1634 # .hgtags fnodes are only relevant for head changesets. While we could
1635 # transfer values for all known nodes, there will likely be little to
1635 # transfer values for all known nodes, there will likely be little to
1636 # no benefit.
1636 # no benefit.
1637 #
1637 #
1638 # We don't bother using a generator to produce output data because
1638 # We don't bother using a generator to produce output data because
1639 # a) we only have 40 bytes per head and even esoteric numbers of heads
1639 # a) we only have 40 bytes per head and even esoteric numbers of heads
1640 # consume little memory (1M heads is 40MB) b) we don't want to send the
1640 # consume little memory (1M heads is 40MB) b) we don't want to send the
1641 # part if we don't have entries and knowing if we have entries requires
1641 # part if we don't have entries and knowing if we have entries requires
1642 # cache lookups.
1642 # cache lookups.
1643 for node in outgoing.missingheads:
1643 for node in outgoing.missingheads:
1644 # Don't compute missing, as this may slow down serving.
1644 # Don't compute missing, as this may slow down serving.
1645 fnode = cache.getfnode(node, computemissing=False)
1645 fnode = cache.getfnode(node, computemissing=False)
1646 if fnode is not None:
1646 if fnode is not None:
1647 chunks.extend([node, fnode])
1647 chunks.extend([node, fnode])
1648
1648
1649 if chunks:
1649 if chunks:
1650 bundler.newpart('hgtagsfnodes', data=''.join(chunks))
1650 bundler.newpart('hgtagsfnodes', data=''.join(chunks))
1651
1651
1652 def addpartrevbranchcache(repo, bundler, outgoing):
1652 def addpartrevbranchcache(repo, bundler, outgoing):
1653 # we include the rev branch cache for the bundle changeset
1653 # we include the rev branch cache for the bundle changeset
1654 # (as an optional parts)
1654 # (as an optional parts)
1655 cache = repo.revbranchcache()
1655 cache = repo.revbranchcache()
1656 cl = repo.unfiltered().changelog
1656 cl = repo.unfiltered().changelog
1657 branchesdata = collections.defaultdict(lambda: (set(), set()))
1657 branchesdata = collections.defaultdict(lambda: (set(), set()))
1658 for node in outgoing.missing:
1658 for node in outgoing.missing:
1659 branch, close = cache.branchinfo(cl.rev(node))
1659 branch, close = cache.branchinfo(cl.rev(node))
1660 branchesdata[branch][close].add(node)
1660 branchesdata[branch][close].add(node)
1661
1661
1662 def generate():
1662 def generate():
1663 for branch, (nodes, closed) in sorted(branchesdata.items()):
1663 for branch, (nodes, closed) in sorted(branchesdata.items()):
1664 utf8branch = encoding.fromlocal(branch)
1664 utf8branch = encoding.fromlocal(branch)
1665 yield rbcstruct.pack(len(utf8branch), len(nodes), len(closed))
1665 yield rbcstruct.pack(len(utf8branch), len(nodes), len(closed))
1666 yield utf8branch
1666 yield utf8branch
1667 for n in sorted(nodes):
1667 for n in sorted(nodes):
1668 yield n
1668 yield n
1669 for n in sorted(closed):
1669 for n in sorted(closed):
1670 yield n
1670 yield n
1671
1671
1672 bundler.newpart('cache:rev-branch-cache', data=generate(),
1672 bundler.newpart('cache:rev-branch-cache', data=generate(),
1673 mandatory=False)
1673 mandatory=False)
1674
1674
1675 def _formatrequirementsspec(requirements):
1675 def _formatrequirementsspec(requirements):
1676 requirements = [req for req in requirements if req != "shared"]
1676 requirements = [req for req in requirements if req != "shared"]
1677 return urlreq.quote(','.join(sorted(requirements)))
1677 return urlreq.quote(','.join(sorted(requirements)))
1678
1678
1679 def _formatrequirementsparams(requirements):
1679 def _formatrequirementsparams(requirements):
1680 requirements = _formatrequirementsspec(requirements)
1680 requirements = _formatrequirementsspec(requirements)
1681 params = "%s%s" % (urlreq.quote("requirements="), requirements)
1681 params = "%s%s" % (urlreq.quote("requirements="), requirements)
1682 return params
1682 return params
1683
1683
1684 def addpartbundlestream2(bundler, repo, **kwargs):
1684 def addpartbundlestream2(bundler, repo, **kwargs):
1685 if not kwargs.get(r'stream', False):
1685 if not kwargs.get(r'stream', False):
1686 return
1686 return
1687
1687
1688 if not streamclone.allowservergeneration(repo):
1688 if not streamclone.allowservergeneration(repo):
1689 raise error.Abort(_('stream data requested but server does not allow '
1689 raise error.Abort(_('stream data requested but server does not allow '
1690 'this feature'),
1690 'this feature'),
1691 hint=_('well-behaved clients should not be '
1691 hint=_('well-behaved clients should not be '
1692 'requesting stream data from servers not '
1692 'requesting stream data from servers not '
1693 'advertising it; the client may be buggy'))
1693 'advertising it; the client may be buggy'))
1694
1694
1695 # Stream clones don't compress well. And compression undermines a
1695 # Stream clones don't compress well. And compression undermines a
1696 # goal of stream clones, which is to be fast. Communicate the desire
1696 # goal of stream clones, which is to be fast. Communicate the desire
1697 # to avoid compression to consumers of the bundle.
1697 # to avoid compression to consumers of the bundle.
1698 bundler.prefercompressed = False
1698 bundler.prefercompressed = False
1699
1699
1700 # get the includes and excludes
1700 # get the includes and excludes
1701 includepats = kwargs.get(r'includepats')
1701 includepats = kwargs.get(r'includepats')
1702 excludepats = kwargs.get(r'excludepats')
1702 excludepats = kwargs.get(r'excludepats')
1703
1703
1704 narrowstream = repo.ui.configbool('experimental',
1704 narrowstream = repo.ui.configbool('experimental',
1705 'server.stream-narrow-clones')
1705 'server.stream-narrow-clones')
1706
1706
1707 if (includepats or excludepats) and not narrowstream:
1707 if (includepats or excludepats) and not narrowstream:
1708 raise error.Abort(_('server does not support narrow stream clones'))
1708 raise error.Abort(_('server does not support narrow stream clones'))
1709
1709
1710 includeobsmarkers = False
1710 includeobsmarkers = False
1711 if repo.obsstore:
1711 if repo.obsstore:
1712 remoteversions = obsmarkersversion(bundler.capabilities)
1712 remoteversions = obsmarkersversion(bundler.capabilities)
1713 if not remoteversions:
1713 if not remoteversions:
1714 raise error.Abort(_('server has obsolescence markers, but client '
1714 raise error.Abort(_('server has obsolescence markers, but client '
1715 'cannot receive them via stream clone'))
1715 'cannot receive them via stream clone'))
1716 elif repo.obsstore._version in remoteversions:
1716 elif repo.obsstore._version in remoteversions:
1717 includeobsmarkers = True
1717 includeobsmarkers = True
1718
1718
1719 filecount, bytecount, it = streamclone.generatev2(repo, includepats,
1719 filecount, bytecount, it = streamclone.generatev2(repo, includepats,
1720 excludepats,
1720 excludepats,
1721 includeobsmarkers)
1721 includeobsmarkers)
1722 requirements = _formatrequirementsspec(repo.requirements)
1722 requirements = _formatrequirementsspec(repo.requirements)
1723 part = bundler.newpart('stream2', data=it)
1723 part = bundler.newpart('stream2', data=it)
1724 part.addparam('bytecount', '%d' % bytecount, mandatory=True)
1724 part.addparam('bytecount', '%d' % bytecount, mandatory=True)
1725 part.addparam('filecount', '%d' % filecount, mandatory=True)
1725 part.addparam('filecount', '%d' % filecount, mandatory=True)
1726 part.addparam('requirements', requirements, mandatory=True)
1726 part.addparam('requirements', requirements, mandatory=True)
1727
1727
1728 def buildobsmarkerspart(bundler, markers):
1728 def buildobsmarkerspart(bundler, markers):
1729 """add an obsmarker part to the bundler with <markers>
1729 """add an obsmarker part to the bundler with <markers>
1730
1730
1731 No part is created if markers is empty.
1731 No part is created if markers is empty.
1732 Raises ValueError if the bundler doesn't support any known obsmarker format.
1732 Raises ValueError if the bundler doesn't support any known obsmarker format.
1733 """
1733 """
1734 if not markers:
1734 if not markers:
1735 return None
1735 return None
1736
1736
1737 remoteversions = obsmarkersversion(bundler.capabilities)
1737 remoteversions = obsmarkersversion(bundler.capabilities)
1738 version = obsolete.commonversion(remoteversions)
1738 version = obsolete.commonversion(remoteversions)
1739 if version is None:
1739 if version is None:
1740 raise ValueError('bundler does not support common obsmarker format')
1740 raise ValueError('bundler does not support common obsmarker format')
1741 stream = obsolete.encodemarkers(markers, True, version=version)
1741 stream = obsolete.encodemarkers(markers, True, version=version)
1742 return bundler.newpart('obsmarkers', data=stream)
1742 return bundler.newpart('obsmarkers', data=stream)
1743
1743
1744 def writebundle(ui, cg, filename, bundletype, vfs=None, compression=None,
1744 def writebundle(ui, cg, filename, bundletype, vfs=None, compression=None,
1745 compopts=None):
1745 compopts=None):
1746 """Write a bundle file and return its filename.
1746 """Write a bundle file and return its filename.
1747
1747
1748 Existing files will not be overwritten.
1748 Existing files will not be overwritten.
1749 If no filename is specified, a temporary file is created.
1749 If no filename is specified, a temporary file is created.
1750 bz2 compression can be turned off.
1750 bz2 compression can be turned off.
1751 The bundle file will be deleted in case of errors.
1751 The bundle file will be deleted in case of errors.
1752 """
1752 """
1753
1753
1754 if bundletype == "HG20":
1754 if bundletype == "HG20":
1755 bundle = bundle20(ui)
1755 bundle = bundle20(ui)
1756 bundle.setcompression(compression, compopts)
1756 bundle.setcompression(compression, compopts)
1757 part = bundle.newpart('changegroup', data=cg.getchunks())
1757 part = bundle.newpart('changegroup', data=cg.getchunks())
1758 part.addparam('version', cg.version)
1758 part.addparam('version', cg.version)
1759 if 'clcount' in cg.extras:
1759 if 'clcount' in cg.extras:
1760 part.addparam('nbchanges', '%d' % cg.extras['clcount'],
1760 part.addparam('nbchanges', '%d' % cg.extras['clcount'],
1761 mandatory=False)
1761 mandatory=False)
1762 chunkiter = bundle.getchunks()
1762 chunkiter = bundle.getchunks()
1763 else:
1763 else:
1764 # compression argument is only for the bundle2 case
1764 # compression argument is only for the bundle2 case
1765 assert compression is None
1765 assert compression is None
1766 if cg.version != '01':
1766 if cg.version != '01':
1767 raise error.Abort(_('old bundle types only supports v1 '
1767 raise error.Abort(_('old bundle types only supports v1 '
1768 'changegroups'))
1768 'changegroups'))
1769 header, comp = bundletypes[bundletype]
1769 header, comp = bundletypes[bundletype]
1770 if comp not in util.compengines.supportedbundletypes:
1770 if comp not in util.compengines.supportedbundletypes:
1771 raise error.Abort(_('unknown stream compression type: %s')
1771 raise error.Abort(_('unknown stream compression type: %s')
1772 % comp)
1772 % comp)
1773 compengine = util.compengines.forbundletype(comp)
1773 compengine = util.compengines.forbundletype(comp)
1774 def chunkiter():
1774 def chunkiter():
1775 yield header
1775 yield header
1776 for chunk in compengine.compressstream(cg.getchunks(), compopts):
1776 for chunk in compengine.compressstream(cg.getchunks(), compopts):
1777 yield chunk
1777 yield chunk
1778 chunkiter = chunkiter()
1778 chunkiter = chunkiter()
1779
1779
1780 # parse the changegroup data, otherwise we will block
1780 # parse the changegroup data, otherwise we will block
1781 # in case of sshrepo because we don't know the end of the stream
1781 # in case of sshrepo because we don't know the end of the stream
1782 return changegroup.writechunks(ui, chunkiter, filename, vfs=vfs)
1782 return changegroup.writechunks(ui, chunkiter, filename, vfs=vfs)
1783
1783
1784 def combinechangegroupresults(op):
1784 def combinechangegroupresults(op):
1785 """logic to combine 0 or more addchangegroup results into one"""
1785 """logic to combine 0 or more addchangegroup results into one"""
1786 results = [r.get('return', 0)
1786 results = [r.get('return', 0)
1787 for r in op.records['changegroup']]
1787 for r in op.records['changegroup']]
1788 changedheads = 0
1788 changedheads = 0
1789 result = 1
1789 result = 1
1790 for ret in results:
1790 for ret in results:
1791 # If any changegroup result is 0, return 0
1791 # If any changegroup result is 0, return 0
1792 if ret == 0:
1792 if ret == 0:
1793 result = 0
1793 result = 0
1794 break
1794 break
1795 if ret < -1:
1795 if ret < -1:
1796 changedheads += ret + 1
1796 changedheads += ret + 1
1797 elif ret > 1:
1797 elif ret > 1:
1798 changedheads += ret - 1
1798 changedheads += ret - 1
1799 if changedheads > 0:
1799 if changedheads > 0:
1800 result = 1 + changedheads
1800 result = 1 + changedheads
1801 elif changedheads < 0:
1801 elif changedheads < 0:
1802 result = -1 + changedheads
1802 result = -1 + changedheads
1803 return result
1803 return result
1804
1804
1805 @parthandler('changegroup', ('version', 'nbchanges', 'treemanifest',
1805 @parthandler('changegroup', ('version', 'nbchanges', 'treemanifest',
1806 'targetphase'))
1806 'targetphase'))
1807 def handlechangegroup(op, inpart):
1807 def handlechangegroup(op, inpart):
1808 """apply a changegroup part on the repo
1808 """apply a changegroup part on the repo
1809
1809
1810 This is a very early implementation that will massive rework before being
1810 This is a very early implementation that will massive rework before being
1811 inflicted to any end-user.
1811 inflicted to any end-user.
1812 """
1812 """
1813 from . import localrepo
1813 from . import localrepo
1814
1814
1815 tr = op.gettransaction()
1815 tr = op.gettransaction()
1816 unpackerversion = inpart.params.get('version', '01')
1816 unpackerversion = inpart.params.get('version', '01')
1817 # We should raise an appropriate exception here
1817 # We should raise an appropriate exception here
1818 cg = changegroup.getunbundler(unpackerversion, inpart, None)
1818 cg = changegroup.getunbundler(unpackerversion, inpart, None)
1819 # the source and url passed here are overwritten by the one contained in
1819 # the source and url passed here are overwritten by the one contained in
1820 # the transaction.hookargs argument. So 'bundle2' is a placeholder
1820 # the transaction.hookargs argument. So 'bundle2' is a placeholder
1821 nbchangesets = None
1821 nbchangesets = None
1822 if 'nbchanges' in inpart.params:
1822 if 'nbchanges' in inpart.params:
1823 nbchangesets = int(inpart.params.get('nbchanges'))
1823 nbchangesets = int(inpart.params.get('nbchanges'))
1824 if ('treemanifest' in inpart.params and
1824 if ('treemanifest' in inpart.params and
1825 'treemanifest' not in op.repo.requirements):
1825 'treemanifest' not in op.repo.requirements):
1826 if len(op.repo.changelog) != 0:
1826 if len(op.repo.changelog) != 0:
1827 raise error.Abort(_(
1827 raise error.Abort(_(
1828 "bundle contains tree manifests, but local repo is "
1828 "bundle contains tree manifests, but local repo is "
1829 "non-empty and does not use tree manifests"))
1829 "non-empty and does not use tree manifests"))
1830 op.repo.requirements.add('treemanifest')
1830 op.repo.requirements.add('treemanifest')
1831 op.repo.svfs.options = localrepo.resolvestorevfsoptions(
1831 op.repo.svfs.options = localrepo.resolvestorevfsoptions(
1832 op.repo.ui, op.repo.requirements, op.repo.features)
1832 op.repo.ui, op.repo.requirements, op.repo.features)
1833 op.repo._writerequirements()
1833 op.repo._writerequirements()
1834 extrakwargs = {}
1834 extrakwargs = {}
1835 targetphase = inpart.params.get('targetphase')
1835 targetphase = inpart.params.get('targetphase')
1836 if targetphase is not None:
1836 if targetphase is not None:
1837 extrakwargs[r'targetphase'] = int(targetphase)
1837 extrakwargs[r'targetphase'] = int(targetphase)
1838 ret = _processchangegroup(op, cg, tr, 'bundle2', 'bundle2',
1838 ret = _processchangegroup(op, cg, tr, 'bundle2', 'bundle2',
1839 expectedtotal=nbchangesets, **extrakwargs)
1839 expectedtotal=nbchangesets, **extrakwargs)
1840 if op.reply is not None:
1840 if op.reply is not None:
1841 # This is definitely not the final form of this
1841 # This is definitely not the final form of this
1842 # return. But one need to start somewhere.
1842 # return. But one need to start somewhere.
1843 part = op.reply.newpart('reply:changegroup', mandatory=False)
1843 part = op.reply.newpart('reply:changegroup', mandatory=False)
1844 part.addparam(
1844 part.addparam(
1845 'in-reply-to', pycompat.bytestr(inpart.id), mandatory=False)
1845 'in-reply-to', pycompat.bytestr(inpart.id), mandatory=False)
1846 part.addparam('return', '%i' % ret, mandatory=False)
1846 part.addparam('return', '%i' % ret, mandatory=False)
1847 assert not inpart.read()
1847 assert not inpart.read()
1848
1848
1849 _remotechangegroupparams = tuple(['url', 'size', 'digests'] +
1849 _remotechangegroupparams = tuple(['url', 'size', 'digests'] +
1850 ['digest:%s' % k for k in util.DIGESTS.keys()])
1850 ['digest:%s' % k for k in util.DIGESTS.keys()])
1851 @parthandler('remote-changegroup', _remotechangegroupparams)
1851 @parthandler('remote-changegroup', _remotechangegroupparams)
1852 def handleremotechangegroup(op, inpart):
1852 def handleremotechangegroup(op, inpart):
1853 """apply a bundle10 on the repo, given an url and validation information
1853 """apply a bundle10 on the repo, given an url and validation information
1854
1854
1855 All the information about the remote bundle to import are given as
1855 All the information about the remote bundle to import are given as
1856 parameters. The parameters include:
1856 parameters. The parameters include:
1857 - url: the url to the bundle10.
1857 - url: the url to the bundle10.
1858 - size: the bundle10 file size. It is used to validate what was
1858 - size: the bundle10 file size. It is used to validate what was
1859 retrieved by the client matches the server knowledge about the bundle.
1859 retrieved by the client matches the server knowledge about the bundle.
1860 - digests: a space separated list of the digest types provided as
1860 - digests: a space separated list of the digest types provided as
1861 parameters.
1861 parameters.
1862 - digest:<digest-type>: the hexadecimal representation of the digest with
1862 - digest:<digest-type>: the hexadecimal representation of the digest with
1863 that name. Like the size, it is used to validate what was retrieved by
1863 that name. Like the size, it is used to validate what was retrieved by
1864 the client matches what the server knows about the bundle.
1864 the client matches what the server knows about the bundle.
1865
1865
1866 When multiple digest types are given, all of them are checked.
1866 When multiple digest types are given, all of them are checked.
1867 """
1867 """
1868 try:
1868 try:
1869 raw_url = inpart.params['url']
1869 raw_url = inpart.params['url']
1870 except KeyError:
1870 except KeyError:
1871 raise error.Abort(_('remote-changegroup: missing "%s" param') % 'url')
1871 raise error.Abort(_('remote-changegroup: missing "%s" param') % 'url')
1872 parsed_url = util.url(raw_url)
1872 parsed_url = util.url(raw_url)
1873 if parsed_url.scheme not in capabilities['remote-changegroup']:
1873 if parsed_url.scheme not in capabilities['remote-changegroup']:
1874 raise error.Abort(_('remote-changegroup does not support %s urls') %
1874 raise error.Abort(_('remote-changegroup does not support %s urls') %
1875 parsed_url.scheme)
1875 parsed_url.scheme)
1876
1876
1877 try:
1877 try:
1878 size = int(inpart.params['size'])
1878 size = int(inpart.params['size'])
1879 except ValueError:
1879 except ValueError:
1880 raise error.Abort(_('remote-changegroup: invalid value for param "%s"')
1880 raise error.Abort(_('remote-changegroup: invalid value for param "%s"')
1881 % 'size')
1881 % 'size')
1882 except KeyError:
1882 except KeyError:
1883 raise error.Abort(_('remote-changegroup: missing "%s" param') % 'size')
1883 raise error.Abort(_('remote-changegroup: missing "%s" param') % 'size')
1884
1884
1885 digests = {}
1885 digests = {}
1886 for typ in inpart.params.get('digests', '').split():
1886 for typ in inpart.params.get('digests', '').split():
1887 param = 'digest:%s' % typ
1887 param = 'digest:%s' % typ
1888 try:
1888 try:
1889 value = inpart.params[param]
1889 value = inpart.params[param]
1890 except KeyError:
1890 except KeyError:
1891 raise error.Abort(_('remote-changegroup: missing "%s" param') %
1891 raise error.Abort(_('remote-changegroup: missing "%s" param') %
1892 param)
1892 param)
1893 digests[typ] = value
1893 digests[typ] = value
1894
1894
1895 real_part = util.digestchecker(url.open(op.ui, raw_url), size, digests)
1895 real_part = util.digestchecker(url.open(op.ui, raw_url), size, digests)
1896
1896
1897 tr = op.gettransaction()
1897 tr = op.gettransaction()
1898 from . import exchange
1898 from . import exchange
1899 cg = exchange.readbundle(op.repo.ui, real_part, raw_url)
1899 cg = exchange.readbundle(op.repo.ui, real_part, raw_url)
1900 if not isinstance(cg, changegroup.cg1unpacker):
1900 if not isinstance(cg, changegroup.cg1unpacker):
1901 raise error.Abort(_('%s: not a bundle version 1.0') %
1901 raise error.Abort(_('%s: not a bundle version 1.0') %
1902 util.hidepassword(raw_url))
1902 util.hidepassword(raw_url))
1903 ret = _processchangegroup(op, cg, tr, 'bundle2', 'bundle2')
1903 ret = _processchangegroup(op, cg, tr, 'bundle2', 'bundle2')
1904 if op.reply is not None:
1904 if op.reply is not None:
1905 # This is definitely not the final form of this
1905 # This is definitely not the final form of this
1906 # return. But one need to start somewhere.
1906 # return. But one need to start somewhere.
1907 part = op.reply.newpart('reply:changegroup')
1907 part = op.reply.newpart('reply:changegroup')
1908 part.addparam(
1908 part.addparam(
1909 'in-reply-to', pycompat.bytestr(inpart.id), mandatory=False)
1909 'in-reply-to', pycompat.bytestr(inpart.id), mandatory=False)
1910 part.addparam('return', '%i' % ret, mandatory=False)
1910 part.addparam('return', '%i' % ret, mandatory=False)
1911 try:
1911 try:
1912 real_part.validate()
1912 real_part.validate()
1913 except error.Abort as e:
1913 except error.Abort as e:
1914 raise error.Abort(_('bundle at %s is corrupted:\n%s') %
1914 raise error.Abort(_('bundle at %s is corrupted:\n%s') %
1915 (util.hidepassword(raw_url), bytes(e)))
1915 (util.hidepassword(raw_url), bytes(e)))
1916 assert not inpart.read()
1916 assert not inpart.read()
1917
1917
1918 @parthandler('reply:changegroup', ('return', 'in-reply-to'))
1918 @parthandler('reply:changegroup', ('return', 'in-reply-to'))
1919 def handlereplychangegroup(op, inpart):
1919 def handlereplychangegroup(op, inpart):
1920 ret = int(inpart.params['return'])
1920 ret = int(inpart.params['return'])
1921 replyto = int(inpart.params['in-reply-to'])
1921 replyto = int(inpart.params['in-reply-to'])
1922 op.records.add('changegroup', {'return': ret}, replyto)
1922 op.records.add('changegroup', {'return': ret}, replyto)
1923
1923
1924 @parthandler('check:bookmarks')
1924 @parthandler('check:bookmarks')
1925 def handlecheckbookmarks(op, inpart):
1925 def handlecheckbookmarks(op, inpart):
1926 """check location of bookmarks
1926 """check location of bookmarks
1927
1927
1928 This part is to be used to detect push race regarding bookmark, it
1928 This part is to be used to detect push race regarding bookmark, it
1929 contains binary encoded (bookmark, node) tuple. If the local state does
1929 contains binary encoded (bookmark, node) tuple. If the local state does
1930 not marks the one in the part, a PushRaced exception is raised
1930 not marks the one in the part, a PushRaced exception is raised
1931 """
1931 """
1932 bookdata = bookmarks.binarydecode(inpart)
1932 bookdata = bookmarks.binarydecode(inpart)
1933
1933
1934 msgstandard = ('remote repository changed while pushing - please try again '
1934 msgstandard = ('remote repository changed while pushing - please try again '
1935 '(bookmark "%s" move from %s to %s)')
1935 '(bookmark "%s" move from %s to %s)')
1936 msgmissing = ('remote repository changed while pushing - please try again '
1936 msgmissing = ('remote repository changed while pushing - please try again '
1937 '(bookmark "%s" is missing, expected %s)')
1937 '(bookmark "%s" is missing, expected %s)')
1938 msgexist = ('remote repository changed while pushing - please try again '
1938 msgexist = ('remote repository changed while pushing - please try again '
1939 '(bookmark "%s" set on %s, expected missing)')
1939 '(bookmark "%s" set on %s, expected missing)')
1940 for book, node in bookdata:
1940 for book, node in bookdata:
1941 currentnode = op.repo._bookmarks.get(book)
1941 currentnode = op.repo._bookmarks.get(book)
1942 if currentnode != node:
1942 if currentnode != node:
1943 if node is None:
1943 if node is None:
1944 finalmsg = msgexist % (book, nodemod.short(currentnode))
1944 finalmsg = msgexist % (book, nodemod.short(currentnode))
1945 elif currentnode is None:
1945 elif currentnode is None:
1946 finalmsg = msgmissing % (book, nodemod.short(node))
1946 finalmsg = msgmissing % (book, nodemod.short(node))
1947 else:
1947 else:
1948 finalmsg = msgstandard % (book, nodemod.short(node),
1948 finalmsg = msgstandard % (book, nodemod.short(node),
1949 nodemod.short(currentnode))
1949 nodemod.short(currentnode))
1950 raise error.PushRaced(finalmsg)
1950 raise error.PushRaced(finalmsg)
1951
1951
1952 @parthandler('check:heads')
1952 @parthandler('check:heads')
1953 def handlecheckheads(op, inpart):
1953 def handlecheckheads(op, inpart):
1954 """check that head of the repo did not change
1954 """check that head of the repo did not change
1955
1955
1956 This is used to detect a push race when using unbundle.
1956 This is used to detect a push race when using unbundle.
1957 This replaces the "heads" argument of unbundle."""
1957 This replaces the "heads" argument of unbundle."""
1958 h = inpart.read(20)
1958 h = inpart.read(20)
1959 heads = []
1959 heads = []
1960 while len(h) == 20:
1960 while len(h) == 20:
1961 heads.append(h)
1961 heads.append(h)
1962 h = inpart.read(20)
1962 h = inpart.read(20)
1963 assert not h
1963 assert not h
1964 # Trigger a transaction so that we are guaranteed to have the lock now.
1964 # Trigger a transaction so that we are guaranteed to have the lock now.
1965 if op.ui.configbool('experimental', 'bundle2lazylocking'):
1965 if op.ui.configbool('experimental', 'bundle2lazylocking'):
1966 op.gettransaction()
1966 op.gettransaction()
1967 if sorted(heads) != sorted(op.repo.heads()):
1967 if sorted(heads) != sorted(op.repo.heads()):
1968 raise error.PushRaced('remote repository changed while pushing - '
1968 raise error.PushRaced('remote repository changed while pushing - '
1969 'please try again')
1969 'please try again')
1970
1970
1971 @parthandler('check:updated-heads')
1971 @parthandler('check:updated-heads')
1972 def handlecheckupdatedheads(op, inpart):
1972 def handlecheckupdatedheads(op, inpart):
1973 """check for race on the heads touched by a push
1973 """check for race on the heads touched by a push
1974
1974
1975 This is similar to 'check:heads' but focus on the heads actually updated
1975 This is similar to 'check:heads' but focus on the heads actually updated
1976 during the push. If other activities happen on unrelated heads, it is
1976 during the push. If other activities happen on unrelated heads, it is
1977 ignored.
1977 ignored.
1978
1978
1979 This allow server with high traffic to avoid push contention as long as
1979 This allow server with high traffic to avoid push contention as long as
1980 unrelated parts of the graph are involved."""
1980 unrelated parts of the graph are involved."""
1981 h = inpart.read(20)
1981 h = inpart.read(20)
1982 heads = []
1982 heads = []
1983 while len(h) == 20:
1983 while len(h) == 20:
1984 heads.append(h)
1984 heads.append(h)
1985 h = inpart.read(20)
1985 h = inpart.read(20)
1986 assert not h
1986 assert not h
1987 # trigger a transaction so that we are guaranteed to have the lock now.
1987 # trigger a transaction so that we are guaranteed to have the lock now.
1988 if op.ui.configbool('experimental', 'bundle2lazylocking'):
1988 if op.ui.configbool('experimental', 'bundle2lazylocking'):
1989 op.gettransaction()
1989 op.gettransaction()
1990
1990
1991 currentheads = set()
1991 currentheads = set()
1992 for ls in op.repo.branchmap().iterheads():
1992 for ls in op.repo.branchmap().iterheads():
1993 currentheads.update(ls)
1993 currentheads.update(ls)
1994
1994
1995 for h in heads:
1995 for h in heads:
1996 if h not in currentheads:
1996 if h not in currentheads:
1997 raise error.PushRaced('remote repository changed while pushing - '
1997 raise error.PushRaced('remote repository changed while pushing - '
1998 'please try again')
1998 'please try again')
1999
1999
2000 @parthandler('check:phases')
2000 @parthandler('check:phases')
2001 def handlecheckphases(op, inpart):
2001 def handlecheckphases(op, inpart):
2002 """check that phase boundaries of the repository did not change
2002 """check that phase boundaries of the repository did not change
2003
2003
2004 This is used to detect a push race.
2004 This is used to detect a push race.
2005 """
2005 """
2006 phasetonodes = phases.binarydecode(inpart)
2006 phasetonodes = phases.binarydecode(inpart)
2007 unfi = op.repo.unfiltered()
2007 unfi = op.repo.unfiltered()
2008 cl = unfi.changelog
2008 cl = unfi.changelog
2009 phasecache = unfi._phasecache
2009 phasecache = unfi._phasecache
2010 msg = ('remote repository changed while pushing - please try again '
2010 msg = ('remote repository changed while pushing - please try again '
2011 '(%s is %s expected %s)')
2011 '(%s is %s expected %s)')
2012 for expectedphase, nodes in enumerate(phasetonodes):
2012 for expectedphase, nodes in enumerate(phasetonodes):
2013 for n in nodes:
2013 for n in nodes:
2014 actualphase = phasecache.phase(unfi, cl.rev(n))
2014 actualphase = phasecache.phase(unfi, cl.rev(n))
2015 if actualphase != expectedphase:
2015 if actualphase != expectedphase:
2016 finalmsg = msg % (nodemod.short(n),
2016 finalmsg = msg % (nodemod.short(n),
2017 phases.phasenames[actualphase],
2017 phases.phasenames[actualphase],
2018 phases.phasenames[expectedphase])
2018 phases.phasenames[expectedphase])
2019 raise error.PushRaced(finalmsg)
2019 raise error.PushRaced(finalmsg)
2020
2020
2021 @parthandler('output')
2021 @parthandler('output')
2022 def handleoutput(op, inpart):
2022 def handleoutput(op, inpart):
2023 """forward output captured on the server to the client"""
2023 """forward output captured on the server to the client"""
2024 for line in inpart.read().splitlines():
2024 for line in inpart.read().splitlines():
2025 op.ui.status(_('remote: %s\n') % line)
2025 op.ui.status(_('remote: %s\n') % line)
2026
2026
2027 @parthandler('replycaps')
2027 @parthandler('replycaps')
2028 def handlereplycaps(op, inpart):
2028 def handlereplycaps(op, inpart):
2029 """Notify that a reply bundle should be created
2029 """Notify that a reply bundle should be created
2030
2030
2031 The payload contains the capabilities information for the reply"""
2031 The payload contains the capabilities information for the reply"""
2032 caps = decodecaps(inpart.read())
2032 caps = decodecaps(inpart.read())
2033 if op.reply is None:
2033 if op.reply is None:
2034 op.reply = bundle20(op.ui, caps)
2034 op.reply = bundle20(op.ui, caps)
2035
2035
2036 class AbortFromPart(error.Abort):
2036 class AbortFromPart(error.Abort):
2037 """Sub-class of Abort that denotes an error from a bundle2 part."""
2037 """Sub-class of Abort that denotes an error from a bundle2 part."""
2038
2038
2039 @parthandler('error:abort', ('message', 'hint'))
2039 @parthandler('error:abort', ('message', 'hint'))
2040 def handleerrorabort(op, inpart):
2040 def handleerrorabort(op, inpart):
2041 """Used to transmit abort error over the wire"""
2041 """Used to transmit abort error over the wire"""
2042 raise AbortFromPart(inpart.params['message'],
2042 raise AbortFromPart(inpart.params['message'],
2043 hint=inpart.params.get('hint'))
2043 hint=inpart.params.get('hint'))
2044
2044
2045 @parthandler('error:pushkey', ('namespace', 'key', 'new', 'old', 'ret',
2045 @parthandler('error:pushkey', ('namespace', 'key', 'new', 'old', 'ret',
2046 'in-reply-to'))
2046 'in-reply-to'))
2047 def handleerrorpushkey(op, inpart):
2047 def handleerrorpushkey(op, inpart):
2048 """Used to transmit failure of a mandatory pushkey over the wire"""
2048 """Used to transmit failure of a mandatory pushkey over the wire"""
2049 kwargs = {}
2049 kwargs = {}
2050 for name in ('namespace', 'key', 'new', 'old', 'ret'):
2050 for name in ('namespace', 'key', 'new', 'old', 'ret'):
2051 value = inpart.params.get(name)
2051 value = inpart.params.get(name)
2052 if value is not None:
2052 if value is not None:
2053 kwargs[name] = value
2053 kwargs[name] = value
2054 raise error.PushkeyFailed(inpart.params['in-reply-to'],
2054 raise error.PushkeyFailed(inpart.params['in-reply-to'],
2055 **pycompat.strkwargs(kwargs))
2055 **pycompat.strkwargs(kwargs))
2056
2056
2057 @parthandler('error:unsupportedcontent', ('parttype', 'params'))
2057 @parthandler('error:unsupportedcontent', ('parttype', 'params'))
2058 def handleerrorunsupportedcontent(op, inpart):
2058 def handleerrorunsupportedcontent(op, inpart):
2059 """Used to transmit unknown content error over the wire"""
2059 """Used to transmit unknown content error over the wire"""
2060 kwargs = {}
2060 kwargs = {}
2061 parttype = inpart.params.get('parttype')
2061 parttype = inpart.params.get('parttype')
2062 if parttype is not None:
2062 if parttype is not None:
2063 kwargs['parttype'] = parttype
2063 kwargs['parttype'] = parttype
2064 params = inpart.params.get('params')
2064 params = inpart.params.get('params')
2065 if params is not None:
2065 if params is not None:
2066 kwargs['params'] = params.split('\0')
2066 kwargs['params'] = params.split('\0')
2067
2067
2068 raise error.BundleUnknownFeatureError(**pycompat.strkwargs(kwargs))
2068 raise error.BundleUnknownFeatureError(**pycompat.strkwargs(kwargs))
2069
2069
2070 @parthandler('error:pushraced', ('message',))
2070 @parthandler('error:pushraced', ('message',))
2071 def handleerrorpushraced(op, inpart):
2071 def handleerrorpushraced(op, inpart):
2072 """Used to transmit push race error over the wire"""
2072 """Used to transmit push race error over the wire"""
2073 raise error.ResponseError(_('push failed:'), inpart.params['message'])
2073 raise error.ResponseError(_('push failed:'), inpart.params['message'])
2074
2074
2075 @parthandler('listkeys', ('namespace',))
2075 @parthandler('listkeys', ('namespace',))
2076 def handlelistkeys(op, inpart):
2076 def handlelistkeys(op, inpart):
2077 """retrieve pushkey namespace content stored in a bundle2"""
2077 """retrieve pushkey namespace content stored in a bundle2"""
2078 namespace = inpart.params['namespace']
2078 namespace = inpart.params['namespace']
2079 r = pushkey.decodekeys(inpart.read())
2079 r = pushkey.decodekeys(inpart.read())
2080 op.records.add('listkeys', (namespace, r))
2080 op.records.add('listkeys', (namespace, r))
2081
2081
2082 @parthandler('pushkey', ('namespace', 'key', 'old', 'new'))
2082 @parthandler('pushkey', ('namespace', 'key', 'old', 'new'))
2083 def handlepushkey(op, inpart):
2083 def handlepushkey(op, inpart):
2084 """process a pushkey request"""
2084 """process a pushkey request"""
2085 dec = pushkey.decode
2085 dec = pushkey.decode
2086 namespace = dec(inpart.params['namespace'])
2086 namespace = dec(inpart.params['namespace'])
2087 key = dec(inpart.params['key'])
2087 key = dec(inpart.params['key'])
2088 old = dec(inpart.params['old'])
2088 old = dec(inpart.params['old'])
2089 new = dec(inpart.params['new'])
2089 new = dec(inpart.params['new'])
2090 # Grab the transaction to ensure that we have the lock before performing the
2090 # Grab the transaction to ensure that we have the lock before performing the
2091 # pushkey.
2091 # pushkey.
2092 if op.ui.configbool('experimental', 'bundle2lazylocking'):
2092 if op.ui.configbool('experimental', 'bundle2lazylocking'):
2093 op.gettransaction()
2093 op.gettransaction()
2094 ret = op.repo.pushkey(namespace, key, old, new)
2094 ret = op.repo.pushkey(namespace, key, old, new)
2095 record = {'namespace': namespace,
2095 record = {'namespace': namespace,
2096 'key': key,
2096 'key': key,
2097 'old': old,
2097 'old': old,
2098 'new': new}
2098 'new': new}
2099 op.records.add('pushkey', record)
2099 op.records.add('pushkey', record)
2100 if op.reply is not None:
2100 if op.reply is not None:
2101 rpart = op.reply.newpart('reply:pushkey')
2101 rpart = op.reply.newpart('reply:pushkey')
2102 rpart.addparam(
2102 rpart.addparam(
2103 'in-reply-to', pycompat.bytestr(inpart.id), mandatory=False)
2103 'in-reply-to', pycompat.bytestr(inpart.id), mandatory=False)
2104 rpart.addparam('return', '%i' % ret, mandatory=False)
2104 rpart.addparam('return', '%i' % ret, mandatory=False)
2105 if inpart.mandatory and not ret:
2105 if inpart.mandatory and not ret:
2106 kwargs = {}
2106 kwargs = {}
2107 for key in ('namespace', 'key', 'new', 'old', 'ret'):
2107 for key in ('namespace', 'key', 'new', 'old', 'ret'):
2108 if key in inpart.params:
2108 if key in inpart.params:
2109 kwargs[key] = inpart.params[key]
2109 kwargs[key] = inpart.params[key]
2110 raise error.PushkeyFailed(partid='%d' % inpart.id,
2110 raise error.PushkeyFailed(partid='%d' % inpart.id,
2111 **pycompat.strkwargs(kwargs))
2111 **pycompat.strkwargs(kwargs))
2112
2112
2113 @parthandler('bookmarks')
2113 @parthandler('bookmarks')
2114 def handlebookmark(op, inpart):
2114 def handlebookmark(op, inpart):
2115 """transmit bookmark information
2115 """transmit bookmark information
2116
2116
2117 The part contains binary encoded bookmark information.
2117 The part contains binary encoded bookmark information.
2118
2118
2119 The exact behavior of this part can be controlled by the 'bookmarks' mode
2119 The exact behavior of this part can be controlled by the 'bookmarks' mode
2120 on the bundle operation.
2120 on the bundle operation.
2121
2121
2122 When mode is 'apply' (the default) the bookmark information is applied as
2122 When mode is 'apply' (the default) the bookmark information is applied as
2123 is to the unbundling repository. Make sure a 'check:bookmarks' part is
2123 is to the unbundling repository. Make sure a 'check:bookmarks' part is
2124 issued earlier to check for push races in such update. This behavior is
2124 issued earlier to check for push races in such update. This behavior is
2125 suitable for pushing.
2125 suitable for pushing.
2126
2126
2127 When mode is 'records', the information is recorded into the 'bookmarks'
2127 When mode is 'records', the information is recorded into the 'bookmarks'
2128 records of the bundle operation. This behavior is suitable for pulling.
2128 records of the bundle operation. This behavior is suitable for pulling.
2129 """
2129 """
2130 changes = bookmarks.binarydecode(inpart)
2130 changes = bookmarks.binarydecode(inpart)
2131
2131
2132 pushkeycompat = op.repo.ui.configbool('server', 'bookmarks-pushkey-compat')
2132 pushkeycompat = op.repo.ui.configbool('server', 'bookmarks-pushkey-compat')
2133 bookmarksmode = op.modes.get('bookmarks', 'apply')
2133 bookmarksmode = op.modes.get('bookmarks', 'apply')
2134
2134
2135 if bookmarksmode == 'apply':
2135 if bookmarksmode == 'apply':
2136 tr = op.gettransaction()
2136 tr = op.gettransaction()
2137 bookstore = op.repo._bookmarks
2137 bookstore = op.repo._bookmarks
2138 if pushkeycompat:
2138 if pushkeycompat:
2139 allhooks = []
2139 allhooks = []
2140 for book, node in changes:
2140 for book, node in changes:
2141 hookargs = tr.hookargs.copy()
2141 hookargs = tr.hookargs.copy()
2142 hookargs['pushkeycompat'] = '1'
2142 hookargs['pushkeycompat'] = '1'
2143 hookargs['namespace'] = 'bookmarks'
2143 hookargs['namespace'] = 'bookmarks'
2144 hookargs['key'] = book
2144 hookargs['key'] = book
2145 hookargs['old'] = nodemod.hex(bookstore.get(book, ''))
2145 hookargs['old'] = nodemod.hex(bookstore.get(book, ''))
2146 hookargs['new'] = nodemod.hex(node if node is not None else '')
2146 hookargs['new'] = nodemod.hex(node if node is not None else '')
2147 allhooks.append(hookargs)
2147 allhooks.append(hookargs)
2148
2148
2149 for hookargs in allhooks:
2149 for hookargs in allhooks:
2150 op.repo.hook('prepushkey', throw=True,
2150 op.repo.hook('prepushkey', throw=True,
2151 **pycompat.strkwargs(hookargs))
2151 **pycompat.strkwargs(hookargs))
2152
2152
2153 bookstore.applychanges(op.repo, op.gettransaction(), changes)
2153 bookstore.applychanges(op.repo, op.gettransaction(), changes)
2154
2154
2155 if pushkeycompat:
2155 if pushkeycompat:
2156 def runhook():
2156 def runhook():
2157 for hookargs in allhooks:
2157 for hookargs in allhooks:
2158 op.repo.hook('pushkey', **pycompat.strkwargs(hookargs))
2158 op.repo.hook('pushkey', **pycompat.strkwargs(hookargs))
2159 op.repo._afterlock(runhook)
2159 op.repo._afterlock(runhook)
2160
2160
2161 elif bookmarksmode == 'records':
2161 elif bookmarksmode == 'records':
2162 for book, node in changes:
2162 for book, node in changes:
2163 record = {'bookmark': book, 'node': node}
2163 record = {'bookmark': book, 'node': node}
2164 op.records.add('bookmarks', record)
2164 op.records.add('bookmarks', record)
2165 else:
2165 else:
2166 raise error.ProgrammingError('unkown bookmark mode: %s' % bookmarksmode)
2166 raise error.ProgrammingError('unkown bookmark mode: %s' % bookmarksmode)
2167
2167
2168 @parthandler('phase-heads')
2168 @parthandler('phase-heads')
2169 def handlephases(op, inpart):
2169 def handlephases(op, inpart):
2170 """apply phases from bundle part to repo"""
2170 """apply phases from bundle part to repo"""
2171 headsbyphase = phases.binarydecode(inpart)
2171 headsbyphase = phases.binarydecode(inpart)
2172 phases.updatephases(op.repo.unfiltered(), op.gettransaction, headsbyphase)
2172 phases.updatephases(op.repo.unfiltered(), op.gettransaction, headsbyphase)
2173
2173
2174 @parthandler('reply:pushkey', ('return', 'in-reply-to'))
2174 @parthandler('reply:pushkey', ('return', 'in-reply-to'))
2175 def handlepushkeyreply(op, inpart):
2175 def handlepushkeyreply(op, inpart):
2176 """retrieve the result of a pushkey request"""
2176 """retrieve the result of a pushkey request"""
2177 ret = int(inpart.params['return'])
2177 ret = int(inpart.params['return'])
2178 partid = int(inpart.params['in-reply-to'])
2178 partid = int(inpart.params['in-reply-to'])
2179 op.records.add('pushkey', {'return': ret}, partid)
2179 op.records.add('pushkey', {'return': ret}, partid)
2180
2180
2181 @parthandler('obsmarkers')
2181 @parthandler('obsmarkers')
2182 def handleobsmarker(op, inpart):
2182 def handleobsmarker(op, inpart):
2183 """add a stream of obsmarkers to the repo"""
2183 """add a stream of obsmarkers to the repo"""
2184 tr = op.gettransaction()
2184 tr = op.gettransaction()
2185 markerdata = inpart.read()
2185 markerdata = inpart.read()
2186 if op.ui.config('experimental', 'obsmarkers-exchange-debug'):
2186 if op.ui.config('experimental', 'obsmarkers-exchange-debug'):
2187 op.ui.write(('obsmarker-exchange: %i bytes received\n')
2187 op.ui.write(('obsmarker-exchange: %i bytes received\n')
2188 % len(markerdata))
2188 % len(markerdata))
2189 # The mergemarkers call will crash if marker creation is not enabled.
2189 # The mergemarkers call will crash if marker creation is not enabled.
2190 # we want to avoid this if the part is advisory.
2190 # we want to avoid this if the part is advisory.
2191 if not inpart.mandatory and op.repo.obsstore.readonly:
2191 if not inpart.mandatory and op.repo.obsstore.readonly:
2192 op.repo.ui.debug('ignoring obsolescence markers, feature not enabled\n')
2192 op.repo.ui.debug('ignoring obsolescence markers, feature not enabled\n')
2193 return
2193 return
2194 new = op.repo.obsstore.mergemarkers(tr, markerdata)
2194 new = op.repo.obsstore.mergemarkers(tr, markerdata)
2195 op.repo.invalidatevolatilesets()
2195 op.repo.invalidatevolatilesets()
2196 op.records.add('obsmarkers', {'new': new})
2196 op.records.add('obsmarkers', {'new': new})
2197 if op.reply is not None:
2197 if op.reply is not None:
2198 rpart = op.reply.newpart('reply:obsmarkers')
2198 rpart = op.reply.newpart('reply:obsmarkers')
2199 rpart.addparam(
2199 rpart.addparam(
2200 'in-reply-to', pycompat.bytestr(inpart.id), mandatory=False)
2200 'in-reply-to', pycompat.bytestr(inpart.id), mandatory=False)
2201 rpart.addparam('new', '%i' % new, mandatory=False)
2201 rpart.addparam('new', '%i' % new, mandatory=False)
2202
2202
2203
2203
2204 @parthandler('reply:obsmarkers', ('new', 'in-reply-to'))
2204 @parthandler('reply:obsmarkers', ('new', 'in-reply-to'))
2205 def handleobsmarkerreply(op, inpart):
2205 def handleobsmarkerreply(op, inpart):
2206 """retrieve the result of a pushkey request"""
2206 """retrieve the result of a pushkey request"""
2207 ret = int(inpart.params['new'])
2207 ret = int(inpart.params['new'])
2208 partid = int(inpart.params['in-reply-to'])
2208 partid = int(inpart.params['in-reply-to'])
2209 op.records.add('obsmarkers', {'new': ret}, partid)
2209 op.records.add('obsmarkers', {'new': ret}, partid)
2210
2210
2211 @parthandler('hgtagsfnodes')
2211 @parthandler('hgtagsfnodes')
2212 def handlehgtagsfnodes(op, inpart):
2212 def handlehgtagsfnodes(op, inpart):
2213 """Applies .hgtags fnodes cache entries to the local repo.
2213 """Applies .hgtags fnodes cache entries to the local repo.
2214
2214
2215 Payload is pairs of 20 byte changeset nodes and filenodes.
2215 Payload is pairs of 20 byte changeset nodes and filenodes.
2216 """
2216 """
2217 # Grab the transaction so we ensure that we have the lock at this point.
2217 # Grab the transaction so we ensure that we have the lock at this point.
2218 if op.ui.configbool('experimental', 'bundle2lazylocking'):
2218 if op.ui.configbool('experimental', 'bundle2lazylocking'):
2219 op.gettransaction()
2219 op.gettransaction()
2220 cache = tags.hgtagsfnodescache(op.repo.unfiltered())
2220 cache = tags.hgtagsfnodescache(op.repo.unfiltered())
2221
2221
2222 count = 0
2222 count = 0
2223 while True:
2223 while True:
2224 node = inpart.read(20)
2224 node = inpart.read(20)
2225 fnode = inpart.read(20)
2225 fnode = inpart.read(20)
2226 if len(node) < 20 or len(fnode) < 20:
2226 if len(node) < 20 or len(fnode) < 20:
2227 op.ui.debug('ignoring incomplete received .hgtags fnodes data\n')
2227 op.ui.debug('ignoring incomplete received .hgtags fnodes data\n')
2228 break
2228 break
2229 cache.setfnode(node, fnode)
2229 cache.setfnode(node, fnode)
2230 count += 1
2230 count += 1
2231
2231
2232 cache.write()
2232 cache.write()
2233 op.ui.debug('applied %i hgtags fnodes cache entries\n' % count)
2233 op.ui.debug('applied %i hgtags fnodes cache entries\n' % count)
2234
2234
2235 rbcstruct = struct.Struct('>III')
2235 rbcstruct = struct.Struct('>III')
2236
2236
2237 @parthandler('cache:rev-branch-cache')
2237 @parthandler('cache:rev-branch-cache')
2238 def handlerbc(op, inpart):
2238 def handlerbc(op, inpart):
2239 """receive a rev-branch-cache payload and update the local cache
2239 """receive a rev-branch-cache payload and update the local cache
2240
2240
2241 The payload is a series of data related to each branch
2241 The payload is a series of data related to each branch
2242
2242
2243 1) branch name length
2243 1) branch name length
2244 2) number of open heads
2244 2) number of open heads
2245 3) number of closed heads
2245 3) number of closed heads
2246 4) open heads nodes
2246 4) open heads nodes
2247 5) closed heads nodes
2247 5) closed heads nodes
2248 """
2248 """
2249 total = 0
2249 total = 0
2250 rawheader = inpart.read(rbcstruct.size)
2250 rawheader = inpart.read(rbcstruct.size)
2251 cache = op.repo.revbranchcache()
2251 cache = op.repo.revbranchcache()
2252 cl = op.repo.unfiltered().changelog
2252 cl = op.repo.unfiltered().changelog
2253 while rawheader:
2253 while rawheader:
2254 header = rbcstruct.unpack(rawheader)
2254 header = rbcstruct.unpack(rawheader)
2255 total += header[1] + header[2]
2255 total += header[1] + header[2]
2256 utf8branch = inpart.read(header[0])
2256 utf8branch = inpart.read(header[0])
2257 branch = encoding.tolocal(utf8branch)
2257 branch = encoding.tolocal(utf8branch)
2258 for x in pycompat.xrange(header[1]):
2258 for x in pycompat.xrange(header[1]):
2259 node = inpart.read(20)
2259 node = inpart.read(20)
2260 rev = cl.rev(node)
2260 rev = cl.rev(node)
2261 cache.setdata(branch, rev, node, False)
2261 cache.setdata(branch, rev, node, False)
2262 for x in pycompat.xrange(header[2]):
2262 for x in pycompat.xrange(header[2]):
2263 node = inpart.read(20)
2263 node = inpart.read(20)
2264 rev = cl.rev(node)
2264 rev = cl.rev(node)
2265 cache.setdata(branch, rev, node, True)
2265 cache.setdata(branch, rev, node, True)
2266 rawheader = inpart.read(rbcstruct.size)
2266 rawheader = inpart.read(rbcstruct.size)
2267 cache.write()
2267 cache.write()
2268
2268
2269 @parthandler('pushvars')
2269 @parthandler('pushvars')
2270 def bundle2getvars(op, part):
2270 def bundle2getvars(op, part):
2271 '''unbundle a bundle2 containing shellvars on the server'''
2271 '''unbundle a bundle2 containing shellvars on the server'''
2272 # An option to disable unbundling on server-side for security reasons
2272 # An option to disable unbundling on server-side for security reasons
2273 if op.ui.configbool('push', 'pushvars.server'):
2273 if op.ui.configbool('push', 'pushvars.server'):
2274 hookargs = {}
2274 hookargs = {}
2275 for key, value in part.advisoryparams:
2275 for key, value in part.advisoryparams:
2276 key = key.upper()
2276 key = key.upper()
2277 # We want pushed variables to have USERVAR_ prepended so we know
2277 # We want pushed variables to have USERVAR_ prepended so we know
2278 # they came from the --pushvar flag.
2278 # they came from the --pushvar flag.
2279 key = "USERVAR_" + key
2279 key = "USERVAR_" + key
2280 hookargs[key] = value
2280 hookargs[key] = value
2281 op.addhookargs(hookargs)
2281 op.addhookargs(hookargs)
2282
2282
2283 @parthandler('stream2', ('requirements', 'filecount', 'bytecount'))
2283 @parthandler('stream2', ('requirements', 'filecount', 'bytecount'))
2284 def handlestreamv2bundle(op, part):
2284 def handlestreamv2bundle(op, part):
2285
2285
2286 requirements = urlreq.unquote(part.params['requirements']).split(',')
2286 requirements = urlreq.unquote(part.params['requirements']).split(',')
2287 filecount = int(part.params['filecount'])
2287 filecount = int(part.params['filecount'])
2288 bytecount = int(part.params['bytecount'])
2288 bytecount = int(part.params['bytecount'])
2289
2289
2290 repo = op.repo
2290 repo = op.repo
2291 if len(repo):
2291 if len(repo):
2292 msg = _('cannot apply stream clone to non empty repository')
2292 msg = _('cannot apply stream clone to non empty repository')
2293 raise error.Abort(msg)
2293 raise error.Abort(msg)
2294
2294
2295 repo.ui.debug('applying stream bundle\n')
2295 repo.ui.debug('applying stream bundle\n')
2296 streamclone.applybundlev2(repo, part, filecount, bytecount,
2296 streamclone.applybundlev2(repo, part, filecount, bytecount,
2297 requirements)
2297 requirements)
2298
2298
2299 def widen_bundle(bundler, repo, oldmatcher, newmatcher, common,
2299 def widen_bundle(bundler, repo, oldmatcher, newmatcher, common,
2300 known, cgversion, ellipses):
2300 known, cgversion, ellipses):
2301 """generates bundle2 for widening a narrow clone
2301 """generates bundle2 for widening a narrow clone
2302
2302
2303 bundler is the bundle to which data should be added
2303 bundler is the bundle to which data should be added
2304 repo is the localrepository instance
2304 repo is the localrepository instance
2305 oldmatcher matches what the client already has
2305 oldmatcher matches what the client already has
2306 newmatcher matches what the client needs (including what it already has)
2306 newmatcher matches what the client needs (including what it already has)
2307 common is set of common heads between server and client
2307 common is set of common heads between server and client
2308 known is a set of revs known on the client side (used in ellipses)
2308 known is a set of revs known on the client side (used in ellipses)
2309 cgversion is the changegroup version to send
2309 cgversion is the changegroup version to send
2310 ellipses is boolean value telling whether to send ellipses data or not
2310 ellipses is boolean value telling whether to send ellipses data or not
2311
2311
2312 returns bundle2 of the data required for extending
2312 returns bundle2 of the data required for extending
2313 """
2313 """
2314 commonnodes = set()
2314 commonnodes = set()
2315 cl = repo.changelog
2315 cl = repo.changelog
2316 for r in repo.revs("::%ln", common):
2316 for r in repo.revs("::%ln", common):
2317 commonnodes.add(cl.node(r))
2317 commonnodes.add(cl.node(r))
2318 if commonnodes:
2318 if commonnodes:
2319 # XXX: we should only send the filelogs (and treemanifest). user
2319 # XXX: we should only send the filelogs (and treemanifest). user
2320 # already has the changelog and manifest
2320 # already has the changelog and manifest
2321 packer = changegroup.getbundler(cgversion, repo,
2321 packer = changegroup.getbundler(cgversion, repo,
2322 oldmatcher=oldmatcher,
2322 oldmatcher=oldmatcher,
2323 matcher=newmatcher,
2323 matcher=newmatcher,
2324 fullnodes=commonnodes)
2324 fullnodes=commonnodes)
2325 cgdata = packer.generate({nodemod.nullid}, list(commonnodes),
2325 cgdata = packer.generate({nodemod.nullid}, list(commonnodes),
2326 False, 'narrow_widen', changelog=False)
2326 False, 'narrow_widen', changelog=False)
2327
2327
2328 part = bundler.newpart('changegroup', data=cgdata)
2328 part = bundler.newpart('changegroup', data=cgdata)
2329 part.addparam('version', cgversion)
2329 part.addparam('version', cgversion)
2330 if 'treemanifest' in repo.requirements:
2330 if 'treemanifest' in repo.requirements:
2331 part.addparam('treemanifest', '1')
2331 part.addparam('treemanifest', '1')
2332
2332
2333 return bundler
2333 return bundler
@@ -1,2394 +1,2394 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" 205 bytes payload
112 bundle2-output-part: "replycaps" 205 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:heads" streamed payload
114 bundle2-output-part: "check: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 205
119 bundle2-input-part: total payload size 205
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:heads" supported
122 bundle2-input-part: "check: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: 4 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: 0 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 listing keys for "bookmarks"
170 listing keys for "bookmarks"
171 3 changesets found
171 3 changesets found
172 list of changesets:
172 list of changesets:
173 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
173 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
174 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
174 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
175 911600dab2ae7a9baff75958b84fe606851ce955
175 911600dab2ae7a9baff75958b84fe606851ce955
176 bundle2-output-bundle: "HG20", 5 parts total
176 bundle2-output-bundle: "HG20", 5 parts total
177 bundle2-output-part: "replycaps" 205 bytes payload
177 bundle2-output-part: "replycaps" 205 bytes payload
178 bundle2-output-part: "check:phases" 24 bytes payload
178 bundle2-output-part: "check:phases" 24 bytes payload
179 bundle2-output-part: "check:heads" streamed payload
179 bundle2-output-part: "check:heads" streamed payload
180 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
180 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
181 bundle2-output-part: "phase-heads" 24 bytes payload
181 bundle2-output-part: "phase-heads" 24 bytes payload
182 bundle2-input-bundle: with-transaction
182 bundle2-input-bundle: with-transaction
183 bundle2-input-part: "replycaps" supported
183 bundle2-input-part: "replycaps" supported
184 bundle2-input-part: total payload size 205
184 bundle2-input-part: total payload size 205
185 bundle2-input-part: "check:phases" supported
185 bundle2-input-part: "check:phases" supported
186 bundle2-input-part: total payload size 24
186 bundle2-input-part: total payload size 24
187 bundle2-input-part: "check:heads" supported
187 bundle2-input-part: "check:heads" supported
188 bundle2-input-part: total payload size 20
188 bundle2-input-part: total payload size 20
189 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
189 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
190 adding changesets
190 adding changesets
191 add changeset ef1ea85a6374
191 add changeset ef1ea85a6374
192 add changeset f9cafe1212c8
192 add changeset f9cafe1212c8
193 add changeset 911600dab2ae
193 add changeset 911600dab2ae
194 adding manifests
194 adding manifests
195 adding file changes
195 adding file changes
196 adding foo/Bar/file.txt revisions
196 adding foo/Bar/file.txt revisions
197 adding foo/file.txt revisions
197 adding foo/file.txt revisions
198 adding quux/file.py revisions
198 adding quux/file.py revisions
199 calling hook pretxnchangegroup.acl: hgext.acl.hook
199 calling hook pretxnchangegroup.acl: hgext.acl.hook
200 acl: changes have source "push" - skipping
200 acl: changes have source "push" - skipping
201 bundle2-input-part: total payload size 1553
201 bundle2-input-part: total payload size 1553
202 bundle2-input-part: "phase-heads" supported
202 bundle2-input-part: "phase-heads" supported
203 bundle2-input-part: total payload size 24
203 bundle2-input-part: total payload size 24
204 bundle2-input-bundle: 4 parts total
204 bundle2-input-bundle: 5 parts total
205 updating the branch cache
205 updating the branch cache
206 added 3 changesets with 3 changes to 3 files
206 added 3 changesets with 3 changes to 3 files
207 bundle2-output-bundle: "HG20", 1 parts total
207 bundle2-output-bundle: "HG20", 1 parts total
208 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
208 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
209 bundle2-input-bundle: no-transaction
209 bundle2-input-bundle: no-transaction
210 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
210 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
211 bundle2-input-bundle: 0 parts total
211 bundle2-input-bundle: 1 parts total
212 listing keys for "phases"
212 listing keys for "phases"
213 repository tip rolled back to revision 0 (undo push)
213 repository tip rolled back to revision 0 (undo push)
214 0:6675d58eff77
214 0:6675d58eff77
215
215
216
216
217 No [acl.allow]/[acl.deny]
217 No [acl.allow]/[acl.deny]
218
218
219 $ echo '[acl]' >> $config
219 $ echo '[acl]' >> $config
220 $ echo 'sources = push' >> $config
220 $ echo 'sources = push' >> $config
221 $ do_push fred
221 $ do_push fred
222 Pushing as user fred
222 Pushing as user fred
223 hgrc = """
223 hgrc = """
224 [hooks]
224 [hooks]
225 pretxnchangegroup.acl = python:hgext.acl.hook
225 pretxnchangegroup.acl = python:hgext.acl.hook
226 prepushkey.acl = python:hgext.acl.hook
226 prepushkey.acl = python:hgext.acl.hook
227 [acl]
227 [acl]
228 sources = push
228 sources = push
229 """
229 """
230 pushing to ../b
230 pushing to ../b
231 query 1; heads
231 query 1; heads
232 searching for changes
232 searching for changes
233 all remote heads known locally
233 all remote heads known locally
234 listing keys for "phases"
234 listing keys for "phases"
235 checking for updated bookmarks
235 checking for updated bookmarks
236 listing keys for "bookmarks"
236 listing keys for "bookmarks"
237 listing keys for "bookmarks"
237 listing keys for "bookmarks"
238 3 changesets found
238 3 changesets found
239 list of changesets:
239 list of changesets:
240 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
240 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
241 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
241 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
242 911600dab2ae7a9baff75958b84fe606851ce955
242 911600dab2ae7a9baff75958b84fe606851ce955
243 bundle2-output-bundle: "HG20", 5 parts total
243 bundle2-output-bundle: "HG20", 5 parts total
244 bundle2-output-part: "replycaps" 205 bytes payload
244 bundle2-output-part: "replycaps" 205 bytes payload
245 bundle2-output-part: "check:phases" 24 bytes payload
245 bundle2-output-part: "check:phases" 24 bytes payload
246 bundle2-output-part: "check:heads" streamed payload
246 bundle2-output-part: "check:heads" streamed payload
247 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
247 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
248 bundle2-output-part: "phase-heads" 24 bytes payload
248 bundle2-output-part: "phase-heads" 24 bytes payload
249 bundle2-input-bundle: with-transaction
249 bundle2-input-bundle: with-transaction
250 bundle2-input-part: "replycaps" supported
250 bundle2-input-part: "replycaps" supported
251 bundle2-input-part: total payload size 205
251 bundle2-input-part: total payload size 205
252 bundle2-input-part: "check:phases" supported
252 bundle2-input-part: "check:phases" supported
253 bundle2-input-part: total payload size 24
253 bundle2-input-part: total payload size 24
254 bundle2-input-part: "check:heads" supported
254 bundle2-input-part: "check:heads" supported
255 bundle2-input-part: total payload size 20
255 bundle2-input-part: total payload size 20
256 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
256 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
257 adding changesets
257 adding changesets
258 add changeset ef1ea85a6374
258 add changeset ef1ea85a6374
259 add changeset f9cafe1212c8
259 add changeset f9cafe1212c8
260 add changeset 911600dab2ae
260 add changeset 911600dab2ae
261 adding manifests
261 adding manifests
262 adding file changes
262 adding file changes
263 adding foo/Bar/file.txt revisions
263 adding foo/Bar/file.txt revisions
264 adding foo/file.txt revisions
264 adding foo/file.txt revisions
265 adding quux/file.py revisions
265 adding quux/file.py revisions
266 calling hook pretxnchangegroup.acl: hgext.acl.hook
266 calling hook pretxnchangegroup.acl: hgext.acl.hook
267 acl: checking access for user "fred"
267 acl: checking access for user "fred"
268 acl: acl.allow.branches not enabled
268 acl: acl.allow.branches not enabled
269 acl: acl.deny.branches not enabled
269 acl: acl.deny.branches not enabled
270 acl: acl.allow not enabled
270 acl: acl.allow not enabled
271 acl: acl.deny not enabled
271 acl: acl.deny not enabled
272 acl: branch access granted: "ef1ea85a6374" on branch "default"
272 acl: branch access granted: "ef1ea85a6374" on branch "default"
273 acl: path access granted: "ef1ea85a6374"
273 acl: path access granted: "ef1ea85a6374"
274 acl: branch access granted: "f9cafe1212c8" on branch "default"
274 acl: branch access granted: "f9cafe1212c8" on branch "default"
275 acl: path access granted: "f9cafe1212c8"
275 acl: path access granted: "f9cafe1212c8"
276 acl: branch access granted: "911600dab2ae" on branch "default"
276 acl: branch access granted: "911600dab2ae" on branch "default"
277 acl: path access granted: "911600dab2ae"
277 acl: path access granted: "911600dab2ae"
278 bundle2-input-part: total payload size 1553
278 bundle2-input-part: total payload size 1553
279 bundle2-input-part: "phase-heads" supported
279 bundle2-input-part: "phase-heads" supported
280 bundle2-input-part: total payload size 24
280 bundle2-input-part: total payload size 24
281 bundle2-input-bundle: 4 parts total
281 bundle2-input-bundle: 5 parts total
282 updating the branch cache
282 updating the branch cache
283 added 3 changesets with 3 changes to 3 files
283 added 3 changesets with 3 changes to 3 files
284 bundle2-output-bundle: "HG20", 1 parts total
284 bundle2-output-bundle: "HG20", 1 parts total
285 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
285 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
286 bundle2-input-bundle: no-transaction
286 bundle2-input-bundle: no-transaction
287 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
287 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
288 bundle2-input-bundle: 0 parts total
288 bundle2-input-bundle: 1 parts total
289 listing keys for "phases"
289 listing keys for "phases"
290 repository tip rolled back to revision 0 (undo push)
290 repository tip rolled back to revision 0 (undo push)
291 0:6675d58eff77
291 0:6675d58eff77
292
292
293
293
294 Empty [acl.allow]
294 Empty [acl.allow]
295
295
296 $ echo '[acl.allow]' >> $config
296 $ echo '[acl.allow]' >> $config
297 $ do_push fred
297 $ do_push fred
298 Pushing as user fred
298 Pushing as user fred
299 hgrc = """
299 hgrc = """
300 [hooks]
300 [hooks]
301 pretxnchangegroup.acl = python:hgext.acl.hook
301 pretxnchangegroup.acl = python:hgext.acl.hook
302 prepushkey.acl = python:hgext.acl.hook
302 prepushkey.acl = python:hgext.acl.hook
303 [acl]
303 [acl]
304 sources = push
304 sources = push
305 [acl.allow]
305 [acl.allow]
306 """
306 """
307 pushing to ../b
307 pushing to ../b
308 query 1; heads
308 query 1; heads
309 searching for changes
309 searching for changes
310 all remote heads known locally
310 all remote heads known locally
311 listing keys for "phases"
311 listing keys for "phases"
312 checking for updated bookmarks
312 checking for updated bookmarks
313 listing keys for "bookmarks"
313 listing keys for "bookmarks"
314 listing keys for "bookmarks"
314 listing keys for "bookmarks"
315 3 changesets found
315 3 changesets found
316 list of changesets:
316 list of changesets:
317 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
317 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
318 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
318 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
319 911600dab2ae7a9baff75958b84fe606851ce955
319 911600dab2ae7a9baff75958b84fe606851ce955
320 bundle2-output-bundle: "HG20", 5 parts total
320 bundle2-output-bundle: "HG20", 5 parts total
321 bundle2-output-part: "replycaps" 205 bytes payload
321 bundle2-output-part: "replycaps" 205 bytes payload
322 bundle2-output-part: "check:phases" 24 bytes payload
322 bundle2-output-part: "check:phases" 24 bytes payload
323 bundle2-output-part: "check:heads" streamed payload
323 bundle2-output-part: "check:heads" streamed payload
324 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
324 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
325 bundle2-output-part: "phase-heads" 24 bytes payload
325 bundle2-output-part: "phase-heads" 24 bytes payload
326 bundle2-input-bundle: with-transaction
326 bundle2-input-bundle: with-transaction
327 bundle2-input-part: "replycaps" supported
327 bundle2-input-part: "replycaps" supported
328 bundle2-input-part: total payload size 205
328 bundle2-input-part: total payload size 205
329 bundle2-input-part: "check:phases" supported
329 bundle2-input-part: "check:phases" supported
330 bundle2-input-part: total payload size 24
330 bundle2-input-part: total payload size 24
331 bundle2-input-part: "check:heads" supported
331 bundle2-input-part: "check:heads" supported
332 bundle2-input-part: total payload size 20
332 bundle2-input-part: total payload size 20
333 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
333 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
334 adding changesets
334 adding changesets
335 add changeset ef1ea85a6374
335 add changeset ef1ea85a6374
336 add changeset f9cafe1212c8
336 add changeset f9cafe1212c8
337 add changeset 911600dab2ae
337 add changeset 911600dab2ae
338 adding manifests
338 adding manifests
339 adding file changes
339 adding file changes
340 adding foo/Bar/file.txt revisions
340 adding foo/Bar/file.txt revisions
341 adding foo/file.txt revisions
341 adding foo/file.txt revisions
342 adding quux/file.py revisions
342 adding quux/file.py revisions
343 calling hook pretxnchangegroup.acl: hgext.acl.hook
343 calling hook pretxnchangegroup.acl: hgext.acl.hook
344 acl: checking access for user "fred"
344 acl: checking access for user "fred"
345 acl: acl.allow.branches not enabled
345 acl: acl.allow.branches not enabled
346 acl: acl.deny.branches not enabled
346 acl: acl.deny.branches not enabled
347 acl: acl.allow enabled, 0 entries for user fred
347 acl: acl.allow enabled, 0 entries for user fred
348 acl: acl.deny not enabled
348 acl: acl.deny not enabled
349 acl: branch access granted: "ef1ea85a6374" on branch "default"
349 acl: branch access granted: "ef1ea85a6374" on branch "default"
350 error: pretxnchangegroup.acl hook failed: acl: user "fred" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
350 error: pretxnchangegroup.acl hook failed: acl: user "fred" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
351 bundle2-input-part: total payload size 1553
351 bundle2-input-part: total payload size 1553
352 bundle2-input-part: total payload size 24
352 bundle2-input-part: total payload size 24
353 bundle2-input-bundle: 4 parts total
353 bundle2-input-bundle: 5 parts total
354 transaction abort!
354 transaction abort!
355 rollback completed
355 rollback completed
356 abort: acl: user "fred" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
356 abort: acl: user "fred" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
357 no rollback information available
357 no rollback information available
358 0:6675d58eff77
358 0:6675d58eff77
359
359
360
360
361 fred is allowed inside foo/
361 fred is allowed inside foo/
362
362
363 $ echo 'foo/** = fred' >> $config
363 $ echo 'foo/** = fred' >> $config
364 $ do_push fred
364 $ do_push fred
365 Pushing as user fred
365 Pushing as user fred
366 hgrc = """
366 hgrc = """
367 [hooks]
367 [hooks]
368 pretxnchangegroup.acl = python:hgext.acl.hook
368 pretxnchangegroup.acl = python:hgext.acl.hook
369 prepushkey.acl = python:hgext.acl.hook
369 prepushkey.acl = python:hgext.acl.hook
370 [acl]
370 [acl]
371 sources = push
371 sources = push
372 [acl.allow]
372 [acl.allow]
373 foo/** = fred
373 foo/** = fred
374 """
374 """
375 pushing to ../b
375 pushing to ../b
376 query 1; heads
376 query 1; heads
377 searching for changes
377 searching for changes
378 all remote heads known locally
378 all remote heads known locally
379 listing keys for "phases"
379 listing keys for "phases"
380 checking for updated bookmarks
380 checking for updated bookmarks
381 listing keys for "bookmarks"
381 listing keys for "bookmarks"
382 listing keys for "bookmarks"
382 listing keys for "bookmarks"
383 3 changesets found
383 3 changesets found
384 list of changesets:
384 list of changesets:
385 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
385 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
386 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
386 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
387 911600dab2ae7a9baff75958b84fe606851ce955
387 911600dab2ae7a9baff75958b84fe606851ce955
388 bundle2-output-bundle: "HG20", 5 parts total
388 bundle2-output-bundle: "HG20", 5 parts total
389 bundle2-output-part: "replycaps" 205 bytes payload
389 bundle2-output-part: "replycaps" 205 bytes payload
390 bundle2-output-part: "check:phases" 24 bytes payload
390 bundle2-output-part: "check:phases" 24 bytes payload
391 bundle2-output-part: "check:heads" streamed payload
391 bundle2-output-part: "check:heads" streamed payload
392 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
392 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
393 bundle2-output-part: "phase-heads" 24 bytes payload
393 bundle2-output-part: "phase-heads" 24 bytes payload
394 bundle2-input-bundle: with-transaction
394 bundle2-input-bundle: with-transaction
395 bundle2-input-part: "replycaps" supported
395 bundle2-input-part: "replycaps" supported
396 bundle2-input-part: total payload size 205
396 bundle2-input-part: total payload size 205
397 bundle2-input-part: "check:phases" supported
397 bundle2-input-part: "check:phases" supported
398 bundle2-input-part: total payload size 24
398 bundle2-input-part: total payload size 24
399 bundle2-input-part: "check:heads" supported
399 bundle2-input-part: "check:heads" supported
400 bundle2-input-part: total payload size 20
400 bundle2-input-part: total payload size 20
401 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
401 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
402 adding changesets
402 adding changesets
403 add changeset ef1ea85a6374
403 add changeset ef1ea85a6374
404 add changeset f9cafe1212c8
404 add changeset f9cafe1212c8
405 add changeset 911600dab2ae
405 add changeset 911600dab2ae
406 adding manifests
406 adding manifests
407 adding file changes
407 adding file changes
408 adding foo/Bar/file.txt revisions
408 adding foo/Bar/file.txt revisions
409 adding foo/file.txt revisions
409 adding foo/file.txt revisions
410 adding quux/file.py revisions
410 adding quux/file.py revisions
411 calling hook pretxnchangegroup.acl: hgext.acl.hook
411 calling hook pretxnchangegroup.acl: hgext.acl.hook
412 acl: checking access for user "fred"
412 acl: checking access for user "fred"
413 acl: acl.allow.branches not enabled
413 acl: acl.allow.branches not enabled
414 acl: acl.deny.branches not enabled
414 acl: acl.deny.branches not enabled
415 acl: acl.allow enabled, 1 entries for user fred
415 acl: acl.allow enabled, 1 entries for user fred
416 acl: acl.deny not enabled
416 acl: acl.deny not enabled
417 acl: branch access granted: "ef1ea85a6374" on branch "default"
417 acl: branch access granted: "ef1ea85a6374" on branch "default"
418 acl: path access granted: "ef1ea85a6374"
418 acl: path access granted: "ef1ea85a6374"
419 acl: branch access granted: "f9cafe1212c8" on branch "default"
419 acl: branch access granted: "f9cafe1212c8" on branch "default"
420 acl: path access granted: "f9cafe1212c8"
420 acl: path access granted: "f9cafe1212c8"
421 acl: branch access granted: "911600dab2ae" on branch "default"
421 acl: branch access granted: "911600dab2ae" on branch "default"
422 error: pretxnchangegroup.acl hook failed: acl: user "fred" not allowed on "quux/file.py" (changeset "911600dab2ae")
422 error: pretxnchangegroup.acl hook failed: acl: user "fred" not allowed on "quux/file.py" (changeset "911600dab2ae")
423 bundle2-input-part: total payload size 1553
423 bundle2-input-part: total payload size 1553
424 bundle2-input-part: total payload size 24
424 bundle2-input-part: total payload size 24
425 bundle2-input-bundle: 4 parts total
425 bundle2-input-bundle: 5 parts total
426 transaction abort!
426 transaction abort!
427 rollback completed
427 rollback completed
428 abort: acl: user "fred" not allowed on "quux/file.py" (changeset "911600dab2ae")
428 abort: acl: user "fred" not allowed on "quux/file.py" (changeset "911600dab2ae")
429 no rollback information available
429 no rollback information available
430 0:6675d58eff77
430 0:6675d58eff77
431
431
432
432
433 Empty [acl.deny]
433 Empty [acl.deny]
434
434
435 $ echo '[acl.deny]' >> $config
435 $ echo '[acl.deny]' >> $config
436 $ do_push barney
436 $ do_push barney
437 Pushing as user barney
437 Pushing as user barney
438 hgrc = """
438 hgrc = """
439 [hooks]
439 [hooks]
440 pretxnchangegroup.acl = python:hgext.acl.hook
440 pretxnchangegroup.acl = python:hgext.acl.hook
441 prepushkey.acl = python:hgext.acl.hook
441 prepushkey.acl = python:hgext.acl.hook
442 [acl]
442 [acl]
443 sources = push
443 sources = push
444 [acl.allow]
444 [acl.allow]
445 foo/** = fred
445 foo/** = fred
446 [acl.deny]
446 [acl.deny]
447 """
447 """
448 pushing to ../b
448 pushing to ../b
449 query 1; heads
449 query 1; heads
450 searching for changes
450 searching for changes
451 all remote heads known locally
451 all remote heads known locally
452 listing keys for "phases"
452 listing keys for "phases"
453 checking for updated bookmarks
453 checking for updated bookmarks
454 listing keys for "bookmarks"
454 listing keys for "bookmarks"
455 listing keys for "bookmarks"
455 listing keys for "bookmarks"
456 3 changesets found
456 3 changesets found
457 list of changesets:
457 list of changesets:
458 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
458 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
459 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
459 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
460 911600dab2ae7a9baff75958b84fe606851ce955
460 911600dab2ae7a9baff75958b84fe606851ce955
461 bundle2-output-bundle: "HG20", 5 parts total
461 bundle2-output-bundle: "HG20", 5 parts total
462 bundle2-output-part: "replycaps" 205 bytes payload
462 bundle2-output-part: "replycaps" 205 bytes payload
463 bundle2-output-part: "check:phases" 24 bytes payload
463 bundle2-output-part: "check:phases" 24 bytes payload
464 bundle2-output-part: "check:heads" streamed payload
464 bundle2-output-part: "check:heads" streamed payload
465 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
465 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
466 bundle2-output-part: "phase-heads" 24 bytes payload
466 bundle2-output-part: "phase-heads" 24 bytes payload
467 bundle2-input-bundle: with-transaction
467 bundle2-input-bundle: with-transaction
468 bundle2-input-part: "replycaps" supported
468 bundle2-input-part: "replycaps" supported
469 bundle2-input-part: total payload size 205
469 bundle2-input-part: total payload size 205
470 bundle2-input-part: "check:phases" supported
470 bundle2-input-part: "check:phases" supported
471 bundle2-input-part: total payload size 24
471 bundle2-input-part: total payload size 24
472 bundle2-input-part: "check:heads" supported
472 bundle2-input-part: "check:heads" supported
473 bundle2-input-part: total payload size 20
473 bundle2-input-part: total payload size 20
474 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
474 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
475 adding changesets
475 adding changesets
476 add changeset ef1ea85a6374
476 add changeset ef1ea85a6374
477 add changeset f9cafe1212c8
477 add changeset f9cafe1212c8
478 add changeset 911600dab2ae
478 add changeset 911600dab2ae
479 adding manifests
479 adding manifests
480 adding file changes
480 adding file changes
481 adding foo/Bar/file.txt revisions
481 adding foo/Bar/file.txt revisions
482 adding foo/file.txt revisions
482 adding foo/file.txt revisions
483 adding quux/file.py revisions
483 adding quux/file.py revisions
484 calling hook pretxnchangegroup.acl: hgext.acl.hook
484 calling hook pretxnchangegroup.acl: hgext.acl.hook
485 acl: checking access for user "barney"
485 acl: checking access for user "barney"
486 acl: acl.allow.branches not enabled
486 acl: acl.allow.branches not enabled
487 acl: acl.deny.branches not enabled
487 acl: acl.deny.branches not enabled
488 acl: acl.allow enabled, 0 entries for user barney
488 acl: acl.allow enabled, 0 entries for user barney
489 acl: acl.deny enabled, 0 entries for user barney
489 acl: acl.deny enabled, 0 entries for user barney
490 acl: branch access granted: "ef1ea85a6374" on branch "default"
490 acl: branch access granted: "ef1ea85a6374" on branch "default"
491 error: pretxnchangegroup.acl hook failed: acl: user "barney" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
491 error: pretxnchangegroup.acl hook failed: acl: user "barney" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
492 bundle2-input-part: total payload size 1553
492 bundle2-input-part: total payload size 1553
493 bundle2-input-part: total payload size 24
493 bundle2-input-part: total payload size 24
494 bundle2-input-bundle: 4 parts total
494 bundle2-input-bundle: 5 parts total
495 transaction abort!
495 transaction abort!
496 rollback completed
496 rollback completed
497 abort: acl: user "barney" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
497 abort: acl: user "barney" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
498 no rollback information available
498 no rollback information available
499 0:6675d58eff77
499 0:6675d58eff77
500
500
501
501
502 fred is allowed inside foo/, but not foo/bar/ (case matters)
502 fred is allowed inside foo/, but not foo/bar/ (case matters)
503
503
504 $ echo 'foo/bar/** = fred' >> $config
504 $ echo 'foo/bar/** = fred' >> $config
505 $ do_push fred
505 $ do_push fred
506 Pushing as user fred
506 Pushing as user fred
507 hgrc = """
507 hgrc = """
508 [hooks]
508 [hooks]
509 pretxnchangegroup.acl = python:hgext.acl.hook
509 pretxnchangegroup.acl = python:hgext.acl.hook
510 prepushkey.acl = python:hgext.acl.hook
510 prepushkey.acl = python:hgext.acl.hook
511 [acl]
511 [acl]
512 sources = push
512 sources = push
513 [acl.allow]
513 [acl.allow]
514 foo/** = fred
514 foo/** = fred
515 [acl.deny]
515 [acl.deny]
516 foo/bar/** = fred
516 foo/bar/** = fred
517 """
517 """
518 pushing to ../b
518 pushing to ../b
519 query 1; heads
519 query 1; heads
520 searching for changes
520 searching for changes
521 all remote heads known locally
521 all remote heads known locally
522 listing keys for "phases"
522 listing keys for "phases"
523 checking for updated bookmarks
523 checking for updated bookmarks
524 listing keys for "bookmarks"
524 listing keys for "bookmarks"
525 listing keys for "bookmarks"
525 listing keys for "bookmarks"
526 3 changesets found
526 3 changesets found
527 list of changesets:
527 list of changesets:
528 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
528 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
529 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
529 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
530 911600dab2ae7a9baff75958b84fe606851ce955
530 911600dab2ae7a9baff75958b84fe606851ce955
531 bundle2-output-bundle: "HG20", 5 parts total
531 bundle2-output-bundle: "HG20", 5 parts total
532 bundle2-output-part: "replycaps" 205 bytes payload
532 bundle2-output-part: "replycaps" 205 bytes payload
533 bundle2-output-part: "check:phases" 24 bytes payload
533 bundle2-output-part: "check:phases" 24 bytes payload
534 bundle2-output-part: "check:heads" streamed payload
534 bundle2-output-part: "check:heads" streamed payload
535 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
535 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
536 bundle2-output-part: "phase-heads" 24 bytes payload
536 bundle2-output-part: "phase-heads" 24 bytes payload
537 bundle2-input-bundle: with-transaction
537 bundle2-input-bundle: with-transaction
538 bundle2-input-part: "replycaps" supported
538 bundle2-input-part: "replycaps" supported
539 bundle2-input-part: total payload size 205
539 bundle2-input-part: total payload size 205
540 bundle2-input-part: "check:phases" supported
540 bundle2-input-part: "check:phases" supported
541 bundle2-input-part: total payload size 24
541 bundle2-input-part: total payload size 24
542 bundle2-input-part: "check:heads" supported
542 bundle2-input-part: "check:heads" supported
543 bundle2-input-part: total payload size 20
543 bundle2-input-part: total payload size 20
544 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
544 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
545 adding changesets
545 adding changesets
546 add changeset ef1ea85a6374
546 add changeset ef1ea85a6374
547 add changeset f9cafe1212c8
547 add changeset f9cafe1212c8
548 add changeset 911600dab2ae
548 add changeset 911600dab2ae
549 adding manifests
549 adding manifests
550 adding file changes
550 adding file changes
551 adding foo/Bar/file.txt revisions
551 adding foo/Bar/file.txt revisions
552 adding foo/file.txt revisions
552 adding foo/file.txt revisions
553 adding quux/file.py revisions
553 adding quux/file.py revisions
554 calling hook pretxnchangegroup.acl: hgext.acl.hook
554 calling hook pretxnchangegroup.acl: hgext.acl.hook
555 acl: checking access for user "fred"
555 acl: checking access for user "fred"
556 acl: acl.allow.branches not enabled
556 acl: acl.allow.branches not enabled
557 acl: acl.deny.branches not enabled
557 acl: acl.deny.branches not enabled
558 acl: acl.allow enabled, 1 entries for user fred
558 acl: acl.allow enabled, 1 entries for user fred
559 acl: acl.deny enabled, 1 entries for user fred
559 acl: acl.deny enabled, 1 entries for user fred
560 acl: branch access granted: "ef1ea85a6374" on branch "default"
560 acl: branch access granted: "ef1ea85a6374" on branch "default"
561 acl: path access granted: "ef1ea85a6374"
561 acl: path access granted: "ef1ea85a6374"
562 acl: branch access granted: "f9cafe1212c8" on branch "default"
562 acl: branch access granted: "f9cafe1212c8" on branch "default"
563 acl: path access granted: "f9cafe1212c8"
563 acl: path access granted: "f9cafe1212c8"
564 acl: branch access granted: "911600dab2ae" on branch "default"
564 acl: branch access granted: "911600dab2ae" on branch "default"
565 error: pretxnchangegroup.acl hook failed: acl: user "fred" not allowed on "quux/file.py" (changeset "911600dab2ae")
565 error: pretxnchangegroup.acl hook failed: acl: user "fred" not allowed on "quux/file.py" (changeset "911600dab2ae")
566 bundle2-input-part: total payload size 1553
566 bundle2-input-part: total payload size 1553
567 bundle2-input-part: total payload size 24
567 bundle2-input-part: total payload size 24
568 bundle2-input-bundle: 4 parts total
568 bundle2-input-bundle: 5 parts total
569 transaction abort!
569 transaction abort!
570 rollback completed
570 rollback completed
571 abort: acl: user "fred" not allowed on "quux/file.py" (changeset "911600dab2ae")
571 abort: acl: user "fred" not allowed on "quux/file.py" (changeset "911600dab2ae")
572 no rollback information available
572 no rollback information available
573 0:6675d58eff77
573 0:6675d58eff77
574
574
575
575
576 fred is allowed inside foo/, but not foo/Bar/
576 fred is allowed inside foo/, but not foo/Bar/
577
577
578 $ echo 'foo/Bar/** = fred' >> $config
578 $ echo 'foo/Bar/** = fred' >> $config
579 $ do_push fred
579 $ do_push fred
580 Pushing as user fred
580 Pushing as user fred
581 hgrc = """
581 hgrc = """
582 [hooks]
582 [hooks]
583 pretxnchangegroup.acl = python:hgext.acl.hook
583 pretxnchangegroup.acl = python:hgext.acl.hook
584 prepushkey.acl = python:hgext.acl.hook
584 prepushkey.acl = python:hgext.acl.hook
585 [acl]
585 [acl]
586 sources = push
586 sources = push
587 [acl.allow]
587 [acl.allow]
588 foo/** = fred
588 foo/** = fred
589 [acl.deny]
589 [acl.deny]
590 foo/bar/** = fred
590 foo/bar/** = fred
591 foo/Bar/** = fred
591 foo/Bar/** = fred
592 """
592 """
593 pushing to ../b
593 pushing to ../b
594 query 1; heads
594 query 1; heads
595 searching for changes
595 searching for changes
596 all remote heads known locally
596 all remote heads known locally
597 listing keys for "phases"
597 listing keys for "phases"
598 checking for updated bookmarks
598 checking for updated bookmarks
599 listing keys for "bookmarks"
599 listing keys for "bookmarks"
600 listing keys for "bookmarks"
600 listing keys for "bookmarks"
601 3 changesets found
601 3 changesets found
602 list of changesets:
602 list of changesets:
603 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
603 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
604 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
604 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
605 911600dab2ae7a9baff75958b84fe606851ce955
605 911600dab2ae7a9baff75958b84fe606851ce955
606 bundle2-output-bundle: "HG20", 5 parts total
606 bundle2-output-bundle: "HG20", 5 parts total
607 bundle2-output-part: "replycaps" 205 bytes payload
607 bundle2-output-part: "replycaps" 205 bytes payload
608 bundle2-output-part: "check:phases" 24 bytes payload
608 bundle2-output-part: "check:phases" 24 bytes payload
609 bundle2-output-part: "check:heads" streamed payload
609 bundle2-output-part: "check:heads" streamed payload
610 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
610 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
611 bundle2-output-part: "phase-heads" 24 bytes payload
611 bundle2-output-part: "phase-heads" 24 bytes payload
612 bundle2-input-bundle: with-transaction
612 bundle2-input-bundle: with-transaction
613 bundle2-input-part: "replycaps" supported
613 bundle2-input-part: "replycaps" supported
614 bundle2-input-part: total payload size 205
614 bundle2-input-part: total payload size 205
615 bundle2-input-part: "check:phases" supported
615 bundle2-input-part: "check:phases" supported
616 bundle2-input-part: total payload size 24
616 bundle2-input-part: total payload size 24
617 bundle2-input-part: "check:heads" supported
617 bundle2-input-part: "check:heads" supported
618 bundle2-input-part: total payload size 20
618 bundle2-input-part: total payload size 20
619 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
619 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
620 adding changesets
620 adding changesets
621 add changeset ef1ea85a6374
621 add changeset ef1ea85a6374
622 add changeset f9cafe1212c8
622 add changeset f9cafe1212c8
623 add changeset 911600dab2ae
623 add changeset 911600dab2ae
624 adding manifests
624 adding manifests
625 adding file changes
625 adding file changes
626 adding foo/Bar/file.txt revisions
626 adding foo/Bar/file.txt revisions
627 adding foo/file.txt revisions
627 adding foo/file.txt revisions
628 adding quux/file.py revisions
628 adding quux/file.py revisions
629 calling hook pretxnchangegroup.acl: hgext.acl.hook
629 calling hook pretxnchangegroup.acl: hgext.acl.hook
630 acl: checking access for user "fred"
630 acl: checking access for user "fred"
631 acl: acl.allow.branches not enabled
631 acl: acl.allow.branches not enabled
632 acl: acl.deny.branches not enabled
632 acl: acl.deny.branches not enabled
633 acl: acl.allow enabled, 1 entries for user fred
633 acl: acl.allow enabled, 1 entries for user fred
634 acl: acl.deny enabled, 2 entries for user fred
634 acl: acl.deny enabled, 2 entries for user fred
635 acl: branch access granted: "ef1ea85a6374" on branch "default"
635 acl: branch access granted: "ef1ea85a6374" on branch "default"
636 acl: path access granted: "ef1ea85a6374"
636 acl: path access granted: "ef1ea85a6374"
637 acl: branch access granted: "f9cafe1212c8" on branch "default"
637 acl: branch access granted: "f9cafe1212c8" on branch "default"
638 error: pretxnchangegroup.acl hook failed: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
638 error: pretxnchangegroup.acl hook failed: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
639 bundle2-input-part: total payload size 1553
639 bundle2-input-part: total payload size 1553
640 bundle2-input-part: total payload size 24
640 bundle2-input-part: total payload size 24
641 bundle2-input-bundle: 4 parts total
641 bundle2-input-bundle: 5 parts total
642 transaction abort!
642 transaction abort!
643 rollback completed
643 rollback completed
644 abort: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
644 abort: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
645 no rollback information available
645 no rollback information available
646 0:6675d58eff77
646 0:6675d58eff77
647
647
648
648
649 $ echo 'barney is not mentioned => not allowed anywhere'
649 $ echo 'barney is not mentioned => not allowed anywhere'
650 barney is not mentioned => not allowed anywhere
650 barney is not mentioned => not allowed anywhere
651 $ do_push barney
651 $ do_push barney
652 Pushing as user barney
652 Pushing as user barney
653 hgrc = """
653 hgrc = """
654 [hooks]
654 [hooks]
655 pretxnchangegroup.acl = python:hgext.acl.hook
655 pretxnchangegroup.acl = python:hgext.acl.hook
656 prepushkey.acl = python:hgext.acl.hook
656 prepushkey.acl = python:hgext.acl.hook
657 [acl]
657 [acl]
658 sources = push
658 sources = push
659 [acl.allow]
659 [acl.allow]
660 foo/** = fred
660 foo/** = fred
661 [acl.deny]
661 [acl.deny]
662 foo/bar/** = fred
662 foo/bar/** = fred
663 foo/Bar/** = fred
663 foo/Bar/** = fred
664 """
664 """
665 pushing to ../b
665 pushing to ../b
666 query 1; heads
666 query 1; heads
667 searching for changes
667 searching for changes
668 all remote heads known locally
668 all remote heads known locally
669 listing keys for "phases"
669 listing keys for "phases"
670 checking for updated bookmarks
670 checking for updated bookmarks
671 listing keys for "bookmarks"
671 listing keys for "bookmarks"
672 listing keys for "bookmarks"
672 listing keys for "bookmarks"
673 3 changesets found
673 3 changesets found
674 list of changesets:
674 list of changesets:
675 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
675 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
676 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
676 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
677 911600dab2ae7a9baff75958b84fe606851ce955
677 911600dab2ae7a9baff75958b84fe606851ce955
678 bundle2-output-bundle: "HG20", 5 parts total
678 bundle2-output-bundle: "HG20", 5 parts total
679 bundle2-output-part: "replycaps" 205 bytes payload
679 bundle2-output-part: "replycaps" 205 bytes payload
680 bundle2-output-part: "check:phases" 24 bytes payload
680 bundle2-output-part: "check:phases" 24 bytes payload
681 bundle2-output-part: "check:heads" streamed payload
681 bundle2-output-part: "check:heads" streamed payload
682 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
682 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
683 bundle2-output-part: "phase-heads" 24 bytes payload
683 bundle2-output-part: "phase-heads" 24 bytes payload
684 bundle2-input-bundle: with-transaction
684 bundle2-input-bundle: with-transaction
685 bundle2-input-part: "replycaps" supported
685 bundle2-input-part: "replycaps" supported
686 bundle2-input-part: total payload size 205
686 bundle2-input-part: total payload size 205
687 bundle2-input-part: "check:phases" supported
687 bundle2-input-part: "check:phases" supported
688 bundle2-input-part: total payload size 24
688 bundle2-input-part: total payload size 24
689 bundle2-input-part: "check:heads" supported
689 bundle2-input-part: "check:heads" supported
690 bundle2-input-part: total payload size 20
690 bundle2-input-part: total payload size 20
691 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
691 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
692 adding changesets
692 adding changesets
693 add changeset ef1ea85a6374
693 add changeset ef1ea85a6374
694 add changeset f9cafe1212c8
694 add changeset f9cafe1212c8
695 add changeset 911600dab2ae
695 add changeset 911600dab2ae
696 adding manifests
696 adding manifests
697 adding file changes
697 adding file changes
698 adding foo/Bar/file.txt revisions
698 adding foo/Bar/file.txt revisions
699 adding foo/file.txt revisions
699 adding foo/file.txt revisions
700 adding quux/file.py revisions
700 adding quux/file.py revisions
701 calling hook pretxnchangegroup.acl: hgext.acl.hook
701 calling hook pretxnchangegroup.acl: hgext.acl.hook
702 acl: checking access for user "barney"
702 acl: checking access for user "barney"
703 acl: acl.allow.branches not enabled
703 acl: acl.allow.branches not enabled
704 acl: acl.deny.branches not enabled
704 acl: acl.deny.branches not enabled
705 acl: acl.allow enabled, 0 entries for user barney
705 acl: acl.allow enabled, 0 entries for user barney
706 acl: acl.deny enabled, 0 entries for user barney
706 acl: acl.deny enabled, 0 entries for user barney
707 acl: branch access granted: "ef1ea85a6374" on branch "default"
707 acl: branch access granted: "ef1ea85a6374" on branch "default"
708 error: pretxnchangegroup.acl hook failed: acl: user "barney" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
708 error: pretxnchangegroup.acl hook failed: acl: user "barney" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
709 bundle2-input-part: total payload size 1553
709 bundle2-input-part: total payload size 1553
710 bundle2-input-part: total payload size 24
710 bundle2-input-part: total payload size 24
711 bundle2-input-bundle: 4 parts total
711 bundle2-input-bundle: 5 parts total
712 transaction abort!
712 transaction abort!
713 rollback completed
713 rollback completed
714 abort: acl: user "barney" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
714 abort: acl: user "barney" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
715 no rollback information available
715 no rollback information available
716 0:6675d58eff77
716 0:6675d58eff77
717
717
718
718
719 fred is not blocked from moving bookmarks
719 fred is not blocked from moving bookmarks
720
720
721 $ hg -R a book -q moving-bookmark -r 1
721 $ hg -R a book -q moving-bookmark -r 1
722 $ hg -R b book -q moving-bookmark -r 0
722 $ hg -R b book -q moving-bookmark -r 0
723 $ cp $config normalconfig
723 $ cp $config normalconfig
724 $ do_push fred -r 1
724 $ do_push fred -r 1
725 Pushing as user fred
725 Pushing as user fred
726 hgrc = """
726 hgrc = """
727 [hooks]
727 [hooks]
728 pretxnchangegroup.acl = python:hgext.acl.hook
728 pretxnchangegroup.acl = python:hgext.acl.hook
729 prepushkey.acl = python:hgext.acl.hook
729 prepushkey.acl = python:hgext.acl.hook
730 [acl]
730 [acl]
731 sources = push
731 sources = push
732 [acl.allow]
732 [acl.allow]
733 foo/** = fred
733 foo/** = fred
734 [acl.deny]
734 [acl.deny]
735 foo/bar/** = fred
735 foo/bar/** = fred
736 foo/Bar/** = fred
736 foo/Bar/** = fred
737 """
737 """
738 pushing to ../b
738 pushing to ../b
739 query 1; heads
739 query 1; heads
740 searching for changes
740 searching for changes
741 all remote heads known locally
741 all remote heads known locally
742 listing keys for "phases"
742 listing keys for "phases"
743 checking for updated bookmarks
743 checking for updated bookmarks
744 listing keys for "bookmarks"
744 listing keys for "bookmarks"
745 listing keys for "bookmarks"
745 listing keys for "bookmarks"
746 1 changesets found
746 1 changesets found
747 list of changesets:
747 list of changesets:
748 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
748 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
749 bundle2-output-bundle: "HG20", 7 parts total
749 bundle2-output-bundle: "HG20", 7 parts total
750 bundle2-output-part: "replycaps" 205 bytes payload
750 bundle2-output-part: "replycaps" 205 bytes payload
751 bundle2-output-part: "check:bookmarks" 37 bytes payload
751 bundle2-output-part: "check:bookmarks" 37 bytes payload
752 bundle2-output-part: "check:phases" 24 bytes payload
752 bundle2-output-part: "check:phases" 24 bytes payload
753 bundle2-output-part: "check:heads" streamed payload
753 bundle2-output-part: "check:heads" streamed payload
754 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
754 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
755 bundle2-output-part: "phase-heads" 24 bytes payload
755 bundle2-output-part: "phase-heads" 24 bytes payload
756 bundle2-output-part: "bookmarks" 37 bytes payload
756 bundle2-output-part: "bookmarks" 37 bytes payload
757 bundle2-input-bundle: with-transaction
757 bundle2-input-bundle: with-transaction
758 bundle2-input-part: "replycaps" supported
758 bundle2-input-part: "replycaps" supported
759 bundle2-input-part: total payload size 205
759 bundle2-input-part: total payload size 205
760 bundle2-input-part: "check:bookmarks" supported
760 bundle2-input-part: "check:bookmarks" supported
761 bundle2-input-part: total payload size 37
761 bundle2-input-part: total payload size 37
762 bundle2-input-part: "check:phases" supported
762 bundle2-input-part: "check:phases" supported
763 bundle2-input-part: total payload size 24
763 bundle2-input-part: total payload size 24
764 bundle2-input-part: "check:heads" supported
764 bundle2-input-part: "check:heads" supported
765 bundle2-input-part: total payload size 20
765 bundle2-input-part: total payload size 20
766 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
766 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
767 adding changesets
767 adding changesets
768 add changeset ef1ea85a6374
768 add changeset ef1ea85a6374
769 adding manifests
769 adding manifests
770 adding file changes
770 adding file changes
771 adding foo/file.txt revisions
771 adding foo/file.txt revisions
772 calling hook pretxnchangegroup.acl: hgext.acl.hook
772 calling hook pretxnchangegroup.acl: hgext.acl.hook
773 acl: checking access for user "fred"
773 acl: checking access for user "fred"
774 acl: acl.allow.branches not enabled
774 acl: acl.allow.branches not enabled
775 acl: acl.deny.branches not enabled
775 acl: acl.deny.branches not enabled
776 acl: acl.allow enabled, 1 entries for user fred
776 acl: acl.allow enabled, 1 entries for user fred
777 acl: acl.deny enabled, 2 entries for user fred
777 acl: acl.deny enabled, 2 entries for user fred
778 acl: branch access granted: "ef1ea85a6374" on branch "default"
778 acl: branch access granted: "ef1ea85a6374" on branch "default"
779 acl: path access granted: "ef1ea85a6374"
779 acl: path access granted: "ef1ea85a6374"
780 bundle2-input-part: total payload size 520
780 bundle2-input-part: total payload size 520
781 bundle2-input-part: "phase-heads" supported
781 bundle2-input-part: "phase-heads" supported
782 bundle2-input-part: total payload size 24
782 bundle2-input-part: total payload size 24
783 bundle2-input-part: "bookmarks" supported
783 bundle2-input-part: "bookmarks" supported
784 bundle2-input-part: total payload size 37
784 bundle2-input-part: total payload size 37
785 calling hook prepushkey.acl: hgext.acl.hook
785 calling hook prepushkey.acl: hgext.acl.hook
786 acl: checking access for user "fred"
786 acl: checking access for user "fred"
787 acl: acl.allow.bookmarks not enabled
787 acl: acl.allow.bookmarks not enabled
788 acl: acl.deny.bookmarks not enabled
788 acl: acl.deny.bookmarks not enabled
789 acl: bookmark access granted: "ef1ea85a6374b77d6da9dcda9541f498f2d17df7" on bookmark "moving-bookmark"
789 acl: bookmark access granted: "ef1ea85a6374b77d6da9dcda9541f498f2d17df7" on bookmark "moving-bookmark"
790 bundle2-input-bundle: 6 parts total
790 bundle2-input-bundle: 7 parts total
791 updating the branch cache
791 updating the branch cache
792 added 1 changesets with 1 changes to 1 files
792 added 1 changesets with 1 changes to 1 files
793 bundle2-output-bundle: "HG20", 1 parts total
793 bundle2-output-bundle: "HG20", 1 parts total
794 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
794 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
795 bundle2-input-bundle: no-transaction
795 bundle2-input-bundle: no-transaction
796 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
796 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
797 bundle2-input-bundle: 0 parts total
797 bundle2-input-bundle: 1 parts total
798 updating bookmark moving-bookmark
798 updating bookmark moving-bookmark
799 listing keys for "phases"
799 listing keys for "phases"
800 repository tip rolled back to revision 0 (undo push)
800 repository tip rolled back to revision 0 (undo push)
801 0:6675d58eff77
801 0:6675d58eff77
802
802
803
803
804 fred is not allowed to move bookmarks
804 fred is not allowed to move bookmarks
805
805
806 $ echo '[acl.deny.bookmarks]' >> $config
806 $ echo '[acl.deny.bookmarks]' >> $config
807 $ echo '* = fred' >> $config
807 $ echo '* = fred' >> $config
808 $ do_push fred -r 1
808 $ do_push fred -r 1
809 Pushing as user fred
809 Pushing as user fred
810 hgrc = """
810 hgrc = """
811 [hooks]
811 [hooks]
812 pretxnchangegroup.acl = python:hgext.acl.hook
812 pretxnchangegroup.acl = python:hgext.acl.hook
813 prepushkey.acl = python:hgext.acl.hook
813 prepushkey.acl = python:hgext.acl.hook
814 [acl]
814 [acl]
815 sources = push
815 sources = push
816 [acl.allow]
816 [acl.allow]
817 foo/** = fred
817 foo/** = fred
818 [acl.deny]
818 [acl.deny]
819 foo/bar/** = fred
819 foo/bar/** = fred
820 foo/Bar/** = fred
820 foo/Bar/** = fred
821 [acl.deny.bookmarks]
821 [acl.deny.bookmarks]
822 * = fred
822 * = fred
823 """
823 """
824 pushing to ../b
824 pushing to ../b
825 query 1; heads
825 query 1; heads
826 searching for changes
826 searching for changes
827 all remote heads known locally
827 all remote heads known locally
828 listing keys for "phases"
828 listing keys for "phases"
829 checking for updated bookmarks
829 checking for updated bookmarks
830 listing keys for "bookmarks"
830 listing keys for "bookmarks"
831 listing keys for "bookmarks"
831 listing keys for "bookmarks"
832 1 changesets found
832 1 changesets found
833 list of changesets:
833 list of changesets:
834 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
834 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
835 bundle2-output-bundle: "HG20", 7 parts total
835 bundle2-output-bundle: "HG20", 7 parts total
836 bundle2-output-part: "replycaps" 205 bytes payload
836 bundle2-output-part: "replycaps" 205 bytes payload
837 bundle2-output-part: "check:bookmarks" 37 bytes payload
837 bundle2-output-part: "check:bookmarks" 37 bytes payload
838 bundle2-output-part: "check:phases" 24 bytes payload
838 bundle2-output-part: "check:phases" 24 bytes payload
839 bundle2-output-part: "check:heads" streamed payload
839 bundle2-output-part: "check:heads" streamed payload
840 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
840 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
841 bundle2-output-part: "phase-heads" 24 bytes payload
841 bundle2-output-part: "phase-heads" 24 bytes payload
842 bundle2-output-part: "bookmarks" 37 bytes payload
842 bundle2-output-part: "bookmarks" 37 bytes payload
843 bundle2-input-bundle: with-transaction
843 bundle2-input-bundle: with-transaction
844 bundle2-input-part: "replycaps" supported
844 bundle2-input-part: "replycaps" supported
845 bundle2-input-part: total payload size 205
845 bundle2-input-part: total payload size 205
846 bundle2-input-part: "check:bookmarks" supported
846 bundle2-input-part: "check:bookmarks" supported
847 bundle2-input-part: total payload size 37
847 bundle2-input-part: total payload size 37
848 bundle2-input-part: "check:phases" supported
848 bundle2-input-part: "check:phases" supported
849 bundle2-input-part: total payload size 24
849 bundle2-input-part: total payload size 24
850 bundle2-input-part: "check:heads" supported
850 bundle2-input-part: "check:heads" supported
851 bundle2-input-part: total payload size 20
851 bundle2-input-part: total payload size 20
852 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
852 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
853 adding changesets
853 adding changesets
854 add changeset ef1ea85a6374
854 add changeset ef1ea85a6374
855 adding manifests
855 adding manifests
856 adding file changes
856 adding file changes
857 adding foo/file.txt revisions
857 adding foo/file.txt revisions
858 calling hook pretxnchangegroup.acl: hgext.acl.hook
858 calling hook pretxnchangegroup.acl: hgext.acl.hook
859 acl: checking access for user "fred"
859 acl: checking access for user "fred"
860 acl: acl.allow.branches not enabled
860 acl: acl.allow.branches not enabled
861 acl: acl.deny.branches not enabled
861 acl: acl.deny.branches not enabled
862 acl: acl.allow enabled, 1 entries for user fred
862 acl: acl.allow enabled, 1 entries for user fred
863 acl: acl.deny enabled, 2 entries for user fred
863 acl: acl.deny enabled, 2 entries for user fred
864 acl: branch access granted: "ef1ea85a6374" on branch "default"
864 acl: branch access granted: "ef1ea85a6374" on branch "default"
865 acl: path access granted: "ef1ea85a6374"
865 acl: path access granted: "ef1ea85a6374"
866 bundle2-input-part: total payload size 520
866 bundle2-input-part: total payload size 520
867 bundle2-input-part: "phase-heads" supported
867 bundle2-input-part: "phase-heads" supported
868 bundle2-input-part: total payload size 24
868 bundle2-input-part: total payload size 24
869 bundle2-input-part: "bookmarks" supported
869 bundle2-input-part: "bookmarks" supported
870 bundle2-input-part: total payload size 37
870 bundle2-input-part: total payload size 37
871 calling hook prepushkey.acl: hgext.acl.hook
871 calling hook prepushkey.acl: hgext.acl.hook
872 acl: checking access for user "fred"
872 acl: checking access for user "fred"
873 acl: acl.allow.bookmarks not enabled
873 acl: acl.allow.bookmarks not enabled
874 acl: acl.deny.bookmarks enabled, 1 entries for user fred
874 acl: acl.deny.bookmarks enabled, 1 entries for user fred
875 error: prepushkey.acl hook failed: acl: user "fred" denied on bookmark "moving-bookmark" (changeset "ef1ea85a6374b77d6da9dcda9541f498f2d17df7")
875 error: prepushkey.acl hook failed: acl: user "fred" denied on bookmark "moving-bookmark" (changeset "ef1ea85a6374b77d6da9dcda9541f498f2d17df7")
876 bundle2-input-bundle: 6 parts total
876 bundle2-input-bundle: 7 parts total
877 transaction abort!
877 transaction abort!
878 rollback completed
878 rollback completed
879 abort: acl: user "fred" denied on bookmark "moving-bookmark" (changeset "ef1ea85a6374b77d6da9dcda9541f498f2d17df7")
879 abort: acl: user "fred" denied on bookmark "moving-bookmark" (changeset "ef1ea85a6374b77d6da9dcda9541f498f2d17df7")
880 no rollback information available
880 no rollback information available
881 0:6675d58eff77
881 0:6675d58eff77
882
882
883
883
884 cleanup bookmark stuff
884 cleanup bookmark stuff
885
885
886 $ hg book -R a -d moving-bookmark
886 $ hg book -R a -d moving-bookmark
887 $ hg book -R b -d moving-bookmark
887 $ hg book -R b -d moving-bookmark
888 $ cp normalconfig $config
888 $ cp normalconfig $config
889
889
890 barney is allowed everywhere
890 barney is allowed everywhere
891
891
892 $ echo '[acl.allow]' >> $config
892 $ echo '[acl.allow]' >> $config
893 $ echo '** = barney' >> $config
893 $ echo '** = barney' >> $config
894 $ do_push barney
894 $ do_push barney
895 Pushing as user barney
895 Pushing as user barney
896 hgrc = """
896 hgrc = """
897 [hooks]
897 [hooks]
898 pretxnchangegroup.acl = python:hgext.acl.hook
898 pretxnchangegroup.acl = python:hgext.acl.hook
899 prepushkey.acl = python:hgext.acl.hook
899 prepushkey.acl = python:hgext.acl.hook
900 [acl]
900 [acl]
901 sources = push
901 sources = push
902 [acl.allow]
902 [acl.allow]
903 foo/** = fred
903 foo/** = fred
904 [acl.deny]
904 [acl.deny]
905 foo/bar/** = fred
905 foo/bar/** = fred
906 foo/Bar/** = fred
906 foo/Bar/** = fred
907 [acl.allow]
907 [acl.allow]
908 ** = barney
908 ** = barney
909 """
909 """
910 pushing to ../b
910 pushing to ../b
911 query 1; heads
911 query 1; heads
912 searching for changes
912 searching for changes
913 all remote heads known locally
913 all remote heads known locally
914 listing keys for "phases"
914 listing keys for "phases"
915 checking for updated bookmarks
915 checking for updated bookmarks
916 listing keys for "bookmarks"
916 listing keys for "bookmarks"
917 listing keys for "bookmarks"
917 listing keys for "bookmarks"
918 3 changesets found
918 3 changesets found
919 list of changesets:
919 list of changesets:
920 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
920 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
921 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
921 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
922 911600dab2ae7a9baff75958b84fe606851ce955
922 911600dab2ae7a9baff75958b84fe606851ce955
923 bundle2-output-bundle: "HG20", 5 parts total
923 bundle2-output-bundle: "HG20", 5 parts total
924 bundle2-output-part: "replycaps" 205 bytes payload
924 bundle2-output-part: "replycaps" 205 bytes payload
925 bundle2-output-part: "check:phases" 24 bytes payload
925 bundle2-output-part: "check:phases" 24 bytes payload
926 bundle2-output-part: "check:heads" streamed payload
926 bundle2-output-part: "check:heads" streamed payload
927 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
927 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
928 bundle2-output-part: "phase-heads" 24 bytes payload
928 bundle2-output-part: "phase-heads" 24 bytes payload
929 bundle2-input-bundle: with-transaction
929 bundle2-input-bundle: with-transaction
930 bundle2-input-part: "replycaps" supported
930 bundle2-input-part: "replycaps" supported
931 bundle2-input-part: total payload size 205
931 bundle2-input-part: total payload size 205
932 bundle2-input-part: "check:phases" supported
932 bundle2-input-part: "check:phases" supported
933 bundle2-input-part: total payload size 24
933 bundle2-input-part: total payload size 24
934 bundle2-input-part: "check:heads" supported
934 bundle2-input-part: "check:heads" supported
935 bundle2-input-part: total payload size 20
935 bundle2-input-part: total payload size 20
936 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
936 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
937 adding changesets
937 adding changesets
938 add changeset ef1ea85a6374
938 add changeset ef1ea85a6374
939 add changeset f9cafe1212c8
939 add changeset f9cafe1212c8
940 add changeset 911600dab2ae
940 add changeset 911600dab2ae
941 adding manifests
941 adding manifests
942 adding file changes
942 adding file changes
943 adding foo/Bar/file.txt revisions
943 adding foo/Bar/file.txt revisions
944 adding foo/file.txt revisions
944 adding foo/file.txt revisions
945 adding quux/file.py revisions
945 adding quux/file.py revisions
946 calling hook pretxnchangegroup.acl: hgext.acl.hook
946 calling hook pretxnchangegroup.acl: hgext.acl.hook
947 acl: checking access for user "barney"
947 acl: checking access for user "barney"
948 acl: acl.allow.branches not enabled
948 acl: acl.allow.branches not enabled
949 acl: acl.deny.branches not enabled
949 acl: acl.deny.branches not enabled
950 acl: acl.allow enabled, 1 entries for user barney
950 acl: acl.allow enabled, 1 entries for user barney
951 acl: acl.deny enabled, 0 entries for user barney
951 acl: acl.deny enabled, 0 entries for user barney
952 acl: branch access granted: "ef1ea85a6374" on branch "default"
952 acl: branch access granted: "ef1ea85a6374" on branch "default"
953 acl: path access granted: "ef1ea85a6374"
953 acl: path access granted: "ef1ea85a6374"
954 acl: branch access granted: "f9cafe1212c8" on branch "default"
954 acl: branch access granted: "f9cafe1212c8" on branch "default"
955 acl: path access granted: "f9cafe1212c8"
955 acl: path access granted: "f9cafe1212c8"
956 acl: branch access granted: "911600dab2ae" on branch "default"
956 acl: branch access granted: "911600dab2ae" on branch "default"
957 acl: path access granted: "911600dab2ae"
957 acl: path access granted: "911600dab2ae"
958 bundle2-input-part: total payload size 1553
958 bundle2-input-part: total payload size 1553
959 bundle2-input-part: "phase-heads" supported
959 bundle2-input-part: "phase-heads" supported
960 bundle2-input-part: total payload size 24
960 bundle2-input-part: total payload size 24
961 bundle2-input-bundle: 4 parts total
961 bundle2-input-bundle: 5 parts total
962 updating the branch cache
962 updating the branch cache
963 added 3 changesets with 3 changes to 3 files
963 added 3 changesets with 3 changes to 3 files
964 bundle2-output-bundle: "HG20", 1 parts total
964 bundle2-output-bundle: "HG20", 1 parts total
965 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
965 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
966 bundle2-input-bundle: no-transaction
966 bundle2-input-bundle: no-transaction
967 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
967 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
968 bundle2-input-bundle: 0 parts total
968 bundle2-input-bundle: 1 parts total
969 listing keys for "phases"
969 listing keys for "phases"
970 repository tip rolled back to revision 0 (undo push)
970 repository tip rolled back to revision 0 (undo push)
971 0:6675d58eff77
971 0:6675d58eff77
972
972
973
973
974 wilma can change files with a .txt extension
974 wilma can change files with a .txt extension
975
975
976 $ echo '**/*.txt = wilma' >> $config
976 $ echo '**/*.txt = wilma' >> $config
977 $ do_push wilma
977 $ do_push wilma
978 Pushing as user wilma
978 Pushing as user wilma
979 hgrc = """
979 hgrc = """
980 [hooks]
980 [hooks]
981 pretxnchangegroup.acl = python:hgext.acl.hook
981 pretxnchangegroup.acl = python:hgext.acl.hook
982 prepushkey.acl = python:hgext.acl.hook
982 prepushkey.acl = python:hgext.acl.hook
983 [acl]
983 [acl]
984 sources = push
984 sources = push
985 [acl.allow]
985 [acl.allow]
986 foo/** = fred
986 foo/** = fred
987 [acl.deny]
987 [acl.deny]
988 foo/bar/** = fred
988 foo/bar/** = fred
989 foo/Bar/** = fred
989 foo/Bar/** = fred
990 [acl.allow]
990 [acl.allow]
991 ** = barney
991 ** = barney
992 **/*.txt = wilma
992 **/*.txt = wilma
993 """
993 """
994 pushing to ../b
994 pushing to ../b
995 query 1; heads
995 query 1; heads
996 searching for changes
996 searching for changes
997 all remote heads known locally
997 all remote heads known locally
998 listing keys for "phases"
998 listing keys for "phases"
999 checking for updated bookmarks
999 checking for updated bookmarks
1000 listing keys for "bookmarks"
1000 listing keys for "bookmarks"
1001 listing keys for "bookmarks"
1001 listing keys for "bookmarks"
1002 3 changesets found
1002 3 changesets found
1003 list of changesets:
1003 list of changesets:
1004 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1004 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1005 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1005 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1006 911600dab2ae7a9baff75958b84fe606851ce955
1006 911600dab2ae7a9baff75958b84fe606851ce955
1007 bundle2-output-bundle: "HG20", 5 parts total
1007 bundle2-output-bundle: "HG20", 5 parts total
1008 bundle2-output-part: "replycaps" 205 bytes payload
1008 bundle2-output-part: "replycaps" 205 bytes payload
1009 bundle2-output-part: "check:phases" 24 bytes payload
1009 bundle2-output-part: "check:phases" 24 bytes payload
1010 bundle2-output-part: "check:heads" streamed payload
1010 bundle2-output-part: "check:heads" streamed payload
1011 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1011 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1012 bundle2-output-part: "phase-heads" 24 bytes payload
1012 bundle2-output-part: "phase-heads" 24 bytes payload
1013 bundle2-input-bundle: with-transaction
1013 bundle2-input-bundle: with-transaction
1014 bundle2-input-part: "replycaps" supported
1014 bundle2-input-part: "replycaps" supported
1015 bundle2-input-part: total payload size 205
1015 bundle2-input-part: total payload size 205
1016 bundle2-input-part: "check:phases" supported
1016 bundle2-input-part: "check:phases" supported
1017 bundle2-input-part: total payload size 24
1017 bundle2-input-part: total payload size 24
1018 bundle2-input-part: "check:heads" supported
1018 bundle2-input-part: "check:heads" supported
1019 bundle2-input-part: total payload size 20
1019 bundle2-input-part: total payload size 20
1020 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1020 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1021 adding changesets
1021 adding changesets
1022 add changeset ef1ea85a6374
1022 add changeset ef1ea85a6374
1023 add changeset f9cafe1212c8
1023 add changeset f9cafe1212c8
1024 add changeset 911600dab2ae
1024 add changeset 911600dab2ae
1025 adding manifests
1025 adding manifests
1026 adding file changes
1026 adding file changes
1027 adding foo/Bar/file.txt revisions
1027 adding foo/Bar/file.txt revisions
1028 adding foo/file.txt revisions
1028 adding foo/file.txt revisions
1029 adding quux/file.py revisions
1029 adding quux/file.py revisions
1030 calling hook pretxnchangegroup.acl: hgext.acl.hook
1030 calling hook pretxnchangegroup.acl: hgext.acl.hook
1031 acl: checking access for user "wilma"
1031 acl: checking access for user "wilma"
1032 acl: acl.allow.branches not enabled
1032 acl: acl.allow.branches not enabled
1033 acl: acl.deny.branches not enabled
1033 acl: acl.deny.branches not enabled
1034 acl: acl.allow enabled, 1 entries for user wilma
1034 acl: acl.allow enabled, 1 entries for user wilma
1035 acl: acl.deny enabled, 0 entries for user wilma
1035 acl: acl.deny enabled, 0 entries for user wilma
1036 acl: branch access granted: "ef1ea85a6374" on branch "default"
1036 acl: branch access granted: "ef1ea85a6374" on branch "default"
1037 acl: path access granted: "ef1ea85a6374"
1037 acl: path access granted: "ef1ea85a6374"
1038 acl: branch access granted: "f9cafe1212c8" on branch "default"
1038 acl: branch access granted: "f9cafe1212c8" on branch "default"
1039 acl: path access granted: "f9cafe1212c8"
1039 acl: path access granted: "f9cafe1212c8"
1040 acl: branch access granted: "911600dab2ae" on branch "default"
1040 acl: branch access granted: "911600dab2ae" on branch "default"
1041 error: pretxnchangegroup.acl hook failed: acl: user "wilma" not allowed on "quux/file.py" (changeset "911600dab2ae")
1041 error: pretxnchangegroup.acl hook failed: acl: user "wilma" not allowed on "quux/file.py" (changeset "911600dab2ae")
1042 bundle2-input-part: total payload size 1553
1042 bundle2-input-part: total payload size 1553
1043 bundle2-input-part: total payload size 24
1043 bundle2-input-part: total payload size 24
1044 bundle2-input-bundle: 4 parts total
1044 bundle2-input-bundle: 5 parts total
1045 transaction abort!
1045 transaction abort!
1046 rollback completed
1046 rollback completed
1047 abort: acl: user "wilma" not allowed on "quux/file.py" (changeset "911600dab2ae")
1047 abort: acl: user "wilma" not allowed on "quux/file.py" (changeset "911600dab2ae")
1048 no rollback information available
1048 no rollback information available
1049 0:6675d58eff77
1049 0:6675d58eff77
1050
1050
1051
1051
1052 file specified by acl.config does not exist
1052 file specified by acl.config does not exist
1053
1053
1054 $ echo '[acl]' >> $config
1054 $ echo '[acl]' >> $config
1055 $ echo 'config = ../acl.config' >> $config
1055 $ echo 'config = ../acl.config' >> $config
1056 $ do_push barney
1056 $ do_push barney
1057 Pushing as user barney
1057 Pushing as user barney
1058 hgrc = """
1058 hgrc = """
1059 [hooks]
1059 [hooks]
1060 pretxnchangegroup.acl = python:hgext.acl.hook
1060 pretxnchangegroup.acl = python:hgext.acl.hook
1061 prepushkey.acl = python:hgext.acl.hook
1061 prepushkey.acl = python:hgext.acl.hook
1062 [acl]
1062 [acl]
1063 sources = push
1063 sources = push
1064 [acl.allow]
1064 [acl.allow]
1065 foo/** = fred
1065 foo/** = fred
1066 [acl.deny]
1066 [acl.deny]
1067 foo/bar/** = fred
1067 foo/bar/** = fred
1068 foo/Bar/** = fred
1068 foo/Bar/** = fred
1069 [acl.allow]
1069 [acl.allow]
1070 ** = barney
1070 ** = barney
1071 **/*.txt = wilma
1071 **/*.txt = wilma
1072 [acl]
1072 [acl]
1073 config = ../acl.config
1073 config = ../acl.config
1074 """
1074 """
1075 pushing to ../b
1075 pushing to ../b
1076 query 1; heads
1076 query 1; heads
1077 searching for changes
1077 searching for changes
1078 all remote heads known locally
1078 all remote heads known locally
1079 listing keys for "phases"
1079 listing keys for "phases"
1080 checking for updated bookmarks
1080 checking for updated bookmarks
1081 listing keys for "bookmarks"
1081 listing keys for "bookmarks"
1082 listing keys for "bookmarks"
1082 listing keys for "bookmarks"
1083 3 changesets found
1083 3 changesets found
1084 list of changesets:
1084 list of changesets:
1085 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1085 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1086 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1086 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1087 911600dab2ae7a9baff75958b84fe606851ce955
1087 911600dab2ae7a9baff75958b84fe606851ce955
1088 bundle2-output-bundle: "HG20", 5 parts total
1088 bundle2-output-bundle: "HG20", 5 parts total
1089 bundle2-output-part: "replycaps" 205 bytes payload
1089 bundle2-output-part: "replycaps" 205 bytes payload
1090 bundle2-output-part: "check:phases" 24 bytes payload
1090 bundle2-output-part: "check:phases" 24 bytes payload
1091 bundle2-output-part: "check:heads" streamed payload
1091 bundle2-output-part: "check:heads" streamed payload
1092 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1092 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1093 bundle2-output-part: "phase-heads" 24 bytes payload
1093 bundle2-output-part: "phase-heads" 24 bytes payload
1094 bundle2-input-bundle: with-transaction
1094 bundle2-input-bundle: with-transaction
1095 bundle2-input-part: "replycaps" supported
1095 bundle2-input-part: "replycaps" supported
1096 bundle2-input-part: total payload size 205
1096 bundle2-input-part: total payload size 205
1097 bundle2-input-part: "check:phases" supported
1097 bundle2-input-part: "check:phases" supported
1098 bundle2-input-part: total payload size 24
1098 bundle2-input-part: total payload size 24
1099 bundle2-input-part: "check:heads" supported
1099 bundle2-input-part: "check:heads" supported
1100 bundle2-input-part: total payload size 20
1100 bundle2-input-part: total payload size 20
1101 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1101 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1102 adding changesets
1102 adding changesets
1103 add changeset ef1ea85a6374
1103 add changeset ef1ea85a6374
1104 add changeset f9cafe1212c8
1104 add changeset f9cafe1212c8
1105 add changeset 911600dab2ae
1105 add changeset 911600dab2ae
1106 adding manifests
1106 adding manifests
1107 adding file changes
1107 adding file changes
1108 adding foo/Bar/file.txt revisions
1108 adding foo/Bar/file.txt revisions
1109 adding foo/file.txt revisions
1109 adding foo/file.txt revisions
1110 adding quux/file.py revisions
1110 adding quux/file.py revisions
1111 calling hook pretxnchangegroup.acl: hgext.acl.hook
1111 calling hook pretxnchangegroup.acl: hgext.acl.hook
1112 acl: checking access for user "barney"
1112 acl: checking access for user "barney"
1113 error: pretxnchangegroup.acl hook raised an exception: [Errno *] * (glob)
1113 error: pretxnchangegroup.acl hook raised an exception: [Errno *] * (glob)
1114 bundle2-input-part: total payload size 1553
1114 bundle2-input-part: total payload size 1553
1115 bundle2-input-part: total payload size 24
1115 bundle2-input-part: total payload size 24
1116 bundle2-input-bundle: 4 parts total
1116 bundle2-input-bundle: 5 parts total
1117 transaction abort!
1117 transaction abort!
1118 rollback completed
1118 rollback completed
1119 abort: $ENOENT$: '../acl.config'
1119 abort: $ENOENT$: '../acl.config'
1120 no rollback information available
1120 no rollback information available
1121 0:6675d58eff77
1121 0:6675d58eff77
1122
1122
1123
1123
1124 betty is allowed inside foo/ by a acl.config file
1124 betty is allowed inside foo/ by a acl.config file
1125
1125
1126 $ echo '[acl.allow]' >> acl.config
1126 $ echo '[acl.allow]' >> acl.config
1127 $ echo 'foo/** = betty' >> acl.config
1127 $ echo 'foo/** = betty' >> acl.config
1128 $ do_push betty
1128 $ do_push betty
1129 Pushing as user betty
1129 Pushing as user betty
1130 hgrc = """
1130 hgrc = """
1131 [hooks]
1131 [hooks]
1132 pretxnchangegroup.acl = python:hgext.acl.hook
1132 pretxnchangegroup.acl = python:hgext.acl.hook
1133 prepushkey.acl = python:hgext.acl.hook
1133 prepushkey.acl = python:hgext.acl.hook
1134 [acl]
1134 [acl]
1135 sources = push
1135 sources = push
1136 [acl.allow]
1136 [acl.allow]
1137 foo/** = fred
1137 foo/** = fred
1138 [acl.deny]
1138 [acl.deny]
1139 foo/bar/** = fred
1139 foo/bar/** = fred
1140 foo/Bar/** = fred
1140 foo/Bar/** = fred
1141 [acl.allow]
1141 [acl.allow]
1142 ** = barney
1142 ** = barney
1143 **/*.txt = wilma
1143 **/*.txt = wilma
1144 [acl]
1144 [acl]
1145 config = ../acl.config
1145 config = ../acl.config
1146 """
1146 """
1147 acl.config = """
1147 acl.config = """
1148 [acl.allow]
1148 [acl.allow]
1149 foo/** = betty
1149 foo/** = betty
1150 """
1150 """
1151 pushing to ../b
1151 pushing to ../b
1152 query 1; heads
1152 query 1; heads
1153 searching for changes
1153 searching for changes
1154 all remote heads known locally
1154 all remote heads known locally
1155 listing keys for "phases"
1155 listing keys for "phases"
1156 checking for updated bookmarks
1156 checking for updated bookmarks
1157 listing keys for "bookmarks"
1157 listing keys for "bookmarks"
1158 listing keys for "bookmarks"
1158 listing keys for "bookmarks"
1159 3 changesets found
1159 3 changesets found
1160 list of changesets:
1160 list of changesets:
1161 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1161 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1162 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1162 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1163 911600dab2ae7a9baff75958b84fe606851ce955
1163 911600dab2ae7a9baff75958b84fe606851ce955
1164 bundle2-output-bundle: "HG20", 5 parts total
1164 bundle2-output-bundle: "HG20", 5 parts total
1165 bundle2-output-part: "replycaps" 205 bytes payload
1165 bundle2-output-part: "replycaps" 205 bytes payload
1166 bundle2-output-part: "check:phases" 24 bytes payload
1166 bundle2-output-part: "check:phases" 24 bytes payload
1167 bundle2-output-part: "check:heads" streamed payload
1167 bundle2-output-part: "check:heads" streamed payload
1168 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1168 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1169 bundle2-output-part: "phase-heads" 24 bytes payload
1169 bundle2-output-part: "phase-heads" 24 bytes payload
1170 bundle2-input-bundle: with-transaction
1170 bundle2-input-bundle: with-transaction
1171 bundle2-input-part: "replycaps" supported
1171 bundle2-input-part: "replycaps" supported
1172 bundle2-input-part: total payload size 205
1172 bundle2-input-part: total payload size 205
1173 bundle2-input-part: "check:phases" supported
1173 bundle2-input-part: "check:phases" supported
1174 bundle2-input-part: total payload size 24
1174 bundle2-input-part: total payload size 24
1175 bundle2-input-part: "check:heads" supported
1175 bundle2-input-part: "check:heads" supported
1176 bundle2-input-part: total payload size 20
1176 bundle2-input-part: total payload size 20
1177 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1177 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1178 adding changesets
1178 adding changesets
1179 add changeset ef1ea85a6374
1179 add changeset ef1ea85a6374
1180 add changeset f9cafe1212c8
1180 add changeset f9cafe1212c8
1181 add changeset 911600dab2ae
1181 add changeset 911600dab2ae
1182 adding manifests
1182 adding manifests
1183 adding file changes
1183 adding file changes
1184 adding foo/Bar/file.txt revisions
1184 adding foo/Bar/file.txt revisions
1185 adding foo/file.txt revisions
1185 adding foo/file.txt revisions
1186 adding quux/file.py revisions
1186 adding quux/file.py revisions
1187 calling hook pretxnchangegroup.acl: hgext.acl.hook
1187 calling hook pretxnchangegroup.acl: hgext.acl.hook
1188 acl: checking access for user "betty"
1188 acl: checking access for user "betty"
1189 acl: acl.allow.branches not enabled
1189 acl: acl.allow.branches not enabled
1190 acl: acl.deny.branches not enabled
1190 acl: acl.deny.branches not enabled
1191 acl: acl.allow enabled, 1 entries for user betty
1191 acl: acl.allow enabled, 1 entries for user betty
1192 acl: acl.deny enabled, 0 entries for user betty
1192 acl: acl.deny enabled, 0 entries for user betty
1193 acl: branch access granted: "ef1ea85a6374" on branch "default"
1193 acl: branch access granted: "ef1ea85a6374" on branch "default"
1194 acl: path access granted: "ef1ea85a6374"
1194 acl: path access granted: "ef1ea85a6374"
1195 acl: branch access granted: "f9cafe1212c8" on branch "default"
1195 acl: branch access granted: "f9cafe1212c8" on branch "default"
1196 acl: path access granted: "f9cafe1212c8"
1196 acl: path access granted: "f9cafe1212c8"
1197 acl: branch access granted: "911600dab2ae" on branch "default"
1197 acl: branch access granted: "911600dab2ae" on branch "default"
1198 error: pretxnchangegroup.acl hook failed: acl: user "betty" not allowed on "quux/file.py" (changeset "911600dab2ae")
1198 error: pretxnchangegroup.acl hook failed: acl: user "betty" not allowed on "quux/file.py" (changeset "911600dab2ae")
1199 bundle2-input-part: total payload size 1553
1199 bundle2-input-part: total payload size 1553
1200 bundle2-input-part: total payload size 24
1200 bundle2-input-part: total payload size 24
1201 bundle2-input-bundle: 4 parts total
1201 bundle2-input-bundle: 5 parts total
1202 transaction abort!
1202 transaction abort!
1203 rollback completed
1203 rollback completed
1204 abort: acl: user "betty" not allowed on "quux/file.py" (changeset "911600dab2ae")
1204 abort: acl: user "betty" not allowed on "quux/file.py" (changeset "911600dab2ae")
1205 no rollback information available
1205 no rollback information available
1206 0:6675d58eff77
1206 0:6675d58eff77
1207
1207
1208
1208
1209 acl.config can set only [acl.allow]/[acl.deny]
1209 acl.config can set only [acl.allow]/[acl.deny]
1210
1210
1211 $ echo '[hooks]' >> acl.config
1211 $ echo '[hooks]' >> acl.config
1212 $ echo 'changegroup.acl = false' >> acl.config
1212 $ echo 'changegroup.acl = false' >> acl.config
1213 $ do_push barney
1213 $ do_push barney
1214 Pushing as user barney
1214 Pushing as user barney
1215 hgrc = """
1215 hgrc = """
1216 [hooks]
1216 [hooks]
1217 pretxnchangegroup.acl = python:hgext.acl.hook
1217 pretxnchangegroup.acl = python:hgext.acl.hook
1218 prepushkey.acl = python:hgext.acl.hook
1218 prepushkey.acl = python:hgext.acl.hook
1219 [acl]
1219 [acl]
1220 sources = push
1220 sources = push
1221 [acl.allow]
1221 [acl.allow]
1222 foo/** = fred
1222 foo/** = fred
1223 [acl.deny]
1223 [acl.deny]
1224 foo/bar/** = fred
1224 foo/bar/** = fred
1225 foo/Bar/** = fred
1225 foo/Bar/** = fred
1226 [acl.allow]
1226 [acl.allow]
1227 ** = barney
1227 ** = barney
1228 **/*.txt = wilma
1228 **/*.txt = wilma
1229 [acl]
1229 [acl]
1230 config = ../acl.config
1230 config = ../acl.config
1231 """
1231 """
1232 acl.config = """
1232 acl.config = """
1233 [acl.allow]
1233 [acl.allow]
1234 foo/** = betty
1234 foo/** = betty
1235 [hooks]
1235 [hooks]
1236 changegroup.acl = false
1236 changegroup.acl = false
1237 """
1237 """
1238 pushing to ../b
1238 pushing to ../b
1239 query 1; heads
1239 query 1; heads
1240 searching for changes
1240 searching for changes
1241 all remote heads known locally
1241 all remote heads known locally
1242 listing keys for "phases"
1242 listing keys for "phases"
1243 checking for updated bookmarks
1243 checking for updated bookmarks
1244 listing keys for "bookmarks"
1244 listing keys for "bookmarks"
1245 listing keys for "bookmarks"
1245 listing keys for "bookmarks"
1246 3 changesets found
1246 3 changesets found
1247 list of changesets:
1247 list of changesets:
1248 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1248 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1249 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1249 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1250 911600dab2ae7a9baff75958b84fe606851ce955
1250 911600dab2ae7a9baff75958b84fe606851ce955
1251 bundle2-output-bundle: "HG20", 5 parts total
1251 bundle2-output-bundle: "HG20", 5 parts total
1252 bundle2-output-part: "replycaps" 205 bytes payload
1252 bundle2-output-part: "replycaps" 205 bytes payload
1253 bundle2-output-part: "check:phases" 24 bytes payload
1253 bundle2-output-part: "check:phases" 24 bytes payload
1254 bundle2-output-part: "check:heads" streamed payload
1254 bundle2-output-part: "check:heads" streamed payload
1255 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1255 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1256 bundle2-output-part: "phase-heads" 24 bytes payload
1256 bundle2-output-part: "phase-heads" 24 bytes payload
1257 bundle2-input-bundle: with-transaction
1257 bundle2-input-bundle: with-transaction
1258 bundle2-input-part: "replycaps" supported
1258 bundle2-input-part: "replycaps" supported
1259 bundle2-input-part: total payload size 205
1259 bundle2-input-part: total payload size 205
1260 bundle2-input-part: "check:phases" supported
1260 bundle2-input-part: "check:phases" supported
1261 bundle2-input-part: total payload size 24
1261 bundle2-input-part: total payload size 24
1262 bundle2-input-part: "check:heads" supported
1262 bundle2-input-part: "check:heads" supported
1263 bundle2-input-part: total payload size 20
1263 bundle2-input-part: total payload size 20
1264 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1264 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1265 adding changesets
1265 adding changesets
1266 add changeset ef1ea85a6374
1266 add changeset ef1ea85a6374
1267 add changeset f9cafe1212c8
1267 add changeset f9cafe1212c8
1268 add changeset 911600dab2ae
1268 add changeset 911600dab2ae
1269 adding manifests
1269 adding manifests
1270 adding file changes
1270 adding file changes
1271 adding foo/Bar/file.txt revisions
1271 adding foo/Bar/file.txt revisions
1272 adding foo/file.txt revisions
1272 adding foo/file.txt revisions
1273 adding quux/file.py revisions
1273 adding quux/file.py revisions
1274 calling hook pretxnchangegroup.acl: hgext.acl.hook
1274 calling hook pretxnchangegroup.acl: hgext.acl.hook
1275 acl: checking access for user "barney"
1275 acl: checking access for user "barney"
1276 acl: acl.allow.branches not enabled
1276 acl: acl.allow.branches not enabled
1277 acl: acl.deny.branches not enabled
1277 acl: acl.deny.branches not enabled
1278 acl: acl.allow enabled, 1 entries for user barney
1278 acl: acl.allow enabled, 1 entries for user barney
1279 acl: acl.deny enabled, 0 entries for user barney
1279 acl: acl.deny enabled, 0 entries for user barney
1280 acl: branch access granted: "ef1ea85a6374" on branch "default"
1280 acl: branch access granted: "ef1ea85a6374" on branch "default"
1281 acl: path access granted: "ef1ea85a6374"
1281 acl: path access granted: "ef1ea85a6374"
1282 acl: branch access granted: "f9cafe1212c8" on branch "default"
1282 acl: branch access granted: "f9cafe1212c8" on branch "default"
1283 acl: path access granted: "f9cafe1212c8"
1283 acl: path access granted: "f9cafe1212c8"
1284 acl: branch access granted: "911600dab2ae" on branch "default"
1284 acl: branch access granted: "911600dab2ae" on branch "default"
1285 acl: path access granted: "911600dab2ae"
1285 acl: path access granted: "911600dab2ae"
1286 bundle2-input-part: total payload size 1553
1286 bundle2-input-part: total payload size 1553
1287 bundle2-input-part: "phase-heads" supported
1287 bundle2-input-part: "phase-heads" supported
1288 bundle2-input-part: total payload size 24
1288 bundle2-input-part: total payload size 24
1289 bundle2-input-bundle: 4 parts total
1289 bundle2-input-bundle: 5 parts total
1290 updating the branch cache
1290 updating the branch cache
1291 added 3 changesets with 3 changes to 3 files
1291 added 3 changesets with 3 changes to 3 files
1292 bundle2-output-bundle: "HG20", 1 parts total
1292 bundle2-output-bundle: "HG20", 1 parts total
1293 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
1293 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
1294 bundle2-input-bundle: no-transaction
1294 bundle2-input-bundle: no-transaction
1295 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
1295 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
1296 bundle2-input-bundle: 0 parts total
1296 bundle2-input-bundle: 1 parts total
1297 listing keys for "phases"
1297 listing keys for "phases"
1298 repository tip rolled back to revision 0 (undo push)
1298 repository tip rolled back to revision 0 (undo push)
1299 0:6675d58eff77
1299 0:6675d58eff77
1300
1300
1301
1301
1302 asterisk
1302 asterisk
1303
1303
1304 $ init_config
1304 $ init_config
1305
1305
1306 asterisk test
1306 asterisk test
1307
1307
1308 $ echo '[acl.allow]' >> $config
1308 $ echo '[acl.allow]' >> $config
1309 $ echo "** = fred" >> $config
1309 $ echo "** = fred" >> $config
1310
1310
1311 fred is always allowed
1311 fred is always allowed
1312
1312
1313 $ do_push fred
1313 $ do_push fred
1314 Pushing as user fred
1314 Pushing as user fred
1315 hgrc = """
1315 hgrc = """
1316 [hooks]
1316 [hooks]
1317 pretxnchangegroup.acl = python:hgext.acl.hook
1317 pretxnchangegroup.acl = python:hgext.acl.hook
1318 prepushkey.acl = python:hgext.acl.hook
1318 prepushkey.acl = python:hgext.acl.hook
1319 [acl]
1319 [acl]
1320 sources = push
1320 sources = push
1321 [extensions]
1321 [extensions]
1322 posixgetuser=$TESTTMP/posixgetuser.py
1322 posixgetuser=$TESTTMP/posixgetuser.py
1323 [acl.allow]
1323 [acl.allow]
1324 ** = fred
1324 ** = fred
1325 """
1325 """
1326 pushing to ../b
1326 pushing to ../b
1327 query 1; heads
1327 query 1; heads
1328 searching for changes
1328 searching for changes
1329 all remote heads known locally
1329 all remote heads known locally
1330 listing keys for "phases"
1330 listing keys for "phases"
1331 checking for updated bookmarks
1331 checking for updated bookmarks
1332 listing keys for "bookmarks"
1332 listing keys for "bookmarks"
1333 listing keys for "bookmarks"
1333 listing keys for "bookmarks"
1334 3 changesets found
1334 3 changesets found
1335 list of changesets:
1335 list of changesets:
1336 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1336 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1337 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1337 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1338 911600dab2ae7a9baff75958b84fe606851ce955
1338 911600dab2ae7a9baff75958b84fe606851ce955
1339 bundle2-output-bundle: "HG20", 5 parts total
1339 bundle2-output-bundle: "HG20", 5 parts total
1340 bundle2-output-part: "replycaps" 205 bytes payload
1340 bundle2-output-part: "replycaps" 205 bytes payload
1341 bundle2-output-part: "check:phases" 24 bytes payload
1341 bundle2-output-part: "check:phases" 24 bytes payload
1342 bundle2-output-part: "check:heads" streamed payload
1342 bundle2-output-part: "check:heads" streamed payload
1343 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1343 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1344 bundle2-output-part: "phase-heads" 24 bytes payload
1344 bundle2-output-part: "phase-heads" 24 bytes payload
1345 bundle2-input-bundle: with-transaction
1345 bundle2-input-bundle: with-transaction
1346 bundle2-input-part: "replycaps" supported
1346 bundle2-input-part: "replycaps" supported
1347 bundle2-input-part: total payload size 205
1347 bundle2-input-part: total payload size 205
1348 bundle2-input-part: "check:phases" supported
1348 bundle2-input-part: "check:phases" supported
1349 bundle2-input-part: total payload size 24
1349 bundle2-input-part: total payload size 24
1350 bundle2-input-part: "check:heads" supported
1350 bundle2-input-part: "check:heads" supported
1351 bundle2-input-part: total payload size 20
1351 bundle2-input-part: total payload size 20
1352 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1352 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1353 adding changesets
1353 adding changesets
1354 add changeset ef1ea85a6374
1354 add changeset ef1ea85a6374
1355 add changeset f9cafe1212c8
1355 add changeset f9cafe1212c8
1356 add changeset 911600dab2ae
1356 add changeset 911600dab2ae
1357 adding manifests
1357 adding manifests
1358 adding file changes
1358 adding file changes
1359 adding foo/Bar/file.txt revisions
1359 adding foo/Bar/file.txt revisions
1360 adding foo/file.txt revisions
1360 adding foo/file.txt revisions
1361 adding quux/file.py revisions
1361 adding quux/file.py revisions
1362 calling hook pretxnchangegroup.acl: hgext.acl.hook
1362 calling hook pretxnchangegroup.acl: hgext.acl.hook
1363 acl: checking access for user "fred"
1363 acl: checking access for user "fred"
1364 acl: acl.allow.branches not enabled
1364 acl: acl.allow.branches not enabled
1365 acl: acl.deny.branches not enabled
1365 acl: acl.deny.branches not enabled
1366 acl: acl.allow enabled, 1 entries for user fred
1366 acl: acl.allow enabled, 1 entries for user fred
1367 acl: acl.deny not enabled
1367 acl: acl.deny not enabled
1368 acl: branch access granted: "ef1ea85a6374" on branch "default"
1368 acl: branch access granted: "ef1ea85a6374" on branch "default"
1369 acl: path access granted: "ef1ea85a6374"
1369 acl: path access granted: "ef1ea85a6374"
1370 acl: branch access granted: "f9cafe1212c8" on branch "default"
1370 acl: branch access granted: "f9cafe1212c8" on branch "default"
1371 acl: path access granted: "f9cafe1212c8"
1371 acl: path access granted: "f9cafe1212c8"
1372 acl: branch access granted: "911600dab2ae" on branch "default"
1372 acl: branch access granted: "911600dab2ae" on branch "default"
1373 acl: path access granted: "911600dab2ae"
1373 acl: path access granted: "911600dab2ae"
1374 bundle2-input-part: total payload size 1553
1374 bundle2-input-part: total payload size 1553
1375 bundle2-input-part: "phase-heads" supported
1375 bundle2-input-part: "phase-heads" supported
1376 bundle2-input-part: total payload size 24
1376 bundle2-input-part: total payload size 24
1377 bundle2-input-bundle: 4 parts total
1377 bundle2-input-bundle: 5 parts total
1378 updating the branch cache
1378 updating the branch cache
1379 added 3 changesets with 3 changes to 3 files
1379 added 3 changesets with 3 changes to 3 files
1380 bundle2-output-bundle: "HG20", 1 parts total
1380 bundle2-output-bundle: "HG20", 1 parts total
1381 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
1381 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
1382 bundle2-input-bundle: no-transaction
1382 bundle2-input-bundle: no-transaction
1383 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
1383 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
1384 bundle2-input-bundle: 0 parts total
1384 bundle2-input-bundle: 1 parts total
1385 listing keys for "phases"
1385 listing keys for "phases"
1386 repository tip rolled back to revision 0 (undo push)
1386 repository tip rolled back to revision 0 (undo push)
1387 0:6675d58eff77
1387 0:6675d58eff77
1388
1388
1389
1389
1390 $ echo '[acl.deny]' >> $config
1390 $ echo '[acl.deny]' >> $config
1391 $ echo "foo/Bar/** = *" >> $config
1391 $ echo "foo/Bar/** = *" >> $config
1392
1392
1393 no one is allowed inside foo/Bar/
1393 no one is allowed inside foo/Bar/
1394
1394
1395 $ do_push fred
1395 $ do_push fred
1396 Pushing as user fred
1396 Pushing as user fred
1397 hgrc = """
1397 hgrc = """
1398 [hooks]
1398 [hooks]
1399 pretxnchangegroup.acl = python:hgext.acl.hook
1399 pretxnchangegroup.acl = python:hgext.acl.hook
1400 prepushkey.acl = python:hgext.acl.hook
1400 prepushkey.acl = python:hgext.acl.hook
1401 [acl]
1401 [acl]
1402 sources = push
1402 sources = push
1403 [extensions]
1403 [extensions]
1404 posixgetuser=$TESTTMP/posixgetuser.py
1404 posixgetuser=$TESTTMP/posixgetuser.py
1405 [acl.allow]
1405 [acl.allow]
1406 ** = fred
1406 ** = fred
1407 [acl.deny]
1407 [acl.deny]
1408 foo/Bar/** = *
1408 foo/Bar/** = *
1409 """
1409 """
1410 pushing to ../b
1410 pushing to ../b
1411 query 1; heads
1411 query 1; heads
1412 searching for changes
1412 searching for changes
1413 all remote heads known locally
1413 all remote heads known locally
1414 listing keys for "phases"
1414 listing keys for "phases"
1415 checking for updated bookmarks
1415 checking for updated bookmarks
1416 listing keys for "bookmarks"
1416 listing keys for "bookmarks"
1417 listing keys for "bookmarks"
1417 listing keys for "bookmarks"
1418 3 changesets found
1418 3 changesets found
1419 list of changesets:
1419 list of changesets:
1420 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1420 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1421 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1421 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1422 911600dab2ae7a9baff75958b84fe606851ce955
1422 911600dab2ae7a9baff75958b84fe606851ce955
1423 bundle2-output-bundle: "HG20", 5 parts total
1423 bundle2-output-bundle: "HG20", 5 parts total
1424 bundle2-output-part: "replycaps" 205 bytes payload
1424 bundle2-output-part: "replycaps" 205 bytes payload
1425 bundle2-output-part: "check:phases" 24 bytes payload
1425 bundle2-output-part: "check:phases" 24 bytes payload
1426 bundle2-output-part: "check:heads" streamed payload
1426 bundle2-output-part: "check:heads" streamed payload
1427 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1427 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1428 bundle2-output-part: "phase-heads" 24 bytes payload
1428 bundle2-output-part: "phase-heads" 24 bytes payload
1429 bundle2-input-bundle: with-transaction
1429 bundle2-input-bundle: with-transaction
1430 bundle2-input-part: "replycaps" supported
1430 bundle2-input-part: "replycaps" supported
1431 bundle2-input-part: total payload size 205
1431 bundle2-input-part: total payload size 205
1432 bundle2-input-part: "check:phases" supported
1432 bundle2-input-part: "check:phases" supported
1433 bundle2-input-part: total payload size 24
1433 bundle2-input-part: total payload size 24
1434 bundle2-input-part: "check:heads" supported
1434 bundle2-input-part: "check:heads" supported
1435 bundle2-input-part: total payload size 20
1435 bundle2-input-part: total payload size 20
1436 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1436 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1437 adding changesets
1437 adding changesets
1438 add changeset ef1ea85a6374
1438 add changeset ef1ea85a6374
1439 add changeset f9cafe1212c8
1439 add changeset f9cafe1212c8
1440 add changeset 911600dab2ae
1440 add changeset 911600dab2ae
1441 adding manifests
1441 adding manifests
1442 adding file changes
1442 adding file changes
1443 adding foo/Bar/file.txt revisions
1443 adding foo/Bar/file.txt revisions
1444 adding foo/file.txt revisions
1444 adding foo/file.txt revisions
1445 adding quux/file.py revisions
1445 adding quux/file.py revisions
1446 calling hook pretxnchangegroup.acl: hgext.acl.hook
1446 calling hook pretxnchangegroup.acl: hgext.acl.hook
1447 acl: checking access for user "fred"
1447 acl: checking access for user "fred"
1448 acl: acl.allow.branches not enabled
1448 acl: acl.allow.branches not enabled
1449 acl: acl.deny.branches not enabled
1449 acl: acl.deny.branches not enabled
1450 acl: acl.allow enabled, 1 entries for user fred
1450 acl: acl.allow enabled, 1 entries for user fred
1451 acl: acl.deny enabled, 1 entries for user fred
1451 acl: acl.deny enabled, 1 entries for user fred
1452 acl: branch access granted: "ef1ea85a6374" on branch "default"
1452 acl: branch access granted: "ef1ea85a6374" on branch "default"
1453 acl: path access granted: "ef1ea85a6374"
1453 acl: path access granted: "ef1ea85a6374"
1454 acl: branch access granted: "f9cafe1212c8" on branch "default"
1454 acl: branch access granted: "f9cafe1212c8" on branch "default"
1455 error: pretxnchangegroup.acl hook failed: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
1455 error: pretxnchangegroup.acl hook failed: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
1456 bundle2-input-part: total payload size 1553
1456 bundle2-input-part: total payload size 1553
1457 bundle2-input-part: total payload size 24
1457 bundle2-input-part: total payload size 24
1458 bundle2-input-bundle: 4 parts total
1458 bundle2-input-bundle: 5 parts total
1459 transaction abort!
1459 transaction abort!
1460 rollback completed
1460 rollback completed
1461 abort: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
1461 abort: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
1462 no rollback information available
1462 no rollback information available
1463 0:6675d58eff77
1463 0:6675d58eff77
1464
1464
1465
1465
1466 Groups
1466 Groups
1467
1467
1468 $ init_config
1468 $ init_config
1469
1469
1470 OS-level groups
1470 OS-level groups
1471
1471
1472 $ echo '[acl.allow]' >> $config
1472 $ echo '[acl.allow]' >> $config
1473 $ echo "** = @group1" >> $config
1473 $ echo "** = @group1" >> $config
1474
1474
1475 @group1 is always allowed
1475 @group1 is always allowed
1476
1476
1477 $ do_push fred
1477 $ do_push fred
1478 Pushing as user fred
1478 Pushing as user fred
1479 hgrc = """
1479 hgrc = """
1480 [hooks]
1480 [hooks]
1481 pretxnchangegroup.acl = python:hgext.acl.hook
1481 pretxnchangegroup.acl = python:hgext.acl.hook
1482 prepushkey.acl = python:hgext.acl.hook
1482 prepushkey.acl = python:hgext.acl.hook
1483 [acl]
1483 [acl]
1484 sources = push
1484 sources = push
1485 [extensions]
1485 [extensions]
1486 posixgetuser=$TESTTMP/posixgetuser.py
1486 posixgetuser=$TESTTMP/posixgetuser.py
1487 [acl.allow]
1487 [acl.allow]
1488 ** = @group1
1488 ** = @group1
1489 """
1489 """
1490 pushing to ../b
1490 pushing to ../b
1491 query 1; heads
1491 query 1; heads
1492 searching for changes
1492 searching for changes
1493 all remote heads known locally
1493 all remote heads known locally
1494 listing keys for "phases"
1494 listing keys for "phases"
1495 checking for updated bookmarks
1495 checking for updated bookmarks
1496 listing keys for "bookmarks"
1496 listing keys for "bookmarks"
1497 listing keys for "bookmarks"
1497 listing keys for "bookmarks"
1498 3 changesets found
1498 3 changesets found
1499 list of changesets:
1499 list of changesets:
1500 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1500 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1501 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1501 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1502 911600dab2ae7a9baff75958b84fe606851ce955
1502 911600dab2ae7a9baff75958b84fe606851ce955
1503 bundle2-output-bundle: "HG20", 5 parts total
1503 bundle2-output-bundle: "HG20", 5 parts total
1504 bundle2-output-part: "replycaps" 205 bytes payload
1504 bundle2-output-part: "replycaps" 205 bytes payload
1505 bundle2-output-part: "check:phases" 24 bytes payload
1505 bundle2-output-part: "check:phases" 24 bytes payload
1506 bundle2-output-part: "check:heads" streamed payload
1506 bundle2-output-part: "check:heads" streamed payload
1507 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1507 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1508 bundle2-output-part: "phase-heads" 24 bytes payload
1508 bundle2-output-part: "phase-heads" 24 bytes payload
1509 bundle2-input-bundle: with-transaction
1509 bundle2-input-bundle: with-transaction
1510 bundle2-input-part: "replycaps" supported
1510 bundle2-input-part: "replycaps" supported
1511 bundle2-input-part: total payload size 205
1511 bundle2-input-part: total payload size 205
1512 bundle2-input-part: "check:phases" supported
1512 bundle2-input-part: "check:phases" supported
1513 bundle2-input-part: total payload size 24
1513 bundle2-input-part: total payload size 24
1514 bundle2-input-part: "check:heads" supported
1514 bundle2-input-part: "check:heads" supported
1515 bundle2-input-part: total payload size 20
1515 bundle2-input-part: total payload size 20
1516 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1516 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1517 adding changesets
1517 adding changesets
1518 add changeset ef1ea85a6374
1518 add changeset ef1ea85a6374
1519 add changeset f9cafe1212c8
1519 add changeset f9cafe1212c8
1520 add changeset 911600dab2ae
1520 add changeset 911600dab2ae
1521 adding manifests
1521 adding manifests
1522 adding file changes
1522 adding file changes
1523 adding foo/Bar/file.txt revisions
1523 adding foo/Bar/file.txt revisions
1524 adding foo/file.txt revisions
1524 adding foo/file.txt revisions
1525 adding quux/file.py revisions
1525 adding quux/file.py revisions
1526 calling hook pretxnchangegroup.acl: hgext.acl.hook
1526 calling hook pretxnchangegroup.acl: hgext.acl.hook
1527 acl: checking access for user "fred"
1527 acl: checking access for user "fred"
1528 acl: acl.allow.branches not enabled
1528 acl: acl.allow.branches not enabled
1529 acl: acl.deny.branches not enabled
1529 acl: acl.deny.branches not enabled
1530 acl: "group1" not defined in [acl.groups]
1530 acl: "group1" not defined in [acl.groups]
1531 acl: acl.allow enabled, 1 entries for user fred
1531 acl: acl.allow enabled, 1 entries for user fred
1532 acl: acl.deny not enabled
1532 acl: acl.deny not enabled
1533 acl: branch access granted: "ef1ea85a6374" on branch "default"
1533 acl: branch access granted: "ef1ea85a6374" on branch "default"
1534 acl: path access granted: "ef1ea85a6374"
1534 acl: path access granted: "ef1ea85a6374"
1535 acl: branch access granted: "f9cafe1212c8" on branch "default"
1535 acl: branch access granted: "f9cafe1212c8" on branch "default"
1536 acl: path access granted: "f9cafe1212c8"
1536 acl: path access granted: "f9cafe1212c8"
1537 acl: branch access granted: "911600dab2ae" on branch "default"
1537 acl: branch access granted: "911600dab2ae" on branch "default"
1538 acl: path access granted: "911600dab2ae"
1538 acl: path access granted: "911600dab2ae"
1539 bundle2-input-part: total payload size 1553
1539 bundle2-input-part: total payload size 1553
1540 bundle2-input-part: "phase-heads" supported
1540 bundle2-input-part: "phase-heads" supported
1541 bundle2-input-part: total payload size 24
1541 bundle2-input-part: total payload size 24
1542 bundle2-input-bundle: 4 parts total
1542 bundle2-input-bundle: 5 parts total
1543 updating the branch cache
1543 updating the branch cache
1544 added 3 changesets with 3 changes to 3 files
1544 added 3 changesets with 3 changes to 3 files
1545 bundle2-output-bundle: "HG20", 1 parts total
1545 bundle2-output-bundle: "HG20", 1 parts total
1546 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
1546 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
1547 bundle2-input-bundle: no-transaction
1547 bundle2-input-bundle: no-transaction
1548 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
1548 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
1549 bundle2-input-bundle: 0 parts total
1549 bundle2-input-bundle: 1 parts total
1550 listing keys for "phases"
1550 listing keys for "phases"
1551 repository tip rolled back to revision 0 (undo push)
1551 repository tip rolled back to revision 0 (undo push)
1552 0:6675d58eff77
1552 0:6675d58eff77
1553
1553
1554
1554
1555 $ echo '[acl.deny]' >> $config
1555 $ echo '[acl.deny]' >> $config
1556 $ echo "foo/Bar/** = @group1" >> $config
1556 $ echo "foo/Bar/** = @group1" >> $config
1557
1557
1558 @group is allowed inside anything but foo/Bar/
1558 @group is allowed inside anything but foo/Bar/
1559
1559
1560 $ do_push fred
1560 $ do_push fred
1561 Pushing as user fred
1561 Pushing as user fred
1562 hgrc = """
1562 hgrc = """
1563 [hooks]
1563 [hooks]
1564 pretxnchangegroup.acl = python:hgext.acl.hook
1564 pretxnchangegroup.acl = python:hgext.acl.hook
1565 prepushkey.acl = python:hgext.acl.hook
1565 prepushkey.acl = python:hgext.acl.hook
1566 [acl]
1566 [acl]
1567 sources = push
1567 sources = push
1568 [extensions]
1568 [extensions]
1569 posixgetuser=$TESTTMP/posixgetuser.py
1569 posixgetuser=$TESTTMP/posixgetuser.py
1570 [acl.allow]
1570 [acl.allow]
1571 ** = @group1
1571 ** = @group1
1572 [acl.deny]
1572 [acl.deny]
1573 foo/Bar/** = @group1
1573 foo/Bar/** = @group1
1574 """
1574 """
1575 pushing to ../b
1575 pushing to ../b
1576 query 1; heads
1576 query 1; heads
1577 searching for changes
1577 searching for changes
1578 all remote heads known locally
1578 all remote heads known locally
1579 listing keys for "phases"
1579 listing keys for "phases"
1580 checking for updated bookmarks
1580 checking for updated bookmarks
1581 listing keys for "bookmarks"
1581 listing keys for "bookmarks"
1582 listing keys for "bookmarks"
1582 listing keys for "bookmarks"
1583 3 changesets found
1583 3 changesets found
1584 list of changesets:
1584 list of changesets:
1585 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1585 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1586 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1586 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1587 911600dab2ae7a9baff75958b84fe606851ce955
1587 911600dab2ae7a9baff75958b84fe606851ce955
1588 bundle2-output-bundle: "HG20", 5 parts total
1588 bundle2-output-bundle: "HG20", 5 parts total
1589 bundle2-output-part: "replycaps" 205 bytes payload
1589 bundle2-output-part: "replycaps" 205 bytes payload
1590 bundle2-output-part: "check:phases" 24 bytes payload
1590 bundle2-output-part: "check:phases" 24 bytes payload
1591 bundle2-output-part: "check:heads" streamed payload
1591 bundle2-output-part: "check:heads" streamed payload
1592 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1592 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1593 bundle2-output-part: "phase-heads" 24 bytes payload
1593 bundle2-output-part: "phase-heads" 24 bytes payload
1594 bundle2-input-bundle: with-transaction
1594 bundle2-input-bundle: with-transaction
1595 bundle2-input-part: "replycaps" supported
1595 bundle2-input-part: "replycaps" supported
1596 bundle2-input-part: total payload size 205
1596 bundle2-input-part: total payload size 205
1597 bundle2-input-part: "check:phases" supported
1597 bundle2-input-part: "check:phases" supported
1598 bundle2-input-part: total payload size 24
1598 bundle2-input-part: total payload size 24
1599 bundle2-input-part: "check:heads" supported
1599 bundle2-input-part: "check:heads" supported
1600 bundle2-input-part: total payload size 20
1600 bundle2-input-part: total payload size 20
1601 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1601 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1602 adding changesets
1602 adding changesets
1603 add changeset ef1ea85a6374
1603 add changeset ef1ea85a6374
1604 add changeset f9cafe1212c8
1604 add changeset f9cafe1212c8
1605 add changeset 911600dab2ae
1605 add changeset 911600dab2ae
1606 adding manifests
1606 adding manifests
1607 adding file changes
1607 adding file changes
1608 adding foo/Bar/file.txt revisions
1608 adding foo/Bar/file.txt revisions
1609 adding foo/file.txt revisions
1609 adding foo/file.txt revisions
1610 adding quux/file.py revisions
1610 adding quux/file.py revisions
1611 calling hook pretxnchangegroup.acl: hgext.acl.hook
1611 calling hook pretxnchangegroup.acl: hgext.acl.hook
1612 acl: checking access for user "fred"
1612 acl: checking access for user "fred"
1613 acl: acl.allow.branches not enabled
1613 acl: acl.allow.branches not enabled
1614 acl: acl.deny.branches not enabled
1614 acl: acl.deny.branches not enabled
1615 acl: "group1" not defined in [acl.groups]
1615 acl: "group1" not defined in [acl.groups]
1616 acl: acl.allow enabled, 1 entries for user fred
1616 acl: acl.allow enabled, 1 entries for user fred
1617 acl: "group1" not defined in [acl.groups]
1617 acl: "group1" not defined in [acl.groups]
1618 acl: acl.deny enabled, 1 entries for user fred
1618 acl: acl.deny enabled, 1 entries for user fred
1619 acl: branch access granted: "ef1ea85a6374" on branch "default"
1619 acl: branch access granted: "ef1ea85a6374" on branch "default"
1620 acl: path access granted: "ef1ea85a6374"
1620 acl: path access granted: "ef1ea85a6374"
1621 acl: branch access granted: "f9cafe1212c8" on branch "default"
1621 acl: branch access granted: "f9cafe1212c8" on branch "default"
1622 error: pretxnchangegroup.acl hook failed: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
1622 error: pretxnchangegroup.acl hook failed: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
1623 bundle2-input-part: total payload size 1553
1623 bundle2-input-part: total payload size 1553
1624 bundle2-input-part: total payload size 24
1624 bundle2-input-part: total payload size 24
1625 bundle2-input-bundle: 4 parts total
1625 bundle2-input-bundle: 5 parts total
1626 transaction abort!
1626 transaction abort!
1627 rollback completed
1627 rollback completed
1628 abort: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
1628 abort: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
1629 no rollback information available
1629 no rollback information available
1630 0:6675d58eff77
1630 0:6675d58eff77
1631
1631
1632
1632
1633 Invalid group
1633 Invalid group
1634
1634
1635 Disable the fakegroups trick to get real failures
1635 Disable the fakegroups trick to get real failures
1636
1636
1637 $ grep -v fakegroups $config > config.tmp
1637 $ grep -v fakegroups $config > config.tmp
1638 $ mv config.tmp $config
1638 $ mv config.tmp $config
1639 $ echo '[acl.allow]' >> $config
1639 $ echo '[acl.allow]' >> $config
1640 $ echo "** = @unlikelytoexist" >> $config
1640 $ echo "** = @unlikelytoexist" >> $config
1641 $ do_push fred 2>&1 | grep unlikelytoexist
1641 $ do_push fred 2>&1 | grep unlikelytoexist
1642 ** = @unlikelytoexist
1642 ** = @unlikelytoexist
1643 acl: "unlikelytoexist" not defined in [acl.groups]
1643 acl: "unlikelytoexist" not defined in [acl.groups]
1644 error: pretxnchangegroup.acl hook failed: group 'unlikelytoexist' is undefined
1644 error: pretxnchangegroup.acl hook failed: group 'unlikelytoexist' is undefined
1645 abort: group 'unlikelytoexist' is undefined
1645 abort: group 'unlikelytoexist' is undefined
1646
1646
1647
1647
1648 Branch acl tests setup
1648 Branch acl tests setup
1649
1649
1650 $ init_config
1650 $ init_config
1651 $ cd b
1651 $ cd b
1652 $ hg up
1652 $ hg up
1653 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1653 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1654 $ hg branch foobar
1654 $ hg branch foobar
1655 marked working directory as branch foobar
1655 marked working directory as branch foobar
1656 (branches are permanent and global, did you want a bookmark?)
1656 (branches are permanent and global, did you want a bookmark?)
1657 $ hg commit -m 'create foobar'
1657 $ hg commit -m 'create foobar'
1658 $ echo 'foo contents' > abc.txt
1658 $ echo 'foo contents' > abc.txt
1659 $ hg add abc.txt
1659 $ hg add abc.txt
1660 $ hg commit -m 'foobar contents'
1660 $ hg commit -m 'foobar contents'
1661 $ cd ..
1661 $ cd ..
1662 $ hg --cwd a pull ../b
1662 $ hg --cwd a pull ../b
1663 pulling from ../b
1663 pulling from ../b
1664 searching for changes
1664 searching for changes
1665 adding changesets
1665 adding changesets
1666 adding manifests
1666 adding manifests
1667 adding file changes
1667 adding file changes
1668 added 2 changesets with 1 changes to 1 files (+1 heads)
1668 added 2 changesets with 1 changes to 1 files (+1 heads)
1669 new changesets 81fbf4469322:fb35475503ef
1669 new changesets 81fbf4469322:fb35475503ef
1670 (run 'hg heads' to see heads)
1670 (run 'hg heads' to see heads)
1671
1671
1672 Create additional changeset on foobar branch
1672 Create additional changeset on foobar branch
1673
1673
1674 $ cd a
1674 $ cd a
1675 $ hg up -C foobar
1675 $ hg up -C foobar
1676 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
1676 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
1677 $ echo 'foo contents2' > abc.txt
1677 $ echo 'foo contents2' > abc.txt
1678 $ hg commit -m 'foobar contents2'
1678 $ hg commit -m 'foobar contents2'
1679 $ cd ..
1679 $ cd ..
1680
1680
1681
1681
1682 No branch acls specified
1682 No branch acls specified
1683
1683
1684 $ do_push astro
1684 $ do_push astro
1685 Pushing as user astro
1685 Pushing as user astro
1686 hgrc = """
1686 hgrc = """
1687 [hooks]
1687 [hooks]
1688 pretxnchangegroup.acl = python:hgext.acl.hook
1688 pretxnchangegroup.acl = python:hgext.acl.hook
1689 prepushkey.acl = python:hgext.acl.hook
1689 prepushkey.acl = python:hgext.acl.hook
1690 [acl]
1690 [acl]
1691 sources = push
1691 sources = push
1692 [extensions]
1692 [extensions]
1693 posixgetuser=$TESTTMP/posixgetuser.py
1693 posixgetuser=$TESTTMP/posixgetuser.py
1694 """
1694 """
1695 pushing to ../b
1695 pushing to ../b
1696 query 1; heads
1696 query 1; heads
1697 searching for changes
1697 searching for changes
1698 all remote heads known locally
1698 all remote heads known locally
1699 listing keys for "phases"
1699 listing keys for "phases"
1700 checking for updated bookmarks
1700 checking for updated bookmarks
1701 listing keys for "bookmarks"
1701 listing keys for "bookmarks"
1702 listing keys for "bookmarks"
1702 listing keys for "bookmarks"
1703 4 changesets found
1703 4 changesets found
1704 list of changesets:
1704 list of changesets:
1705 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1705 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1706 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1706 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1707 911600dab2ae7a9baff75958b84fe606851ce955
1707 911600dab2ae7a9baff75958b84fe606851ce955
1708 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1708 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1709 bundle2-output-bundle: "HG20", 5 parts total
1709 bundle2-output-bundle: "HG20", 5 parts total
1710 bundle2-output-part: "replycaps" 205 bytes payload
1710 bundle2-output-part: "replycaps" 205 bytes payload
1711 bundle2-output-part: "check:phases" 48 bytes payload
1711 bundle2-output-part: "check:phases" 48 bytes payload
1712 bundle2-output-part: "check:heads" streamed payload
1712 bundle2-output-part: "check:heads" streamed payload
1713 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1713 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1714 bundle2-output-part: "phase-heads" 48 bytes payload
1714 bundle2-output-part: "phase-heads" 48 bytes payload
1715 bundle2-input-bundle: with-transaction
1715 bundle2-input-bundle: with-transaction
1716 bundle2-input-part: "replycaps" supported
1716 bundle2-input-part: "replycaps" supported
1717 bundle2-input-part: total payload size 205
1717 bundle2-input-part: total payload size 205
1718 bundle2-input-part: "check:phases" supported
1718 bundle2-input-part: "check:phases" supported
1719 bundle2-input-part: total payload size 48
1719 bundle2-input-part: total payload size 48
1720 bundle2-input-part: "check:heads" supported
1720 bundle2-input-part: "check:heads" supported
1721 bundle2-input-part: total payload size 20
1721 bundle2-input-part: total payload size 20
1722 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1722 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1723 adding changesets
1723 adding changesets
1724 add changeset ef1ea85a6374
1724 add changeset ef1ea85a6374
1725 add changeset f9cafe1212c8
1725 add changeset f9cafe1212c8
1726 add changeset 911600dab2ae
1726 add changeset 911600dab2ae
1727 add changeset e8fc755d4d82
1727 add changeset e8fc755d4d82
1728 adding manifests
1728 adding manifests
1729 adding file changes
1729 adding file changes
1730 adding abc.txt revisions
1730 adding abc.txt revisions
1731 adding foo/Bar/file.txt revisions
1731 adding foo/Bar/file.txt revisions
1732 adding foo/file.txt revisions
1732 adding foo/file.txt revisions
1733 adding quux/file.py revisions
1733 adding quux/file.py revisions
1734 calling hook pretxnchangegroup.acl: hgext.acl.hook
1734 calling hook pretxnchangegroup.acl: hgext.acl.hook
1735 acl: checking access for user "astro"
1735 acl: checking access for user "astro"
1736 acl: acl.allow.branches not enabled
1736 acl: acl.allow.branches not enabled
1737 acl: acl.deny.branches not enabled
1737 acl: acl.deny.branches not enabled
1738 acl: acl.allow not enabled
1738 acl: acl.allow not enabled
1739 acl: acl.deny not enabled
1739 acl: acl.deny not enabled
1740 acl: branch access granted: "ef1ea85a6374" on branch "default"
1740 acl: branch access granted: "ef1ea85a6374" on branch "default"
1741 acl: path access granted: "ef1ea85a6374"
1741 acl: path access granted: "ef1ea85a6374"
1742 acl: branch access granted: "f9cafe1212c8" on branch "default"
1742 acl: branch access granted: "f9cafe1212c8" on branch "default"
1743 acl: path access granted: "f9cafe1212c8"
1743 acl: path access granted: "f9cafe1212c8"
1744 acl: branch access granted: "911600dab2ae" on branch "default"
1744 acl: branch access granted: "911600dab2ae" on branch "default"
1745 acl: path access granted: "911600dab2ae"
1745 acl: path access granted: "911600dab2ae"
1746 acl: branch access granted: "e8fc755d4d82" on branch "foobar"
1746 acl: branch access granted: "e8fc755d4d82" on branch "foobar"
1747 acl: path access granted: "e8fc755d4d82"
1747 acl: path access granted: "e8fc755d4d82"
1748 bundle2-input-part: total payload size 2068
1748 bundle2-input-part: total payload size 2068
1749 bundle2-input-part: "phase-heads" supported
1749 bundle2-input-part: "phase-heads" supported
1750 bundle2-input-part: total payload size 48
1750 bundle2-input-part: total payload size 48
1751 bundle2-input-bundle: 4 parts total
1751 bundle2-input-bundle: 5 parts total
1752 updating the branch cache
1752 updating the branch cache
1753 added 4 changesets with 4 changes to 4 files (+1 heads)
1753 added 4 changesets with 4 changes to 4 files (+1 heads)
1754 bundle2-output-bundle: "HG20", 1 parts total
1754 bundle2-output-bundle: "HG20", 1 parts total
1755 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
1755 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
1756 bundle2-input-bundle: no-transaction
1756 bundle2-input-bundle: no-transaction
1757 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
1757 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
1758 bundle2-input-bundle: 0 parts total
1758 bundle2-input-bundle: 1 parts total
1759 listing keys for "phases"
1759 listing keys for "phases"
1760 repository tip rolled back to revision 2 (undo push)
1760 repository tip rolled back to revision 2 (undo push)
1761 2:fb35475503ef
1761 2:fb35475503ef
1762
1762
1763
1763
1764 Branch acl deny test
1764 Branch acl deny test
1765
1765
1766 $ echo "[acl.deny.branches]" >> $config
1766 $ echo "[acl.deny.branches]" >> $config
1767 $ echo "foobar = *" >> $config
1767 $ echo "foobar = *" >> $config
1768 $ do_push astro
1768 $ do_push astro
1769 Pushing as user astro
1769 Pushing as user astro
1770 hgrc = """
1770 hgrc = """
1771 [hooks]
1771 [hooks]
1772 pretxnchangegroup.acl = python:hgext.acl.hook
1772 pretxnchangegroup.acl = python:hgext.acl.hook
1773 prepushkey.acl = python:hgext.acl.hook
1773 prepushkey.acl = python:hgext.acl.hook
1774 [acl]
1774 [acl]
1775 sources = push
1775 sources = push
1776 [extensions]
1776 [extensions]
1777 posixgetuser=$TESTTMP/posixgetuser.py
1777 posixgetuser=$TESTTMP/posixgetuser.py
1778 [acl.deny.branches]
1778 [acl.deny.branches]
1779 foobar = *
1779 foobar = *
1780 """
1780 """
1781 pushing to ../b
1781 pushing to ../b
1782 query 1; heads
1782 query 1; heads
1783 searching for changes
1783 searching for changes
1784 all remote heads known locally
1784 all remote heads known locally
1785 listing keys for "phases"
1785 listing keys for "phases"
1786 checking for updated bookmarks
1786 checking for updated bookmarks
1787 listing keys for "bookmarks"
1787 listing keys for "bookmarks"
1788 listing keys for "bookmarks"
1788 listing keys for "bookmarks"
1789 4 changesets found
1789 4 changesets found
1790 list of changesets:
1790 list of changesets:
1791 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1791 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1792 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1792 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1793 911600dab2ae7a9baff75958b84fe606851ce955
1793 911600dab2ae7a9baff75958b84fe606851ce955
1794 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1794 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1795 bundle2-output-bundle: "HG20", 5 parts total
1795 bundle2-output-bundle: "HG20", 5 parts total
1796 bundle2-output-part: "replycaps" 205 bytes payload
1796 bundle2-output-part: "replycaps" 205 bytes payload
1797 bundle2-output-part: "check:phases" 48 bytes payload
1797 bundle2-output-part: "check:phases" 48 bytes payload
1798 bundle2-output-part: "check:heads" streamed payload
1798 bundle2-output-part: "check:heads" streamed payload
1799 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1799 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1800 bundle2-output-part: "phase-heads" 48 bytes payload
1800 bundle2-output-part: "phase-heads" 48 bytes payload
1801 bundle2-input-bundle: with-transaction
1801 bundle2-input-bundle: with-transaction
1802 bundle2-input-part: "replycaps" supported
1802 bundle2-input-part: "replycaps" supported
1803 bundle2-input-part: total payload size 205
1803 bundle2-input-part: total payload size 205
1804 bundle2-input-part: "check:phases" supported
1804 bundle2-input-part: "check:phases" supported
1805 bundle2-input-part: total payload size 48
1805 bundle2-input-part: total payload size 48
1806 bundle2-input-part: "check:heads" supported
1806 bundle2-input-part: "check:heads" supported
1807 bundle2-input-part: total payload size 20
1807 bundle2-input-part: total payload size 20
1808 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1808 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1809 adding changesets
1809 adding changesets
1810 add changeset ef1ea85a6374
1810 add changeset ef1ea85a6374
1811 add changeset f9cafe1212c8
1811 add changeset f9cafe1212c8
1812 add changeset 911600dab2ae
1812 add changeset 911600dab2ae
1813 add changeset e8fc755d4d82
1813 add changeset e8fc755d4d82
1814 adding manifests
1814 adding manifests
1815 adding file changes
1815 adding file changes
1816 adding abc.txt revisions
1816 adding abc.txt revisions
1817 adding foo/Bar/file.txt revisions
1817 adding foo/Bar/file.txt revisions
1818 adding foo/file.txt revisions
1818 adding foo/file.txt revisions
1819 adding quux/file.py revisions
1819 adding quux/file.py revisions
1820 calling hook pretxnchangegroup.acl: hgext.acl.hook
1820 calling hook pretxnchangegroup.acl: hgext.acl.hook
1821 acl: checking access for user "astro"
1821 acl: checking access for user "astro"
1822 acl: acl.allow.branches not enabled
1822 acl: acl.allow.branches not enabled
1823 acl: acl.deny.branches enabled, 1 entries for user astro
1823 acl: acl.deny.branches enabled, 1 entries for user astro
1824 acl: acl.allow not enabled
1824 acl: acl.allow not enabled
1825 acl: acl.deny not enabled
1825 acl: acl.deny not enabled
1826 acl: branch access granted: "ef1ea85a6374" on branch "default"
1826 acl: branch access granted: "ef1ea85a6374" on branch "default"
1827 acl: path access granted: "ef1ea85a6374"
1827 acl: path access granted: "ef1ea85a6374"
1828 acl: branch access granted: "f9cafe1212c8" on branch "default"
1828 acl: branch access granted: "f9cafe1212c8" on branch "default"
1829 acl: path access granted: "f9cafe1212c8"
1829 acl: path access granted: "f9cafe1212c8"
1830 acl: branch access granted: "911600dab2ae" on branch "default"
1830 acl: branch access granted: "911600dab2ae" on branch "default"
1831 acl: path access granted: "911600dab2ae"
1831 acl: path access granted: "911600dab2ae"
1832 error: pretxnchangegroup.acl hook failed: acl: user "astro" denied on branch "foobar" (changeset "e8fc755d4d82")
1832 error: pretxnchangegroup.acl hook failed: acl: user "astro" denied on branch "foobar" (changeset "e8fc755d4d82")
1833 bundle2-input-part: total payload size 2068
1833 bundle2-input-part: total payload size 2068
1834 bundle2-input-part: total payload size 48
1834 bundle2-input-part: total payload size 48
1835 bundle2-input-bundle: 4 parts total
1835 bundle2-input-bundle: 5 parts total
1836 transaction abort!
1836 transaction abort!
1837 rollback completed
1837 rollback completed
1838 abort: acl: user "astro" denied on branch "foobar" (changeset "e8fc755d4d82")
1838 abort: acl: user "astro" denied on branch "foobar" (changeset "e8fc755d4d82")
1839 no rollback information available
1839 no rollback information available
1840 2:fb35475503ef
1840 2:fb35475503ef
1841
1841
1842
1842
1843 Branch acl empty allow test
1843 Branch acl empty allow test
1844
1844
1845 $ init_config
1845 $ init_config
1846 $ echo "[acl.allow.branches]" >> $config
1846 $ echo "[acl.allow.branches]" >> $config
1847 $ do_push astro
1847 $ do_push astro
1848 Pushing as user astro
1848 Pushing as user astro
1849 hgrc = """
1849 hgrc = """
1850 [hooks]
1850 [hooks]
1851 pretxnchangegroup.acl = python:hgext.acl.hook
1851 pretxnchangegroup.acl = python:hgext.acl.hook
1852 prepushkey.acl = python:hgext.acl.hook
1852 prepushkey.acl = python:hgext.acl.hook
1853 [acl]
1853 [acl]
1854 sources = push
1854 sources = push
1855 [extensions]
1855 [extensions]
1856 posixgetuser=$TESTTMP/posixgetuser.py
1856 posixgetuser=$TESTTMP/posixgetuser.py
1857 [acl.allow.branches]
1857 [acl.allow.branches]
1858 """
1858 """
1859 pushing to ../b
1859 pushing to ../b
1860 query 1; heads
1860 query 1; heads
1861 searching for changes
1861 searching for changes
1862 all remote heads known locally
1862 all remote heads known locally
1863 listing keys for "phases"
1863 listing keys for "phases"
1864 checking for updated bookmarks
1864 checking for updated bookmarks
1865 listing keys for "bookmarks"
1865 listing keys for "bookmarks"
1866 listing keys for "bookmarks"
1866 listing keys for "bookmarks"
1867 4 changesets found
1867 4 changesets found
1868 list of changesets:
1868 list of changesets:
1869 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1869 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1870 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1870 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1871 911600dab2ae7a9baff75958b84fe606851ce955
1871 911600dab2ae7a9baff75958b84fe606851ce955
1872 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1872 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1873 bundle2-output-bundle: "HG20", 5 parts total
1873 bundle2-output-bundle: "HG20", 5 parts total
1874 bundle2-output-part: "replycaps" 205 bytes payload
1874 bundle2-output-part: "replycaps" 205 bytes payload
1875 bundle2-output-part: "check:phases" 48 bytes payload
1875 bundle2-output-part: "check:phases" 48 bytes payload
1876 bundle2-output-part: "check:heads" streamed payload
1876 bundle2-output-part: "check:heads" streamed payload
1877 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1877 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1878 bundle2-output-part: "phase-heads" 48 bytes payload
1878 bundle2-output-part: "phase-heads" 48 bytes payload
1879 bundle2-input-bundle: with-transaction
1879 bundle2-input-bundle: with-transaction
1880 bundle2-input-part: "replycaps" supported
1880 bundle2-input-part: "replycaps" supported
1881 bundle2-input-part: total payload size 205
1881 bundle2-input-part: total payload size 205
1882 bundle2-input-part: "check:phases" supported
1882 bundle2-input-part: "check:phases" supported
1883 bundle2-input-part: total payload size 48
1883 bundle2-input-part: total payload size 48
1884 bundle2-input-part: "check:heads" supported
1884 bundle2-input-part: "check:heads" supported
1885 bundle2-input-part: total payload size 20
1885 bundle2-input-part: total payload size 20
1886 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1886 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1887 adding changesets
1887 adding changesets
1888 add changeset ef1ea85a6374
1888 add changeset ef1ea85a6374
1889 add changeset f9cafe1212c8
1889 add changeset f9cafe1212c8
1890 add changeset 911600dab2ae
1890 add changeset 911600dab2ae
1891 add changeset e8fc755d4d82
1891 add changeset e8fc755d4d82
1892 adding manifests
1892 adding manifests
1893 adding file changes
1893 adding file changes
1894 adding abc.txt revisions
1894 adding abc.txt revisions
1895 adding foo/Bar/file.txt revisions
1895 adding foo/Bar/file.txt revisions
1896 adding foo/file.txt revisions
1896 adding foo/file.txt revisions
1897 adding quux/file.py revisions
1897 adding quux/file.py revisions
1898 calling hook pretxnchangegroup.acl: hgext.acl.hook
1898 calling hook pretxnchangegroup.acl: hgext.acl.hook
1899 acl: checking access for user "astro"
1899 acl: checking access for user "astro"
1900 acl: acl.allow.branches enabled, 0 entries for user astro
1900 acl: acl.allow.branches enabled, 0 entries for user astro
1901 acl: acl.deny.branches not enabled
1901 acl: acl.deny.branches not enabled
1902 acl: acl.allow not enabled
1902 acl: acl.allow not enabled
1903 acl: acl.deny not enabled
1903 acl: acl.deny not enabled
1904 error: pretxnchangegroup.acl hook failed: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
1904 error: pretxnchangegroup.acl hook failed: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
1905 bundle2-input-part: total payload size 2068
1905 bundle2-input-part: total payload size 2068
1906 bundle2-input-part: total payload size 48
1906 bundle2-input-part: total payload size 48
1907 bundle2-input-bundle: 4 parts total
1907 bundle2-input-bundle: 5 parts total
1908 transaction abort!
1908 transaction abort!
1909 rollback completed
1909 rollback completed
1910 abort: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
1910 abort: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
1911 no rollback information available
1911 no rollback information available
1912 2:fb35475503ef
1912 2:fb35475503ef
1913
1913
1914
1914
1915 Branch acl allow other
1915 Branch acl allow other
1916
1916
1917 $ init_config
1917 $ init_config
1918 $ echo "[acl.allow.branches]" >> $config
1918 $ echo "[acl.allow.branches]" >> $config
1919 $ echo "* = george" >> $config
1919 $ echo "* = george" >> $config
1920 $ do_push astro
1920 $ do_push astro
1921 Pushing as user astro
1921 Pushing as user astro
1922 hgrc = """
1922 hgrc = """
1923 [hooks]
1923 [hooks]
1924 pretxnchangegroup.acl = python:hgext.acl.hook
1924 pretxnchangegroup.acl = python:hgext.acl.hook
1925 prepushkey.acl = python:hgext.acl.hook
1925 prepushkey.acl = python:hgext.acl.hook
1926 [acl]
1926 [acl]
1927 sources = push
1927 sources = push
1928 [extensions]
1928 [extensions]
1929 posixgetuser=$TESTTMP/posixgetuser.py
1929 posixgetuser=$TESTTMP/posixgetuser.py
1930 [acl.allow.branches]
1930 [acl.allow.branches]
1931 * = george
1931 * = george
1932 """
1932 """
1933 pushing to ../b
1933 pushing to ../b
1934 query 1; heads
1934 query 1; heads
1935 searching for changes
1935 searching for changes
1936 all remote heads known locally
1936 all remote heads known locally
1937 listing keys for "phases"
1937 listing keys for "phases"
1938 checking for updated bookmarks
1938 checking for updated bookmarks
1939 listing keys for "bookmarks"
1939 listing keys for "bookmarks"
1940 listing keys for "bookmarks"
1940 listing keys for "bookmarks"
1941 4 changesets found
1941 4 changesets found
1942 list of changesets:
1942 list of changesets:
1943 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1943 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1944 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1944 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1945 911600dab2ae7a9baff75958b84fe606851ce955
1945 911600dab2ae7a9baff75958b84fe606851ce955
1946 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1946 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1947 bundle2-output-bundle: "HG20", 5 parts total
1947 bundle2-output-bundle: "HG20", 5 parts total
1948 bundle2-output-part: "replycaps" 205 bytes payload
1948 bundle2-output-part: "replycaps" 205 bytes payload
1949 bundle2-output-part: "check:phases" 48 bytes payload
1949 bundle2-output-part: "check:phases" 48 bytes payload
1950 bundle2-output-part: "check:heads" streamed payload
1950 bundle2-output-part: "check:heads" streamed payload
1951 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1951 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1952 bundle2-output-part: "phase-heads" 48 bytes payload
1952 bundle2-output-part: "phase-heads" 48 bytes payload
1953 bundle2-input-bundle: with-transaction
1953 bundle2-input-bundle: with-transaction
1954 bundle2-input-part: "replycaps" supported
1954 bundle2-input-part: "replycaps" supported
1955 bundle2-input-part: total payload size 205
1955 bundle2-input-part: total payload size 205
1956 bundle2-input-part: "check:phases" supported
1956 bundle2-input-part: "check:phases" supported
1957 bundle2-input-part: total payload size 48
1957 bundle2-input-part: total payload size 48
1958 bundle2-input-part: "check:heads" supported
1958 bundle2-input-part: "check:heads" supported
1959 bundle2-input-part: total payload size 20
1959 bundle2-input-part: total payload size 20
1960 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1960 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1961 adding changesets
1961 adding changesets
1962 add changeset ef1ea85a6374
1962 add changeset ef1ea85a6374
1963 add changeset f9cafe1212c8
1963 add changeset f9cafe1212c8
1964 add changeset 911600dab2ae
1964 add changeset 911600dab2ae
1965 add changeset e8fc755d4d82
1965 add changeset e8fc755d4d82
1966 adding manifests
1966 adding manifests
1967 adding file changes
1967 adding file changes
1968 adding abc.txt revisions
1968 adding abc.txt revisions
1969 adding foo/Bar/file.txt revisions
1969 adding foo/Bar/file.txt revisions
1970 adding foo/file.txt revisions
1970 adding foo/file.txt revisions
1971 adding quux/file.py revisions
1971 adding quux/file.py revisions
1972 calling hook pretxnchangegroup.acl: hgext.acl.hook
1972 calling hook pretxnchangegroup.acl: hgext.acl.hook
1973 acl: checking access for user "astro"
1973 acl: checking access for user "astro"
1974 acl: acl.allow.branches enabled, 0 entries for user astro
1974 acl: acl.allow.branches enabled, 0 entries for user astro
1975 acl: acl.deny.branches not enabled
1975 acl: acl.deny.branches not enabled
1976 acl: acl.allow not enabled
1976 acl: acl.allow not enabled
1977 acl: acl.deny not enabled
1977 acl: acl.deny not enabled
1978 error: pretxnchangegroup.acl hook failed: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
1978 error: pretxnchangegroup.acl hook failed: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
1979 bundle2-input-part: total payload size 2068
1979 bundle2-input-part: total payload size 2068
1980 bundle2-input-part: total payload size 48
1980 bundle2-input-part: total payload size 48
1981 bundle2-input-bundle: 4 parts total
1981 bundle2-input-bundle: 5 parts total
1982 transaction abort!
1982 transaction abort!
1983 rollback completed
1983 rollback completed
1984 abort: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
1984 abort: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
1985 no rollback information available
1985 no rollback information available
1986 2:fb35475503ef
1986 2:fb35475503ef
1987
1987
1988 $ do_push george
1988 $ do_push george
1989 Pushing as user george
1989 Pushing as user george
1990 hgrc = """
1990 hgrc = """
1991 [hooks]
1991 [hooks]
1992 pretxnchangegroup.acl = python:hgext.acl.hook
1992 pretxnchangegroup.acl = python:hgext.acl.hook
1993 prepushkey.acl = python:hgext.acl.hook
1993 prepushkey.acl = python:hgext.acl.hook
1994 [acl]
1994 [acl]
1995 sources = push
1995 sources = push
1996 [extensions]
1996 [extensions]
1997 posixgetuser=$TESTTMP/posixgetuser.py
1997 posixgetuser=$TESTTMP/posixgetuser.py
1998 [acl.allow.branches]
1998 [acl.allow.branches]
1999 * = george
1999 * = george
2000 """
2000 """
2001 pushing to ../b
2001 pushing to ../b
2002 query 1; heads
2002 query 1; heads
2003 searching for changes
2003 searching for changes
2004 all remote heads known locally
2004 all remote heads known locally
2005 listing keys for "phases"
2005 listing keys for "phases"
2006 checking for updated bookmarks
2006 checking for updated bookmarks
2007 listing keys for "bookmarks"
2007 listing keys for "bookmarks"
2008 listing keys for "bookmarks"
2008 listing keys for "bookmarks"
2009 4 changesets found
2009 4 changesets found
2010 list of changesets:
2010 list of changesets:
2011 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
2011 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
2012 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
2012 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
2013 911600dab2ae7a9baff75958b84fe606851ce955
2013 911600dab2ae7a9baff75958b84fe606851ce955
2014 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
2014 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
2015 bundle2-output-bundle: "HG20", 5 parts total
2015 bundle2-output-bundle: "HG20", 5 parts total
2016 bundle2-output-part: "replycaps" 205 bytes payload
2016 bundle2-output-part: "replycaps" 205 bytes payload
2017 bundle2-output-part: "check:phases" 48 bytes payload
2017 bundle2-output-part: "check:phases" 48 bytes payload
2018 bundle2-output-part: "check:heads" streamed payload
2018 bundle2-output-part: "check:heads" streamed payload
2019 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
2019 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
2020 bundle2-output-part: "phase-heads" 48 bytes payload
2020 bundle2-output-part: "phase-heads" 48 bytes payload
2021 bundle2-input-bundle: with-transaction
2021 bundle2-input-bundle: with-transaction
2022 bundle2-input-part: "replycaps" supported
2022 bundle2-input-part: "replycaps" supported
2023 bundle2-input-part: total payload size 205
2023 bundle2-input-part: total payload size 205
2024 bundle2-input-part: "check:phases" supported
2024 bundle2-input-part: "check:phases" supported
2025 bundle2-input-part: total payload size 48
2025 bundle2-input-part: total payload size 48
2026 bundle2-input-part: "check:heads" supported
2026 bundle2-input-part: "check:heads" supported
2027 bundle2-input-part: total payload size 20
2027 bundle2-input-part: total payload size 20
2028 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
2028 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
2029 adding changesets
2029 adding changesets
2030 add changeset ef1ea85a6374
2030 add changeset ef1ea85a6374
2031 add changeset f9cafe1212c8
2031 add changeset f9cafe1212c8
2032 add changeset 911600dab2ae
2032 add changeset 911600dab2ae
2033 add changeset e8fc755d4d82
2033 add changeset e8fc755d4d82
2034 adding manifests
2034 adding manifests
2035 adding file changes
2035 adding file changes
2036 adding abc.txt revisions
2036 adding abc.txt revisions
2037 adding foo/Bar/file.txt revisions
2037 adding foo/Bar/file.txt revisions
2038 adding foo/file.txt revisions
2038 adding foo/file.txt revisions
2039 adding quux/file.py revisions
2039 adding quux/file.py revisions
2040 calling hook pretxnchangegroup.acl: hgext.acl.hook
2040 calling hook pretxnchangegroup.acl: hgext.acl.hook
2041 acl: checking access for user "george"
2041 acl: checking access for user "george"
2042 acl: acl.allow.branches enabled, 1 entries for user george
2042 acl: acl.allow.branches enabled, 1 entries for user george
2043 acl: acl.deny.branches not enabled
2043 acl: acl.deny.branches not enabled
2044 acl: acl.allow not enabled
2044 acl: acl.allow not enabled
2045 acl: acl.deny not enabled
2045 acl: acl.deny not enabled
2046 acl: branch access granted: "ef1ea85a6374" on branch "default"
2046 acl: branch access granted: "ef1ea85a6374" on branch "default"
2047 acl: path access granted: "ef1ea85a6374"
2047 acl: path access granted: "ef1ea85a6374"
2048 acl: branch access granted: "f9cafe1212c8" on branch "default"
2048 acl: branch access granted: "f9cafe1212c8" on branch "default"
2049 acl: path access granted: "f9cafe1212c8"
2049 acl: path access granted: "f9cafe1212c8"
2050 acl: branch access granted: "911600dab2ae" on branch "default"
2050 acl: branch access granted: "911600dab2ae" on branch "default"
2051 acl: path access granted: "911600dab2ae"
2051 acl: path access granted: "911600dab2ae"
2052 acl: branch access granted: "e8fc755d4d82" on branch "foobar"
2052 acl: branch access granted: "e8fc755d4d82" on branch "foobar"
2053 acl: path access granted: "e8fc755d4d82"
2053 acl: path access granted: "e8fc755d4d82"
2054 bundle2-input-part: total payload size 2068
2054 bundle2-input-part: total payload size 2068
2055 bundle2-input-part: "phase-heads" supported
2055 bundle2-input-part: "phase-heads" supported
2056 bundle2-input-part: total payload size 48
2056 bundle2-input-part: total payload size 48
2057 bundle2-input-bundle: 4 parts total
2057 bundle2-input-bundle: 5 parts total
2058 updating the branch cache
2058 updating the branch cache
2059 added 4 changesets with 4 changes to 4 files (+1 heads)
2059 added 4 changesets with 4 changes to 4 files (+1 heads)
2060 bundle2-output-bundle: "HG20", 1 parts total
2060 bundle2-output-bundle: "HG20", 1 parts total
2061 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
2061 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
2062 bundle2-input-bundle: no-transaction
2062 bundle2-input-bundle: no-transaction
2063 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
2063 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
2064 bundle2-input-bundle: 0 parts total
2064 bundle2-input-bundle: 1 parts total
2065 listing keys for "phases"
2065 listing keys for "phases"
2066 repository tip rolled back to revision 2 (undo push)
2066 repository tip rolled back to revision 2 (undo push)
2067 2:fb35475503ef
2067 2:fb35475503ef
2068
2068
2069
2069
2070 Branch acl conflicting allow
2070 Branch acl conflicting allow
2071 asterisk ends up applying to all branches and allowing george to
2071 asterisk ends up applying to all branches and allowing george to
2072 push foobar into the remote
2072 push foobar into the remote
2073
2073
2074 $ init_config
2074 $ init_config
2075 $ echo "[acl.allow.branches]" >> $config
2075 $ echo "[acl.allow.branches]" >> $config
2076 $ echo "foobar = astro" >> $config
2076 $ echo "foobar = astro" >> $config
2077 $ echo "* = george" >> $config
2077 $ echo "* = george" >> $config
2078 $ do_push george
2078 $ do_push george
2079 Pushing as user george
2079 Pushing as user george
2080 hgrc = """
2080 hgrc = """
2081 [hooks]
2081 [hooks]
2082 pretxnchangegroup.acl = python:hgext.acl.hook
2082 pretxnchangegroup.acl = python:hgext.acl.hook
2083 prepushkey.acl = python:hgext.acl.hook
2083 prepushkey.acl = python:hgext.acl.hook
2084 [acl]
2084 [acl]
2085 sources = push
2085 sources = push
2086 [extensions]
2086 [extensions]
2087 posixgetuser=$TESTTMP/posixgetuser.py
2087 posixgetuser=$TESTTMP/posixgetuser.py
2088 [acl.allow.branches]
2088 [acl.allow.branches]
2089 foobar = astro
2089 foobar = astro
2090 * = george
2090 * = george
2091 """
2091 """
2092 pushing to ../b
2092 pushing to ../b
2093 query 1; heads
2093 query 1; heads
2094 searching for changes
2094 searching for changes
2095 all remote heads known locally
2095 all remote heads known locally
2096 listing keys for "phases"
2096 listing keys for "phases"
2097 checking for updated bookmarks
2097 checking for updated bookmarks
2098 listing keys for "bookmarks"
2098 listing keys for "bookmarks"
2099 listing keys for "bookmarks"
2099 listing keys for "bookmarks"
2100 4 changesets found
2100 4 changesets found
2101 list of changesets:
2101 list of changesets:
2102 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
2102 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
2103 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
2103 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
2104 911600dab2ae7a9baff75958b84fe606851ce955
2104 911600dab2ae7a9baff75958b84fe606851ce955
2105 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
2105 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
2106 bundle2-output-bundle: "HG20", 5 parts total
2106 bundle2-output-bundle: "HG20", 5 parts total
2107 bundle2-output-part: "replycaps" 205 bytes payload
2107 bundle2-output-part: "replycaps" 205 bytes payload
2108 bundle2-output-part: "check:phases" 48 bytes payload
2108 bundle2-output-part: "check:phases" 48 bytes payload
2109 bundle2-output-part: "check:heads" streamed payload
2109 bundle2-output-part: "check:heads" streamed payload
2110 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
2110 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
2111 bundle2-output-part: "phase-heads" 48 bytes payload
2111 bundle2-output-part: "phase-heads" 48 bytes payload
2112 bundle2-input-bundle: with-transaction
2112 bundle2-input-bundle: with-transaction
2113 bundle2-input-part: "replycaps" supported
2113 bundle2-input-part: "replycaps" supported
2114 bundle2-input-part: total payload size 205
2114 bundle2-input-part: total payload size 205
2115 bundle2-input-part: "check:phases" supported
2115 bundle2-input-part: "check:phases" supported
2116 bundle2-input-part: total payload size 48
2116 bundle2-input-part: total payload size 48
2117 bundle2-input-part: "check:heads" supported
2117 bundle2-input-part: "check:heads" supported
2118 bundle2-input-part: total payload size 20
2118 bundle2-input-part: total payload size 20
2119 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
2119 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
2120 adding changesets
2120 adding changesets
2121 add changeset ef1ea85a6374
2121 add changeset ef1ea85a6374
2122 add changeset f9cafe1212c8
2122 add changeset f9cafe1212c8
2123 add changeset 911600dab2ae
2123 add changeset 911600dab2ae
2124 add changeset e8fc755d4d82
2124 add changeset e8fc755d4d82
2125 adding manifests
2125 adding manifests
2126 adding file changes
2126 adding file changes
2127 adding abc.txt revisions
2127 adding abc.txt revisions
2128 adding foo/Bar/file.txt revisions
2128 adding foo/Bar/file.txt revisions
2129 adding foo/file.txt revisions
2129 adding foo/file.txt revisions
2130 adding quux/file.py revisions
2130 adding quux/file.py revisions
2131 calling hook pretxnchangegroup.acl: hgext.acl.hook
2131 calling hook pretxnchangegroup.acl: hgext.acl.hook
2132 acl: checking access for user "george"
2132 acl: checking access for user "george"
2133 acl: acl.allow.branches enabled, 1 entries for user george
2133 acl: acl.allow.branches enabled, 1 entries for user george
2134 acl: acl.deny.branches not enabled
2134 acl: acl.deny.branches not enabled
2135 acl: acl.allow not enabled
2135 acl: acl.allow not enabled
2136 acl: acl.deny not enabled
2136 acl: acl.deny not enabled
2137 acl: branch access granted: "ef1ea85a6374" on branch "default"
2137 acl: branch access granted: "ef1ea85a6374" on branch "default"
2138 acl: path access granted: "ef1ea85a6374"
2138 acl: path access granted: "ef1ea85a6374"
2139 acl: branch access granted: "f9cafe1212c8" on branch "default"
2139 acl: branch access granted: "f9cafe1212c8" on branch "default"
2140 acl: path access granted: "f9cafe1212c8"
2140 acl: path access granted: "f9cafe1212c8"
2141 acl: branch access granted: "911600dab2ae" on branch "default"
2141 acl: branch access granted: "911600dab2ae" on branch "default"
2142 acl: path access granted: "911600dab2ae"
2142 acl: path access granted: "911600dab2ae"
2143 acl: branch access granted: "e8fc755d4d82" on branch "foobar"
2143 acl: branch access granted: "e8fc755d4d82" on branch "foobar"
2144 acl: path access granted: "e8fc755d4d82"
2144 acl: path access granted: "e8fc755d4d82"
2145 bundle2-input-part: total payload size 2068
2145 bundle2-input-part: total payload size 2068
2146 bundle2-input-part: "phase-heads" supported
2146 bundle2-input-part: "phase-heads" supported
2147 bundle2-input-part: total payload size 48
2147 bundle2-input-part: total payload size 48
2148 bundle2-input-bundle: 4 parts total
2148 bundle2-input-bundle: 5 parts total
2149 updating the branch cache
2149 updating the branch cache
2150 added 4 changesets with 4 changes to 4 files (+1 heads)
2150 added 4 changesets with 4 changes to 4 files (+1 heads)
2151 bundle2-output-bundle: "HG20", 1 parts total
2151 bundle2-output-bundle: "HG20", 1 parts total
2152 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
2152 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
2153 bundle2-input-bundle: no-transaction
2153 bundle2-input-bundle: no-transaction
2154 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
2154 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
2155 bundle2-input-bundle: 0 parts total
2155 bundle2-input-bundle: 1 parts total
2156 listing keys for "phases"
2156 listing keys for "phases"
2157 repository tip rolled back to revision 2 (undo push)
2157 repository tip rolled back to revision 2 (undo push)
2158 2:fb35475503ef
2158 2:fb35475503ef
2159
2159
2160 Branch acl conflicting deny
2160 Branch acl conflicting deny
2161
2161
2162 $ init_config
2162 $ init_config
2163 $ echo "[acl.deny.branches]" >> $config
2163 $ echo "[acl.deny.branches]" >> $config
2164 $ echo "foobar = astro" >> $config
2164 $ echo "foobar = astro" >> $config
2165 $ echo "default = astro" >> $config
2165 $ echo "default = astro" >> $config
2166 $ echo "* = george" >> $config
2166 $ echo "* = george" >> $config
2167 $ do_push george
2167 $ do_push george
2168 Pushing as user george
2168 Pushing as user george
2169 hgrc = """
2169 hgrc = """
2170 [hooks]
2170 [hooks]
2171 pretxnchangegroup.acl = python:hgext.acl.hook
2171 pretxnchangegroup.acl = python:hgext.acl.hook
2172 prepushkey.acl = python:hgext.acl.hook
2172 prepushkey.acl = python:hgext.acl.hook
2173 [acl]
2173 [acl]
2174 sources = push
2174 sources = push
2175 [extensions]
2175 [extensions]
2176 posixgetuser=$TESTTMP/posixgetuser.py
2176 posixgetuser=$TESTTMP/posixgetuser.py
2177 [acl.deny.branches]
2177 [acl.deny.branches]
2178 foobar = astro
2178 foobar = astro
2179 default = astro
2179 default = astro
2180 * = george
2180 * = george
2181 """
2181 """
2182 pushing to ../b
2182 pushing to ../b
2183 query 1; heads
2183 query 1; heads
2184 searching for changes
2184 searching for changes
2185 all remote heads known locally
2185 all remote heads known locally
2186 listing keys for "phases"
2186 listing keys for "phases"
2187 checking for updated bookmarks
2187 checking for updated bookmarks
2188 listing keys for "bookmarks"
2188 listing keys for "bookmarks"
2189 listing keys for "bookmarks"
2189 listing keys for "bookmarks"
2190 4 changesets found
2190 4 changesets found
2191 list of changesets:
2191 list of changesets:
2192 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
2192 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
2193 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
2193 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
2194 911600dab2ae7a9baff75958b84fe606851ce955
2194 911600dab2ae7a9baff75958b84fe606851ce955
2195 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
2195 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
2196 bundle2-output-bundle: "HG20", 5 parts total
2196 bundle2-output-bundle: "HG20", 5 parts total
2197 bundle2-output-part: "replycaps" 205 bytes payload
2197 bundle2-output-part: "replycaps" 205 bytes payload
2198 bundle2-output-part: "check:phases" 48 bytes payload
2198 bundle2-output-part: "check:phases" 48 bytes payload
2199 bundle2-output-part: "check:heads" streamed payload
2199 bundle2-output-part: "check:heads" streamed payload
2200 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
2200 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
2201 bundle2-output-part: "phase-heads" 48 bytes payload
2201 bundle2-output-part: "phase-heads" 48 bytes payload
2202 bundle2-input-bundle: with-transaction
2202 bundle2-input-bundle: with-transaction
2203 bundle2-input-part: "replycaps" supported
2203 bundle2-input-part: "replycaps" supported
2204 bundle2-input-part: total payload size 205
2204 bundle2-input-part: total payload size 205
2205 bundle2-input-part: "check:phases" supported
2205 bundle2-input-part: "check:phases" supported
2206 bundle2-input-part: total payload size 48
2206 bundle2-input-part: total payload size 48
2207 bundle2-input-part: "check:heads" supported
2207 bundle2-input-part: "check:heads" supported
2208 bundle2-input-part: total payload size 20
2208 bundle2-input-part: total payload size 20
2209 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
2209 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
2210 adding changesets
2210 adding changesets
2211 add changeset ef1ea85a6374
2211 add changeset ef1ea85a6374
2212 add changeset f9cafe1212c8
2212 add changeset f9cafe1212c8
2213 add changeset 911600dab2ae
2213 add changeset 911600dab2ae
2214 add changeset e8fc755d4d82
2214 add changeset e8fc755d4d82
2215 adding manifests
2215 adding manifests
2216 adding file changes
2216 adding file changes
2217 adding abc.txt revisions
2217 adding abc.txt revisions
2218 adding foo/Bar/file.txt revisions
2218 adding foo/Bar/file.txt revisions
2219 adding foo/file.txt revisions
2219 adding foo/file.txt revisions
2220 adding quux/file.py revisions
2220 adding quux/file.py revisions
2221 calling hook pretxnchangegroup.acl: hgext.acl.hook
2221 calling hook pretxnchangegroup.acl: hgext.acl.hook
2222 acl: checking access for user "george"
2222 acl: checking access for user "george"
2223 acl: acl.allow.branches not enabled
2223 acl: acl.allow.branches not enabled
2224 acl: acl.deny.branches enabled, 1 entries for user george
2224 acl: acl.deny.branches enabled, 1 entries for user george
2225 acl: acl.allow not enabled
2225 acl: acl.allow not enabled
2226 acl: acl.deny not enabled
2226 acl: acl.deny not enabled
2227 error: pretxnchangegroup.acl hook failed: acl: user "george" denied on branch "default" (changeset "ef1ea85a6374")
2227 error: pretxnchangegroup.acl hook failed: acl: user "george" denied on branch "default" (changeset "ef1ea85a6374")
2228 bundle2-input-part: total payload size 2068
2228 bundle2-input-part: total payload size 2068
2229 bundle2-input-part: total payload size 48
2229 bundle2-input-part: total payload size 48
2230 bundle2-input-bundle: 4 parts total
2230 bundle2-input-bundle: 5 parts total
2231 transaction abort!
2231 transaction abort!
2232 rollback completed
2232 rollback completed
2233 abort: acl: user "george" denied on branch "default" (changeset "ef1ea85a6374")
2233 abort: acl: user "george" denied on branch "default" (changeset "ef1ea85a6374")
2234 no rollback information available
2234 no rollback information available
2235 2:fb35475503ef
2235 2:fb35475503ef
2236
2236
2237 User 'astro' must not be denied
2237 User 'astro' must not be denied
2238
2238
2239 $ init_config
2239 $ init_config
2240 $ echo "[acl.deny.branches]" >> $config
2240 $ echo "[acl.deny.branches]" >> $config
2241 $ echo "default = !astro" >> $config
2241 $ echo "default = !astro" >> $config
2242 $ do_push astro
2242 $ do_push astro
2243 Pushing as user astro
2243 Pushing as user astro
2244 hgrc = """
2244 hgrc = """
2245 [hooks]
2245 [hooks]
2246 pretxnchangegroup.acl = python:hgext.acl.hook
2246 pretxnchangegroup.acl = python:hgext.acl.hook
2247 prepushkey.acl = python:hgext.acl.hook
2247 prepushkey.acl = python:hgext.acl.hook
2248 [acl]
2248 [acl]
2249 sources = push
2249 sources = push
2250 [extensions]
2250 [extensions]
2251 posixgetuser=$TESTTMP/posixgetuser.py
2251 posixgetuser=$TESTTMP/posixgetuser.py
2252 [acl.deny.branches]
2252 [acl.deny.branches]
2253 default = !astro
2253 default = !astro
2254 """
2254 """
2255 pushing to ../b
2255 pushing to ../b
2256 query 1; heads
2256 query 1; heads
2257 searching for changes
2257 searching for changes
2258 all remote heads known locally
2258 all remote heads known locally
2259 listing keys for "phases"
2259 listing keys for "phases"
2260 checking for updated bookmarks
2260 checking for updated bookmarks
2261 listing keys for "bookmarks"
2261 listing keys for "bookmarks"
2262 listing keys for "bookmarks"
2262 listing keys for "bookmarks"
2263 4 changesets found
2263 4 changesets found
2264 list of changesets:
2264 list of changesets:
2265 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
2265 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
2266 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
2266 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
2267 911600dab2ae7a9baff75958b84fe606851ce955
2267 911600dab2ae7a9baff75958b84fe606851ce955
2268 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
2268 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
2269 bundle2-output-bundle: "HG20", 5 parts total
2269 bundle2-output-bundle: "HG20", 5 parts total
2270 bundle2-output-part: "replycaps" 205 bytes payload
2270 bundle2-output-part: "replycaps" 205 bytes payload
2271 bundle2-output-part: "check:phases" 48 bytes payload
2271 bundle2-output-part: "check:phases" 48 bytes payload
2272 bundle2-output-part: "check:heads" streamed payload
2272 bundle2-output-part: "check:heads" streamed payload
2273 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
2273 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
2274 bundle2-output-part: "phase-heads" 48 bytes payload
2274 bundle2-output-part: "phase-heads" 48 bytes payload
2275 bundle2-input-bundle: with-transaction
2275 bundle2-input-bundle: with-transaction
2276 bundle2-input-part: "replycaps" supported
2276 bundle2-input-part: "replycaps" supported
2277 bundle2-input-part: total payload size 205
2277 bundle2-input-part: total payload size 205
2278 bundle2-input-part: "check:phases" supported
2278 bundle2-input-part: "check:phases" supported
2279 bundle2-input-part: total payload size 48
2279 bundle2-input-part: total payload size 48
2280 bundle2-input-part: "check:heads" supported
2280 bundle2-input-part: "check:heads" supported
2281 bundle2-input-part: total payload size 20
2281 bundle2-input-part: total payload size 20
2282 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
2282 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
2283 adding changesets
2283 adding changesets
2284 add changeset ef1ea85a6374
2284 add changeset ef1ea85a6374
2285 add changeset f9cafe1212c8
2285 add changeset f9cafe1212c8
2286 add changeset 911600dab2ae
2286 add changeset 911600dab2ae
2287 add changeset e8fc755d4d82
2287 add changeset e8fc755d4d82
2288 adding manifests
2288 adding manifests
2289 adding file changes
2289 adding file changes
2290 adding abc.txt revisions
2290 adding abc.txt revisions
2291 adding foo/Bar/file.txt revisions
2291 adding foo/Bar/file.txt revisions
2292 adding foo/file.txt revisions
2292 adding foo/file.txt revisions
2293 adding quux/file.py revisions
2293 adding quux/file.py revisions
2294 calling hook pretxnchangegroup.acl: hgext.acl.hook
2294 calling hook pretxnchangegroup.acl: hgext.acl.hook
2295 acl: checking access for user "astro"
2295 acl: checking access for user "astro"
2296 acl: acl.allow.branches not enabled
2296 acl: acl.allow.branches not enabled
2297 acl: acl.deny.branches enabled, 0 entries for user astro
2297 acl: acl.deny.branches enabled, 0 entries for user astro
2298 acl: acl.allow not enabled
2298 acl: acl.allow not enabled
2299 acl: acl.deny not enabled
2299 acl: acl.deny not enabled
2300 acl: branch access granted: "ef1ea85a6374" on branch "default"
2300 acl: branch access granted: "ef1ea85a6374" on branch "default"
2301 acl: path access granted: "ef1ea85a6374"
2301 acl: path access granted: "ef1ea85a6374"
2302 acl: branch access granted: "f9cafe1212c8" on branch "default"
2302 acl: branch access granted: "f9cafe1212c8" on branch "default"
2303 acl: path access granted: "f9cafe1212c8"
2303 acl: path access granted: "f9cafe1212c8"
2304 acl: branch access granted: "911600dab2ae" on branch "default"
2304 acl: branch access granted: "911600dab2ae" on branch "default"
2305 acl: path access granted: "911600dab2ae"
2305 acl: path access granted: "911600dab2ae"
2306 acl: branch access granted: "e8fc755d4d82" on branch "foobar"
2306 acl: branch access granted: "e8fc755d4d82" on branch "foobar"
2307 acl: path access granted: "e8fc755d4d82"
2307 acl: path access granted: "e8fc755d4d82"
2308 bundle2-input-part: total payload size 2068
2308 bundle2-input-part: total payload size 2068
2309 bundle2-input-part: "phase-heads" supported
2309 bundle2-input-part: "phase-heads" supported
2310 bundle2-input-part: total payload size 48
2310 bundle2-input-part: total payload size 48
2311 bundle2-input-bundle: 4 parts total
2311 bundle2-input-bundle: 5 parts total
2312 updating the branch cache
2312 updating the branch cache
2313 added 4 changesets with 4 changes to 4 files (+1 heads)
2313 added 4 changesets with 4 changes to 4 files (+1 heads)
2314 bundle2-output-bundle: "HG20", 1 parts total
2314 bundle2-output-bundle: "HG20", 1 parts total
2315 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
2315 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
2316 bundle2-input-bundle: no-transaction
2316 bundle2-input-bundle: no-transaction
2317 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
2317 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
2318 bundle2-input-bundle: 0 parts total
2318 bundle2-input-bundle: 1 parts total
2319 listing keys for "phases"
2319 listing keys for "phases"
2320 repository tip rolled back to revision 2 (undo push)
2320 repository tip rolled back to revision 2 (undo push)
2321 2:fb35475503ef
2321 2:fb35475503ef
2322
2322
2323
2323
2324 Non-astro users must be denied
2324 Non-astro users must be denied
2325
2325
2326 $ do_push george
2326 $ do_push george
2327 Pushing as user george
2327 Pushing as user george
2328 hgrc = """
2328 hgrc = """
2329 [hooks]
2329 [hooks]
2330 pretxnchangegroup.acl = python:hgext.acl.hook
2330 pretxnchangegroup.acl = python:hgext.acl.hook
2331 prepushkey.acl = python:hgext.acl.hook
2331 prepushkey.acl = python:hgext.acl.hook
2332 [acl]
2332 [acl]
2333 sources = push
2333 sources = push
2334 [extensions]
2334 [extensions]
2335 posixgetuser=$TESTTMP/posixgetuser.py
2335 posixgetuser=$TESTTMP/posixgetuser.py
2336 [acl.deny.branches]
2336 [acl.deny.branches]
2337 default = !astro
2337 default = !astro
2338 """
2338 """
2339 pushing to ../b
2339 pushing to ../b
2340 query 1; heads
2340 query 1; heads
2341 searching for changes
2341 searching for changes
2342 all remote heads known locally
2342 all remote heads known locally
2343 listing keys for "phases"
2343 listing keys for "phases"
2344 checking for updated bookmarks
2344 checking for updated bookmarks
2345 listing keys for "bookmarks"
2345 listing keys for "bookmarks"
2346 listing keys for "bookmarks"
2346 listing keys for "bookmarks"
2347 4 changesets found
2347 4 changesets found
2348 list of changesets:
2348 list of changesets:
2349 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
2349 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
2350 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
2350 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
2351 911600dab2ae7a9baff75958b84fe606851ce955
2351 911600dab2ae7a9baff75958b84fe606851ce955
2352 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
2352 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
2353 bundle2-output-bundle: "HG20", 5 parts total
2353 bundle2-output-bundle: "HG20", 5 parts total
2354 bundle2-output-part: "replycaps" 205 bytes payload
2354 bundle2-output-part: "replycaps" 205 bytes payload
2355 bundle2-output-part: "check:phases" 48 bytes payload
2355 bundle2-output-part: "check:phases" 48 bytes payload
2356 bundle2-output-part: "check:heads" streamed payload
2356 bundle2-output-part: "check:heads" streamed payload
2357 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
2357 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
2358 bundle2-output-part: "phase-heads" 48 bytes payload
2358 bundle2-output-part: "phase-heads" 48 bytes payload
2359 bundle2-input-bundle: with-transaction
2359 bundle2-input-bundle: with-transaction
2360 bundle2-input-part: "replycaps" supported
2360 bundle2-input-part: "replycaps" supported
2361 bundle2-input-part: total payload size 205
2361 bundle2-input-part: total payload size 205
2362 bundle2-input-part: "check:phases" supported
2362 bundle2-input-part: "check:phases" supported
2363 bundle2-input-part: total payload size 48
2363 bundle2-input-part: total payload size 48
2364 bundle2-input-part: "check:heads" supported
2364 bundle2-input-part: "check:heads" supported
2365 bundle2-input-part: total payload size 20
2365 bundle2-input-part: total payload size 20
2366 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
2366 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
2367 adding changesets
2367 adding changesets
2368 add changeset ef1ea85a6374
2368 add changeset ef1ea85a6374
2369 add changeset f9cafe1212c8
2369 add changeset f9cafe1212c8
2370 add changeset 911600dab2ae
2370 add changeset 911600dab2ae
2371 add changeset e8fc755d4d82
2371 add changeset e8fc755d4d82
2372 adding manifests
2372 adding manifests
2373 adding file changes
2373 adding file changes
2374 adding abc.txt revisions
2374 adding abc.txt revisions
2375 adding foo/Bar/file.txt revisions
2375 adding foo/Bar/file.txt revisions
2376 adding foo/file.txt revisions
2376 adding foo/file.txt revisions
2377 adding quux/file.py revisions
2377 adding quux/file.py revisions
2378 calling hook pretxnchangegroup.acl: hgext.acl.hook
2378 calling hook pretxnchangegroup.acl: hgext.acl.hook
2379 acl: checking access for user "george"
2379 acl: checking access for user "george"
2380 acl: acl.allow.branches not enabled
2380 acl: acl.allow.branches not enabled
2381 acl: acl.deny.branches enabled, 1 entries for user george
2381 acl: acl.deny.branches enabled, 1 entries for user george
2382 acl: acl.allow not enabled
2382 acl: acl.allow not enabled
2383 acl: acl.deny not enabled
2383 acl: acl.deny not enabled
2384 error: pretxnchangegroup.acl hook failed: acl: user "george" denied on branch "default" (changeset "ef1ea85a6374")
2384 error: pretxnchangegroup.acl hook failed: acl: user "george" denied on branch "default" (changeset "ef1ea85a6374")
2385 bundle2-input-part: total payload size 2068
2385 bundle2-input-part: total payload size 2068
2386 bundle2-input-part: total payload size 48
2386 bundle2-input-part: total payload size 48
2387 bundle2-input-bundle: 4 parts total
2387 bundle2-input-bundle: 5 parts total
2388 transaction abort!
2388 transaction abort!
2389 rollback completed
2389 rollback completed
2390 abort: acl: user "george" denied on branch "default" (changeset "ef1ea85a6374")
2390 abort: acl: user "george" denied on branch "default" (changeset "ef1ea85a6374")
2391 no rollback information available
2391 no rollback information available
2392 2:fb35475503ef
2392 2:fb35475503ef
2393
2393
2394
2394
@@ -1,1355 +1,1355 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 > [ui]
13 > [ui]
14 > logtemplate={rev}:{node|short} {desc|firstline}
14 > logtemplate={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" 222 bytes payload
132 bundle2-output-part: "replycaps" 222 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: 222
135 bundle2-output: payload chunk size: 222
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: 222
165 bundle2-input: payload chunk size: 222
166 bundle2-input: payload chunk size: 0
166 bundle2-input: payload chunk size: 0
167 bundle2-input-part: total payload size 222
167 bundle2-input-part: total payload size 222
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: 3 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: 0 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" 222 bytes payload
244 bundle2-output-part: "replycaps" 222 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: 222
247 bundle2-output: payload chunk size: 222
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: 222
278 bundle2-input: payload chunk size: 222
279 bundle2-input: payload chunk size: 0
279 bundle2-input: payload chunk size: 0
280 bundle2-input-part: total payload size 222
280 bundle2-input-part: total payload size 222
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: 3 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 export the active bookmark
331 export the active bookmark
332
332
333 $ hg bookmark V
333 $ hg bookmark V
334 $ hg push -B . ../a
334 $ hg push -B . ../a
335 pushing to ../a
335 pushing to ../a
336 searching for changes
336 searching for changes
337 no changes found
337 no changes found
338 exporting bookmark V
338 exporting bookmark V
339 [1]
339 [1]
340
340
341 exporting the active bookmark with 'push -B .'
341 exporting the active bookmark with 'push -B .'
342 demand that one of the bookmarks is activated
342 demand that one of the bookmarks is activated
343
343
344 $ hg update -r default
344 $ hg update -r default
345 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
345 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
346 (leaving bookmark V)
346 (leaving bookmark V)
347 $ hg push -B . ../a
347 $ hg push -B . ../a
348 abort: no active bookmark!
348 abort: no active bookmark!
349 [255]
349 [255]
350 $ hg update -r V
350 $ hg update -r V
351 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
351 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
352 (activating bookmark V)
352 (activating bookmark V)
353
353
354 delete the bookmark
354 delete the bookmark
355
355
356 $ hg book -d V
356 $ hg book -d V
357 $ hg push -B V ../a
357 $ hg push -B V ../a
358 pushing to ../a
358 pushing to ../a
359 searching for changes
359 searching for changes
360 no changes found
360 no changes found
361 deleting remote bookmark V
361 deleting remote bookmark V
362 [1]
362 [1]
363 $ hg up foobar
363 $ hg up foobar
364 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
364 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
365 (activating bookmark foobar)
365 (activating bookmark foobar)
366
366
367 push/pull name that doesn't exist
367 push/pull name that doesn't exist
368
368
369 $ hg push -B badname ../a
369 $ hg push -B badname ../a
370 pushing to ../a
370 pushing to ../a
371 searching for changes
371 searching for changes
372 bookmark badname does not exist on the local or remote repository!
372 bookmark badname does not exist on the local or remote repository!
373 no changes found
373 no changes found
374 [2]
374 [2]
375 $ hg pull -B anotherbadname ../a
375 $ hg pull -B anotherbadname ../a
376 pulling from ../a
376 pulling from ../a
377 abort: remote bookmark anotherbadname not found!
377 abort: remote bookmark anotherbadname not found!
378 [255]
378 [255]
379
379
380 divergent bookmarks
380 divergent bookmarks
381
381
382 $ cd ../a
382 $ cd ../a
383 $ echo c1 > f1
383 $ echo c1 > f1
384 $ hg ci -Am1
384 $ hg ci -Am1
385 adding f1
385 adding f1
386 $ hg book -f @
386 $ hg book -f @
387 $ hg book -f X
387 $ hg book -f X
388 $ hg book
388 $ hg book
389 @ 1:0d2164f0ce0d
389 @ 1:0d2164f0ce0d
390 * X 1:0d2164f0ce0d
390 * X 1:0d2164f0ce0d
391 Y 0:4e3505fd9583
391 Y 0:4e3505fd9583
392 Z 1:0d2164f0ce0d
392 Z 1:0d2164f0ce0d
393
393
394 $ cd ../b
394 $ cd ../b
395 $ hg up
395 $ hg up
396 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
396 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
397 updating bookmark foobar
397 updating bookmark foobar
398 $ echo c2 > f2
398 $ echo c2 > f2
399 $ hg ci -Am2
399 $ hg ci -Am2
400 adding f2
400 adding f2
401 $ hg book -if @
401 $ hg book -if @
402 $ hg book -if X
402 $ hg book -if X
403 $ hg book
403 $ hg book
404 @ 1:9b140be10808
404 @ 1:9b140be10808
405 X 1:9b140be10808
405 X 1:9b140be10808
406 Y 0:4e3505fd9583
406 Y 0:4e3505fd9583
407 Z 0:4e3505fd9583
407 Z 0:4e3505fd9583
408 foo -1:000000000000
408 foo -1:000000000000
409 * foobar 1:9b140be10808
409 * foobar 1:9b140be10808
410
410
411 $ hg pull --config paths.foo=../a foo --config "$TESTHOOK"
411 $ hg pull --config paths.foo=../a foo --config "$TESTHOOK"
412 pulling from $TESTTMP/a
412 pulling from $TESTTMP/a
413 searching for changes
413 searching for changes
414 adding changesets
414 adding changesets
415 adding manifests
415 adding manifests
416 adding file changes
416 adding file changes
417 divergent bookmark @ stored as @foo
417 divergent bookmark @ stored as @foo
418 divergent bookmark X stored as X@foo
418 divergent bookmark X stored as X@foo
419 updating bookmark Z
419 updating bookmark Z
420 added 1 changesets with 1 changes to 1 files (+1 heads)
420 added 1 changesets with 1 changes to 1 files (+1 heads)
421 new changesets 0d2164f0ce0d (1 drafts)
421 new changesets 0d2164f0ce0d (1 drafts)
422 test-hook-bookmark: @foo: -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
422 test-hook-bookmark: @foo: -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
423 test-hook-bookmark: X@foo: -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
423 test-hook-bookmark: X@foo: -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
424 test-hook-bookmark: Z: 4e3505fd95835d721066b76e75dbb8cc554d7f77 -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
424 test-hook-bookmark: Z: 4e3505fd95835d721066b76e75dbb8cc554d7f77 -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
425 (run 'hg heads' to see heads, 'hg merge' to merge)
425 (run 'hg heads' to see heads, 'hg merge' to merge)
426 $ hg book
426 $ hg book
427 @ 1:9b140be10808
427 @ 1:9b140be10808
428 @foo 2:0d2164f0ce0d
428 @foo 2:0d2164f0ce0d
429 X 1:9b140be10808
429 X 1:9b140be10808
430 X@foo 2:0d2164f0ce0d
430 X@foo 2:0d2164f0ce0d
431 Y 0:4e3505fd9583
431 Y 0:4e3505fd9583
432 Z 2:0d2164f0ce0d
432 Z 2:0d2164f0ce0d
433 foo -1:000000000000
433 foo -1:000000000000
434 * foobar 1:9b140be10808
434 * foobar 1:9b140be10808
435
435
436 (test that too many divergence of bookmark)
436 (test that too many divergence of bookmark)
437
437
438 $ "$PYTHON" $TESTDIR/seq.py 1 100 | while read i; do hg bookmarks -r 000000000000 "X@${i}"; done
438 $ "$PYTHON" $TESTDIR/seq.py 1 100 | while read i; do hg bookmarks -r 000000000000 "X@${i}"; done
439 $ hg pull ../a
439 $ hg pull ../a
440 pulling from ../a
440 pulling from ../a
441 searching for changes
441 searching for changes
442 no changes found
442 no changes found
443 warning: failed to assign numbered name to divergent bookmark X
443 warning: failed to assign numbered name to divergent bookmark X
444 divergent bookmark @ stored as @1
444 divergent bookmark @ stored as @1
445 $ hg bookmarks | grep '^ X' | grep -v ':000000000000'
445 $ hg bookmarks | grep '^ X' | grep -v ':000000000000'
446 X 1:9b140be10808
446 X 1:9b140be10808
447 X@foo 2:0d2164f0ce0d
447 X@foo 2:0d2164f0ce0d
448
448
449 (test that remotely diverged bookmarks are reused if they aren't changed)
449 (test that remotely diverged bookmarks are reused if they aren't changed)
450
450
451 $ hg bookmarks | grep '^ @'
451 $ hg bookmarks | grep '^ @'
452 @ 1:9b140be10808
452 @ 1:9b140be10808
453 @1 2:0d2164f0ce0d
453 @1 2:0d2164f0ce0d
454 @foo 2:0d2164f0ce0d
454 @foo 2:0d2164f0ce0d
455 $ hg pull ../a
455 $ hg pull ../a
456 pulling from ../a
456 pulling from ../a
457 searching for changes
457 searching for changes
458 no changes found
458 no changes found
459 warning: failed to assign numbered name to divergent bookmark X
459 warning: failed to assign numbered name to divergent bookmark X
460 divergent bookmark @ stored as @1
460 divergent bookmark @ stored as @1
461 $ hg bookmarks | grep '^ @'
461 $ hg bookmarks | grep '^ @'
462 @ 1:9b140be10808
462 @ 1:9b140be10808
463 @1 2:0d2164f0ce0d
463 @1 2:0d2164f0ce0d
464 @foo 2:0d2164f0ce0d
464 @foo 2:0d2164f0ce0d
465
465
466 $ "$PYTHON" $TESTDIR/seq.py 1 100 | while read i; do hg bookmarks -d "X@${i}"; done
466 $ "$PYTHON" $TESTDIR/seq.py 1 100 | while read i; do hg bookmarks -d "X@${i}"; done
467 $ hg bookmarks -d "@1"
467 $ hg bookmarks -d "@1"
468
468
469 $ hg push -f ../a
469 $ hg push -f ../a
470 pushing to ../a
470 pushing to ../a
471 searching for changes
471 searching for changes
472 adding changesets
472 adding changesets
473 adding manifests
473 adding manifests
474 adding file changes
474 adding file changes
475 added 1 changesets with 1 changes to 1 files (+1 heads)
475 added 1 changesets with 1 changes to 1 files (+1 heads)
476 $ hg -R ../a book
476 $ hg -R ../a book
477 @ 1:0d2164f0ce0d
477 @ 1:0d2164f0ce0d
478 * X 1:0d2164f0ce0d
478 * X 1:0d2164f0ce0d
479 Y 0:4e3505fd9583
479 Y 0:4e3505fd9583
480 Z 1:0d2164f0ce0d
480 Z 1:0d2164f0ce0d
481
481
482 explicit pull should overwrite the local version (issue4439)
482 explicit pull should overwrite the local version (issue4439)
483
483
484 $ hg update -r X
484 $ hg update -r X
485 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
485 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
486 (activating bookmark X)
486 (activating bookmark X)
487 $ hg pull --config paths.foo=../a foo -B . --config "$TESTHOOK"
487 $ hg pull --config paths.foo=../a foo -B . --config "$TESTHOOK"
488 pulling from $TESTTMP/a
488 pulling from $TESTTMP/a
489 no changes found
489 no changes found
490 divergent bookmark @ stored as @foo
490 divergent bookmark @ stored as @foo
491 importing bookmark X
491 importing bookmark X
492 test-hook-bookmark: @foo: 0d2164f0ce0d8f1d6f94351eba04b794909be66c -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
492 test-hook-bookmark: @foo: 0d2164f0ce0d8f1d6f94351eba04b794909be66c -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
493 test-hook-bookmark: X: 9b140be1080824d768c5a4691a564088eede71f9 -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
493 test-hook-bookmark: X: 9b140be1080824d768c5a4691a564088eede71f9 -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
494
494
495 reinstall state for further testing:
495 reinstall state for further testing:
496
496
497 $ hg book -fr 9b140be10808 X
497 $ hg book -fr 9b140be10808 X
498
498
499 revsets should not ignore divergent bookmarks
499 revsets should not ignore divergent bookmarks
500
500
501 $ hg bookmark -fr 1 Z
501 $ hg bookmark -fr 1 Z
502 $ hg log -r 'bookmark()' --template '{rev}:{node|short} {bookmarks}\n'
502 $ hg log -r 'bookmark()' --template '{rev}:{node|short} {bookmarks}\n'
503 0:4e3505fd9583 Y
503 0:4e3505fd9583 Y
504 1:9b140be10808 @ X Z foobar
504 1:9b140be10808 @ X Z foobar
505 2:0d2164f0ce0d @foo X@foo
505 2:0d2164f0ce0d @foo X@foo
506 $ hg log -r 'bookmark("X@foo")' --template '{rev}:{node|short} {bookmarks}\n'
506 $ hg log -r 'bookmark("X@foo")' --template '{rev}:{node|short} {bookmarks}\n'
507 2:0d2164f0ce0d @foo X@foo
507 2:0d2164f0ce0d @foo X@foo
508 $ hg log -r 'bookmark("re:X@foo")' --template '{rev}:{node|short} {bookmarks}\n'
508 $ hg log -r 'bookmark("re:X@foo")' --template '{rev}:{node|short} {bookmarks}\n'
509 2:0d2164f0ce0d @foo X@foo
509 2:0d2164f0ce0d @foo X@foo
510
510
511 update a remote bookmark from a non-head to a head
511 update a remote bookmark from a non-head to a head
512
512
513 $ hg up -q Y
513 $ hg up -q Y
514 $ echo c3 > f2
514 $ echo c3 > f2
515 $ hg ci -Am3
515 $ hg ci -Am3
516 adding f2
516 adding f2
517 created new head
517 created new head
518 $ hg push ../a --config "$TESTHOOK"
518 $ hg push ../a --config "$TESTHOOK"
519 pushing to ../a
519 pushing to ../a
520 searching for changes
520 searching for changes
521 adding changesets
521 adding changesets
522 adding manifests
522 adding manifests
523 adding file changes
523 adding file changes
524 added 1 changesets with 1 changes to 1 files (+1 heads)
524 added 1 changesets with 1 changes to 1 files (+1 heads)
525 test-hook-bookmark: Y: 4e3505fd95835d721066b76e75dbb8cc554d7f77 -> f6fc62dde3c0771e29704af56ba4d8af77abcc2f
525 test-hook-bookmark: Y: 4e3505fd95835d721066b76e75dbb8cc554d7f77 -> f6fc62dde3c0771e29704af56ba4d8af77abcc2f
526 updating bookmark Y
526 updating bookmark Y
527 $ hg -R ../a book
527 $ hg -R ../a book
528 @ 1:0d2164f0ce0d
528 @ 1:0d2164f0ce0d
529 * X 1:0d2164f0ce0d
529 * X 1:0d2164f0ce0d
530 Y 3:f6fc62dde3c0
530 Y 3:f6fc62dde3c0
531 Z 1:0d2164f0ce0d
531 Z 1:0d2164f0ce0d
532
532
533 update a bookmark in the middle of a client pulling changes
533 update a bookmark in the middle of a client pulling changes
534
534
535 $ cd ..
535 $ cd ..
536 $ hg clone -q a pull-race
536 $ hg clone -q a pull-race
537
537
538 We want to use http because it is stateless and therefore more susceptible to
538 We want to use http because it is stateless and therefore more susceptible to
539 race conditions
539 race conditions
540
540
541 $ hg serve -R pull-race -p $HGPORT -d --pid-file=pull-race.pid -E main-error.log
541 $ hg serve -R pull-race -p $HGPORT -d --pid-file=pull-race.pid -E main-error.log
542 $ cat pull-race.pid >> $DAEMON_PIDS
542 $ cat pull-race.pid >> $DAEMON_PIDS
543
543
544 $ cat <<EOF > $TESTTMP/out_makecommit.sh
544 $ cat <<EOF > $TESTTMP/out_makecommit.sh
545 > #!/bin/sh
545 > #!/bin/sh
546 > hg ci -Am5
546 > hg ci -Am5
547 > echo committed in pull-race
547 > echo committed in pull-race
548 > EOF
548 > EOF
549
549
550 $ hg clone -q http://localhost:$HGPORT/ pull-race2 --config "$TESTHOOK"
550 $ hg clone -q http://localhost:$HGPORT/ pull-race2 --config "$TESTHOOK"
551 test-hook-bookmark: @: -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
551 test-hook-bookmark: @: -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
552 test-hook-bookmark: X: -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
552 test-hook-bookmark: X: -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
553 test-hook-bookmark: Y: -> f6fc62dde3c0771e29704af56ba4d8af77abcc2f
553 test-hook-bookmark: Y: -> f6fc62dde3c0771e29704af56ba4d8af77abcc2f
554 test-hook-bookmark: Z: -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
554 test-hook-bookmark: Z: -> 0d2164f0ce0d8f1d6f94351eba04b794909be66c
555 $ cd pull-race
555 $ cd pull-race
556 $ hg up -q Y
556 $ hg up -q Y
557 $ echo c4 > f2
557 $ echo c4 > f2
558 $ hg ci -Am4
558 $ hg ci -Am4
559 $ echo c5 > f3
559 $ echo c5 > f3
560 $ cat <<EOF > .hg/hgrc
560 $ cat <<EOF > .hg/hgrc
561 > [hooks]
561 > [hooks]
562 > outgoing.makecommit = sh $TESTTMP/out_makecommit.sh
562 > outgoing.makecommit = sh $TESTTMP/out_makecommit.sh
563 > EOF
563 > EOF
564
564
565 (new config needs a server restart)
565 (new config needs a server restart)
566
566
567 $ cd ..
567 $ cd ..
568 $ killdaemons.py
568 $ killdaemons.py
569 $ hg serve -R pull-race -p $HGPORT -d --pid-file=pull-race.pid -E main-error.log
569 $ hg serve -R pull-race -p $HGPORT -d --pid-file=pull-race.pid -E main-error.log
570 $ cat pull-race.pid >> $DAEMON_PIDS
570 $ cat pull-race.pid >> $DAEMON_PIDS
571 $ cd pull-race2
571 $ cd pull-race2
572 $ hg -R $TESTTMP/pull-race book
572 $ hg -R $TESTTMP/pull-race book
573 @ 1:0d2164f0ce0d
573 @ 1:0d2164f0ce0d
574 X 1:0d2164f0ce0d
574 X 1:0d2164f0ce0d
575 * Y 4:b0a5eff05604
575 * Y 4:b0a5eff05604
576 Z 1:0d2164f0ce0d
576 Z 1:0d2164f0ce0d
577 $ hg pull
577 $ hg pull
578 pulling from http://localhost:$HGPORT/
578 pulling from http://localhost:$HGPORT/
579 searching for changes
579 searching for changes
580 adding changesets
580 adding changesets
581 adding manifests
581 adding manifests
582 adding file changes
582 adding file changes
583 updating bookmark Y
583 updating bookmark Y
584 added 1 changesets with 1 changes to 1 files
584 added 1 changesets with 1 changes to 1 files
585 new changesets b0a5eff05604 (1 drafts)
585 new changesets b0a5eff05604 (1 drafts)
586 (run 'hg update' to get a working copy)
586 (run 'hg update' to get a working copy)
587 $ hg book
587 $ hg book
588 * @ 1:0d2164f0ce0d
588 * @ 1:0d2164f0ce0d
589 X 1:0d2164f0ce0d
589 X 1:0d2164f0ce0d
590 Y 4:b0a5eff05604
590 Y 4:b0a5eff05604
591 Z 1:0d2164f0ce0d
591 Z 1:0d2164f0ce0d
592
592
593 Update a bookmark right after the initial lookup -B (issue4689)
593 Update a bookmark right after the initial lookup -B (issue4689)
594
594
595 $ echo c6 > ../pull-race/f3 # to be committed during the race
595 $ echo c6 > ../pull-race/f3 # to be committed during the race
596 $ cat <<EOF > $TESTTMP/listkeys_makecommit.sh
596 $ cat <<EOF > $TESTTMP/listkeys_makecommit.sh
597 > #!/bin/sh
597 > #!/bin/sh
598 > if hg st | grep -q M; then
598 > if hg st | grep -q M; then
599 > hg commit -m race
599 > hg commit -m race
600 > echo committed in pull-race
600 > echo committed in pull-race
601 > else
601 > else
602 > exit 0
602 > exit 0
603 > fi
603 > fi
604 > EOF
604 > EOF
605 $ cat <<EOF > ../pull-race/.hg/hgrc
605 $ cat <<EOF > ../pull-race/.hg/hgrc
606 > [hooks]
606 > [hooks]
607 > # If anything to commit, commit it right after the first key listing used
607 > # If anything to commit, commit it right after the first key listing used
608 > # during lookup. This makes the commit appear before the actual getbundle
608 > # during lookup. This makes the commit appear before the actual getbundle
609 > # call.
609 > # call.
610 > listkeys.makecommit= sh $TESTTMP/listkeys_makecommit.sh
610 > listkeys.makecommit= sh $TESTTMP/listkeys_makecommit.sh
611 > EOF
611 > EOF
612 $ restart_server() {
612 $ restart_server() {
613 > "$TESTDIR/killdaemons.py" $DAEMON_PIDS
613 > "$TESTDIR/killdaemons.py" $DAEMON_PIDS
614 > hg serve -R ../pull-race -p $HGPORT -d --pid-file=../pull-race.pid -E main-error.log
614 > hg serve -R ../pull-race -p $HGPORT -d --pid-file=../pull-race.pid -E main-error.log
615 > cat ../pull-race.pid >> $DAEMON_PIDS
615 > cat ../pull-race.pid >> $DAEMON_PIDS
616 > }
616 > }
617 $ restart_server # new config need server restart
617 $ restart_server # new config need server restart
618 $ hg -R $TESTTMP/pull-race book
618 $ hg -R $TESTTMP/pull-race book
619 @ 1:0d2164f0ce0d
619 @ 1:0d2164f0ce0d
620 X 1:0d2164f0ce0d
620 X 1:0d2164f0ce0d
621 * Y 5:35d1ef0a8d1b
621 * Y 5:35d1ef0a8d1b
622 Z 1:0d2164f0ce0d
622 Z 1:0d2164f0ce0d
623 $ hg update -r Y
623 $ hg update -r Y
624 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
624 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
625 (activating bookmark Y)
625 (activating bookmark Y)
626 $ hg pull -B .
626 $ hg pull -B .
627 pulling from http://localhost:$HGPORT/
627 pulling from http://localhost:$HGPORT/
628 searching for changes
628 searching for changes
629 adding changesets
629 adding changesets
630 adding manifests
630 adding manifests
631 adding file changes
631 adding file changes
632 updating bookmark Y
632 updating bookmark Y
633 added 1 changesets with 1 changes to 1 files
633 added 1 changesets with 1 changes to 1 files
634 new changesets 35d1ef0a8d1b (1 drafts)
634 new changesets 35d1ef0a8d1b (1 drafts)
635 (run 'hg update' to get a working copy)
635 (run 'hg update' to get a working copy)
636 $ hg book
636 $ hg book
637 @ 1:0d2164f0ce0d
637 @ 1:0d2164f0ce0d
638 X 1:0d2164f0ce0d
638 X 1:0d2164f0ce0d
639 * Y 5:35d1ef0a8d1b
639 * Y 5:35d1ef0a8d1b
640 Z 1:0d2164f0ce0d
640 Z 1:0d2164f0ce0d
641
641
642 Update a bookmark right after the initial lookup -r (issue4700)
642 Update a bookmark right after the initial lookup -r (issue4700)
643
643
644 $ echo c7 > ../pull-race/f3 # to be committed during the race
644 $ echo c7 > ../pull-race/f3 # to be committed during the race
645 $ cat <<EOF > ../lookuphook.py
645 $ cat <<EOF > ../lookuphook.py
646 > """small extensions adding a hook after wireprotocol lookup to test race"""
646 > """small extensions adding a hook after wireprotocol lookup to test race"""
647 > import functools
647 > import functools
648 > from mercurial import wireprotov1server, wireprotov2server
648 > from mercurial import wireprotov1server, wireprotov2server
649 >
649 >
650 > def wrappedlookup(orig, repo, *args, **kwargs):
650 > def wrappedlookup(orig, repo, *args, **kwargs):
651 > ret = orig(repo, *args, **kwargs)
651 > ret = orig(repo, *args, **kwargs)
652 > repo.hook(b'lookup')
652 > repo.hook(b'lookup')
653 > return ret
653 > return ret
654 > for table in [wireprotov1server.commands, wireprotov2server.COMMANDS]:
654 > for table in [wireprotov1server.commands, wireprotov2server.COMMANDS]:
655 > table[b'lookup'].func = functools.partial(wrappedlookup, table[b'lookup'].func)
655 > table[b'lookup'].func = functools.partial(wrappedlookup, table[b'lookup'].func)
656 > EOF
656 > EOF
657 $ cat <<EOF > ../pull-race/.hg/hgrc
657 $ cat <<EOF > ../pull-race/.hg/hgrc
658 > [extensions]
658 > [extensions]
659 > lookuphook=$TESTTMP/lookuphook.py
659 > lookuphook=$TESTTMP/lookuphook.py
660 > [hooks]
660 > [hooks]
661 > lookup.makecommit= sh $TESTTMP/listkeys_makecommit.sh
661 > lookup.makecommit= sh $TESTTMP/listkeys_makecommit.sh
662 > EOF
662 > EOF
663 $ restart_server # new config need server restart
663 $ restart_server # new config need server restart
664 $ hg -R $TESTTMP/pull-race book
664 $ hg -R $TESTTMP/pull-race book
665 @ 1:0d2164f0ce0d
665 @ 1:0d2164f0ce0d
666 X 1:0d2164f0ce0d
666 X 1:0d2164f0ce0d
667 * Y 6:0d60821d2197
667 * Y 6:0d60821d2197
668 Z 1:0d2164f0ce0d
668 Z 1:0d2164f0ce0d
669 $ hg pull -r Y
669 $ hg pull -r Y
670 pulling from http://localhost:$HGPORT/
670 pulling from http://localhost:$HGPORT/
671 searching for changes
671 searching for changes
672 adding changesets
672 adding changesets
673 adding manifests
673 adding manifests
674 adding file changes
674 adding file changes
675 updating bookmark Y
675 updating bookmark Y
676 added 1 changesets with 1 changes to 1 files
676 added 1 changesets with 1 changes to 1 files
677 new changesets 0d60821d2197 (1 drafts)
677 new changesets 0d60821d2197 (1 drafts)
678 (run 'hg update' to get a working copy)
678 (run 'hg update' to get a working copy)
679 $ hg book
679 $ hg book
680 @ 1:0d2164f0ce0d
680 @ 1:0d2164f0ce0d
681 X 1:0d2164f0ce0d
681 X 1:0d2164f0ce0d
682 * Y 6:0d60821d2197
682 * Y 6:0d60821d2197
683 Z 1:0d2164f0ce0d
683 Z 1:0d2164f0ce0d
684 $ hg -R $TESTTMP/pull-race book
684 $ hg -R $TESTTMP/pull-race book
685 @ 1:0d2164f0ce0d
685 @ 1:0d2164f0ce0d
686 X 1:0d2164f0ce0d
686 X 1:0d2164f0ce0d
687 * Y 7:714424d9e8b8
687 * Y 7:714424d9e8b8
688 Z 1:0d2164f0ce0d
688 Z 1:0d2164f0ce0d
689
689
690 (done with this section of the test)
690 (done with this section of the test)
691
691
692 $ killdaemons.py
692 $ killdaemons.py
693 $ cd ../b
693 $ cd ../b
694
694
695 diverging a remote bookmark fails
695 diverging a remote bookmark fails
696
696
697 $ hg up -q 4e3505fd9583
697 $ hg up -q 4e3505fd9583
698 $ echo c4 > f2
698 $ echo c4 > f2
699 $ hg ci -Am4
699 $ hg ci -Am4
700 adding f2
700 adding f2
701 created new head
701 created new head
702 $ echo c5 > f2
702 $ echo c5 > f2
703 $ hg ci -Am5
703 $ hg ci -Am5
704 $ hg log -G
704 $ hg log -G
705 @ 5:c922c0139ca0 5
705 @ 5:c922c0139ca0 5
706 |
706 |
707 o 4:4efff6d98829 4
707 o 4:4efff6d98829 4
708 |
708 |
709 | o 3:f6fc62dde3c0 3
709 | o 3:f6fc62dde3c0 3
710 |/
710 |/
711 | o 2:0d2164f0ce0d 1
711 | o 2:0d2164f0ce0d 1
712 |/
712 |/
713 | o 1:9b140be10808 2
713 | o 1:9b140be10808 2
714 |/
714 |/
715 o 0:4e3505fd9583 test
715 o 0:4e3505fd9583 test
716
716
717
717
718 $ hg book -f Y
718 $ hg book -f Y
719
719
720 $ cat <<EOF > ../a/.hg/hgrc
720 $ cat <<EOF > ../a/.hg/hgrc
721 > [web]
721 > [web]
722 > push_ssl = false
722 > push_ssl = false
723 > allow_push = *
723 > allow_push = *
724 > EOF
724 > EOF
725
725
726 $ hg serve -R ../a -p $HGPORT2 -d --pid-file=../hg2.pid
726 $ hg serve -R ../a -p $HGPORT2 -d --pid-file=../hg2.pid
727 $ cat ../hg2.pid >> $DAEMON_PIDS
727 $ cat ../hg2.pid >> $DAEMON_PIDS
728
728
729 $ hg push http://localhost:$HGPORT2/
729 $ hg push http://localhost:$HGPORT2/
730 pushing to http://localhost:$HGPORT2/
730 pushing to http://localhost:$HGPORT2/
731 searching for changes
731 searching for changes
732 abort: push creates new remote head c922c0139ca0 with bookmark 'Y'!
732 abort: push creates new remote head c922c0139ca0 with bookmark 'Y'!
733 (merge or see 'hg help push' for details about pushing new heads)
733 (merge or see 'hg help push' for details about pushing new heads)
734 [255]
734 [255]
735 $ hg -R ../a book
735 $ hg -R ../a book
736 @ 1:0d2164f0ce0d
736 @ 1:0d2164f0ce0d
737 * X 1:0d2164f0ce0d
737 * X 1:0d2164f0ce0d
738 Y 3:f6fc62dde3c0
738 Y 3:f6fc62dde3c0
739 Z 1:0d2164f0ce0d
739 Z 1:0d2164f0ce0d
740
740
741
741
742 Unrelated marker does not alter the decision
742 Unrelated marker does not alter the decision
743
743
744 $ hg debugobsolete aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
744 $ hg debugobsolete aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
745 1 new obsolescence markers
745 1 new obsolescence markers
746 $ hg push http://localhost:$HGPORT2/
746 $ hg push http://localhost:$HGPORT2/
747 pushing to http://localhost:$HGPORT2/
747 pushing to http://localhost:$HGPORT2/
748 searching for changes
748 searching for changes
749 abort: push creates new remote head c922c0139ca0 with bookmark 'Y'!
749 abort: push creates new remote head c922c0139ca0 with bookmark 'Y'!
750 (merge or see 'hg help push' for details about pushing new heads)
750 (merge or see 'hg help push' for details about pushing new heads)
751 [255]
751 [255]
752 $ hg -R ../a book
752 $ hg -R ../a book
753 @ 1:0d2164f0ce0d
753 @ 1:0d2164f0ce0d
754 * X 1:0d2164f0ce0d
754 * X 1:0d2164f0ce0d
755 Y 3:f6fc62dde3c0
755 Y 3:f6fc62dde3c0
756 Z 1:0d2164f0ce0d
756 Z 1:0d2164f0ce0d
757
757
758 Update to a successor works
758 Update to a successor works
759
759
760 $ hg id --debug -r 3
760 $ hg id --debug -r 3
761 f6fc62dde3c0771e29704af56ba4d8af77abcc2f
761 f6fc62dde3c0771e29704af56ba4d8af77abcc2f
762 $ hg id --debug -r 4
762 $ hg id --debug -r 4
763 4efff6d98829d9c824c621afd6e3f01865f5439f
763 4efff6d98829d9c824c621afd6e3f01865f5439f
764 $ hg id --debug -r 5
764 $ hg id --debug -r 5
765 c922c0139ca03858f655e4a2af4dd02796a63969 tip Y
765 c922c0139ca03858f655e4a2af4dd02796a63969 tip Y
766 $ hg debugobsolete f6fc62dde3c0771e29704af56ba4d8af77abcc2f cccccccccccccccccccccccccccccccccccccccc
766 $ hg debugobsolete f6fc62dde3c0771e29704af56ba4d8af77abcc2f cccccccccccccccccccccccccccccccccccccccc
767 1 new obsolescence markers
767 1 new obsolescence markers
768 obsoleted 1 changesets
768 obsoleted 1 changesets
769 $ hg debugobsolete cccccccccccccccccccccccccccccccccccccccc 4efff6d98829d9c824c621afd6e3f01865f5439f
769 $ hg debugobsolete cccccccccccccccccccccccccccccccccccccccc 4efff6d98829d9c824c621afd6e3f01865f5439f
770 1 new obsolescence markers
770 1 new obsolescence markers
771 $ hg push http://localhost:$HGPORT2/
771 $ hg push http://localhost:$HGPORT2/
772 pushing to http://localhost:$HGPORT2/
772 pushing to http://localhost:$HGPORT2/
773 searching for changes
773 searching for changes
774 remote: adding changesets
774 remote: adding changesets
775 remote: adding manifests
775 remote: adding manifests
776 remote: adding file changes
776 remote: adding file changes
777 remote: added 2 changesets with 2 changes to 1 files (+1 heads)
777 remote: added 2 changesets with 2 changes to 1 files (+1 heads)
778 remote: 2 new obsolescence markers
778 remote: 2 new obsolescence markers
779 remote: obsoleted 1 changesets
779 remote: obsoleted 1 changesets
780 updating bookmark Y
780 updating bookmark Y
781 $ hg -R ../a book
781 $ hg -R ../a book
782 @ 1:0d2164f0ce0d
782 @ 1:0d2164f0ce0d
783 * X 1:0d2164f0ce0d
783 * X 1:0d2164f0ce0d
784 Y 5:c922c0139ca0
784 Y 5:c922c0139ca0
785 Z 1:0d2164f0ce0d
785 Z 1:0d2164f0ce0d
786
786
787 hgweb
787 hgweb
788
788
789 $ cat <<EOF > .hg/hgrc
789 $ cat <<EOF > .hg/hgrc
790 > [web]
790 > [web]
791 > push_ssl = false
791 > push_ssl = false
792 > allow_push = *
792 > allow_push = *
793 > EOF
793 > EOF
794
794
795 $ hg serve -p $HGPORT -d --pid-file=../hg.pid -E errors.log
795 $ hg serve -p $HGPORT -d --pid-file=../hg.pid -E errors.log
796 $ cat ../hg.pid >> $DAEMON_PIDS
796 $ cat ../hg.pid >> $DAEMON_PIDS
797 $ cd ../a
797 $ cd ../a
798
798
799 $ hg debugpushkey http://localhost:$HGPORT/ namespaces
799 $ hg debugpushkey http://localhost:$HGPORT/ namespaces
800 bookmarks
800 bookmarks
801 namespaces
801 namespaces
802 obsolete
802 obsolete
803 phases
803 phases
804 $ hg debugpushkey http://localhost:$HGPORT/ bookmarks
804 $ hg debugpushkey http://localhost:$HGPORT/ bookmarks
805 @ 9b140be1080824d768c5a4691a564088eede71f9
805 @ 9b140be1080824d768c5a4691a564088eede71f9
806 X 9b140be1080824d768c5a4691a564088eede71f9
806 X 9b140be1080824d768c5a4691a564088eede71f9
807 Y c922c0139ca03858f655e4a2af4dd02796a63969
807 Y c922c0139ca03858f655e4a2af4dd02796a63969
808 Z 9b140be1080824d768c5a4691a564088eede71f9
808 Z 9b140be1080824d768c5a4691a564088eede71f9
809 foo 0000000000000000000000000000000000000000
809 foo 0000000000000000000000000000000000000000
810 foobar 9b140be1080824d768c5a4691a564088eede71f9
810 foobar 9b140be1080824d768c5a4691a564088eede71f9
811 $ hg out -B http://localhost:$HGPORT/
811 $ hg out -B http://localhost:$HGPORT/
812 comparing with http://localhost:$HGPORT/
812 comparing with http://localhost:$HGPORT/
813 searching for changed bookmarks
813 searching for changed bookmarks
814 @ 0d2164f0ce0d
814 @ 0d2164f0ce0d
815 X 0d2164f0ce0d
815 X 0d2164f0ce0d
816 Z 0d2164f0ce0d
816 Z 0d2164f0ce0d
817 foo
817 foo
818 foobar
818 foobar
819 $ hg push -B Z http://localhost:$HGPORT/
819 $ hg push -B Z http://localhost:$HGPORT/
820 pushing to http://localhost:$HGPORT/
820 pushing to http://localhost:$HGPORT/
821 searching for changes
821 searching for changes
822 no changes found
822 no changes found
823 updating bookmark Z
823 updating bookmark Z
824 [1]
824 [1]
825 $ hg book -d Z
825 $ hg book -d Z
826 $ hg in -B http://localhost:$HGPORT/
826 $ hg in -B http://localhost:$HGPORT/
827 comparing with http://localhost:$HGPORT/
827 comparing with http://localhost:$HGPORT/
828 searching for changed bookmarks
828 searching for changed bookmarks
829 @ 9b140be10808
829 @ 9b140be10808
830 X 9b140be10808
830 X 9b140be10808
831 Z 0d2164f0ce0d
831 Z 0d2164f0ce0d
832 foo 000000000000
832 foo 000000000000
833 foobar 9b140be10808
833 foobar 9b140be10808
834 $ hg pull -B Z http://localhost:$HGPORT/
834 $ hg pull -B Z http://localhost:$HGPORT/
835 pulling from http://localhost:$HGPORT/
835 pulling from http://localhost:$HGPORT/
836 no changes found
836 no changes found
837 divergent bookmark @ stored as @1
837 divergent bookmark @ stored as @1
838 divergent bookmark X stored as X@1
838 divergent bookmark X stored as X@1
839 adding remote bookmark Z
839 adding remote bookmark Z
840 adding remote bookmark foo
840 adding remote bookmark foo
841 adding remote bookmark foobar
841 adding remote bookmark foobar
842 $ hg clone http://localhost:$HGPORT/ cloned-bookmarks
842 $ hg clone http://localhost:$HGPORT/ cloned-bookmarks
843 requesting all changes
843 requesting all changes
844 adding changesets
844 adding changesets
845 adding manifests
845 adding manifests
846 adding file changes
846 adding file changes
847 added 5 changesets with 5 changes to 3 files (+2 heads)
847 added 5 changesets with 5 changes to 3 files (+2 heads)
848 2 new obsolescence markers
848 2 new obsolescence markers
849 new changesets 4e3505fd9583:c922c0139ca0 (5 drafts)
849 new changesets 4e3505fd9583:c922c0139ca0 (5 drafts)
850 updating to bookmark @
850 updating to bookmark @
851 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
851 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
852 $ hg -R cloned-bookmarks bookmarks
852 $ hg -R cloned-bookmarks bookmarks
853 * @ 1:9b140be10808
853 * @ 1:9b140be10808
854 X 1:9b140be10808
854 X 1:9b140be10808
855 Y 4:c922c0139ca0
855 Y 4:c922c0139ca0
856 Z 2:0d2164f0ce0d
856 Z 2:0d2164f0ce0d
857 foo -1:000000000000
857 foo -1:000000000000
858 foobar 1:9b140be10808
858 foobar 1:9b140be10808
859
859
860 $ cd ..
860 $ cd ..
861
861
862 Test to show result of bookmarks comparison
862 Test to show result of bookmarks comparison
863
863
864 $ mkdir bmcomparison
864 $ mkdir bmcomparison
865 $ cd bmcomparison
865 $ cd bmcomparison
866
866
867 $ hg init source
867 $ hg init source
868 $ hg -R source debugbuilddag '+2*2*3*4'
868 $ hg -R source debugbuilddag '+2*2*3*4'
869 $ hg -R source log -G --template '{rev}:{node|short}'
869 $ hg -R source log -G --template '{rev}:{node|short}'
870 o 4:e7bd5218ca15
870 o 4:e7bd5218ca15
871 |
871 |
872 | o 3:6100d3090acf
872 | o 3:6100d3090acf
873 |/
873 |/
874 | o 2:fa942426a6fd
874 | o 2:fa942426a6fd
875 |/
875 |/
876 | o 1:66f7d451a68b
876 | o 1:66f7d451a68b
877 |/
877 |/
878 o 0:1ea73414a91b
878 o 0:1ea73414a91b
879
879
880 $ hg -R source bookmarks -r 0 SAME
880 $ hg -R source bookmarks -r 0 SAME
881 $ hg -R source bookmarks -r 0 ADV_ON_REPO1
881 $ hg -R source bookmarks -r 0 ADV_ON_REPO1
882 $ hg -R source bookmarks -r 0 ADV_ON_REPO2
882 $ hg -R source bookmarks -r 0 ADV_ON_REPO2
883 $ hg -R source bookmarks -r 0 DIFF_ADV_ON_REPO1
883 $ hg -R source bookmarks -r 0 DIFF_ADV_ON_REPO1
884 $ hg -R source bookmarks -r 0 DIFF_ADV_ON_REPO2
884 $ hg -R source bookmarks -r 0 DIFF_ADV_ON_REPO2
885 $ hg -R source bookmarks -r 1 DIVERGED
885 $ hg -R source bookmarks -r 1 DIVERGED
886
886
887 $ hg clone -U source repo1
887 $ hg clone -U source repo1
888
888
889 (test that incoming/outgoing exit with 1, if there is no bookmark to
889 (test that incoming/outgoing exit with 1, if there is no bookmark to
890 be exchanged)
890 be exchanged)
891
891
892 $ hg -R repo1 incoming -B
892 $ hg -R repo1 incoming -B
893 comparing with $TESTTMP/bmcomparison/source
893 comparing with $TESTTMP/bmcomparison/source
894 searching for changed bookmarks
894 searching for changed bookmarks
895 no changed bookmarks found
895 no changed bookmarks found
896 [1]
896 [1]
897 $ hg -R repo1 outgoing -B
897 $ hg -R repo1 outgoing -B
898 comparing with $TESTTMP/bmcomparison/source
898 comparing with $TESTTMP/bmcomparison/source
899 searching for changed bookmarks
899 searching for changed bookmarks
900 no changed bookmarks found
900 no changed bookmarks found
901 [1]
901 [1]
902
902
903 $ hg -R repo1 bookmarks -f -r 1 ADD_ON_REPO1
903 $ hg -R repo1 bookmarks -f -r 1 ADD_ON_REPO1
904 $ hg -R repo1 bookmarks -f -r 2 ADV_ON_REPO1
904 $ hg -R repo1 bookmarks -f -r 2 ADV_ON_REPO1
905 $ hg -R repo1 bookmarks -f -r 3 DIFF_ADV_ON_REPO1
905 $ hg -R repo1 bookmarks -f -r 3 DIFF_ADV_ON_REPO1
906 $ hg -R repo1 bookmarks -f -r 3 DIFF_DIVERGED
906 $ hg -R repo1 bookmarks -f -r 3 DIFF_DIVERGED
907 $ hg -R repo1 -q --config extensions.mq= strip 4
907 $ hg -R repo1 -q --config extensions.mq= strip 4
908 $ hg -R repo1 log -G --template '{node|short} ({bookmarks})'
908 $ hg -R repo1 log -G --template '{node|short} ({bookmarks})'
909 o 6100d3090acf (DIFF_ADV_ON_REPO1 DIFF_DIVERGED)
909 o 6100d3090acf (DIFF_ADV_ON_REPO1 DIFF_DIVERGED)
910 |
910 |
911 | o fa942426a6fd (ADV_ON_REPO1)
911 | o fa942426a6fd (ADV_ON_REPO1)
912 |/
912 |/
913 | o 66f7d451a68b (ADD_ON_REPO1 DIVERGED)
913 | o 66f7d451a68b (ADD_ON_REPO1 DIVERGED)
914 |/
914 |/
915 o 1ea73414a91b (ADV_ON_REPO2 DIFF_ADV_ON_REPO2 SAME)
915 o 1ea73414a91b (ADV_ON_REPO2 DIFF_ADV_ON_REPO2 SAME)
916
916
917
917
918 $ hg clone -U source repo2
918 $ hg clone -U source repo2
919 $ hg -R repo2 bookmarks -f -r 1 ADD_ON_REPO2
919 $ hg -R repo2 bookmarks -f -r 1 ADD_ON_REPO2
920 $ hg -R repo2 bookmarks -f -r 1 ADV_ON_REPO2
920 $ hg -R repo2 bookmarks -f -r 1 ADV_ON_REPO2
921 $ hg -R repo2 bookmarks -f -r 2 DIVERGED
921 $ hg -R repo2 bookmarks -f -r 2 DIVERGED
922 $ hg -R repo2 bookmarks -f -r 4 DIFF_ADV_ON_REPO2
922 $ hg -R repo2 bookmarks -f -r 4 DIFF_ADV_ON_REPO2
923 $ hg -R repo2 bookmarks -f -r 4 DIFF_DIVERGED
923 $ hg -R repo2 bookmarks -f -r 4 DIFF_DIVERGED
924 $ hg -R repo2 -q --config extensions.mq= strip 3
924 $ hg -R repo2 -q --config extensions.mq= strip 3
925 $ hg -R repo2 log -G --template '{node|short} ({bookmarks})'
925 $ hg -R repo2 log -G --template '{node|short} ({bookmarks})'
926 o e7bd5218ca15 (DIFF_ADV_ON_REPO2 DIFF_DIVERGED)
926 o e7bd5218ca15 (DIFF_ADV_ON_REPO2 DIFF_DIVERGED)
927 |
927 |
928 | o fa942426a6fd (DIVERGED)
928 | o fa942426a6fd (DIVERGED)
929 |/
929 |/
930 | o 66f7d451a68b (ADD_ON_REPO2 ADV_ON_REPO2)
930 | o 66f7d451a68b (ADD_ON_REPO2 ADV_ON_REPO2)
931 |/
931 |/
932 o 1ea73414a91b (ADV_ON_REPO1 DIFF_ADV_ON_REPO1 SAME)
932 o 1ea73414a91b (ADV_ON_REPO1 DIFF_ADV_ON_REPO1 SAME)
933
933
934
934
935 (test that difference of bookmarks between repositories are fully shown)
935 (test that difference of bookmarks between repositories are fully shown)
936
936
937 $ hg -R repo1 incoming -B repo2 -v
937 $ hg -R repo1 incoming -B repo2 -v
938 comparing with repo2
938 comparing with repo2
939 searching for changed bookmarks
939 searching for changed bookmarks
940 ADD_ON_REPO2 66f7d451a68b added
940 ADD_ON_REPO2 66f7d451a68b added
941 ADV_ON_REPO2 66f7d451a68b advanced
941 ADV_ON_REPO2 66f7d451a68b advanced
942 DIFF_ADV_ON_REPO2 e7bd5218ca15 changed
942 DIFF_ADV_ON_REPO2 e7bd5218ca15 changed
943 DIFF_DIVERGED e7bd5218ca15 changed
943 DIFF_DIVERGED e7bd5218ca15 changed
944 DIVERGED fa942426a6fd diverged
944 DIVERGED fa942426a6fd diverged
945 $ hg -R repo1 outgoing -B repo2 -v
945 $ hg -R repo1 outgoing -B repo2 -v
946 comparing with repo2
946 comparing with repo2
947 searching for changed bookmarks
947 searching for changed bookmarks
948 ADD_ON_REPO1 66f7d451a68b added
948 ADD_ON_REPO1 66f7d451a68b added
949 ADD_ON_REPO2 deleted
949 ADD_ON_REPO2 deleted
950 ADV_ON_REPO1 fa942426a6fd advanced
950 ADV_ON_REPO1 fa942426a6fd advanced
951 DIFF_ADV_ON_REPO1 6100d3090acf advanced
951 DIFF_ADV_ON_REPO1 6100d3090acf advanced
952 DIFF_ADV_ON_REPO2 1ea73414a91b changed
952 DIFF_ADV_ON_REPO2 1ea73414a91b changed
953 DIFF_DIVERGED 6100d3090acf changed
953 DIFF_DIVERGED 6100d3090acf changed
954 DIVERGED 66f7d451a68b diverged
954 DIVERGED 66f7d451a68b diverged
955
955
956 $ hg -R repo2 incoming -B repo1 -v
956 $ hg -R repo2 incoming -B repo1 -v
957 comparing with repo1
957 comparing with repo1
958 searching for changed bookmarks
958 searching for changed bookmarks
959 ADD_ON_REPO1 66f7d451a68b added
959 ADD_ON_REPO1 66f7d451a68b added
960 ADV_ON_REPO1 fa942426a6fd advanced
960 ADV_ON_REPO1 fa942426a6fd advanced
961 DIFF_ADV_ON_REPO1 6100d3090acf changed
961 DIFF_ADV_ON_REPO1 6100d3090acf changed
962 DIFF_DIVERGED 6100d3090acf changed
962 DIFF_DIVERGED 6100d3090acf changed
963 DIVERGED 66f7d451a68b diverged
963 DIVERGED 66f7d451a68b diverged
964 $ hg -R repo2 outgoing -B repo1 -v
964 $ hg -R repo2 outgoing -B repo1 -v
965 comparing with repo1
965 comparing with repo1
966 searching for changed bookmarks
966 searching for changed bookmarks
967 ADD_ON_REPO1 deleted
967 ADD_ON_REPO1 deleted
968 ADD_ON_REPO2 66f7d451a68b added
968 ADD_ON_REPO2 66f7d451a68b added
969 ADV_ON_REPO2 66f7d451a68b advanced
969 ADV_ON_REPO2 66f7d451a68b advanced
970 DIFF_ADV_ON_REPO1 1ea73414a91b changed
970 DIFF_ADV_ON_REPO1 1ea73414a91b changed
971 DIFF_ADV_ON_REPO2 e7bd5218ca15 advanced
971 DIFF_ADV_ON_REPO2 e7bd5218ca15 advanced
972 DIFF_DIVERGED e7bd5218ca15 changed
972 DIFF_DIVERGED e7bd5218ca15 changed
973 DIVERGED fa942426a6fd diverged
973 DIVERGED fa942426a6fd diverged
974
974
975 $ cd ..
975 $ cd ..
976
976
977 Pushing a bookmark should only push the changes required by that
977 Pushing a bookmark should only push the changes required by that
978 bookmark, not all outgoing changes:
978 bookmark, not all outgoing changes:
979 $ hg clone http://localhost:$HGPORT/ addmarks
979 $ hg clone http://localhost:$HGPORT/ addmarks
980 requesting all changes
980 requesting all changes
981 adding changesets
981 adding changesets
982 adding manifests
982 adding manifests
983 adding file changes
983 adding file changes
984 added 5 changesets with 5 changes to 3 files (+2 heads)
984 added 5 changesets with 5 changes to 3 files (+2 heads)
985 2 new obsolescence markers
985 2 new obsolescence markers
986 new changesets 4e3505fd9583:c922c0139ca0 (5 drafts)
986 new changesets 4e3505fd9583:c922c0139ca0 (5 drafts)
987 updating to bookmark @
987 updating to bookmark @
988 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
988 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
989 $ cd addmarks
989 $ cd addmarks
990 $ echo foo > foo
990 $ echo foo > foo
991 $ hg add foo
991 $ hg add foo
992 $ hg commit -m 'add foo'
992 $ hg commit -m 'add foo'
993 $ echo bar > bar
993 $ echo bar > bar
994 $ hg add bar
994 $ hg add bar
995 $ hg commit -m 'add bar'
995 $ hg commit -m 'add bar'
996 $ hg co "tip^"
996 $ hg co "tip^"
997 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
997 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
998 (leaving bookmark @)
998 (leaving bookmark @)
999 $ hg book add-foo
999 $ hg book add-foo
1000 $ hg book -r tip add-bar
1000 $ hg book -r tip add-bar
1001 Note: this push *must* push only a single changeset, as that's the point
1001 Note: this push *must* push only a single changeset, as that's the point
1002 of this test.
1002 of this test.
1003 $ hg push -B add-foo --traceback
1003 $ hg push -B add-foo --traceback
1004 pushing to http://localhost:$HGPORT/
1004 pushing to http://localhost:$HGPORT/
1005 searching for changes
1005 searching for changes
1006 remote: adding changesets
1006 remote: adding changesets
1007 remote: adding manifests
1007 remote: adding manifests
1008 remote: adding file changes
1008 remote: adding file changes
1009 remote: added 1 changesets with 1 changes to 1 files
1009 remote: added 1 changesets with 1 changes to 1 files
1010 exporting bookmark add-foo
1010 exporting bookmark add-foo
1011
1011
1012 pushing a new bookmark on a new head does not require -f if -B is specified
1012 pushing a new bookmark on a new head does not require -f if -B is specified
1013
1013
1014 $ hg up -q X
1014 $ hg up -q X
1015 $ hg book W
1015 $ hg book W
1016 $ echo c5 > f2
1016 $ echo c5 > f2
1017 $ hg ci -Am5
1017 $ hg ci -Am5
1018 created new head
1018 created new head
1019 $ hg push -B .
1019 $ hg push -B .
1020 pushing to http://localhost:$HGPORT/
1020 pushing to http://localhost:$HGPORT/
1021 searching for changes
1021 searching for changes
1022 remote: adding changesets
1022 remote: adding changesets
1023 remote: adding manifests
1023 remote: adding manifests
1024 remote: adding file changes
1024 remote: adding file changes
1025 remote: added 1 changesets with 1 changes to 1 files (+1 heads)
1025 remote: added 1 changesets with 1 changes to 1 files (+1 heads)
1026 exporting bookmark W
1026 exporting bookmark W
1027 $ hg -R ../b id -r W
1027 $ hg -R ../b id -r W
1028 cc978a373a53 tip W
1028 cc978a373a53 tip W
1029
1029
1030 pushing an existing but divergent bookmark with -B still requires -f
1030 pushing an existing but divergent bookmark with -B still requires -f
1031
1031
1032 $ hg clone -q . ../r
1032 $ hg clone -q . ../r
1033 $ hg up -q X
1033 $ hg up -q X
1034 $ echo 1 > f2
1034 $ echo 1 > f2
1035 $ hg ci -qAml
1035 $ hg ci -qAml
1036
1036
1037 $ cd ../r
1037 $ cd ../r
1038 $ hg up -q X
1038 $ hg up -q X
1039 $ echo 2 > f2
1039 $ echo 2 > f2
1040 $ hg ci -qAmr
1040 $ hg ci -qAmr
1041 $ hg push -B X
1041 $ hg push -B X
1042 pushing to $TESTTMP/addmarks
1042 pushing to $TESTTMP/addmarks
1043 searching for changes
1043 searching for changes
1044 remote has heads on branch 'default' that are not known locally: a2a606d9ff1b
1044 remote has heads on branch 'default' that are not known locally: a2a606d9ff1b
1045 abort: push creates new remote head 54694f811df9 with bookmark 'X'!
1045 abort: push creates new remote head 54694f811df9 with bookmark 'X'!
1046 (pull and merge or see 'hg help push' for details about pushing new heads)
1046 (pull and merge or see 'hg help push' for details about pushing new heads)
1047 [255]
1047 [255]
1048 $ cd ../addmarks
1048 $ cd ../addmarks
1049
1049
1050 Check summary output for incoming/outgoing bookmarks
1050 Check summary output for incoming/outgoing bookmarks
1051
1051
1052 $ hg bookmarks -d X
1052 $ hg bookmarks -d X
1053 $ hg bookmarks -d Y
1053 $ hg bookmarks -d Y
1054 $ hg summary --remote | grep '^remote:'
1054 $ hg summary --remote | grep '^remote:'
1055 remote: *, 2 incoming bookmarks, 1 outgoing bookmarks (glob)
1055 remote: *, 2 incoming bookmarks, 1 outgoing bookmarks (glob)
1056
1056
1057 $ cd ..
1057 $ cd ..
1058
1058
1059 pushing an unchanged bookmark should result in no changes
1059 pushing an unchanged bookmark should result in no changes
1060
1060
1061 $ hg init unchanged-a
1061 $ hg init unchanged-a
1062 $ hg init unchanged-b
1062 $ hg init unchanged-b
1063 $ cd unchanged-a
1063 $ cd unchanged-a
1064 $ echo initial > foo
1064 $ echo initial > foo
1065 $ hg commit -A -m initial
1065 $ hg commit -A -m initial
1066 adding foo
1066 adding foo
1067 $ hg bookmark @
1067 $ hg bookmark @
1068 $ hg push -B @ ../unchanged-b
1068 $ hg push -B @ ../unchanged-b
1069 pushing to ../unchanged-b
1069 pushing to ../unchanged-b
1070 searching for changes
1070 searching for changes
1071 adding changesets
1071 adding changesets
1072 adding manifests
1072 adding manifests
1073 adding file changes
1073 adding file changes
1074 added 1 changesets with 1 changes to 1 files
1074 added 1 changesets with 1 changes to 1 files
1075 exporting bookmark @
1075 exporting bookmark @
1076
1076
1077 $ hg push -B @ ../unchanged-b
1077 $ hg push -B @ ../unchanged-b
1078 pushing to ../unchanged-b
1078 pushing to ../unchanged-b
1079 searching for changes
1079 searching for changes
1080 no changes found
1080 no changes found
1081 [1]
1081 [1]
1082
1082
1083 Pushing a really long bookmark should work fine (issue5165)
1083 Pushing a really long bookmark should work fine (issue5165)
1084 ===============================================
1084 ===============================================
1085
1085
1086 #if b2-binary
1086 #if b2-binary
1087 >>> with open('longname', 'w') as f:
1087 >>> with open('longname', 'w') as f:
1088 ... f.write('wat' * 100) and None
1088 ... f.write('wat' * 100) and None
1089 $ hg book `cat longname`
1089 $ hg book `cat longname`
1090 $ hg push -B `cat longname` ../unchanged-b
1090 $ hg push -B `cat longname` ../unchanged-b
1091 pushing to ../unchanged-b
1091 pushing to ../unchanged-b
1092 searching for changes
1092 searching for changes
1093 no changes found
1093 no changes found
1094 exporting bookmark (wat){100} (re)
1094 exporting bookmark (wat){100} (re)
1095 [1]
1095 [1]
1096 $ hg -R ../unchanged-b book --delete `cat longname`
1096 $ hg -R ../unchanged-b book --delete `cat longname`
1097
1097
1098 Test again but forcing bundle2 exchange to make sure that doesn't regress.
1098 Test again but forcing bundle2 exchange to make sure that doesn't regress.
1099
1099
1100 $ hg push -B `cat longname` ../unchanged-b --config devel.legacy.exchange=bundle1
1100 $ hg push -B `cat longname` ../unchanged-b --config devel.legacy.exchange=bundle1
1101 pushing to ../unchanged-b
1101 pushing to ../unchanged-b
1102 searching for changes
1102 searching for changes
1103 no changes found
1103 no changes found
1104 exporting bookmark (wat){100} (re)
1104 exporting bookmark (wat){100} (re)
1105 [1]
1105 [1]
1106 $ hg -R ../unchanged-b book --delete `cat longname`
1106 $ hg -R ../unchanged-b book --delete `cat longname`
1107 $ hg book --delete `cat longname`
1107 $ hg book --delete `cat longname`
1108 $ hg co @
1108 $ hg co @
1109 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1109 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1110 (activating bookmark @)
1110 (activating bookmark @)
1111 #endif
1111 #endif
1112
1112
1113 Check hook preventing push (issue4455)
1113 Check hook preventing push (issue4455)
1114 ======================================
1114 ======================================
1115
1115
1116 $ hg bookmarks
1116 $ hg bookmarks
1117 * @ 0:55482a6fb4b1
1117 * @ 0:55482a6fb4b1
1118 $ hg log -G
1118 $ hg log -G
1119 @ 0:55482a6fb4b1 initial
1119 @ 0:55482a6fb4b1 initial
1120
1120
1121 $ hg init ../issue4455-dest
1121 $ hg init ../issue4455-dest
1122 $ hg push ../issue4455-dest # changesets only
1122 $ hg push ../issue4455-dest # changesets only
1123 pushing to ../issue4455-dest
1123 pushing to ../issue4455-dest
1124 searching for changes
1124 searching for changes
1125 adding changesets
1125 adding changesets
1126 adding manifests
1126 adding manifests
1127 adding file changes
1127 adding file changes
1128 added 1 changesets with 1 changes to 1 files
1128 added 1 changesets with 1 changes to 1 files
1129 $ cat >> .hg/hgrc << EOF
1129 $ cat >> .hg/hgrc << EOF
1130 > [paths]
1130 > [paths]
1131 > local=../issue4455-dest/
1131 > local=../issue4455-dest/
1132 > ssh=ssh://user@dummy/issue4455-dest
1132 > ssh=ssh://user@dummy/issue4455-dest
1133 > http=http://localhost:$HGPORT/
1133 > http=http://localhost:$HGPORT/
1134 > [ui]
1134 > [ui]
1135 > ssh="$PYTHON" "$TESTDIR/dummyssh"
1135 > ssh="$PYTHON" "$TESTDIR/dummyssh"
1136 > EOF
1136 > EOF
1137 $ cat >> ../issue4455-dest/.hg/hgrc << EOF
1137 $ cat >> ../issue4455-dest/.hg/hgrc << EOF
1138 > [hooks]
1138 > [hooks]
1139 > prepushkey=false
1139 > prepushkey=false
1140 > [web]
1140 > [web]
1141 > push_ssl = false
1141 > push_ssl = false
1142 > allow_push = *
1142 > allow_push = *
1143 > EOF
1143 > EOF
1144 $ killdaemons.py
1144 $ killdaemons.py
1145 $ hg serve -R ../issue4455-dest -p $HGPORT -d --pid-file=../issue4455.pid -E ../issue4455-error.log
1145 $ hg serve -R ../issue4455-dest -p $HGPORT -d --pid-file=../issue4455.pid -E ../issue4455-error.log
1146 $ cat ../issue4455.pid >> $DAEMON_PIDS
1146 $ cat ../issue4455.pid >> $DAEMON_PIDS
1147
1147
1148 Local push
1148 Local push
1149 ----------
1149 ----------
1150
1150
1151 #if b2-pushkey
1151 #if b2-pushkey
1152
1152
1153 $ hg push -B @ local
1153 $ hg push -B @ local
1154 pushing to $TESTTMP/issue4455-dest
1154 pushing to $TESTTMP/issue4455-dest
1155 searching for changes
1155 searching for changes
1156 no changes found
1156 no changes found
1157 pushkey-abort: prepushkey hook exited with status 1
1157 pushkey-abort: prepushkey hook exited with status 1
1158 abort: exporting bookmark @ failed!
1158 abort: exporting bookmark @ failed!
1159 [255]
1159 [255]
1160
1160
1161 #endif
1161 #endif
1162 #if b2-binary
1162 #if b2-binary
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 abort: prepushkey hook exited with status 1
1168 abort: prepushkey hook exited with status 1
1169 [255]
1169 [255]
1170
1170
1171 #endif
1171 #endif
1172
1172
1173 $ hg -R ../issue4455-dest/ bookmarks
1173 $ hg -R ../issue4455-dest/ bookmarks
1174 no bookmarks set
1174 no bookmarks set
1175
1175
1176 Using ssh
1176 Using ssh
1177 ---------
1177 ---------
1178
1178
1179 #if b2-pushkey
1179 #if b2-pushkey
1180
1180
1181 $ hg push -B @ ssh # bundle2+
1181 $ hg push -B @ ssh # bundle2+
1182 pushing to ssh://user@dummy/issue4455-dest
1182 pushing to ssh://user@dummy/issue4455-dest
1183 searching for changes
1183 searching for changes
1184 no changes found
1184 no changes found
1185 remote: pushkey-abort: prepushkey hook exited with status 1
1185 remote: pushkey-abort: prepushkey hook exited with status 1
1186 abort: exporting bookmark @ failed!
1186 abort: exporting bookmark @ failed!
1187 [255]
1187 [255]
1188
1188
1189 $ hg -R ../issue4455-dest/ bookmarks
1189 $ hg -R ../issue4455-dest/ bookmarks
1190 no bookmarks set
1190 no bookmarks set
1191
1191
1192 $ hg push -B @ ssh --config devel.legacy.exchange=bundle1
1192 $ hg push -B @ ssh --config devel.legacy.exchange=bundle1
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 exporting bookmark @ failed!
1197 exporting bookmark @ failed!
1198 [1]
1198 [1]
1199
1199
1200 #endif
1200 #endif
1201 #if b2-binary
1201 #if b2-binary
1202
1202
1203 $ hg push -B @ ssh # bundle2+
1203 $ hg push -B @ ssh # bundle2+
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: prepushkey hook exited with status 1
1207 remote: prepushkey hook exited with status 1
1208 abort: push failed on remote
1208 abort: push failed on remote
1209 [255]
1209 [255]
1210
1210
1211 #endif
1211 #endif
1212
1212
1213 $ hg -R ../issue4455-dest/ bookmarks
1213 $ hg -R ../issue4455-dest/ bookmarks
1214 no bookmarks set
1214 no bookmarks set
1215
1215
1216 Using http
1216 Using http
1217 ----------
1217 ----------
1218
1218
1219 #if b2-pushkey
1219 #if b2-pushkey
1220 $ hg push -B @ http # bundle2+
1220 $ hg push -B @ http # bundle2+
1221 pushing to http://localhost:$HGPORT/
1221 pushing to http://localhost:$HGPORT/
1222 searching for changes
1222 searching for changes
1223 no changes found
1223 no changes found
1224 remote: pushkey-abort: prepushkey hook exited with status 1
1224 remote: pushkey-abort: prepushkey hook exited with status 1
1225 abort: exporting bookmark @ failed!
1225 abort: exporting bookmark @ failed!
1226 [255]
1226 [255]
1227
1227
1228 $ hg -R ../issue4455-dest/ bookmarks
1228 $ hg -R ../issue4455-dest/ bookmarks
1229 no bookmarks set
1229 no bookmarks set
1230
1230
1231 $ hg push -B @ http --config devel.legacy.exchange=bundle1
1231 $ hg push -B @ http --config devel.legacy.exchange=bundle1
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 exporting bookmark @ failed!
1236 exporting bookmark @ failed!
1237 [1]
1237 [1]
1238
1238
1239 #endif
1239 #endif
1240
1240
1241 #if b2-binary
1241 #if b2-binary
1242
1242
1243 $ hg push -B @ ssh # bundle2+
1243 $ hg push -B @ ssh # bundle2+
1244 pushing to ssh://user@dummy/issue4455-dest
1244 pushing to ssh://user@dummy/issue4455-dest
1245 searching for changes
1245 searching for changes
1246 no changes found
1246 no changes found
1247 remote: prepushkey hook exited with status 1
1247 remote: prepushkey hook exited with status 1
1248 abort: push failed on remote
1248 abort: push failed on remote
1249 [255]
1249 [255]
1250
1250
1251 #endif
1251 #endif
1252
1252
1253 $ hg -R ../issue4455-dest/ bookmarks
1253 $ hg -R ../issue4455-dest/ bookmarks
1254 no bookmarks set
1254 no bookmarks set
1255
1255
1256 $ cd ..
1256 $ cd ..
1257
1257
1258 Test that pre-pushkey compat for bookmark works as expected (issue5777)
1258 Test that pre-pushkey compat for bookmark works as expected (issue5777)
1259
1259
1260 $ cat << EOF >> $HGRCPATH
1260 $ cat << EOF >> $HGRCPATH
1261 > [ui]
1261 > [ui]
1262 > ssh="$PYTHON" "$TESTDIR/dummyssh"
1262 > ssh="$PYTHON" "$TESTDIR/dummyssh"
1263 > [server]
1263 > [server]
1264 > bookmarks-pushkey-compat = yes
1264 > bookmarks-pushkey-compat = yes
1265 > EOF
1265 > EOF
1266
1266
1267 $ hg init server
1267 $ hg init server
1268 $ echo foo > server/a
1268 $ echo foo > server/a
1269 $ hg -R server book foo
1269 $ hg -R server book foo
1270 $ hg -R server commit -Am a
1270 $ hg -R server commit -Am a
1271 adding a
1271 adding a
1272 $ hg clone ssh://user@dummy/server client
1272 $ hg clone ssh://user@dummy/server client
1273 requesting all changes
1273 requesting all changes
1274 adding changesets
1274 adding changesets
1275 adding manifests
1275 adding manifests
1276 adding file changes
1276 adding file changes
1277 added 1 changesets with 1 changes to 1 files
1277 added 1 changesets with 1 changes to 1 files
1278 new changesets 79513d0d7716 (1 drafts)
1278 new changesets 79513d0d7716 (1 drafts)
1279 updating to branch default
1279 updating to branch default
1280 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1280 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1281
1281
1282 Forbid bookmark move on the server
1282 Forbid bookmark move on the server
1283
1283
1284 $ cat << EOF >> $TESTTMP/no-bm-move.sh
1284 $ cat << EOF >> $TESTTMP/no-bm-move.sh
1285 > #!/bin/sh
1285 > #!/bin/sh
1286 > echo \$HG_NAMESPACE | grep -v bookmarks
1286 > echo \$HG_NAMESPACE | grep -v bookmarks
1287 > EOF
1287 > EOF
1288 $ cat << EOF >> server/.hg/hgrc
1288 $ cat << EOF >> server/.hg/hgrc
1289 > [hooks]
1289 > [hooks]
1290 > prepushkey.no-bm-move= sh $TESTTMP/no-bm-move.sh
1290 > prepushkey.no-bm-move= sh $TESTTMP/no-bm-move.sh
1291 > EOF
1291 > EOF
1292
1292
1293 pushing changeset is okay
1293 pushing changeset is okay
1294
1294
1295 $ echo bar >> client/a
1295 $ echo bar >> client/a
1296 $ hg -R client commit -m b
1296 $ hg -R client commit -m b
1297 $ hg -R client push
1297 $ hg -R client push
1298 pushing to ssh://user@dummy/server
1298 pushing to ssh://user@dummy/server
1299 searching for changes
1299 searching for changes
1300 remote: adding changesets
1300 remote: adding changesets
1301 remote: adding manifests
1301 remote: adding manifests
1302 remote: adding file changes
1302 remote: adding file changes
1303 remote: added 1 changesets with 1 changes to 1 files
1303 remote: added 1 changesets with 1 changes to 1 files
1304
1304
1305 attempt to move the bookmark is rejected
1305 attempt to move the bookmark is rejected
1306
1306
1307 $ hg -R client book foo -r .
1307 $ hg -R client book foo -r .
1308 moving bookmark 'foo' forward from 79513d0d7716
1308 moving bookmark 'foo' forward from 79513d0d7716
1309
1309
1310 #if b2-pushkey
1310 #if b2-pushkey
1311 $ hg -R client push
1311 $ hg -R client push
1312 pushing to ssh://user@dummy/server
1312 pushing to ssh://user@dummy/server
1313 searching for changes
1313 searching for changes
1314 no changes found
1314 no changes found
1315 remote: pushkey-abort: prepushkey.no-bm-move hook exited with status 1
1315 remote: pushkey-abort: prepushkey.no-bm-move hook exited with status 1
1316 abort: updating bookmark foo failed!
1316 abort: updating bookmark foo failed!
1317 [255]
1317 [255]
1318 #endif
1318 #endif
1319 #if b2-binary
1319 #if b2-binary
1320 $ hg -R client push
1320 $ hg -R client push
1321 pushing to ssh://user@dummy/server
1321 pushing to ssh://user@dummy/server
1322 searching for changes
1322 searching for changes
1323 no changes found
1323 no changes found
1324 remote: prepushkey.no-bm-move hook exited with status 1
1324 remote: prepushkey.no-bm-move hook exited with status 1
1325 abort: push failed on remote
1325 abort: push failed on remote
1326 [255]
1326 [255]
1327 #endif
1327 #endif
1328
1328
1329 -- test for pushing bookmarks pointing to secret changesets
1329 -- test for pushing bookmarks pointing to secret changesets
1330
1330
1331 Set up a "remote" repo
1331 Set up a "remote" repo
1332 $ hg init issue6159remote
1332 $ hg init issue6159remote
1333 $ cd issue6159remote
1333 $ cd issue6159remote
1334 $ echo a > a
1334 $ echo a > a
1335 $ hg add a
1335 $ hg add a
1336 $ hg commit -m_
1336 $ hg commit -m_
1337 $ hg bookmark foo
1337 $ hg bookmark foo
1338 $ cd ..
1338 $ cd ..
1339
1339
1340 Clone a local repo
1340 Clone a local repo
1341 $ hg clone -q issue6159remote issue6159local
1341 $ hg clone -q issue6159remote issue6159local
1342 $ cd issue6159local
1342 $ cd issue6159local
1343 $ hg up -qr foo
1343 $ hg up -qr foo
1344 $ echo b > b
1344 $ echo b > b
1345
1345
1346 Move the bookmark "foo" to point at a secret changeset
1346 Move the bookmark "foo" to point at a secret changeset
1347 $ hg commit -qAm_ --config phases.new-commit=secret
1347 $ hg commit -qAm_ --config phases.new-commit=secret
1348
1348
1349 Pushing the bookmark "foo" now fails as it contains a secret changeset
1349 Pushing the bookmark "foo" now fails as it contains a secret changeset
1350 $ hg push -r foo
1350 $ hg push -r foo
1351 pushing to $TESTTMP/issue6159remote
1351 pushing to $TESTTMP/issue6159remote
1352 searching for changes
1352 searching for changes
1353 no changes found (ignored 1 secret changesets)
1353 no changes found (ignored 1 secret changesets)
1354 abort: cannot push bookmark foo as it points to a secret changeset
1354 abort: cannot push bookmark foo as it points to a secret changeset
1355 [255]
1355 [255]
@@ -1,1236 +1,1236 b''
1 This test is dedicated to test the bundle2 container format
1 This test is dedicated to test the bundle2 container format
2
2
3 It test multiple existing parts to test different feature of the container. You
3 It test multiple existing parts to test different feature of the container. You
4 probably do not need to touch this test unless you change the binary encoding
4 probably do not need to touch this test unless you change the binary encoding
5 of the bundle2 format itself.
5 of the bundle2 format itself.
6
6
7 Create an extension to test bundle2 API
7 Create an extension to test bundle2 API
8
8
9 $ cat > bundle2.py << EOF
9 $ cat > bundle2.py << EOF
10 > """A small extension to test bundle2 implementation
10 > """A small extension to test bundle2 implementation
11 >
11 >
12 > This extension allows detailed testing of the various bundle2 API and
12 > This extension allows detailed testing of the various bundle2 API and
13 > behaviors.
13 > behaviors.
14 > """
14 > """
15 > import gc
15 > import gc
16 > import os
16 > import os
17 > import sys
17 > import sys
18 > from mercurial import util
18 > from mercurial import util
19 > from mercurial import bundle2
19 > from mercurial import bundle2
20 > from mercurial import scmutil
20 > from mercurial import scmutil
21 > from mercurial import discovery
21 > from mercurial import discovery
22 > from mercurial import changegroup
22 > from mercurial import changegroup
23 > from mercurial import error
23 > from mercurial import error
24 > from mercurial import obsolete
24 > from mercurial import obsolete
25 > from mercurial import pycompat
25 > from mercurial import pycompat
26 > from mercurial import registrar
26 > from mercurial import registrar
27 >
27 >
28 >
28 >
29 > try:
29 > try:
30 > import msvcrt
30 > import msvcrt
31 > msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY)
31 > msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY)
32 > msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
32 > msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
33 > msvcrt.setmode(sys.stderr.fileno(), os.O_BINARY)
33 > msvcrt.setmode(sys.stderr.fileno(), os.O_BINARY)
34 > except ImportError:
34 > except ImportError:
35 > pass
35 > pass
36 >
36 >
37 > cmdtable = {}
37 > cmdtable = {}
38 > command = registrar.command(cmdtable)
38 > command = registrar.command(cmdtable)
39 >
39 >
40 > ELEPHANTSSONG = b"""Patali Dirapata, Cromda Cromda Ripalo, Pata Pata, Ko Ko Ko
40 > ELEPHANTSSONG = b"""Patali Dirapata, Cromda Cromda Ripalo, Pata Pata, Ko Ko Ko
41 > Bokoro Dipoulito, Rondi Rondi Pepino, Pata Pata, Ko Ko Ko
41 > Bokoro Dipoulito, Rondi Rondi Pepino, Pata Pata, Ko Ko Ko
42 > Emana Karassoli, Loucra Loucra Ponponto, Pata Pata, Ko Ko Ko."""
42 > Emana Karassoli, Loucra Loucra Ponponto, Pata Pata, Ko Ko Ko."""
43 > assert len(ELEPHANTSSONG) == 178 # future test say 178 bytes, trust it.
43 > assert len(ELEPHANTSSONG) == 178 # future test say 178 bytes, trust it.
44 >
44 >
45 > @bundle2.parthandler(b'test:song')
45 > @bundle2.parthandler(b'test:song')
46 > def songhandler(op, part):
46 > def songhandler(op, part):
47 > """handle a "test:song" bundle2 part, printing the lyrics on stdin"""
47 > """handle a "test:song" bundle2 part, printing the lyrics on stdin"""
48 > op.ui.write(b'The choir starts singing:\n')
48 > op.ui.write(b'The choir starts singing:\n')
49 > verses = 0
49 > verses = 0
50 > for line in part.read().split(b'\n'):
50 > for line in part.read().split(b'\n'):
51 > op.ui.write(b' %s\n' % line)
51 > op.ui.write(b' %s\n' % line)
52 > verses += 1
52 > verses += 1
53 > op.records.add(b'song', {b'verses': verses})
53 > op.records.add(b'song', {b'verses': verses})
54 >
54 >
55 > @bundle2.parthandler(b'test:ping')
55 > @bundle2.parthandler(b'test:ping')
56 > def pinghandler(op, part):
56 > def pinghandler(op, part):
57 > op.ui.write(b'received ping request (id %i)\n' % part.id)
57 > op.ui.write(b'received ping request (id %i)\n' % part.id)
58 > if op.reply is not None and b'ping-pong' in op.reply.capabilities:
58 > if op.reply is not None and b'ping-pong' in op.reply.capabilities:
59 > op.ui.write_err(b'replying to ping request (id %i)\n' % part.id)
59 > op.ui.write_err(b'replying to ping request (id %i)\n' % part.id)
60 > op.reply.newpart(b'test:pong', [(b'in-reply-to', b'%d' % part.id)],
60 > op.reply.newpart(b'test:pong', [(b'in-reply-to', b'%d' % part.id)],
61 > mandatory=False)
61 > mandatory=False)
62 >
62 >
63 > @bundle2.parthandler(b'test:debugreply')
63 > @bundle2.parthandler(b'test:debugreply')
64 > def debugreply(op, part):
64 > def debugreply(op, part):
65 > """print data about the capacity of the bundle reply"""
65 > """print data about the capacity of the bundle reply"""
66 > if op.reply is None:
66 > if op.reply is None:
67 > op.ui.write(b'debugreply: no reply\n')
67 > op.ui.write(b'debugreply: no reply\n')
68 > else:
68 > else:
69 > op.ui.write(b'debugreply: capabilities:\n')
69 > op.ui.write(b'debugreply: capabilities:\n')
70 > for cap in sorted(op.reply.capabilities):
70 > for cap in sorted(op.reply.capabilities):
71 > op.ui.write(b"debugreply: '%s'\n" % cap)
71 > op.ui.write(b"debugreply: '%s'\n" % cap)
72 > for val in op.reply.capabilities[cap]:
72 > for val in op.reply.capabilities[cap]:
73 > op.ui.write(b"debugreply: '%s'\n" % val)
73 > op.ui.write(b"debugreply: '%s'\n" % val)
74 >
74 >
75 > @command(b'bundle2',
75 > @command(b'bundle2',
76 > [(b'', b'param', [], b'stream level parameter'),
76 > [(b'', b'param', [], b'stream level parameter'),
77 > (b'', b'unknown', False, b'include an unknown mandatory part in the bundle'),
77 > (b'', b'unknown', False, b'include an unknown mandatory part in the bundle'),
78 > (b'', b'unknownparams', False, b'include an unknown part parameters in the bundle'),
78 > (b'', b'unknownparams', False, b'include an unknown part parameters in the bundle'),
79 > (b'', b'parts', False, b'include some arbitrary parts to the bundle'),
79 > (b'', b'parts', False, b'include some arbitrary parts to the bundle'),
80 > (b'', b'reply', False, b'produce a reply bundle'),
80 > (b'', b'reply', False, b'produce a reply bundle'),
81 > (b'', b'pushrace', False, b'includes a check:head part with unknown nodes'),
81 > (b'', b'pushrace', False, b'includes a check:head part with unknown nodes'),
82 > (b'', b'genraise', False, b'includes a part that raise an exception during generation'),
82 > (b'', b'genraise', False, b'includes a part that raise an exception during generation'),
83 > (b'', b'timeout', False, b'emulate a timeout during bundle generation'),
83 > (b'', b'timeout', False, b'emulate a timeout during bundle generation'),
84 > (b'r', b'rev', [], b'includes those changeset in the bundle'),
84 > (b'r', b'rev', [], b'includes those changeset in the bundle'),
85 > (b'', b'compress', b'', b'compress the stream'),
85 > (b'', b'compress', b'', b'compress the stream'),
86 > ],
86 > ],
87 > b'[OUTPUTFILE]')
87 > b'[OUTPUTFILE]')
88 > def cmdbundle2(ui, repo, path=None, **opts):
88 > def cmdbundle2(ui, repo, path=None, **opts):
89 > """write a bundle2 container on standard output"""
89 > """write a bundle2 container on standard output"""
90 > bundler = bundle2.bundle20(ui)
90 > bundler = bundle2.bundle20(ui)
91 > for p in opts['param']:
91 > for p in opts['param']:
92 > p = p.split(b'=', 1)
92 > p = p.split(b'=', 1)
93 > try:
93 > try:
94 > bundler.addparam(*p)
94 > bundler.addparam(*p)
95 > except error.ProgrammingError as exc:
95 > except error.ProgrammingError as exc:
96 > raise error.Abort(b'%s' % exc)
96 > raise error.Abort(b'%s' % exc)
97 >
97 >
98 > if opts['compress']:
98 > if opts['compress']:
99 > bundler.setcompression(opts['compress'])
99 > bundler.setcompression(opts['compress'])
100 >
100 >
101 > if opts['reply']:
101 > if opts['reply']:
102 > capsstring = b'ping-pong\nelephants=babar,celeste\ncity%3D%21=celeste%2Cville'
102 > capsstring = b'ping-pong\nelephants=babar,celeste\ncity%3D%21=celeste%2Cville'
103 > bundler.newpart(b'replycaps', data=capsstring)
103 > bundler.newpart(b'replycaps', data=capsstring)
104 >
104 >
105 > if opts['pushrace']:
105 > if opts['pushrace']:
106 > # also serve to test the assignement of data outside of init
106 > # also serve to test the assignement of data outside of init
107 > part = bundler.newpart(b'check:heads')
107 > part = bundler.newpart(b'check:heads')
108 > part.data = b'01234567890123456789'
108 > part.data = b'01234567890123456789'
109 >
109 >
110 > revs = opts['rev']
110 > revs = opts['rev']
111 > if 'rev' in opts:
111 > if 'rev' in opts:
112 > revs = scmutil.revrange(repo, opts['rev'])
112 > revs = scmutil.revrange(repo, opts['rev'])
113 > if revs:
113 > if revs:
114 > # very crude version of a changegroup part creation
114 > # very crude version of a changegroup part creation
115 > bundled = repo.revs('%ld::%ld', revs, revs)
115 > bundled = repo.revs('%ld::%ld', revs, revs)
116 > headmissing = [c.node() for c in repo.set('heads(%ld)', revs)]
116 > headmissing = [c.node() for c in repo.set('heads(%ld)', revs)]
117 > headcommon = [c.node() for c in repo.set('parents(%ld) - %ld', revs, revs)]
117 > headcommon = [c.node() for c in repo.set('parents(%ld) - %ld', revs, revs)]
118 > outgoing = discovery.outgoing(repo, headcommon, headmissing)
118 > outgoing = discovery.outgoing(repo, headcommon, headmissing)
119 > cg = changegroup.makechangegroup(repo, outgoing, b'01',
119 > cg = changegroup.makechangegroup(repo, outgoing, b'01',
120 > b'test:bundle2')
120 > b'test:bundle2')
121 > bundler.newpart(b'changegroup', data=cg.getchunks(),
121 > bundler.newpart(b'changegroup', data=cg.getchunks(),
122 > mandatory=False)
122 > mandatory=False)
123 >
123 >
124 > if opts['parts']:
124 > if opts['parts']:
125 > bundler.newpart(b'test:empty', mandatory=False)
125 > bundler.newpart(b'test:empty', mandatory=False)
126 > # add a second one to make sure we handle multiple parts
126 > # add a second one to make sure we handle multiple parts
127 > bundler.newpart(b'test:empty', mandatory=False)
127 > bundler.newpart(b'test:empty', mandatory=False)
128 > bundler.newpart(b'test:song', data=ELEPHANTSSONG, mandatory=False)
128 > bundler.newpart(b'test:song', data=ELEPHANTSSONG, mandatory=False)
129 > bundler.newpart(b'test:debugreply', mandatory=False)
129 > bundler.newpart(b'test:debugreply', mandatory=False)
130 > mathpart = bundler.newpart(b'test:math')
130 > mathpart = bundler.newpart(b'test:math')
131 > mathpart.addparam(b'pi', b'3.14')
131 > mathpart.addparam(b'pi', b'3.14')
132 > mathpart.addparam(b'e', b'2.72')
132 > mathpart.addparam(b'e', b'2.72')
133 > mathpart.addparam(b'cooking', b'raw', mandatory=False)
133 > mathpart.addparam(b'cooking', b'raw', mandatory=False)
134 > mathpart.data = b'42'
134 > mathpart.data = b'42'
135 > mathpart.mandatory = False
135 > mathpart.mandatory = False
136 > # advisory known part with unknown mandatory param
136 > # advisory known part with unknown mandatory param
137 > bundler.newpart(b'test:song', [(b'randomparam', b'')], mandatory=False)
137 > bundler.newpart(b'test:song', [(b'randomparam', b'')], mandatory=False)
138 > if opts['unknown']:
138 > if opts['unknown']:
139 > bundler.newpart(b'test:unknown', data=b'some random content')
139 > bundler.newpart(b'test:unknown', data=b'some random content')
140 > if opts['unknownparams']:
140 > if opts['unknownparams']:
141 > bundler.newpart(b'test:song', [(b'randomparams', b'')])
141 > bundler.newpart(b'test:song', [(b'randomparams', b'')])
142 > if opts['parts']:
142 > if opts['parts']:
143 > bundler.newpart(b'test:ping', mandatory=False)
143 > bundler.newpart(b'test:ping', mandatory=False)
144 > if opts['genraise']:
144 > if opts['genraise']:
145 > def genraise():
145 > def genraise():
146 > yield b'first line\n'
146 > yield b'first line\n'
147 > raise RuntimeError('Someone set up us the bomb!')
147 > raise RuntimeError('Someone set up us the bomb!')
148 > bundler.newpart(b'output', data=genraise(), mandatory=False)
148 > bundler.newpart(b'output', data=genraise(), mandatory=False)
149 >
149 >
150 > if path is None:
150 > if path is None:
151 > file = pycompat.stdout
151 > file = pycompat.stdout
152 > else:
152 > else:
153 > file = open(path, 'wb')
153 > file = open(path, 'wb')
154 >
154 >
155 > if opts['timeout']:
155 > if opts['timeout']:
156 > bundler.newpart(b'test:song', data=ELEPHANTSSONG, mandatory=False)
156 > bundler.newpart(b'test:song', data=ELEPHANTSSONG, mandatory=False)
157 > for idx, junk in enumerate(bundler.getchunks()):
157 > for idx, junk in enumerate(bundler.getchunks()):
158 > ui.write(b'%d chunk\n' % idx)
158 > ui.write(b'%d chunk\n' % idx)
159 > if idx > 4:
159 > if idx > 4:
160 > # This throws a GeneratorExit inside the generator, which
160 > # This throws a GeneratorExit inside the generator, which
161 > # can cause problems if the exception-recovery code is
161 > # can cause problems if the exception-recovery code is
162 > # too zealous. It's important for this test that the break
162 > # too zealous. It's important for this test that the break
163 > # occur while we're in the middle of a part.
163 > # occur while we're in the middle of a part.
164 > break
164 > break
165 > gc.collect()
165 > gc.collect()
166 > ui.write(b'fake timeout complete.\n')
166 > ui.write(b'fake timeout complete.\n')
167 > return
167 > return
168 > try:
168 > try:
169 > for chunk in bundler.getchunks():
169 > for chunk in bundler.getchunks():
170 > file.write(chunk)
170 > file.write(chunk)
171 > except RuntimeError as exc:
171 > except RuntimeError as exc:
172 > raise error.Abort(exc)
172 > raise error.Abort(exc)
173 > finally:
173 > finally:
174 > file.flush()
174 > file.flush()
175 >
175 >
176 > @command(b'unbundle2', [], b'')
176 > @command(b'unbundle2', [], b'')
177 > def cmdunbundle2(ui, repo, replypath=None):
177 > def cmdunbundle2(ui, repo, replypath=None):
178 > """process a bundle2 stream from stdin on the current repo"""
178 > """process a bundle2 stream from stdin on the current repo"""
179 > try:
179 > try:
180 > tr = None
180 > tr = None
181 > lock = repo.lock()
181 > lock = repo.lock()
182 > tr = repo.transaction(b'processbundle')
182 > tr = repo.transaction(b'processbundle')
183 > try:
183 > try:
184 > unbundler = bundle2.getunbundler(ui, pycompat.stdin)
184 > unbundler = bundle2.getunbundler(ui, pycompat.stdin)
185 > op = bundle2.processbundle(repo, unbundler, lambda: tr)
185 > op = bundle2.processbundle(repo, unbundler, lambda: tr)
186 > tr.close()
186 > tr.close()
187 > except error.BundleValueError as exc:
187 > except error.BundleValueError as exc:
188 > raise error.Abort(b'missing support for %s' % exc)
188 > raise error.Abort(b'missing support for %s' % exc)
189 > except error.PushRaced as exc:
189 > except error.PushRaced as exc:
190 > raise error.Abort(b'push race: %s' % exc)
190 > raise error.Abort(b'push race: %s' % exc)
191 > finally:
191 > finally:
192 > if tr is not None:
192 > if tr is not None:
193 > tr.release()
193 > tr.release()
194 > lock.release()
194 > lock.release()
195 > remains = pycompat.stdin.read()
195 > remains = pycompat.stdin.read()
196 > ui.write(b'%i unread bytes\n' % len(remains))
196 > ui.write(b'%i unread bytes\n' % len(remains))
197 > if op.records[b'song']:
197 > if op.records[b'song']:
198 > totalverses = sum(r[b'verses'] for r in op.records[b'song'])
198 > totalverses = sum(r[b'verses'] for r in op.records[b'song'])
199 > ui.write(b'%i total verses sung\n' % totalverses)
199 > ui.write(b'%i total verses sung\n' % totalverses)
200 > for rec in op.records[b'changegroup']:
200 > for rec in op.records[b'changegroup']:
201 > ui.write(b'addchangegroup return: %i\n' % rec[b'return'])
201 > ui.write(b'addchangegroup return: %i\n' % rec[b'return'])
202 > if op.reply is not None and replypath is not None:
202 > if op.reply is not None and replypath is not None:
203 > with open(replypath, 'wb') as file:
203 > with open(replypath, 'wb') as file:
204 > for chunk in op.reply.getchunks():
204 > for chunk in op.reply.getchunks():
205 > file.write(chunk)
205 > file.write(chunk)
206 >
206 >
207 > @command(b'statbundle2', [], b'')
207 > @command(b'statbundle2', [], b'')
208 > def cmdstatbundle2(ui, repo):
208 > def cmdstatbundle2(ui, repo):
209 > """print statistic on the bundle2 container read from stdin"""
209 > """print statistic on the bundle2 container read from stdin"""
210 > unbundler = bundle2.getunbundler(ui, pycompat.stdin)
210 > unbundler = bundle2.getunbundler(ui, pycompat.stdin)
211 > try:
211 > try:
212 > params = unbundler.params
212 > params = unbundler.params
213 > except error.BundleValueError as exc:
213 > except error.BundleValueError as exc:
214 > raise error.Abort(b'unknown parameters: %s' % exc)
214 > raise error.Abort(b'unknown parameters: %s' % exc)
215 > ui.write(b'options count: %i\n' % len(params))
215 > ui.write(b'options count: %i\n' % len(params))
216 > for key in sorted(params):
216 > for key in sorted(params):
217 > ui.write(b'- %s\n' % key)
217 > ui.write(b'- %s\n' % key)
218 > value = params[key]
218 > value = params[key]
219 > if value is not None:
219 > if value is not None:
220 > ui.write(b' %s\n' % value)
220 > ui.write(b' %s\n' % value)
221 > count = 0
221 > count = 0
222 > for p in unbundler.iterparts():
222 > for p in unbundler.iterparts():
223 > count += 1
223 > count += 1
224 > ui.write(b' :%s:\n' % p.type)
224 > ui.write(b' :%s:\n' % p.type)
225 > ui.write(b' mandatory: %i\n' % len(p.mandatoryparams))
225 > ui.write(b' mandatory: %i\n' % len(p.mandatoryparams))
226 > ui.write(b' advisory: %i\n' % len(p.advisoryparams))
226 > ui.write(b' advisory: %i\n' % len(p.advisoryparams))
227 > ui.write(b' payload: %i bytes\n' % len(p.read()))
227 > ui.write(b' payload: %i bytes\n' % len(p.read()))
228 > ui.write(b'parts count: %i\n' % count)
228 > ui.write(b'parts count: %i\n' % count)
229 > EOF
229 > EOF
230 $ cat >> $HGRCPATH << EOF
230 $ cat >> $HGRCPATH << EOF
231 > [extensions]
231 > [extensions]
232 > bundle2=$TESTTMP/bundle2.py
232 > bundle2=$TESTTMP/bundle2.py
233 > [experimental]
233 > [experimental]
234 > evolution.createmarkers=True
234 > evolution.createmarkers=True
235 > [ui]
235 > [ui]
236 > ssh="$PYTHON" "$TESTDIR/dummyssh"
236 > ssh="$PYTHON" "$TESTDIR/dummyssh"
237 > logtemplate={rev}:{node|short} {phase} {author} {bookmarks} {desc|firstline}
237 > logtemplate={rev}:{node|short} {phase} {author} {bookmarks} {desc|firstline}
238 > [web]
238 > [web]
239 > push_ssl = false
239 > push_ssl = false
240 > allow_push = *
240 > allow_push = *
241 > [phases]
241 > [phases]
242 > publish=False
242 > publish=False
243 > EOF
243 > EOF
244
244
245 The extension requires a repo (currently unused)
245 The extension requires a repo (currently unused)
246
246
247 $ hg init main
247 $ hg init main
248 $ cd main
248 $ cd main
249 $ touch a
249 $ touch a
250 $ hg add a
250 $ hg add a
251 $ hg commit -m 'a'
251 $ hg commit -m 'a'
252
252
253
253
254 Empty bundle
254 Empty bundle
255 =================
255 =================
256
256
257 - no option
257 - no option
258 - no parts
258 - no parts
259
259
260 Test bundling
260 Test bundling
261
261
262 $ hg bundle2 | f --hexdump
262 $ hg bundle2 | f --hexdump
263
263
264 0000: 48 47 32 30 00 00 00 00 00 00 00 00 |HG20........|
264 0000: 48 47 32 30 00 00 00 00 00 00 00 00 |HG20........|
265
265
266 Test timeouts during bundling
266 Test timeouts during bundling
267 $ hg bundle2 --timeout --debug --config devel.bundle2.debug=yes
267 $ hg bundle2 --timeout --debug --config devel.bundle2.debug=yes
268 bundle2-output-bundle: "HG20", 1 parts total
268 bundle2-output-bundle: "HG20", 1 parts total
269 bundle2-output: start emission of HG20 stream
269 bundle2-output: start emission of HG20 stream
270 0 chunk
270 0 chunk
271 bundle2-output: bundle parameter:
271 bundle2-output: bundle parameter:
272 1 chunk
272 1 chunk
273 bundle2-output: start of parts
273 bundle2-output: start of parts
274 bundle2-output: bundle part: "test:song"
274 bundle2-output: bundle part: "test:song"
275 bundle2-output-part: "test:song" (advisory) 178 bytes payload
275 bundle2-output-part: "test:song" (advisory) 178 bytes payload
276 bundle2-output: part 0: "test:song"
276 bundle2-output: part 0: "test:song"
277 bundle2-output: header chunk size: 16
277 bundle2-output: header chunk size: 16
278 2 chunk
278 2 chunk
279 3 chunk
279 3 chunk
280 bundle2-output: payload chunk size: 178
280 bundle2-output: payload chunk size: 178
281 4 chunk
281 4 chunk
282 5 chunk
282 5 chunk
283 bundle2-generatorexit
283 bundle2-generatorexit
284 fake timeout complete.
284 fake timeout complete.
285
285
286 Test unbundling
286 Test unbundling
287
287
288 $ hg bundle2 | hg statbundle2
288 $ hg bundle2 | hg statbundle2
289 options count: 0
289 options count: 0
290 parts count: 0
290 parts count: 0
291
291
292 Test old style bundle are detected and refused
292 Test old style bundle are detected and refused
293
293
294 $ hg bundle --all --type v1 ../bundle.hg
294 $ hg bundle --all --type v1 ../bundle.hg
295 1 changesets found
295 1 changesets found
296 $ hg statbundle2 < ../bundle.hg
296 $ hg statbundle2 < ../bundle.hg
297 abort: unknown bundle version 10
297 abort: unknown bundle version 10
298 [255]
298 [255]
299
299
300 Test parameters
300 Test parameters
301 =================
301 =================
302
302
303 - some options
303 - some options
304 - no parts
304 - no parts
305
305
306 advisory parameters, no value
306 advisory parameters, no value
307 -------------------------------
307 -------------------------------
308
308
309 Simplest possible parameters form
309 Simplest possible parameters form
310
310
311 Test generation simple option
311 Test generation simple option
312
312
313 $ hg bundle2 --param 'caution' | f --hexdump
313 $ hg bundle2 --param 'caution' | f --hexdump
314
314
315 0000: 48 47 32 30 00 00 00 07 63 61 75 74 69 6f 6e 00 |HG20....caution.|
315 0000: 48 47 32 30 00 00 00 07 63 61 75 74 69 6f 6e 00 |HG20....caution.|
316 0010: 00 00 00 |...|
316 0010: 00 00 00 |...|
317
317
318 Test unbundling
318 Test unbundling
319
319
320 $ hg bundle2 --param 'caution' | hg statbundle2
320 $ hg bundle2 --param 'caution' | hg statbundle2
321 options count: 1
321 options count: 1
322 - caution
322 - caution
323 parts count: 0
323 parts count: 0
324
324
325 Test generation multiple option
325 Test generation multiple option
326
326
327 $ hg bundle2 --param 'caution' --param 'meal' | f --hexdump
327 $ hg bundle2 --param 'caution' --param 'meal' | f --hexdump
328
328
329 0000: 48 47 32 30 00 00 00 0c 63 61 75 74 69 6f 6e 20 |HG20....caution |
329 0000: 48 47 32 30 00 00 00 0c 63 61 75 74 69 6f 6e 20 |HG20....caution |
330 0010: 6d 65 61 6c 00 00 00 00 |meal....|
330 0010: 6d 65 61 6c 00 00 00 00 |meal....|
331
331
332 Test unbundling
332 Test unbundling
333
333
334 $ hg bundle2 --param 'caution' --param 'meal' | hg statbundle2
334 $ hg bundle2 --param 'caution' --param 'meal' | hg statbundle2
335 options count: 2
335 options count: 2
336 - caution
336 - caution
337 - meal
337 - meal
338 parts count: 0
338 parts count: 0
339
339
340 advisory parameters, with value
340 advisory parameters, with value
341 -------------------------------
341 -------------------------------
342
342
343 Test generation
343 Test generation
344
344
345 $ hg bundle2 --param 'caution' --param 'meal=vegan' --param 'elephants' | f --hexdump
345 $ hg bundle2 --param 'caution' --param 'meal=vegan' --param 'elephants' | f --hexdump
346
346
347 0000: 48 47 32 30 00 00 00 1c 63 61 75 74 69 6f 6e 20 |HG20....caution |
347 0000: 48 47 32 30 00 00 00 1c 63 61 75 74 69 6f 6e 20 |HG20....caution |
348 0010: 6d 65 61 6c 3d 76 65 67 61 6e 20 65 6c 65 70 68 |meal=vegan eleph|
348 0010: 6d 65 61 6c 3d 76 65 67 61 6e 20 65 6c 65 70 68 |meal=vegan eleph|
349 0020: 61 6e 74 73 00 00 00 00 |ants....|
349 0020: 61 6e 74 73 00 00 00 00 |ants....|
350
350
351 Test unbundling
351 Test unbundling
352
352
353 $ hg bundle2 --param 'caution' --param 'meal=vegan' --param 'elephants' | hg statbundle2
353 $ hg bundle2 --param 'caution' --param 'meal=vegan' --param 'elephants' | hg statbundle2
354 options count: 3
354 options count: 3
355 - caution
355 - caution
356 - elephants
356 - elephants
357 - meal
357 - meal
358 vegan
358 vegan
359 parts count: 0
359 parts count: 0
360
360
361 parameter with special char in value
361 parameter with special char in value
362 ---------------------------------------------------
362 ---------------------------------------------------
363
363
364 Test generation
364 Test generation
365
365
366 $ hg bundle2 --param 'e|! 7/=babar%#==tutu' --param simple | f --hexdump
366 $ hg bundle2 --param 'e|! 7/=babar%#==tutu' --param simple | f --hexdump
367
367
368 0000: 48 47 32 30 00 00 00 29 65 25 37 43 25 32 31 25 |HG20...)e%7C%21%|
368 0000: 48 47 32 30 00 00 00 29 65 25 37 43 25 32 31 25 |HG20...)e%7C%21%|
369 0010: 32 30 37 2f 3d 62 61 62 61 72 25 32 35 25 32 33 |207/=babar%25%23|
369 0010: 32 30 37 2f 3d 62 61 62 61 72 25 32 35 25 32 33 |207/=babar%25%23|
370 0020: 25 33 44 25 33 44 74 75 74 75 20 73 69 6d 70 6c |%3D%3Dtutu simpl|
370 0020: 25 33 44 25 33 44 74 75 74 75 20 73 69 6d 70 6c |%3D%3Dtutu simpl|
371 0030: 65 00 00 00 00 |e....|
371 0030: 65 00 00 00 00 |e....|
372
372
373 Test unbundling
373 Test unbundling
374
374
375 $ hg bundle2 --param 'e|! 7/=babar%#==tutu' --param simple | hg statbundle2
375 $ hg bundle2 --param 'e|! 7/=babar%#==tutu' --param simple | hg statbundle2
376 options count: 2
376 options count: 2
377 - e|! 7/
377 - e|! 7/
378 babar%#==tutu
378 babar%#==tutu
379 - simple
379 - simple
380 parts count: 0
380 parts count: 0
381
381
382 Test unknown mandatory option
382 Test unknown mandatory option
383 ---------------------------------------------------
383 ---------------------------------------------------
384
384
385 $ hg bundle2 --param 'Gravity' | hg statbundle2
385 $ hg bundle2 --param 'Gravity' | hg statbundle2
386 abort: unknown parameters: Stream Parameter - Gravity
386 abort: unknown parameters: Stream Parameter - Gravity
387 [255]
387 [255]
388
388
389 Test debug output
389 Test debug output
390 ---------------------------------------------------
390 ---------------------------------------------------
391
391
392 bundling debug
392 bundling debug
393
393
394 $ hg bundle2 --debug --param 'e|! 7/=babar%#==tutu' --param simple ../out.hg2 --config progress.debug=true --config devel.bundle2.debug=true
394 $ hg bundle2 --debug --param 'e|! 7/=babar%#==tutu' --param simple ../out.hg2 --config progress.debug=true --config devel.bundle2.debug=true
395 bundle2-output-bundle: "HG20", (2 params) 0 parts total
395 bundle2-output-bundle: "HG20", (2 params) 0 parts total
396 bundle2-output: start emission of HG20 stream
396 bundle2-output: start emission of HG20 stream
397 bundle2-output: bundle parameter: e%7C%21%207/=babar%25%23%3D%3Dtutu simple
397 bundle2-output: bundle parameter: e%7C%21%207/=babar%25%23%3D%3Dtutu simple
398 bundle2-output: start of parts
398 bundle2-output: start of parts
399 bundle2-output: end of bundle
399 bundle2-output: end of bundle
400
400
401 file content is ok
401 file content is ok
402
402
403 $ f --hexdump ../out.hg2
403 $ f --hexdump ../out.hg2
404 ../out.hg2:
404 ../out.hg2:
405 0000: 48 47 32 30 00 00 00 29 65 25 37 43 25 32 31 25 |HG20...)e%7C%21%|
405 0000: 48 47 32 30 00 00 00 29 65 25 37 43 25 32 31 25 |HG20...)e%7C%21%|
406 0010: 32 30 37 2f 3d 62 61 62 61 72 25 32 35 25 32 33 |207/=babar%25%23|
406 0010: 32 30 37 2f 3d 62 61 62 61 72 25 32 35 25 32 33 |207/=babar%25%23|
407 0020: 25 33 44 25 33 44 74 75 74 75 20 73 69 6d 70 6c |%3D%3Dtutu simpl|
407 0020: 25 33 44 25 33 44 74 75 74 75 20 73 69 6d 70 6c |%3D%3Dtutu simpl|
408 0030: 65 00 00 00 00 |e....|
408 0030: 65 00 00 00 00 |e....|
409
409
410 unbundling debug
410 unbundling debug
411
411
412 $ hg statbundle2 --debug --config progress.debug=true --config devel.bundle2.debug=true < ../out.hg2
412 $ hg statbundle2 --debug --config progress.debug=true --config devel.bundle2.debug=true < ../out.hg2
413 bundle2-input: start processing of HG20 stream
413 bundle2-input: start processing of HG20 stream
414 bundle2-input: reading bundle2 stream parameters
414 bundle2-input: reading bundle2 stream parameters
415 bundle2-input: ignoring unknown parameter e|! 7/
415 bundle2-input: ignoring unknown parameter e|! 7/
416 bundle2-input: ignoring unknown parameter simple
416 bundle2-input: ignoring unknown parameter simple
417 options count: 2
417 options count: 2
418 - e|! 7/
418 - e|! 7/
419 babar%#==tutu
419 babar%#==tutu
420 - simple
420 - simple
421 bundle2-input: start extraction of bundle2 parts
421 bundle2-input: start extraction of bundle2 parts
422 bundle2-input: part header size: 0
422 bundle2-input: part header size: 0
423 bundle2-input: end of bundle2 stream
423 bundle2-input: end of bundle2 stream
424 parts count: 0
424 parts count: 0
425
425
426
426
427 Test buggy input
427 Test buggy input
428 ---------------------------------------------------
428 ---------------------------------------------------
429
429
430 empty parameter name
430 empty parameter name
431
431
432 $ hg bundle2 --param '' --quiet
432 $ hg bundle2 --param '' --quiet
433 abort: empty parameter name
433 abort: empty parameter name
434 [255]
434 [255]
435
435
436 bad parameter name
436 bad parameter name
437
437
438 $ hg bundle2 --param 42babar
438 $ hg bundle2 --param 42babar
439 abort: non letter first character: 42babar
439 abort: non letter first character: 42babar
440 [255]
440 [255]
441
441
442
442
443 Test part
443 Test part
444 =================
444 =================
445
445
446 $ hg bundle2 --parts ../parts.hg2 --debug --config progress.debug=true --config devel.bundle2.debug=true
446 $ hg bundle2 --parts ../parts.hg2 --debug --config progress.debug=true --config devel.bundle2.debug=true
447 bundle2-output-bundle: "HG20", 7 parts total
447 bundle2-output-bundle: "HG20", 7 parts total
448 bundle2-output: start emission of HG20 stream
448 bundle2-output: start emission of HG20 stream
449 bundle2-output: bundle parameter:
449 bundle2-output: bundle parameter:
450 bundle2-output: start of parts
450 bundle2-output: start of parts
451 bundle2-output: bundle part: "test:empty"
451 bundle2-output: bundle part: "test:empty"
452 bundle2-output-part: "test:empty" (advisory) empty payload
452 bundle2-output-part: "test:empty" (advisory) empty payload
453 bundle2-output: part 0: "test:empty"
453 bundle2-output: part 0: "test:empty"
454 bundle2-output: header chunk size: 17
454 bundle2-output: header chunk size: 17
455 bundle2-output: closing payload chunk
455 bundle2-output: closing payload chunk
456 bundle2-output: bundle part: "test:empty"
456 bundle2-output: bundle part: "test:empty"
457 bundle2-output-part: "test:empty" (advisory) empty payload
457 bundle2-output-part: "test:empty" (advisory) empty payload
458 bundle2-output: part 1: "test:empty"
458 bundle2-output: part 1: "test:empty"
459 bundle2-output: header chunk size: 17
459 bundle2-output: header chunk size: 17
460 bundle2-output: closing payload chunk
460 bundle2-output: closing payload chunk
461 bundle2-output: bundle part: "test:song"
461 bundle2-output: bundle part: "test:song"
462 bundle2-output-part: "test:song" (advisory) 178 bytes payload
462 bundle2-output-part: "test:song" (advisory) 178 bytes payload
463 bundle2-output: part 2: "test:song"
463 bundle2-output: part 2: "test:song"
464 bundle2-output: header chunk size: 16
464 bundle2-output: header chunk size: 16
465 bundle2-output: payload chunk size: 178
465 bundle2-output: payload chunk size: 178
466 bundle2-output: closing payload chunk
466 bundle2-output: closing payload chunk
467 bundle2-output: bundle part: "test:debugreply"
467 bundle2-output: bundle part: "test:debugreply"
468 bundle2-output-part: "test:debugreply" (advisory) empty payload
468 bundle2-output-part: "test:debugreply" (advisory) empty payload
469 bundle2-output: part 3: "test:debugreply"
469 bundle2-output: part 3: "test:debugreply"
470 bundle2-output: header chunk size: 22
470 bundle2-output: header chunk size: 22
471 bundle2-output: closing payload chunk
471 bundle2-output: closing payload chunk
472 bundle2-output: bundle part: "test:math"
472 bundle2-output: bundle part: "test:math"
473 bundle2-output-part: "test:math" (advisory) (params: 2 mandatory 2 advisory) 2 bytes payload
473 bundle2-output-part: "test:math" (advisory) (params: 2 mandatory 2 advisory) 2 bytes payload
474 bundle2-output: part 4: "test:math"
474 bundle2-output: part 4: "test:math"
475 bundle2-output: header chunk size: 43
475 bundle2-output: header chunk size: 43
476 bundle2-output: payload chunk size: 2
476 bundle2-output: payload chunk size: 2
477 bundle2-output: closing payload chunk
477 bundle2-output: closing payload chunk
478 bundle2-output: bundle part: "test:song"
478 bundle2-output: bundle part: "test:song"
479 bundle2-output-part: "test:song" (advisory) (params: 1 mandatory) empty payload
479 bundle2-output-part: "test:song" (advisory) (params: 1 mandatory) empty payload
480 bundle2-output: part 5: "test:song"
480 bundle2-output: part 5: "test:song"
481 bundle2-output: header chunk size: 29
481 bundle2-output: header chunk size: 29
482 bundle2-output: closing payload chunk
482 bundle2-output: closing payload chunk
483 bundle2-output: bundle part: "test:ping"
483 bundle2-output: bundle part: "test:ping"
484 bundle2-output-part: "test:ping" (advisory) empty payload
484 bundle2-output-part: "test:ping" (advisory) empty payload
485 bundle2-output: part 6: "test:ping"
485 bundle2-output: part 6: "test:ping"
486 bundle2-output: header chunk size: 16
486 bundle2-output: header chunk size: 16
487 bundle2-output: closing payload chunk
487 bundle2-output: closing payload chunk
488 bundle2-output: end of bundle
488 bundle2-output: end of bundle
489
489
490 $ f --hexdump ../parts.hg2
490 $ f --hexdump ../parts.hg2
491 ../parts.hg2:
491 ../parts.hg2:
492 0000: 48 47 32 30 00 00 00 00 00 00 00 11 0a 74 65 73 |HG20.........tes|
492 0000: 48 47 32 30 00 00 00 00 00 00 00 11 0a 74 65 73 |HG20.........tes|
493 0010: 74 3a 65 6d 70 74 79 00 00 00 00 00 00 00 00 00 |t:empty.........|
493 0010: 74 3a 65 6d 70 74 79 00 00 00 00 00 00 00 00 00 |t:empty.........|
494 0020: 00 00 00 00 11 0a 74 65 73 74 3a 65 6d 70 74 79 |......test:empty|
494 0020: 00 00 00 00 11 0a 74 65 73 74 3a 65 6d 70 74 79 |......test:empty|
495 0030: 00 00 00 01 00 00 00 00 00 00 00 00 00 10 09 74 |...............t|
495 0030: 00 00 00 01 00 00 00 00 00 00 00 00 00 10 09 74 |...............t|
496 0040: 65 73 74 3a 73 6f 6e 67 00 00 00 02 00 00 00 00 |est:song........|
496 0040: 65 73 74 3a 73 6f 6e 67 00 00 00 02 00 00 00 00 |est:song........|
497 0050: 00 b2 50 61 74 61 6c 69 20 44 69 72 61 70 61 74 |..Patali Dirapat|
497 0050: 00 b2 50 61 74 61 6c 69 20 44 69 72 61 70 61 74 |..Patali Dirapat|
498 0060: 61 2c 20 43 72 6f 6d 64 61 20 43 72 6f 6d 64 61 |a, Cromda Cromda|
498 0060: 61 2c 20 43 72 6f 6d 64 61 20 43 72 6f 6d 64 61 |a, Cromda Cromda|
499 0070: 20 52 69 70 61 6c 6f 2c 20 50 61 74 61 20 50 61 | Ripalo, Pata Pa|
499 0070: 20 52 69 70 61 6c 6f 2c 20 50 61 74 61 20 50 61 | Ripalo, Pata Pa|
500 0080: 74 61 2c 20 4b 6f 20 4b 6f 20 4b 6f 0a 42 6f 6b |ta, Ko Ko Ko.Bok|
500 0080: 74 61 2c 20 4b 6f 20 4b 6f 20 4b 6f 0a 42 6f 6b |ta, Ko Ko Ko.Bok|
501 0090: 6f 72 6f 20 44 69 70 6f 75 6c 69 74 6f 2c 20 52 |oro Dipoulito, R|
501 0090: 6f 72 6f 20 44 69 70 6f 75 6c 69 74 6f 2c 20 52 |oro Dipoulito, R|
502 00a0: 6f 6e 64 69 20 52 6f 6e 64 69 20 50 65 70 69 6e |ondi Rondi Pepin|
502 00a0: 6f 6e 64 69 20 52 6f 6e 64 69 20 50 65 70 69 6e |ondi Rondi Pepin|
503 00b0: 6f 2c 20 50 61 74 61 20 50 61 74 61 2c 20 4b 6f |o, Pata Pata, Ko|
503 00b0: 6f 2c 20 50 61 74 61 20 50 61 74 61 2c 20 4b 6f |o, Pata Pata, Ko|
504 00c0: 20 4b 6f 20 4b 6f 0a 45 6d 61 6e 61 20 4b 61 72 | Ko Ko.Emana Kar|
504 00c0: 20 4b 6f 20 4b 6f 0a 45 6d 61 6e 61 20 4b 61 72 | Ko Ko.Emana Kar|
505 00d0: 61 73 73 6f 6c 69 2c 20 4c 6f 75 63 72 61 20 4c |assoli, Loucra L|
505 00d0: 61 73 73 6f 6c 69 2c 20 4c 6f 75 63 72 61 20 4c |assoli, Loucra L|
506 00e0: 6f 75 63 72 61 20 50 6f 6e 70 6f 6e 74 6f 2c 20 |oucra Ponponto, |
506 00e0: 6f 75 63 72 61 20 50 6f 6e 70 6f 6e 74 6f 2c 20 |oucra Ponponto, |
507 00f0: 50 61 74 61 20 50 61 74 61 2c 20 4b 6f 20 4b 6f |Pata Pata, Ko Ko|
507 00f0: 50 61 74 61 20 50 61 74 61 2c 20 4b 6f 20 4b 6f |Pata Pata, Ko Ko|
508 0100: 20 4b 6f 2e 00 00 00 00 00 00 00 16 0f 74 65 73 | Ko..........tes|
508 0100: 20 4b 6f 2e 00 00 00 00 00 00 00 16 0f 74 65 73 | Ko..........tes|
509 0110: 74 3a 64 65 62 75 67 72 65 70 6c 79 00 00 00 03 |t:debugreply....|
509 0110: 74 3a 64 65 62 75 67 72 65 70 6c 79 00 00 00 03 |t:debugreply....|
510 0120: 00 00 00 00 00 00 00 00 00 2b 09 74 65 73 74 3a |.........+.test:|
510 0120: 00 00 00 00 00 00 00 00 00 2b 09 74 65 73 74 3a |.........+.test:|
511 0130: 6d 61 74 68 00 00 00 04 02 01 02 04 01 04 07 03 |math............|
511 0130: 6d 61 74 68 00 00 00 04 02 01 02 04 01 04 07 03 |math............|
512 0140: 70 69 33 2e 31 34 65 32 2e 37 32 63 6f 6f 6b 69 |pi3.14e2.72cooki|
512 0140: 70 69 33 2e 31 34 65 32 2e 37 32 63 6f 6f 6b 69 |pi3.14e2.72cooki|
513 0150: 6e 67 72 61 77 00 00 00 02 34 32 00 00 00 00 00 |ngraw....42.....|
513 0150: 6e 67 72 61 77 00 00 00 02 34 32 00 00 00 00 00 |ngraw....42.....|
514 0160: 00 00 1d 09 74 65 73 74 3a 73 6f 6e 67 00 00 00 |....test:song...|
514 0160: 00 00 1d 09 74 65 73 74 3a 73 6f 6e 67 00 00 00 |....test:song...|
515 0170: 05 01 00 0b 00 72 61 6e 64 6f 6d 70 61 72 61 6d |.....randomparam|
515 0170: 05 01 00 0b 00 72 61 6e 64 6f 6d 70 61 72 61 6d |.....randomparam|
516 0180: 00 00 00 00 00 00 00 10 09 74 65 73 74 3a 70 69 |.........test:pi|
516 0180: 00 00 00 00 00 00 00 10 09 74 65 73 74 3a 70 69 |.........test:pi|
517 0190: 6e 67 00 00 00 06 00 00 00 00 00 00 00 00 00 00 |ng..............|
517 0190: 6e 67 00 00 00 06 00 00 00 00 00 00 00 00 00 00 |ng..............|
518
518
519
519
520 $ hg statbundle2 < ../parts.hg2
520 $ hg statbundle2 < ../parts.hg2
521 options count: 0
521 options count: 0
522 :test:empty:
522 :test:empty:
523 mandatory: 0
523 mandatory: 0
524 advisory: 0
524 advisory: 0
525 payload: 0 bytes
525 payload: 0 bytes
526 :test:empty:
526 :test:empty:
527 mandatory: 0
527 mandatory: 0
528 advisory: 0
528 advisory: 0
529 payload: 0 bytes
529 payload: 0 bytes
530 :test:song:
530 :test:song:
531 mandatory: 0
531 mandatory: 0
532 advisory: 0
532 advisory: 0
533 payload: 178 bytes
533 payload: 178 bytes
534 :test:debugreply:
534 :test:debugreply:
535 mandatory: 0
535 mandatory: 0
536 advisory: 0
536 advisory: 0
537 payload: 0 bytes
537 payload: 0 bytes
538 :test:math:
538 :test:math:
539 mandatory: 2
539 mandatory: 2
540 advisory: 1
540 advisory: 1
541 payload: 2 bytes
541 payload: 2 bytes
542 :test:song:
542 :test:song:
543 mandatory: 1
543 mandatory: 1
544 advisory: 0
544 advisory: 0
545 payload: 0 bytes
545 payload: 0 bytes
546 :test:ping:
546 :test:ping:
547 mandatory: 0
547 mandatory: 0
548 advisory: 0
548 advisory: 0
549 payload: 0 bytes
549 payload: 0 bytes
550 parts count: 7
550 parts count: 7
551
551
552 $ hg statbundle2 --debug --config progress.debug=true --config devel.bundle2.debug=true < ../parts.hg2
552 $ hg statbundle2 --debug --config progress.debug=true --config devel.bundle2.debug=true < ../parts.hg2
553 bundle2-input: start processing of HG20 stream
553 bundle2-input: start processing of HG20 stream
554 bundle2-input: reading bundle2 stream parameters
554 bundle2-input: reading bundle2 stream parameters
555 options count: 0
555 options count: 0
556 bundle2-input: start extraction of bundle2 parts
556 bundle2-input: start extraction of bundle2 parts
557 bundle2-input: part header size: 17
557 bundle2-input: part header size: 17
558 bundle2-input: part type: "test:empty"
558 bundle2-input: part type: "test:empty"
559 bundle2-input: part id: "0"
559 bundle2-input: part id: "0"
560 bundle2-input: part parameters: 0
560 bundle2-input: part parameters: 0
561 :test:empty:
561 :test:empty:
562 mandatory: 0
562 mandatory: 0
563 advisory: 0
563 advisory: 0
564 bundle2-input: payload chunk size: 0
564 bundle2-input: payload chunk size: 0
565 payload: 0 bytes
565 payload: 0 bytes
566 bundle2-input: part header size: 17
566 bundle2-input: part header size: 17
567 bundle2-input: part type: "test:empty"
567 bundle2-input: part type: "test:empty"
568 bundle2-input: part id: "1"
568 bundle2-input: part id: "1"
569 bundle2-input: part parameters: 0
569 bundle2-input: part parameters: 0
570 :test:empty:
570 :test:empty:
571 mandatory: 0
571 mandatory: 0
572 advisory: 0
572 advisory: 0
573 bundle2-input: payload chunk size: 0
573 bundle2-input: payload chunk size: 0
574 payload: 0 bytes
574 payload: 0 bytes
575 bundle2-input: part header size: 16
575 bundle2-input: part header size: 16
576 bundle2-input: part type: "test:song"
576 bundle2-input: part type: "test:song"
577 bundle2-input: part id: "2"
577 bundle2-input: part id: "2"
578 bundle2-input: part parameters: 0
578 bundle2-input: part parameters: 0
579 :test:song:
579 :test:song:
580 mandatory: 0
580 mandatory: 0
581 advisory: 0
581 advisory: 0
582 bundle2-input: payload chunk size: 178
582 bundle2-input: payload chunk size: 178
583 bundle2-input: payload chunk size: 0
583 bundle2-input: payload chunk size: 0
584 bundle2-input-part: total payload size 178
584 bundle2-input-part: total payload size 178
585 payload: 178 bytes
585 payload: 178 bytes
586 bundle2-input: part header size: 22
586 bundle2-input: part header size: 22
587 bundle2-input: part type: "test:debugreply"
587 bundle2-input: part type: "test:debugreply"
588 bundle2-input: part id: "3"
588 bundle2-input: part id: "3"
589 bundle2-input: part parameters: 0
589 bundle2-input: part parameters: 0
590 :test:debugreply:
590 :test:debugreply:
591 mandatory: 0
591 mandatory: 0
592 advisory: 0
592 advisory: 0
593 bundle2-input: payload chunk size: 0
593 bundle2-input: payload chunk size: 0
594 payload: 0 bytes
594 payload: 0 bytes
595 bundle2-input: part header size: 43
595 bundle2-input: part header size: 43
596 bundle2-input: part type: "test:math"
596 bundle2-input: part type: "test:math"
597 bundle2-input: part id: "4"
597 bundle2-input: part id: "4"
598 bundle2-input: part parameters: 3
598 bundle2-input: part parameters: 3
599 :test:math:
599 :test:math:
600 mandatory: 2
600 mandatory: 2
601 advisory: 1
601 advisory: 1
602 bundle2-input: payload chunk size: 2
602 bundle2-input: payload chunk size: 2
603 bundle2-input: payload chunk size: 0
603 bundle2-input: payload chunk size: 0
604 bundle2-input-part: total payload size 2
604 bundle2-input-part: total payload size 2
605 payload: 2 bytes
605 payload: 2 bytes
606 bundle2-input: part header size: 29
606 bundle2-input: part header size: 29
607 bundle2-input: part type: "test:song"
607 bundle2-input: part type: "test:song"
608 bundle2-input: part id: "5"
608 bundle2-input: part id: "5"
609 bundle2-input: part parameters: 1
609 bundle2-input: part parameters: 1
610 :test:song:
610 :test:song:
611 mandatory: 1
611 mandatory: 1
612 advisory: 0
612 advisory: 0
613 bundle2-input: payload chunk size: 0
613 bundle2-input: payload chunk size: 0
614 payload: 0 bytes
614 payload: 0 bytes
615 bundle2-input: part header size: 16
615 bundle2-input: part header size: 16
616 bundle2-input: part type: "test:ping"
616 bundle2-input: part type: "test:ping"
617 bundle2-input: part id: "6"
617 bundle2-input: part id: "6"
618 bundle2-input: part parameters: 0
618 bundle2-input: part parameters: 0
619 :test:ping:
619 :test:ping:
620 mandatory: 0
620 mandatory: 0
621 advisory: 0
621 advisory: 0
622 bundle2-input: payload chunk size: 0
622 bundle2-input: payload chunk size: 0
623 payload: 0 bytes
623 payload: 0 bytes
624 bundle2-input: part header size: 0
624 bundle2-input: part header size: 0
625 bundle2-input: end of bundle2 stream
625 bundle2-input: end of bundle2 stream
626 parts count: 7
626 parts count: 7
627
627
628 Test actual unbundling of test part
628 Test actual unbundling of test part
629 =======================================
629 =======================================
630
630
631 Process the bundle
631 Process the bundle
632
632
633 $ hg unbundle2 --debug --config progress.debug=true --config devel.bundle2.debug=true < ../parts.hg2
633 $ hg unbundle2 --debug --config progress.debug=true --config devel.bundle2.debug=true < ../parts.hg2
634 bundle2-input: start processing of HG20 stream
634 bundle2-input: start processing of HG20 stream
635 bundle2-input: reading bundle2 stream parameters
635 bundle2-input: reading bundle2 stream parameters
636 bundle2-input-bundle: with-transaction
636 bundle2-input-bundle: with-transaction
637 bundle2-input: start extraction of bundle2 parts
637 bundle2-input: start extraction of bundle2 parts
638 bundle2-input: part header size: 17
638 bundle2-input: part header size: 17
639 bundle2-input: part type: "test:empty"
639 bundle2-input: part type: "test:empty"
640 bundle2-input: part id: "0"
640 bundle2-input: part id: "0"
641 bundle2-input: part parameters: 0
641 bundle2-input: part parameters: 0
642 bundle2-input: ignoring unsupported advisory part test:empty
642 bundle2-input: ignoring unsupported advisory part test:empty
643 bundle2-input-part: "test:empty" (advisory) unsupported-type
643 bundle2-input-part: "test:empty" (advisory) unsupported-type
644 bundle2-input: payload chunk size: 0
644 bundle2-input: payload chunk size: 0
645 bundle2-input: part header size: 17
645 bundle2-input: part header size: 17
646 bundle2-input: part type: "test:empty"
646 bundle2-input: part type: "test:empty"
647 bundle2-input: part id: "1"
647 bundle2-input: part id: "1"
648 bundle2-input: part parameters: 0
648 bundle2-input: part parameters: 0
649 bundle2-input: ignoring unsupported advisory part test:empty
649 bundle2-input: ignoring unsupported advisory part test:empty
650 bundle2-input-part: "test:empty" (advisory) unsupported-type
650 bundle2-input-part: "test:empty" (advisory) unsupported-type
651 bundle2-input: payload chunk size: 0
651 bundle2-input: payload chunk size: 0
652 bundle2-input: part header size: 16
652 bundle2-input: part header size: 16
653 bundle2-input: part type: "test:song"
653 bundle2-input: part type: "test:song"
654 bundle2-input: part id: "2"
654 bundle2-input: part id: "2"
655 bundle2-input: part parameters: 0
655 bundle2-input: part parameters: 0
656 bundle2-input: found a handler for part test:song
656 bundle2-input: found a handler for part test:song
657 bundle2-input-part: "test:song" (advisory) supported
657 bundle2-input-part: "test:song" (advisory) supported
658 The choir starts singing:
658 The choir starts singing:
659 bundle2-input: payload chunk size: 178
659 bundle2-input: payload chunk size: 178
660 bundle2-input: payload chunk size: 0
660 bundle2-input: payload chunk size: 0
661 bundle2-input-part: total payload size 178
661 bundle2-input-part: total payload size 178
662 Patali Dirapata, Cromda Cromda Ripalo, Pata Pata, Ko Ko Ko
662 Patali Dirapata, Cromda Cromda Ripalo, Pata Pata, Ko Ko Ko
663 Bokoro Dipoulito, Rondi Rondi Pepino, Pata Pata, Ko Ko Ko
663 Bokoro Dipoulito, Rondi Rondi Pepino, Pata Pata, Ko Ko Ko
664 Emana Karassoli, Loucra Loucra Ponponto, Pata Pata, Ko Ko Ko.
664 Emana Karassoli, Loucra Loucra Ponponto, Pata Pata, Ko Ko Ko.
665 bundle2-input: part header size: 22
665 bundle2-input: part header size: 22
666 bundle2-input: part type: "test:debugreply"
666 bundle2-input: part type: "test:debugreply"
667 bundle2-input: part id: "3"
667 bundle2-input: part id: "3"
668 bundle2-input: part parameters: 0
668 bundle2-input: part parameters: 0
669 bundle2-input: found a handler for part test:debugreply
669 bundle2-input: found a handler for part test:debugreply
670 bundle2-input-part: "test:debugreply" (advisory) supported
670 bundle2-input-part: "test:debugreply" (advisory) supported
671 debugreply: no reply
671 debugreply: no reply
672 bundle2-input: payload chunk size: 0
672 bundle2-input: payload chunk size: 0
673 bundle2-input: part header size: 43
673 bundle2-input: part header size: 43
674 bundle2-input: part type: "test:math"
674 bundle2-input: part type: "test:math"
675 bundle2-input: part id: "4"
675 bundle2-input: part id: "4"
676 bundle2-input: part parameters: 3
676 bundle2-input: part parameters: 3
677 bundle2-input: ignoring unsupported advisory part test:math
677 bundle2-input: ignoring unsupported advisory part test:math
678 bundle2-input-part: "test:math" (advisory) (params: 2 mandatory 2 advisory) unsupported-type
678 bundle2-input-part: "test:math" (advisory) (params: 2 mandatory 2 advisory) unsupported-type
679 bundle2-input: payload chunk size: 2
679 bundle2-input: payload chunk size: 2
680 bundle2-input: payload chunk size: 0
680 bundle2-input: payload chunk size: 0
681 bundle2-input-part: total payload size 2
681 bundle2-input-part: total payload size 2
682 bundle2-input: part header size: 29
682 bundle2-input: part header size: 29
683 bundle2-input: part type: "test:song"
683 bundle2-input: part type: "test:song"
684 bundle2-input: part id: "5"
684 bundle2-input: part id: "5"
685 bundle2-input: part parameters: 1
685 bundle2-input: part parameters: 1
686 bundle2-input: found a handler for part test:song
686 bundle2-input: found a handler for part test:song
687 bundle2-input: ignoring unsupported advisory part test:song - randomparam
687 bundle2-input: ignoring unsupported advisory part test:song - randomparam
688 bundle2-input-part: "test:song" (advisory) (params: 1 mandatory) unsupported-params (randomparam)
688 bundle2-input-part: "test:song" (advisory) (params: 1 mandatory) unsupported-params (randomparam)
689 bundle2-input: payload chunk size: 0
689 bundle2-input: payload chunk size: 0
690 bundle2-input: part header size: 16
690 bundle2-input: part header size: 16
691 bundle2-input: part type: "test:ping"
691 bundle2-input: part type: "test:ping"
692 bundle2-input: part id: "6"
692 bundle2-input: part id: "6"
693 bundle2-input: part parameters: 0
693 bundle2-input: part parameters: 0
694 bundle2-input: found a handler for part test:ping
694 bundle2-input: found a handler for part test:ping
695 bundle2-input-part: "test:ping" (advisory) supported
695 bundle2-input-part: "test:ping" (advisory) supported
696 received ping request (id 6)
696 received ping request (id 6)
697 bundle2-input: payload chunk size: 0
697 bundle2-input: payload chunk size: 0
698 bundle2-input: part header size: 0
698 bundle2-input: part header size: 0
699 bundle2-input: end of bundle2 stream
699 bundle2-input: end of bundle2 stream
700 bundle2-input-bundle: 6 parts total
700 bundle2-input-bundle: 7 parts total
701 0 unread bytes
701 0 unread bytes
702 3 total verses sung
702 3 total verses sung
703
703
704 Unbundle with an unknown mandatory part
704 Unbundle with an unknown mandatory part
705 (should abort)
705 (should abort)
706
706
707 $ hg bundle2 --parts --unknown ../unknown.hg2
707 $ hg bundle2 --parts --unknown ../unknown.hg2
708
708
709 $ hg unbundle2 < ../unknown.hg2
709 $ hg unbundle2 < ../unknown.hg2
710 The choir starts singing:
710 The choir starts singing:
711 Patali Dirapata, Cromda Cromda Ripalo, Pata Pata, Ko Ko Ko
711 Patali Dirapata, Cromda Cromda Ripalo, Pata Pata, Ko Ko Ko
712 Bokoro Dipoulito, Rondi Rondi Pepino, Pata Pata, Ko Ko Ko
712 Bokoro Dipoulito, Rondi Rondi Pepino, Pata Pata, Ko Ko Ko
713 Emana Karassoli, Loucra Loucra Ponponto, Pata Pata, Ko Ko Ko.
713 Emana Karassoli, Loucra Loucra Ponponto, Pata Pata, Ko Ko Ko.
714 debugreply: no reply
714 debugreply: no reply
715 0 unread bytes
715 0 unread bytes
716 abort: missing support for test:unknown
716 abort: missing support for test:unknown
717 [255]
717 [255]
718
718
719 Unbundle with an unknown mandatory part parameters
719 Unbundle with an unknown mandatory part parameters
720 (should abort)
720 (should abort)
721
721
722 $ hg bundle2 --unknownparams ../unknown.hg2
722 $ hg bundle2 --unknownparams ../unknown.hg2
723
723
724 $ hg unbundle2 < ../unknown.hg2
724 $ hg unbundle2 < ../unknown.hg2
725 0 unread bytes
725 0 unread bytes
726 abort: missing support for test:song - randomparams
726 abort: missing support for test:song - randomparams
727 [255]
727 [255]
728
728
729 unbundle with a reply
729 unbundle with a reply
730
730
731 $ hg bundle2 --parts --reply ../parts-reply.hg2
731 $ hg bundle2 --parts --reply ../parts-reply.hg2
732 $ hg unbundle2 ../reply.hg2 < ../parts-reply.hg2
732 $ hg unbundle2 ../reply.hg2 < ../parts-reply.hg2
733 0 unread bytes
733 0 unread bytes
734 3 total verses sung
734 3 total verses sung
735
735
736 The reply is a bundle
736 The reply is a bundle
737
737
738 $ f --hexdump ../reply.hg2
738 $ f --hexdump ../reply.hg2
739 ../reply.hg2:
739 ../reply.hg2:
740 0000: 48 47 32 30 00 00 00 00 00 00 00 1b 06 6f 75 74 |HG20.........out|
740 0000: 48 47 32 30 00 00 00 00 00 00 00 1b 06 6f 75 74 |HG20.........out|
741 0010: 70 75 74 00 00 00 00 00 01 0b 01 69 6e 2d 72 65 |put........in-re|
741 0010: 70 75 74 00 00 00 00 00 01 0b 01 69 6e 2d 72 65 |put........in-re|
742 0020: 70 6c 79 2d 74 6f 33 00 00 00 d9 54 68 65 20 63 |ply-to3....The c|
742 0020: 70 6c 79 2d 74 6f 33 00 00 00 d9 54 68 65 20 63 |ply-to3....The c|
743 0030: 68 6f 69 72 20 73 74 61 72 74 73 20 73 69 6e 67 |hoir starts sing|
743 0030: 68 6f 69 72 20 73 74 61 72 74 73 20 73 69 6e 67 |hoir starts sing|
744 0040: 69 6e 67 3a 0a 20 20 20 20 50 61 74 61 6c 69 20 |ing:. Patali |
744 0040: 69 6e 67 3a 0a 20 20 20 20 50 61 74 61 6c 69 20 |ing:. Patali |
745 0050: 44 69 72 61 70 61 74 61 2c 20 43 72 6f 6d 64 61 |Dirapata, Cromda|
745 0050: 44 69 72 61 70 61 74 61 2c 20 43 72 6f 6d 64 61 |Dirapata, Cromda|
746 0060: 20 43 72 6f 6d 64 61 20 52 69 70 61 6c 6f 2c 20 | Cromda Ripalo, |
746 0060: 20 43 72 6f 6d 64 61 20 52 69 70 61 6c 6f 2c 20 | Cromda Ripalo, |
747 0070: 50 61 74 61 20 50 61 74 61 2c 20 4b 6f 20 4b 6f |Pata Pata, Ko Ko|
747 0070: 50 61 74 61 20 50 61 74 61 2c 20 4b 6f 20 4b 6f |Pata Pata, Ko Ko|
748 0080: 20 4b 6f 0a 20 20 20 20 42 6f 6b 6f 72 6f 20 44 | Ko. Bokoro D|
748 0080: 20 4b 6f 0a 20 20 20 20 42 6f 6b 6f 72 6f 20 44 | Ko. Bokoro D|
749 0090: 69 70 6f 75 6c 69 74 6f 2c 20 52 6f 6e 64 69 20 |ipoulito, Rondi |
749 0090: 69 70 6f 75 6c 69 74 6f 2c 20 52 6f 6e 64 69 20 |ipoulito, Rondi |
750 00a0: 52 6f 6e 64 69 20 50 65 70 69 6e 6f 2c 20 50 61 |Rondi Pepino, Pa|
750 00a0: 52 6f 6e 64 69 20 50 65 70 69 6e 6f 2c 20 50 61 |Rondi Pepino, Pa|
751 00b0: 74 61 20 50 61 74 61 2c 20 4b 6f 20 4b 6f 20 4b |ta Pata, Ko Ko K|
751 00b0: 74 61 20 50 61 74 61 2c 20 4b 6f 20 4b 6f 20 4b |ta Pata, Ko Ko K|
752 00c0: 6f 0a 20 20 20 20 45 6d 61 6e 61 20 4b 61 72 61 |o. Emana Kara|
752 00c0: 6f 0a 20 20 20 20 45 6d 61 6e 61 20 4b 61 72 61 |o. Emana Kara|
753 00d0: 73 73 6f 6c 69 2c 20 4c 6f 75 63 72 61 20 4c 6f |ssoli, Loucra Lo|
753 00d0: 73 73 6f 6c 69 2c 20 4c 6f 75 63 72 61 20 4c 6f |ssoli, Loucra Lo|
754 00e0: 75 63 72 61 20 50 6f 6e 70 6f 6e 74 6f 2c 20 50 |ucra Ponponto, P|
754 00e0: 75 63 72 61 20 50 6f 6e 70 6f 6e 74 6f 2c 20 50 |ucra Ponponto, P|
755 00f0: 61 74 61 20 50 61 74 61 2c 20 4b 6f 20 4b 6f 20 |ata Pata, Ko Ko |
755 00f0: 61 74 61 20 50 61 74 61 2c 20 4b 6f 20 4b 6f 20 |ata Pata, Ko Ko |
756 0100: 4b 6f 2e 0a 00 00 00 00 00 00 00 1b 06 6f 75 74 |Ko...........out|
756 0100: 4b 6f 2e 0a 00 00 00 00 00 00 00 1b 06 6f 75 74 |Ko...........out|
757 0110: 70 75 74 00 00 00 01 00 01 0b 01 69 6e 2d 72 65 |put........in-re|
757 0110: 70 75 74 00 00 00 01 00 01 0b 01 69 6e 2d 72 65 |put........in-re|
758 0120: 70 6c 79 2d 74 6f 34 00 00 00 c9 64 65 62 75 67 |ply-to4....debug|
758 0120: 70 6c 79 2d 74 6f 34 00 00 00 c9 64 65 62 75 67 |ply-to4....debug|
759 0130: 72 65 70 6c 79 3a 20 63 61 70 61 62 69 6c 69 74 |reply: capabilit|
759 0130: 72 65 70 6c 79 3a 20 63 61 70 61 62 69 6c 69 74 |reply: capabilit|
760 0140: 69 65 73 3a 0a 64 65 62 75 67 72 65 70 6c 79 3a |ies:.debugreply:|
760 0140: 69 65 73 3a 0a 64 65 62 75 67 72 65 70 6c 79 3a |ies:.debugreply:|
761 0150: 20 20 20 20 20 27 63 69 74 79 3d 21 27 0a 64 65 | 'city=!'.de|
761 0150: 20 20 20 20 20 27 63 69 74 79 3d 21 27 0a 64 65 | 'city=!'.de|
762 0160: 62 75 67 72 65 70 6c 79 3a 20 20 20 20 20 20 20 |bugreply: |
762 0160: 62 75 67 72 65 70 6c 79 3a 20 20 20 20 20 20 20 |bugreply: |
763 0170: 20 20 27 63 65 6c 65 73 74 65 2c 76 69 6c 6c 65 | 'celeste,ville|
763 0170: 20 20 27 63 65 6c 65 73 74 65 2c 76 69 6c 6c 65 | 'celeste,ville|
764 0180: 27 0a 64 65 62 75 67 72 65 70 6c 79 3a 20 20 20 |'.debugreply: |
764 0180: 27 0a 64 65 62 75 67 72 65 70 6c 79 3a 20 20 20 |'.debugreply: |
765 0190: 20 20 27 65 6c 65 70 68 61 6e 74 73 27 0a 64 65 | 'elephants'.de|
765 0190: 20 20 27 65 6c 65 70 68 61 6e 74 73 27 0a 64 65 | 'elephants'.de|
766 01a0: 62 75 67 72 65 70 6c 79 3a 20 20 20 20 20 20 20 |bugreply: |
766 01a0: 62 75 67 72 65 70 6c 79 3a 20 20 20 20 20 20 20 |bugreply: |
767 01b0: 20 20 27 62 61 62 61 72 27 0a 64 65 62 75 67 72 | 'babar'.debugr|
767 01b0: 20 20 27 62 61 62 61 72 27 0a 64 65 62 75 67 72 | 'babar'.debugr|
768 01c0: 65 70 6c 79 3a 20 20 20 20 20 20 20 20 20 27 63 |eply: 'c|
768 01c0: 65 70 6c 79 3a 20 20 20 20 20 20 20 20 20 27 63 |eply: 'c|
769 01d0: 65 6c 65 73 74 65 27 0a 64 65 62 75 67 72 65 70 |eleste'.debugrep|
769 01d0: 65 6c 65 73 74 65 27 0a 64 65 62 75 67 72 65 70 |eleste'.debugrep|
770 01e0: 6c 79 3a 20 20 20 20 20 27 70 69 6e 67 2d 70 6f |ly: 'ping-po|
770 01e0: 6c 79 3a 20 20 20 20 20 27 70 69 6e 67 2d 70 6f |ly: 'ping-po|
771 01f0: 6e 67 27 0a 00 00 00 00 00 00 00 1e 09 74 65 73 |ng'..........tes|
771 01f0: 6e 67 27 0a 00 00 00 00 00 00 00 1e 09 74 65 73 |ng'..........tes|
772 0200: 74 3a 70 6f 6e 67 00 00 00 02 01 00 0b 01 69 6e |t:pong........in|
772 0200: 74 3a 70 6f 6e 67 00 00 00 02 01 00 0b 01 69 6e |t:pong........in|
773 0210: 2d 72 65 70 6c 79 2d 74 6f 37 00 00 00 00 00 00 |-reply-to7......|
773 0210: 2d 72 65 70 6c 79 2d 74 6f 37 00 00 00 00 00 00 |-reply-to7......|
774 0220: 00 1b 06 6f 75 74 70 75 74 00 00 00 03 00 01 0b |...output.......|
774 0220: 00 1b 06 6f 75 74 70 75 74 00 00 00 03 00 01 0b |...output.......|
775 0230: 01 69 6e 2d 72 65 70 6c 79 2d 74 6f 37 00 00 00 |.in-reply-to7...|
775 0230: 01 69 6e 2d 72 65 70 6c 79 2d 74 6f 37 00 00 00 |.in-reply-to7...|
776 0240: 3d 72 65 63 65 69 76 65 64 20 70 69 6e 67 20 72 |=received ping r|
776 0240: 3d 72 65 63 65 69 76 65 64 20 70 69 6e 67 20 72 |=received ping r|
777 0250: 65 71 75 65 73 74 20 28 69 64 20 37 29 0a 72 65 |equest (id 7).re|
777 0250: 65 71 75 65 73 74 20 28 69 64 20 37 29 0a 72 65 |equest (id 7).re|
778 0260: 70 6c 79 69 6e 67 20 74 6f 20 70 69 6e 67 20 72 |plying to ping r|
778 0260: 70 6c 79 69 6e 67 20 74 6f 20 70 69 6e 67 20 72 |plying to ping r|
779 0270: 65 71 75 65 73 74 20 28 69 64 20 37 29 0a 00 00 |equest (id 7)...|
779 0270: 65 71 75 65 73 74 20 28 69 64 20 37 29 0a 00 00 |equest (id 7)...|
780 0280: 00 00 00 00 00 00 |......|
780 0280: 00 00 00 00 00 00 |......|
781
781
782 The reply is valid
782 The reply is valid
783
783
784 $ hg statbundle2 < ../reply.hg2
784 $ hg statbundle2 < ../reply.hg2
785 options count: 0
785 options count: 0
786 :output:
786 :output:
787 mandatory: 0
787 mandatory: 0
788 advisory: 1
788 advisory: 1
789 payload: 217 bytes
789 payload: 217 bytes
790 :output:
790 :output:
791 mandatory: 0
791 mandatory: 0
792 advisory: 1
792 advisory: 1
793 payload: 201 bytes
793 payload: 201 bytes
794 :test:pong:
794 :test:pong:
795 mandatory: 1
795 mandatory: 1
796 advisory: 0
796 advisory: 0
797 payload: 0 bytes
797 payload: 0 bytes
798 :output:
798 :output:
799 mandatory: 0
799 mandatory: 0
800 advisory: 1
800 advisory: 1
801 payload: 61 bytes
801 payload: 61 bytes
802 parts count: 4
802 parts count: 4
803
803
804 Unbundle the reply to get the output:
804 Unbundle the reply to get the output:
805
805
806 $ hg unbundle2 < ../reply.hg2
806 $ hg unbundle2 < ../reply.hg2
807 remote: The choir starts singing:
807 remote: The choir starts singing:
808 remote: Patali Dirapata, Cromda Cromda Ripalo, Pata Pata, Ko Ko Ko
808 remote: Patali Dirapata, Cromda Cromda Ripalo, Pata Pata, Ko Ko Ko
809 remote: Bokoro Dipoulito, Rondi Rondi Pepino, Pata Pata, Ko Ko Ko
809 remote: Bokoro Dipoulito, Rondi Rondi Pepino, Pata Pata, Ko Ko Ko
810 remote: Emana Karassoli, Loucra Loucra Ponponto, Pata Pata, Ko Ko Ko.
810 remote: Emana Karassoli, Loucra Loucra Ponponto, Pata Pata, Ko Ko Ko.
811 remote: debugreply: capabilities:
811 remote: debugreply: capabilities:
812 remote: debugreply: 'city=!'
812 remote: debugreply: 'city=!'
813 remote: debugreply: 'celeste,ville'
813 remote: debugreply: 'celeste,ville'
814 remote: debugreply: 'elephants'
814 remote: debugreply: 'elephants'
815 remote: debugreply: 'babar'
815 remote: debugreply: 'babar'
816 remote: debugreply: 'celeste'
816 remote: debugreply: 'celeste'
817 remote: debugreply: 'ping-pong'
817 remote: debugreply: 'ping-pong'
818 remote: received ping request (id 7)
818 remote: received ping request (id 7)
819 remote: replying to ping request (id 7)
819 remote: replying to ping request (id 7)
820 0 unread bytes
820 0 unread bytes
821
821
822 Test push race detection
822 Test push race detection
823
823
824 $ hg bundle2 --pushrace ../part-race.hg2
824 $ hg bundle2 --pushrace ../part-race.hg2
825
825
826 $ hg unbundle2 < ../part-race.hg2
826 $ hg unbundle2 < ../part-race.hg2
827 0 unread bytes
827 0 unread bytes
828 abort: push race: remote repository changed while pushing - please try again
828 abort: push race: remote repository changed while pushing - please try again
829 [255]
829 [255]
830
830
831 Support for changegroup
831 Support for changegroup
832 ===================================
832 ===================================
833
833
834 $ hg unbundle $TESTDIR/bundles/rebase.hg
834 $ hg unbundle $TESTDIR/bundles/rebase.hg
835 adding changesets
835 adding changesets
836 adding manifests
836 adding manifests
837 adding file changes
837 adding file changes
838 added 8 changesets with 7 changes to 7 files (+3 heads)
838 added 8 changesets with 7 changes to 7 files (+3 heads)
839 new changesets cd010b8cd998:02de42196ebe (8 drafts)
839 new changesets cd010b8cd998:02de42196ebe (8 drafts)
840 (run 'hg heads' to see heads, 'hg merge' to merge)
840 (run 'hg heads' to see heads, 'hg merge' to merge)
841
841
842 $ hg log -G
842 $ hg log -G
843 o 8:02de42196ebe draft Nicolas Dumazet <nicdumz.commits@gmail.com> H
843 o 8:02de42196ebe draft Nicolas Dumazet <nicdumz.commits@gmail.com> H
844 |
844 |
845 | o 7:eea13746799a draft Nicolas Dumazet <nicdumz.commits@gmail.com> G
845 | o 7:eea13746799a draft Nicolas Dumazet <nicdumz.commits@gmail.com> G
846 |/|
846 |/|
847 o | 6:24b6387c8c8c draft Nicolas Dumazet <nicdumz.commits@gmail.com> F
847 o | 6:24b6387c8c8c draft Nicolas Dumazet <nicdumz.commits@gmail.com> F
848 | |
848 | |
849 | o 5:9520eea781bc draft Nicolas Dumazet <nicdumz.commits@gmail.com> E
849 | o 5:9520eea781bc draft Nicolas Dumazet <nicdumz.commits@gmail.com> E
850 |/
850 |/
851 | o 4:32af7686d403 draft Nicolas Dumazet <nicdumz.commits@gmail.com> D
851 | o 4:32af7686d403 draft Nicolas Dumazet <nicdumz.commits@gmail.com> D
852 | |
852 | |
853 | o 3:5fddd98957c8 draft Nicolas Dumazet <nicdumz.commits@gmail.com> C
853 | o 3:5fddd98957c8 draft Nicolas Dumazet <nicdumz.commits@gmail.com> C
854 | |
854 | |
855 | o 2:42ccdea3bb16 draft Nicolas Dumazet <nicdumz.commits@gmail.com> B
855 | o 2:42ccdea3bb16 draft Nicolas Dumazet <nicdumz.commits@gmail.com> B
856 |/
856 |/
857 o 1:cd010b8cd998 draft Nicolas Dumazet <nicdumz.commits@gmail.com> A
857 o 1:cd010b8cd998 draft Nicolas Dumazet <nicdumz.commits@gmail.com> A
858
858
859 @ 0:3903775176ed draft test a
859 @ 0:3903775176ed draft test a
860
860
861
861
862 $ hg bundle2 --debug --config progress.debug=true --config devel.bundle2.debug=true --rev '8+7+5+4' ../rev.hg2
862 $ hg bundle2 --debug --config progress.debug=true --config devel.bundle2.debug=true --rev '8+7+5+4' ../rev.hg2
863 4 changesets found
863 4 changesets found
864 list of changesets:
864 list of changesets:
865 32af7686d403cf45b5d95f2d70cebea587ac806a
865 32af7686d403cf45b5d95f2d70cebea587ac806a
866 9520eea781bcca16c1e15acc0ba14335a0e8e5ba
866 9520eea781bcca16c1e15acc0ba14335a0e8e5ba
867 eea13746799a9e0bfd88f29d3c2e9dc9389f524f
867 eea13746799a9e0bfd88f29d3c2e9dc9389f524f
868 02de42196ebee42ef284b6780a87cdc96e8eaab6
868 02de42196ebee42ef284b6780a87cdc96e8eaab6
869 bundle2-output-bundle: "HG20", 1 parts total
869 bundle2-output-bundle: "HG20", 1 parts total
870 bundle2-output: start emission of HG20 stream
870 bundle2-output: start emission of HG20 stream
871 bundle2-output: bundle parameter:
871 bundle2-output: bundle parameter:
872 bundle2-output: start of parts
872 bundle2-output: start of parts
873 bundle2-output: bundle part: "changegroup"
873 bundle2-output: bundle part: "changegroup"
874 bundle2-output-part: "changegroup" (advisory) streamed payload
874 bundle2-output-part: "changegroup" (advisory) streamed payload
875 bundle2-output: part 0: "changegroup"
875 bundle2-output: part 0: "changegroup"
876 bundle2-output: header chunk size: 18
876 bundle2-output: header chunk size: 18
877 changesets: 1/4 chunks (25.00%)
877 changesets: 1/4 chunks (25.00%)
878 changesets: 2/4 chunks (50.00%)
878 changesets: 2/4 chunks (50.00%)
879 changesets: 3/4 chunks (75.00%)
879 changesets: 3/4 chunks (75.00%)
880 changesets: 4/4 chunks (100.00%)
880 changesets: 4/4 chunks (100.00%)
881 manifests: 1/4 chunks (25.00%)
881 manifests: 1/4 chunks (25.00%)
882 manifests: 2/4 chunks (50.00%)
882 manifests: 2/4 chunks (50.00%)
883 manifests: 3/4 chunks (75.00%)
883 manifests: 3/4 chunks (75.00%)
884 manifests: 4/4 chunks (100.00%)
884 manifests: 4/4 chunks (100.00%)
885 files: D 1/3 files (33.33%)
885 files: D 1/3 files (33.33%)
886 files: E 2/3 files (66.67%)
886 files: E 2/3 files (66.67%)
887 files: H 3/3 files (100.00%)
887 files: H 3/3 files (100.00%)
888 bundle2-output: payload chunk size: 1555
888 bundle2-output: payload chunk size: 1555
889 bundle2-output: closing payload chunk
889 bundle2-output: closing payload chunk
890 bundle2-output: end of bundle
890 bundle2-output: end of bundle
891
891
892 $ f --hexdump ../rev.hg2
892 $ f --hexdump ../rev.hg2
893 ../rev.hg2:
893 ../rev.hg2:
894 0000: 48 47 32 30 00 00 00 00 00 00 00 12 0b 63 68 61 |HG20.........cha|
894 0000: 48 47 32 30 00 00 00 00 00 00 00 12 0b 63 68 61 |HG20.........cha|
895 0010: 6e 67 65 67 72 6f 75 70 00 00 00 00 00 00 00 00 |ngegroup........|
895 0010: 6e 67 65 67 72 6f 75 70 00 00 00 00 00 00 00 00 |ngegroup........|
896 0020: 06 13 00 00 00 a4 32 af 76 86 d4 03 cf 45 b5 d9 |......2.v....E..|
896 0020: 06 13 00 00 00 a4 32 af 76 86 d4 03 cf 45 b5 d9 |......2.v....E..|
897 0030: 5f 2d 70 ce be a5 87 ac 80 6a 5f dd d9 89 57 c8 |_-p......j_...W.|
897 0030: 5f 2d 70 ce be a5 87 ac 80 6a 5f dd d9 89 57 c8 |_-p......j_...W.|
898 0040: a5 4a 4d 43 6d fe 1d a9 d8 7f 21 a1 b9 7b 00 00 |.JMCm.....!..{..|
898 0040: a5 4a 4d 43 6d fe 1d a9 d8 7f 21 a1 b9 7b 00 00 |.JMCm.....!..{..|
899 0050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
899 0050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
900 0060: 00 00 32 af 76 86 d4 03 cf 45 b5 d9 5f 2d 70 ce |..2.v....E.._-p.|
900 0060: 00 00 32 af 76 86 d4 03 cf 45 b5 d9 5f 2d 70 ce |..2.v....E.._-p.|
901 0070: be a5 87 ac 80 6a 00 00 00 00 00 00 00 29 00 00 |.....j.......)..|
901 0070: be a5 87 ac 80 6a 00 00 00 00 00 00 00 29 00 00 |.....j.......)..|
902 0080: 00 29 36 65 31 66 34 63 34 37 65 63 62 35 33 33 |.)6e1f4c47ecb533|
902 0080: 00 29 36 65 31 66 34 63 34 37 65 63 62 35 33 33 |.)6e1f4c47ecb533|
903 0090: 66 66 64 30 63 38 65 35 32 63 64 63 38 38 61 66 |ffd0c8e52cdc88af|
903 0090: 66 66 64 30 63 38 65 35 32 63 64 63 38 38 61 66 |ffd0c8e52cdc88af|
904 00a0: 62 36 63 64 33 39 65 32 30 63 0a 00 00 00 66 00 |b6cd39e20c....f.|
904 00a0: 62 36 63 64 33 39 65 32 30 63 0a 00 00 00 66 00 |b6cd39e20c....f.|
905 00b0: 00 00 68 00 00 00 02 44 0a 00 00 00 69 00 00 00 |..h....D....i...|
905 00b0: 00 00 68 00 00 00 02 44 0a 00 00 00 69 00 00 00 |..h....D....i...|
906 00c0: 6a 00 00 00 01 44 00 00 00 a4 95 20 ee a7 81 bc |j....D..... ....|
906 00c0: 6a 00 00 00 01 44 00 00 00 a4 95 20 ee a7 81 bc |j....D..... ....|
907 00d0: ca 16 c1 e1 5a cc 0b a1 43 35 a0 e8 e5 ba cd 01 |....Z...C5......|
907 00d0: ca 16 c1 e1 5a cc 0b a1 43 35 a0 e8 e5 ba cd 01 |....Z...C5......|
908 00e0: 0b 8c d9 98 f3 98 1a 5a 81 15 f9 4f 8d a4 ab 50 |.......Z...O...P|
908 00e0: 0b 8c d9 98 f3 98 1a 5a 81 15 f9 4f 8d a4 ab 50 |.......Z...O...P|
909 00f0: 60 89 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |`...............|
909 00f0: 60 89 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |`...............|
910 0100: 00 00 00 00 00 00 95 20 ee a7 81 bc ca 16 c1 e1 |....... ........|
910 0100: 00 00 00 00 00 00 95 20 ee a7 81 bc ca 16 c1 e1 |....... ........|
911 0110: 5a cc 0b a1 43 35 a0 e8 e5 ba 00 00 00 00 00 00 |Z...C5..........|
911 0110: 5a cc 0b a1 43 35 a0 e8 e5 ba 00 00 00 00 00 00 |Z...C5..........|
912 0120: 00 29 00 00 00 29 34 64 65 63 65 39 63 38 32 36 |.)...)4dece9c826|
912 0120: 00 29 00 00 00 29 34 64 65 63 65 39 63 38 32 36 |.)...)4dece9c826|
913 0130: 66 36 39 34 39 30 35 30 37 62 39 38 63 36 33 38 |f69490507b98c638|
913 0130: 66 36 39 34 39 30 35 30 37 62 39 38 63 36 33 38 |f69490507b98c638|
914 0140: 33 61 33 30 30 39 62 32 39 35 38 33 37 64 0a 00 |3a3009b295837d..|
914 0140: 33 61 33 30 30 39 62 32 39 35 38 33 37 64 0a 00 |3a3009b295837d..|
915 0150: 00 00 66 00 00 00 68 00 00 00 02 45 0a 00 00 00 |..f...h....E....|
915 0150: 00 00 66 00 00 00 68 00 00 00 02 45 0a 00 00 00 |..f...h....E....|
916 0160: 69 00 00 00 6a 00 00 00 01 45 00 00 00 a2 ee a1 |i...j....E......|
916 0160: 69 00 00 00 6a 00 00 00 01 45 00 00 00 a2 ee a1 |i...j....E......|
917 0170: 37 46 79 9a 9e 0b fd 88 f2 9d 3c 2e 9d c9 38 9f |7Fy.......<...8.|
917 0170: 37 46 79 9a 9e 0b fd 88 f2 9d 3c 2e 9d c9 38 9f |7Fy.......<...8.|
918 0180: 52 4f 24 b6 38 7c 8c 8c ae 37 17 88 80 f3 fa 95 |RO$.8|...7......|
918 0180: 52 4f 24 b6 38 7c 8c 8c ae 37 17 88 80 f3 fa 95 |RO$.8|...7......|
919 0190: de d3 cb 1c f7 85 95 20 ee a7 81 bc ca 16 c1 e1 |....... ........|
919 0190: de d3 cb 1c f7 85 95 20 ee a7 81 bc ca 16 c1 e1 |....... ........|
920 01a0: 5a cc 0b a1 43 35 a0 e8 e5 ba ee a1 37 46 79 9a |Z...C5......7Fy.|
920 01a0: 5a cc 0b a1 43 35 a0 e8 e5 ba ee a1 37 46 79 9a |Z...C5......7Fy.|
921 01b0: 9e 0b fd 88 f2 9d 3c 2e 9d c9 38 9f 52 4f 00 00 |......<...8.RO..|
921 01b0: 9e 0b fd 88 f2 9d 3c 2e 9d c9 38 9f 52 4f 00 00 |......<...8.RO..|
922 01c0: 00 00 00 00 00 29 00 00 00 29 33 36 35 62 39 33 |.....)...)365b93|
922 01c0: 00 00 00 00 00 29 00 00 00 29 33 36 35 62 39 33 |.....)...)365b93|
923 01d0: 64 35 37 66 64 66 34 38 31 34 65 32 62 35 39 31 |d57fdf4814e2b591|
923 01d0: 64 35 37 66 64 66 34 38 31 34 65 32 62 35 39 31 |d57fdf4814e2b591|
924 01e0: 31 64 36 62 61 63 66 66 32 62 31 32 30 31 34 34 |1d6bacff2b120144|
924 01e0: 31 64 36 62 61 63 66 66 32 62 31 32 30 31 34 34 |1d6bacff2b120144|
925 01f0: 34 31 0a 00 00 00 66 00 00 00 68 00 00 00 00 00 |41....f...h.....|
925 01f0: 34 31 0a 00 00 00 66 00 00 00 68 00 00 00 00 00 |41....f...h.....|
926 0200: 00 00 69 00 00 00 6a 00 00 00 01 47 00 00 00 a4 |..i...j....G....|
926 0200: 00 00 69 00 00 00 6a 00 00 00 01 47 00 00 00 a4 |..i...j....G....|
927 0210: 02 de 42 19 6e be e4 2e f2 84 b6 78 0a 87 cd c9 |..B.n......x....|
927 0210: 02 de 42 19 6e be e4 2e f2 84 b6 78 0a 87 cd c9 |..B.n......x....|
928 0220: 6e 8e aa b6 24 b6 38 7c 8c 8c ae 37 17 88 80 f3 |n...$.8|...7....|
928 0220: 6e 8e aa b6 24 b6 38 7c 8c 8c ae 37 17 88 80 f3 |n...$.8|...7....|
929 0230: fa 95 de d3 cb 1c f7 85 00 00 00 00 00 00 00 00 |................|
929 0230: fa 95 de d3 cb 1c f7 85 00 00 00 00 00 00 00 00 |................|
930 0240: 00 00 00 00 00 00 00 00 00 00 00 00 02 de 42 19 |..............B.|
930 0240: 00 00 00 00 00 00 00 00 00 00 00 00 02 de 42 19 |..............B.|
931 0250: 6e be e4 2e f2 84 b6 78 0a 87 cd c9 6e 8e aa b6 |n......x....n...|
931 0250: 6e be e4 2e f2 84 b6 78 0a 87 cd c9 6e 8e aa b6 |n......x....n...|
932 0260: 00 00 00 00 00 00 00 29 00 00 00 29 38 62 65 65 |.......)...)8bee|
932 0260: 00 00 00 00 00 00 00 29 00 00 00 29 38 62 65 65 |.......)...)8bee|
933 0270: 34 38 65 64 63 37 33 31 38 35 34 31 66 63 30 30 |48edc7318541fc00|
933 0270: 34 38 65 64 63 37 33 31 38 35 34 31 66 63 30 30 |48edc7318541fc00|
934 0280: 31 33 65 65 34 31 62 30 38 39 32 37 36 61 38 63 |13ee41b089276a8c|
934 0280: 31 33 65 65 34 31 62 30 38 39 32 37 36 61 38 63 |13ee41b089276a8c|
935 0290: 32 34 62 66 0a 00 00 00 66 00 00 00 66 00 00 00 |24bf....f...f...|
935 0290: 32 34 62 66 0a 00 00 00 66 00 00 00 66 00 00 00 |24bf....f...f...|
936 02a0: 02 48 0a 00 00 00 67 00 00 00 68 00 00 00 01 48 |.H....g...h....H|
936 02a0: 02 48 0a 00 00 00 67 00 00 00 68 00 00 00 01 48 |.H....g...h....H|
937 02b0: 00 00 00 00 00 00 00 8b 6e 1f 4c 47 ec b5 33 ff |........n.LG..3.|
937 02b0: 00 00 00 00 00 00 00 8b 6e 1f 4c 47 ec b5 33 ff |........n.LG..3.|
938 02c0: d0 c8 e5 2c dc 88 af b6 cd 39 e2 0c 66 a5 a0 18 |...,.....9..f...|
938 02c0: d0 c8 e5 2c dc 88 af b6 cd 39 e2 0c 66 a5 a0 18 |...,.....9..f...|
939 02d0: 17 fd f5 23 9c 27 38 02 b5 b7 61 8d 05 1c 89 e4 |...#.'8...a.....|
939 02d0: 17 fd f5 23 9c 27 38 02 b5 b7 61 8d 05 1c 89 e4 |...#.'8...a.....|
940 02e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
940 02e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
941 02f0: 00 00 00 00 32 af 76 86 d4 03 cf 45 b5 d9 5f 2d |....2.v....E.._-|
941 02f0: 00 00 00 00 32 af 76 86 d4 03 cf 45 b5 d9 5f 2d |....2.v....E.._-|
942 0300: 70 ce be a5 87 ac 80 6a 00 00 00 81 00 00 00 81 |p......j........|
942 0300: 70 ce be a5 87 ac 80 6a 00 00 00 81 00 00 00 81 |p......j........|
943 0310: 00 00 00 2b 44 00 63 33 66 31 63 61 32 39 32 34 |...+D.c3f1ca2924|
943 0310: 00 00 00 2b 44 00 63 33 66 31 63 61 32 39 32 34 |...+D.c3f1ca2924|
944 0320: 63 31 36 61 31 39 62 30 36 35 36 61 38 34 39 30 |c16a19b0656a8490|
944 0320: 63 31 36 61 31 39 62 30 36 35 36 61 38 34 39 30 |c16a19b0656a8490|
945 0330: 30 65 35 30 34 65 35 62 30 61 65 63 32 64 0a 00 |0e504e5b0aec2d..|
945 0330: 30 65 35 30 34 65 35 62 30 61 65 63 32 64 0a 00 |0e504e5b0aec2d..|
946 0340: 00 00 8b 4d ec e9 c8 26 f6 94 90 50 7b 98 c6 38 |...M...&...P{..8|
946 0340: 00 00 8b 4d ec e9 c8 26 f6 94 90 50 7b 98 c6 38 |...M...&...P{..8|
947 0350: 3a 30 09 b2 95 83 7d 00 7d 8c 9d 88 84 13 25 f5 |:0....}.}.....%.|
947 0350: 3a 30 09 b2 95 83 7d 00 7d 8c 9d 88 84 13 25 f5 |:0....}.}.....%.|
948 0360: c6 b0 63 71 b3 5b 4e 8a 2b 1a 83 00 00 00 00 00 |..cq.[N.+.......|
948 0360: c6 b0 63 71 b3 5b 4e 8a 2b 1a 83 00 00 00 00 00 |..cq.[N.+.......|
949 0370: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 95 |................|
949 0370: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 95 |................|
950 0380: 20 ee a7 81 bc ca 16 c1 e1 5a cc 0b a1 43 35 a0 | ........Z...C5.|
950 0380: 20 ee a7 81 bc ca 16 c1 e1 5a cc 0b a1 43 35 a0 | ........Z...C5.|
951 0390: e8 e5 ba 00 00 00 2b 00 00 00 ac 00 00 00 2b 45 |......+.......+E|
951 0390: e8 e5 ba 00 00 00 2b 00 00 00 ac 00 00 00 2b 45 |......+.......+E|
952 03a0: 00 39 63 36 66 64 30 33 35 30 61 36 63 30 64 30 |.9c6fd0350a6c0d0|
952 03a0: 00 39 63 36 66 64 30 33 35 30 61 36 63 30 64 30 |.9c6fd0350a6c0d0|
953 03b0: 63 34 39 64 34 61 39 63 35 30 31 37 63 66 30 37 |c49d4a9c5017cf07|
953 03b0: 63 34 39 64 34 61 39 63 35 30 31 37 63 66 30 37 |c49d4a9c5017cf07|
954 03c0: 30 34 33 66 35 34 65 35 38 0a 00 00 00 8b 36 5b |043f54e58.....6[|
954 03c0: 30 34 33 66 35 34 65 35 38 0a 00 00 00 8b 36 5b |043f54e58.....6[|
955 03d0: 93 d5 7f df 48 14 e2 b5 91 1d 6b ac ff 2b 12 01 |....H.....k..+..|
955 03d0: 93 d5 7f df 48 14 e2 b5 91 1d 6b ac ff 2b 12 01 |....H.....k..+..|
956 03e0: 44 41 28 a5 84 c6 5e f1 21 f8 9e b6 6a b7 d0 bc |DA(...^.!...j...|
956 03e0: 44 41 28 a5 84 c6 5e f1 21 f8 9e b6 6a b7 d0 bc |DA(...^.!...j...|
957 03f0: 15 3d 80 99 e7 ce 4d ec e9 c8 26 f6 94 90 50 7b |.=....M...&...P{|
957 03f0: 15 3d 80 99 e7 ce 4d ec e9 c8 26 f6 94 90 50 7b |.=....M...&...P{|
958 0400: 98 c6 38 3a 30 09 b2 95 83 7d ee a1 37 46 79 9a |..8:0....}..7Fy.|
958 0400: 98 c6 38 3a 30 09 b2 95 83 7d ee a1 37 46 79 9a |..8:0....}..7Fy.|
959 0410: 9e 0b fd 88 f2 9d 3c 2e 9d c9 38 9f 52 4f 00 00 |......<...8.RO..|
959 0410: 9e 0b fd 88 f2 9d 3c 2e 9d c9 38 9f 52 4f 00 00 |......<...8.RO..|
960 0420: 00 56 00 00 00 56 00 00 00 2b 46 00 32 32 62 66 |.V...V...+F.22bf|
960 0420: 00 56 00 00 00 56 00 00 00 2b 46 00 32 32 62 66 |.V...V...+F.22bf|
961 0430: 63 66 64 36 32 61 32 31 61 33 32 38 37 65 64 62 |cfd62a21a3287edb|
961 0430: 63 66 64 36 32 61 32 31 61 33 32 38 37 65 64 62 |cfd62a21a3287edb|
962 0440: 64 34 64 36 35 36 32 31 38 64 30 66 35 32 35 65 |d4d656218d0f525e|
962 0440: 64 34 64 36 35 36 32 31 38 64 30 66 35 32 35 65 |d4d656218d0f525e|
963 0450: 64 37 36 61 0a 00 00 00 97 8b ee 48 ed c7 31 85 |d76a.......H..1.|
963 0450: 64 37 36 61 0a 00 00 00 97 8b ee 48 ed c7 31 85 |d76a.......H..1.|
964 0460: 41 fc 00 13 ee 41 b0 89 27 6a 8c 24 bf 28 a5 84 |A....A..'j.$.(..|
964 0460: 41 fc 00 13 ee 41 b0 89 27 6a 8c 24 bf 28 a5 84 |A....A..'j.$.(..|
965 0470: c6 5e f1 21 f8 9e b6 6a b7 d0 bc 15 3d 80 99 e7 |.^.!...j....=...|
965 0470: c6 5e f1 21 f8 9e b6 6a b7 d0 bc 15 3d 80 99 e7 |.^.!...j....=...|
966 0480: ce 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
966 0480: ce 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
967 0490: 00 00 00 00 00 02 de 42 19 6e be e4 2e f2 84 b6 |.......B.n......|
967 0490: 00 00 00 00 00 02 de 42 19 6e be e4 2e f2 84 b6 |.......B.n......|
968 04a0: 78 0a 87 cd c9 6e 8e aa b6 00 00 00 2b 00 00 00 |x....n......+...|
968 04a0: 78 0a 87 cd c9 6e 8e aa b6 00 00 00 2b 00 00 00 |x....n......+...|
969 04b0: 56 00 00 00 00 00 00 00 81 00 00 00 81 00 00 00 |V...............|
969 04b0: 56 00 00 00 00 00 00 00 81 00 00 00 81 00 00 00 |V...............|
970 04c0: 2b 48 00 38 35 30 30 31 38 39 65 37 34 61 39 65 |+H.8500189e74a9e|
970 04c0: 2b 48 00 38 35 30 30 31 38 39 65 37 34 61 39 65 |+H.8500189e74a9e|
971 04d0: 30 34 37 35 65 38 32 32 30 39 33 62 63 37 64 62 |0475e822093bc7db|
971 04d0: 30 34 37 35 65 38 32 32 30 39 33 62 63 37 64 62 |0475e822093bc7db|
972 04e0: 30 64 36 33 31 61 65 62 30 62 34 0a 00 00 00 00 |0d631aeb0b4.....|
972 04e0: 30 64 36 33 31 61 65 62 30 62 34 0a 00 00 00 00 |0d631aeb0b4.....|
973 04f0: 00 00 00 05 44 00 00 00 62 c3 f1 ca 29 24 c1 6a |....D...b...)$.j|
973 04f0: 00 00 00 05 44 00 00 00 62 c3 f1 ca 29 24 c1 6a |....D...b...)$.j|
974 0500: 19 b0 65 6a 84 90 0e 50 4e 5b 0a ec 2d 00 00 00 |..ej...PN[..-...|
974 0500: 19 b0 65 6a 84 90 0e 50 4e 5b 0a ec 2d 00 00 00 |..ej...PN[..-...|
975 0510: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
975 0510: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
976 0520: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
976 0520: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
977 0530: 00 00 00 00 00 32 af 76 86 d4 03 cf 45 b5 d9 5f |.....2.v....E.._|
977 0530: 00 00 00 00 00 32 af 76 86 d4 03 cf 45 b5 d9 5f |.....2.v....E.._|
978 0540: 2d 70 ce be a5 87 ac 80 6a 00 00 00 00 00 00 00 |-p......j.......|
978 0540: 2d 70 ce be a5 87 ac 80 6a 00 00 00 00 00 00 00 |-p......j.......|
979 0550: 00 00 00 00 02 44 0a 00 00 00 00 00 00 00 05 45 |.....D.........E|
979 0550: 00 00 00 00 02 44 0a 00 00 00 00 00 00 00 05 45 |.....D.........E|
980 0560: 00 00 00 62 9c 6f d0 35 0a 6c 0d 0c 49 d4 a9 c5 |...b.o.5.l..I...|
980 0560: 00 00 00 62 9c 6f d0 35 0a 6c 0d 0c 49 d4 a9 c5 |...b.o.5.l..I...|
981 0570: 01 7c f0 70 43 f5 4e 58 00 00 00 00 00 00 00 00 |.|.pC.NX........|
981 0570: 01 7c f0 70 43 f5 4e 58 00 00 00 00 00 00 00 00 |.|.pC.NX........|
982 0580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
982 0580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
983 0590: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
983 0590: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
984 05a0: 95 20 ee a7 81 bc ca 16 c1 e1 5a cc 0b a1 43 35 |. ........Z...C5|
984 05a0: 95 20 ee a7 81 bc ca 16 c1 e1 5a cc 0b a1 43 35 |. ........Z...C5|
985 05b0: a0 e8 e5 ba 00 00 00 00 00 00 00 00 00 00 00 02 |................|
985 05b0: a0 e8 e5 ba 00 00 00 00 00 00 00 00 00 00 00 02 |................|
986 05c0: 45 0a 00 00 00 00 00 00 00 05 48 00 00 00 62 85 |E.........H...b.|
986 05c0: 45 0a 00 00 00 00 00 00 00 05 48 00 00 00 62 85 |E.........H...b.|
987 05d0: 00 18 9e 74 a9 e0 47 5e 82 20 93 bc 7d b0 d6 31 |...t..G^. ..}..1|
987 05d0: 00 18 9e 74 a9 e0 47 5e 82 20 93 bc 7d b0 d6 31 |...t..G^. ..}..1|
988 05e0: ae b0 b4 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
988 05e0: ae b0 b4 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
989 05f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
989 05f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
990 0600: 00 00 00 00 00 00 00 00 00 00 00 02 de 42 19 6e |.............B.n|
990 0600: 00 00 00 00 00 00 00 00 00 00 00 02 de 42 19 6e |.............B.n|
991 0610: be e4 2e f2 84 b6 78 0a 87 cd c9 6e 8e aa b6 00 |......x....n....|
991 0610: be e4 2e f2 84 b6 78 0a 87 cd c9 6e 8e aa b6 00 |......x....n....|
992 0620: 00 00 00 00 00 00 00 00 00 00 02 48 0a 00 00 00 |...........H....|
992 0620: 00 00 00 00 00 00 00 00 00 00 02 48 0a 00 00 00 |...........H....|
993 0630: 00 00 00 00 00 00 00 00 00 00 00 00 00 |.............|
993 0630: 00 00 00 00 00 00 00 00 00 00 00 00 00 |.............|
994
994
995 $ hg debugbundle ../rev.hg2
995 $ hg debugbundle ../rev.hg2
996 Stream params: {}
996 Stream params: {}
997 changegroup -- {} (mandatory: False)
997 changegroup -- {} (mandatory: False)
998 32af7686d403cf45b5d95f2d70cebea587ac806a
998 32af7686d403cf45b5d95f2d70cebea587ac806a
999 9520eea781bcca16c1e15acc0ba14335a0e8e5ba
999 9520eea781bcca16c1e15acc0ba14335a0e8e5ba
1000 eea13746799a9e0bfd88f29d3c2e9dc9389f524f
1000 eea13746799a9e0bfd88f29d3c2e9dc9389f524f
1001 02de42196ebee42ef284b6780a87cdc96e8eaab6
1001 02de42196ebee42ef284b6780a87cdc96e8eaab6
1002 $ hg unbundle ../rev.hg2
1002 $ hg unbundle ../rev.hg2
1003 adding changesets
1003 adding changesets
1004 adding manifests
1004 adding manifests
1005 adding file changes
1005 adding file changes
1006 added 0 changesets with 0 changes to 3 files
1006 added 0 changesets with 0 changes to 3 files
1007 (run 'hg update' to get a working copy)
1007 (run 'hg update' to get a working copy)
1008
1008
1009 with reply
1009 with reply
1010
1010
1011 $ hg bundle2 --rev '8+7+5+4' --reply ../rev-rr.hg2
1011 $ hg bundle2 --rev '8+7+5+4' --reply ../rev-rr.hg2
1012 $ hg unbundle2 ../rev-reply.hg2 < ../rev-rr.hg2
1012 $ hg unbundle2 ../rev-reply.hg2 < ../rev-rr.hg2
1013 added 0 changesets with 0 changes to 3 files
1013 added 0 changesets with 0 changes to 3 files
1014 0 unread bytes
1014 0 unread bytes
1015 addchangegroup return: 1
1015 addchangegroup return: 1
1016
1016
1017 $ f --hexdump ../rev-reply.hg2
1017 $ f --hexdump ../rev-reply.hg2
1018 ../rev-reply.hg2:
1018 ../rev-reply.hg2:
1019 0000: 48 47 32 30 00 00 00 00 00 00 00 2f 11 72 65 70 |HG20......./.rep|
1019 0000: 48 47 32 30 00 00 00 00 00 00 00 2f 11 72 65 70 |HG20......./.rep|
1020 0010: 6c 79 3a 63 68 61 6e 67 65 67 72 6f 75 70 00 00 |ly:changegroup..|
1020 0010: 6c 79 3a 63 68 61 6e 67 65 67 72 6f 75 70 00 00 |ly:changegroup..|
1021 0020: 00 00 00 02 0b 01 06 01 69 6e 2d 72 65 70 6c 79 |........in-reply|
1021 0020: 00 00 00 02 0b 01 06 01 69 6e 2d 72 65 70 6c 79 |........in-reply|
1022 0030: 2d 74 6f 31 72 65 74 75 72 6e 31 00 00 00 00 00 |-to1return1.....|
1022 0030: 2d 74 6f 31 72 65 74 75 72 6e 31 00 00 00 00 00 |-to1return1.....|
1023 0040: 00 00 1b 06 6f 75 74 70 75 74 00 00 00 01 00 01 |....output......|
1023 0040: 00 00 1b 06 6f 75 74 70 75 74 00 00 00 01 00 01 |....output......|
1024 0050: 0b 01 69 6e 2d 72 65 70 6c 79 2d 74 6f 31 00 00 |..in-reply-to1..|
1024 0050: 0b 01 69 6e 2d 72 65 70 6c 79 2d 74 6f 31 00 00 |..in-reply-to1..|
1025 0060: 00 37 61 64 64 69 6e 67 20 63 68 61 6e 67 65 73 |.7adding changes|
1025 0060: 00 37 61 64 64 69 6e 67 20 63 68 61 6e 67 65 73 |.7adding changes|
1026 0070: 65 74 73 0a 61 64 64 69 6e 67 20 6d 61 6e 69 66 |ets.adding manif|
1026 0070: 65 74 73 0a 61 64 64 69 6e 67 20 6d 61 6e 69 66 |ets.adding manif|
1027 0080: 65 73 74 73 0a 61 64 64 69 6e 67 20 66 69 6c 65 |ests.adding file|
1027 0080: 65 73 74 73 0a 61 64 64 69 6e 67 20 66 69 6c 65 |ests.adding file|
1028 0090: 20 63 68 61 6e 67 65 73 0a 00 00 00 00 00 00 00 | changes........|
1028 0090: 20 63 68 61 6e 67 65 73 0a 00 00 00 00 00 00 00 | changes........|
1029 00a0: 00 |.|
1029 00a0: 00 |.|
1030
1030
1031 Check handling of exception during generation.
1031 Check handling of exception during generation.
1032 ----------------------------------------------
1032 ----------------------------------------------
1033
1033
1034 $ hg bundle2 --genraise > ../genfailed.hg2
1034 $ hg bundle2 --genraise > ../genfailed.hg2
1035 abort: Someone set up us the bomb!
1035 abort: Someone set up us the bomb!
1036 [255]
1036 [255]
1037
1037
1038 Should still be a valid bundle
1038 Should still be a valid bundle
1039
1039
1040 $ f --hexdump ../genfailed.hg2
1040 $ f --hexdump ../genfailed.hg2
1041 ../genfailed.hg2:
1041 ../genfailed.hg2:
1042 0000: 48 47 32 30 00 00 00 00 00 00 00 0d 06 6f 75 74 |HG20.........out|
1042 0000: 48 47 32 30 00 00 00 00 00 00 00 0d 06 6f 75 74 |HG20.........out|
1043 0010: 70 75 74 00 00 00 00 00 00 ff ff ff ff 00 00 00 |put.............|
1043 0010: 70 75 74 00 00 00 00 00 00 ff ff ff ff 00 00 00 |put.............|
1044 0020: 48 0b 65 72 72 6f 72 3a 61 62 6f 72 74 00 00 00 |H.error:abort...|
1044 0020: 48 0b 65 72 72 6f 72 3a 61 62 6f 72 74 00 00 00 |H.error:abort...|
1045 0030: 00 01 00 07 2d 6d 65 73 73 61 67 65 75 6e 65 78 |....-messageunex|
1045 0030: 00 01 00 07 2d 6d 65 73 73 61 67 65 75 6e 65 78 |....-messageunex|
1046 0040: 70 65 63 74 65 64 20 65 72 72 6f 72 3a 20 53 6f |pected error: So|
1046 0040: 70 65 63 74 65 64 20 65 72 72 6f 72 3a 20 53 6f |pected error: So|
1047 0050: 6d 65 6f 6e 65 20 73 65 74 20 75 70 20 75 73 20 |meone set up us |
1047 0050: 6d 65 6f 6e 65 20 73 65 74 20 75 70 20 75 73 20 |meone set up us |
1048 0060: 74 68 65 20 62 6f 6d 62 21 00 00 00 00 00 00 00 |the bomb!.......|
1048 0060: 74 68 65 20 62 6f 6d 62 21 00 00 00 00 00 00 00 |the bomb!.......|
1049 0070: 00 |.|
1049 0070: 00 |.|
1050
1050
1051 And its handling on the other size raise a clean exception
1051 And its handling on the other size raise a clean exception
1052
1052
1053 $ cat ../genfailed.hg2 | hg unbundle2
1053 $ cat ../genfailed.hg2 | hg unbundle2
1054 0 unread bytes
1054 0 unread bytes
1055 abort: unexpected error: Someone set up us the bomb!
1055 abort: unexpected error: Someone set up us the bomb!
1056 [255]
1056 [255]
1057
1057
1058 Test compression
1058 Test compression
1059 ================
1059 ================
1060
1060
1061 Simple case where it just work: GZ
1061 Simple case where it just work: GZ
1062 ----------------------------------
1062 ----------------------------------
1063
1063
1064 $ hg bundle2 --compress GZ --rev '8+7+5+4' ../rev.hg2.bz
1064 $ hg bundle2 --compress GZ --rev '8+7+5+4' ../rev.hg2.bz
1065 $ f --hexdump ../rev.hg2.bz
1065 $ f --hexdump ../rev.hg2.bz
1066 ../rev.hg2.bz:
1066 ../rev.hg2.bz:
1067 0000: 48 47 32 30 00 00 00 0e 43 6f 6d 70 72 65 73 73 |HG20....Compress|
1067 0000: 48 47 32 30 00 00 00 0e 43 6f 6d 70 72 65 73 73 |HG20....Compress|
1068 0010: 69 6f 6e 3d 47 5a 78 9c 95 94 7d 68 95 55 1c c7 |ion=GZx...}h.U..|
1068 0010: 69 6f 6e 3d 47 5a 78 9c 95 94 7d 68 95 55 1c c7 |ion=GZx...}h.U..|
1069 0020: 9f 3b 31 e8 ce fa c3 65 be a0 a4 b4 52 b9 29 e7 |.;1....e....R.).|
1069 0020: 9f 3b 31 e8 ce fa c3 65 be a0 a4 b4 52 b9 29 e7 |.;1....e....R.).|
1070 0030: f5 79 ce 89 fa 63 ed 5e 77 8b 9c c3 3f 2a 1c 68 |.y...c.^w...?*.h|
1070 0030: f5 79 ce 89 fa 63 ed 5e 77 8b 9c c3 3f 2a 1c 68 |.y...c.^w...?*.h|
1071 0040: cf 79 9b dd 6a ae b0 28 74 b8 e5 96 5b bb 86 61 |.y..j..(t...[..a|
1071 0040: cf 79 9b dd 6a ae b0 28 74 b8 e5 96 5b bb 86 61 |.y..j..(t...[..a|
1072 0050: a3 15 6e 3a 71 c8 6a e8 a5 da 95 64 28 22 ce 69 |..n:q.j....d(".i|
1072 0050: a3 15 6e 3a 71 c8 6a e8 a5 da 95 64 28 22 ce 69 |..n:q.j....d(".i|
1073 0060: cd 06 59 34 28 2b 51 2a 58 c3 17 56 2a 9a 9d 67 |..Y4(+Q*X..V*..g|
1073 0060: cd 06 59 34 28 2b 51 2a 58 c3 17 56 2a 9a 9d 67 |..Y4(+Q*X..V*..g|
1074 0070: dc c6 35 9e c4 1d f8 9e 87 f3 9c f3 3b bf 0f bf |..5.........;...|
1074 0070: dc c6 35 9e c4 1d f8 9e 87 f3 9c f3 3b bf 0f bf |..5.........;...|
1075 0080: 97 e3 38 ce f4 42 b9 d6 af ae d2 55 af ae 7b ad |..8..B.....U..{.|
1075 0080: 97 e3 38 ce f4 42 b9 d6 af ae d2 55 af ae 7b ad |..8..B.....U..{.|
1076 0090: c6 c9 8d bb 8a ec b4 07 ed 7f fd ed d3 53 be 4e |.............S.N|
1076 0090: c6 c9 8d bb 8a ec b4 07 ed 7f fd ed d3 53 be 4e |.............S.N|
1077 00a0: f4 0e af 59 52 73 ea 50 d7 96 9e ba d4 9a 1f 87 |...YRs.P........|
1077 00a0: f4 0e af 59 52 73 ea 50 d7 96 9e ba d4 9a 1f 87 |...YRs.P........|
1078 00b0: 9b 9f 1d e8 7a 6a 79 e9 cb 7f cf eb fe 7e d3 82 |....zjy......~..|
1078 00b0: 9b 9f 1d e8 7a 6a 79 e9 cb 7f cf eb fe 7e d3 82 |....zjy......~..|
1079 00c0: ce 2f 36 38 21 23 cc 36 b7 b5 38 90 ab a1 21 92 |./68!#.6..8...!.|
1079 00c0: ce 2f 36 38 21 23 cc 36 b7 b5 38 90 ab a1 21 92 |./68!#.6..8...!.|
1080 00d0: 78 5a 0a 8a b1 31 0a 48 a6 29 92 4a 32 e6 1b e1 |xZ...1.H.).J2...|
1080 00d0: 78 5a 0a 8a b1 31 0a 48 a6 29 92 4a 32 e6 1b e1 |xZ...1.H.).J2...|
1081 00e0: 4a 85 b9 46 40 46 ed 61 63 b5 d6 aa 20 1e ac 5e |J..F@F.ac... ..^|
1081 00e0: 4a 85 b9 46 40 46 ed 61 63 b5 d6 aa 20 1e ac 5e |J..F@F.ac... ..^|
1082 00f0: b0 0a ae 8a c4 03 c6 d6 f9 a3 7b eb fb 4e de 7f |..........{..N..|
1082 00f0: b0 0a ae 8a c4 03 c6 d6 f9 a3 7b eb fb 4e de 7f |..........{..N..|
1083 0100: e4 97 55 5f 15 76 96 d2 5d bf 9d 3f 38 18 29 4c |..U_.v..]..?8.)L|
1083 0100: e4 97 55 5f 15 76 96 d2 5d bf 9d 3f 38 18 29 4c |..U_.v..]..?8.)L|
1084 0110: 0f b7 5d 6e 9b b3 aa 7e c6 d5 15 5b f7 7c 52 f1 |..]n...~...[.|R.|
1084 0110: 0f b7 5d 6e 9b b3 aa 7e c6 d5 15 5b f7 7c 52 f1 |..]n...~...[.|R.|
1085 0120: 7c 73 18 63 98 6d 3e 23 51 5a 6a 2e 19 72 8d cb ||s.c.m>#QZj..r..|
1085 0120: 7c 73 18 63 98 6d 3e 23 51 5a 6a 2e 19 72 8d cb ||s.c.m>#QZj..r..|
1086 0130: 09 07 14 78 82 33 e9 62 86 7d 0c 00 17 88 53 86 |...x.3.b.}....S.|
1086 0130: 09 07 14 78 82 33 e9 62 86 7d 0c 00 17 88 53 86 |...x.3.b.}....S.|
1087 0140: 3d 75 0b 63 e2 16 c6 84 9d 76 8f 76 7a cb de fc |=u.c.....v.vz...|
1087 0140: 3d 75 0b 63 e2 16 c6 84 9d 76 8f 76 7a cb de fc |=u.c.....v.vz...|
1088 0150: a8 a3 f0 46 d3 a5 f6 c7 96 b6 9f 60 3b 57 ae 28 |...F.......`;W.(|
1088 0150: a8 a3 f0 46 d3 a5 f6 c7 96 b6 9f 60 3b 57 ae 28 |...F.......`;W.(|
1089 0160: ce b2 8d e9 f4 3e 6f 66 53 dd e5 6b ad 67 be f9 |.....>ofS..k.g..|
1089 0160: ce b2 8d e9 f4 3e 6f 66 53 dd e5 6b ad 67 be f9 |.....>ofS..k.g..|
1090 0170: 72 ee 5f 8d 61 3c 61 b6 f9 8c d8 a5 82 63 45 3d |r._.a<a......cE=|
1090 0170: 72 ee 5f 8d 61 3c 61 b6 f9 8c d8 a5 82 63 45 3d |r._.a<a......cE=|
1091 0180: a3 0c 61 90 68 24 28 87 50 b9 c2 97 c6 20 01 11 |..a.h$(.P.... ..|
1091 0180: a3 0c 61 90 68 24 28 87 50 b9 c2 97 c6 20 01 11 |..a.h$(.P.... ..|
1092 0190: 80 84 10 98 cf e8 e4 13 96 05 51 2c 38 f3 c4 ec |..........Q,8...|
1092 0190: 80 84 10 98 cf e8 e4 13 96 05 51 2c 38 f3 c4 ec |..........Q,8...|
1093 01a0: ea 43 e7 96 5e 6a c8 be 11 dd 32 78 a2 fa dd 8f |.C..^j....2x....|
1093 01a0: ea 43 e7 96 5e 6a c8 be 11 dd 32 78 a2 fa dd 8f |.C..^j....2x....|
1094 01b0: b3 61 84 61 51 0c b3 cd 27 64 42 6b c2 b4 92 1e |.a.aQ...'dBk....|
1094 01b0: b3 61 84 61 51 0c b3 cd 27 64 42 6b c2 b4 92 1e |.a.aQ...'dBk....|
1095 01c0: 86 8c 12 68 24 00 10 db 7f 50 00 c6 91 e7 fa 4c |...h$....P.....L|
1095 01c0: 86 8c 12 68 24 00 10 db 7f 50 00 c6 91 e7 fa 4c |...h$....P.....L|
1096 01d0: 22 22 cc bf 84 81 0a 92 c1 aa 2a c7 1b 49 e6 ee |""........*..I..|
1096 01d0: 22 22 cc bf 84 81 0a 92 c1 aa 2a c7 1b 49 e6 ee |""........*..I..|
1097 01e0: 6b a9 7e e0 e9 b2 91 5e 7c 73 68 e0 fc 23 3f 34 |k.~....^|sh..#?4|
1097 01e0: 6b a9 7e e0 e9 b2 91 5e 7c 73 68 e0 fc 23 3f 34 |k.~....^|sh..#?4|
1098 01f0: ed cf 0e f2 b3 d3 4c d7 ae 59 33 6f 8c 3d b8 63 |......L..Y3o.=.c|
1098 01f0: ed cf 0e f2 b3 d3 4c d7 ae 59 33 6f 8c 3d b8 63 |......L..Y3o.=.c|
1099 0200: 21 2b e8 3d e0 6f 9d 3a b7 f9 dc 24 2a b2 3e a7 |!+.=.o.:...$*.>.|
1099 0200: 21 2b e8 3d e0 6f 9d 3a b7 f9 dc 24 2a b2 3e a7 |!+.=.o.:...$*.>.|
1100 0210: 58 dc 91 d8 40 e9 23 8e 88 84 ae 0f b9 00 2e b5 |X...@.#.........|
1100 0210: 58 dc 91 d8 40 e9 23 8e 88 84 ae 0f b9 00 2e b5 |X...@.#.........|
1101 0220: 74 36 f3 40 53 40 34 15 c0 d7 12 8d e7 bb 65 f9 |t6.@S@4.......e.|
1101 0220: 74 36 f3 40 53 40 34 15 c0 d7 12 8d e7 bb 65 f9 |t6.@S@4.......e.|
1102 0230: c8 ef 03 0f ff f9 fe b6 8a 0d 6d fd ec 51 70 f7 |..........m..Qp.|
1102 0230: c8 ef 03 0f ff f9 fe b6 8a 0d 6d fd ec 51 70 f7 |..........m..Qp.|
1103 0240: a7 ad 9b 6b 9d da 74 7b 53 43 d1 43 63 fd 19 f9 |...k..t{SC.Cc...|
1103 0240: a7 ad 9b 6b 9d da 74 7b 53 43 d1 43 63 fd 19 f9 |...k..t{SC.Cc...|
1104 0250: ca 67 95 e5 ef c4 e6 6c 9e 44 e1 c5 ac 7a 82 6f |.g.....l.D...z.o|
1104 0250: ca 67 95 e5 ef c4 e6 6c 9e 44 e1 c5 ac 7a 82 6f |.g.....l.D...z.o|
1105 0260: c2 e1 d2 b5 2d 81 29 f0 5d 09 6c 6f 10 ae 88 cf |....-.).].lo....|
1105 0260: c2 e1 d2 b5 2d 81 29 f0 5d 09 6c 6f 10 ae 88 cf |....-.).].lo....|
1106 0270: 25 05 d0 93 06 78 80 60 43 2d 10 1b 47 71 2b b7 |%....x.`C-..Gq+.|
1106 0270: 25 05 d0 93 06 78 80 60 43 2d 10 1b 47 71 2b b7 |%....x.`C-..Gq+.|
1107 0280: 7f bb e9 a7 e4 7d 67 7b df 9b f7 62 cf cd d8 f4 |.....}g{...b....|
1107 0280: 7f bb e9 a7 e4 7d 67 7b df 9b f7 62 cf cd d8 f4 |.....}g{...b....|
1108 0290: 48 bc 64 51 57 43 ff ea 8b 0b ae 74 64 53 07 86 |H.dQWC.....tdS..|
1108 0290: 48 bc 64 51 57 43 ff ea 8b 0b ae 74 64 53 07 86 |H.dQWC.....tdS..|
1109 02a0: fa 66 3c 5e f7 e1 af a7 c2 90 ff a7 be 9e c9 29 |.f<^...........)|
1109 02a0: fa 66 3c 5e f7 e1 af a7 c2 90 ff a7 be 9e c9 29 |.f<^...........)|
1110 02b0: b6 cc 41 48 18 69 94 8b 7c 04 7d 8c 98 a7 95 50 |..AH.i..|.}....P|
1110 02b0: b6 cc 41 48 18 69 94 8b 7c 04 7d 8c 98 a7 95 50 |..AH.i..|.}....P|
1111 02c0: 44 d9 d0 20 c8 14 30 14 51 ad 6c 16 03 94 0f 5a |D.. ..0.Q.l....Z|
1111 02c0: 44 d9 d0 20 c8 14 30 14 51 ad 6c 16 03 94 0f 5a |D.. ..0.Q.l....Z|
1112 02d0: 46 93 7f 1c 87 8d 25 d7 9d a2 d1 92 4c f3 c2 54 |F.....%.....L..T|
1112 02d0: 46 93 7f 1c 87 8d 25 d7 9d a2 d1 92 4c f3 c2 54 |F.....%.....L..T|
1113 02e0: ba f8 70 18 ca 24 0a 29 96 43 71 f2 93 95 74 18 |..p..$.).Cq...t.|
1113 02e0: ba f8 70 18 ca 24 0a 29 96 43 71 f2 93 95 74 18 |..p..$.).Cq...t.|
1114 02f0: b5 65 c4 b8 f6 6c 5c 34 20 1e d5 0c 21 c0 b1 90 |.e...l\4 ...!...|
1114 02f0: b5 65 c4 b8 f6 6c 5c 34 20 1e d5 0c 21 c0 b1 90 |.e...l\4 ...!...|
1115 0300: 9e 12 40 b9 18 fa 5a 00 41 a2 39 d3 a9 c1 73 21 |..@...Z.A.9...s!|
1115 0300: 9e 12 40 b9 18 fa 5a 00 41 a2 39 d3 a9 c1 73 21 |..@...Z.A.9...s!|
1116 0310: 8e 5e 3c b9 b8 f8 48 6a 76 46 a7 1a b6 dd 5b 51 |.^<...HjvF....[Q|
1116 0310: 8e 5e 3c b9 b8 f8 48 6a 76 46 a7 1a b6 dd 5b 51 |.^<...HjvF....[Q|
1117 0320: 5e 19 1d 59 12 c6 32 89 02 9a c0 8f 4f b8 0a ba |^..Y..2.....O...|
1117 0320: 5e 19 1d 59 12 c6 32 89 02 9a c0 8f 4f b8 0a ba |^..Y..2.....O...|
1118 0330: 5e ec 58 37 44 a3 2f dd 33 ed c9 d3 dd c7 22 1b |^.X7D./.3.....".|
1118 0330: 5e ec 58 37 44 a3 2f dd 33 ed c9 d3 dd c7 22 1b |^.X7D./.3.....".|
1119 0340: 2f d4 94 8e 95 3f 77 a7 ae 6e f3 32 8d bb 4a 4c |/....?w..n.2..JL|
1119 0340: 2f d4 94 8e 95 3f 77 a7 ae 6e f3 32 8d bb 4a 4c |/....?w..n.2..JL|
1120 0350: b8 0a 5a 43 34 3a b3 3a d6 77 ff 5c b6 fa ad f9 |..ZC4:.:.w.\....|
1120 0350: b8 0a 5a 43 34 3a b3 3a d6 77 ff 5c b6 fa ad f9 |..ZC4:.:.w.\....|
1121 0360: db fb 6a 33 df c1 7d 99 cf ef d4 d5 6d da 77 7c |..j3..}.....m.w||
1121 0360: db fb 6a 33 df c1 7d 99 cf ef d4 d5 6d da 77 7c |..j3..}.....m.w||
1122 0370: 3b 19 fd af c5 3f f1 60 c3 17 |;....?.`..|
1122 0370: 3b 19 fd af c5 3f f1 60 c3 17 |;....?.`..|
1123 $ hg debugbundle ../rev.hg2.bz
1123 $ hg debugbundle ../rev.hg2.bz
1124 Stream params: {Compression: GZ}
1124 Stream params: {Compression: GZ}
1125 changegroup -- {} (mandatory: False)
1125 changegroup -- {} (mandatory: False)
1126 32af7686d403cf45b5d95f2d70cebea587ac806a
1126 32af7686d403cf45b5d95f2d70cebea587ac806a
1127 9520eea781bcca16c1e15acc0ba14335a0e8e5ba
1127 9520eea781bcca16c1e15acc0ba14335a0e8e5ba
1128 eea13746799a9e0bfd88f29d3c2e9dc9389f524f
1128 eea13746799a9e0bfd88f29d3c2e9dc9389f524f
1129 02de42196ebee42ef284b6780a87cdc96e8eaab6
1129 02de42196ebee42ef284b6780a87cdc96e8eaab6
1130 $ hg unbundle ../rev.hg2.bz
1130 $ hg unbundle ../rev.hg2.bz
1131 adding changesets
1131 adding changesets
1132 adding manifests
1132 adding manifests
1133 adding file changes
1133 adding file changes
1134 added 0 changesets with 0 changes to 3 files
1134 added 0 changesets with 0 changes to 3 files
1135 (run 'hg update' to get a working copy)
1135 (run 'hg update' to get a working copy)
1136 Simple case where it just work: BZ
1136 Simple case where it just work: BZ
1137 ----------------------------------
1137 ----------------------------------
1138
1138
1139 $ hg bundle2 --compress BZ --rev '8+7+5+4' ../rev.hg2.bz
1139 $ hg bundle2 --compress BZ --rev '8+7+5+4' ../rev.hg2.bz
1140 $ f --hexdump ../rev.hg2.bz
1140 $ f --hexdump ../rev.hg2.bz
1141 ../rev.hg2.bz:
1141 ../rev.hg2.bz:
1142 0000: 48 47 32 30 00 00 00 0e 43 6f 6d 70 72 65 73 73 |HG20....Compress|
1142 0000: 48 47 32 30 00 00 00 0e 43 6f 6d 70 72 65 73 73 |HG20....Compress|
1143 0010: 69 6f 6e 3d 42 5a 42 5a 68 39 31 41 59 26 53 59 |ion=BZBZh91AY&SY|
1143 0010: 69 6f 6e 3d 42 5a 42 5a 68 39 31 41 59 26 53 59 |ion=BZBZh91AY&SY|
1144 0020: a3 4b 18 3d 00 00 1a 7f ff ff bf 5f f6 ef ef 7f |.K.=......._....|
1144 0020: a3 4b 18 3d 00 00 1a 7f ff ff bf 5f f6 ef ef 7f |.K.=......._....|
1145 0030: f6 3f f7 d1 d9 ff ff f7 6e ff ff 6e f7 f6 bd df |.?......n..n....|
1145 0030: f6 3f f7 d1 d9 ff ff f7 6e ff ff 6e f7 f6 bd df |.?......n..n....|
1146 0040: b5 ab ff cf 67 f6 e7 7b f7 c0 02 d7 33 82 8b 51 |....g..{....3..Q|
1146 0040: b5 ab ff cf 67 f6 e7 7b f7 c0 02 d7 33 82 8b 51 |....g..{....3..Q|
1147 0050: 04 a5 53 d5 3d 27 a0 99 18 4d 0d 34 00 d1 a1 e8 |..S.='...M.4....|
1147 0050: 04 a5 53 d5 3d 27 a0 99 18 4d 0d 34 00 d1 a1 e8 |..S.='...M.4....|
1148 0060: 80 c8 7a 87 a9 a3 43 6a 3d 46 86 26 80 34 3d 40 |..z...Cj=F.&.4=@|
1148 0060: 80 c8 7a 87 a9 a3 43 6a 3d 46 86 26 80 34 3d 40 |..z...Cj=F.&.4=@|
1149 0070: c8 c9 b5 34 f4 8f 48 0f 51 ea 34 34 fd 4d aa 19 |...4..H.Q.44.M..|
1149 0070: c8 c9 b5 34 f4 8f 48 0f 51 ea 34 34 fd 4d aa 19 |...4..H.Q.44.M..|
1150 0080: 03 40 0c 08 da 86 43 d4 f5 0f 42 1e a0 f3 54 33 |.@....C...B...T3|
1150 0080: 03 40 0c 08 da 86 43 d4 f5 0f 42 1e a0 f3 54 33 |.@....C...B...T3|
1151 0090: 54 d3 13 4d 03 40 32 00 00 32 03 26 80 0d 00 0d |T..M.@2..2.&....|
1151 0090: 54 d3 13 4d 03 40 32 00 00 32 03 26 80 0d 00 0d |T..M.@2..2.&....|
1152 00a0: 00 68 c8 c8 03 20 32 30 98 8c 80 00 00 03 4d 00 |.h... 20......M.|
1152 00a0: 00 68 c8 c8 03 20 32 30 98 8c 80 00 00 03 4d 00 |.h... 20......M.|
1153 00b0: c8 00 00 0d 00 00 22 99 a1 34 c2 64 a6 d5 34 1a |......"..4.d..4.|
1153 00b0: c8 00 00 0d 00 00 22 99 a1 34 c2 64 a6 d5 34 1a |......"..4.d..4.|
1154 00c0: 00 00 06 86 83 4d 07 a8 d1 a0 68 01 a0 00 00 00 |.....M....h.....|
1154 00c0: 00 00 06 86 83 4d 07 a8 d1 a0 68 01 a0 00 00 00 |.....M....h.....|
1155 00d0: 00 0d 06 80 00 00 00 0d 00 03 40 00 00 04 a4 a1 |..........@.....|
1155 00d0: 00 0d 06 80 00 00 00 0d 00 03 40 00 00 04 a4 a1 |..........@.....|
1156 00e0: 4d a9 89 89 b4 9a 32 0c 43 46 86 87 a9 8d 41 9a |M.....2.CF....A.|
1156 00e0: 4d a9 89 89 b4 9a 32 0c 43 46 86 87 a9 8d 41 9a |M.....2.CF....A.|
1157 00f0: 98 46 9a 0d 31 32 1a 34 0d 0c 8d a2 0c 98 4d 06 |.F..12.4......M.|
1157 00f0: 98 46 9a 0d 31 32 1a 34 0d 0c 8d a2 0c 98 4d 06 |.F..12.4......M.|
1158 0100: 8c 40 c2 60 8d 0d 0c 20 c9 89 fa a0 d0 d3 21 a1 |.@.`... ......!.|
1158 0100: 8c 40 c2 60 8d 0d 0c 20 c9 89 fa a0 d0 d3 21 a1 |.@.`... ......!.|
1159 0110: ea 34 d3 68 9e a6 d1 74 05 33 cb 66 96 93 28 64 |.4.h...t.3.f..(d|
1159 0110: ea 34 d3 68 9e a6 d1 74 05 33 cb 66 96 93 28 64 |.4.h...t.3.f..(d|
1160 0120: 40 91 22 ac 55 9b ea 40 7b 38 94 e2 f8 06 00 cb |@.".U..@{8......|
1160 0120: 40 91 22 ac 55 9b ea 40 7b 38 94 e2 f8 06 00 cb |@.".U..@{8......|
1161 0130: 28 02 00 4d ab 40 24 10 43 18 cf 64 b4 06 83 0c |(..M.@$.C..d....|
1161 0130: 28 02 00 4d ab 40 24 10 43 18 cf 64 b4 06 83 0c |(..M.@$.C..d....|
1162 0140: 34 6c b4 a3 d4 0a 0a e4 a8 5c 4e 23 c0 c9 7a 31 |4l.......\N#..z1|
1162 0140: 34 6c b4 a3 d4 0a 0a e4 a8 5c 4e 23 c0 c9 7a 31 |4l.......\N#..z1|
1163 0150: 97 87 77 7a 64 88 80 8e 60 97 20 93 0f 8e eb c4 |..wzd...`. .....|
1163 0150: 97 87 77 7a 64 88 80 8e 60 97 20 93 0f 8e eb c4 |..wzd...`. .....|
1164 0160: 62 a4 44 a3 52 20 b2 99 a9 2e e1 d7 29 4a 54 ac |b.D.R ......)JT.|
1164 0160: 62 a4 44 a3 52 20 b2 99 a9 2e e1 d7 29 4a 54 ac |b.D.R ......)JT.|
1165 0170: 44 7a bb cc 04 3d e0 aa bd 6a 33 5e 9b a2 57 36 |Dz...=...j3^..W6|
1165 0170: 44 7a bb cc 04 3d e0 aa bd 6a 33 5e 9b a2 57 36 |Dz...=...j3^..W6|
1166 0180: fa cb 45 bb 6d 3e c1 d9 d9 f5 83 69 8a d0 e0 e2 |..E.m>.....i....|
1166 0180: fa cb 45 bb 6d 3e c1 d9 d9 f5 83 69 8a d0 e0 e2 |..E.m>.....i....|
1167 0190: e7 ae 90 55 24 da 3f ab 78 c0 4c b4 56 a3 9e a4 |...U$.?.x.L.V...|
1167 0190: e7 ae 90 55 24 da 3f ab 78 c0 4c b4 56 a3 9e a4 |...U$.?.x.L.V...|
1168 01a0: af 9c 65 74 86 ec 6d dc 62 dc 33 ca c8 50 dd 9d |..et..m.b.3..P..|
1168 01a0: af 9c 65 74 86 ec 6d dc 62 dc 33 ca c8 50 dd 9d |..et..m.b.3..P..|
1169 01b0: 98 8e 9e 59 20 f3 f0 42 91 4a 09 f5 75 8d 3d a5 |...Y ..B.J..u.=.|
1169 01b0: 98 8e 9e 59 20 f3 f0 42 91 4a 09 f5 75 8d 3d a5 |...Y ..B.J..u.=.|
1170 01c0: a5 15 cb 8d 10 63 b0 c2 2e b2 81 f7 c1 76 0e 53 |.....c.......v.S|
1170 01c0: a5 15 cb 8d 10 63 b0 c2 2e b2 81 f7 c1 76 0e 53 |.....c.......v.S|
1171 01d0: 6c 0e 46 73 b5 ae 67 f9 4c 0b 45 6b a8 32 2a 2f |l.Fs..g.L.Ek.2*/|
1171 01d0: 6c 0e 46 73 b5 ae 67 f9 4c 0b 45 6b a8 32 2a 2f |l.Fs..g.L.Ek.2*/|
1172 01e0: a2 54 a4 44 05 20 a1 38 d1 a4 c6 09 a8 2b 08 99 |.T.D. .8.....+..|
1172 01e0: a2 54 a4 44 05 20 a1 38 d1 a4 c6 09 a8 2b 08 99 |.T.D. .8.....+..|
1173 01f0: a4 14 ae 8d a3 e3 aa 34 27 d8 44 ca c3 5d 21 8b |.......4'.D..]!.|
1173 01f0: a4 14 ae 8d a3 e3 aa 34 27 d8 44 ca c3 5d 21 8b |.......4'.D..]!.|
1174 0200: 1a 1e 97 29 71 2b 09 4a 4a 55 55 94 58 65 b2 bc |...)q+.JJUU.Xe..|
1174 0200: 1a 1e 97 29 71 2b 09 4a 4a 55 55 94 58 65 b2 bc |...)q+.JJUU.Xe..|
1175 0210: f3 a5 90 26 36 76 67 7a 51 98 d6 8a 4a 99 50 b5 |...&6vgzQ...J.P.|
1175 0210: f3 a5 90 26 36 76 67 7a 51 98 d6 8a 4a 99 50 b5 |...&6vgzQ...J.P.|
1176 0220: 99 8f 94 21 17 a9 8b f3 ad 4c 33 d4 2e 40 c8 0c |...!.....L3..@..|
1176 0220: 99 8f 94 21 17 a9 8b f3 ad 4c 33 d4 2e 40 c8 0c |...!.....L3..@..|
1177 0230: 3b 90 53 39 db 48 02 34 83 48 d6 b3 99 13 d2 58 |;.S9.H.4.H.....X|
1177 0230: 3b 90 53 39 db 48 02 34 83 48 d6 b3 99 13 d2 58 |;.S9.H.4.H.....X|
1178 0240: 65 8e 71 ac a9 06 95 f2 c4 8e b4 08 6b d3 0c ae |e.q.........k...|
1178 0240: 65 8e 71 ac a9 06 95 f2 c4 8e b4 08 6b d3 0c ae |e.q.........k...|
1179 0250: d9 90 56 71 43 a7 a2 62 16 3e 50 63 d3 57 3c 2d |..VqC..b.>Pc.W<-|
1179 0250: d9 90 56 71 43 a7 a2 62 16 3e 50 63 d3 57 3c 2d |..VqC..b.>Pc.W<-|
1180 0260: 9f 0f 34 05 08 d8 a6 4b 59 31 54 66 3a 45 0c 8a |..4....KY1Tf:E..|
1180 0260: 9f 0f 34 05 08 d8 a6 4b 59 31 54 66 3a 45 0c 8a |..4....KY1Tf:E..|
1181 0270: c7 90 3a f0 6a 83 1b f5 ca fb 80 2b 50 06 fb 51 |..:.j......+P..Q|
1181 0270: c7 90 3a f0 6a 83 1b f5 ca fb 80 2b 50 06 fb 51 |..:.j......+P..Q|
1182 0280: 7e a6 a4 d4 81 44 82 21 54 00 5b 1a 30 83 62 a3 |~....D.!T.[.0.b.|
1182 0280: 7e a6 a4 d4 81 44 82 21 54 00 5b 1a 30 83 62 a3 |~....D.!T.[.0.b.|
1183 0290: 18 b6 24 19 1e 45 df 4d 5c db a6 af 5b ac 90 fa |..$..E.M\...[...|
1183 0290: 18 b6 24 19 1e 45 df 4d 5c db a6 af 5b ac 90 fa |..$..E.M\...[...|
1184 02a0: 3e ed f9 ec 4c ba 36 ee d8 60 20 a7 c7 3b cb d1 |>...L.6..` ..;..|
1184 02a0: 3e ed f9 ec 4c ba 36 ee d8 60 20 a7 c7 3b cb d1 |>...L.6..` ..;..|
1185 02b0: 90 43 7d 27 16 50 5d ad f4 14 07 0b 90 5c cc 6b |.C}'.P]......\.k|
1185 02b0: 90 43 7d 27 16 50 5d ad f4 14 07 0b 90 5c cc 6b |.C}'.P]......\.k|
1186 02c0: 8d 3f a6 88 f4 34 37 a8 cf 14 63 36 19 f7 3e 28 |.?...47...c6..>(|
1186 02c0: 8d 3f a6 88 f4 34 37 a8 cf 14 63 36 19 f7 3e 28 |.?...47...c6..>(|
1187 02d0: de 99 e8 16 a4 9d 0d 40 a1 a7 24 52 14 a6 72 62 |.......@..$R..rb|
1187 02d0: de 99 e8 16 a4 9d 0d 40 a1 a7 24 52 14 a6 72 62 |.......@..$R..rb|
1188 02e0: 59 5a ca 2d e5 51 90 78 88 d9 c6 c7 21 d0 f7 46 |YZ.-.Q.x....!..F|
1188 02e0: 59 5a ca 2d e5 51 90 78 88 d9 c6 c7 21 d0 f7 46 |YZ.-.Q.x....!..F|
1189 02f0: b2 04 46 44 4e 20 9c 12 b1 03 4e 25 e0 a9 0c 58 |..FDN ....N%...X|
1189 02f0: b2 04 46 44 4e 20 9c 12 b1 03 4e 25 e0 a9 0c 58 |..FDN ....N%...X|
1190 0300: 5b 1d 3c 93 20 01 51 de a9 1c 69 23 32 46 14 b4 |[.<. .Q...i#2F..|
1190 0300: 5b 1d 3c 93 20 01 51 de a9 1c 69 23 32 46 14 b4 |[.<. .Q...i#2F..|
1191 0310: 90 db 17 98 98 50 03 90 29 aa 40 b0 13 d8 43 d2 |.....P..).@...C.|
1191 0310: 90 db 17 98 98 50 03 90 29 aa 40 b0 13 d8 43 d2 |.....P..).@...C.|
1192 0320: 5f c5 9d eb f3 f2 ad 41 e8 7a a9 ed a1 58 84 a6 |_......A.z...X..|
1192 0320: 5f c5 9d eb f3 f2 ad 41 e8 7a a9 ed a1 58 84 a6 |_......A.z...X..|
1193 0330: 42 bf d6 fc 24 82 c1 20 32 26 4a 15 a6 1d 29 7f |B...$.. 2&J...).|
1193 0330: 42 bf d6 fc 24 82 c1 20 32 26 4a 15 a6 1d 29 7f |B...$.. 2&J...).|
1194 0340: 7e f4 3d 07 bc 62 9a 5b ec 44 3d 72 1d 41 8b 5c |~.=..b.[.D=r.A.\|
1194 0340: 7e f4 3d 07 bc 62 9a 5b ec 44 3d 72 1d 41 8b 5c |~.=..b.[.D=r.A.\|
1195 0350: 80 de 0e 62 9a 2e f8 83 00 d5 07 a0 9c c6 74 98 |...b..........t.|
1195 0350: 80 de 0e 62 9a 2e f8 83 00 d5 07 a0 9c c6 74 98 |...b..........t.|
1196 0360: 11 b2 5e a9 38 02 03 ee fd 86 5c f4 86 b3 ae da |..^.8.....\.....|
1196 0360: 11 b2 5e a9 38 02 03 ee fd 86 5c f4 86 b3 ae da |..^.8.....\.....|
1197 0370: 05 94 01 c5 c6 ea 18 e6 ba 2a ba b3 04 5c 96 89 |.........*...\..|
1197 0370: 05 94 01 c5 c6 ea 18 e6 ba 2a ba b3 04 5c 96 89 |.........*...\..|
1198 0380: 72 63 5b 10 11 f6 67 34 98 cb e4 c0 4e fa e6 99 |rc[...g4....N...|
1198 0380: 72 63 5b 10 11 f6 67 34 98 cb e4 c0 4e fa e6 99 |rc[...g4....N...|
1199 0390: 19 6e 50 e8 26 8d 0c 17 e0 be ef e1 8e 02 6f 32 |.nP.&.........o2|
1199 0390: 19 6e 50 e8 26 8d 0c 17 e0 be ef e1 8e 02 6f 32 |.nP.&.........o2|
1200 03a0: 82 dc 26 f8 a1 08 f3 8a 0d f3 c4 75 00 48 73 b8 |..&........u.Hs.|
1200 03a0: 82 dc 26 f8 a1 08 f3 8a 0d f3 c4 75 00 48 73 b8 |..&........u.Hs.|
1201 03b0: be 3b 0d 7f d0 fd c7 78 96 ec e0 03 80 68 4d 8d |.;.....x.....hM.|
1201 03b0: be 3b 0d 7f d0 fd c7 78 96 ec e0 03 80 68 4d 8d |.;.....x.....hM.|
1202 03c0: 43 8c d7 68 58 f9 50 f0 18 cb 21 58 1b 60 cd 1f |C..hX.P...!X.`..|
1202 03c0: 43 8c d7 68 58 f9 50 f0 18 cb 21 58 1b 60 cd 1f |C..hX.P...!X.`..|
1203 03d0: 84 36 2e 16 1f 0a f7 4e 8f eb df 01 2d c2 79 0b |.6.....N....-.y.|
1203 03d0: 84 36 2e 16 1f 0a f7 4e 8f eb df 01 2d c2 79 0b |.6.....N....-.y.|
1204 03e0: f7 24 ea 0d e8 59 86 51 6e 1c 30 a3 ad 2f ee 8c |.$...Y.Qn.0../..|
1204 03e0: f7 24 ea 0d e8 59 86 51 6e 1c 30 a3 ad 2f ee 8c |.$...Y.Qn.0../..|
1205 03f0: 90 c8 84 d5 e8 34 c1 95 b2 c9 f6 4d 87 1c 7d 19 |.....4.....M..}.|
1205 03f0: 90 c8 84 d5 e8 34 c1 95 b2 c9 f6 4d 87 1c 7d 19 |.....4.....M..}.|
1206 0400: d6 41 58 56 7a e0 6c ba 10 c7 e8 33 39 36 96 e7 |.AXVz.l....396..|
1206 0400: d6 41 58 56 7a e0 6c ba 10 c7 e8 33 39 36 96 e7 |.AXVz.l....396..|
1207 0410: d2 f9 59 9a 08 95 48 38 e7 0b b7 0a 24 67 c4 39 |..Y...H8....$g.9|
1207 0410: d2 f9 59 9a 08 95 48 38 e7 0b b7 0a 24 67 c4 39 |..Y...H8....$g.9|
1208 0420: 8b 43 88 57 9c 01 f5 61 b5 e1 27 41 7e af 83 fe |.C.W...a..'A~...|
1208 0420: 8b 43 88 57 9c 01 f5 61 b5 e1 27 41 7e af 83 fe |.C.W...a..'A~...|
1209 0430: 2e e4 8a 70 a1 21 46 96 30 7a |...p.!F.0z|
1209 0430: 2e e4 8a 70 a1 21 46 96 30 7a |...p.!F.0z|
1210 $ hg debugbundle ../rev.hg2.bz
1210 $ hg debugbundle ../rev.hg2.bz
1211 Stream params: {Compression: BZ}
1211 Stream params: {Compression: BZ}
1212 changegroup -- {} (mandatory: False)
1212 changegroup -- {} (mandatory: False)
1213 32af7686d403cf45b5d95f2d70cebea587ac806a
1213 32af7686d403cf45b5d95f2d70cebea587ac806a
1214 9520eea781bcca16c1e15acc0ba14335a0e8e5ba
1214 9520eea781bcca16c1e15acc0ba14335a0e8e5ba
1215 eea13746799a9e0bfd88f29d3c2e9dc9389f524f
1215 eea13746799a9e0bfd88f29d3c2e9dc9389f524f
1216 02de42196ebee42ef284b6780a87cdc96e8eaab6
1216 02de42196ebee42ef284b6780a87cdc96e8eaab6
1217 $ hg unbundle ../rev.hg2.bz
1217 $ hg unbundle ../rev.hg2.bz
1218 adding changesets
1218 adding changesets
1219 adding manifests
1219 adding manifests
1220 adding file changes
1220 adding file changes
1221 added 0 changesets with 0 changes to 3 files
1221 added 0 changesets with 0 changes to 3 files
1222 (run 'hg update' to get a working copy)
1222 (run 'hg update' to get a working copy)
1223
1223
1224 unknown compression while unbundling
1224 unknown compression while unbundling
1225 -----------------------------
1225 -----------------------------
1226
1226
1227 $ hg bundle2 --param Compression=FooBarUnknown --rev '8+7+5+4' ../rev.hg2.bz
1227 $ hg bundle2 --param Compression=FooBarUnknown --rev '8+7+5+4' ../rev.hg2.bz
1228 $ cat ../rev.hg2.bz | hg statbundle2
1228 $ cat ../rev.hg2.bz | hg statbundle2
1229 abort: unknown parameters: Stream Parameter - Compression='FooBarUnknown'
1229 abort: unknown parameters: Stream Parameter - Compression='FooBarUnknown'
1230 [255]
1230 [255]
1231 $ hg unbundle ../rev.hg2.bz
1231 $ hg unbundle ../rev.hg2.bz
1232 abort: ../rev.hg2.bz: unknown bundle feature, Stream Parameter - Compression='FooBarUnknown'
1232 abort: ../rev.hg2.bz: unknown bundle feature, Stream Parameter - Compression='FooBarUnknown'
1233 (see https://mercurial-scm.org/wiki/BundleFeature for more information)
1233 (see https://mercurial-scm.org/wiki/BundleFeature for more information)
1234 [255]
1234 [255]
1235
1235
1236 $ cd ..
1236 $ cd ..
@@ -1,568 +1,568 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 digests
57 digests
58 md5
58 md5
59 sha1
59 sha1
60 sha512
60 sha512
61 error
61 error
62 abort
62 abort
63 unsupportedcontent
63 unsupportedcontent
64 pushraced
64 pushraced
65 pushkey
65 pushkey
66 hgtagsfnodes
66 hgtagsfnodes
67 listkeys
67 listkeys
68 phases
68 phases
69 heads
69 heads
70 pushkey
70 pushkey
71 remote-changegroup
71 remote-changegroup
72 http
72 http
73 https
73 https
74 rev-branch-cache
74 rev-branch-cache
75
75
76 $ hg clone --stream -U http://localhost:$HGPORT server-disabled
76 $ hg clone --stream -U http://localhost:$HGPORT server-disabled
77 warning: stream clone requested but server has them disabled
77 warning: stream clone requested but server has them disabled
78 requesting all changes
78 requesting all changes
79 adding changesets
79 adding changesets
80 adding manifests
80 adding manifests
81 adding file changes
81 adding file changes
82 added 2 changesets with 1025 changes to 1025 files
82 added 2 changesets with 1025 changes to 1025 files
83 new changesets 96ee1d7354c4:c17445101a72
83 new changesets 96ee1d7354c4:c17445101a72
84
84
85 $ 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"
85 $ 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 200 Script output follows
86 200 Script output follows
87 content-type: application/mercurial-0.2
87 content-type: application/mercurial-0.2
88
88
89
89
90 $ f --size body --hexdump --bytes 100
90 $ f --size body --hexdump --bytes 100
91 body: size=232
91 body: size=232
92 0000: 04 6e 6f 6e 65 48 47 32 30 00 00 00 00 00 00 00 |.noneHG20.......|
92 0000: 04 6e 6f 6e 65 48 47 32 30 00 00 00 00 00 00 00 |.noneHG20.......|
93 0010: cf 0b 45 52 52 4f 52 3a 41 42 4f 52 54 00 00 00 |..ERROR:ABORT...|
93 0010: cf 0b 45 52 52 4f 52 3a 41 42 4f 52 54 00 00 00 |..ERROR:ABORT...|
94 0020: 00 01 01 07 3c 04 72 6d 65 73 73 61 67 65 73 74 |....<.rmessagest|
94 0020: 00 01 01 07 3c 04 72 6d 65 73 73 61 67 65 73 74 |....<.rmessagest|
95 0030: 72 65 61 6d 20 64 61 74 61 20 72 65 71 75 65 73 |ream data reques|
95 0030: 72 65 61 6d 20 64 61 74 61 20 72 65 71 75 65 73 |ream data reques|
96 0040: 74 65 64 20 62 75 74 20 73 65 72 76 65 72 20 64 |ted but server d|
96 0040: 74 65 64 20 62 75 74 20 73 65 72 76 65 72 20 64 |ted but server d|
97 0050: 6f 65 73 20 6e 6f 74 20 61 6c 6c 6f 77 20 74 68 |oes not allow th|
97 0050: 6f 65 73 20 6e 6f 74 20 61 6c 6c 6f 77 20 74 68 |oes not allow th|
98 0060: 69 73 20 66 |is f|
98 0060: 69 73 20 66 |is f|
99
99
100 #endif
100 #endif
101 #if stream-bundle2
101 #if stream-bundle2
102 $ hg debugcapabilities http://localhost:$HGPORT
102 $ hg debugcapabilities http://localhost:$HGPORT
103 Main capabilities:
103 Main capabilities:
104 batch
104 batch
105 branchmap
105 branchmap
106 $USUAL_BUNDLE2_CAPS_SERVER$
106 $USUAL_BUNDLE2_CAPS_SERVER$
107 changegroupsubset
107 changegroupsubset
108 compression=$BUNDLE2_COMPRESSIONS$
108 compression=$BUNDLE2_COMPRESSIONS$
109 getbundle
109 getbundle
110 httpheader=1024
110 httpheader=1024
111 httpmediatype=0.1rx,0.1tx,0.2tx
111 httpmediatype=0.1rx,0.1tx,0.2tx
112 known
112 known
113 lookup
113 lookup
114 pushkey
114 pushkey
115 unbundle=HG10GZ,HG10BZ,HG10UN
115 unbundle=HG10GZ,HG10BZ,HG10UN
116 unbundlehash
116 unbundlehash
117 Bundle2 capabilities:
117 Bundle2 capabilities:
118 HG20
118 HG20
119 bookmarks
119 bookmarks
120 changegroup
120 changegroup
121 01
121 01
122 02
122 02
123 digests
123 digests
124 md5
124 md5
125 sha1
125 sha1
126 sha512
126 sha512
127 error
127 error
128 abort
128 abort
129 unsupportedcontent
129 unsupportedcontent
130 pushraced
130 pushraced
131 pushkey
131 pushkey
132 hgtagsfnodes
132 hgtagsfnodes
133 listkeys
133 listkeys
134 phases
134 phases
135 heads
135 heads
136 pushkey
136 pushkey
137 remote-changegroup
137 remote-changegroup
138 http
138 http
139 https
139 https
140 rev-branch-cache
140 rev-branch-cache
141
141
142 $ hg clone --stream -U http://localhost:$HGPORT server-disabled
142 $ hg clone --stream -U http://localhost:$HGPORT server-disabled
143 warning: stream clone requested but server has them disabled
143 warning: stream clone requested but server has them disabled
144 requesting all changes
144 requesting all changes
145 adding changesets
145 adding changesets
146 adding manifests
146 adding manifests
147 adding file changes
147 adding file changes
148 added 2 changesets with 1025 changes to 1025 files
148 added 2 changesets with 1025 changes to 1025 files
149 new changesets 96ee1d7354c4:c17445101a72
149 new changesets 96ee1d7354c4:c17445101a72
150
150
151 $ 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"
151 $ 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"
152 200 Script output follows
152 200 Script output follows
153 content-type: application/mercurial-0.2
153 content-type: application/mercurial-0.2
154
154
155
155
156 $ f --size body --hexdump --bytes 100
156 $ f --size body --hexdump --bytes 100
157 body: size=232
157 body: size=232
158 0000: 04 6e 6f 6e 65 48 47 32 30 00 00 00 00 00 00 00 |.noneHG20.......|
158 0000: 04 6e 6f 6e 65 48 47 32 30 00 00 00 00 00 00 00 |.noneHG20.......|
159 0010: cf 0b 45 52 52 4f 52 3a 41 42 4f 52 54 00 00 00 |..ERROR:ABORT...|
159 0010: cf 0b 45 52 52 4f 52 3a 41 42 4f 52 54 00 00 00 |..ERROR:ABORT...|
160 0020: 00 01 01 07 3c 04 72 6d 65 73 73 61 67 65 73 74 |....<.rmessagest|
160 0020: 00 01 01 07 3c 04 72 6d 65 73 73 61 67 65 73 74 |....<.rmessagest|
161 0030: 72 65 61 6d 20 64 61 74 61 20 72 65 71 75 65 73 |ream data reques|
161 0030: 72 65 61 6d 20 64 61 74 61 20 72 65 71 75 65 73 |ream data reques|
162 0040: 74 65 64 20 62 75 74 20 73 65 72 76 65 72 20 64 |ted but server d|
162 0040: 74 65 64 20 62 75 74 20 73 65 72 76 65 72 20 64 |ted but server d|
163 0050: 6f 65 73 20 6e 6f 74 20 61 6c 6c 6f 77 20 74 68 |oes not allow th|
163 0050: 6f 65 73 20 6e 6f 74 20 61 6c 6c 6f 77 20 74 68 |oes not allow th|
164 0060: 69 73 20 66 |is f|
164 0060: 69 73 20 66 |is f|
165
165
166 #endif
166 #endif
167
167
168 $ killdaemons.py
168 $ killdaemons.py
169 $ cd server
169 $ cd server
170 $ hg serve -p $HGPORT -d --pid-file=hg.pid
170 $ hg serve -p $HGPORT -d --pid-file=hg.pid
171 $ cat hg.pid > $DAEMON_PIDS
171 $ cat hg.pid > $DAEMON_PIDS
172 $ cd ..
172 $ cd ..
173
173
174 Basic clone
174 Basic clone
175
175
176 #if stream-legacy
176 #if stream-legacy
177 $ hg clone --stream -U http://localhost:$HGPORT clone1
177 $ hg clone --stream -U http://localhost:$HGPORT clone1
178 streaming all changes
178 streaming all changes
179 1027 files to transfer, 96.3 KB of data
179 1027 files to transfer, 96.3 KB of data
180 transferred 96.3 KB in * seconds (*/sec) (glob)
180 transferred 96.3 KB in * seconds (*/sec) (glob)
181 searching for changes
181 searching for changes
182 no changes found
182 no changes found
183 #endif
183 #endif
184 #if stream-bundle2
184 #if stream-bundle2
185 $ hg clone --stream -U http://localhost:$HGPORT clone1
185 $ hg clone --stream -U http://localhost:$HGPORT clone1
186 streaming all changes
186 streaming all changes
187 1030 files to transfer, 96.5 KB of data
187 1030 files to transfer, 96.5 KB of data
188 transferred 96.5 KB in * seconds (* */sec) (glob)
188 transferred 96.5 KB in * seconds (* */sec) (glob)
189
189
190 $ ls -1 clone1/.hg/cache
190 $ ls -1 clone1/.hg/cache
191 branch2-served
191 branch2-served
192 rbc-names-v1
192 rbc-names-v1
193 rbc-revs-v1
193 rbc-revs-v1
194 #endif
194 #endif
195
195
196 getbundle requests with stream=1 are uncompressed
196 getbundle requests with stream=1 are uncompressed
197
197
198 $ 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"
198 $ 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"
199 200 Script output follows
199 200 Script output follows
200 content-type: application/mercurial-0.2
200 content-type: application/mercurial-0.2
201
201
202
202
203 $ f --size --hex --bytes 256 body
203 $ f --size --hex --bytes 256 body
204 body: size=112262
204 body: size=112262
205 0000: 04 6e 6f 6e 65 48 47 32 30 00 00 00 00 00 00 00 |.noneHG20.......|
205 0000: 04 6e 6f 6e 65 48 47 32 30 00 00 00 00 00 00 00 |.noneHG20.......|
206 0010: 7f 07 53 54 52 45 41 4d 32 00 00 00 00 03 00 09 |..STREAM2.......|
206 0010: 7f 07 53 54 52 45 41 4d 32 00 00 00 00 03 00 09 |..STREAM2.......|
207 0020: 05 09 04 0c 44 62 79 74 65 63 6f 75 6e 74 39 38 |....Dbytecount98|
207 0020: 05 09 04 0c 44 62 79 74 65 63 6f 75 6e 74 39 38 |....Dbytecount98|
208 0030: 37 37 35 66 69 6c 65 63 6f 75 6e 74 31 30 33 30 |775filecount1030|
208 0030: 37 37 35 66 69 6c 65 63 6f 75 6e 74 31 30 33 30 |775filecount1030|
209 0040: 72 65 71 75 69 72 65 6d 65 6e 74 73 64 6f 74 65 |requirementsdote|
209 0040: 72 65 71 75 69 72 65 6d 65 6e 74 73 64 6f 74 65 |requirementsdote|
210 0050: 6e 63 6f 64 65 25 32 43 66 6e 63 61 63 68 65 25 |ncode%2Cfncache%|
210 0050: 6e 63 6f 64 65 25 32 43 66 6e 63 61 63 68 65 25 |ncode%2Cfncache%|
211 0060: 32 43 67 65 6e 65 72 61 6c 64 65 6c 74 61 25 32 |2Cgeneraldelta%2|
211 0060: 32 43 67 65 6e 65 72 61 6c 64 65 6c 74 61 25 32 |2Cgeneraldelta%2|
212 0070: 43 72 65 76 6c 6f 67 76 31 25 32 43 73 70 61 72 |Crevlogv1%2Cspar|
212 0070: 43 72 65 76 6c 6f 67 76 31 25 32 43 73 70 61 72 |Crevlogv1%2Cspar|
213 0080: 73 65 72 65 76 6c 6f 67 25 32 43 73 74 6f 72 65 |serevlog%2Cstore|
213 0080: 73 65 72 65 76 6c 6f 67 25 32 43 73 74 6f 72 65 |serevlog%2Cstore|
214 0090: 00 00 80 00 73 08 42 64 61 74 61 2f 30 2e 69 00 |....s.Bdata/0.i.|
214 0090: 00 00 80 00 73 08 42 64 61 74 61 2f 30 2e 69 00 |....s.Bdata/0.i.|
215 00a0: 03 00 01 00 00 00 00 00 00 00 02 00 00 00 01 00 |................|
215 00a0: 03 00 01 00 00 00 00 00 00 00 02 00 00 00 01 00 |................|
216 00b0: 00 00 00 00 00 00 01 ff ff ff ff ff ff ff ff 80 |................|
216 00b0: 00 00 00 00 00 00 01 ff ff ff ff ff ff ff ff 80 |................|
217 00c0: 29 63 a0 49 d3 23 87 bf ce fe 56 67 92 67 2c 69 |)c.I.#....Vg.g,i|
217 00c0: 29 63 a0 49 d3 23 87 bf ce fe 56 67 92 67 2c 69 |)c.I.#....Vg.g,i|
218 00d0: d1 ec 39 00 00 00 00 00 00 00 00 00 00 00 00 75 |..9............u|
218 00d0: d1 ec 39 00 00 00 00 00 00 00 00 00 00 00 00 75 |..9............u|
219 00e0: 30 73 08 42 64 61 74 61 2f 31 2e 69 00 03 00 01 |0s.Bdata/1.i....|
219 00e0: 30 73 08 42 64 61 74 61 2f 31 2e 69 00 03 00 01 |0s.Bdata/1.i....|
220 00f0: 00 00 00 00 00 00 00 02 00 00 00 01 00 00 00 00 |................|
220 00f0: 00 00 00 00 00 00 00 02 00 00 00 01 00 00 00 00 |................|
221
221
222 --uncompressed is an alias to --stream
222 --uncompressed is an alias to --stream
223
223
224 #if stream-legacy
224 #if stream-legacy
225 $ hg clone --uncompressed -U http://localhost:$HGPORT clone1-uncompressed
225 $ hg clone --uncompressed -U http://localhost:$HGPORT clone1-uncompressed
226 streaming all changes
226 streaming all changes
227 1027 files to transfer, 96.3 KB of data
227 1027 files to transfer, 96.3 KB of data
228 transferred 96.3 KB in * seconds (*/sec) (glob)
228 transferred 96.3 KB in * seconds (*/sec) (glob)
229 searching for changes
229 searching for changes
230 no changes found
230 no changes found
231 #endif
231 #endif
232 #if stream-bundle2
232 #if stream-bundle2
233 $ hg clone --uncompressed -U http://localhost:$HGPORT clone1-uncompressed
233 $ hg clone --uncompressed -U http://localhost:$HGPORT clone1-uncompressed
234 streaming all changes
234 streaming all changes
235 1030 files to transfer, 96.5 KB of data
235 1030 files to transfer, 96.5 KB of data
236 transferred 96.5 KB in * seconds (* */sec) (glob)
236 transferred 96.5 KB in * seconds (* */sec) (glob)
237 #endif
237 #endif
238
238
239 Clone with background file closing enabled
239 Clone with background file closing enabled
240
240
241 #if stream-legacy
241 #if stream-legacy
242 $ hg --debug --config worker.backgroundclose=true --config worker.backgroundcloseminfilecount=1 clone --stream -U http://localhost:$HGPORT clone-background | grep -v adding
242 $ hg --debug --config worker.backgroundclose=true --config worker.backgroundcloseminfilecount=1 clone --stream -U http://localhost:$HGPORT clone-background | grep -v adding
243 using http://localhost:$HGPORT/
243 using http://localhost:$HGPORT/
244 sending capabilities command
244 sending capabilities command
245 sending branchmap command
245 sending branchmap command
246 streaming all changes
246 streaming all changes
247 sending stream_out command
247 sending stream_out command
248 1027 files to transfer, 96.3 KB of data
248 1027 files to transfer, 96.3 KB of data
249 starting 4 threads for background file closing
249 starting 4 threads for background file closing
250 updating the branch cache
250 updating the branch cache
251 transferred 96.3 KB in * seconds (*/sec) (glob)
251 transferred 96.3 KB in * seconds (*/sec) (glob)
252 query 1; heads
252 query 1; heads
253 sending batch command
253 sending batch command
254 searching for changes
254 searching for changes
255 all remote heads known locally
255 all remote heads known locally
256 no changes found
256 no changes found
257 sending getbundle command
257 sending getbundle command
258 bundle2-input-bundle: with-transaction
258 bundle2-input-bundle: with-transaction
259 bundle2-input-part: "listkeys" (params: 1 mandatory) supported
259 bundle2-input-part: "listkeys" (params: 1 mandatory) supported
260 bundle2-input-part: "phase-heads" supported
260 bundle2-input-part: "phase-heads" supported
261 bundle2-input-part: total payload size 24
261 bundle2-input-part: total payload size 24
262 bundle2-input-bundle: 1 parts total
262 bundle2-input-bundle: 2 parts total
263 checking for updated bookmarks
263 checking for updated bookmarks
264 (sent 5 HTTP requests and * bytes; received * bytes in responses) (glob)
264 (sent 5 HTTP requests and * bytes; received * bytes in responses) (glob)
265 #endif
265 #endif
266 #if stream-bundle2
266 #if stream-bundle2
267 $ hg --debug --config worker.backgroundclose=true --config worker.backgroundcloseminfilecount=1 clone --stream -U http://localhost:$HGPORT clone-background | grep -v adding
267 $ hg --debug --config worker.backgroundclose=true --config worker.backgroundcloseminfilecount=1 clone --stream -U http://localhost:$HGPORT clone-background | grep -v adding
268 using http://localhost:$HGPORT/
268 using http://localhost:$HGPORT/
269 sending capabilities command
269 sending capabilities command
270 query 1; heads
270 query 1; heads
271 sending batch command
271 sending batch command
272 streaming all changes
272 streaming all changes
273 sending getbundle command
273 sending getbundle command
274 bundle2-input-bundle: with-transaction
274 bundle2-input-bundle: with-transaction
275 bundle2-input-part: "stream2" (params: 3 mandatory) supported
275 bundle2-input-part: "stream2" (params: 3 mandatory) supported
276 applying stream bundle
276 applying stream bundle
277 1030 files to transfer, 96.5 KB of data
277 1030 files to transfer, 96.5 KB of data
278 starting 4 threads for background file closing
278 starting 4 threads for background file closing
279 starting 4 threads for background file closing
279 starting 4 threads for background file closing
280 updating the branch cache
280 updating the branch cache
281 transferred 96.5 KB in * seconds (* */sec) (glob)
281 transferred 96.5 KB in * seconds (* */sec) (glob)
282 bundle2-input-part: total payload size 112094
282 bundle2-input-part: total payload size 112094
283 bundle2-input-part: "listkeys" (params: 1 mandatory) supported
283 bundle2-input-part: "listkeys" (params: 1 mandatory) supported
284 bundle2-input-bundle: 1 parts total
284 bundle2-input-bundle: 2 parts total
285 checking for updated bookmarks
285 checking for updated bookmarks
286 (sent 3 HTTP requests and * bytes; received * bytes in responses) (glob)
286 (sent 3 HTTP requests and * bytes; received * bytes in responses) (glob)
287 #endif
287 #endif
288
288
289 Cannot stream clone when there are secret changesets
289 Cannot stream clone when there are secret changesets
290
290
291 $ hg -R server phase --force --secret -r tip
291 $ hg -R server phase --force --secret -r tip
292 $ hg clone --stream -U http://localhost:$HGPORT secret-denied
292 $ hg clone --stream -U http://localhost:$HGPORT secret-denied
293 warning: stream clone requested but server has them disabled
293 warning: stream clone requested but server has them disabled
294 requesting all changes
294 requesting all changes
295 adding changesets
295 adding changesets
296 adding manifests
296 adding manifests
297 adding file changes
297 adding file changes
298 added 1 changesets with 1 changes to 1 files
298 added 1 changesets with 1 changes to 1 files
299 new changesets 96ee1d7354c4
299 new changesets 96ee1d7354c4
300
300
301 $ killdaemons.py
301 $ killdaemons.py
302
302
303 Streaming of secrets can be overridden by server config
303 Streaming of secrets can be overridden by server config
304
304
305 $ cd server
305 $ cd server
306 $ hg serve --config server.uncompressedallowsecret=true -p $HGPORT -d --pid-file=hg.pid
306 $ hg serve --config server.uncompressedallowsecret=true -p $HGPORT -d --pid-file=hg.pid
307 $ cat hg.pid > $DAEMON_PIDS
307 $ cat hg.pid > $DAEMON_PIDS
308 $ cd ..
308 $ cd ..
309
309
310 #if stream-legacy
310 #if stream-legacy
311 $ hg clone --stream -U http://localhost:$HGPORT secret-allowed
311 $ hg clone --stream -U http://localhost:$HGPORT secret-allowed
312 streaming all changes
312 streaming all changes
313 1027 files to transfer, 96.3 KB of data
313 1027 files to transfer, 96.3 KB of data
314 transferred 96.3 KB in * seconds (*/sec) (glob)
314 transferred 96.3 KB in * seconds (*/sec) (glob)
315 searching for changes
315 searching for changes
316 no changes found
316 no changes found
317 #endif
317 #endif
318 #if stream-bundle2
318 #if stream-bundle2
319 $ hg clone --stream -U http://localhost:$HGPORT secret-allowed
319 $ hg clone --stream -U http://localhost:$HGPORT secret-allowed
320 streaming all changes
320 streaming all changes
321 1030 files to transfer, 96.5 KB of data
321 1030 files to transfer, 96.5 KB of data
322 transferred 96.5 KB in * seconds (* */sec) (glob)
322 transferred 96.5 KB in * seconds (* */sec) (glob)
323 #endif
323 #endif
324
324
325 $ killdaemons.py
325 $ killdaemons.py
326
326
327 Verify interaction between preferuncompressed and secret presence
327 Verify interaction between preferuncompressed and secret presence
328
328
329 $ cd server
329 $ cd server
330 $ hg serve --config server.preferuncompressed=true -p $HGPORT -d --pid-file=hg.pid
330 $ hg serve --config server.preferuncompressed=true -p $HGPORT -d --pid-file=hg.pid
331 $ cat hg.pid > $DAEMON_PIDS
331 $ cat hg.pid > $DAEMON_PIDS
332 $ cd ..
332 $ cd ..
333
333
334 $ hg clone -U http://localhost:$HGPORT preferuncompressed-secret
334 $ hg clone -U http://localhost:$HGPORT preferuncompressed-secret
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 1 changesets with 1 changes to 1 files
339 added 1 changesets with 1 changes to 1 files
340 new changesets 96ee1d7354c4
340 new changesets 96ee1d7354c4
341
341
342 $ killdaemons.py
342 $ killdaemons.py
343
343
344 Clone not allowed when full bundles disabled and can't serve secrets
344 Clone not allowed when full bundles disabled and can't serve secrets
345
345
346 $ cd server
346 $ cd server
347 $ hg serve --config server.disablefullbundle=true -p $HGPORT -d --pid-file=hg.pid
347 $ hg serve --config server.disablefullbundle=true -p $HGPORT -d --pid-file=hg.pid
348 $ cat hg.pid > $DAEMON_PIDS
348 $ cat hg.pid > $DAEMON_PIDS
349 $ cd ..
349 $ cd ..
350
350
351 $ hg clone --stream http://localhost:$HGPORT secret-full-disabled
351 $ hg clone --stream http://localhost:$HGPORT secret-full-disabled
352 warning: stream clone requested but server has them disabled
352 warning: stream clone requested but server has them disabled
353 requesting all changes
353 requesting all changes
354 remote: abort: server has pull-based clones disabled
354 remote: abort: server has pull-based clones disabled
355 abort: pull failed on remote
355 abort: pull failed on remote
356 (remove --pull if specified or upgrade Mercurial)
356 (remove --pull if specified or upgrade Mercurial)
357 [255]
357 [255]
358
358
359 Local stream clone with secrets involved
359 Local stream clone with secrets involved
360 (This is just a test over behavior: if you have access to the repo's files,
360 (This is just a test over behavior: if you have access to the repo's files,
361 there is no security so it isn't important to prevent a clone here.)
361 there is no security so it isn't important to prevent a clone here.)
362
362
363 $ hg clone -U --stream server local-secret
363 $ hg clone -U --stream server local-secret
364 warning: stream clone requested but server has them disabled
364 warning: stream clone requested but server has them disabled
365 requesting all changes
365 requesting all changes
366 adding changesets
366 adding changesets
367 adding manifests
367 adding manifests
368 adding file changes
368 adding file changes
369 added 1 changesets with 1 changes to 1 files
369 added 1 changesets with 1 changes to 1 files
370 new changesets 96ee1d7354c4
370 new changesets 96ee1d7354c4
371
371
372 Stream clone while repo is changing:
372 Stream clone while repo is changing:
373
373
374 $ mkdir changing
374 $ mkdir changing
375 $ cd changing
375 $ cd changing
376
376
377 extension for delaying the server process so we reliably can modify the repo
377 extension for delaying the server process so we reliably can modify the repo
378 while cloning
378 while cloning
379
379
380 $ cat > delayer.py <<EOF
380 $ cat > delayer.py <<EOF
381 > import time
381 > import time
382 > from mercurial import extensions, vfs
382 > from mercurial import extensions, vfs
383 > def __call__(orig, self, path, *args, **kwargs):
383 > def __call__(orig, self, path, *args, **kwargs):
384 > if path == 'data/f1.i':
384 > if path == 'data/f1.i':
385 > time.sleep(2)
385 > time.sleep(2)
386 > return orig(self, path, *args, **kwargs)
386 > return orig(self, path, *args, **kwargs)
387 > extensions.wrapfunction(vfs.vfs, '__call__', __call__)
387 > extensions.wrapfunction(vfs.vfs, '__call__', __call__)
388 > EOF
388 > EOF
389
389
390 prepare repo with small and big file to cover both code paths in emitrevlogdata
390 prepare repo with small and big file to cover both code paths in emitrevlogdata
391
391
392 $ hg init repo
392 $ hg init repo
393 $ touch repo/f1
393 $ touch repo/f1
394 $ $TESTDIR/seq.py 50000 > repo/f2
394 $ $TESTDIR/seq.py 50000 > repo/f2
395 $ hg -R repo ci -Aqm "0"
395 $ hg -R repo ci -Aqm "0"
396 $ hg serve -R repo -p $HGPORT1 -d --pid-file=hg.pid --config extensions.delayer=delayer.py
396 $ hg serve -R repo -p $HGPORT1 -d --pid-file=hg.pid --config extensions.delayer=delayer.py
397 $ cat hg.pid >> $DAEMON_PIDS
397 $ cat hg.pid >> $DAEMON_PIDS
398
398
399 clone while modifying the repo between stating file with write lock and
399 clone while modifying the repo between stating file with write lock and
400 actually serving file content
400 actually serving file content
401
401
402 $ hg clone -q --stream -U http://localhost:$HGPORT1 clone &
402 $ hg clone -q --stream -U http://localhost:$HGPORT1 clone &
403 $ sleep 1
403 $ sleep 1
404 $ echo >> repo/f1
404 $ echo >> repo/f1
405 $ echo >> repo/f2
405 $ echo >> repo/f2
406 $ hg -R repo ci -m "1"
406 $ hg -R repo ci -m "1"
407 $ wait
407 $ wait
408 $ hg -R clone id
408 $ hg -R clone id
409 000000000000
409 000000000000
410 $ cd ..
410 $ cd ..
411
411
412 Stream repository with bookmarks
412 Stream repository with bookmarks
413 --------------------------------
413 --------------------------------
414
414
415 (revert introduction of secret changeset)
415 (revert introduction of secret changeset)
416
416
417 $ hg -R server phase --draft 'secret()'
417 $ hg -R server phase --draft 'secret()'
418
418
419 add a bookmark
419 add a bookmark
420
420
421 $ hg -R server bookmark -r tip some-bookmark
421 $ hg -R server bookmark -r tip some-bookmark
422
422
423 clone it
423 clone it
424
424
425 #if stream-legacy
425 #if stream-legacy
426 $ hg clone --stream http://localhost:$HGPORT with-bookmarks
426 $ hg clone --stream http://localhost:$HGPORT with-bookmarks
427 streaming all changes
427 streaming all changes
428 1027 files to transfer, 96.3 KB of data
428 1027 files to transfer, 96.3 KB of data
429 transferred 96.3 KB in * seconds (*) (glob)
429 transferred 96.3 KB in * seconds (*) (glob)
430 searching for changes
430 searching for changes
431 no changes found
431 no changes found
432 updating to branch default
432 updating to branch default
433 1025 files updated, 0 files merged, 0 files removed, 0 files unresolved
433 1025 files updated, 0 files merged, 0 files removed, 0 files unresolved
434 #endif
434 #endif
435 #if stream-bundle2
435 #if stream-bundle2
436 $ hg clone --stream http://localhost:$HGPORT with-bookmarks
436 $ hg clone --stream http://localhost:$HGPORT with-bookmarks
437 streaming all changes
437 streaming all changes
438 1033 files to transfer, 96.6 KB of data
438 1033 files to transfer, 96.6 KB of data
439 transferred 96.6 KB in * seconds (* */sec) (glob)
439 transferred 96.6 KB in * seconds (* */sec) (glob)
440 updating to branch default
440 updating to branch default
441 1025 files updated, 0 files merged, 0 files removed, 0 files unresolved
441 1025 files updated, 0 files merged, 0 files removed, 0 files unresolved
442 #endif
442 #endif
443 $ hg -R with-bookmarks bookmarks
443 $ hg -R with-bookmarks bookmarks
444 some-bookmark 1:c17445101a72
444 some-bookmark 1:c17445101a72
445
445
446 Stream repository with phases
446 Stream repository with phases
447 -----------------------------
447 -----------------------------
448
448
449 Clone as publishing
449 Clone as publishing
450
450
451 $ hg -R server phase -r 'all()'
451 $ hg -R server phase -r 'all()'
452 0: draft
452 0: draft
453 1: draft
453 1: draft
454
454
455 #if stream-legacy
455 #if stream-legacy
456 $ hg clone --stream http://localhost:$HGPORT phase-publish
456 $ hg clone --stream http://localhost:$HGPORT phase-publish
457 streaming all changes
457 streaming all changes
458 1027 files to transfer, 96.3 KB of data
458 1027 files to transfer, 96.3 KB of data
459 transferred 96.3 KB in * seconds (*) (glob)
459 transferred 96.3 KB in * seconds (*) (glob)
460 searching for changes
460 searching for changes
461 no changes found
461 no changes found
462 updating to branch default
462 updating to branch default
463 1025 files updated, 0 files merged, 0 files removed, 0 files unresolved
463 1025 files updated, 0 files merged, 0 files removed, 0 files unresolved
464 #endif
464 #endif
465 #if stream-bundle2
465 #if stream-bundle2
466 $ hg clone --stream http://localhost:$HGPORT phase-publish
466 $ hg clone --stream http://localhost:$HGPORT phase-publish
467 streaming all changes
467 streaming all changes
468 1033 files to transfer, 96.6 KB of data
468 1033 files to transfer, 96.6 KB of data
469 transferred 96.6 KB in * seconds (* */sec) (glob)
469 transferred 96.6 KB in * seconds (* */sec) (glob)
470 updating to branch default
470 updating to branch default
471 1025 files updated, 0 files merged, 0 files removed, 0 files unresolved
471 1025 files updated, 0 files merged, 0 files removed, 0 files unresolved
472 #endif
472 #endif
473 $ hg -R phase-publish phase -r 'all()'
473 $ hg -R phase-publish phase -r 'all()'
474 0: public
474 0: public
475 1: public
475 1: public
476
476
477 Clone as non publishing
477 Clone as non publishing
478
478
479 $ cat << EOF >> server/.hg/hgrc
479 $ cat << EOF >> server/.hg/hgrc
480 > [phases]
480 > [phases]
481 > publish = False
481 > publish = False
482 > EOF
482 > EOF
483 $ killdaemons.py
483 $ killdaemons.py
484 $ hg -R server serve -p $HGPORT -d --pid-file=hg.pid
484 $ hg -R server serve -p $HGPORT -d --pid-file=hg.pid
485 $ cat hg.pid > $DAEMON_PIDS
485 $ cat hg.pid > $DAEMON_PIDS
486
486
487 #if stream-legacy
487 #if stream-legacy
488
488
489 With v1 of the stream protocol, changeset are always cloned as public. It make
489 With v1 of the stream protocol, changeset are always cloned as public. It make
490 stream v1 unsuitable for non-publishing repository.
490 stream v1 unsuitable for non-publishing repository.
491
491
492 $ hg clone --stream http://localhost:$HGPORT phase-no-publish
492 $ hg clone --stream http://localhost:$HGPORT phase-no-publish
493 streaming all changes
493 streaming all changes
494 1027 files to transfer, 96.3 KB of data
494 1027 files to transfer, 96.3 KB of data
495 transferred 96.3 KB in * seconds (*) (glob)
495 transferred 96.3 KB in * seconds (*) (glob)
496 searching for changes
496 searching for changes
497 no changes found
497 no changes found
498 updating to branch default
498 updating to branch default
499 1025 files updated, 0 files merged, 0 files removed, 0 files unresolved
499 1025 files updated, 0 files merged, 0 files removed, 0 files unresolved
500 $ hg -R phase-no-publish phase -r 'all()'
500 $ hg -R phase-no-publish phase -r 'all()'
501 0: public
501 0: public
502 1: public
502 1: public
503 #endif
503 #endif
504 #if stream-bundle2
504 #if stream-bundle2
505 $ hg clone --stream http://localhost:$HGPORT phase-no-publish
505 $ hg clone --stream http://localhost:$HGPORT phase-no-publish
506 streaming all changes
506 streaming all changes
507 1034 files to transfer, 96.7 KB of data
507 1034 files to transfer, 96.7 KB of data
508 transferred 96.7 KB in * seconds (* */sec) (glob)
508 transferred 96.7 KB in * seconds (* */sec) (glob)
509 updating to branch default
509 updating to branch default
510 1025 files updated, 0 files merged, 0 files removed, 0 files unresolved
510 1025 files updated, 0 files merged, 0 files removed, 0 files unresolved
511 $ hg -R phase-no-publish phase -r 'all()'
511 $ hg -R phase-no-publish phase -r 'all()'
512 0: draft
512 0: draft
513 1: draft
513 1: draft
514 #endif
514 #endif
515
515
516 $ killdaemons.py
516 $ killdaemons.py
517
517
518 #if stream-legacy
518 #if stream-legacy
519
519
520 With v1 of the stream protocol, changeset are always cloned as public. There's
520 With v1 of the stream protocol, changeset are always cloned as public. There's
521 no obsolescence markers exchange in stream v1.
521 no obsolescence markers exchange in stream v1.
522
522
523 #endif
523 #endif
524 #if stream-bundle2
524 #if stream-bundle2
525
525
526 Stream repository with obsolescence
526 Stream repository with obsolescence
527 -----------------------------------
527 -----------------------------------
528
528
529 Clone non-publishing with obsolescence
529 Clone non-publishing with obsolescence
530
530
531 $ cat >> $HGRCPATH << EOF
531 $ cat >> $HGRCPATH << EOF
532 > [experimental]
532 > [experimental]
533 > evolution=all
533 > evolution=all
534 > EOF
534 > EOF
535
535
536 $ cd server
536 $ cd server
537 $ echo foo > foo
537 $ echo foo > foo
538 $ hg -q commit -m 'about to be pruned'
538 $ hg -q commit -m 'about to be pruned'
539 $ hg debugobsolete `hg log -r . -T '{node}'` -d '0 0' -u test --record-parents
539 $ hg debugobsolete `hg log -r . -T '{node}'` -d '0 0' -u test --record-parents
540 1 new obsolescence markers
540 1 new obsolescence markers
541 obsoleted 1 changesets
541 obsoleted 1 changesets
542 $ hg up null -q
542 $ hg up null -q
543 $ hg log -T '{rev}: {phase}\n'
543 $ hg log -T '{rev}: {phase}\n'
544 1: draft
544 1: draft
545 0: draft
545 0: draft
546 $ hg serve -p $HGPORT -d --pid-file=hg.pid
546 $ hg serve -p $HGPORT -d --pid-file=hg.pid
547 $ cat hg.pid > $DAEMON_PIDS
547 $ cat hg.pid > $DAEMON_PIDS
548 $ cd ..
548 $ cd ..
549
549
550 $ hg clone -U --stream http://localhost:$HGPORT with-obsolescence
550 $ hg clone -U --stream http://localhost:$HGPORT with-obsolescence
551 streaming all changes
551 streaming all changes
552 1035 files to transfer, 97.1 KB of data
552 1035 files to transfer, 97.1 KB of data
553 transferred 97.1 KB in * seconds (* */sec) (glob)
553 transferred 97.1 KB in * seconds (* */sec) (glob)
554 $ hg -R with-obsolescence log -T '{rev}: {phase}\n'
554 $ hg -R with-obsolescence log -T '{rev}: {phase}\n'
555 1: draft
555 1: draft
556 0: draft
556 0: draft
557 $ hg debugobsolete -R with-obsolescence
557 $ hg debugobsolete -R with-obsolescence
558 50382b884f66690b7045cac93a540cba4d4c906f 0 {c17445101a72edac06facd130d14808dfbd5c7c2} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
558 50382b884f66690b7045cac93a540cba4d4c906f 0 {c17445101a72edac06facd130d14808dfbd5c7c2} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
559
559
560 $ hg clone -U --stream --config experimental.evolution=0 http://localhost:$HGPORT with-obsolescence-no-evolution
560 $ hg clone -U --stream --config experimental.evolution=0 http://localhost:$HGPORT with-obsolescence-no-evolution
561 streaming all changes
561 streaming all changes
562 remote: abort: server has obsolescence markers, but client cannot receive them via stream clone
562 remote: abort: server has obsolescence markers, but client cannot receive them via stream clone
563 abort: pull failed on remote
563 abort: pull failed on remote
564 [255]
564 [255]
565
565
566 $ killdaemons.py
566 $ killdaemons.py
567
567
568 #endif
568 #endif
@@ -1,584 +1,584 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 [255]
170 [255]
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 --config extensions.getpass=get_pass.py http://user@localhost:$HGPORT2/
195 $ hg id --config ui.interactive=true --config extensions.getpass=get_pass.py http://user@localhost:$HGPORT2/
196 http authorization required for http://localhost:$HGPORT2/
196 http authorization required for http://localhost:$HGPORT2/
197 realm: mercurial
197 realm: mercurial
198 user: user
198 user: user
199 password: 5fed3813f7f5
199 password: 5fed3813f7f5
200 $ hg id http://user:pass@localhost:$HGPORT2/
200 $ hg id http://user:pass@localhost:$HGPORT2/
201 5fed3813f7f5
201 5fed3813f7f5
202 $ echo '[auth]' >> .hg/hgrc
202 $ echo '[auth]' >> .hg/hgrc
203 $ echo 'l.schemes=http' >> .hg/hgrc
203 $ echo 'l.schemes=http' >> .hg/hgrc
204 $ echo 'l.prefix=lo' >> .hg/hgrc
204 $ echo 'l.prefix=lo' >> .hg/hgrc
205 $ echo 'l.username=user' >> .hg/hgrc
205 $ echo 'l.username=user' >> .hg/hgrc
206 $ echo 'l.password=pass' >> .hg/hgrc
206 $ echo 'l.password=pass' >> .hg/hgrc
207 $ hg id http://localhost:$HGPORT2/
207 $ hg id http://localhost:$HGPORT2/
208 5fed3813f7f5
208 5fed3813f7f5
209 $ hg id http://localhost:$HGPORT2/
209 $ hg id http://localhost:$HGPORT2/
210 5fed3813f7f5
210 5fed3813f7f5
211 $ hg id http://user@localhost:$HGPORT2/
211 $ hg id http://user@localhost:$HGPORT2/
212 5fed3813f7f5
212 5fed3813f7f5
213
213
214 $ cat > use_digests.py << EOF
214 $ cat > use_digests.py << EOF
215 > from mercurial import (
215 > from mercurial import (
216 > exthelper,
216 > exthelper,
217 > url,
217 > url,
218 > )
218 > )
219 >
219 >
220 > eh = exthelper.exthelper()
220 > eh = exthelper.exthelper()
221 > uisetup = eh.finaluisetup
221 > uisetup = eh.finaluisetup
222 >
222 >
223 > @eh.wrapfunction(url, 'opener')
223 > @eh.wrapfunction(url, 'opener')
224 > def urlopener(orig, *args, **kwargs):
224 > def urlopener(orig, *args, **kwargs):
225 > opener = orig(*args, **kwargs)
225 > opener = orig(*args, **kwargs)
226 > opener.addheaders.append((r'X-HgTest-AuthType', r'Digest'))
226 > opener.addheaders.append((r'X-HgTest-AuthType', r'Digest'))
227 > return opener
227 > return opener
228 > EOF
228 > EOF
229
229
230 $ hg id http://localhost:$HGPORT2/ --config extensions.x=use_digests.py
230 $ hg id http://localhost:$HGPORT2/ --config extensions.x=use_digests.py
231 5fed3813f7f5
231 5fed3813f7f5
232
232
233 #if no-reposimplestore
233 #if no-reposimplestore
234 $ hg clone http://user:pass@localhost:$HGPORT2/ dest 2>&1
234 $ hg clone http://user:pass@localhost:$HGPORT2/ dest 2>&1
235 streaming all changes
235 streaming all changes
236 10 files to transfer, 1.01 KB of data
236 10 files to transfer, 1.01 KB of data
237 transferred * KB in * seconds (*/sec) (glob)
237 transferred * KB in * seconds (*/sec) (glob)
238 updating to branch default
238 updating to branch default
239 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
239 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
240 #endif
240 #endif
241
241
242 --pull should override server's preferuncompressed
242 --pull should override server's preferuncompressed
243 $ hg clone --pull http://user:pass@localhost:$HGPORT2/ dest-pull 2>&1
243 $ hg clone --pull http://user:pass@localhost:$HGPORT2/ dest-pull 2>&1
244 requesting all changes
244 requesting all changes
245 adding changesets
245 adding changesets
246 adding manifests
246 adding manifests
247 adding file changes
247 adding file changes
248 added 2 changesets with 5 changes to 5 files
248 added 2 changesets with 5 changes to 5 files
249 new changesets 8b6053c928fe:5fed3813f7f5
249 new changesets 8b6053c928fe:5fed3813f7f5
250 updating to branch default
250 updating to branch default
251 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
251 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
252
252
253 $ hg id http://user2@localhost:$HGPORT2/
253 $ hg id http://user2@localhost:$HGPORT2/
254 abort: http authorization required for http://localhost:$HGPORT2/
254 abort: http authorization required for http://localhost:$HGPORT2/
255 [255]
255 [255]
256 $ hg id http://user:pass2@localhost:$HGPORT2/
256 $ hg id http://user:pass2@localhost:$HGPORT2/
257 abort: HTTP Error 403: no
257 abort: HTTP Error 403: no
258 [255]
258 [255]
259
259
260 $ hg -R dest-pull tag -r tip top
260 $ hg -R dest-pull tag -r tip top
261 $ hg -R dest-pull push http://user:pass@localhost:$HGPORT2/
261 $ hg -R dest-pull push http://user:pass@localhost:$HGPORT2/
262 pushing to http://user:***@localhost:$HGPORT2/
262 pushing to http://user:***@localhost:$HGPORT2/
263 searching for changes
263 searching for changes
264 remote: adding changesets
264 remote: adding changesets
265 remote: adding manifests
265 remote: adding manifests
266 remote: adding file changes
266 remote: adding file changes
267 remote: added 1 changesets with 1 changes to 1 files
267 remote: added 1 changesets with 1 changes to 1 files
268 $ hg rollback -q
268 $ hg rollback -q
269 $ hg -R dest-pull push http://user:pass@localhost:$HGPORT2/ --debug --config devel.debug.peer-request=yes
269 $ hg -R dest-pull push http://user:pass@localhost:$HGPORT2/ --debug --config devel.debug.peer-request=yes
270 pushing to http://user:***@localhost:$HGPORT2/
270 pushing to http://user:***@localhost:$HGPORT2/
271 using http://localhost:$HGPORT2/
271 using http://localhost:$HGPORT2/
272 http auth: user user, password ****
272 http auth: user user, password ****
273 sending capabilities command
273 sending capabilities command
274 devel-peer-request: GET http://localhost:$HGPORT2/?cmd=capabilities
274 devel-peer-request: GET http://localhost:$HGPORT2/?cmd=capabilities
275 http auth: user user, password ****
275 http auth: user user, password ****
276 devel-peer-request: finished in *.???? seconds (200) (glob)
276 devel-peer-request: finished in *.???? seconds (200) (glob)
277 query 1; heads
277 query 1; heads
278 devel-peer-request: batched-content
278 devel-peer-request: batched-content
279 devel-peer-request: - heads (0 arguments)
279 devel-peer-request: - heads (0 arguments)
280 devel-peer-request: - known (1 arguments)
280 devel-peer-request: - known (1 arguments)
281 sending batch command
281 sending batch command
282 devel-peer-request: GET http://localhost:$HGPORT2/?cmd=batch
282 devel-peer-request: GET http://localhost:$HGPORT2/?cmd=batch
283 devel-peer-request: Vary X-HgArg-1,X-HgProto-1
283 devel-peer-request: Vary X-HgArg-1,X-HgProto-1
284 devel-peer-request: X-hgproto-1 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
284 devel-peer-request: X-hgproto-1 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
285 devel-peer-request: 68 bytes of commands arguments in headers
285 devel-peer-request: 68 bytes of commands arguments in headers
286 devel-peer-request: finished in *.???? seconds (200) (glob)
286 devel-peer-request: finished in *.???? seconds (200) (glob)
287 searching for changes
287 searching for changes
288 all remote heads known locally
288 all remote heads known locally
289 preparing listkeys for "phases"
289 preparing listkeys for "phases"
290 sending listkeys command
290 sending listkeys command
291 devel-peer-request: GET http://localhost:$HGPORT2/?cmd=listkeys
291 devel-peer-request: GET http://localhost:$HGPORT2/?cmd=listkeys
292 devel-peer-request: Vary X-HgArg-1,X-HgProto-1
292 devel-peer-request: Vary X-HgArg-1,X-HgProto-1
293 devel-peer-request: X-hgproto-1 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
293 devel-peer-request: X-hgproto-1 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
294 devel-peer-request: 16 bytes of commands arguments in headers
294 devel-peer-request: 16 bytes of commands arguments in headers
295 devel-peer-request: finished in *.???? seconds (200) (glob)
295 devel-peer-request: finished in *.???? seconds (200) (glob)
296 received listkey for "phases": 58 bytes
296 received listkey for "phases": 58 bytes
297 checking for updated bookmarks
297 checking for updated bookmarks
298 preparing listkeys for "bookmarks"
298 preparing listkeys for "bookmarks"
299 sending listkeys command
299 sending listkeys command
300 devel-peer-request: GET http://localhost:$HGPORT2/?cmd=listkeys
300 devel-peer-request: GET http://localhost:$HGPORT2/?cmd=listkeys
301 devel-peer-request: Vary X-HgArg-1,X-HgProto-1
301 devel-peer-request: Vary X-HgArg-1,X-HgProto-1
302 devel-peer-request: X-hgproto-1 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
302 devel-peer-request: X-hgproto-1 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
303 devel-peer-request: 19 bytes of commands arguments in headers
303 devel-peer-request: 19 bytes of commands arguments in headers
304 devel-peer-request: finished in *.???? seconds (200) (glob)
304 devel-peer-request: finished in *.???? seconds (200) (glob)
305 received listkey for "bookmarks": 0 bytes
305 received listkey for "bookmarks": 0 bytes
306 sending branchmap command
306 sending branchmap command
307 devel-peer-request: GET http://localhost:$HGPORT2/?cmd=branchmap
307 devel-peer-request: GET http://localhost:$HGPORT2/?cmd=branchmap
308 devel-peer-request: Vary X-HgProto-1
308 devel-peer-request: Vary X-HgProto-1
309 devel-peer-request: X-hgproto-1 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
309 devel-peer-request: X-hgproto-1 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
310 devel-peer-request: finished in *.???? seconds (200) (glob)
310 devel-peer-request: finished in *.???? seconds (200) (glob)
311 preparing listkeys for "bookmarks"
311 preparing listkeys for "bookmarks"
312 sending listkeys command
312 sending listkeys command
313 devel-peer-request: GET http://localhost:$HGPORT2/?cmd=listkeys
313 devel-peer-request: GET http://localhost:$HGPORT2/?cmd=listkeys
314 devel-peer-request: Vary X-HgArg-1,X-HgProto-1
314 devel-peer-request: Vary X-HgArg-1,X-HgProto-1
315 devel-peer-request: X-hgproto-1 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
315 devel-peer-request: X-hgproto-1 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
316 devel-peer-request: 19 bytes of commands arguments in headers
316 devel-peer-request: 19 bytes of commands arguments in headers
317 devel-peer-request: finished in *.???? seconds (200) (glob)
317 devel-peer-request: finished in *.???? seconds (200) (glob)
318 received listkey for "bookmarks": 0 bytes
318 received listkey for "bookmarks": 0 bytes
319 1 changesets found
319 1 changesets found
320 list of changesets:
320 list of changesets:
321 7f4e523d01f2cc3765ac8934da3d14db775ff872
321 7f4e523d01f2cc3765ac8934da3d14db775ff872
322 bundle2-output-bundle: "HG20", 5 parts total
322 bundle2-output-bundle: "HG20", 5 parts total
323 bundle2-output-part: "replycaps" 205 bytes payload
323 bundle2-output-part: "replycaps" 205 bytes payload
324 bundle2-output-part: "check:phases" 24 bytes payload
324 bundle2-output-part: "check:phases" 24 bytes payload
325 bundle2-output-part: "check:heads" streamed payload
325 bundle2-output-part: "check:heads" streamed payload
326 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
326 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
327 bundle2-output-part: "phase-heads" 24 bytes payload
327 bundle2-output-part: "phase-heads" 24 bytes payload
328 sending unbundle command
328 sending unbundle command
329 sending 1013 bytes
329 sending 1013 bytes
330 devel-peer-request: POST http://localhost:$HGPORT2/?cmd=unbundle
330 devel-peer-request: POST http://localhost:$HGPORT2/?cmd=unbundle
331 devel-peer-request: Content-length 1013
331 devel-peer-request: Content-length 1013
332 devel-peer-request: Content-type application/mercurial-0.1
332 devel-peer-request: Content-type application/mercurial-0.1
333 devel-peer-request: Vary X-HgArg-1,X-HgProto-1
333 devel-peer-request: Vary X-HgArg-1,X-HgProto-1
334 devel-peer-request: X-hgproto-1 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
334 devel-peer-request: X-hgproto-1 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
335 devel-peer-request: 16 bytes of commands arguments in headers
335 devel-peer-request: 16 bytes of commands arguments in headers
336 devel-peer-request: 1013 bytes of data
336 devel-peer-request: 1013 bytes of data
337 devel-peer-request: finished in *.???? seconds (200) (glob)
337 devel-peer-request: finished in *.???? seconds (200) (glob)
338 bundle2-input-bundle: no-transaction
338 bundle2-input-bundle: no-transaction
339 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
339 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
340 bundle2-input-part: "output" (advisory) (params: 0 advisory) supported
340 bundle2-input-part: "output" (advisory) (params: 0 advisory) supported
341 bundle2-input-part: total payload size 55
341 bundle2-input-part: total payload size 55
342 remote: adding changesets
342 remote: adding changesets
343 remote: adding manifests
343 remote: adding manifests
344 remote: adding file changes
344 remote: adding file changes
345 bundle2-input-part: "output" (advisory) supported
345 bundle2-input-part: "output" (advisory) supported
346 bundle2-input-part: total payload size 45
346 bundle2-input-part: total payload size 45
347 remote: added 1 changesets with 1 changes to 1 files
347 remote: added 1 changesets with 1 changes to 1 files
348 bundle2-input-bundle: 2 parts total
348 bundle2-input-bundle: 3 parts total
349 preparing listkeys for "phases"
349 preparing listkeys for "phases"
350 sending listkeys command
350 sending listkeys command
351 devel-peer-request: GET http://localhost:$HGPORT2/?cmd=listkeys
351 devel-peer-request: GET http://localhost:$HGPORT2/?cmd=listkeys
352 devel-peer-request: Vary X-HgArg-1,X-HgProto-1
352 devel-peer-request: Vary X-HgArg-1,X-HgProto-1
353 devel-peer-request: X-hgproto-1 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
353 devel-peer-request: X-hgproto-1 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
354 devel-peer-request: 16 bytes of commands arguments in headers
354 devel-peer-request: 16 bytes of commands arguments in headers
355 devel-peer-request: finished in *.???? seconds (200) (glob)
355 devel-peer-request: finished in *.???? seconds (200) (glob)
356 received listkey for "phases": 15 bytes
356 received listkey for "phases": 15 bytes
357 $ hg rollback -q
357 $ hg rollback -q
358
358
359 $ sed 's/.*] "/"/' < ../access.log
359 $ sed 's/.*] "/"/' < ../access.log
360 "GET /?cmd=capabilities HTTP/1.1" 401 -
360 "GET /?cmd=capabilities HTTP/1.1" 401 -
361 "GET /?cmd=capabilities HTTP/1.1" 401 -
361 "GET /?cmd=capabilities HTTP/1.1" 401 -
362 "GET /?cmd=capabilities HTTP/1.1" 401 -
362 "GET /?cmd=capabilities HTTP/1.1" 401 -
363 "GET /?cmd=capabilities HTTP/1.1" 200 -
363 "GET /?cmd=capabilities HTTP/1.1" 200 -
364 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
364 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
365 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
365 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
366 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
366 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
367 "GET /?cmd=capabilities HTTP/1.1" 401 -
367 "GET /?cmd=capabilities HTTP/1.1" 401 -
368 "GET /?cmd=capabilities HTTP/1.1" 200 -
368 "GET /?cmd=capabilities HTTP/1.1" 200 -
369 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
369 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
370 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
370 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
371 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
371 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
372 "GET /?cmd=capabilities HTTP/1.1" 401 -
372 "GET /?cmd=capabilities HTTP/1.1" 401 -
373 "GET /?cmd=capabilities HTTP/1.1" 200 -
373 "GET /?cmd=capabilities HTTP/1.1" 200 -
374 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
374 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
375 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
375 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
376 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
376 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
377 "GET /?cmd=capabilities HTTP/1.1" 401 -
377 "GET /?cmd=capabilities HTTP/1.1" 401 -
378 "GET /?cmd=capabilities HTTP/1.1" 200 -
378 "GET /?cmd=capabilities HTTP/1.1" 200 -
379 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
379 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
380 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
380 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
381 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
381 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
382 "GET /?cmd=capabilities HTTP/1.1" 401 -
382 "GET /?cmd=capabilities HTTP/1.1" 401 -
383 "GET /?cmd=capabilities HTTP/1.1" 200 -
383 "GET /?cmd=capabilities HTTP/1.1" 200 -
384 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
384 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
385 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
385 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
386 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
386 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
387 "GET /?cmd=capabilities HTTP/1.1" 401 - x-hgtest-authtype:Digest
387 "GET /?cmd=capabilities HTTP/1.1" 401 - x-hgtest-authtype:Digest
388 "GET /?cmd=capabilities HTTP/1.1" 200 - x-hgtest-authtype:Digest
388 "GET /?cmd=capabilities HTTP/1.1" 200 - x-hgtest-authtype:Digest
389 "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
389 "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
390 "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
390 "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
391 "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
391 "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
392 "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
392 "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
393 "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
393 "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
394 "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
394 "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
395 "GET /?cmd=capabilities HTTP/1.1" 401 - (no-reposimplestore !)
395 "GET /?cmd=capabilities HTTP/1.1" 401 - (no-reposimplestore !)
396 "GET /?cmd=capabilities HTTP/1.1" 200 - (no-reposimplestore !)
396 "GET /?cmd=capabilities HTTP/1.1" 200 - (no-reposimplestore !)
397 "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 !)
397 "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 !)
398 "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 !)
398 "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 !)
399 "GET /?cmd=capabilities HTTP/1.1" 401 - (no-reposimplestore !)
399 "GET /?cmd=capabilities HTTP/1.1" 401 - (no-reposimplestore !)
400 "GET /?cmd=capabilities HTTP/1.1" 200 - (no-reposimplestore !)
400 "GET /?cmd=capabilities HTTP/1.1" 200 - (no-reposimplestore !)
401 "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
401 "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
402 "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
402 "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
403 "GET /?cmd=capabilities HTTP/1.1" 401 -
403 "GET /?cmd=capabilities HTTP/1.1" 401 -
404 "GET /?cmd=capabilities HTTP/1.1" 401 -
404 "GET /?cmd=capabilities HTTP/1.1" 401 -
405 "GET /?cmd=capabilities HTTP/1.1" 403 -
405 "GET /?cmd=capabilities HTTP/1.1" 403 -
406 "GET /?cmd=capabilities HTTP/1.1" 401 -
406 "GET /?cmd=capabilities HTTP/1.1" 401 -
407 "GET /?cmd=capabilities HTTP/1.1" 200 -
407 "GET /?cmd=capabilities HTTP/1.1" 200 -
408 "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
408 "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
409 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
409 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
410 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
410 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
411 "GET /?cmd=branchmap HTTP/1.1" 200 - x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
411 "GET /?cmd=branchmap HTTP/1.1" 200 - 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 "POST /?cmd=unbundle HTTP/1.1" 200 - x-hgarg-1:heads=666f726365* (glob)
413 "POST /?cmd=unbundle HTTP/1.1" 200 - x-hgarg-1:heads=666f726365* (glob)
414 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
414 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
415 "GET /?cmd=capabilities HTTP/1.1" 401 -
415 "GET /?cmd=capabilities HTTP/1.1" 401 -
416 "GET /?cmd=capabilities HTTP/1.1" 200 -
416 "GET /?cmd=capabilities HTTP/1.1" 200 -
417 "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
417 "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
418 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
418 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
419 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
419 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
420 "GET /?cmd=branchmap HTTP/1.1" 200 - x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
420 "GET /?cmd=branchmap HTTP/1.1" 200 - x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
421 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
421 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
422 "POST /?cmd=unbundle HTTP/1.1" 200 - x-hgarg-1:heads=666f726365 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
422 "POST /?cmd=unbundle HTTP/1.1" 200 - x-hgarg-1:heads=666f726365 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
423 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
423 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
424
424
425 $ cd ..
425 $ cd ..
426
426
427 clone of serve with repo in root and unserved subrepo (issue2970)
427 clone of serve with repo in root and unserved subrepo (issue2970)
428
428
429 $ hg --cwd test init sub
429 $ hg --cwd test init sub
430 $ echo empty > test/sub/empty
430 $ echo empty > test/sub/empty
431 $ hg --cwd test/sub add empty
431 $ hg --cwd test/sub add empty
432 $ hg --cwd test/sub commit -qm 'add empty'
432 $ hg --cwd test/sub commit -qm 'add empty'
433 $ hg --cwd test/sub tag -r 0 something
433 $ hg --cwd test/sub tag -r 0 something
434 $ echo sub = sub > test/.hgsub
434 $ echo sub = sub > test/.hgsub
435 $ hg --cwd test add .hgsub
435 $ hg --cwd test add .hgsub
436 $ hg --cwd test commit -qm 'add subrepo'
436 $ hg --cwd test commit -qm 'add subrepo'
437 $ hg clone http://localhost:$HGPORT noslash-clone
437 $ hg clone http://localhost:$HGPORT noslash-clone
438 requesting all changes
438 requesting all changes
439 adding changesets
439 adding changesets
440 adding manifests
440 adding manifests
441 adding file changes
441 adding file changes
442 added 3 changesets with 7 changes to 7 files
442 added 3 changesets with 7 changes to 7 files
443 new changesets 8b6053c928fe:56f9bc90cce6
443 new changesets 8b6053c928fe:56f9bc90cce6
444 updating to branch default
444 updating to branch default
445 cloning subrepo sub from http://localhost:$HGPORT/sub
445 cloning subrepo sub from http://localhost:$HGPORT/sub
446 abort: HTTP Error 404: Not Found
446 abort: HTTP Error 404: Not Found
447 [255]
447 [255]
448 $ hg clone http://localhost:$HGPORT/ slash-clone
448 $ hg clone http://localhost:$HGPORT/ slash-clone
449 requesting all changes
449 requesting all changes
450 adding changesets
450 adding changesets
451 adding manifests
451 adding manifests
452 adding file changes
452 adding file changes
453 added 3 changesets with 7 changes to 7 files
453 added 3 changesets with 7 changes to 7 files
454 new changesets 8b6053c928fe:56f9bc90cce6
454 new changesets 8b6053c928fe:56f9bc90cce6
455 updating to branch default
455 updating to branch default
456 cloning subrepo sub from http://localhost:$HGPORT/sub
456 cloning subrepo sub from http://localhost:$HGPORT/sub
457 abort: HTTP Error 404: Not Found
457 abort: HTTP Error 404: Not Found
458 [255]
458 [255]
459
459
460 check error log
460 check error log
461
461
462 $ cat error.log
462 $ cat error.log
463
463
464 $ cat errors2.log
464 $ cat errors2.log
465
465
466 check abort error reporting while pulling/cloning
466 check abort error reporting while pulling/cloning
467
467
468 $ $RUNTESTDIR/killdaemons.py
468 $ $RUNTESTDIR/killdaemons.py
469 $ hg serve -R test -p $HGPORT -d --pid-file=hg3.pid -E error.log --config extensions.crash=${TESTDIR}/crashgetbundler.py
469 $ hg serve -R test -p $HGPORT -d --pid-file=hg3.pid -E error.log --config extensions.crash=${TESTDIR}/crashgetbundler.py
470 $ cat hg3.pid >> $DAEMON_PIDS
470 $ cat hg3.pid >> $DAEMON_PIDS
471 $ hg clone http://localhost:$HGPORT/ abort-clone
471 $ hg clone http://localhost:$HGPORT/ abort-clone
472 requesting all changes
472 requesting all changes
473 remote: abort: this is an exercise
473 remote: abort: this is an exercise
474 abort: pull failed on remote
474 abort: pull failed on remote
475 [255]
475 [255]
476 $ cat error.log
476 $ cat error.log
477
477
478 disable pull-based clones
478 disable pull-based clones
479
479
480 $ hg serve -R test -p $HGPORT1 -d --pid-file=hg4.pid -E error.log --config server.disablefullbundle=True
480 $ hg serve -R test -p $HGPORT1 -d --pid-file=hg4.pid -E error.log --config server.disablefullbundle=True
481 $ cat hg4.pid >> $DAEMON_PIDS
481 $ cat hg4.pid >> $DAEMON_PIDS
482 $ hg clone http://localhost:$HGPORT1/ disable-pull-clone
482 $ hg clone http://localhost:$HGPORT1/ disable-pull-clone
483 requesting all changes
483 requesting all changes
484 remote: abort: server has pull-based clones disabled
484 remote: abort: server has pull-based clones disabled
485 abort: pull failed on remote
485 abort: pull failed on remote
486 (remove --pull if specified or upgrade Mercurial)
486 (remove --pull if specified or upgrade Mercurial)
487 [255]
487 [255]
488
488
489 #if no-reposimplestore
489 #if no-reposimplestore
490 ... but keep stream clones working
490 ... but keep stream clones working
491
491
492 $ hg clone --stream --noupdate http://localhost:$HGPORT1/ test-stream-clone
492 $ hg clone --stream --noupdate http://localhost:$HGPORT1/ test-stream-clone
493 streaming all changes
493 streaming all changes
494 * files to transfer, * of data (glob)
494 * files to transfer, * of data (glob)
495 transferred * in * seconds (*/sec) (glob)
495 transferred * in * seconds (*/sec) (glob)
496 $ cat error.log
496 $ cat error.log
497 #endif
497 #endif
498
498
499 ... and also keep partial clones and pulls working
499 ... and also keep partial clones and pulls working
500 $ hg clone http://localhost:$HGPORT1 --rev 0 test/partial/clone
500 $ hg clone http://localhost:$HGPORT1 --rev 0 test/partial/clone
501 adding changesets
501 adding changesets
502 adding manifests
502 adding manifests
503 adding file changes
503 adding file changes
504 added 1 changesets with 4 changes to 4 files
504 added 1 changesets with 4 changes to 4 files
505 new changesets 8b6053c928fe
505 new changesets 8b6053c928fe
506 updating to branch default
506 updating to branch default
507 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
507 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
508 $ hg pull -R test/partial/clone
508 $ hg pull -R test/partial/clone
509 pulling from http://localhost:$HGPORT1/
509 pulling from http://localhost:$HGPORT1/
510 searching for changes
510 searching for changes
511 adding changesets
511 adding changesets
512 adding manifests
512 adding manifests
513 adding file changes
513 adding file changes
514 added 2 changesets with 3 changes to 3 files
514 added 2 changesets with 3 changes to 3 files
515 new changesets 5fed3813f7f5:56f9bc90cce6
515 new changesets 5fed3813f7f5:56f9bc90cce6
516 (run 'hg update' to get a working copy)
516 (run 'hg update' to get a working copy)
517
517
518 $ hg clone -U -r 0 test/partial/clone test/another/clone
518 $ hg clone -U -r 0 test/partial/clone test/another/clone
519 adding changesets
519 adding changesets
520 adding manifests
520 adding manifests
521 adding file changes
521 adding file changes
522 added 1 changesets with 4 changes to 4 files
522 added 1 changesets with 4 changes to 4 files
523 new changesets 8b6053c928fe
523 new changesets 8b6053c928fe
524
524
525 corrupt cookies file should yield a warning
525 corrupt cookies file should yield a warning
526
526
527 $ cat > $TESTTMP/cookies.txt << EOF
527 $ cat > $TESTTMP/cookies.txt << EOF
528 > bad format
528 > bad format
529 > EOF
529 > EOF
530
530
531 $ hg --config auth.cookiefile=$TESTTMP/cookies.txt id http://localhost:$HGPORT/
531 $ hg --config auth.cookiefile=$TESTTMP/cookies.txt id http://localhost:$HGPORT/
532 (error loading cookie file $TESTTMP/cookies.txt: '*/cookies.txt' does not look like a Netscape format cookies file; continuing without cookies) (glob)
532 (error loading cookie file $TESTTMP/cookies.txt: '*/cookies.txt' does not look like a Netscape format cookies file; continuing without cookies) (glob)
533 56f9bc90cce6
533 56f9bc90cce6
534
534
535 $ killdaemons.py
535 $ killdaemons.py
536
536
537 Create dummy authentication handler that looks for cookies. It doesn't do anything
537 Create dummy authentication handler that looks for cookies. It doesn't do anything
538 useful. It just raises an HTTP 500 with details about the Cookie request header.
538 useful. It just raises an HTTP 500 with details about the Cookie request header.
539 We raise HTTP 500 because its message is printed in the abort message.
539 We raise HTTP 500 because its message is printed in the abort message.
540
540
541 $ cat > cookieauth.py << EOF
541 $ cat > cookieauth.py << EOF
542 > from mercurial import util
542 > from mercurial import util
543 > from mercurial.hgweb import common
543 > from mercurial.hgweb import common
544 > def perform_authentication(hgweb, req, op):
544 > def perform_authentication(hgweb, req, op):
545 > cookie = req.headers.get(b'Cookie')
545 > cookie = req.headers.get(b'Cookie')
546 > if not cookie:
546 > if not cookie:
547 > raise common.ErrorResponse(common.HTTP_SERVER_ERROR, b'no-cookie')
547 > raise common.ErrorResponse(common.HTTP_SERVER_ERROR, b'no-cookie')
548 > raise common.ErrorResponse(common.HTTP_SERVER_ERROR, b'Cookie: %s' % cookie)
548 > raise common.ErrorResponse(common.HTTP_SERVER_ERROR, b'Cookie: %s' % cookie)
549 > def extsetup(ui):
549 > def extsetup(ui):
550 > common.permhooks.insert(0, perform_authentication)
550 > common.permhooks.insert(0, perform_authentication)
551 > EOF
551 > EOF
552
552
553 $ hg serve --config extensions.cookieauth=cookieauth.py -R test -p $HGPORT -d --pid-file=pid
553 $ hg serve --config extensions.cookieauth=cookieauth.py -R test -p $HGPORT -d --pid-file=pid
554 $ cat pid > $DAEMON_PIDS
554 $ cat pid > $DAEMON_PIDS
555
555
556 Request without cookie sent should fail due to lack of cookie
556 Request without cookie sent should fail due to lack of cookie
557
557
558 $ hg id http://localhost:$HGPORT
558 $ hg id http://localhost:$HGPORT
559 abort: HTTP Error 500: no-cookie
559 abort: HTTP Error 500: no-cookie
560 [255]
560 [255]
561
561
562 Populate a cookies file
562 Populate a cookies file
563
563
564 $ cat > cookies.txt << EOF
564 $ cat > cookies.txt << EOF
565 > # HTTP Cookie File
565 > # HTTP Cookie File
566 > # Expiration is 2030-01-01 at midnight
566 > # Expiration is 2030-01-01 at midnight
567 > .example.com TRUE / FALSE 1893456000 hgkey examplevalue
567 > .example.com TRUE / FALSE 1893456000 hgkey examplevalue
568 > EOF
568 > EOF
569
569
570 Should not send a cookie for another domain
570 Should not send a cookie for another domain
571
571
572 $ hg --config auth.cookiefile=cookies.txt id http://localhost:$HGPORT/
572 $ hg --config auth.cookiefile=cookies.txt id http://localhost:$HGPORT/
573 abort: HTTP Error 500: no-cookie
573 abort: HTTP Error 500: no-cookie
574 [255]
574 [255]
575
575
576 Add a cookie entry for our test server and verify it is sent
576 Add a cookie entry for our test server and verify it is sent
577
577
578 $ cat >> cookies.txt << EOF
578 $ cat >> cookies.txt << EOF
579 > localhost.local FALSE / FALSE 1893456000 hgkey localhostvalue
579 > localhost.local FALSE / FALSE 1893456000 hgkey localhostvalue
580 > EOF
580 > EOF
581
581
582 $ hg --config auth.cookiefile=cookies.txt id http://localhost:$HGPORT/
582 $ hg --config auth.cookiefile=cookies.txt id http://localhost:$HGPORT/
583 abort: HTTP Error 500: Cookie: hgkey=localhostvalue
583 abort: HTTP Error 500: Cookie: hgkey=localhostvalue
584 [255]
584 [255]
@@ -1,506 +1,506 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 > -p $HGPORT --pid-file=hg.pid -A $TESTTMP/access.log -E $TESTTMP/errors.log
20 > -p $HGPORT --pid-file=hg.pid -A $TESTTMP/access.log -E $TESTTMP/errors.log
21 $ cat hg.pid >> $DAEMON_PIDS
21 $ cat hg.pid >> $DAEMON_PIDS
22
22
23 Uploads fail...
23 Uploads fail...
24
24
25 $ hg init client
25 $ hg init client
26 $ echo 'this-is-an-lfs-file' > client/lfs.bin
26 $ echo 'this-is-an-lfs-file' > client/lfs.bin
27 $ hg -R client ci -Am 'initial commit'
27 $ hg -R client ci -Am 'initial commit'
28 adding lfs.bin
28 adding lfs.bin
29 $ hg -R client push http://localhost:$HGPORT
29 $ hg -R client push http://localhost:$HGPORT
30 pushing to http://localhost:$HGPORT/
30 pushing to http://localhost:$HGPORT/
31 searching for changes
31 searching for changes
32 abort: LFS HTTP error: HTTP Error 400: no such method: .git!
32 abort: LFS HTTP error: HTTP Error 400: no such method: .git!
33 (check that lfs serving is enabled on http://localhost:$HGPORT/.git/info/lfs and "upload" is supported)
33 (check that lfs serving is enabled on http://localhost:$HGPORT/.git/info/lfs and "upload" is supported)
34 [255]
34 [255]
35
35
36 ... so do a local push to make the data available. Remove the blob from the
36 ... so do a local push to make the data available. Remove the blob from the
37 default cache, so it attempts to download.
37 default cache, so it attempts to download.
38 $ hg --config "lfs.usercache=$TESTTMP/servercache" \
38 $ hg --config "lfs.usercache=$TESTTMP/servercache" \
39 > --config "lfs.url=null://" \
39 > --config "lfs.url=null://" \
40 > -R client push -q server
40 > -R client push -q server
41 $ mv `hg config lfs.usercache` $TESTTMP/servercache
41 $ mv `hg config lfs.usercache` $TESTTMP/servercache
42
42
43 Downloads fail...
43 Downloads fail...
44
44
45 $ hg clone http://localhost:$HGPORT httpclone
45 $ hg clone http://localhost:$HGPORT httpclone
46 (remote is using large file support (lfs); lfs will be enabled for this repository)
46 (remote is using large file support (lfs); lfs will be enabled for this repository)
47 requesting all changes
47 requesting all changes
48 adding changesets
48 adding changesets
49 adding manifests
49 adding manifests
50 adding file changes
50 adding file changes
51 added 1 changesets with 1 changes to 1 files
51 added 1 changesets with 1 changes to 1 files
52 new changesets 525251863cad
52 new changesets 525251863cad
53 updating to branch default
53 updating to branch default
54 abort: LFS HTTP error: HTTP Error 400: no such method: .git!
54 abort: LFS HTTP error: HTTP Error 400: no such method: .git!
55 (check that lfs serving is enabled on http://localhost:$HGPORT/.git/info/lfs and "download" is supported)
55 (check that lfs serving is enabled on http://localhost:$HGPORT/.git/info/lfs and "download" is supported)
56 [255]
56 [255]
57
57
58 $ "$PYTHON" $RUNTESTDIR/killdaemons.py $DAEMON_PIDS
58 $ "$PYTHON" $RUNTESTDIR/killdaemons.py $DAEMON_PIDS
59
59
60 $ cat $TESTTMP/access.log $TESTTMP/errors.log
60 $ cat $TESTTMP/access.log $TESTTMP/errors.log
61 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
61 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
62 $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)
62 $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=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
63 $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=bookmarks 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=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
65 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 400 - (glob)
65 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 400 - (glob)
66 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
66 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
67 $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)
67 $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=getbundle HTTP/1.1" 200 - x-hgarg-1:bookmarks=1&bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%252C03%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)
68 $LOCALIP - - [$LOGDATE$] "GET /?cmd=getbundle HTTP/1.1" 200 - x-hgarg-1:bookmarks=1&bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%252C03%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$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 400 - (glob)
69 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 400 - (glob)
70
70
71 $ rm -f $TESTTMP/access.log $TESTTMP/errors.log
71 $ rm -f $TESTTMP/access.log $TESTTMP/errors.log
72 $ hg --config "lfs.usercache=$TESTTMP/servercache" -R server serve -d \
72 $ hg --config "lfs.usercache=$TESTTMP/servercache" -R server serve -d \
73 > -p $HGPORT --pid-file=hg.pid --prefix=subdir/mount/point \
73 > -p $HGPORT --pid-file=hg.pid --prefix=subdir/mount/point \
74 > -A $TESTTMP/access.log -E $TESTTMP/errors.log
74 > -A $TESTTMP/access.log -E $TESTTMP/errors.log
75 $ cat hg.pid >> $DAEMON_PIDS
75 $ cat hg.pid >> $DAEMON_PIDS
76
76
77 Reasonable hint for a misconfigured blob server
77 Reasonable hint for a misconfigured blob server
78
78
79 $ hg -R httpclone update default --config lfs.url=http://localhost:$HGPORT/missing
79 $ hg -R httpclone update default --config lfs.url=http://localhost:$HGPORT/missing
80 abort: LFS HTTP error: HTTP Error 404: Not Found!
80 abort: LFS HTTP error: HTTP Error 404: Not Found!
81 (the "lfs.url" config may be used to override http://localhost:$HGPORT/missing)
81 (the "lfs.url" config may be used to override http://localhost:$HGPORT/missing)
82 [255]
82 [255]
83
83
84 $ hg -R httpclone update default --config lfs.url=http://localhost:$HGPORT2/missing
84 $ hg -R httpclone update default --config lfs.url=http://localhost:$HGPORT2/missing
85 abort: LFS error: *onnection *refused*! (glob) (?)
85 abort: LFS error: *onnection *refused*! (glob) (?)
86 abort: LFS error: $EADDRNOTAVAIL$! (glob) (?)
86 abort: LFS error: $EADDRNOTAVAIL$! (glob) (?)
87 abort: LFS error: No route to host! (?)
87 abort: LFS error: No route to host! (?)
88 (the "lfs.url" config may be used to override http://localhost:$HGPORT2/missing)
88 (the "lfs.url" config may be used to override http://localhost:$HGPORT2/missing)
89 [255]
89 [255]
90
90
91 Blob URIs are correct when --prefix is used
91 Blob URIs are correct when --prefix is used
92
92
93 $ hg clone --debug http://localhost:$HGPORT/subdir/mount/point cloned2
93 $ hg clone --debug http://localhost:$HGPORT/subdir/mount/point cloned2
94 using http://localhost:$HGPORT/subdir/mount/point
94 using http://localhost:$HGPORT/subdir/mount/point
95 sending capabilities command
95 sending capabilities command
96 (remote is using large file support (lfs); lfs will be enabled for this repository)
96 (remote is using large file support (lfs); lfs will be enabled for this repository)
97 query 1; heads
97 query 1; heads
98 sending batch command
98 sending batch command
99 requesting all changes
99 requesting all changes
100 sending getbundle command
100 sending getbundle command
101 bundle2-input-bundle: with-transaction
101 bundle2-input-bundle: with-transaction
102 bundle2-input-part: "changegroup" (params: 1 mandatory 1 advisory) supported
102 bundle2-input-part: "changegroup" (params: 1 mandatory 1 advisory) supported
103 adding changesets
103 adding changesets
104 add changeset 525251863cad
104 add changeset 525251863cad
105 adding manifests
105 adding manifests
106 adding file changes
106 adding file changes
107 adding lfs.bin revisions
107 adding lfs.bin revisions
108 bundle2-input-part: total payload size 648
108 bundle2-input-part: total payload size 648
109 bundle2-input-part: "listkeys" (params: 1 mandatory) supported
109 bundle2-input-part: "listkeys" (params: 1 mandatory) supported
110 bundle2-input-part: "phase-heads" supported
110 bundle2-input-part: "phase-heads" supported
111 bundle2-input-part: total payload size 24
111 bundle2-input-part: total payload size 24
112 bundle2-input-part: "cache:rev-branch-cache" (advisory) supported
112 bundle2-input-part: "cache:rev-branch-cache" (advisory) supported
113 bundle2-input-part: total payload size 39
113 bundle2-input-part: total payload size 39
114 bundle2-input-bundle: 3 parts total
114 bundle2-input-bundle: 4 parts total
115 checking for updated bookmarks
115 checking for updated bookmarks
116 updating the branch cache
116 updating the branch cache
117 added 1 changesets with 1 changes to 1 files
117 added 1 changesets with 1 changes to 1 files
118 new changesets 525251863cad
118 new changesets 525251863cad
119 updating to branch default
119 updating to branch default
120 resolving manifests
120 resolving manifests
121 branchmerge: False, force: False, partial: False
121 branchmerge: False, force: False, partial: False
122 ancestor: 000000000000, local: 000000000000+, remote: 525251863cad
122 ancestor: 000000000000, local: 000000000000+, remote: 525251863cad
123 lfs: assuming remote store: http://localhost:$HGPORT/subdir/mount/point/.git/info/lfs
123 lfs: assuming remote store: http://localhost:$HGPORT/subdir/mount/point/.git/info/lfs
124 Status: 200
124 Status: 200
125 Content-Length: 371
125 Content-Length: 371
126 Content-Type: application/vnd.git-lfs+json
126 Content-Type: application/vnd.git-lfs+json
127 Date: $HTTP_DATE$
127 Date: $HTTP_DATE$
128 Server: testing stub value
128 Server: testing stub value
129 {
129 {
130 "objects": [
130 "objects": [
131 {
131 {
132 "actions": {
132 "actions": {
133 "download": {
133 "download": {
134 "expires_at": "$ISO_8601_DATE_TIME$"
134 "expires_at": "$ISO_8601_DATE_TIME$"
135 "header": {
135 "header": {
136 "Accept": "application/vnd.git-lfs"
136 "Accept": "application/vnd.git-lfs"
137 }
137 }
138 "href": "http://localhost:$HGPORT/subdir/mount/point/.hg/lfs/objects/f03217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e"
138 "href": "http://localhost:$HGPORT/subdir/mount/point/.hg/lfs/objects/f03217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e"
139 }
139 }
140 }
140 }
141 "oid": "f03217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e"
141 "oid": "f03217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e"
142 "size": 20
142 "size": 20
143 }
143 }
144 ]
144 ]
145 "transfer": "basic"
145 "transfer": "basic"
146 }
146 }
147 lfs: downloading f03217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e (20 bytes)
147 lfs: downloading f03217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e (20 bytes)
148 Status: 200
148 Status: 200
149 Content-Length: 20
149 Content-Length: 20
150 Content-Type: application/octet-stream
150 Content-Type: application/octet-stream
151 Date: $HTTP_DATE$
151 Date: $HTTP_DATE$
152 Server: testing stub value
152 Server: testing stub value
153 lfs: adding f03217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e to the usercache
153 lfs: adding f03217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e to the usercache
154 lfs: processed: f03217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e
154 lfs: processed: f03217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e
155 lfs: downloaded 1 files (20 bytes)
155 lfs: downloaded 1 files (20 bytes)
156 lfs.bin: remote created -> g
156 lfs.bin: remote created -> g
157 getting lfs.bin
157 getting lfs.bin
158 lfs: found f03217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e in the local lfs store
158 lfs: found f03217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e in the local lfs store
159 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
159 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
160 (sent 3 HTTP requests and * bytes; received * bytes in responses) (glob)
160 (sent 3 HTTP requests and * bytes; received * bytes in responses) (glob)
161
161
162 $ "$PYTHON" $RUNTESTDIR/killdaemons.py $DAEMON_PIDS
162 $ "$PYTHON" $RUNTESTDIR/killdaemons.py $DAEMON_PIDS
163
163
164 $ cat $TESTTMP/access.log $TESTTMP/errors.log
164 $ cat $TESTTMP/access.log $TESTTMP/errors.log
165 $LOCALIP - - [$LOGDATE$] "POST /missing/objects/batch HTTP/1.1" 404 - (glob)
165 $LOCALIP - - [$LOGDATE$] "POST /missing/objects/batch HTTP/1.1" 404 - (glob)
166 $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)
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)
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)
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%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%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)
169 $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)
170 $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)
171
171
172 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
173 though the client doesn't send the blob.
173 though the client doesn't send the blob.
174
174
175 $ hg init server2
175 $ hg init server2
176 $ hg --config "lfs.usercache=$TESTTMP/servercache" -R server2 serve -d \
176 $ hg --config "lfs.usercache=$TESTTMP/servercache" -R server2 serve -d \
177 > -p $HGPORT --pid-file=hg.pid \
177 > -p $HGPORT --pid-file=hg.pid \
178 > -A $TESTTMP/access.log -E $TESTTMP/errors.log
178 > -A $TESTTMP/access.log -E $TESTTMP/errors.log
179 $ cat hg.pid >> $DAEMON_PIDS
179 $ cat hg.pid >> $DAEMON_PIDS
180
180
181 $ hg --config "lfs.usercache=$TESTTMP/servercache" -R cloned2 --debug \
181 $ hg --config "lfs.usercache=$TESTTMP/servercache" -R cloned2 --debug \
182 > push http://localhost:$HGPORT | grep '^[{} ]'
182 > push http://localhost:$HGPORT | grep '^[{} ]'
183 {
183 {
184 "objects": [
184 "objects": [
185 {
185 {
186 "oid": "f03217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e"
186 "oid": "f03217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e"
187 "size": 20
187 "size": 20
188 }
188 }
189 ]
189 ]
190 "transfer": "basic"
190 "transfer": "basic"
191 }
191 }
192 $ find server2/.hg/store/lfs/objects | sort
192 $ find server2/.hg/store/lfs/objects | sort
193 server2/.hg/store/lfs/objects
193 server2/.hg/store/lfs/objects
194 server2/.hg/store/lfs/objects/f0
194 server2/.hg/store/lfs/objects/f0
195 server2/.hg/store/lfs/objects/f0/3217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e
195 server2/.hg/store/lfs/objects/f0/3217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e
196 $ "$PYTHON" $RUNTESTDIR/killdaemons.py $DAEMON_PIDS
196 $ "$PYTHON" $RUNTESTDIR/killdaemons.py $DAEMON_PIDS
197 $ cat $TESTTMP/errors.log
197 $ cat $TESTTMP/errors.log
198
198
199 $ cat >> $TESTTMP/lfsstoreerror.py <<EOF
199 $ cat >> $TESTTMP/lfsstoreerror.py <<EOF
200 > import errno
200 > import errno
201 > from hgext.lfs import blobstore
201 > from hgext.lfs import blobstore
202 >
202 >
203 > _numverifies = 0
203 > _numverifies = 0
204 > _readerr = True
204 > _readerr = True
205 >
205 >
206 > def reposetup(ui, repo):
206 > def reposetup(ui, repo):
207 > # Nothing to do with a remote repo
207 > # Nothing to do with a remote repo
208 > if not repo.local():
208 > if not repo.local():
209 > return
209 > return
210 >
210 >
211 > store = repo.svfs.lfslocalblobstore
211 > store = repo.svfs.lfslocalblobstore
212 > class badstore(store.__class__):
212 > class badstore(store.__class__):
213 > def download(self, oid, src):
213 > def download(self, oid, src):
214 > '''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
215 > PUT request.'''
215 > PUT request.'''
216 > origread = src.read
216 > origread = src.read
217 > def _badread(nbytes):
217 > def _badread(nbytes):
218 > # Simulate bad data/checksum failure from the client
218 > # Simulate bad data/checksum failure from the client
219 > return b'0' * len(origread(nbytes))
219 > return b'0' * len(origread(nbytes))
220 > src.read = _badread
220 > src.read = _badread
221 > super(badstore, self).download(oid, src)
221 > super(badstore, self).download(oid, src)
222 >
222 >
223 > def _read(self, vfs, oid, verify):
223 > def _read(self, vfs, oid, verify):
224 > '''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
225 > calls self._verify() on it before returning.'''
225 > calls self._verify() on it before returning.'''
226 > global _readerr
226 > global _readerr
227 > # One time simulation of a read error
227 > # One time simulation of a read error
228 > if _readerr:
228 > if _readerr:
229 > _readerr = False
229 > _readerr = False
230 > 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"))
231 > # Simulate corrupt content on client download
231 > # Simulate corrupt content on client download
232 > blobstore._verify(oid, b'dummy content')
232 > blobstore._verify(oid, b'dummy content')
233 >
233 >
234 > def verify(self, oid):
234 > def verify(self, oid):
235 > '''Called in the server to populate the Batch API response,
235 > '''Called in the server to populate the Batch API response,
236 > letting the client re-upload if the file is corrupt.'''
236 > letting the client re-upload if the file is corrupt.'''
237 > # 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
238 > # command with an IOError. Then let it through to access other
238 > # command with an IOError. Then let it through to access other
239 > # functions. Checksum failure is tested elsewhere.
239 > # functions. Checksum failure is tested elsewhere.
240 > global _numverifies
240 > global _numverifies
241 > _numverifies += 1
241 > _numverifies += 1
242 > if _numverifies <= 2:
242 > if _numverifies <= 2:
243 > 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"))
244 > return super(badstore, self).verify(oid)
244 > return super(badstore, self).verify(oid)
245 >
245 >
246 > store.__class__ = badstore
246 > store.__class__ = badstore
247 > EOF
247 > EOF
248
248
249 $ rm -rf `hg config lfs.usercache`
249 $ rm -rf `hg config lfs.usercache`
250 $ rm -f $TESTTMP/access.log $TESTTMP/errors.log
250 $ rm -f $TESTTMP/access.log $TESTTMP/errors.log
251 $ hg --config "lfs.usercache=$TESTTMP/servercache" \
251 $ hg --config "lfs.usercache=$TESTTMP/servercache" \
252 > --config extensions.lfsstoreerror=$TESTTMP/lfsstoreerror.py \
252 > --config extensions.lfsstoreerror=$TESTTMP/lfsstoreerror.py \
253 > -R server serve -d \
253 > -R server serve -d \
254 > -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
255 $ cat hg.pid >> $DAEMON_PIDS
255 $ cat hg.pid >> $DAEMON_PIDS
256
256
257 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
258
258
259 $ hg clone http://localhost:$HGPORT1 httpclone2
259 $ hg clone http://localhost:$HGPORT1 httpclone2
260 (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)
261 requesting all changes
261 requesting all changes
262 adding changesets
262 adding changesets
263 adding manifests
263 adding manifests
264 adding file changes
264 adding file changes
265 added 1 changesets with 1 changes to 1 files
265 added 1 changesets with 1 changes to 1 files
266 new changesets 525251863cad
266 new changesets 525251863cad
267 updating to branch default
267 updating to branch default
268 abort: LFS server error for "lfs.bin": Internal server error!
268 abort: LFS server error for "lfs.bin": Internal server error!
269 [255]
269 [255]
270
270
271 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
272
272
273 $ echo foo > client/lfs.bin
273 $ echo foo > client/lfs.bin
274 $ hg -R client ci -m 'mod lfs'
274 $ hg -R client ci -m 'mod lfs'
275 $ hg -R client push http://localhost:$HGPORT1
275 $ hg -R client push http://localhost:$HGPORT1
276 pushing to http://localhost:$HGPORT1/
276 pushing to http://localhost:$HGPORT1/
277 searching for changes
277 searching for changes
278 abort: LFS server error for "unknown": Internal server error!
278 abort: LFS server error for "unknown": Internal server error!
279 [255]
279 [255]
280 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
281
281
282 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
283
283
284 $ hg -R client push http://localhost:$HGPORT1
284 $ hg -R client push http://localhost:$HGPORT1
285 pushing to http://localhost:$HGPORT1/
285 pushing to http://localhost:$HGPORT1/
286 searching for changes
286 searching for changes
287 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)!
288 [255]
288 [255]
289
289
290 $ echo 'test lfs file' > server/lfs3.bin
290 $ echo 'test lfs file' > server/lfs3.bin
291 $ hg --config experimental.lfs.disableusercache=True \
291 $ hg --config experimental.lfs.disableusercache=True \
292 > -R server ci -Aqm 'another lfs file'
292 > -R server ci -Aqm 'another lfs file'
293 $ hg -R client pull -q http://localhost:$HGPORT1
293 $ hg -R client pull -q http://localhost:$HGPORT1
294
294
295 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
296
296
297 $ hg --config lfs.url=http://localhost:$HGPORT1/.git/info/lfs \
297 $ hg --config lfs.url=http://localhost:$HGPORT1/.git/info/lfs \
298 > -R client update -r tip
298 > -R client update -r tip
299 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)!
300 [255]
300 [255]
301
301
302 Test a checksum failure during the processing of the GET request
302 Test a checksum failure during the processing of the GET request
303
303
304 $ hg --config lfs.url=http://localhost:$HGPORT1/.git/info/lfs \
304 $ hg --config lfs.url=http://localhost:$HGPORT1/.git/info/lfs \
305 > -R client update -r tip
305 > -R client update -r tip
306 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)!
307 [255]
307 [255]
308
308
309 $ "$PYTHON" $RUNTESTDIR/killdaemons.py $DAEMON_PIDS
309 $ "$PYTHON" $RUNTESTDIR/killdaemons.py $DAEMON_PIDS
310
310
311 $ cat $TESTTMP/access.log
311 $ cat $TESTTMP/access.log
312 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
312 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 200 - (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)
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)
314 $LOCALIP - - [$LOGDATE$] "GET /?cmd=getbundle HTTP/1.1" 200 - x-hgarg-1:bookmarks=1&bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%252C03%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%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)
315 $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)
316 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
316 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 200 - (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)
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)
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)
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)
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)
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)
320 $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)
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)
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)
322 $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)
323 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
323 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 200 - (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)
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)
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)
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)
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)
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)
327 $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)
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)
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)
329 $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)
330 $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)
331 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
331 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 200 - (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)
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)
333 $LOCALIP - - [$LOGDATE$] "GET /?cmd=getbundle HTTP/1.1" 200 - x-hgarg-1:bookmarks=1&bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%252C03%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%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)
334 $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)
335 $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)
336 $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)
337 $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)
338
338
339 $ grep -v ' File "' $TESTTMP/errors.log
339 $ grep -v ' File "' $TESTTMP/errors.log
340 $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)
341 $LOCALIP - - [$ERRDATE$] HG error: Traceback (most recent call last): (glob)
341 $LOCALIP - - [$ERRDATE$] HG error: Traceback (most recent call last): (glob)
342 $LOCALIP - - [$ERRDATE$] HG error: verifies = store.verify(oid) (glob)
342 $LOCALIP - - [$ERRDATE$] HG error: verifies = store.verify(oid) (glob)
343 $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)
344 $LOCALIP - - [$ERRDATE$] HG error: *Error: [Errno 5] f03217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e: I/O error (glob)
344 $LOCALIP - - [$ERRDATE$] HG error: *Error: [Errno 5] f03217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e: I/O error (glob)
345 $LOCALIP - - [$ERRDATE$] HG error: (glob)
345 $LOCALIP - - [$ERRDATE$] HG error: (glob)
346 $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)
347 $LOCALIP - - [$ERRDATE$] HG error: Traceback (most recent call last): (glob)
347 $LOCALIP - - [$ERRDATE$] HG error: Traceback (most recent call last): (glob)
348 $LOCALIP - - [$ERRDATE$] HG error: verifies = store.verify(oid) (glob)
348 $LOCALIP - - [$ERRDATE$] HG error: verifies = store.verify(oid) (glob)
349 $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)
350 $LOCALIP - - [$ERRDATE$] HG error: *Error: [Errno 5] b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c: I/O error (glob)
350 $LOCALIP - - [$ERRDATE$] HG error: *Error: [Errno 5] b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c: I/O error (glob)
351 $LOCALIP - - [$ERRDATE$] HG error: (glob)
351 $LOCALIP - - [$ERRDATE$] HG error: (glob)
352 $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)
353 $LOCALIP - - [$ERRDATE$] HG error: Traceback (most recent call last): (glob)
353 $LOCALIP - - [$ERRDATE$] HG error: Traceback (most recent call last): (glob)
354 $LOCALIP - - [$ERRDATE$] HG error: localstore.download(oid, req.bodyfh) (glob)
354 $LOCALIP - - [$ERRDATE$] HG error: localstore.download(oid, req.bodyfh) (glob)
355 $LOCALIP - - [$ERRDATE$] HG error: super(badstore, self).download(oid, src) (glob)
355 $LOCALIP - - [$ERRDATE$] HG error: super(badstore, self).download(oid, src) (glob)
356 $LOCALIP - - [$ERRDATE$] HG error: % oid) (glob)
356 $LOCALIP - - [$ERRDATE$] HG error: % oid) (glob)
357 $LOCALIP - - [$ERRDATE$] HG error: LfsCorruptionError: corrupt remote lfs object: b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c (glob)
357 $LOCALIP - - [$ERRDATE$] HG error: LfsCorruptionError: corrupt remote lfs object: b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c (glob)
358 $LOCALIP - - [$ERRDATE$] HG error: (glob)
358 $LOCALIP - - [$ERRDATE$] HG error: (glob)
359 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/.hg/lfs/objects/276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d': (glob)
359 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/.hg/lfs/objects/276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d': (glob)
360 Traceback (most recent call last):
360 Traceback (most recent call last):
361 self.do_write()
361 self.do_write()
362 self.do_hgweb()
362 self.do_hgweb()
363 for chunk in self.server.application(env, self._start_response):
363 for chunk in self.server.application(env, self._start_response):
364 for r in self._runwsgi(req, res, repo):
364 for r in self._runwsgi(req, res, repo):
365 rctx, req, res, self.check_perm)
365 rctx, req, res, self.check_perm)
366 return func(*(args + a), **kw) (no-py3 !)
366 return func(*(args + a), **kw) (no-py3 !)
367 lambda perm:
367 lambda perm:
368 res.setbodybytes(localstore.read(oid))
368 res.setbodybytes(localstore.read(oid))
369 blob = self._read(self.vfs, oid, verify)
369 blob = self._read(self.vfs, oid, verify)
370 raise IOError(errno.EIO, r'%s: I/O error' % oid.decode("utf-8"))
370 raise IOError(errno.EIO, r'%s: I/O error' % oid.decode("utf-8"))
371 *Error: [Errno 5] 276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d: I/O error (glob)
371 *Error: [Errno 5] 276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d: I/O error (glob)
372
372
373 $LOCALIP - - [$ERRDATE$] HG error: Exception happened while processing request '/.hg/lfs/objects/276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d': (glob)
373 $LOCALIP - - [$ERRDATE$] HG error: Exception happened while processing request '/.hg/lfs/objects/276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d': (glob)
374 $LOCALIP - - [$ERRDATE$] HG error: Traceback (most recent call last): (glob)
374 $LOCALIP - - [$ERRDATE$] HG error: Traceback (most recent call last): (glob)
375 $LOCALIP - - [$ERRDATE$] HG error: res.setbodybytes(localstore.read(oid)) (glob)
375 $LOCALIP - - [$ERRDATE$] HG error: res.setbodybytes(localstore.read(oid)) (glob)
376 $LOCALIP - - [$ERRDATE$] HG error: blob = self._read(self.vfs, oid, verify) (glob)
376 $LOCALIP - - [$ERRDATE$] HG error: blob = self._read(self.vfs, oid, verify) (glob)
377 $LOCALIP - - [$ERRDATE$] HG error: blobstore._verify(oid, b'dummy content') (glob)
377 $LOCALIP - - [$ERRDATE$] HG error: blobstore._verify(oid, b'dummy content') (glob)
378 $LOCALIP - - [$ERRDATE$] HG error: hint=_(b'run hg verify')) (glob)
378 $LOCALIP - - [$ERRDATE$] HG error: hint=_(b'run hg verify')) (glob)
379 $LOCALIP - - [$ERRDATE$] HG error: LfsCorruptionError: detected corrupt lfs object: 276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d (glob)
379 $LOCALIP - - [$ERRDATE$] HG error: LfsCorruptionError: detected corrupt lfs object: 276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d (glob)
380 $LOCALIP - - [$ERRDATE$] HG error: (glob)
380 $LOCALIP - - [$ERRDATE$] HG error: (glob)
381
381
382 Basic Authorization headers are returned by the Batch API, and sent back with
382 Basic Authorization headers are returned by the Batch API, and sent back with
383 the GET/PUT request.
383 the GET/PUT request.
384
384
385 $ rm -f $TESTTMP/access.log $TESTTMP/errors.log
385 $ rm -f $TESTTMP/access.log $TESTTMP/errors.log
386
386
387 $ cat >> $HGRCPATH << EOF
387 $ cat >> $HGRCPATH << EOF
388 > [experimental]
388 > [experimental]
389 > lfs.disableusercache = True
389 > lfs.disableusercache = True
390 > [auth]
390 > [auth]
391 > l.schemes=http
391 > l.schemes=http
392 > l.prefix=lo
392 > l.prefix=lo
393 > l.username=user
393 > l.username=user
394 > l.password=pass
394 > l.password=pass
395 > EOF
395 > EOF
396
396
397 $ hg --config extensions.x=$TESTDIR/httpserverauth.py \
397 $ hg --config extensions.x=$TESTDIR/httpserverauth.py \
398 > -R server serve -d -p $HGPORT1 --pid-file=hg.pid \
398 > -R server serve -d -p $HGPORT1 --pid-file=hg.pid \
399 > -A $TESTTMP/access.log -E $TESTTMP/errors.log
399 > -A $TESTTMP/access.log -E $TESTTMP/errors.log
400 $ mv hg.pid $DAEMON_PIDS
400 $ mv hg.pid $DAEMON_PIDS
401
401
402 $ hg clone --debug http://localhost:$HGPORT1 auth_clone | egrep '^[{}]| '
402 $ hg clone --debug http://localhost:$HGPORT1 auth_clone | egrep '^[{}]| '
403 {
403 {
404 "objects": [
404 "objects": [
405 {
405 {
406 "actions": {
406 "actions": {
407 "download": {
407 "download": {
408 "expires_at": "$ISO_8601_DATE_TIME$"
408 "expires_at": "$ISO_8601_DATE_TIME$"
409 "header": {
409 "header": {
410 "Accept": "application/vnd.git-lfs"
410 "Accept": "application/vnd.git-lfs"
411 "Authorization": "Basic dXNlcjpwYXNz"
411 "Authorization": "Basic dXNlcjpwYXNz"
412 }
412 }
413 "href": "http://localhost:$HGPORT1/.hg/lfs/objects/276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d"
413 "href": "http://localhost:$HGPORT1/.hg/lfs/objects/276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d"
414 }
414 }
415 }
415 }
416 "oid": "276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d"
416 "oid": "276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d"
417 "size": 14
417 "size": 14
418 }
418 }
419 ]
419 ]
420 "transfer": "basic"
420 "transfer": "basic"
421 }
421 }
422
422
423 $ echo 'another blob' > auth_clone/lfs.blob
423 $ echo 'another blob' > auth_clone/lfs.blob
424 $ hg -R auth_clone ci -Aqm 'add blob'
424 $ hg -R auth_clone ci -Aqm 'add blob'
425
425
426 $ cat > use_digests.py << EOF
426 $ cat > use_digests.py << EOF
427 > from mercurial import (
427 > from mercurial import (
428 > exthelper,
428 > exthelper,
429 > url,
429 > url,
430 > )
430 > )
431 >
431 >
432 > eh = exthelper.exthelper()
432 > eh = exthelper.exthelper()
433 > uisetup = eh.finaluisetup
433 > uisetup = eh.finaluisetup
434 >
434 >
435 > @eh.wrapfunction(url, 'opener')
435 > @eh.wrapfunction(url, 'opener')
436 > def urlopener(orig, *args, **kwargs):
436 > def urlopener(orig, *args, **kwargs):
437 > opener = orig(*args, **kwargs)
437 > opener = orig(*args, **kwargs)
438 > opener.addheaders.append((r'X-HgTest-AuthType', r'Digest'))
438 > opener.addheaders.append((r'X-HgTest-AuthType', r'Digest'))
439 > return opener
439 > return opener
440 > EOF
440 > EOF
441
441
442 Test that Digest Auth fails gracefully before testing the successful Basic Auth
442 Test that Digest Auth fails gracefully before testing the successful Basic Auth
443
443
444 $ hg -R auth_clone push --config extensions.x=use_digests.py
444 $ hg -R auth_clone push --config extensions.x=use_digests.py
445 pushing to http://localhost:$HGPORT1/
445 pushing to http://localhost:$HGPORT1/
446 searching for changes
446 searching for changes
447 abort: LFS HTTP error: HTTP Error 401: the server must support Basic Authentication!
447 abort: LFS HTTP error: HTTP Error 401: the server must support Basic Authentication!
448 (api=http://localhost:$HGPORT1/.git/info/lfs/objects/batch, action=upload)
448 (api=http://localhost:$HGPORT1/.git/info/lfs/objects/batch, action=upload)
449 [255]
449 [255]
450
450
451 $ hg -R auth_clone --debug push | egrep '^[{}]| '
451 $ hg -R auth_clone --debug push | egrep '^[{}]| '
452 {
452 {
453 "objects": [
453 "objects": [
454 {
454 {
455 "actions": {
455 "actions": {
456 "upload": {
456 "upload": {
457 "expires_at": "$ISO_8601_DATE_TIME$"
457 "expires_at": "$ISO_8601_DATE_TIME$"
458 "header": {
458 "header": {
459 "Accept": "application/vnd.git-lfs"
459 "Accept": "application/vnd.git-lfs"
460 "Authorization": "Basic dXNlcjpwYXNz"
460 "Authorization": "Basic dXNlcjpwYXNz"
461 }
461 }
462 "href": "http://localhost:$HGPORT1/.hg/lfs/objects/df14287d8d75f076a6459e7a3703ca583ca9fb3f4918caed10c77ac8622d49b3"
462 "href": "http://localhost:$HGPORT1/.hg/lfs/objects/df14287d8d75f076a6459e7a3703ca583ca9fb3f4918caed10c77ac8622d49b3"
463 }
463 }
464 }
464 }
465 "oid": "df14287d8d75f076a6459e7a3703ca583ca9fb3f4918caed10c77ac8622d49b3"
465 "oid": "df14287d8d75f076a6459e7a3703ca583ca9fb3f4918caed10c77ac8622d49b3"
466 "size": 13
466 "size": 13
467 }
467 }
468 ]
468 ]
469 "transfer": "basic"
469 "transfer": "basic"
470 }
470 }
471
471
472 $ "$PYTHON" $RUNTESTDIR/killdaemons.py $DAEMON_PIDS
472 $ "$PYTHON" $RUNTESTDIR/killdaemons.py $DAEMON_PIDS
473
473
474 $ cat $TESTTMP/access.log $TESTTMP/errors.log
474 $ cat $TESTTMP/access.log $TESTTMP/errors.log
475 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 401 - (glob)
475 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 401 - (glob)
476 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
476 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
477 $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)
477 $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)
478 $LOCALIP - - [$LOGDATE$] "GET /?cmd=getbundle HTTP/1.1" 200 - x-hgarg-1:bookmarks=1&bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%252C03%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)
478 $LOCALIP - - [$LOGDATE$] "GET /?cmd=getbundle HTTP/1.1" 200 - x-hgarg-1:bookmarks=1&bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%252C03%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)
479 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 401 - (glob)
479 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 401 - (glob)
480 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
480 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
481 $LOCALIP - - [$LOGDATE$] "GET /.hg/lfs/objects/276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d HTTP/1.1" 200 - (glob)
481 $LOCALIP - - [$LOGDATE$] "GET /.hg/lfs/objects/276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d HTTP/1.1" 200 - (glob)
482 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 401 - x-hgtest-authtype:Digest (glob)
482 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 401 - x-hgtest-authtype:Digest (glob)
483 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 200 - x-hgtest-authtype:Digest (glob)
483 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 200 - x-hgtest-authtype:Digest (glob)
484 $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)
484 $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)
485 $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)
485 $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)
486 $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)
486 $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)
487 $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)
487 $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)
488 $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)
488 $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)
489 $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)
489 $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)
490 $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)
490 $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)
491 $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)
491 $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)
492 $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)
492 $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)
493 $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)
493 $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)
494 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 401 - x-hgtest-authtype:Digest (glob)
494 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 401 - x-hgtest-authtype:Digest (glob)
495 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 401 - (glob)
495 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 401 - (glob)
496 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
496 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
497 $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)
497 $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)
498 $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)
498 $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)
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 (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 (glob)
500 $LOCALIP - - [$LOGDATE$] "GET /?cmd=branchmap HTTP/1.1" 200 - x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
500 $LOCALIP - - [$LOGDATE$] "GET /?cmd=branchmap HTTP/1.1" 200 - x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (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 (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 (glob)
502 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 401 - (glob)
502 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 401 - (glob)
503 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
503 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
504 $LOCALIP - - [$LOGDATE$] "PUT /.hg/lfs/objects/df14287d8d75f076a6459e7a3703ca583ca9fb3f4918caed10c77ac8622d49b3 HTTP/1.1" 201 - (glob)
504 $LOCALIP - - [$LOGDATE$] "PUT /.hg/lfs/objects/df14287d8d75f076a6459e7a3703ca583ca9fb3f4918caed10c77ac8622d49b3 HTTP/1.1" 201 - (glob)
505 $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)
505 $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)
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)
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)
@@ -1,941 +1,941 b''
1 #require no-reposimplestore no-chg
1 #require no-reposimplestore no-chg
2 #testcases git-server hg-server
2 #testcases git-server hg-server
3
3
4 #if git-server
4 #if git-server
5 #require lfs-test-server
5 #require lfs-test-server
6 #else
6 #else
7 #require serve
7 #require serve
8 #endif
8 #endif
9
9
10 #if git-server
10 #if git-server
11 $ LFS_LISTEN="tcp://:$HGPORT"
11 $ LFS_LISTEN="tcp://:$HGPORT"
12 $ LFS_HOST="localhost:$HGPORT"
12 $ LFS_HOST="localhost:$HGPORT"
13 $ LFS_PUBLIC=1
13 $ LFS_PUBLIC=1
14 $ export LFS_LISTEN LFS_HOST LFS_PUBLIC
14 $ export LFS_LISTEN LFS_HOST LFS_PUBLIC
15 #else
15 #else
16 $ LFS_HOST="localhost:$HGPORT/.git/info/lfs"
16 $ LFS_HOST="localhost:$HGPORT/.git/info/lfs"
17 #endif
17 #endif
18
18
19 #if no-windows git-server
19 #if no-windows git-server
20 $ lfs-test-server &> lfs-server.log &
20 $ lfs-test-server &> lfs-server.log &
21 $ echo $! >> $DAEMON_PIDS
21 $ echo $! >> $DAEMON_PIDS
22 #endif
22 #endif
23
23
24 #if windows git-server
24 #if windows git-server
25 $ cat >> $TESTTMP/spawn.py <<EOF
25 $ cat >> $TESTTMP/spawn.py <<EOF
26 > import os
26 > import os
27 > import subprocess
27 > import subprocess
28 > import sys
28 > import sys
29 >
29 >
30 > for path in os.environ["PATH"].split(os.pathsep):
30 > for path in os.environ["PATH"].split(os.pathsep):
31 > exe = os.path.join(path, 'lfs-test-server.exe')
31 > exe = os.path.join(path, 'lfs-test-server.exe')
32 > if os.path.exists(exe):
32 > if os.path.exists(exe):
33 > with open('lfs-server.log', 'wb') as out:
33 > with open('lfs-server.log', 'wb') as out:
34 > p = subprocess.Popen(exe, stdout=out, stderr=out)
34 > p = subprocess.Popen(exe, stdout=out, stderr=out)
35 > sys.stdout.write('%s\n' % p.pid)
35 > sys.stdout.write('%s\n' % p.pid)
36 > sys.exit(0)
36 > sys.exit(0)
37 > sys.exit(1)
37 > sys.exit(1)
38 > EOF
38 > EOF
39 $ "$PYTHON" $TESTTMP/spawn.py >> $DAEMON_PIDS
39 $ "$PYTHON" $TESTTMP/spawn.py >> $DAEMON_PIDS
40 #endif
40 #endif
41
41
42 $ cat >> $HGRCPATH <<EOF
42 $ cat >> $HGRCPATH <<EOF
43 > [extensions]
43 > [extensions]
44 > lfs=
44 > lfs=
45 > [lfs]
45 > [lfs]
46 > url=http://foo:bar@$LFS_HOST
46 > url=http://foo:bar@$LFS_HOST
47 > track=all()
47 > track=all()
48 > [web]
48 > [web]
49 > push_ssl = False
49 > push_ssl = False
50 > allow-push = *
50 > allow-push = *
51 > EOF
51 > EOF
52
52
53 Use a separate usercache, otherwise the server sees what the client commits, and
53 Use a separate usercache, otherwise the server sees what the client commits, and
54 never requests a transfer.
54 never requests a transfer.
55
55
56 #if hg-server
56 #if hg-server
57 $ hg init server
57 $ hg init server
58 $ hg --config "lfs.usercache=$TESTTMP/servercache" -R server serve -d \
58 $ hg --config "lfs.usercache=$TESTTMP/servercache" -R server serve -d \
59 > -p $HGPORT --pid-file=hg.pid -A $TESTTMP/access.log -E $TESTTMP/errors.log
59 > -p $HGPORT --pid-file=hg.pid -A $TESTTMP/access.log -E $TESTTMP/errors.log
60 $ cat hg.pid >> $DAEMON_PIDS
60 $ cat hg.pid >> $DAEMON_PIDS
61 #endif
61 #endif
62
62
63 $ hg init repo1
63 $ hg init repo1
64 $ cd repo1
64 $ cd repo1
65 $ echo THIS-IS-LFS > a
65 $ echo THIS-IS-LFS > a
66 $ hg commit -m a -A a
66 $ hg commit -m a -A a
67
67
68 A push can be serviced directly from the usercache if it isn't in the local
68 A push can be serviced directly from the usercache if it isn't in the local
69 store.
69 store.
70
70
71 $ hg init ../repo2
71 $ hg init ../repo2
72 $ mv .hg/store/lfs .hg/store/lfs_
72 $ mv .hg/store/lfs .hg/store/lfs_
73 $ hg push ../repo2 --debug
73 $ hg push ../repo2 --debug
74 http auth: user foo, password ***
74 http auth: user foo, password ***
75 pushing to ../repo2
75 pushing to ../repo2
76 http auth: user foo, password ***
76 http auth: user foo, password ***
77 http auth: user foo, password ***
77 http auth: user foo, password ***
78 query 1; heads
78 query 1; heads
79 searching for changes
79 searching for changes
80 1 total queries in *s (glob)
80 1 total queries in *s (glob)
81 listing keys for "phases"
81 listing keys for "phases"
82 checking for updated bookmarks
82 checking for updated bookmarks
83 listing keys for "bookmarks"
83 listing keys for "bookmarks"
84 lfs: computing set of blobs to upload
84 lfs: computing set of blobs to upload
85 Status: 200
85 Status: 200
86 Content-Length: 309 (git-server !)
86 Content-Length: 309 (git-server !)
87 Content-Length: 350 (hg-server !)
87 Content-Length: 350 (hg-server !)
88 Content-Type: application/vnd.git-lfs+json
88 Content-Type: application/vnd.git-lfs+json
89 Date: $HTTP_DATE$
89 Date: $HTTP_DATE$
90 Server: testing stub value (hg-server !)
90 Server: testing stub value (hg-server !)
91 {
91 {
92 "objects": [
92 "objects": [
93 {
93 {
94 "actions": {
94 "actions": {
95 "upload": {
95 "upload": {
96 "expires_at": "$ISO_8601_DATE_TIME$"
96 "expires_at": "$ISO_8601_DATE_TIME$"
97 "header": {
97 "header": {
98 "Accept": "application/vnd.git-lfs"
98 "Accept": "application/vnd.git-lfs"
99 }
99 }
100 "href": "http://localhost:$HGPORT/objects/31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b" (git-server !)
100 "href": "http://localhost:$HGPORT/objects/31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b" (git-server !)
101 "href": "http://localhost:$HGPORT/.hg/lfs/objects/31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b" (hg-server !)
101 "href": "http://localhost:$HGPORT/.hg/lfs/objects/31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b" (hg-server !)
102 }
102 }
103 }
103 }
104 "oid": "31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b"
104 "oid": "31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b"
105 "size": 12
105 "size": 12
106 }
106 }
107 ]
107 ]
108 "transfer": "basic" (hg-server !)
108 "transfer": "basic" (hg-server !)
109 }
109 }
110 lfs: uploading 31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b (12 bytes)
110 lfs: uploading 31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b (12 bytes)
111 Status: 200 (git-server !)
111 Status: 200 (git-server !)
112 Status: 201 (hg-server !)
112 Status: 201 (hg-server !)
113 Content-Length: 0
113 Content-Length: 0
114 Content-Type: text/plain; charset=utf-8
114 Content-Type: text/plain; charset=utf-8
115 Date: $HTTP_DATE$
115 Date: $HTTP_DATE$
116 Server: testing stub value (hg-server !)
116 Server: testing stub value (hg-server !)
117 lfs: processed: 31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b
117 lfs: processed: 31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b
118 lfs: uploaded 1 files (12 bytes)
118 lfs: uploaded 1 files (12 bytes)
119 1 changesets found
119 1 changesets found
120 list of changesets:
120 list of changesets:
121 99a7098854a3984a5c9eab0fc7a2906697b7cb5c
121 99a7098854a3984a5c9eab0fc7a2906697b7cb5c
122 bundle2-output-bundle: "HG20", 4 parts total
122 bundle2-output-bundle: "HG20", 4 parts total
123 bundle2-output-part: "replycaps" * bytes payload (glob)
123 bundle2-output-part: "replycaps" * bytes payload (glob)
124 bundle2-output-part: "check:heads" streamed payload
124 bundle2-output-part: "check:heads" streamed payload
125 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
125 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
126 bundle2-output-part: "phase-heads" 24 bytes payload
126 bundle2-output-part: "phase-heads" 24 bytes payload
127 bundle2-input-bundle: with-transaction
127 bundle2-input-bundle: with-transaction
128 bundle2-input-part: "replycaps" supported
128 bundle2-input-part: "replycaps" supported
129 bundle2-input-part: total payload size * (glob)
129 bundle2-input-part: total payload size * (glob)
130 bundle2-input-part: "check:heads" supported
130 bundle2-input-part: "check:heads" supported
131 bundle2-input-part: total payload size 20
131 bundle2-input-part: total payload size 20
132 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
132 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
133 adding changesets
133 adding changesets
134 add changeset 99a7098854a3
134 add changeset 99a7098854a3
135 adding manifests
135 adding manifests
136 adding file changes
136 adding file changes
137 adding a revisions
137 adding a revisions
138 calling hook pretxnchangegroup.lfs: hgext.lfs.checkrequireslfs
138 calling hook pretxnchangegroup.lfs: hgext.lfs.checkrequireslfs
139 bundle2-input-part: total payload size 617
139 bundle2-input-part: total payload size 617
140 bundle2-input-part: "phase-heads" supported
140 bundle2-input-part: "phase-heads" supported
141 bundle2-input-part: total payload size 24
141 bundle2-input-part: total payload size 24
142 bundle2-input-bundle: 3 parts total
142 bundle2-input-bundle: 4 parts total
143 updating the branch cache
143 updating the branch cache
144 added 1 changesets with 1 changes to 1 files
144 added 1 changesets with 1 changes to 1 files
145 bundle2-output-bundle: "HG20", 1 parts total
145 bundle2-output-bundle: "HG20", 1 parts total
146 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
146 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
147 bundle2-input-bundle: no-transaction
147 bundle2-input-bundle: no-transaction
148 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
148 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
149 bundle2-input-bundle: 0 parts total
149 bundle2-input-bundle: 1 parts total
150 listing keys for "phases"
150 listing keys for "phases"
151 $ mv .hg/store/lfs_ .hg/store/lfs
151 $ mv .hg/store/lfs_ .hg/store/lfs
152
152
153 Clear the cache to force a download
153 Clear the cache to force a download
154 $ rm -rf `hg config lfs.usercache`
154 $ rm -rf `hg config lfs.usercache`
155 $ cd ../repo2
155 $ cd ../repo2
156 $ hg update tip --debug
156 $ hg update tip --debug
157 http auth: user foo, password ***
157 http auth: user foo, password ***
158 resolving manifests
158 resolving manifests
159 branchmerge: False, force: False, partial: False
159 branchmerge: False, force: False, partial: False
160 ancestor: 000000000000, local: 000000000000+, remote: 99a7098854a3
160 ancestor: 000000000000, local: 000000000000+, remote: 99a7098854a3
161 http auth: user foo, password ***
161 http auth: user foo, password ***
162 Status: 200
162 Status: 200
163 Content-Length: 311 (git-server !)
163 Content-Length: 311 (git-server !)
164 Content-Length: 352 (hg-server !)
164 Content-Length: 352 (hg-server !)
165 Content-Type: application/vnd.git-lfs+json
165 Content-Type: application/vnd.git-lfs+json
166 Date: $HTTP_DATE$
166 Date: $HTTP_DATE$
167 Server: testing stub value (hg-server !)
167 Server: testing stub value (hg-server !)
168 {
168 {
169 "objects": [
169 "objects": [
170 {
170 {
171 "actions": {
171 "actions": {
172 "download": {
172 "download": {
173 "expires_at": "$ISO_8601_DATE_TIME$"
173 "expires_at": "$ISO_8601_DATE_TIME$"
174 "header": {
174 "header": {
175 "Accept": "application/vnd.git-lfs"
175 "Accept": "application/vnd.git-lfs"
176 }
176 }
177 "href": "http://localhost:$HGPORT/*/31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b" (glob)
177 "href": "http://localhost:$HGPORT/*/31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b" (glob)
178 }
178 }
179 }
179 }
180 "oid": "31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b"
180 "oid": "31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b"
181 "size": 12
181 "size": 12
182 }
182 }
183 ]
183 ]
184 "transfer": "basic" (hg-server !)
184 "transfer": "basic" (hg-server !)
185 }
185 }
186 lfs: downloading 31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b (12 bytes)
186 lfs: downloading 31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b (12 bytes)
187 Status: 200
187 Status: 200
188 Content-Length: 12
188 Content-Length: 12
189 Content-Type: text/plain; charset=utf-8 (git-server !)
189 Content-Type: text/plain; charset=utf-8 (git-server !)
190 Content-Type: application/octet-stream (hg-server !)
190 Content-Type: application/octet-stream (hg-server !)
191 Date: $HTTP_DATE$
191 Date: $HTTP_DATE$
192 Server: testing stub value (hg-server !)
192 Server: testing stub value (hg-server !)
193 lfs: adding 31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b to the usercache
193 lfs: adding 31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b to the usercache
194 lfs: processed: 31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b
194 lfs: processed: 31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b
195 lfs: downloaded 1 files (12 bytes)
195 lfs: downloaded 1 files (12 bytes)
196 a: remote created -> g
196 a: remote created -> g
197 getting a
197 getting a
198 lfs: found 31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b in the local lfs store
198 lfs: found 31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b in the local lfs store
199 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
199 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
200
200
201 When the server has some blobs already. `hg serve` doesn't offer to upload
201 When the server has some blobs already. `hg serve` doesn't offer to upload
202 blobs that it already knows about. Note that lfs-test-server is simply
202 blobs that it already knows about. Note that lfs-test-server is simply
203 toggling the action to 'download'. The Batch API spec says it should omit the
203 toggling the action to 'download'. The Batch API spec says it should omit the
204 actions property completely.
204 actions property completely.
205
205
206 $ hg mv a b
206 $ hg mv a b
207 $ echo ANOTHER-LARGE-FILE > c
207 $ echo ANOTHER-LARGE-FILE > c
208 $ echo ANOTHER-LARGE-FILE2 > d
208 $ echo ANOTHER-LARGE-FILE2 > d
209 $ hg commit -m b-and-c -A b c d
209 $ hg commit -m b-and-c -A b c d
210 $ hg push ../repo1 --debug
210 $ hg push ../repo1 --debug
211 http auth: user foo, password ***
211 http auth: user foo, password ***
212 pushing to ../repo1
212 pushing to ../repo1
213 http auth: user foo, password ***
213 http auth: user foo, password ***
214 http auth: user foo, password ***
214 http auth: user foo, password ***
215 query 1; heads
215 query 1; heads
216 searching for changes
216 searching for changes
217 all remote heads known locally
217 all remote heads known locally
218 listing keys for "phases"
218 listing keys for "phases"
219 checking for updated bookmarks
219 checking for updated bookmarks
220 listing keys for "bookmarks"
220 listing keys for "bookmarks"
221 listing keys for "bookmarks"
221 listing keys for "bookmarks"
222 lfs: computing set of blobs to upload
222 lfs: computing set of blobs to upload
223 Status: 200
223 Status: 200
224 Content-Length: 901 (git-server !)
224 Content-Length: 901 (git-server !)
225 Content-Length: 755 (hg-server !)
225 Content-Length: 755 (hg-server !)
226 Content-Type: application/vnd.git-lfs+json
226 Content-Type: application/vnd.git-lfs+json
227 Date: $HTTP_DATE$
227 Date: $HTTP_DATE$
228 Server: testing stub value (hg-server !)
228 Server: testing stub value (hg-server !)
229 {
229 {
230 "objects": [
230 "objects": [
231 {
231 {
232 "actions": { (git-server !)
232 "actions": { (git-server !)
233 "download": { (git-server !)
233 "download": { (git-server !)
234 "expires_at": "$ISO_8601_DATE_TIME$" (git-server !)
234 "expires_at": "$ISO_8601_DATE_TIME$" (git-server !)
235 "header": { (git-server !)
235 "header": { (git-server !)
236 "Accept": "application/vnd.git-lfs" (git-server !)
236 "Accept": "application/vnd.git-lfs" (git-server !)
237 } (git-server !)
237 } (git-server !)
238 "href": "http://localhost:$HGPORT/objects/31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b" (git-server !)
238 "href": "http://localhost:$HGPORT/objects/31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b" (git-server !)
239 } (git-server !)
239 } (git-server !)
240 } (git-server !)
240 } (git-server !)
241 "oid": "31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b"
241 "oid": "31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b"
242 "size": 12
242 "size": 12
243 }
243 }
244 {
244 {
245 "actions": {
245 "actions": {
246 "upload": {
246 "upload": {
247 "expires_at": "$ISO_8601_DATE_TIME$"
247 "expires_at": "$ISO_8601_DATE_TIME$"
248 "header": {
248 "header": {
249 "Accept": "application/vnd.git-lfs"
249 "Accept": "application/vnd.git-lfs"
250 }
250 }
251 "href": "http://localhost:$HGPORT/*/37a65ab78d5ecda767e8622c248b5dbff1e68b1678ab0e730d5eb8601ec8ad19" (glob)
251 "href": "http://localhost:$HGPORT/*/37a65ab78d5ecda767e8622c248b5dbff1e68b1678ab0e730d5eb8601ec8ad19" (glob)
252 }
252 }
253 }
253 }
254 "oid": "37a65ab78d5ecda767e8622c248b5dbff1e68b1678ab0e730d5eb8601ec8ad19"
254 "oid": "37a65ab78d5ecda767e8622c248b5dbff1e68b1678ab0e730d5eb8601ec8ad19"
255 "size": 20
255 "size": 20
256 }
256 }
257 {
257 {
258 "actions": {
258 "actions": {
259 "upload": {
259 "upload": {
260 "expires_at": "$ISO_8601_DATE_TIME$"
260 "expires_at": "$ISO_8601_DATE_TIME$"
261 "header": {
261 "header": {
262 "Accept": "application/vnd.git-lfs"
262 "Accept": "application/vnd.git-lfs"
263 }
263 }
264 "href": "http://localhost:$HGPORT/*/d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998" (glob)
264 "href": "http://localhost:$HGPORT/*/d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998" (glob)
265 }
265 }
266 }
266 }
267 "oid": "d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998"
267 "oid": "d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998"
268 "size": 19
268 "size": 19
269 }
269 }
270 ]
270 ]
271 "transfer": "basic" (hg-server !)
271 "transfer": "basic" (hg-server !)
272 }
272 }
273 lfs: need to transfer 2 objects (39 bytes)
273 lfs: need to transfer 2 objects (39 bytes)
274 lfs: uploading 37a65ab78d5ecda767e8622c248b5dbff1e68b1678ab0e730d5eb8601ec8ad19 (20 bytes)
274 lfs: uploading 37a65ab78d5ecda767e8622c248b5dbff1e68b1678ab0e730d5eb8601ec8ad19 (20 bytes)
275 Status: 200 (git-server !)
275 Status: 200 (git-server !)
276 Status: 201 (hg-server !)
276 Status: 201 (hg-server !)
277 Content-Length: 0
277 Content-Length: 0
278 Content-Type: text/plain; charset=utf-8
278 Content-Type: text/plain; charset=utf-8
279 Date: $HTTP_DATE$
279 Date: $HTTP_DATE$
280 Server: testing stub value (hg-server !)
280 Server: testing stub value (hg-server !)
281 lfs: processed: 37a65ab78d5ecda767e8622c248b5dbff1e68b1678ab0e730d5eb8601ec8ad19
281 lfs: processed: 37a65ab78d5ecda767e8622c248b5dbff1e68b1678ab0e730d5eb8601ec8ad19
282 lfs: uploading d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998 (19 bytes)
282 lfs: uploading d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998 (19 bytes)
283 Status: 200 (git-server !)
283 Status: 200 (git-server !)
284 Status: 201 (hg-server !)
284 Status: 201 (hg-server !)
285 Content-Length: 0
285 Content-Length: 0
286 Content-Type: text/plain; charset=utf-8
286 Content-Type: text/plain; charset=utf-8
287 Date: $HTTP_DATE$
287 Date: $HTTP_DATE$
288 Server: testing stub value (hg-server !)
288 Server: testing stub value (hg-server !)
289 lfs: processed: d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998
289 lfs: processed: d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998
290 lfs: uploaded 2 files (39 bytes)
290 lfs: uploaded 2 files (39 bytes)
291 1 changesets found
291 1 changesets found
292 list of changesets:
292 list of changesets:
293 dfca2c9e2ef24996aa61ba2abd99277d884b3d63
293 dfca2c9e2ef24996aa61ba2abd99277d884b3d63
294 bundle2-output-bundle: "HG20", 5 parts total
294 bundle2-output-bundle: "HG20", 5 parts total
295 bundle2-output-part: "replycaps" * bytes payload (glob)
295 bundle2-output-part: "replycaps" * bytes payload (glob)
296 bundle2-output-part: "check:phases" 24 bytes payload
296 bundle2-output-part: "check:phases" 24 bytes payload
297 bundle2-output-part: "check:heads" streamed payload
297 bundle2-output-part: "check:heads" streamed payload
298 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
298 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
299 bundle2-output-part: "phase-heads" 24 bytes payload
299 bundle2-output-part: "phase-heads" 24 bytes payload
300 bundle2-input-bundle: with-transaction
300 bundle2-input-bundle: with-transaction
301 bundle2-input-part: "replycaps" supported
301 bundle2-input-part: "replycaps" supported
302 bundle2-input-part: total payload size * (glob)
302 bundle2-input-part: total payload size * (glob)
303 bundle2-input-part: "check:phases" supported
303 bundle2-input-part: "check:phases" supported
304 bundle2-input-part: total payload size 24
304 bundle2-input-part: total payload size 24
305 bundle2-input-part: "check:heads" supported
305 bundle2-input-part: "check:heads" supported
306 bundle2-input-part: total payload size 20
306 bundle2-input-part: total payload size 20
307 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
307 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
308 adding changesets
308 adding changesets
309 add changeset dfca2c9e2ef2
309 add changeset dfca2c9e2ef2
310 adding manifests
310 adding manifests
311 adding file changes
311 adding file changes
312 adding b revisions
312 adding b revisions
313 adding c revisions
313 adding c revisions
314 adding d revisions
314 adding d revisions
315 bundle2-input-part: total payload size 1315
315 bundle2-input-part: total payload size 1315
316 bundle2-input-part: "phase-heads" supported
316 bundle2-input-part: "phase-heads" supported
317 bundle2-input-part: total payload size 24
317 bundle2-input-part: total payload size 24
318 bundle2-input-bundle: 4 parts total
318 bundle2-input-bundle: 5 parts total
319 updating the branch cache
319 updating the branch cache
320 added 1 changesets with 3 changes to 3 files
320 added 1 changesets with 3 changes to 3 files
321 bundle2-output-bundle: "HG20", 1 parts total
321 bundle2-output-bundle: "HG20", 1 parts total
322 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
322 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
323 bundle2-input-bundle: no-transaction
323 bundle2-input-bundle: no-transaction
324 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
324 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
325 bundle2-input-bundle: 0 parts total
325 bundle2-input-bundle: 1 parts total
326 listing keys for "phases"
326 listing keys for "phases"
327
327
328 Clear the cache to force a download
328 Clear the cache to force a download
329 $ rm -rf `hg config lfs.usercache`
329 $ rm -rf `hg config lfs.usercache`
330 $ hg --repo ../repo1 update tip --debug
330 $ hg --repo ../repo1 update tip --debug
331 http auth: user foo, password ***
331 http auth: user foo, password ***
332 resolving manifests
332 resolving manifests
333 branchmerge: False, force: False, partial: False
333 branchmerge: False, force: False, partial: False
334 ancestor: 99a7098854a3, local: 99a7098854a3+, remote: dfca2c9e2ef2
334 ancestor: 99a7098854a3, local: 99a7098854a3+, remote: dfca2c9e2ef2
335 http auth: user foo, password ***
335 http auth: user foo, password ***
336 Status: 200
336 Status: 200
337 Content-Length: 608 (git-server !)
337 Content-Length: 608 (git-server !)
338 Content-Length: 670 (hg-server !)
338 Content-Length: 670 (hg-server !)
339 Content-Type: application/vnd.git-lfs+json
339 Content-Type: application/vnd.git-lfs+json
340 Date: $HTTP_DATE$
340 Date: $HTTP_DATE$
341 Server: testing stub value (hg-server !)
341 Server: testing stub value (hg-server !)
342 {
342 {
343 "objects": [
343 "objects": [
344 {
344 {
345 "actions": {
345 "actions": {
346 "download": {
346 "download": {
347 "expires_at": "$ISO_8601_DATE_TIME$"
347 "expires_at": "$ISO_8601_DATE_TIME$"
348 "header": {
348 "header": {
349 "Accept": "application/vnd.git-lfs"
349 "Accept": "application/vnd.git-lfs"
350 }
350 }
351 "href": "http://localhost:$HGPORT/*/37a65ab78d5ecda767e8622c248b5dbff1e68b1678ab0e730d5eb8601ec8ad19" (glob)
351 "href": "http://localhost:$HGPORT/*/37a65ab78d5ecda767e8622c248b5dbff1e68b1678ab0e730d5eb8601ec8ad19" (glob)
352 }
352 }
353 }
353 }
354 "oid": "37a65ab78d5ecda767e8622c248b5dbff1e68b1678ab0e730d5eb8601ec8ad19"
354 "oid": "37a65ab78d5ecda767e8622c248b5dbff1e68b1678ab0e730d5eb8601ec8ad19"
355 "size": 20
355 "size": 20
356 }
356 }
357 {
357 {
358 "actions": {
358 "actions": {
359 "download": {
359 "download": {
360 "expires_at": "$ISO_8601_DATE_TIME$"
360 "expires_at": "$ISO_8601_DATE_TIME$"
361 "header": {
361 "header": {
362 "Accept": "application/vnd.git-lfs"
362 "Accept": "application/vnd.git-lfs"
363 }
363 }
364 "href": "http://localhost:$HGPORT/*/d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998" (glob)
364 "href": "http://localhost:$HGPORT/*/d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998" (glob)
365 }
365 }
366 }
366 }
367 "oid": "d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998"
367 "oid": "d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998"
368 "size": 19
368 "size": 19
369 }
369 }
370 ]
370 ]
371 "transfer": "basic" (hg-server !)
371 "transfer": "basic" (hg-server !)
372 }
372 }
373 lfs: need to transfer 2 objects (39 bytes)
373 lfs: need to transfer 2 objects (39 bytes)
374 lfs: downloading 37a65ab78d5ecda767e8622c248b5dbff1e68b1678ab0e730d5eb8601ec8ad19 (20 bytes)
374 lfs: downloading 37a65ab78d5ecda767e8622c248b5dbff1e68b1678ab0e730d5eb8601ec8ad19 (20 bytes)
375 Status: 200
375 Status: 200
376 Content-Length: 20
376 Content-Length: 20
377 Content-Type: text/plain; charset=utf-8 (git-server !)
377 Content-Type: text/plain; charset=utf-8 (git-server !)
378 Content-Type: application/octet-stream (hg-server !)
378 Content-Type: application/octet-stream (hg-server !)
379 Date: $HTTP_DATE$
379 Date: $HTTP_DATE$
380 Server: testing stub value (hg-server !)
380 Server: testing stub value (hg-server !)
381 lfs: adding 37a65ab78d5ecda767e8622c248b5dbff1e68b1678ab0e730d5eb8601ec8ad19 to the usercache
381 lfs: adding 37a65ab78d5ecda767e8622c248b5dbff1e68b1678ab0e730d5eb8601ec8ad19 to the usercache
382 lfs: processed: 37a65ab78d5ecda767e8622c248b5dbff1e68b1678ab0e730d5eb8601ec8ad19
382 lfs: processed: 37a65ab78d5ecda767e8622c248b5dbff1e68b1678ab0e730d5eb8601ec8ad19
383 lfs: downloading d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998 (19 bytes)
383 lfs: downloading d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998 (19 bytes)
384 Status: 200
384 Status: 200
385 Content-Length: 19
385 Content-Length: 19
386 Content-Type: text/plain; charset=utf-8 (git-server !)
386 Content-Type: text/plain; charset=utf-8 (git-server !)
387 Content-Type: application/octet-stream (hg-server !)
387 Content-Type: application/octet-stream (hg-server !)
388 Date: $HTTP_DATE$
388 Date: $HTTP_DATE$
389 Server: testing stub value (hg-server !)
389 Server: testing stub value (hg-server !)
390 lfs: adding d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998 to the usercache
390 lfs: adding d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998 to the usercache
391 lfs: processed: d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998
391 lfs: processed: d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998
392 lfs: downloaded 2 files (39 bytes)
392 lfs: downloaded 2 files (39 bytes)
393 b: remote created -> g
393 b: remote created -> g
394 getting b
394 getting b
395 lfs: found 31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b in the local lfs store
395 lfs: found 31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b in the local lfs store
396 c: remote created -> g
396 c: remote created -> g
397 getting c
397 getting c
398 lfs: found d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998 in the local lfs store
398 lfs: found d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998 in the local lfs store
399 d: remote created -> g
399 d: remote created -> g
400 getting d
400 getting d
401 lfs: found 37a65ab78d5ecda767e8622c248b5dbff1e68b1678ab0e730d5eb8601ec8ad19 in the local lfs store
401 lfs: found 37a65ab78d5ecda767e8622c248b5dbff1e68b1678ab0e730d5eb8601ec8ad19 in the local lfs store
402 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
402 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
403
403
404 Test a corrupt file download, but clear the cache first to force a download.
404 Test a corrupt file download, but clear the cache first to force a download.
405 `hg serve` indicates a corrupt file without transferring it, unlike
405 `hg serve` indicates a corrupt file without transferring it, unlike
406 lfs-test-server.
406 lfs-test-server.
407
407
408 $ rm -rf `hg config lfs.usercache`
408 $ rm -rf `hg config lfs.usercache`
409 #if git-server
409 #if git-server
410 $ cp $TESTTMP/lfs-content/d1/1e/1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998 blob
410 $ cp $TESTTMP/lfs-content/d1/1e/1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998 blob
411 $ echo 'damage' > $TESTTMP/lfs-content/d1/1e/1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998
411 $ echo 'damage' > $TESTTMP/lfs-content/d1/1e/1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998
412 #else
412 #else
413 $ cp $TESTTMP/server/.hg/store/lfs/objects/d1/1e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998 blob
413 $ cp $TESTTMP/server/.hg/store/lfs/objects/d1/1e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998 blob
414 $ echo 'damage' > $TESTTMP/server/.hg/store/lfs/objects/d1/1e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998
414 $ echo 'damage' > $TESTTMP/server/.hg/store/lfs/objects/d1/1e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998
415 #endif
415 #endif
416 $ rm ../repo1/.hg/store/lfs/objects/d1/1e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998
416 $ rm ../repo1/.hg/store/lfs/objects/d1/1e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998
417 $ rm ../repo1/*
417 $ rm ../repo1/*
418
418
419 TODO: give the proper error indication from `hg serve`
419 TODO: give the proper error indication from `hg serve`
420
420
421 $ hg --repo ../repo1 update -C tip --debug
421 $ hg --repo ../repo1 update -C tip --debug
422 http auth: user foo, password ***
422 http auth: user foo, password ***
423 resolving manifests
423 resolving manifests
424 branchmerge: False, force: True, partial: False
424 branchmerge: False, force: True, partial: False
425 ancestor: dfca2c9e2ef2+, local: dfca2c9e2ef2+, remote: dfca2c9e2ef2
425 ancestor: dfca2c9e2ef2+, local: dfca2c9e2ef2+, remote: dfca2c9e2ef2
426 http auth: user foo, password ***
426 http auth: user foo, password ***
427 Status: 200
427 Status: 200
428 Content-Length: 311 (git-server !)
428 Content-Length: 311 (git-server !)
429 Content-Length: 183 (hg-server !)
429 Content-Length: 183 (hg-server !)
430 Content-Type: application/vnd.git-lfs+json
430 Content-Type: application/vnd.git-lfs+json
431 Date: $HTTP_DATE$
431 Date: $HTTP_DATE$
432 Server: testing stub value (hg-server !)
432 Server: testing stub value (hg-server !)
433 {
433 {
434 "objects": [
434 "objects": [
435 {
435 {
436 "actions": { (git-server !)
436 "actions": { (git-server !)
437 "download": { (git-server !)
437 "download": { (git-server !)
438 "expires_at": "$ISO_8601_DATE_TIME$" (git-server !)
438 "expires_at": "$ISO_8601_DATE_TIME$" (git-server !)
439 "header": { (git-server !)
439 "header": { (git-server !)
440 "Accept": "application/vnd.git-lfs" (git-server !)
440 "Accept": "application/vnd.git-lfs" (git-server !)
441 } (git-server !)
441 } (git-server !)
442 "href": "http://localhost:$HGPORT/objects/d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998" (git-server !)
442 "href": "http://localhost:$HGPORT/objects/d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998" (git-server !)
443 } (git-server !)
443 } (git-server !)
444 "error": { (hg-server !)
444 "error": { (hg-server !)
445 "code": 422 (hg-server !)
445 "code": 422 (hg-server !)
446 "message": "The object is corrupt" (hg-server !)
446 "message": "The object is corrupt" (hg-server !)
447 }
447 }
448 "oid": "d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998"
448 "oid": "d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998"
449 "size": 19
449 "size": 19
450 }
450 }
451 ]
451 ]
452 "transfer": "basic" (hg-server !)
452 "transfer": "basic" (hg-server !)
453 }
453 }
454 lfs: downloading d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998 (19 bytes) (git-server !)
454 lfs: downloading d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998 (19 bytes) (git-server !)
455 Status: 200 (git-server !)
455 Status: 200 (git-server !)
456 Content-Length: 7 (git-server !)
456 Content-Length: 7 (git-server !)
457 Content-Type: text/plain; charset=utf-8 (git-server !)
457 Content-Type: text/plain; charset=utf-8 (git-server !)
458 Date: $HTTP_DATE$ (git-server !)
458 Date: $HTTP_DATE$ (git-server !)
459 abort: corrupt remote lfs object: d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998 (git-server !)
459 abort: corrupt remote lfs object: d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998 (git-server !)
460 abort: LFS server error for "c": Validation error! (hg-server !)
460 abort: LFS server error for "c": Validation error! (hg-server !)
461 [255]
461 [255]
462
462
463 The corrupted blob is not added to the usercache or local store
463 The corrupted blob is not added to the usercache or local store
464
464
465 $ test -f ../repo1/.hg/store/lfs/objects/d1/1e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998
465 $ test -f ../repo1/.hg/store/lfs/objects/d1/1e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998
466 [1]
466 [1]
467 $ test -f `hg config lfs.usercache`/d1/1e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998
467 $ test -f `hg config lfs.usercache`/d1/1e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998
468 [1]
468 [1]
469 #if git-server
469 #if git-server
470 $ cp blob $TESTTMP/lfs-content/d1/1e/1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998
470 $ cp blob $TESTTMP/lfs-content/d1/1e/1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998
471 #else
471 #else
472 $ cp blob $TESTTMP/server/.hg/store/lfs/objects/d1/1e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998
472 $ cp blob $TESTTMP/server/.hg/store/lfs/objects/d1/1e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998
473 #endif
473 #endif
474
474
475 Test a corrupted file upload
475 Test a corrupted file upload
476
476
477 $ echo 'another lfs blob' > b
477 $ echo 'another lfs blob' > b
478 $ hg ci -m 'another blob'
478 $ hg ci -m 'another blob'
479 $ echo 'damage' > .hg/store/lfs/objects/e6/59058e26b07b39d2a9c7145b3f99b41f797b6621c8076600e9cb7ee88291f0
479 $ echo 'damage' > .hg/store/lfs/objects/e6/59058e26b07b39d2a9c7145b3f99b41f797b6621c8076600e9cb7ee88291f0
480 $ hg push --debug ../repo1
480 $ hg push --debug ../repo1
481 http auth: user foo, password ***
481 http auth: user foo, password ***
482 pushing to ../repo1
482 pushing to ../repo1
483 http auth: user foo, password ***
483 http auth: user foo, password ***
484 http auth: user foo, password ***
484 http auth: user foo, password ***
485 query 1; heads
485 query 1; heads
486 searching for changes
486 searching for changes
487 all remote heads known locally
487 all remote heads known locally
488 listing keys for "phases"
488 listing keys for "phases"
489 checking for updated bookmarks
489 checking for updated bookmarks
490 listing keys for "bookmarks"
490 listing keys for "bookmarks"
491 listing keys for "bookmarks"
491 listing keys for "bookmarks"
492 lfs: computing set of blobs to upload
492 lfs: computing set of blobs to upload
493 Status: 200
493 Status: 200
494 Content-Length: 309 (git-server !)
494 Content-Length: 309 (git-server !)
495 Content-Length: 350 (hg-server !)
495 Content-Length: 350 (hg-server !)
496 Content-Type: application/vnd.git-lfs+json
496 Content-Type: application/vnd.git-lfs+json
497 Date: $HTTP_DATE$
497 Date: $HTTP_DATE$
498 Server: testing stub value (hg-server !)
498 Server: testing stub value (hg-server !)
499 {
499 {
500 "objects": [
500 "objects": [
501 {
501 {
502 "actions": {
502 "actions": {
503 "upload": {
503 "upload": {
504 "expires_at": "$ISO_8601_DATE_TIME$"
504 "expires_at": "$ISO_8601_DATE_TIME$"
505 "header": {
505 "header": {
506 "Accept": "application/vnd.git-lfs"
506 "Accept": "application/vnd.git-lfs"
507 }
507 }
508 "href": "http://localhost:$HGPORT/*/e659058e26b07b39d2a9c7145b3f99b41f797b6621c8076600e9cb7ee88291f0" (glob)
508 "href": "http://localhost:$HGPORT/*/e659058e26b07b39d2a9c7145b3f99b41f797b6621c8076600e9cb7ee88291f0" (glob)
509 }
509 }
510 }
510 }
511 "oid": "e659058e26b07b39d2a9c7145b3f99b41f797b6621c8076600e9cb7ee88291f0"
511 "oid": "e659058e26b07b39d2a9c7145b3f99b41f797b6621c8076600e9cb7ee88291f0"
512 "size": 17
512 "size": 17
513 }
513 }
514 ]
514 ]
515 "transfer": "basic" (hg-server !)
515 "transfer": "basic" (hg-server !)
516 }
516 }
517 lfs: uploading e659058e26b07b39d2a9c7145b3f99b41f797b6621c8076600e9cb7ee88291f0 (17 bytes)
517 lfs: uploading e659058e26b07b39d2a9c7145b3f99b41f797b6621c8076600e9cb7ee88291f0 (17 bytes)
518 abort: detected corrupt lfs object: e659058e26b07b39d2a9c7145b3f99b41f797b6621c8076600e9cb7ee88291f0
518 abort: detected corrupt lfs object: e659058e26b07b39d2a9c7145b3f99b41f797b6621c8076600e9cb7ee88291f0
519 (run hg verify)
519 (run hg verify)
520 [255]
520 [255]
521
521
522 Archive will prefetch blobs in a group
522 Archive will prefetch blobs in a group
523
523
524 $ rm -rf .hg/store/lfs `hg config lfs.usercache`
524 $ rm -rf .hg/store/lfs `hg config lfs.usercache`
525 $ hg archive --debug -r 1 ../archive
525 $ hg archive --debug -r 1 ../archive
526 http auth: user foo, password ***
526 http auth: user foo, password ***
527 http auth: user foo, password ***
527 http auth: user foo, password ***
528 Status: 200
528 Status: 200
529 Content-Length: 905 (git-server !)
529 Content-Length: 905 (git-server !)
530 Content-Length: 988 (hg-server !)
530 Content-Length: 988 (hg-server !)
531 Content-Type: application/vnd.git-lfs+json
531 Content-Type: application/vnd.git-lfs+json
532 Date: $HTTP_DATE$
532 Date: $HTTP_DATE$
533 Server: testing stub value (hg-server !)
533 Server: testing stub value (hg-server !)
534 {
534 {
535 "objects": [
535 "objects": [
536 {
536 {
537 "actions": {
537 "actions": {
538 "download": {
538 "download": {
539 "expires_at": "$ISO_8601_DATE_TIME$"
539 "expires_at": "$ISO_8601_DATE_TIME$"
540 "header": {
540 "header": {
541 "Accept": "application/vnd.git-lfs"
541 "Accept": "application/vnd.git-lfs"
542 }
542 }
543 "href": "http://localhost:$HGPORT/*/31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b" (glob)
543 "href": "http://localhost:$HGPORT/*/31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b" (glob)
544 }
544 }
545 }
545 }
546 "oid": "31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b"
546 "oid": "31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b"
547 "size": 12
547 "size": 12
548 }
548 }
549 {
549 {
550 "actions": {
550 "actions": {
551 "download": {
551 "download": {
552 "expires_at": "$ISO_8601_DATE_TIME$"
552 "expires_at": "$ISO_8601_DATE_TIME$"
553 "header": {
553 "header": {
554 "Accept": "application/vnd.git-lfs"
554 "Accept": "application/vnd.git-lfs"
555 }
555 }
556 "href": "http://localhost:$HGPORT/*/37a65ab78d5ecda767e8622c248b5dbff1e68b1678ab0e730d5eb8601ec8ad19" (glob)
556 "href": "http://localhost:$HGPORT/*/37a65ab78d5ecda767e8622c248b5dbff1e68b1678ab0e730d5eb8601ec8ad19" (glob)
557 }
557 }
558 }
558 }
559 "oid": "37a65ab78d5ecda767e8622c248b5dbff1e68b1678ab0e730d5eb8601ec8ad19"
559 "oid": "37a65ab78d5ecda767e8622c248b5dbff1e68b1678ab0e730d5eb8601ec8ad19"
560 "size": 20
560 "size": 20
561 }
561 }
562 {
562 {
563 "actions": {
563 "actions": {
564 "download": {
564 "download": {
565 "expires_at": "$ISO_8601_DATE_TIME$"
565 "expires_at": "$ISO_8601_DATE_TIME$"
566 "header": {
566 "header": {
567 "Accept": "application/vnd.git-lfs"
567 "Accept": "application/vnd.git-lfs"
568 }
568 }
569 "href": "http://localhost:$HGPORT/*/d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998" (glob)
569 "href": "http://localhost:$HGPORT/*/d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998" (glob)
570 }
570 }
571 }
571 }
572 "oid": "d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998"
572 "oid": "d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998"
573 "size": 19
573 "size": 19
574 }
574 }
575 ]
575 ]
576 "transfer": "basic" (hg-server !)
576 "transfer": "basic" (hg-server !)
577 }
577 }
578 lfs: need to transfer 3 objects (51 bytes)
578 lfs: need to transfer 3 objects (51 bytes)
579 lfs: downloading 31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b (12 bytes)
579 lfs: downloading 31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b (12 bytes)
580 Status: 200
580 Status: 200
581 Content-Length: 12
581 Content-Length: 12
582 Content-Type: text/plain; charset=utf-8 (git-server !)
582 Content-Type: text/plain; charset=utf-8 (git-server !)
583 Content-Type: application/octet-stream (hg-server !)
583 Content-Type: application/octet-stream (hg-server !)
584 Date: $HTTP_DATE$
584 Date: $HTTP_DATE$
585 Server: testing stub value (hg-server !)
585 Server: testing stub value (hg-server !)
586 lfs: adding 31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b to the usercache
586 lfs: adding 31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b to the usercache
587 lfs: processed: 31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b
587 lfs: processed: 31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b
588 lfs: downloading 37a65ab78d5ecda767e8622c248b5dbff1e68b1678ab0e730d5eb8601ec8ad19 (20 bytes)
588 lfs: downloading 37a65ab78d5ecda767e8622c248b5dbff1e68b1678ab0e730d5eb8601ec8ad19 (20 bytes)
589 Status: 200
589 Status: 200
590 Content-Length: 20
590 Content-Length: 20
591 Content-Type: text/plain; charset=utf-8 (git-server !)
591 Content-Type: text/plain; charset=utf-8 (git-server !)
592 Content-Type: application/octet-stream (hg-server !)
592 Content-Type: application/octet-stream (hg-server !)
593 Date: $HTTP_DATE$
593 Date: $HTTP_DATE$
594 Server: testing stub value (hg-server !)
594 Server: testing stub value (hg-server !)
595 lfs: adding 37a65ab78d5ecda767e8622c248b5dbff1e68b1678ab0e730d5eb8601ec8ad19 to the usercache
595 lfs: adding 37a65ab78d5ecda767e8622c248b5dbff1e68b1678ab0e730d5eb8601ec8ad19 to the usercache
596 lfs: processed: 37a65ab78d5ecda767e8622c248b5dbff1e68b1678ab0e730d5eb8601ec8ad19
596 lfs: processed: 37a65ab78d5ecda767e8622c248b5dbff1e68b1678ab0e730d5eb8601ec8ad19
597 lfs: downloading d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998 (19 bytes)
597 lfs: downloading d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998 (19 bytes)
598 Status: 200
598 Status: 200
599 Content-Length: 19
599 Content-Length: 19
600 Content-Type: text/plain; charset=utf-8 (git-server !)
600 Content-Type: text/plain; charset=utf-8 (git-server !)
601 Content-Type: application/octet-stream (hg-server !)
601 Content-Type: application/octet-stream (hg-server !)
602 Date: $HTTP_DATE$
602 Date: $HTTP_DATE$
603 Server: testing stub value (hg-server !)
603 Server: testing stub value (hg-server !)
604 lfs: adding d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998 to the usercache
604 lfs: adding d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998 to the usercache
605 lfs: processed: d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998
605 lfs: processed: d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998
606 lfs: downloaded 3 files (51 bytes)
606 lfs: downloaded 3 files (51 bytes)
607 lfs: found 31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b in the local lfs store
607 lfs: found 31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b in the local lfs store
608 lfs: found 31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b in the local lfs store
608 lfs: found 31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b in the local lfs store
609 lfs: found d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998 in the local lfs store
609 lfs: found d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998 in the local lfs store
610 lfs: found 37a65ab78d5ecda767e8622c248b5dbff1e68b1678ab0e730d5eb8601ec8ad19 in the local lfs store
610 lfs: found 37a65ab78d5ecda767e8622c248b5dbff1e68b1678ab0e730d5eb8601ec8ad19 in the local lfs store
611 $ find ../archive | sort
611 $ find ../archive | sort
612 ../archive
612 ../archive
613 ../archive/.hg_archival.txt
613 ../archive/.hg_archival.txt
614 ../archive/a
614 ../archive/a
615 ../archive/b
615 ../archive/b
616 ../archive/c
616 ../archive/c
617 ../archive/d
617 ../archive/d
618
618
619 Cat will prefetch blobs in a group
619 Cat will prefetch blobs in a group
620
620
621 $ rm -rf .hg/store/lfs `hg config lfs.usercache`
621 $ rm -rf .hg/store/lfs `hg config lfs.usercache`
622 $ hg cat --debug -r 1 a b c nonexistent
622 $ hg cat --debug -r 1 a b c nonexistent
623 http auth: user foo, password ***
623 http auth: user foo, password ***
624 http auth: user foo, password ***
624 http auth: user foo, password ***
625 Status: 200
625 Status: 200
626 Content-Length: 608 (git-server !)
626 Content-Length: 608 (git-server !)
627 Content-Length: 670 (hg-server !)
627 Content-Length: 670 (hg-server !)
628 Content-Type: application/vnd.git-lfs+json
628 Content-Type: application/vnd.git-lfs+json
629 Date: $HTTP_DATE$
629 Date: $HTTP_DATE$
630 Server: testing stub value (hg-server !)
630 Server: testing stub value (hg-server !)
631 {
631 {
632 "objects": [
632 "objects": [
633 {
633 {
634 "actions": {
634 "actions": {
635 "download": {
635 "download": {
636 "expires_at": "$ISO_8601_DATE_TIME$"
636 "expires_at": "$ISO_8601_DATE_TIME$"
637 "header": {
637 "header": {
638 "Accept": "application/vnd.git-lfs"
638 "Accept": "application/vnd.git-lfs"
639 }
639 }
640 "href": "http://localhost:$HGPORT/*/31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b" (glob)
640 "href": "http://localhost:$HGPORT/*/31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b" (glob)
641 }
641 }
642 }
642 }
643 "oid": "31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b"
643 "oid": "31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b"
644 "size": 12
644 "size": 12
645 }
645 }
646 {
646 {
647 "actions": {
647 "actions": {
648 "download": {
648 "download": {
649 "expires_at": "$ISO_8601_DATE_TIME$"
649 "expires_at": "$ISO_8601_DATE_TIME$"
650 "header": {
650 "header": {
651 "Accept": "application/vnd.git-lfs"
651 "Accept": "application/vnd.git-lfs"
652 }
652 }
653 "href": "http://localhost:$HGPORT/*/d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998" (glob)
653 "href": "http://localhost:$HGPORT/*/d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998" (glob)
654 }
654 }
655 }
655 }
656 "oid": "d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998"
656 "oid": "d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998"
657 "size": 19
657 "size": 19
658 }
658 }
659 ]
659 ]
660 "transfer": "basic" (hg-server !)
660 "transfer": "basic" (hg-server !)
661 }
661 }
662 lfs: need to transfer 2 objects (31 bytes)
662 lfs: need to transfer 2 objects (31 bytes)
663 lfs: downloading 31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b (12 bytes)
663 lfs: downloading 31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b (12 bytes)
664 Status: 200
664 Status: 200
665 Content-Length: 12
665 Content-Length: 12
666 Content-Type: text/plain; charset=utf-8 (git-server !)
666 Content-Type: text/plain; charset=utf-8 (git-server !)
667 Content-Type: application/octet-stream (hg-server !)
667 Content-Type: application/octet-stream (hg-server !)
668 Date: $HTTP_DATE$
668 Date: $HTTP_DATE$
669 Server: testing stub value (hg-server !)
669 Server: testing stub value (hg-server !)
670 lfs: adding 31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b to the usercache
670 lfs: adding 31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b to the usercache
671 lfs: processed: 31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b
671 lfs: processed: 31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b
672 lfs: downloading d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998 (19 bytes)
672 lfs: downloading d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998 (19 bytes)
673 Status: 200
673 Status: 200
674 Content-Length: 19
674 Content-Length: 19
675 Content-Type: text/plain; charset=utf-8 (git-server !)
675 Content-Type: text/plain; charset=utf-8 (git-server !)
676 Content-Type: application/octet-stream (hg-server !)
676 Content-Type: application/octet-stream (hg-server !)
677 Date: $HTTP_DATE$
677 Date: $HTTP_DATE$
678 Server: testing stub value (hg-server !)
678 Server: testing stub value (hg-server !)
679 lfs: adding d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998 to the usercache
679 lfs: adding d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998 to the usercache
680 lfs: processed: d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998
680 lfs: processed: d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998
681 lfs: downloaded 2 files (31 bytes)
681 lfs: downloaded 2 files (31 bytes)
682 lfs: found 31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b in the local lfs store
682 lfs: found 31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b in the local lfs store
683 THIS-IS-LFS
683 THIS-IS-LFS
684 lfs: found 31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b in the local lfs store
684 lfs: found 31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b in the local lfs store
685 THIS-IS-LFS
685 THIS-IS-LFS
686 lfs: found d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998 in the local lfs store
686 lfs: found d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998 in the local lfs store
687 ANOTHER-LARGE-FILE
687 ANOTHER-LARGE-FILE
688 nonexistent: no such file in rev dfca2c9e2ef2
688 nonexistent: no such file in rev dfca2c9e2ef2
689
689
690 Revert will prefetch blobs in a group
690 Revert will prefetch blobs in a group
691
691
692 $ rm -rf .hg/store/lfs
692 $ rm -rf .hg/store/lfs
693 $ rm -rf `hg config lfs.usercache`
693 $ rm -rf `hg config lfs.usercache`
694 $ rm *
694 $ rm *
695 $ hg revert --all -r 1 --debug
695 $ hg revert --all -r 1 --debug
696 http auth: user foo, password ***
696 http auth: user foo, password ***
697 http auth: user foo, password ***
697 http auth: user foo, password ***
698 Status: 200
698 Status: 200
699 Content-Length: 905 (git-server !)
699 Content-Length: 905 (git-server !)
700 Content-Length: 988 (hg-server !)
700 Content-Length: 988 (hg-server !)
701 Content-Type: application/vnd.git-lfs+json
701 Content-Type: application/vnd.git-lfs+json
702 Date: $HTTP_DATE$
702 Date: $HTTP_DATE$
703 Server: testing stub value (hg-server !)
703 Server: testing stub value (hg-server !)
704 {
704 {
705 "objects": [
705 "objects": [
706 {
706 {
707 "actions": {
707 "actions": {
708 "download": {
708 "download": {
709 "expires_at": "$ISO_8601_DATE_TIME$"
709 "expires_at": "$ISO_8601_DATE_TIME$"
710 "header": {
710 "header": {
711 "Accept": "application/vnd.git-lfs"
711 "Accept": "application/vnd.git-lfs"
712 }
712 }
713 "href": "http://localhost:$HGPORT/*/31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b" (glob)
713 "href": "http://localhost:$HGPORT/*/31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b" (glob)
714 }
714 }
715 }
715 }
716 "oid": "31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b"
716 "oid": "31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b"
717 "size": 12
717 "size": 12
718 }
718 }
719 {
719 {
720 "actions": {
720 "actions": {
721 "download": {
721 "download": {
722 "expires_at": "$ISO_8601_DATE_TIME$"
722 "expires_at": "$ISO_8601_DATE_TIME$"
723 "header": {
723 "header": {
724 "Accept": "application/vnd.git-lfs"
724 "Accept": "application/vnd.git-lfs"
725 }
725 }
726 "href": "http://localhost:$HGPORT/*/37a65ab78d5ecda767e8622c248b5dbff1e68b1678ab0e730d5eb8601ec8ad19" (glob)
726 "href": "http://localhost:$HGPORT/*/37a65ab78d5ecda767e8622c248b5dbff1e68b1678ab0e730d5eb8601ec8ad19" (glob)
727 }
727 }
728 }
728 }
729 "oid": "37a65ab78d5ecda767e8622c248b5dbff1e68b1678ab0e730d5eb8601ec8ad19"
729 "oid": "37a65ab78d5ecda767e8622c248b5dbff1e68b1678ab0e730d5eb8601ec8ad19"
730 "size": 20
730 "size": 20
731 }
731 }
732 {
732 {
733 "actions": {
733 "actions": {
734 "download": {
734 "download": {
735 "expires_at": "$ISO_8601_DATE_TIME$"
735 "expires_at": "$ISO_8601_DATE_TIME$"
736 "header": {
736 "header": {
737 "Accept": "application/vnd.git-lfs"
737 "Accept": "application/vnd.git-lfs"
738 }
738 }
739 "href": "http://localhost:$HGPORT/*/d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998" (glob)
739 "href": "http://localhost:$HGPORT/*/d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998" (glob)
740 }
740 }
741 }
741 }
742 "oid": "d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998"
742 "oid": "d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998"
743 "size": 19
743 "size": 19
744 }
744 }
745 ]
745 ]
746 "transfer": "basic" (hg-server !)
746 "transfer": "basic" (hg-server !)
747 }
747 }
748 lfs: need to transfer 3 objects (51 bytes)
748 lfs: need to transfer 3 objects (51 bytes)
749 lfs: downloading 31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b (12 bytes)
749 lfs: downloading 31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b (12 bytes)
750 Status: 200
750 Status: 200
751 Content-Length: 12
751 Content-Length: 12
752 Content-Type: text/plain; charset=utf-8 (git-server !)
752 Content-Type: text/plain; charset=utf-8 (git-server !)
753 Content-Type: application/octet-stream (hg-server !)
753 Content-Type: application/octet-stream (hg-server !)
754 Date: $HTTP_DATE$
754 Date: $HTTP_DATE$
755 Server: testing stub value (hg-server !)
755 Server: testing stub value (hg-server !)
756 lfs: adding 31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b to the usercache
756 lfs: adding 31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b to the usercache
757 lfs: processed: 31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b
757 lfs: processed: 31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b
758 lfs: downloading 37a65ab78d5ecda767e8622c248b5dbff1e68b1678ab0e730d5eb8601ec8ad19 (20 bytes)
758 lfs: downloading 37a65ab78d5ecda767e8622c248b5dbff1e68b1678ab0e730d5eb8601ec8ad19 (20 bytes)
759 Status: 200
759 Status: 200
760 Content-Length: 20
760 Content-Length: 20
761 Content-Type: text/plain; charset=utf-8 (git-server !)
761 Content-Type: text/plain; charset=utf-8 (git-server !)
762 Content-Type: application/octet-stream (hg-server !)
762 Content-Type: application/octet-stream (hg-server !)
763 Date: $HTTP_DATE$
763 Date: $HTTP_DATE$
764 Server: testing stub value (hg-server !)
764 Server: testing stub value (hg-server !)
765 lfs: adding 37a65ab78d5ecda767e8622c248b5dbff1e68b1678ab0e730d5eb8601ec8ad19 to the usercache
765 lfs: adding 37a65ab78d5ecda767e8622c248b5dbff1e68b1678ab0e730d5eb8601ec8ad19 to the usercache
766 lfs: processed: 37a65ab78d5ecda767e8622c248b5dbff1e68b1678ab0e730d5eb8601ec8ad19
766 lfs: processed: 37a65ab78d5ecda767e8622c248b5dbff1e68b1678ab0e730d5eb8601ec8ad19
767 lfs: downloading d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998 (19 bytes)
767 lfs: downloading d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998 (19 bytes)
768 Status: 200
768 Status: 200
769 Content-Length: 19
769 Content-Length: 19
770 Content-Type: text/plain; charset=utf-8 (git-server !)
770 Content-Type: text/plain; charset=utf-8 (git-server !)
771 Content-Type: application/octet-stream (hg-server !)
771 Content-Type: application/octet-stream (hg-server !)
772 Date: $HTTP_DATE$
772 Date: $HTTP_DATE$
773 Server: testing stub value (hg-server !)
773 Server: testing stub value (hg-server !)
774 lfs: adding d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998 to the usercache
774 lfs: adding d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998 to the usercache
775 lfs: processed: d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998
775 lfs: processed: d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998
776 lfs: downloaded 3 files (51 bytes)
776 lfs: downloaded 3 files (51 bytes)
777 reverting b
777 reverting b
778 lfs: found 31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b in the local lfs store
778 lfs: found 31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b in the local lfs store
779 reverting c
779 reverting c
780 lfs: found d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998 in the local lfs store
780 lfs: found d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998 in the local lfs store
781 reverting d
781 reverting d
782 lfs: found 37a65ab78d5ecda767e8622c248b5dbff1e68b1678ab0e730d5eb8601ec8ad19 in the local lfs store
782 lfs: found 37a65ab78d5ecda767e8622c248b5dbff1e68b1678ab0e730d5eb8601ec8ad19 in the local lfs store
783 adding a
783 adding a
784 lfs: found 31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b in the local lfs store
784 lfs: found 31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b in the local lfs store
785
785
786 Check error message when the remote missed a blob:
786 Check error message when the remote missed a blob:
787
787
788 $ echo FFFFF > b
788 $ echo FFFFF > b
789 $ hg commit -m b -A b
789 $ hg commit -m b -A b
790 $ echo FFFFF >> b
790 $ echo FFFFF >> b
791 $ hg commit -m b b
791 $ hg commit -m b b
792 $ rm -rf .hg/store/lfs
792 $ rm -rf .hg/store/lfs
793 $ rm -rf `hg config lfs.usercache`
793 $ rm -rf `hg config lfs.usercache`
794 $ hg update -C '.^' --debug
794 $ hg update -C '.^' --debug
795 http auth: user foo, password ***
795 http auth: user foo, password ***
796 resolving manifests
796 resolving manifests
797 branchmerge: False, force: True, partial: False
797 branchmerge: False, force: True, partial: False
798 ancestor: 62fdbaf221c6+, local: 62fdbaf221c6+, remote: ef0564edf47e
798 ancestor: 62fdbaf221c6+, local: 62fdbaf221c6+, remote: ef0564edf47e
799 http auth: user foo, password ***
799 http auth: user foo, password ***
800 Status: 200
800 Status: 200
801 Content-Length: 308 (git-server !)
801 Content-Length: 308 (git-server !)
802 Content-Length: 186 (hg-server !)
802 Content-Length: 186 (hg-server !)
803 Content-Type: application/vnd.git-lfs+json
803 Content-Type: application/vnd.git-lfs+json
804 Date: $HTTP_DATE$
804 Date: $HTTP_DATE$
805 Server: testing stub value (hg-server !)
805 Server: testing stub value (hg-server !)
806 {
806 {
807 "objects": [
807 "objects": [
808 {
808 {
809 "actions": { (git-server !)
809 "actions": { (git-server !)
810 "upload": { (git-server !)
810 "upload": { (git-server !)
811 "expires_at": "$ISO_8601_DATE_TIME$" (git-server !)
811 "expires_at": "$ISO_8601_DATE_TIME$" (git-server !)
812 "header": { (git-server !)
812 "header": { (git-server !)
813 "Accept": "application/vnd.git-lfs" (git-server !)
813 "Accept": "application/vnd.git-lfs" (git-server !)
814 } (git-server !)
814 } (git-server !)
815 "href": "http://localhost:$HGPORT/objects/8e6ea5f6c066b44a0efa43bcce86aea73f17e6e23f0663df0251e7524e140a13" (git-server !)
815 "href": "http://localhost:$HGPORT/objects/8e6ea5f6c066b44a0efa43bcce86aea73f17e6e23f0663df0251e7524e140a13" (git-server !)
816 } (git-server !)
816 } (git-server !)
817 "error": { (hg-server !)
817 "error": { (hg-server !)
818 "code": 404 (hg-server !)
818 "code": 404 (hg-server !)
819 "message": "The object does not exist" (hg-server !)
819 "message": "The object does not exist" (hg-server !)
820 }
820 }
821 "oid": "8e6ea5f6c066b44a0efa43bcce86aea73f17e6e23f0663df0251e7524e140a13"
821 "oid": "8e6ea5f6c066b44a0efa43bcce86aea73f17e6e23f0663df0251e7524e140a13"
822 "size": 6
822 "size": 6
823 }
823 }
824 ]
824 ]
825 "transfer": "basic" (hg-server !)
825 "transfer": "basic" (hg-server !)
826 }
826 }
827 abort: LFS server error for "b": The object does not exist!
827 abort: LFS server error for "b": The object does not exist!
828 [255]
828 [255]
829
829
830 Check error message when object does not exist:
830 Check error message when object does not exist:
831
831
832 $ cd $TESTTMP
832 $ cd $TESTTMP
833 $ hg init test && cd test
833 $ hg init test && cd test
834 $ echo "[extensions]" >> .hg/hgrc
834 $ echo "[extensions]" >> .hg/hgrc
835 $ echo "lfs=" >> .hg/hgrc
835 $ echo "lfs=" >> .hg/hgrc
836 $ echo "[lfs]" >> .hg/hgrc
836 $ echo "[lfs]" >> .hg/hgrc
837 $ echo "threshold=1" >> .hg/hgrc
837 $ echo "threshold=1" >> .hg/hgrc
838 $ echo a > a
838 $ echo a > a
839 $ hg add a
839 $ hg add a
840 $ hg commit -m 'test'
840 $ hg commit -m 'test'
841 $ echo aaaaa > a
841 $ echo aaaaa > a
842 $ hg commit -m 'largefile'
842 $ hg commit -m 'largefile'
843 $ hg debugdata a 1 # verify this is no the file content but includes "oid", the LFS "pointer".
843 $ hg debugdata a 1 # verify this is no the file content but includes "oid", the LFS "pointer".
844 version https://git-lfs.github.com/spec/v1
844 version https://git-lfs.github.com/spec/v1
845 oid sha256:bdc26931acfb734b142a8d675f205becf27560dc461f501822de13274fe6fc8a
845 oid sha256:bdc26931acfb734b142a8d675f205becf27560dc461f501822de13274fe6fc8a
846 size 6
846 size 6
847 x-is-binary 0
847 x-is-binary 0
848 $ cd ..
848 $ cd ..
849 $ rm -rf `hg config lfs.usercache`
849 $ rm -rf `hg config lfs.usercache`
850
850
851 (Restart the server in a different location so it no longer has the content)
851 (Restart the server in a different location so it no longer has the content)
852
852
853 $ "$PYTHON" $RUNTESTDIR/killdaemons.py $DAEMON_PIDS
853 $ "$PYTHON" $RUNTESTDIR/killdaemons.py $DAEMON_PIDS
854
854
855 #if hg-server
855 #if hg-server
856 $ cat $TESTTMP/access.log $TESTTMP/errors.log
856 $ cat $TESTTMP/access.log $TESTTMP/errors.log
857 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
857 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
858 $LOCALIP - - [$LOGDATE$] "PUT /.hg/lfs/objects/31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b HTTP/1.1" 201 - (glob)
858 $LOCALIP - - [$LOGDATE$] "PUT /.hg/lfs/objects/31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b HTTP/1.1" 201 - (glob)
859 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
859 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
860 $LOCALIP - - [$LOGDATE$] "GET /.hg/lfs/objects/31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b HTTP/1.1" 200 - (glob)
860 $LOCALIP - - [$LOGDATE$] "GET /.hg/lfs/objects/31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b HTTP/1.1" 200 - (glob)
861 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
861 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
862 $LOCALIP - - [$LOGDATE$] "PUT /.hg/lfs/objects/37a65ab78d5ecda767e8622c248b5dbff1e68b1678ab0e730d5eb8601ec8ad19 HTTP/1.1" 201 - (glob)
862 $LOCALIP - - [$LOGDATE$] "PUT /.hg/lfs/objects/37a65ab78d5ecda767e8622c248b5dbff1e68b1678ab0e730d5eb8601ec8ad19 HTTP/1.1" 201 - (glob)
863 $LOCALIP - - [$LOGDATE$] "PUT /.hg/lfs/objects/d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998 HTTP/1.1" 201 - (glob)
863 $LOCALIP - - [$LOGDATE$] "PUT /.hg/lfs/objects/d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998 HTTP/1.1" 201 - (glob)
864 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
864 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
865 $LOCALIP - - [$LOGDATE$] "GET /.hg/lfs/objects/37a65ab78d5ecda767e8622c248b5dbff1e68b1678ab0e730d5eb8601ec8ad19 HTTP/1.1" 200 - (glob)
865 $LOCALIP - - [$LOGDATE$] "GET /.hg/lfs/objects/37a65ab78d5ecda767e8622c248b5dbff1e68b1678ab0e730d5eb8601ec8ad19 HTTP/1.1" 200 - (glob)
866 $LOCALIP - - [$LOGDATE$] "GET /.hg/lfs/objects/d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998 HTTP/1.1" 200 - (glob)
866 $LOCALIP - - [$LOGDATE$] "GET /.hg/lfs/objects/d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998 HTTP/1.1" 200 - (glob)
867 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
867 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
868 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
868 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
869 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
869 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
870 $LOCALIP - - [$LOGDATE$] "GET /.hg/lfs/objects/31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b HTTP/1.1" 200 - (glob)
870 $LOCALIP - - [$LOGDATE$] "GET /.hg/lfs/objects/31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b HTTP/1.1" 200 - (glob)
871 $LOCALIP - - [$LOGDATE$] "GET /.hg/lfs/objects/37a65ab78d5ecda767e8622c248b5dbff1e68b1678ab0e730d5eb8601ec8ad19 HTTP/1.1" 200 - (glob)
871 $LOCALIP - - [$LOGDATE$] "GET /.hg/lfs/objects/37a65ab78d5ecda767e8622c248b5dbff1e68b1678ab0e730d5eb8601ec8ad19 HTTP/1.1" 200 - (glob)
872 $LOCALIP - - [$LOGDATE$] "GET /.hg/lfs/objects/d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998 HTTP/1.1" 200 - (glob)
872 $LOCALIP - - [$LOGDATE$] "GET /.hg/lfs/objects/d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998 HTTP/1.1" 200 - (glob)
873 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
873 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
874 $LOCALIP - - [$LOGDATE$] "GET /.hg/lfs/objects/31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b HTTP/1.1" 200 - (glob)
874 $LOCALIP - - [$LOGDATE$] "GET /.hg/lfs/objects/31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b HTTP/1.1" 200 - (glob)
875 $LOCALIP - - [$LOGDATE$] "GET /.hg/lfs/objects/d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998 HTTP/1.1" 200 - (glob)
875 $LOCALIP - - [$LOGDATE$] "GET /.hg/lfs/objects/d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998 HTTP/1.1" 200 - (glob)
876 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
876 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
877 $LOCALIP - - [$LOGDATE$] "GET /.hg/lfs/objects/31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b HTTP/1.1" 200 - (glob)
877 $LOCALIP - - [$LOGDATE$] "GET /.hg/lfs/objects/31cf46fbc4ecd458a0943c5b4881f1f5a6dd36c53d6167d5b69ac45149b38e5b HTTP/1.1" 200 - (glob)
878 $LOCALIP - - [$LOGDATE$] "GET /.hg/lfs/objects/37a65ab78d5ecda767e8622c248b5dbff1e68b1678ab0e730d5eb8601ec8ad19 HTTP/1.1" 200 - (glob)
878 $LOCALIP - - [$LOGDATE$] "GET /.hg/lfs/objects/37a65ab78d5ecda767e8622c248b5dbff1e68b1678ab0e730d5eb8601ec8ad19 HTTP/1.1" 200 - (glob)
879 $LOCALIP - - [$LOGDATE$] "GET /.hg/lfs/objects/d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998 HTTP/1.1" 200 - (glob)
879 $LOCALIP - - [$LOGDATE$] "GET /.hg/lfs/objects/d11e1a642b60813aee592094109b406089b8dff4cb157157f753418ec7857998 HTTP/1.1" 200 - (glob)
880 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
880 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
881 #endif
881 #endif
882
882
883 $ mkdir $TESTTMP/lfs-server2
883 $ mkdir $TESTTMP/lfs-server2
884 $ cd $TESTTMP/lfs-server2
884 $ cd $TESTTMP/lfs-server2
885 #if no-windows git-server
885 #if no-windows git-server
886 $ lfs-test-server &> lfs-server.log &
886 $ lfs-test-server &> lfs-server.log &
887 $ echo $! >> $DAEMON_PIDS
887 $ echo $! >> $DAEMON_PIDS
888 #endif
888 #endif
889
889
890 #if windows git-server
890 #if windows git-server
891 $ "$PYTHON" $TESTTMP/spawn.py >> $DAEMON_PIDS
891 $ "$PYTHON" $TESTTMP/spawn.py >> $DAEMON_PIDS
892 #endif
892 #endif
893
893
894 #if hg-server
894 #if hg-server
895 $ hg init server2
895 $ hg init server2
896 $ hg --config "lfs.usercache=$TESTTMP/servercache2" -R server2 serve -d \
896 $ hg --config "lfs.usercache=$TESTTMP/servercache2" -R server2 serve -d \
897 > -p $HGPORT --pid-file=hg.pid -A $TESTTMP/access.log -E $TESTTMP/errors.log
897 > -p $HGPORT --pid-file=hg.pid -A $TESTTMP/access.log -E $TESTTMP/errors.log
898 $ cat hg.pid >> $DAEMON_PIDS
898 $ cat hg.pid >> $DAEMON_PIDS
899 #endif
899 #endif
900
900
901 $ cd $TESTTMP
901 $ cd $TESTTMP
902 $ hg --debug clone test test2
902 $ hg --debug clone test test2
903 http auth: user foo, password ***
903 http auth: user foo, password ***
904 linked 6 files
904 linked 6 files
905 http auth: user foo, password ***
905 http auth: user foo, password ***
906 updating to branch default
906 updating to branch default
907 resolving manifests
907 resolving manifests
908 branchmerge: False, force: False, partial: False
908 branchmerge: False, force: False, partial: False
909 ancestor: 000000000000, local: 000000000000+, remote: d2a338f184a8
909 ancestor: 000000000000, local: 000000000000+, remote: d2a338f184a8
910 http auth: user foo, password ***
910 http auth: user foo, password ***
911 Status: 200
911 Status: 200
912 Content-Length: 308 (git-server !)
912 Content-Length: 308 (git-server !)
913 Content-Length: 186 (hg-server !)
913 Content-Length: 186 (hg-server !)
914 Content-Type: application/vnd.git-lfs+json
914 Content-Type: application/vnd.git-lfs+json
915 Date: $HTTP_DATE$
915 Date: $HTTP_DATE$
916 Server: testing stub value (hg-server !)
916 Server: testing stub value (hg-server !)
917 {
917 {
918 "objects": [
918 "objects": [
919 {
919 {
920 "actions": { (git-server !)
920 "actions": { (git-server !)
921 "upload": { (git-server !)
921 "upload": { (git-server !)
922 "expires_at": "$ISO_8601_DATE_TIME$" (git-server !)
922 "expires_at": "$ISO_8601_DATE_TIME$" (git-server !)
923 "header": { (git-server !)
923 "header": { (git-server !)
924 "Accept": "application/vnd.git-lfs" (git-server !)
924 "Accept": "application/vnd.git-lfs" (git-server !)
925 } (git-server !)
925 } (git-server !)
926 "href": "http://localhost:$HGPORT/objects/bdc26931acfb734b142a8d675f205becf27560dc461f501822de13274fe6fc8a" (git-server !)
926 "href": "http://localhost:$HGPORT/objects/bdc26931acfb734b142a8d675f205becf27560dc461f501822de13274fe6fc8a" (git-server !)
927 } (git-server !)
927 } (git-server !)
928 "error": { (hg-server !)
928 "error": { (hg-server !)
929 "code": 404 (hg-server !)
929 "code": 404 (hg-server !)
930 "message": "The object does not exist" (hg-server !)
930 "message": "The object does not exist" (hg-server !)
931 }
931 }
932 "oid": "bdc26931acfb734b142a8d675f205becf27560dc461f501822de13274fe6fc8a"
932 "oid": "bdc26931acfb734b142a8d675f205becf27560dc461f501822de13274fe6fc8a"
933 "size": 6
933 "size": 6
934 }
934 }
935 ]
935 ]
936 "transfer": "basic" (hg-server !)
936 "transfer": "basic" (hg-server !)
937 }
937 }
938 abort: LFS server error for "a": The object does not exist!
938 abort: LFS server error for "a": The object does not exist!
939 [255]
939 [255]
940
940
941 $ "$PYTHON" $RUNTESTDIR/killdaemons.py $DAEMON_PIDS
941 $ "$PYTHON" $RUNTESTDIR/killdaemons.py $DAEMON_PIDS
@@ -1,425 +1,425 b''
1 #testcases tree flat
1 #testcases tree flat
2 $ . "$TESTDIR/narrow-library.sh"
2 $ . "$TESTDIR/narrow-library.sh"
3
3
4 #if tree
4 #if tree
5 $ cat << EOF >> $HGRCPATH
5 $ cat << EOF >> $HGRCPATH
6 > [experimental]
6 > [experimental]
7 > treemanifest = 1
7 > treemanifest = 1
8 > EOF
8 > EOF
9 #endif
9 #endif
10
10
11 $ hg init master
11 $ hg init master
12 $ cd master
12 $ cd master
13
13
14 $ mkdir inside
14 $ mkdir inside
15 $ echo 'inside' > inside/f
15 $ echo 'inside' > inside/f
16 $ hg add inside/f
16 $ hg add inside/f
17 $ hg commit -m 'add inside'
17 $ hg commit -m 'add inside'
18
18
19 $ mkdir widest
19 $ mkdir widest
20 $ echo 'widest' > widest/f
20 $ echo 'widest' > widest/f
21 $ hg add widest/f
21 $ hg add widest/f
22 $ hg commit -m 'add widest'
22 $ hg commit -m 'add widest'
23
23
24 $ mkdir outside
24 $ mkdir outside
25 $ echo 'outside' > outside/f
25 $ echo 'outside' > outside/f
26 $ hg add outside/f
26 $ hg add outside/f
27 $ hg commit -m 'add outside'
27 $ hg commit -m 'add outside'
28
28
29 $ cd ..
29 $ cd ..
30
30
31 narrow clone the inside file
31 narrow clone the inside file
32
32
33 $ hg clone --narrow ssh://user@dummy/master narrow
33 $ hg clone --narrow ssh://user@dummy/master narrow
34 requesting all changes
34 requesting all changes
35 adding changesets
35 adding changesets
36 adding manifests
36 adding manifests
37 adding file changes
37 adding file changes
38 added 3 changesets with 0 changes to 0 files
38 added 3 changesets with 0 changes to 0 files
39 new changesets *:* (glob)
39 new changesets *:* (glob)
40 updating to branch default
40 updating to branch default
41 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
41 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
42 $ cd narrow
42 $ cd narrow
43 $ hg tracked
43 $ hg tracked
44 $ hg files
44 $ hg files
45 [1]
45 [1]
46
46
47 widen from an empty clone
47 widen from an empty clone
48
48
49 $ hg tracked --addinclude inside
49 $ hg tracked --addinclude inside
50 comparing with ssh://user@dummy/master
50 comparing with ssh://user@dummy/master
51 searching for changes
51 searching for changes
52 adding changesets
52 adding changesets
53 adding manifests
53 adding manifests
54 adding file changes
54 adding file changes
55 added 0 changesets with 1 changes to 1 files
55 added 0 changesets with 1 changes to 1 files
56 $ hg tracked
56 $ hg tracked
57 I path:inside
57 I path:inside
58 $ ls
58 $ ls
59 inside
59 inside
60 $ cat inside/f
60 $ cat inside/f
61 inside
61 inside
62 $ cd ..
62 $ cd ..
63
63
64 add more upstream files which we will include in a wider narrow spec
64 add more upstream files which we will include in a wider narrow spec
65
65
66 $ cd master
66 $ cd master
67
67
68 $ mkdir wider
68 $ mkdir wider
69 $ echo 'wider' > wider/f
69 $ echo 'wider' > wider/f
70 $ hg add wider/f
70 $ hg add wider/f
71 $ echo 'widest v2' > widest/f
71 $ echo 'widest v2' > widest/f
72 $ hg commit -m 'add wider, update widest'
72 $ hg commit -m 'add wider, update widest'
73
73
74 $ echo 'widest v3' > widest/f
74 $ echo 'widest v3' > widest/f
75 $ hg commit -m 'update widest v3'
75 $ hg commit -m 'update widest v3'
76
76
77 $ echo 'inside v2' > inside/f
77 $ echo 'inside v2' > inside/f
78 $ hg commit -m 'update inside'
78 $ hg commit -m 'update inside'
79
79
80 $ mkdir outside2
80 $ mkdir outside2
81 $ echo 'outside2' > outside2/f
81 $ echo 'outside2' > outside2/f
82 $ hg add outside2/f
82 $ hg add outside2/f
83 $ hg commit -m 'add outside2'
83 $ hg commit -m 'add outside2'
84
84
85 $ echo 'widest v4' > widest/f
85 $ echo 'widest v4' > widest/f
86 $ hg commit -m 'update widest v4'
86 $ hg commit -m 'update widest v4'
87
87
88 $ hg log -T "{if(ellipsis, '...')}{rev}: {desc}\n"
88 $ hg log -T "{if(ellipsis, '...')}{rev}: {desc}\n"
89 7: update widest v4
89 7: update widest v4
90 6: add outside2
90 6: add outside2
91 5: update inside
91 5: update inside
92 4: update widest v3
92 4: update widest v3
93 3: add wider, update widest
93 3: add wider, update widest
94 2: add outside
94 2: add outside
95 1: add widest
95 1: add widest
96 0: add inside
96 0: add inside
97
97
98 $ cd ..
98 $ cd ..
99
99
100 Widen the narrow spec to see the widest file. This should not get the newly
100 Widen the narrow spec to see the widest file. This should not get the newly
101 added upstream revisions.
101 added upstream revisions.
102
102
103 $ cd narrow
103 $ cd narrow
104 $ hg id -n
104 $ hg id -n
105 2
105 2
106
106
107 $ hg tracked --addinclude widest/f --debug
107 $ hg tracked --addinclude widest/f --debug
108 comparing with ssh://user@dummy/master
108 comparing with ssh://user@dummy/master
109 running python "*dummyssh" *user@dummy* *hg -R master serve --stdio* (glob)
109 running python "*dummyssh" *user@dummy* *hg -R master serve --stdio* (glob)
110 sending hello command
110 sending hello command
111 sending between command
111 sending between command
112 remote: * (glob)
112 remote: * (glob)
113 remote: capabilities: * (glob)
113 remote: capabilities: * (glob)
114 remote: 1
114 remote: 1
115 sending protocaps command
115 sending protocaps command
116 query 1; heads
116 query 1; heads
117 sending batch command
117 sending batch command
118 searching for changes
118 searching for changes
119 all local changesets known remotely
119 all local changesets known remotely
120 sending narrow_widen command
120 sending narrow_widen command
121 bundle2-input-bundle: with-transaction
121 bundle2-input-bundle: with-transaction
122 bundle2-input-part: "changegroup" (params: * mandatory) supported (glob)
122 bundle2-input-part: "changegroup" (params: * mandatory) supported (glob)
123 adding changesets
123 adding changesets
124 adding manifests
124 adding manifests
125 adding widest/ revisions (tree !)
125 adding widest/ revisions (tree !)
126 adding file changes
126 adding file changes
127 adding widest/f revisions
127 adding widest/f revisions
128 bundle2-input-part: total payload size * (glob)
128 bundle2-input-part: total payload size * (glob)
129 bundle2-input-bundle: 0 parts total
129 bundle2-input-bundle: 1 parts total
130 added 0 changesets with 1 changes to 1 files
130 added 0 changesets with 1 changes to 1 files
131 widest/f: narrowspec updated -> g
131 widest/f: narrowspec updated -> g
132 getting widest/f
132 getting widest/f
133 $ hg tracked
133 $ hg tracked
134 I path:inside
134 I path:inside
135 I path:widest/f
135 I path:widest/f
136
136
137 $ cat widest/f
137 $ cat widest/f
138 widest
138 widest
139
139
140 $ hg id -n
140 $ hg id -n
141 2
141 2
142
142
143 Test that extending already included files should not call narrow_widen
143 Test that extending already included files should not call narrow_widen
144 wireprotocol command
144 wireprotocol command
145
145
146 $ hg tracked --addinclude widest/f
146 $ hg tracked --addinclude widest/f
147 nothing to widen or narrow
147 nothing to widen or narrow
148
148
149 Pull down the newly added upstream revision.
149 Pull down the newly added upstream revision.
150
150
151 $ hg pull
151 $ hg pull
152 pulling from ssh://user@dummy/master
152 pulling from ssh://user@dummy/master
153 searching for changes
153 searching for changes
154 adding changesets
154 adding changesets
155 adding manifests
155 adding manifests
156 adding file changes
156 adding file changes
157 added 5 changesets with 4 changes to 2 files
157 added 5 changesets with 4 changes to 2 files
158 new changesets *:* (glob)
158 new changesets *:* (glob)
159 (run 'hg update' to get a working copy)
159 (run 'hg update' to get a working copy)
160 $ hg update -r 'desc("add wider")'
160 $ hg update -r 'desc("add wider")'
161 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
161 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
162
162
163 $ cat widest/f
163 $ cat widest/f
164 widest v2
164 widest v2
165
165
166 $ hg update -r 'desc("update inside")'
166 $ hg update -r 'desc("update inside")'
167 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
167 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
168 $ cat widest/f
168 $ cat widest/f
169 widest v3
169 widest v3
170 $ cat inside/f
170 $ cat inside/f
171 inside v2
171 inside v2
172
172
173 $ hg log -T "{if(ellipsis, '...')}{rev}: {desc}\n"
173 $ hg log -T "{if(ellipsis, '...')}{rev}: {desc}\n"
174 7: update widest v4
174 7: update widest v4
175 6: add outside2
175 6: add outside2
176 5: update inside
176 5: update inside
177 4: update widest v3
177 4: update widest v3
178 3: add wider, update widest
178 3: add wider, update widest
179 2: add outside
179 2: add outside
180 1: add widest
180 1: add widest
181 0: add inside
181 0: add inside
182
182
183 Check that widening with a newline fails
183 Check that widening with a newline fails
184
184
185 $ hg tracked --addinclude 'widest
185 $ hg tracked --addinclude 'widest
186 > '
186 > '
187 abort: newlines are not allowed in narrowspec paths
187 abort: newlines are not allowed in narrowspec paths
188 [255]
188 [255]
189
189
190 widen the narrow spec to include the wider file
190 widen the narrow spec to include the wider file
191
191
192 $ hg tracked --addinclude wider
192 $ hg tracked --addinclude wider
193 comparing with ssh://user@dummy/master
193 comparing with ssh://user@dummy/master
194 searching for changes
194 searching for changes
195 adding changesets
195 adding changesets
196 adding manifests
196 adding manifests
197 adding file changes
197 adding file changes
198 added 0 changesets with 1 changes to 1 files
198 added 0 changesets with 1 changes to 1 files
199 $ hg tracked
199 $ hg tracked
200 I path:inside
200 I path:inside
201 I path:wider
201 I path:wider
202 I path:widest/f
202 I path:widest/f
203 $ hg update 'desc("add widest")'
203 $ hg update 'desc("add widest")'
204 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
204 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
205 $ cat widest/f
205 $ cat widest/f
206 widest
206 widest
207 $ hg update 'desc("add wider, update widest")'
207 $ hg update 'desc("add wider, update widest")'
208 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
208 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
209 $ cat wider/f
209 $ cat wider/f
210 wider
210 wider
211 $ cat widest/f
211 $ cat widest/f
212 widest v2
212 widest v2
213 $ hg update 'desc("update widest v3")'
213 $ hg update 'desc("update widest v3")'
214 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
214 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
215 $ cat widest/f
215 $ cat widest/f
216 widest v3
216 widest v3
217 $ hg update 'desc("update widest v4")'
217 $ hg update 'desc("update widest v4")'
218 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
218 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
219 $ cat widest/f
219 $ cat widest/f
220 widest v4
220 widest v4
221
221
222 $ hg log -T "{if(ellipsis, '...')}{rev}: {desc}\n"
222 $ hg log -T "{if(ellipsis, '...')}{rev}: {desc}\n"
223 7: update widest v4
223 7: update widest v4
224 6: add outside2
224 6: add outside2
225 5: update inside
225 5: update inside
226 4: update widest v3
226 4: update widest v3
227 3: add wider, update widest
227 3: add wider, update widest
228 2: add outside
228 2: add outside
229 1: add widest
229 1: add widest
230 0: add inside
230 0: add inside
231
231
232 separate suite of tests: files from 0-10 modified in changes 0-10. This allows
232 separate suite of tests: files from 0-10 modified in changes 0-10. This allows
233 more obvious precise tests tickling particular corner cases.
233 more obvious precise tests tickling particular corner cases.
234
234
235 $ cd ..
235 $ cd ..
236 $ hg init upstream
236 $ hg init upstream
237 $ cd upstream
237 $ cd upstream
238 $ for x in `$TESTDIR/seq.py 0 10`
238 $ for x in `$TESTDIR/seq.py 0 10`
239 > do
239 > do
240 > mkdir d$x
240 > mkdir d$x
241 > echo $x > d$x/f
241 > echo $x > d$x/f
242 > hg add d$x/f
242 > hg add d$x/f
243 > hg commit -m "add d$x/f"
243 > hg commit -m "add d$x/f"
244 > done
244 > done
245 $ hg log -T "{rev}: {desc}\n"
245 $ hg log -T "{rev}: {desc}\n"
246 10: add d10/f
246 10: add d10/f
247 9: add d9/f
247 9: add d9/f
248 8: add d8/f
248 8: add d8/f
249 7: add d7/f
249 7: add d7/f
250 6: add d6/f
250 6: add d6/f
251 5: add d5/f
251 5: add d5/f
252 4: add d4/f
252 4: add d4/f
253 3: add d3/f
253 3: add d3/f
254 2: add d2/f
254 2: add d2/f
255 1: add d1/f
255 1: add d1/f
256 0: add d0/f
256 0: add d0/f
257
257
258 make narrow clone with every third node.
258 make narrow clone with every third node.
259
259
260 $ cd ..
260 $ cd ..
261 $ hg clone --narrow ssh://user@dummy/upstream narrow2 --include d0 --include d3 --include d6 --include d9
261 $ hg clone --narrow ssh://user@dummy/upstream narrow2 --include d0 --include d3 --include d6 --include d9
262 requesting all changes
262 requesting all changes
263 adding changesets
263 adding changesets
264 adding manifests
264 adding manifests
265 adding file changes
265 adding file changes
266 added 11 changesets with 4 changes to 4 files
266 added 11 changesets with 4 changes to 4 files
267 new changesets *:* (glob)
267 new changesets *:* (glob)
268 updating to branch default
268 updating to branch default
269 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
269 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
270 $ cd narrow2
270 $ cd narrow2
271 $ hg tracked
271 $ hg tracked
272 I path:d0
272 I path:d0
273 I path:d3
273 I path:d3
274 I path:d6
274 I path:d6
275 I path:d9
275 I path:d9
276 $ hg verify
276 $ hg verify
277 checking changesets
277 checking changesets
278 checking manifests
278 checking manifests
279 checking directory manifests (tree !)
279 checking directory manifests (tree !)
280 crosschecking files in changesets and manifests
280 crosschecking files in changesets and manifests
281 checking files
281 checking files
282 checked 11 changesets with 4 changes to 4 files
282 checked 11 changesets with 4 changes to 4 files
283 $ hg log -T "{if(ellipsis, '...')}{rev}: {desc}\n"
283 $ hg log -T "{if(ellipsis, '...')}{rev}: {desc}\n"
284 10: add d10/f
284 10: add d10/f
285 9: add d9/f
285 9: add d9/f
286 8: add d8/f
286 8: add d8/f
287 7: add d7/f
287 7: add d7/f
288 6: add d6/f
288 6: add d6/f
289 5: add d5/f
289 5: add d5/f
290 4: add d4/f
290 4: add d4/f
291 3: add d3/f
291 3: add d3/f
292 2: add d2/f
292 2: add d2/f
293 1: add d1/f
293 1: add d1/f
294 0: add d0/f
294 0: add d0/f
295 $ hg tracked --addinclude d1
295 $ hg tracked --addinclude d1
296 comparing with ssh://user@dummy/upstream
296 comparing with ssh://user@dummy/upstream
297 searching for changes
297 searching for changes
298 adding changesets
298 adding changesets
299 adding manifests
299 adding manifests
300 adding file changes
300 adding file changes
301 added 0 changesets with 1 changes to 1 files
301 added 0 changesets with 1 changes to 1 files
302 $ hg tracked
302 $ hg tracked
303 I path:d0
303 I path:d0
304 I path:d1
304 I path:d1
305 I path:d3
305 I path:d3
306 I path:d6
306 I path:d6
307 I path:d9
307 I path:d9
308 $ hg log -T "{if(ellipsis, '...')}{rev}: {desc}\n"
308 $ hg log -T "{if(ellipsis, '...')}{rev}: {desc}\n"
309 10: add d10/f
309 10: add d10/f
310 9: add d9/f
310 9: add d9/f
311 8: add d8/f
311 8: add d8/f
312 7: add d7/f
312 7: add d7/f
313 6: add d6/f
313 6: add d6/f
314 5: add d5/f
314 5: add d5/f
315 4: add d4/f
315 4: add d4/f
316 3: add d3/f
316 3: add d3/f
317 2: add d2/f
317 2: add d2/f
318 1: add d1/f
318 1: add d1/f
319 0: add d0/f
319 0: add d0/f
320
320
321 Verify shouldn't claim the repo is corrupt after a widen.
321 Verify shouldn't claim the repo is corrupt after a widen.
322
322
323 $ hg verify
323 $ hg verify
324 checking changesets
324 checking changesets
325 checking manifests
325 checking manifests
326 checking directory manifests (tree !)
326 checking directory manifests (tree !)
327 crosschecking files in changesets and manifests
327 crosschecking files in changesets and manifests
328 checking files
328 checking files
329 checked 11 changesets with 5 changes to 5 files
329 checked 11 changesets with 5 changes to 5 files
330
330
331 Widening preserves parent of local commit
331 Widening preserves parent of local commit
332
332
333 $ cd ..
333 $ cd ..
334 $ hg clone -q --narrow ssh://user@dummy/upstream narrow3 --include d2 -r 2
334 $ hg clone -q --narrow ssh://user@dummy/upstream narrow3 --include d2 -r 2
335 $ cd narrow3
335 $ cd narrow3
336 $ hg log -T "{if(ellipsis, '...')}{rev}: {desc}\n"
336 $ hg log -T "{if(ellipsis, '...')}{rev}: {desc}\n"
337 2: add d2/f
337 2: add d2/f
338 1: add d1/f
338 1: add d1/f
339 0: add d0/f
339 0: add d0/f
340 $ hg pull -q -r 3
340 $ hg pull -q -r 3
341 $ hg co -q tip
341 $ hg co -q tip
342 $ hg pull -q -r 4
342 $ hg pull -q -r 4
343 $ echo local > d2/f
343 $ echo local > d2/f
344 $ hg ci -m local
344 $ hg ci -m local
345 created new head
345 created new head
346 $ hg tracked -q --addinclude d0 --addinclude d9
346 $ hg tracked -q --addinclude d0 --addinclude d9
347
347
348 Widening preserves bookmarks
348 Widening preserves bookmarks
349
349
350 $ cd ..
350 $ cd ..
351 $ hg clone -q --narrow ssh://user@dummy/upstream narrow-bookmarks --include d4
351 $ hg clone -q --narrow ssh://user@dummy/upstream narrow-bookmarks --include d4
352 $ cd narrow-bookmarks
352 $ cd narrow-bookmarks
353 $ echo local > d4/f
353 $ echo local > d4/f
354 $ hg ci -m local
354 $ hg ci -m local
355 $ hg bookmarks bookmark
355 $ hg bookmarks bookmark
356 $ hg bookmarks
356 $ hg bookmarks
357 * bookmark 11:* (glob)
357 * bookmark 11:* (glob)
358 $ hg -q tracked --addinclude d2
358 $ hg -q tracked --addinclude d2
359 $ hg bookmarks
359 $ hg bookmarks
360 * bookmark 11:* (glob)
360 * bookmark 11:* (glob)
361 $ hg log -r bookmark -T '{desc}\n'
361 $ hg log -r bookmark -T '{desc}\n'
362 local
362 local
363
363
364 Widening that fails can be recovered from
364 Widening that fails can be recovered from
365
365
366 $ cd ..
366 $ cd ..
367 $ hg clone -q --narrow ssh://user@dummy/upstream interrupted --include d0
367 $ hg clone -q --narrow ssh://user@dummy/upstream interrupted --include d0
368 $ cd interrupted
368 $ cd interrupted
369 $ echo local > d0/f
369 $ echo local > d0/f
370 $ hg ci -m local
370 $ hg ci -m local
371 $ hg log -T "{if(ellipsis, '...')}{rev}: {desc}\n"
371 $ hg log -T "{if(ellipsis, '...')}{rev}: {desc}\n"
372 11: local
372 11: local
373 10: add d10/f
373 10: add d10/f
374 9: add d9/f
374 9: add d9/f
375 8: add d8/f
375 8: add d8/f
376 7: add d7/f
376 7: add d7/f
377 6: add d6/f
377 6: add d6/f
378 5: add d5/f
378 5: add d5/f
379 4: add d4/f
379 4: add d4/f
380 3: add d3/f
380 3: add d3/f
381 2: add d2/f
381 2: add d2/f
382 1: add d1/f
382 1: add d1/f
383 0: add d0/f
383 0: add d0/f
384 $ hg bookmarks bookmark
384 $ hg bookmarks bookmark
385 $ hg --config hooks.pretxnchangegroup.bad=false tracked --addinclude d1
385 $ hg --config hooks.pretxnchangegroup.bad=false tracked --addinclude d1
386 comparing with ssh://user@dummy/upstream
386 comparing with ssh://user@dummy/upstream
387 searching for changes
387 searching for changes
388 adding changesets
388 adding changesets
389 adding manifests
389 adding manifests
390 adding file changes
390 adding file changes
391 added 0 changesets with 1 changes to 1 files
391 added 0 changesets with 1 changes to 1 files
392 $ hg log -T "{if(ellipsis, '...')}{rev}: {desc}\n"
392 $ hg log -T "{if(ellipsis, '...')}{rev}: {desc}\n"
393 11: local
393 11: local
394 10: add d10/f
394 10: add d10/f
395 9: add d9/f
395 9: add d9/f
396 8: add d8/f
396 8: add d8/f
397 7: add d7/f
397 7: add d7/f
398 6: add d6/f
398 6: add d6/f
399 5: add d5/f
399 5: add d5/f
400 4: add d4/f
400 4: add d4/f
401 3: add d3/f
401 3: add d3/f
402 2: add d2/f
402 2: add d2/f
403 1: add d1/f
403 1: add d1/f
404 0: add d0/f
404 0: add d0/f
405 $ hg bookmarks
405 $ hg bookmarks
406 * bookmark 11:* (glob)
406 * bookmark 11:* (glob)
407 $ hg unbundle .hg/strip-backup/*-widen.hg
407 $ hg unbundle .hg/strip-backup/*-widen.hg
408 abort: .hg/strip-backup/*-widen.hg: $ENOTDIR$ (windows !)
408 abort: .hg/strip-backup/*-widen.hg: $ENOTDIR$ (windows !)
409 abort: $ENOENT$: '.hg/strip-backup/*-widen.hg' (no-windows !)
409 abort: $ENOENT$: '.hg/strip-backup/*-widen.hg' (no-windows !)
410 [255]
410 [255]
411 $ hg log -T "{if(ellipsis, '...')}{rev}: {desc}\n"
411 $ hg log -T "{if(ellipsis, '...')}{rev}: {desc}\n"
412 11: local
412 11: local
413 10: add d10/f
413 10: add d10/f
414 9: add d9/f
414 9: add d9/f
415 8: add d8/f
415 8: add d8/f
416 7: add d7/f
416 7: add d7/f
417 6: add d6/f
417 6: add d6/f
418 5: add d5/f
418 5: add d5/f
419 4: add d4/f
419 4: add d4/f
420 3: add d3/f
420 3: add d3/f
421 2: add d2/f
421 2: add d2/f
422 1: add d1/f
422 1: add d1/f
423 0: add d0/f
423 0: add d0/f
424 $ hg bookmarks
424 $ hg bookmarks
425 * bookmark 11:* (glob)
425 * bookmark 11:* (glob)
@@ -1,184 +1,184 b''
1 Test changesets filtering during exchanges (some tests are still in
1 Test changesets filtering during exchanges (some tests are still in
2 test-obsolete.t)
2 test-obsolete.t)
3
3
4 $ cat >> $HGRCPATH << EOF
4 $ cat >> $HGRCPATH << EOF
5 > [experimental]
5 > [experimental]
6 > evolution.createmarkers=True
6 > evolution.createmarkers=True
7 > EOF
7 > EOF
8
8
9 Push does not corrupt remote
9 Push does not corrupt remote
10 ----------------------------
10 ----------------------------
11
11
12 Create a DAG where a changeset reuses a revision from a file first used in an
12 Create a DAG where a changeset reuses a revision from a file first used in an
13 extinct changeset.
13 extinct changeset.
14
14
15 $ hg init local
15 $ hg init local
16 $ cd local
16 $ cd local
17 $ echo 'base' > base
17 $ echo 'base' > base
18 $ hg commit -Am base
18 $ hg commit -Am base
19 adding base
19 adding base
20 $ echo 'A' > A
20 $ echo 'A' > A
21 $ hg commit -Am A
21 $ hg commit -Am A
22 adding A
22 adding A
23 $ hg up 0
23 $ hg up 0
24 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
24 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
25 $ hg revert -ar 1
25 $ hg revert -ar 1
26 adding A
26 adding A
27 $ hg commit -Am "A'"
27 $ hg commit -Am "A'"
28 created new head
28 created new head
29 $ hg log -G --template='{desc} {node}'
29 $ hg log -G --template='{desc} {node}'
30 @ A' f89bcc95eba5174b1ccc3e33a82e84c96e8338ee
30 @ A' f89bcc95eba5174b1ccc3e33a82e84c96e8338ee
31 |
31 |
32 | o A 9d73aac1b2ed7d53835eaeec212ed41ea47da53a
32 | o A 9d73aac1b2ed7d53835eaeec212ed41ea47da53a
33 |/
33 |/
34 o base d20a80d4def38df63a4b330b7fb688f3d4cae1e3
34 o base d20a80d4def38df63a4b330b7fb688f3d4cae1e3
35
35
36 $ hg debugobsolete 9d73aac1b2ed7d53835eaeec212ed41ea47da53a f89bcc95eba5174b1ccc3e33a82e84c96e8338ee
36 $ hg debugobsolete 9d73aac1b2ed7d53835eaeec212ed41ea47da53a f89bcc95eba5174b1ccc3e33a82e84c96e8338ee
37 1 new obsolescence markers
37 1 new obsolescence markers
38 obsoleted 1 changesets
38 obsoleted 1 changesets
39
39
40 Push it. The bundle should not refer to the extinct changeset.
40 Push it. The bundle should not refer to the extinct changeset.
41
41
42 $ hg init ../other
42 $ hg init ../other
43 $ hg push ../other
43 $ hg push ../other
44 pushing to ../other
44 pushing to ../other
45 searching for changes
45 searching for changes
46 adding changesets
46 adding changesets
47 adding manifests
47 adding manifests
48 adding file changes
48 adding file changes
49 added 2 changesets with 2 changes to 2 files
49 added 2 changesets with 2 changes to 2 files
50 $ hg -R ../other verify
50 $ hg -R ../other verify
51 checking changesets
51 checking changesets
52 checking manifests
52 checking manifests
53 crosschecking files in changesets and manifests
53 crosschecking files in changesets and manifests
54 checking files
54 checking files
55 checked 2 changesets with 2 changes to 2 files
55 checked 2 changesets with 2 changes to 2 files
56
56
57 Adding a changeset going extinct locally
57 Adding a changeset going extinct locally
58 ------------------------------------------
58 ------------------------------------------
59
59
60 Pull a changeset that will immediatly goes extinct (because you already have a
60 Pull a changeset that will immediatly goes extinct (because you already have a
61 marker to obsolete him)
61 marker to obsolete him)
62 (test resolution of issue3788)
62 (test resolution of issue3788)
63
63
64 $ hg phase --draft --force f89bcc95eba5
64 $ hg phase --draft --force f89bcc95eba5
65 $ hg phase -R ../other --draft --force f89bcc95eba5
65 $ hg phase -R ../other --draft --force f89bcc95eba5
66 $ hg commit --amend -m "A''"
66 $ hg commit --amend -m "A''"
67 $ hg --hidden --config extensions.mq= strip --no-backup f89bcc95eba5
67 $ hg --hidden --config extensions.mq= strip --no-backup f89bcc95eba5
68 $ hg pull ../other
68 $ hg pull ../other
69 pulling from ../other
69 pulling from ../other
70 searching for changes
70 searching for changes
71 adding changesets
71 adding changesets
72 adding manifests
72 adding manifests
73 adding file changes
73 adding file changes
74 added 1 changesets with 0 changes to 1 files (+1 heads)
74 added 1 changesets with 0 changes to 1 files (+1 heads)
75 1 new phase-divergent changesets
75 1 new phase-divergent changesets
76 new changesets f89bcc95eba5
76 new changesets f89bcc95eba5
77 (run 'hg heads' to see heads, 'hg merge' to merge)
77 (run 'hg heads' to see heads, 'hg merge' to merge)
78
78
79 check that bundle is not affected
79 check that bundle is not affected
80
80
81 $ hg bundle --hidden --rev f89bcc95eba5 --base "f89bcc95eba5^" ../f89bcc95eba5.hg
81 $ hg bundle --hidden --rev f89bcc95eba5 --base "f89bcc95eba5^" ../f89bcc95eba5.hg
82 1 changesets found
82 1 changesets found
83 $ hg --hidden --config extensions.mq= strip --no-backup f89bcc95eba5
83 $ hg --hidden --config extensions.mq= strip --no-backup f89bcc95eba5
84 $ hg unbundle ../f89bcc95eba5.hg
84 $ hg unbundle ../f89bcc95eba5.hg
85 adding changesets
85 adding changesets
86 adding manifests
86 adding manifests
87 adding file changes
87 adding file changes
88 added 1 changesets with 0 changes to 1 files (+1 heads)
88 added 1 changesets with 0 changes to 1 files (+1 heads)
89 (1 other changesets obsolete on arrival)
89 (1 other changesets obsolete on arrival)
90 (run 'hg heads' to see heads)
90 (run 'hg heads' to see heads)
91
91
92 check-that bundle can contain markers:
92 check-that bundle can contain markers:
93
93
94 $ hg bundle --hidden --rev f89bcc95eba5 --base "f89bcc95eba5^" ../f89bcc95eba5-obs.hg --config experimental.evolution.bundle-obsmarker=1
94 $ hg bundle --hidden --rev f89bcc95eba5 --base "f89bcc95eba5^" ../f89bcc95eba5-obs.hg --config experimental.evolution.bundle-obsmarker=1
95 1 changesets found
95 1 changesets found
96 $ hg debugbundle ../f89bcc95eba5.hg
96 $ hg debugbundle ../f89bcc95eba5.hg
97 Stream params: {Compression: BZ}
97 Stream params: {Compression: BZ}
98 changegroup -- {nbchanges: 1, version: 02} (mandatory: True)
98 changegroup -- {nbchanges: 1, version: 02} (mandatory: True)
99 f89bcc95eba5174b1ccc3e33a82e84c96e8338ee
99 f89bcc95eba5174b1ccc3e33a82e84c96e8338ee
100 cache:rev-branch-cache -- {} (mandatory: False)
100 cache:rev-branch-cache -- {} (mandatory: False)
101 $ hg debugbundle ../f89bcc95eba5-obs.hg
101 $ hg debugbundle ../f89bcc95eba5-obs.hg
102 Stream params: {Compression: BZ}
102 Stream params: {Compression: BZ}
103 changegroup -- {nbchanges: 1, version: 02} (mandatory: True)
103 changegroup -- {nbchanges: 1, version: 02} (mandatory: True)
104 f89bcc95eba5174b1ccc3e33a82e84c96e8338ee
104 f89bcc95eba5174b1ccc3e33a82e84c96e8338ee
105 cache:rev-branch-cache -- {} (mandatory: False)
105 cache:rev-branch-cache -- {} (mandatory: False)
106 obsmarkers -- {} (mandatory: True)
106 obsmarkers -- {} (mandatory: True)
107 version: 1 (70 bytes)
107 version: 1 (70 bytes)
108 9d73aac1b2ed7d53835eaeec212ed41ea47da53a f89bcc95eba5174b1ccc3e33a82e84c96e8338ee 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
108 9d73aac1b2ed7d53835eaeec212ed41ea47da53a f89bcc95eba5174b1ccc3e33a82e84c96e8338ee 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
109
109
110 $ cd ..
110 $ cd ..
111
111
112 pull does not fetch excessive changesets when common node is hidden (issue4982)
112 pull does not fetch excessive changesets when common node is hidden (issue4982)
113 -------------------------------------------------------------------------------
113 -------------------------------------------------------------------------------
114
114
115 initial repo with server and client matching
115 initial repo with server and client matching
116
116
117 $ hg init pull-hidden-common
117 $ hg init pull-hidden-common
118 $ cd pull-hidden-common
118 $ cd pull-hidden-common
119 $ touch foo
119 $ touch foo
120 $ hg -q commit -A -m initial
120 $ hg -q commit -A -m initial
121 $ echo 1 > foo
121 $ echo 1 > foo
122 $ hg commit -m 1
122 $ hg commit -m 1
123 $ echo 2a > foo
123 $ echo 2a > foo
124 $ hg commit -m 2a
124 $ hg commit -m 2a
125 $ cd ..
125 $ cd ..
126 $ hg clone --pull pull-hidden-common pull-hidden-common-client
126 $ hg clone --pull pull-hidden-common pull-hidden-common-client
127 requesting all changes
127 requesting all changes
128 adding changesets
128 adding changesets
129 adding manifests
129 adding manifests
130 adding file changes
130 adding file changes
131 added 3 changesets with 3 changes to 1 files
131 added 3 changesets with 3 changes to 1 files
132 new changesets 96ee1d7354c4:6a29ed9c68de
132 new changesets 96ee1d7354c4:6a29ed9c68de
133 updating to branch default
133 updating to branch default
134 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
134 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
135
135
136 server obsoletes the old head
136 server obsoletes the old head
137
137
138 $ cd pull-hidden-common
138 $ cd pull-hidden-common
139 $ hg -q up -r 1
139 $ hg -q up -r 1
140 $ echo 2b > foo
140 $ echo 2b > foo
141 $ hg -q commit -m 2b
141 $ hg -q commit -m 2b
142 $ hg debugobsolete 6a29ed9c68defff1a139e5c6fa9696fb1a75783d bec0734cd68e84477ba7fc1d13e6cff53ab70129
142 $ hg debugobsolete 6a29ed9c68defff1a139e5c6fa9696fb1a75783d bec0734cd68e84477ba7fc1d13e6cff53ab70129
143 1 new obsolescence markers
143 1 new obsolescence markers
144 obsoleted 1 changesets
144 obsoleted 1 changesets
145 $ cd ..
145 $ cd ..
146
146
147 client only pulls down 1 changeset
147 client only pulls down 1 changeset
148
148
149 $ cd pull-hidden-common-client
149 $ cd pull-hidden-common-client
150 $ hg pull --debug
150 $ hg pull --debug
151 pulling from $TESTTMP/pull-hidden-common
151 pulling from $TESTTMP/pull-hidden-common
152 query 1; heads
152 query 1; heads
153 searching for changes
153 searching for changes
154 taking quick initial sample
154 taking quick initial sample
155 query 2; still undecided: 2, sample size is: 2
155 query 2; still undecided: 2, sample size is: 2
156 2 total queries in *.????s (glob)
156 2 total queries in *.????s (glob)
157 1 changesets found
157 1 changesets found
158 list of changesets:
158 list of changesets:
159 bec0734cd68e84477ba7fc1d13e6cff53ab70129
159 bec0734cd68e84477ba7fc1d13e6cff53ab70129
160 listing keys for "bookmarks"
160 listing keys for "bookmarks"
161 bundle2-output-bundle: "HG20", 4 parts total
161 bundle2-output-bundle: "HG20", 4 parts total
162 bundle2-output-part: "changegroup" (params: 1 mandatory 1 advisory) streamed payload
162 bundle2-output-part: "changegroup" (params: 1 mandatory 1 advisory) streamed payload
163 bundle2-output-part: "listkeys" (params: 1 mandatory) empty payload
163 bundle2-output-part: "listkeys" (params: 1 mandatory) empty payload
164 bundle2-output-part: "phase-heads" 24 bytes payload
164 bundle2-output-part: "phase-heads" 24 bytes payload
165 bundle2-output-part: "cache:rev-branch-cache" (advisory) streamed payload
165 bundle2-output-part: "cache:rev-branch-cache" (advisory) streamed payload
166 bundle2-input-bundle: with-transaction
166 bundle2-input-bundle: with-transaction
167 bundle2-input-part: "changegroup" (params: 1 mandatory 1 advisory) supported
167 bundle2-input-part: "changegroup" (params: 1 mandatory 1 advisory) supported
168 adding changesets
168 adding changesets
169 add changeset bec0734cd68e
169 add changeset bec0734cd68e
170 adding manifests
170 adding manifests
171 adding file changes
171 adding file changes
172 adding foo revisions
172 adding foo revisions
173 bundle2-input-part: total payload size 476
173 bundle2-input-part: total payload size 476
174 bundle2-input-part: "listkeys" (params: 1 mandatory) supported
174 bundle2-input-part: "listkeys" (params: 1 mandatory) supported
175 bundle2-input-part: "phase-heads" supported
175 bundle2-input-part: "phase-heads" supported
176 bundle2-input-part: total payload size 24
176 bundle2-input-part: total payload size 24
177 bundle2-input-part: "cache:rev-branch-cache" (advisory) supported
177 bundle2-input-part: "cache:rev-branch-cache" (advisory) supported
178 bundle2-input-part: total payload size 39
178 bundle2-input-part: total payload size 39
179 bundle2-input-bundle: 3 parts total
179 bundle2-input-bundle: 4 parts total
180 checking for updated bookmarks
180 checking for updated bookmarks
181 updating the branch cache
181 updating the branch cache
182 added 1 changesets with 1 changes to 1 files (+1 heads)
182 added 1 changesets with 1 changes to 1 files (+1 heads)
183 new changesets bec0734cd68e
183 new changesets bec0734cd68e
184 (run 'hg heads' to see heads, 'hg merge' to merge)
184 (run 'hg heads' to see heads, 'hg merge' to merge)
@@ -1,431 +1,431 b''
1 $ cat >> $HGRCPATH <<EOF
1 $ cat >> $HGRCPATH <<EOF
2 > [extensions]
2 > [extensions]
3 > rebase=
3 > rebase=
4 > drawdag=$TESTDIR/drawdag.py
4 > drawdag=$TESTDIR/drawdag.py
5 >
5 >
6 > [phases]
6 > [phases]
7 > publish=False
7 > publish=False
8 >
8 >
9 > [alias]
9 > [alias]
10 > tglog = log -G --template "{rev}:{phase} '{desc}' {branches} {bookmarks}\n"
10 > tglog = log -G --template "{rev}:{phase} '{desc}' {branches} {bookmarks}\n"
11 > EOF
11 > EOF
12
12
13 $ hg init a
13 $ hg init a
14 $ cd a
14 $ cd a
15 $ echo c1 >common
15 $ echo c1 >common
16 $ hg add common
16 $ hg add common
17 $ hg ci -m C1
17 $ hg ci -m C1
18
18
19 $ echo c2 >>common
19 $ echo c2 >>common
20 $ hg ci -m C2
20 $ hg ci -m C2
21
21
22 $ echo c3 >>common
22 $ echo c3 >>common
23 $ hg ci -m C3
23 $ hg ci -m C3
24
24
25 $ hg up -q -C 1
25 $ hg up -q -C 1
26
26
27 $ echo l1 >>extra
27 $ echo l1 >>extra
28 $ hg add extra
28 $ hg add extra
29 $ hg ci -m L1
29 $ hg ci -m L1
30 created new head
30 created new head
31
31
32 $ sed -e 's/c2/l2/' common > common.new
32 $ sed -e 's/c2/l2/' common > common.new
33 $ mv common.new common
33 $ mv common.new common
34 $ hg ci -m L2
34 $ hg ci -m L2
35
35
36 $ echo l3 >> extra2
36 $ echo l3 >> extra2
37 $ hg add extra2
37 $ hg add extra2
38 $ hg ci -m L3
38 $ hg ci -m L3
39 $ hg bookmark mybook
39 $ hg bookmark mybook
40
40
41 $ hg phase --force --secret 4
41 $ hg phase --force --secret 4
42
42
43 $ hg tglog
43 $ hg tglog
44 @ 5:secret 'L3' mybook
44 @ 5:secret 'L3' mybook
45 |
45 |
46 o 4:secret 'L2'
46 o 4:secret 'L2'
47 |
47 |
48 o 3:draft 'L1'
48 o 3:draft 'L1'
49 |
49 |
50 | o 2:draft 'C3'
50 | o 2:draft 'C3'
51 |/
51 |/
52 o 1:draft 'C2'
52 o 1:draft 'C2'
53 |
53 |
54 o 0:draft 'C1'
54 o 0:draft 'C1'
55
55
56 Try to call --continue:
56 Try to call --continue:
57
57
58 $ hg rebase --continue
58 $ hg rebase --continue
59 abort: no rebase in progress
59 abort: no rebase in progress
60 [255]
60 [255]
61
61
62 Conflicting rebase:
62 Conflicting rebase:
63
63
64 $ hg rebase -s 3 -d 2
64 $ hg rebase -s 3 -d 2
65 rebasing 3:3163e20567cc "L1"
65 rebasing 3:3163e20567cc "L1"
66 rebasing 4:46f0b057b5c0 "L2"
66 rebasing 4:46f0b057b5c0 "L2"
67 merging common
67 merging common
68 warning: conflicts while merging common! (edit, then use 'hg resolve --mark')
68 warning: conflicts while merging common! (edit, then use 'hg resolve --mark')
69 unresolved conflicts (see hg resolve, then hg rebase --continue)
69 unresolved conflicts (see hg resolve, then hg rebase --continue)
70 [1]
70 [1]
71
71
72 $ hg status --config commands.status.verbose=1
72 $ hg status --config commands.status.verbose=1
73 M common
73 M common
74 ? common.orig
74 ? common.orig
75 # The repository is in an unfinished *rebase* state.
75 # The repository is in an unfinished *rebase* state.
76
76
77 # Unresolved merge conflicts:
77 # Unresolved merge conflicts:
78 #
78 #
79 # common
79 # common
80 #
80 #
81 # To mark files as resolved: hg resolve --mark FILE
81 # To mark files as resolved: hg resolve --mark FILE
82
82
83 # To continue: hg rebase --continue
83 # To continue: hg rebase --continue
84 # To abort: hg rebase --abort
84 # To abort: hg rebase --abort
85 # To stop: hg rebase --stop
85 # To stop: hg rebase --stop
86
86
87
87
88 Try to continue without solving the conflict:
88 Try to continue without solving the conflict:
89
89
90 $ hg rebase --continue
90 $ hg rebase --continue
91 abort: unresolved merge conflicts (see 'hg help resolve')
91 abort: unresolved merge conflicts (see 'hg help resolve')
92 [255]
92 [255]
93
93
94 Conclude rebase:
94 Conclude rebase:
95
95
96 $ echo 'resolved merge' >common
96 $ echo 'resolved merge' >common
97 $ hg resolve -m common
97 $ hg resolve -m common
98 (no more unresolved files)
98 (no more unresolved files)
99 continue: hg rebase --continue
99 continue: hg rebase --continue
100 $ hg rebase --continue
100 $ hg rebase --continue
101 already rebased 3:3163e20567cc "L1" as 3e046f2ecedb
101 already rebased 3:3163e20567cc "L1" as 3e046f2ecedb
102 rebasing 4:46f0b057b5c0 "L2"
102 rebasing 4:46f0b057b5c0 "L2"
103 rebasing 5:8029388f38dc "L3" (mybook)
103 rebasing 5:8029388f38dc "L3" (mybook)
104 saved backup bundle to $TESTTMP/a/.hg/strip-backup/3163e20567cc-5ca4656e-rebase.hg
104 saved backup bundle to $TESTTMP/a/.hg/strip-backup/3163e20567cc-5ca4656e-rebase.hg
105
105
106 $ hg tglog
106 $ hg tglog
107 @ 5:secret 'L3' mybook
107 @ 5:secret 'L3' mybook
108 |
108 |
109 o 4:secret 'L2'
109 o 4:secret 'L2'
110 |
110 |
111 o 3:draft 'L1'
111 o 3:draft 'L1'
112 |
112 |
113 o 2:draft 'C3'
113 o 2:draft 'C3'
114 |
114 |
115 o 1:draft 'C2'
115 o 1:draft 'C2'
116 |
116 |
117 o 0:draft 'C1'
117 o 0:draft 'C1'
118
118
119 Check correctness:
119 Check correctness:
120
120
121 $ hg cat -r 0 common
121 $ hg cat -r 0 common
122 c1
122 c1
123
123
124 $ hg cat -r 1 common
124 $ hg cat -r 1 common
125 c1
125 c1
126 c2
126 c2
127
127
128 $ hg cat -r 2 common
128 $ hg cat -r 2 common
129 c1
129 c1
130 c2
130 c2
131 c3
131 c3
132
132
133 $ hg cat -r 3 common
133 $ hg cat -r 3 common
134 c1
134 c1
135 c2
135 c2
136 c3
136 c3
137
137
138 $ hg cat -r 4 common
138 $ hg cat -r 4 common
139 resolved merge
139 resolved merge
140
140
141 $ hg cat -r 5 common
141 $ hg cat -r 5 common
142 resolved merge
142 resolved merge
143
143
144 Bookmark stays active after --continue
144 Bookmark stays active after --continue
145 $ hg bookmarks
145 $ hg bookmarks
146 * mybook 5:d67b21408fc0
146 * mybook 5:d67b21408fc0
147
147
148 $ cd ..
148 $ cd ..
149
149
150 Check that the right ancestors is used while rebasing a merge (issue4041)
150 Check that the right ancestors is used while rebasing a merge (issue4041)
151
151
152 $ hg init issue4041
152 $ hg init issue4041
153 $ cd issue4041
153 $ cd issue4041
154 $ hg unbundle "$TESTDIR/bundles/issue4041.hg"
154 $ hg unbundle "$TESTDIR/bundles/issue4041.hg"
155 adding changesets
155 adding changesets
156 adding manifests
156 adding manifests
157 adding file changes
157 adding file changes
158 added 11 changesets with 8 changes to 3 files (+1 heads)
158 added 11 changesets with 8 changes to 3 files (+1 heads)
159 new changesets 24797d4f68de:2f2496ddf49d (11 drafts)
159 new changesets 24797d4f68de:2f2496ddf49d (11 drafts)
160 (run 'hg heads' to see heads)
160 (run 'hg heads' to see heads)
161 $ hg up default
161 $ hg up default
162 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
162 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
163 $ hg log -G
163 $ hg log -G
164 o changeset: 10:2f2496ddf49d
164 o changeset: 10:2f2496ddf49d
165 |\ branch: f1
165 |\ branch: f1
166 | | tag: tip
166 | | tag: tip
167 | | parent: 7:4c9fbe56a16f
167 | | parent: 7:4c9fbe56a16f
168 | | parent: 9:e31216eec445
168 | | parent: 9:e31216eec445
169 | | user: szhang
169 | | user: szhang
170 | | date: Thu Sep 05 12:59:39 2013 -0400
170 | | date: Thu Sep 05 12:59:39 2013 -0400
171 | | summary: merge
171 | | summary: merge
172 | |
172 | |
173 | o changeset: 9:e31216eec445
173 | o changeset: 9:e31216eec445
174 | | branch: f1
174 | | branch: f1
175 | | user: szhang
175 | | user: szhang
176 | | date: Thu Sep 05 12:59:10 2013 -0400
176 | | date: Thu Sep 05 12:59:10 2013 -0400
177 | | summary: more changes to f1
177 | | summary: more changes to f1
178 | |
178 | |
179 | o changeset: 8:8e4e2c1a07ae
179 | o changeset: 8:8e4e2c1a07ae
180 | |\ branch: f1
180 | |\ branch: f1
181 | | | parent: 2:4bc80088dc6b
181 | | | parent: 2:4bc80088dc6b
182 | | | parent: 6:400110238667
182 | | | parent: 6:400110238667
183 | | | user: szhang
183 | | | user: szhang
184 | | | date: Thu Sep 05 12:57:59 2013 -0400
184 | | | date: Thu Sep 05 12:57:59 2013 -0400
185 | | | summary: bad merge
185 | | | summary: bad merge
186 | | |
186 | | |
187 o | | changeset: 7:4c9fbe56a16f
187 o | | changeset: 7:4c9fbe56a16f
188 |/ / branch: f1
188 |/ / branch: f1
189 | | parent: 2:4bc80088dc6b
189 | | parent: 2:4bc80088dc6b
190 | | user: szhang
190 | | user: szhang
191 | | date: Thu Sep 05 12:54:00 2013 -0400
191 | | date: Thu Sep 05 12:54:00 2013 -0400
192 | | summary: changed f1
192 | | summary: changed f1
193 | |
193 | |
194 | o changeset: 6:400110238667
194 | o changeset: 6:400110238667
195 | | branch: f2
195 | | branch: f2
196 | | parent: 4:12e8ec6bb010
196 | | parent: 4:12e8ec6bb010
197 | | user: szhang
197 | | user: szhang
198 | | date: Tue Sep 03 13:58:02 2013 -0400
198 | | date: Tue Sep 03 13:58:02 2013 -0400
199 | | summary: changed f2 on f2
199 | | summary: changed f2 on f2
200 | |
200 | |
201 | | @ changeset: 5:d79e2059b5c0
201 | | @ changeset: 5:d79e2059b5c0
202 | | | parent: 3:8a951942e016
202 | | | parent: 3:8a951942e016
203 | | | user: szhang
203 | | | user: szhang
204 | | | date: Tue Sep 03 13:57:39 2013 -0400
204 | | | date: Tue Sep 03 13:57:39 2013 -0400
205 | | | summary: changed f2 on default
205 | | | summary: changed f2 on default
206 | | |
206 | | |
207 | o | changeset: 4:12e8ec6bb010
207 | o | changeset: 4:12e8ec6bb010
208 | |/ branch: f2
208 | |/ branch: f2
209 | | user: szhang
209 | | user: szhang
210 | | date: Tue Sep 03 13:57:18 2013 -0400
210 | | date: Tue Sep 03 13:57:18 2013 -0400
211 | | summary: created f2 branch
211 | | summary: created f2 branch
212 | |
212 | |
213 | o changeset: 3:8a951942e016
213 | o changeset: 3:8a951942e016
214 | | parent: 0:24797d4f68de
214 | | parent: 0:24797d4f68de
215 | | user: szhang
215 | | user: szhang
216 | | date: Tue Sep 03 13:57:11 2013 -0400
216 | | date: Tue Sep 03 13:57:11 2013 -0400
217 | | summary: added f2.txt
217 | | summary: added f2.txt
218 | |
218 | |
219 o | changeset: 2:4bc80088dc6b
219 o | changeset: 2:4bc80088dc6b
220 | | branch: f1
220 | | branch: f1
221 | | user: szhang
221 | | user: szhang
222 | | date: Tue Sep 03 13:56:20 2013 -0400
222 | | date: Tue Sep 03 13:56:20 2013 -0400
223 | | summary: added f1.txt
223 | | summary: added f1.txt
224 | |
224 | |
225 o | changeset: 1:ef53c9e6b608
225 o | changeset: 1:ef53c9e6b608
226 |/ branch: f1
226 |/ branch: f1
227 | user: szhang
227 | user: szhang
228 | date: Tue Sep 03 13:55:26 2013 -0400
228 | date: Tue Sep 03 13:55:26 2013 -0400
229 | summary: created f1 branch
229 | summary: created f1 branch
230 |
230 |
231 o changeset: 0:24797d4f68de
231 o changeset: 0:24797d4f68de
232 user: szhang
232 user: szhang
233 date: Tue Sep 03 13:55:08 2013 -0400
233 date: Tue Sep 03 13:55:08 2013 -0400
234 summary: added default.txt
234 summary: added default.txt
235
235
236 $ hg rebase -s9 -d2 --debug # use debug to really check merge base used
236 $ hg rebase -s9 -d2 --debug # use debug to really check merge base used
237 rebase onto 4bc80088dc6b starting from e31216eec445
237 rebase onto 4bc80088dc6b starting from e31216eec445
238 rebasing on disk
238 rebasing on disk
239 rebase status stored
239 rebase status stored
240 rebasing 9:e31216eec445 "more changes to f1"
240 rebasing 9:e31216eec445 "more changes to f1"
241 future parents are 2 and -1
241 future parents are 2 and -1
242 update to 2:4bc80088dc6b
242 update to 2:4bc80088dc6b
243 resolving manifests
243 resolving manifests
244 branchmerge: False, force: True, partial: False
244 branchmerge: False, force: True, partial: False
245 ancestor: d79e2059b5c0+, local: d79e2059b5c0+, remote: 4bc80088dc6b
245 ancestor: d79e2059b5c0+, local: d79e2059b5c0+, remote: 4bc80088dc6b
246 f2.txt: other deleted -> r
246 f2.txt: other deleted -> r
247 removing f2.txt
247 removing f2.txt
248 f1.txt: remote created -> g
248 f1.txt: remote created -> g
249 getting f1.txt
249 getting f1.txt
250 merge against 9:e31216eec445
250 merge against 9:e31216eec445
251 detach base 8:8e4e2c1a07ae
251 detach base 8:8e4e2c1a07ae
252 resolving manifests
252 resolving manifests
253 branchmerge: True, force: True, partial: False
253 branchmerge: True, force: True, partial: False
254 ancestor: 8e4e2c1a07ae, local: 4bc80088dc6b+, remote: e31216eec445
254 ancestor: 8e4e2c1a07ae, local: 4bc80088dc6b+, remote: e31216eec445
255 f1.txt: remote is newer -> g
255 f1.txt: remote is newer -> g
256 getting f1.txt
256 getting f1.txt
257 committing files:
257 committing files:
258 f1.txt
258 f1.txt
259 committing manifest
259 committing manifest
260 committing changelog
260 committing changelog
261 updating the branch cache
261 updating the branch cache
262 rebased as 19c888675e13
262 rebased as 19c888675e13
263 rebase status stored
263 rebase status stored
264 rebasing 10:2f2496ddf49d "merge" (tip)
264 rebasing 10:2f2496ddf49d "merge" (tip)
265 future parents are 11 and 7
265 future parents are 11 and 7
266 already in destination
266 already in destination
267 merge against 10:2f2496ddf49d
267 merge against 10:2f2496ddf49d
268 detach base 9:e31216eec445
268 detach base 9:e31216eec445
269 resolving manifests
269 resolving manifests
270 branchmerge: True, force: True, partial: False
270 branchmerge: True, force: True, partial: False
271 ancestor: e31216eec445, local: 19c888675e13+, remote: 2f2496ddf49d
271 ancestor: e31216eec445, local: 19c888675e13+, remote: 2f2496ddf49d
272 f1.txt: remote is newer -> g
272 f1.txt: remote is newer -> g
273 getting f1.txt
273 getting f1.txt
274 committing files:
274 committing files:
275 f1.txt
275 f1.txt
276 committing manifest
276 committing manifest
277 committing changelog
277 committing changelog
278 updating the branch cache
278 updating the branch cache
279 rebased as 2a7f09cac94c
279 rebased as 2a7f09cac94c
280 rebase status stored
280 rebase status stored
281 rebase merging completed
281 rebase merging completed
282 update back to initial working directory parent
282 update back to initial working directory parent
283 resolving manifests
283 resolving manifests
284 branchmerge: False, force: False, partial: False
284 branchmerge: False, force: False, partial: False
285 ancestor: 2a7f09cac94c, local: 2a7f09cac94c+, remote: d79e2059b5c0
285 ancestor: 2a7f09cac94c, local: 2a7f09cac94c+, remote: d79e2059b5c0
286 f1.txt: other deleted -> r
286 f1.txt: other deleted -> r
287 removing f1.txt
287 removing f1.txt
288 f2.txt: remote created -> g
288 f2.txt: remote created -> g
289 getting f2.txt
289 getting f2.txt
290 2 changesets found
290 2 changesets found
291 list of changesets:
291 list of changesets:
292 e31216eec445e44352c5f01588856059466a24c9
292 e31216eec445e44352c5f01588856059466a24c9
293 2f2496ddf49d69b5ef23ad8cf9fb2e0e4faf0ac2
293 2f2496ddf49d69b5ef23ad8cf9fb2e0e4faf0ac2
294 bundle2-output-bundle: "HG20", (1 params) 3 parts total
294 bundle2-output-bundle: "HG20", (1 params) 3 parts total
295 bundle2-output-part: "changegroup" (params: 1 mandatory 1 advisory) streamed payload
295 bundle2-output-part: "changegroup" (params: 1 mandatory 1 advisory) streamed payload
296 bundle2-output-part: "cache:rev-branch-cache" (advisory) streamed payload
296 bundle2-output-part: "cache:rev-branch-cache" (advisory) streamed payload
297 bundle2-output-part: "phase-heads" 24 bytes payload
297 bundle2-output-part: "phase-heads" 24 bytes payload
298 saved backup bundle to $TESTTMP/issue4041/.hg/strip-backup/e31216eec445-15f7a814-rebase.hg
298 saved backup bundle to $TESTTMP/issue4041/.hg/strip-backup/e31216eec445-15f7a814-rebase.hg
299 3 changesets found
299 3 changesets found
300 list of changesets:
300 list of changesets:
301 4c9fbe56a16f30c0d5dcc40ec1a97bbe3325209c
301 4c9fbe56a16f30c0d5dcc40ec1a97bbe3325209c
302 19c888675e133ab5dff84516926a65672eaf04d9
302 19c888675e133ab5dff84516926a65672eaf04d9
303 2a7f09cac94c7f4b73ebd5cd1a62d3b2e8e336bf
303 2a7f09cac94c7f4b73ebd5cd1a62d3b2e8e336bf
304 bundle2-output-bundle: "HG20", 3 parts total
304 bundle2-output-bundle: "HG20", 3 parts total
305 bundle2-output-part: "changegroup" (params: 1 mandatory 1 advisory) streamed payload
305 bundle2-output-part: "changegroup" (params: 1 mandatory 1 advisory) streamed payload
306 bundle2-output-part: "cache:rev-branch-cache" (advisory) streamed payload
306 bundle2-output-part: "cache:rev-branch-cache" (advisory) streamed payload
307 bundle2-output-part: "phase-heads" 24 bytes payload
307 bundle2-output-part: "phase-heads" 24 bytes payload
308 adding branch
308 adding branch
309 bundle2-input-bundle: with-transaction
309 bundle2-input-bundle: with-transaction
310 bundle2-input-part: "changegroup" (params: 1 mandatory 1 advisory) supported
310 bundle2-input-part: "changegroup" (params: 1 mandatory 1 advisory) supported
311 adding changesets
311 adding changesets
312 add changeset 4c9fbe56a16f
312 add changeset 4c9fbe56a16f
313 add changeset 19c888675e13
313 add changeset 19c888675e13
314 add changeset 2a7f09cac94c
314 add changeset 2a7f09cac94c
315 adding manifests
315 adding manifests
316 adding file changes
316 adding file changes
317 adding f1.txt revisions
317 adding f1.txt revisions
318 bundle2-input-part: total payload size 1686
318 bundle2-input-part: total payload size 1686
319 bundle2-input-part: "cache:rev-branch-cache" (advisory) supported
319 bundle2-input-part: "cache:rev-branch-cache" (advisory) supported
320 bundle2-input-part: total payload size 74
320 bundle2-input-part: total payload size 74
321 truncating cache/rbc-revs-v1 to 56
321 truncating cache/rbc-revs-v1 to 56
322 bundle2-input-part: "phase-heads" supported
322 bundle2-input-part: "phase-heads" supported
323 bundle2-input-part: total payload size 24
323 bundle2-input-part: total payload size 24
324 bundle2-input-bundle: 2 parts total
324 bundle2-input-bundle: 3 parts total
325 added 2 changesets with 2 changes to 1 files
325 added 2 changesets with 2 changes to 1 files
326 updating the branch cache
326 updating the branch cache
327 invalid branch cache (served): tip differs
327 invalid branch cache (served): tip differs
328 invalid branch cache (served.hidden): tip differs
328 invalid branch cache (served.hidden): tip differs
329 rebase completed
329 rebase completed
330
330
331 Test minimization of merge conflicts
331 Test minimization of merge conflicts
332 $ hg up -q null
332 $ hg up -q null
333 $ echo a > a
333 $ echo a > a
334 $ hg add a
334 $ hg add a
335 $ hg commit -q -m 'a'
335 $ hg commit -q -m 'a'
336 $ echo b >> a
336 $ echo b >> a
337 $ hg commit -q -m 'ab'
337 $ hg commit -q -m 'ab'
338 $ hg bookmark ab
338 $ hg bookmark ab
339 $ hg up -q '.^'
339 $ hg up -q '.^'
340 $ echo b >> a
340 $ echo b >> a
341 $ echo c >> a
341 $ echo c >> a
342 $ hg commit -q -m 'abc'
342 $ hg commit -q -m 'abc'
343 $ hg rebase -s 7bc217434fc1 -d ab --keep
343 $ hg rebase -s 7bc217434fc1 -d ab --keep
344 rebasing 13:7bc217434fc1 "abc" (tip)
344 rebasing 13:7bc217434fc1 "abc" (tip)
345 merging a
345 merging a
346 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
346 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
347 unresolved conflicts (see hg resolve, then hg rebase --continue)
347 unresolved conflicts (see hg resolve, then hg rebase --continue)
348 [1]
348 [1]
349 $ hg diff
349 $ hg diff
350 diff -r 328e4ab1f7cc a
350 diff -r 328e4ab1f7cc a
351 --- a/a Thu Jan 01 00:00:00 1970 +0000
351 --- a/a Thu Jan 01 00:00:00 1970 +0000
352 +++ b/a * (glob)
352 +++ b/a * (glob)
353 @@ -1,2 +1,6 @@
353 @@ -1,2 +1,6 @@
354 a
354 a
355 b
355 b
356 +<<<<<<< dest: 328e4ab1f7cc ab - test: ab
356 +<<<<<<< dest: 328e4ab1f7cc ab - test: ab
357 +=======
357 +=======
358 +c
358 +c
359 +>>>>>>> source: 7bc217434fc1 - test: abc
359 +>>>>>>> source: 7bc217434fc1 - test: abc
360 $ hg rebase --abort
360 $ hg rebase --abort
361 rebase aborted
361 rebase aborted
362 $ hg up -q -C 7bc217434fc1
362 $ hg up -q -C 7bc217434fc1
363 $ hg rebase -s . -d ab --keep -t internal:merge3
363 $ hg rebase -s . -d ab --keep -t internal:merge3
364 rebasing 13:7bc217434fc1 "abc" (tip)
364 rebasing 13:7bc217434fc1 "abc" (tip)
365 merging a
365 merging a
366 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
366 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
367 unresolved conflicts (see hg resolve, then hg rebase --continue)
367 unresolved conflicts (see hg resolve, then hg rebase --continue)
368 [1]
368 [1]
369 $ hg diff
369 $ hg diff
370 diff -r 328e4ab1f7cc a
370 diff -r 328e4ab1f7cc a
371 --- a/a Thu Jan 01 00:00:00 1970 +0000
371 --- a/a Thu Jan 01 00:00:00 1970 +0000
372 +++ b/a * (glob)
372 +++ b/a * (glob)
373 @@ -1,2 +1,8 @@
373 @@ -1,2 +1,8 @@
374 a
374 a
375 +<<<<<<< dest: 328e4ab1f7cc ab - test: ab
375 +<<<<<<< dest: 328e4ab1f7cc ab - test: ab
376 b
376 b
377 +||||||| base
377 +||||||| base
378 +=======
378 +=======
379 +b
379 +b
380 +c
380 +c
381 +>>>>>>> source: 7bc217434fc1 - test: abc
381 +>>>>>>> source: 7bc217434fc1 - test: abc
382
382
383 Test rebase with obsstore turned on and off (issue5606)
383 Test rebase with obsstore turned on and off (issue5606)
384
384
385 $ cd $TESTTMP
385 $ cd $TESTTMP
386 $ hg init b
386 $ hg init b
387 $ cd b
387 $ cd b
388 $ hg debugdrawdag <<'EOS'
388 $ hg debugdrawdag <<'EOS'
389 > D
389 > D
390 > |
390 > |
391 > C
391 > C
392 > |
392 > |
393 > B E
393 > B E
394 > |/
394 > |/
395 > A
395 > A
396 > EOS
396 > EOS
397
397
398 $ hg update E -q
398 $ hg update E -q
399 $ echo 3 > B
399 $ echo 3 > B
400 $ hg commit --amend -m E -A B -q
400 $ hg commit --amend -m E -A B -q
401 $ hg rebase -r B+D -d . --config experimental.evolution=true
401 $ hg rebase -r B+D -d . --config experimental.evolution=true
402 rebasing 1:112478962961 "B" (B)
402 rebasing 1:112478962961 "B" (B)
403 merging B
403 merging B
404 warning: conflicts while merging B! (edit, then use 'hg resolve --mark')
404 warning: conflicts while merging B! (edit, then use 'hg resolve --mark')
405 unresolved conflicts (see hg resolve, then hg rebase --continue)
405 unresolved conflicts (see hg resolve, then hg rebase --continue)
406 [1]
406 [1]
407
407
408 $ echo 4 > B
408 $ echo 4 > B
409 $ hg resolve -m
409 $ hg resolve -m
410 (no more unresolved files)
410 (no more unresolved files)
411 continue: hg rebase --continue
411 continue: hg rebase --continue
412 $ hg rebase --continue --config experimental.evolution=none
412 $ hg rebase --continue --config experimental.evolution=none
413 rebasing 1:112478962961 "B" (B)
413 rebasing 1:112478962961 "B" (B)
414 rebasing 3:f585351a92f8 "D" (D)
414 rebasing 3:f585351a92f8 "D" (D)
415 warning: orphaned descendants detected, not stripping 112478962961
415 warning: orphaned descendants detected, not stripping 112478962961
416 saved backup bundle to $TESTTMP/b/.hg/strip-backup/f585351a92f8-e536a9e4-rebase.hg
416 saved backup bundle to $TESTTMP/b/.hg/strip-backup/f585351a92f8-e536a9e4-rebase.hg
417
417
418 $ rm .hg/localtags
418 $ rm .hg/localtags
419 $ hg tglog
419 $ hg tglog
420 o 5:draft 'D'
420 o 5:draft 'D'
421 |
421 |
422 o 4:draft 'B'
422 o 4:draft 'B'
423 |
423 |
424 @ 3:draft 'E'
424 @ 3:draft 'E'
425 |
425 |
426 | o 2:draft 'C'
426 | o 2:draft 'C'
427 | |
427 | |
428 | o 1:draft 'B'
428 | o 1:draft 'B'
429 |/
429 |/
430 o 0:draft 'A'
430 o 0:draft 'A'
431
431
@@ -1,701 +1,701 b''
1 #testcases sshv1 sshv2
1 #testcases sshv1 sshv2
2
2
3 #if sshv2
3 #if sshv2
4 $ cat >> $HGRCPATH << EOF
4 $ cat >> $HGRCPATH << EOF
5 > [experimental]
5 > [experimental]
6 > sshpeer.advertise-v2 = true
6 > sshpeer.advertise-v2 = true
7 > sshserver.support-v2 = true
7 > sshserver.support-v2 = true
8 > EOF
8 > EOF
9 #endif
9 #endif
10
10
11 This test tries to exercise the ssh functionality with a dummy script
11 This test tries to exercise the ssh functionality with a dummy script
12
12
13 creating 'remote' repo
13 creating 'remote' repo
14
14
15 $ hg init remote
15 $ hg init remote
16 $ cd remote
16 $ cd remote
17 $ echo this > foo
17 $ echo this > foo
18 $ echo this > fooO
18 $ echo this > fooO
19 $ hg ci -A -m "init" foo fooO
19 $ hg ci -A -m "init" foo fooO
20
20
21 insert a closed branch (issue4428)
21 insert a closed branch (issue4428)
22
22
23 $ hg up null
23 $ hg up null
24 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
24 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
25 $ hg branch closed
25 $ hg branch closed
26 marked working directory as branch closed
26 marked working directory as branch closed
27 (branches are permanent and global, did you want a bookmark?)
27 (branches are permanent and global, did you want a bookmark?)
28 $ hg ci -mc0
28 $ hg ci -mc0
29 $ hg ci --close-branch -mc1
29 $ hg ci --close-branch -mc1
30 $ hg up -q default
30 $ hg up -q default
31
31
32 configure for serving
32 configure for serving
33
33
34 $ cat <<EOF > .hg/hgrc
34 $ cat <<EOF > .hg/hgrc
35 > [server]
35 > [server]
36 > uncompressed = True
36 > uncompressed = True
37 >
37 >
38 > [hooks]
38 > [hooks]
39 > changegroup = sh -c "printenv.py --line changegroup-in-remote 0 ../dummylog"
39 > changegroup = sh -c "printenv.py --line changegroup-in-remote 0 ../dummylog"
40 > EOF
40 > EOF
41 $ cd $TESTTMP
41 $ cd $TESTTMP
42
42
43 repo not found error
43 repo not found error
44
44
45 $ hg clone -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" ssh://user@dummy/nonexistent local
45 $ hg clone -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" ssh://user@dummy/nonexistent local
46 remote: abort: repository nonexistent not found!
46 remote: abort: repository nonexistent not found!
47 abort: no suitable response from remote hg!
47 abort: no suitable response from remote hg!
48 [255]
48 [255]
49
49
50 non-existent absolute path
50 non-existent absolute path
51
51
52 $ hg clone -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" ssh://user@dummy/`pwd`/nonexistent local
52 $ hg clone -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" ssh://user@dummy/`pwd`/nonexistent local
53 remote: abort: repository $TESTTMP/nonexistent not found!
53 remote: abort: repository $TESTTMP/nonexistent not found!
54 abort: no suitable response from remote hg!
54 abort: no suitable response from remote hg!
55 [255]
55 [255]
56
56
57 clone remote via stream
57 clone remote via stream
58
58
59 #if no-reposimplestore
59 #if no-reposimplestore
60
60
61 $ hg clone -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" --stream ssh://user@dummy/remote local-stream
61 $ hg clone -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" --stream ssh://user@dummy/remote local-stream
62 streaming all changes
62 streaming all changes
63 8 files to transfer, 827 bytes of data
63 8 files to transfer, 827 bytes of data
64 transferred 827 bytes in * seconds (*) (glob)
64 transferred 827 bytes in * seconds (*) (glob)
65 updating to branch default
65 updating to branch default
66 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
66 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
67 $ cd local-stream
67 $ cd local-stream
68 $ hg verify
68 $ hg verify
69 checking changesets
69 checking changesets
70 checking manifests
70 checking manifests
71 crosschecking files in changesets and manifests
71 crosschecking files in changesets and manifests
72 checking files
72 checking files
73 checked 3 changesets with 2 changes to 2 files
73 checked 3 changesets with 2 changes to 2 files
74 $ hg branches
74 $ hg branches
75 default 0:1160648e36ce
75 default 0:1160648e36ce
76 $ cd $TESTTMP
76 $ cd $TESTTMP
77
77
78 clone bookmarks via stream
78 clone bookmarks via stream
79
79
80 $ hg -R local-stream book mybook
80 $ hg -R local-stream book mybook
81 $ hg clone -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" --stream ssh://user@dummy/local-stream stream2
81 $ hg clone -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" --stream ssh://user@dummy/local-stream stream2
82 streaming all changes
82 streaming all changes
83 9 files to transfer, 870 bytes of data
83 9 files to transfer, 870 bytes of data
84 transferred 870 bytes in * seconds (*) (glob)
84 transferred 870 bytes in * seconds (*) (glob)
85 updating to branch default
85 updating to branch default
86 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
86 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
87 $ cd stream2
87 $ cd stream2
88 $ hg book
88 $ hg book
89 mybook 0:1160648e36ce
89 mybook 0:1160648e36ce
90 $ cd $TESTTMP
90 $ cd $TESTTMP
91 $ rm -rf local-stream stream2
91 $ rm -rf local-stream stream2
92
92
93 #endif
93 #endif
94
94
95 clone remote via pull
95 clone remote via pull
96
96
97 $ hg clone -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote local
97 $ hg clone -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote local
98 requesting all changes
98 requesting all changes
99 adding changesets
99 adding changesets
100 adding manifests
100 adding manifests
101 adding file changes
101 adding file changes
102 added 3 changesets with 2 changes to 2 files
102 added 3 changesets with 2 changes to 2 files
103 new changesets 1160648e36ce:ad076bfb429d
103 new changesets 1160648e36ce:ad076bfb429d
104 updating to branch default
104 updating to branch default
105 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
105 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
106
106
107 verify
107 verify
108
108
109 $ cd local
109 $ cd local
110 $ hg verify
110 $ hg verify
111 checking changesets
111 checking changesets
112 checking manifests
112 checking manifests
113 crosschecking files in changesets and manifests
113 crosschecking files in changesets and manifests
114 checking files
114 checking files
115 checked 3 changesets with 2 changes to 2 files
115 checked 3 changesets with 2 changes to 2 files
116 $ cat >> .hg/hgrc <<EOF
116 $ cat >> .hg/hgrc <<EOF
117 > [hooks]
117 > [hooks]
118 > changegroup = sh -c "printenv.py changegroup-in-local 0 ../dummylog"
118 > changegroup = sh -c "printenv.py changegroup-in-local 0 ../dummylog"
119 > EOF
119 > EOF
120
120
121 empty default pull
121 empty default pull
122
122
123 $ hg paths
123 $ hg paths
124 default = ssh://user@dummy/remote
124 default = ssh://user@dummy/remote
125 $ hg pull -e "\"$PYTHON\" \"$TESTDIR/dummyssh\""
125 $ hg pull -e "\"$PYTHON\" \"$TESTDIR/dummyssh\""
126 pulling from ssh://user@dummy/remote
126 pulling from ssh://user@dummy/remote
127 searching for changes
127 searching for changes
128 no changes found
128 no changes found
129
129
130 pull from wrong ssh URL
130 pull from wrong ssh URL
131
131
132 $ hg pull -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" ssh://user@dummy/doesnotexist
132 $ hg pull -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" ssh://user@dummy/doesnotexist
133 pulling from ssh://user@dummy/doesnotexist
133 pulling from ssh://user@dummy/doesnotexist
134 remote: abort: repository doesnotexist not found!
134 remote: abort: repository doesnotexist not found!
135 abort: no suitable response from remote hg!
135 abort: no suitable response from remote hg!
136 [255]
136 [255]
137
137
138 local change
138 local change
139
139
140 $ echo bleah > foo
140 $ echo bleah > foo
141 $ hg ci -m "add"
141 $ hg ci -m "add"
142
142
143 updating rc
143 updating rc
144
144
145 $ echo "default-push = ssh://user@dummy/remote" >> .hg/hgrc
145 $ echo "default-push = ssh://user@dummy/remote" >> .hg/hgrc
146 $ echo "[ui]" >> .hg/hgrc
146 $ echo "[ui]" >> .hg/hgrc
147 $ echo "ssh = \"$PYTHON\" \"$TESTDIR/dummyssh\"" >> .hg/hgrc
147 $ echo "ssh = \"$PYTHON\" \"$TESTDIR/dummyssh\"" >> .hg/hgrc
148
148
149 find outgoing
149 find outgoing
150
150
151 $ hg out ssh://user@dummy/remote
151 $ hg out ssh://user@dummy/remote
152 comparing with ssh://user@dummy/remote
152 comparing with ssh://user@dummy/remote
153 searching for changes
153 searching for changes
154 changeset: 3:a28a9d1a809c
154 changeset: 3:a28a9d1a809c
155 tag: tip
155 tag: tip
156 parent: 0:1160648e36ce
156 parent: 0:1160648e36ce
157 user: test
157 user: test
158 date: Thu Jan 01 00:00:00 1970 +0000
158 date: Thu Jan 01 00:00:00 1970 +0000
159 summary: add
159 summary: add
160
160
161
161
162 find incoming on the remote side
162 find incoming on the remote side
163
163
164 $ hg incoming -R ../remote -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" ssh://user@dummy/local
164 $ hg incoming -R ../remote -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" ssh://user@dummy/local
165 comparing with ssh://user@dummy/local
165 comparing with ssh://user@dummy/local
166 searching for changes
166 searching for changes
167 changeset: 3:a28a9d1a809c
167 changeset: 3:a28a9d1a809c
168 tag: tip
168 tag: tip
169 parent: 0:1160648e36ce
169 parent: 0:1160648e36ce
170 user: test
170 user: test
171 date: Thu Jan 01 00:00:00 1970 +0000
171 date: Thu Jan 01 00:00:00 1970 +0000
172 summary: add
172 summary: add
173
173
174
174
175 find incoming on the remote side (using absolute path)
175 find incoming on the remote side (using absolute path)
176
176
177 $ hg incoming -R ../remote -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" "ssh://user@dummy/`pwd`"
177 $ hg incoming -R ../remote -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" "ssh://user@dummy/`pwd`"
178 comparing with ssh://user@dummy/$TESTTMP/local
178 comparing with ssh://user@dummy/$TESTTMP/local
179 searching for changes
179 searching for changes
180 changeset: 3:a28a9d1a809c
180 changeset: 3:a28a9d1a809c
181 tag: tip
181 tag: tip
182 parent: 0:1160648e36ce
182 parent: 0:1160648e36ce
183 user: test
183 user: test
184 date: Thu Jan 01 00:00:00 1970 +0000
184 date: Thu Jan 01 00:00:00 1970 +0000
185 summary: add
185 summary: add
186
186
187
187
188 push
188 push
189
189
190 $ hg push
190 $ hg push
191 pushing to ssh://user@dummy/remote
191 pushing to ssh://user@dummy/remote
192 searching for changes
192 searching for changes
193 remote: adding changesets
193 remote: adding changesets
194 remote: adding manifests
194 remote: adding manifests
195 remote: adding file changes
195 remote: adding file changes
196 remote: added 1 changesets with 1 changes to 1 files
196 remote: added 1 changesets with 1 changes to 1 files
197 $ cd $TESTTMP/remote
197 $ cd $TESTTMP/remote
198
198
199 check remote tip
199 check remote tip
200
200
201 $ hg tip
201 $ hg tip
202 changeset: 3:a28a9d1a809c
202 changeset: 3:a28a9d1a809c
203 tag: tip
203 tag: tip
204 parent: 0:1160648e36ce
204 parent: 0:1160648e36ce
205 user: test
205 user: test
206 date: Thu Jan 01 00:00:00 1970 +0000
206 date: Thu Jan 01 00:00:00 1970 +0000
207 summary: add
207 summary: add
208
208
209 $ hg verify
209 $ hg verify
210 checking changesets
210 checking changesets
211 checking manifests
211 checking manifests
212 crosschecking files in changesets and manifests
212 crosschecking files in changesets and manifests
213 checking files
213 checking files
214 checked 4 changesets with 3 changes to 2 files
214 checked 4 changesets with 3 changes to 2 files
215 $ hg cat -r tip foo
215 $ hg cat -r tip foo
216 bleah
216 bleah
217 $ echo z > z
217 $ echo z > z
218 $ hg ci -A -m z z
218 $ hg ci -A -m z z
219 created new head
219 created new head
220
220
221 test pushkeys and bookmarks
221 test pushkeys and bookmarks
222
222
223 $ cd $TESTTMP/local
223 $ cd $TESTTMP/local
224 $ hg debugpushkey --config ui.ssh="\"$PYTHON\" \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote namespaces
224 $ hg debugpushkey --config ui.ssh="\"$PYTHON\" \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote namespaces
225 bookmarks
225 bookmarks
226 namespaces
226 namespaces
227 phases
227 phases
228 $ hg book foo -r 0
228 $ hg book foo -r 0
229 $ hg out -B --config paths.default=bogus://invalid --config paths.default:pushurl=`hg paths default`
229 $ hg out -B --config paths.default=bogus://invalid --config paths.default:pushurl=`hg paths default`
230 comparing with ssh://user@dummy/remote
230 comparing with ssh://user@dummy/remote
231 searching for changed bookmarks
231 searching for changed bookmarks
232 foo 1160648e36ce
232 foo 1160648e36ce
233 $ hg push -B foo
233 $ hg push -B foo
234 pushing to ssh://user@dummy/remote
234 pushing to ssh://user@dummy/remote
235 searching for changes
235 searching for changes
236 no changes found
236 no changes found
237 exporting bookmark foo
237 exporting bookmark foo
238 [1]
238 [1]
239 $ hg debugpushkey --config ui.ssh="\"$PYTHON\" \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote bookmarks
239 $ hg debugpushkey --config ui.ssh="\"$PYTHON\" \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote bookmarks
240 foo 1160648e36cec0054048a7edc4110c6f84fde594
240 foo 1160648e36cec0054048a7edc4110c6f84fde594
241 $ hg book -f foo
241 $ hg book -f foo
242 $ hg push --traceback
242 $ hg push --traceback
243 pushing to ssh://user@dummy/remote
243 pushing to ssh://user@dummy/remote
244 searching for changes
244 searching for changes
245 no changes found
245 no changes found
246 updating bookmark foo
246 updating bookmark foo
247 [1]
247 [1]
248 $ hg book -d foo
248 $ hg book -d foo
249 $ hg in -B
249 $ hg in -B
250 comparing with ssh://user@dummy/remote
250 comparing with ssh://user@dummy/remote
251 searching for changed bookmarks
251 searching for changed bookmarks
252 foo a28a9d1a809c
252 foo a28a9d1a809c
253 $ hg book -f -r 0 foo
253 $ hg book -f -r 0 foo
254 $ hg pull -B foo
254 $ hg pull -B foo
255 pulling from ssh://user@dummy/remote
255 pulling from ssh://user@dummy/remote
256 no changes found
256 no changes found
257 updating bookmark foo
257 updating bookmark foo
258 $ hg book -d foo
258 $ hg book -d foo
259 $ hg push -B foo
259 $ hg push -B foo
260 pushing to ssh://user@dummy/remote
260 pushing to ssh://user@dummy/remote
261 searching for changes
261 searching for changes
262 no changes found
262 no changes found
263 deleting remote bookmark foo
263 deleting remote bookmark foo
264 [1]
264 [1]
265
265
266 a bad, evil hook that prints to stdout
266 a bad, evil hook that prints to stdout
267
267
268 $ cat <<EOF > $TESTTMP/badhook
268 $ cat <<EOF > $TESTTMP/badhook
269 > import sys
269 > import sys
270 > sys.stdout.write("KABOOM\n")
270 > sys.stdout.write("KABOOM\n")
271 > sys.stdout.flush()
271 > sys.stdout.flush()
272 > EOF
272 > EOF
273
273
274 $ cat <<EOF > $TESTTMP/badpyhook.py
274 $ cat <<EOF > $TESTTMP/badpyhook.py
275 > import sys
275 > import sys
276 > def hook(ui, repo, hooktype, **kwargs):
276 > def hook(ui, repo, hooktype, **kwargs):
277 > sys.stdout.write("KABOOM IN PROCESS\n")
277 > sys.stdout.write("KABOOM IN PROCESS\n")
278 > sys.stdout.flush()
278 > sys.stdout.flush()
279 > EOF
279 > EOF
280
280
281 $ cat <<EOF >> ../remote/.hg/hgrc
281 $ cat <<EOF >> ../remote/.hg/hgrc
282 > [hooks]
282 > [hooks]
283 > changegroup.stdout = "$PYTHON" $TESTTMP/badhook
283 > changegroup.stdout = "$PYTHON" $TESTTMP/badhook
284 > changegroup.pystdout = python:$TESTTMP/badpyhook.py:hook
284 > changegroup.pystdout = python:$TESTTMP/badpyhook.py:hook
285 > EOF
285 > EOF
286 $ echo r > r
286 $ echo r > r
287 $ hg ci -A -m z r
287 $ hg ci -A -m z r
288
288
289 push should succeed even though it has an unexpected response
289 push should succeed even though it has an unexpected response
290
290
291 $ hg push
291 $ hg push
292 pushing to ssh://user@dummy/remote
292 pushing to ssh://user@dummy/remote
293 searching for changes
293 searching for changes
294 remote has heads on branch 'default' that are not known locally: 6c0482d977a3
294 remote has heads on branch 'default' that are not known locally: 6c0482d977a3
295 remote: adding changesets
295 remote: adding changesets
296 remote: adding manifests
296 remote: adding manifests
297 remote: adding file changes
297 remote: adding file changes
298 remote: added 1 changesets with 1 changes to 1 files
298 remote: added 1 changesets with 1 changes to 1 files
299 remote: KABOOM
299 remote: KABOOM
300 remote: KABOOM IN PROCESS
300 remote: KABOOM IN PROCESS
301 $ hg -R ../remote heads
301 $ hg -R ../remote heads
302 changeset: 5:1383141674ec
302 changeset: 5:1383141674ec
303 tag: tip
303 tag: tip
304 parent: 3:a28a9d1a809c
304 parent: 3:a28a9d1a809c
305 user: test
305 user: test
306 date: Thu Jan 01 00:00:00 1970 +0000
306 date: Thu Jan 01 00:00:00 1970 +0000
307 summary: z
307 summary: z
308
308
309 changeset: 4:6c0482d977a3
309 changeset: 4:6c0482d977a3
310 parent: 0:1160648e36ce
310 parent: 0:1160648e36ce
311 user: test
311 user: test
312 date: Thu Jan 01 00:00:00 1970 +0000
312 date: Thu Jan 01 00:00:00 1970 +0000
313 summary: z
313 summary: z
314
314
315
315
316 #if chg
316 #if chg
317
317
318 try again with remote chg, which should succeed as well
318 try again with remote chg, which should succeed as well
319
319
320 $ hg rollback -R ../remote
320 $ hg rollback -R ../remote
321 repository tip rolled back to revision 4 (undo serve)
321 repository tip rolled back to revision 4 (undo serve)
322
322
323 $ hg push --config ui.remotecmd=chg
323 $ hg push --config ui.remotecmd=chg
324 pushing to ssh://user@dummy/remote
324 pushing to ssh://user@dummy/remote
325 searching for changes
325 searching for changes
326 remote has heads on branch 'default' that are not known locally: 6c0482d977a3
326 remote has heads on branch 'default' that are not known locally: 6c0482d977a3
327 remote: adding changesets
327 remote: adding changesets
328 remote: adding manifests
328 remote: adding manifests
329 remote: adding file changes
329 remote: adding file changes
330 remote: added 1 changesets with 1 changes to 1 files
330 remote: added 1 changesets with 1 changes to 1 files
331 remote: KABOOM
331 remote: KABOOM
332 remote: KABOOM IN PROCESS
332 remote: KABOOM IN PROCESS
333
333
334 #endif
334 #endif
335
335
336 clone bookmarks
336 clone bookmarks
337
337
338 $ hg -R ../remote bookmark test
338 $ hg -R ../remote bookmark test
339 $ hg -R ../remote bookmarks
339 $ hg -R ../remote bookmarks
340 * test 4:6c0482d977a3
340 * test 4:6c0482d977a3
341 $ hg clone -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote local-bookmarks
341 $ hg clone -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote local-bookmarks
342 requesting all changes
342 requesting all changes
343 adding changesets
343 adding changesets
344 adding manifests
344 adding manifests
345 adding file changes
345 adding file changes
346 added 6 changesets with 5 changes to 4 files (+1 heads)
346 added 6 changesets with 5 changes to 4 files (+1 heads)
347 new changesets 1160648e36ce:1383141674ec
347 new changesets 1160648e36ce:1383141674ec
348 updating to branch default
348 updating to branch default
349 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
349 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
350 $ hg -R local-bookmarks bookmarks
350 $ hg -R local-bookmarks bookmarks
351 test 4:6c0482d977a3
351 test 4:6c0482d977a3
352
352
353 passwords in ssh urls are not supported
353 passwords in ssh urls are not supported
354 (we use a glob here because different Python versions give different
354 (we use a glob here because different Python versions give different
355 results here)
355 results here)
356
356
357 $ hg push ssh://user:erroneouspwd@dummy/remote
357 $ hg push ssh://user:erroneouspwd@dummy/remote
358 pushing to ssh://user:*@dummy/remote (glob)
358 pushing to ssh://user:*@dummy/remote (glob)
359 abort: password in URL not supported!
359 abort: password in URL not supported!
360 [255]
360 [255]
361
361
362 $ cd $TESTTMP
362 $ cd $TESTTMP
363
363
364 hide outer repo
364 hide outer repo
365 $ hg init
365 $ hg init
366
366
367 Test remote paths with spaces (issue2983):
367 Test remote paths with spaces (issue2983):
368
368
369 $ hg init --ssh "\"$PYTHON\" \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo"
369 $ hg init --ssh "\"$PYTHON\" \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo"
370 $ touch "$TESTTMP/a repo/test"
370 $ touch "$TESTTMP/a repo/test"
371 $ hg -R 'a repo' commit -A -m "test"
371 $ hg -R 'a repo' commit -A -m "test"
372 adding test
372 adding test
373 $ hg -R 'a repo' tag tag
373 $ hg -R 'a repo' tag tag
374 $ hg id --ssh "\"$PYTHON\" \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo"
374 $ hg id --ssh "\"$PYTHON\" \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo"
375 73649e48688a
375 73649e48688a
376
376
377 $ hg id --ssh "\"$PYTHON\" \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo#noNoNO"
377 $ hg id --ssh "\"$PYTHON\" \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo#noNoNO"
378 abort: unknown revision 'noNoNO'!
378 abort: unknown revision 'noNoNO'!
379 [255]
379 [255]
380
380
381 Test (non-)escaping of remote paths with spaces when cloning (issue3145):
381 Test (non-)escaping of remote paths with spaces when cloning (issue3145):
382
382
383 $ hg clone --ssh "\"$PYTHON\" \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo"
383 $ hg clone --ssh "\"$PYTHON\" \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo"
384 destination directory: a repo
384 destination directory: a repo
385 abort: destination 'a repo' is not empty
385 abort: destination 'a repo' is not empty
386 [255]
386 [255]
387
387
388 Make sure hg is really paranoid in serve --stdio mode. It used to be
388 Make sure hg is really paranoid in serve --stdio mode. It used to be
389 possible to get a debugger REPL by specifying a repo named --debugger.
389 possible to get a debugger REPL by specifying a repo named --debugger.
390 $ hg -R --debugger serve --stdio
390 $ hg -R --debugger serve --stdio
391 abort: potentially unsafe serve --stdio invocation: ['-R', '--debugger', 'serve', '--stdio']
391 abort: potentially unsafe serve --stdio invocation: ['-R', '--debugger', 'serve', '--stdio']
392 [255]
392 [255]
393 $ hg -R --config=ui.debugger=yes serve --stdio
393 $ hg -R --config=ui.debugger=yes serve --stdio
394 abort: potentially unsafe serve --stdio invocation: ['-R', '--config=ui.debugger=yes', 'serve', '--stdio']
394 abort: potentially unsafe serve --stdio invocation: ['-R', '--config=ui.debugger=yes', 'serve', '--stdio']
395 [255]
395 [255]
396 Abbreviations of 'serve' also don't work, to avoid shenanigans.
396 Abbreviations of 'serve' also don't work, to avoid shenanigans.
397 $ hg -R narf serv --stdio
397 $ hg -R narf serv --stdio
398 abort: potentially unsafe serve --stdio invocation: ['-R', 'narf', 'serv', '--stdio']
398 abort: potentially unsafe serve --stdio invocation: ['-R', 'narf', 'serv', '--stdio']
399 [255]
399 [255]
400
400
401 Test hg-ssh using a helper script that will restore PYTHONPATH (which might
401 Test hg-ssh using a helper script that will restore PYTHONPATH (which might
402 have been cleared by a hg.exe wrapper) and invoke hg-ssh with the right
402 have been cleared by a hg.exe wrapper) and invoke hg-ssh with the right
403 parameters:
403 parameters:
404
404
405 $ cat > ssh.sh << EOF
405 $ cat > ssh.sh << EOF
406 > userhost="\$1"
406 > userhost="\$1"
407 > SSH_ORIGINAL_COMMAND="\$2"
407 > SSH_ORIGINAL_COMMAND="\$2"
408 > export SSH_ORIGINAL_COMMAND
408 > export SSH_ORIGINAL_COMMAND
409 > PYTHONPATH="$PYTHONPATH"
409 > PYTHONPATH="$PYTHONPATH"
410 > export PYTHONPATH
410 > export PYTHONPATH
411 > "$PYTHON" "$TESTDIR/../contrib/hg-ssh" "$TESTTMP/a repo"
411 > "$PYTHON" "$TESTDIR/../contrib/hg-ssh" "$TESTTMP/a repo"
412 > EOF
412 > EOF
413
413
414 $ hg id --ssh "sh ssh.sh" "ssh://user@dummy/a repo"
414 $ hg id --ssh "sh ssh.sh" "ssh://user@dummy/a repo"
415 73649e48688a
415 73649e48688a
416
416
417 $ hg id --ssh "sh ssh.sh" "ssh://user@dummy/a'repo"
417 $ hg id --ssh "sh ssh.sh" "ssh://user@dummy/a'repo"
418 remote: Illegal repository "$TESTTMP/a'repo"
418 remote: Illegal repository "$TESTTMP/a'repo"
419 abort: no suitable response from remote hg!
419 abort: no suitable response from remote hg!
420 [255]
420 [255]
421
421
422 $ hg id --ssh "sh ssh.sh" --remotecmd hacking "ssh://user@dummy/a'repo"
422 $ hg id --ssh "sh ssh.sh" --remotecmd hacking "ssh://user@dummy/a'repo"
423 remote: Illegal command "hacking -R 'a'\''repo' serve --stdio"
423 remote: Illegal command "hacking -R 'a'\''repo' serve --stdio"
424 abort: no suitable response from remote hg!
424 abort: no suitable response from remote hg!
425 [255]
425 [255]
426
426
427 $ SSH_ORIGINAL_COMMAND="'hg' -R 'a'repo' serve --stdio" "$PYTHON" "$TESTDIR/../contrib/hg-ssh"
427 $ SSH_ORIGINAL_COMMAND="'hg' -R 'a'repo' serve --stdio" "$PYTHON" "$TESTDIR/../contrib/hg-ssh"
428 Illegal command "'hg' -R 'a'repo' serve --stdio": No closing quotation
428 Illegal command "'hg' -R 'a'repo' serve --stdio": No closing quotation
429 [255]
429 [255]
430
430
431 Test hg-ssh in read-only mode:
431 Test hg-ssh in read-only mode:
432
432
433 $ cat > ssh.sh << EOF
433 $ cat > ssh.sh << EOF
434 > userhost="\$1"
434 > userhost="\$1"
435 > SSH_ORIGINAL_COMMAND="\$2"
435 > SSH_ORIGINAL_COMMAND="\$2"
436 > export SSH_ORIGINAL_COMMAND
436 > export SSH_ORIGINAL_COMMAND
437 > PYTHONPATH="$PYTHONPATH"
437 > PYTHONPATH="$PYTHONPATH"
438 > export PYTHONPATH
438 > export PYTHONPATH
439 > "$PYTHON" "$TESTDIR/../contrib/hg-ssh" --read-only "$TESTTMP/remote"
439 > "$PYTHON" "$TESTDIR/../contrib/hg-ssh" --read-only "$TESTTMP/remote"
440 > EOF
440 > EOF
441
441
442 $ hg clone --ssh "sh ssh.sh" "ssh://user@dummy/$TESTTMP/remote" read-only-local
442 $ hg clone --ssh "sh ssh.sh" "ssh://user@dummy/$TESTTMP/remote" read-only-local
443 requesting all changes
443 requesting all changes
444 adding changesets
444 adding changesets
445 adding manifests
445 adding manifests
446 adding file changes
446 adding file changes
447 added 6 changesets with 5 changes to 4 files (+1 heads)
447 added 6 changesets with 5 changes to 4 files (+1 heads)
448 new changesets 1160648e36ce:1383141674ec
448 new changesets 1160648e36ce:1383141674ec
449 updating to branch default
449 updating to branch default
450 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
450 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
451
451
452 $ cd read-only-local
452 $ cd read-only-local
453 $ echo "baz" > bar
453 $ echo "baz" > bar
454 $ hg ci -A -m "unpushable commit" bar
454 $ hg ci -A -m "unpushable commit" bar
455 $ hg push --ssh "sh ../ssh.sh"
455 $ hg push --ssh "sh ../ssh.sh"
456 pushing to ssh://user@dummy/*/remote (glob)
456 pushing to ssh://user@dummy/*/remote (glob)
457 searching for changes
457 searching for changes
458 remote: Permission denied
458 remote: Permission denied
459 remote: pretxnopen.hg-ssh hook failed
459 remote: pretxnopen.hg-ssh hook failed
460 abort: push failed on remote
460 abort: push failed on remote
461 [255]
461 [255]
462
462
463 $ cd $TESTTMP
463 $ cd $TESTTMP
464
464
465 stderr from remote commands should be printed before stdout from local code (issue4336)
465 stderr from remote commands should be printed before stdout from local code (issue4336)
466
466
467 $ hg clone remote stderr-ordering
467 $ hg clone remote stderr-ordering
468 updating to branch default
468 updating to branch default
469 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
469 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
470 $ cd stderr-ordering
470 $ cd stderr-ordering
471 $ cat >> localwrite.py << EOF
471 $ cat >> localwrite.py << EOF
472 > from mercurial import exchange, extensions
472 > from mercurial import exchange, extensions
473 >
473 >
474 > def wrappedpush(orig, repo, *args, **kwargs):
474 > def wrappedpush(orig, repo, *args, **kwargs):
475 > res = orig(repo, *args, **kwargs)
475 > res = orig(repo, *args, **kwargs)
476 > repo.ui.write(b'local stdout\n')
476 > repo.ui.write(b'local stdout\n')
477 > repo.ui.flush()
477 > repo.ui.flush()
478 > return res
478 > return res
479 >
479 >
480 > def extsetup(ui):
480 > def extsetup(ui):
481 > extensions.wrapfunction(exchange, b'push', wrappedpush)
481 > extensions.wrapfunction(exchange, b'push', wrappedpush)
482 > EOF
482 > EOF
483
483
484 $ cat >> .hg/hgrc << EOF
484 $ cat >> .hg/hgrc << EOF
485 > [paths]
485 > [paths]
486 > default-push = ssh://user@dummy/remote
486 > default-push = ssh://user@dummy/remote
487 > [ui]
487 > [ui]
488 > ssh = "$PYTHON" "$TESTDIR/dummyssh"
488 > ssh = "$PYTHON" "$TESTDIR/dummyssh"
489 > [extensions]
489 > [extensions]
490 > localwrite = localwrite.py
490 > localwrite = localwrite.py
491 > EOF
491 > EOF
492
492
493 $ echo localwrite > foo
493 $ echo localwrite > foo
494 $ hg commit -m 'testing localwrite'
494 $ hg commit -m 'testing localwrite'
495 $ hg push
495 $ hg push
496 pushing to ssh://user@dummy/remote
496 pushing to ssh://user@dummy/remote
497 searching for changes
497 searching for changes
498 remote: adding changesets
498 remote: adding changesets
499 remote: adding manifests
499 remote: adding manifests
500 remote: adding file changes
500 remote: adding file changes
501 remote: added 1 changesets with 1 changes to 1 files
501 remote: added 1 changesets with 1 changes to 1 files
502 remote: KABOOM
502 remote: KABOOM
503 remote: KABOOM IN PROCESS
503 remote: KABOOM IN PROCESS
504 local stdout
504 local stdout
505
505
506 debug output
506 debug output
507
507
508 $ hg pull --debug ssh://user@dummy/remote --config devel.debug.peer-request=yes
508 $ hg pull --debug ssh://user@dummy/remote --config devel.debug.peer-request=yes
509 pulling from ssh://user@dummy/remote
509 pulling from ssh://user@dummy/remote
510 running .* ".*/dummyssh" ['"]user@dummy['"] ('|")hg -R remote serve --stdio('|") (re)
510 running .* ".*/dummyssh" ['"]user@dummy['"] ('|")hg -R remote serve --stdio('|") (re)
511 sending upgrade request: * proto=exp-ssh-v2-0003 (glob) (sshv2 !)
511 sending upgrade request: * proto=exp-ssh-v2-0003 (glob) (sshv2 !)
512 devel-peer-request: hello+between
512 devel-peer-request: hello+between
513 devel-peer-request: pairs: 81 bytes
513 devel-peer-request: pairs: 81 bytes
514 sending hello command
514 sending hello command
515 sending between command
515 sending between command
516 remote: 440 (sshv1 !)
516 remote: 440 (sshv1 !)
517 protocol upgraded to exp-ssh-v2-0003 (sshv2 !)
517 protocol upgraded to exp-ssh-v2-0003 (sshv2 !)
518 remote: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
518 remote: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
519 remote: 1 (sshv1 !)
519 remote: 1 (sshv1 !)
520 devel-peer-request: protocaps
520 devel-peer-request: protocaps
521 devel-peer-request: caps: * bytes (glob)
521 devel-peer-request: caps: * bytes (glob)
522 sending protocaps command
522 sending protocaps command
523 query 1; heads
523 query 1; heads
524 devel-peer-request: batched-content
524 devel-peer-request: batched-content
525 devel-peer-request: - heads (0 arguments)
525 devel-peer-request: - heads (0 arguments)
526 devel-peer-request: - known (1 arguments)
526 devel-peer-request: - known (1 arguments)
527 devel-peer-request: batch
527 devel-peer-request: batch
528 devel-peer-request: cmds: 141 bytes
528 devel-peer-request: cmds: 141 bytes
529 sending batch command
529 sending batch command
530 searching for changes
530 searching for changes
531 all remote heads known locally
531 all remote heads known locally
532 no changes found
532 no changes found
533 devel-peer-request: getbundle
533 devel-peer-request: getbundle
534 devel-peer-request: bookmarks: 1 bytes
534 devel-peer-request: bookmarks: 1 bytes
535 devel-peer-request: bundlecaps: 266 bytes
535 devel-peer-request: bundlecaps: 266 bytes
536 devel-peer-request: cg: 1 bytes
536 devel-peer-request: cg: 1 bytes
537 devel-peer-request: common: 122 bytes
537 devel-peer-request: common: 122 bytes
538 devel-peer-request: heads: 122 bytes
538 devel-peer-request: heads: 122 bytes
539 devel-peer-request: listkeys: 9 bytes
539 devel-peer-request: listkeys: 9 bytes
540 devel-peer-request: phases: 1 bytes
540 devel-peer-request: phases: 1 bytes
541 sending getbundle command
541 sending getbundle command
542 bundle2-input-bundle: with-transaction
542 bundle2-input-bundle: with-transaction
543 bundle2-input-part: "bookmarks" supported
543 bundle2-input-part: "bookmarks" supported
544 bundle2-input-part: total payload size 26
544 bundle2-input-part: total payload size 26
545 bundle2-input-part: "listkeys" (params: 1 mandatory) supported
545 bundle2-input-part: "listkeys" (params: 1 mandatory) supported
546 bundle2-input-part: total payload size 45
546 bundle2-input-part: total payload size 45
547 bundle2-input-part: "phase-heads" supported
547 bundle2-input-part: "phase-heads" supported
548 bundle2-input-part: total payload size 72
548 bundle2-input-part: total payload size 72
549 bundle2-input-bundle: 2 parts total
549 bundle2-input-bundle: 3 parts total
550 checking for updated bookmarks
550 checking for updated bookmarks
551
551
552 $ cd $TESTTMP
552 $ cd $TESTTMP
553
553
554 $ cat dummylog
554 $ cat dummylog
555 Got arguments 1:user@dummy 2:hg -R nonexistent serve --stdio
555 Got arguments 1:user@dummy 2:hg -R nonexistent serve --stdio
556 Got arguments 1:user@dummy 2:hg -R $TESTTMP/nonexistent serve --stdio
556 Got arguments 1:user@dummy 2:hg -R $TESTTMP/nonexistent serve --stdio
557 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
557 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
558 Got arguments 1:user@dummy 2:hg -R local-stream serve --stdio (no-reposimplestore !)
558 Got arguments 1:user@dummy 2:hg -R local-stream serve --stdio (no-reposimplestore !)
559 Got arguments 1:user@dummy 2:hg -R remote serve --stdio (no-reposimplestore !)
559 Got arguments 1:user@dummy 2:hg -R remote serve --stdio (no-reposimplestore !)
560 Got arguments 1:user@dummy 2:hg -R remote serve --stdio (no-reposimplestore !)
560 Got arguments 1:user@dummy 2:hg -R remote serve --stdio (no-reposimplestore !)
561 Got arguments 1:user@dummy 2:hg -R doesnotexist serve --stdio
561 Got arguments 1:user@dummy 2:hg -R doesnotexist serve --stdio
562 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
562 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
563 Got arguments 1:user@dummy 2:hg -R local serve --stdio
563 Got arguments 1:user@dummy 2:hg -R local serve --stdio
564 Got arguments 1:user@dummy 2:hg -R $TESTTMP/local serve --stdio
564 Got arguments 1:user@dummy 2:hg -R $TESTTMP/local serve --stdio
565 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
565 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
566 changegroup-in-remote hook: HG_BUNDLE2=1
566 changegroup-in-remote hook: HG_BUNDLE2=1
567 HG_HOOKNAME=changegroup
567 HG_HOOKNAME=changegroup
568 HG_HOOKTYPE=changegroup
568 HG_HOOKTYPE=changegroup
569 HG_NODE=a28a9d1a809cab7d4e2fde4bee738a9ede948b60
569 HG_NODE=a28a9d1a809cab7d4e2fde4bee738a9ede948b60
570 HG_NODE_LAST=a28a9d1a809cab7d4e2fde4bee738a9ede948b60
570 HG_NODE_LAST=a28a9d1a809cab7d4e2fde4bee738a9ede948b60
571 HG_SOURCE=serve
571 HG_SOURCE=serve
572 HG_TXNID=TXN:$ID$
572 HG_TXNID=TXN:$ID$
573 HG_TXNNAME=serve
573 HG_TXNNAME=serve
574 HG_URL=remote:ssh:$LOCALIP
574 HG_URL=remote:ssh:$LOCALIP
575
575
576 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
576 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
577 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
577 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
578 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
578 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
579 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
579 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
580 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
580 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
581 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
581 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
582 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
582 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
583 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
583 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
584 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
584 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
585 changegroup-in-remote hook: HG_BUNDLE2=1
585 changegroup-in-remote hook: HG_BUNDLE2=1
586 HG_HOOKNAME=changegroup
586 HG_HOOKNAME=changegroup
587 HG_HOOKTYPE=changegroup
587 HG_HOOKTYPE=changegroup
588 HG_NODE=1383141674ec756a6056f6a9097618482fe0f4a6
588 HG_NODE=1383141674ec756a6056f6a9097618482fe0f4a6
589 HG_NODE_LAST=1383141674ec756a6056f6a9097618482fe0f4a6
589 HG_NODE_LAST=1383141674ec756a6056f6a9097618482fe0f4a6
590 HG_SOURCE=serve
590 HG_SOURCE=serve
591 HG_TXNID=TXN:$ID$
591 HG_TXNID=TXN:$ID$
592 HG_TXNNAME=serve
592 HG_TXNNAME=serve
593 HG_URL=remote:ssh:$LOCALIP
593 HG_URL=remote:ssh:$LOCALIP
594
594
595 Got arguments 1:user@dummy 2:chg -R remote serve --stdio (chg !)
595 Got arguments 1:user@dummy 2:chg -R remote serve --stdio (chg !)
596 changegroup-in-remote hook: HG_BUNDLE2=1 (chg !)
596 changegroup-in-remote hook: HG_BUNDLE2=1 (chg !)
597 HG_HOOKNAME=changegroup (chg !)
597 HG_HOOKNAME=changegroup (chg !)
598 HG_HOOKTYPE=changegroup (chg !)
598 HG_HOOKTYPE=changegroup (chg !)
599 HG_NODE=1383141674ec756a6056f6a9097618482fe0f4a6 (chg !)
599 HG_NODE=1383141674ec756a6056f6a9097618482fe0f4a6 (chg !)
600 HG_NODE_LAST=1383141674ec756a6056f6a9097618482fe0f4a6 (chg !)
600 HG_NODE_LAST=1383141674ec756a6056f6a9097618482fe0f4a6 (chg !)
601 HG_SOURCE=serve (chg !)
601 HG_SOURCE=serve (chg !)
602 HG_TXNID=TXN:$ID$ (chg !)
602 HG_TXNID=TXN:$ID$ (chg !)
603 HG_TXNNAME=serve (chg !)
603 HG_TXNNAME=serve (chg !)
604 HG_URL=remote:ssh:$LOCALIP (chg !)
604 HG_URL=remote:ssh:$LOCALIP (chg !)
605 (chg !)
605 (chg !)
606 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
606 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
607 Got arguments 1:user@dummy 2:hg init 'a repo'
607 Got arguments 1:user@dummy 2:hg init 'a repo'
608 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
608 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
609 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
609 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
610 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
610 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
611 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
611 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
612 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
612 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
613 changegroup-in-remote hook: HG_BUNDLE2=1
613 changegroup-in-remote hook: HG_BUNDLE2=1
614 HG_HOOKNAME=changegroup
614 HG_HOOKNAME=changegroup
615 HG_HOOKTYPE=changegroup
615 HG_HOOKTYPE=changegroup
616 HG_NODE=65c38f4125f9602c8db4af56530cc221d93b8ef8
616 HG_NODE=65c38f4125f9602c8db4af56530cc221d93b8ef8
617 HG_NODE_LAST=65c38f4125f9602c8db4af56530cc221d93b8ef8
617 HG_NODE_LAST=65c38f4125f9602c8db4af56530cc221d93b8ef8
618 HG_SOURCE=serve
618 HG_SOURCE=serve
619 HG_TXNID=TXN:$ID$
619 HG_TXNID=TXN:$ID$
620 HG_TXNNAME=serve
620 HG_TXNNAME=serve
621 HG_URL=remote:ssh:$LOCALIP
621 HG_URL=remote:ssh:$LOCALIP
622
622
623 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
623 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
624
624
625
625
626 remote hook failure is attributed to remote
626 remote hook failure is attributed to remote
627
627
628 $ cat > $TESTTMP/failhook << EOF
628 $ cat > $TESTTMP/failhook << EOF
629 > def hook(ui, repo, **kwargs):
629 > def hook(ui, repo, **kwargs):
630 > ui.write(b'hook failure!\n')
630 > ui.write(b'hook failure!\n')
631 > ui.flush()
631 > ui.flush()
632 > return 1
632 > return 1
633 > EOF
633 > EOF
634
634
635 $ echo "pretxnchangegroup.fail = python:$TESTTMP/failhook:hook" >> remote/.hg/hgrc
635 $ echo "pretxnchangegroup.fail = python:$TESTTMP/failhook:hook" >> remote/.hg/hgrc
636
636
637 $ hg -q --config ui.ssh="\"$PYTHON\" $TESTDIR/dummyssh" clone ssh://user@dummy/remote hookout
637 $ hg -q --config ui.ssh="\"$PYTHON\" $TESTDIR/dummyssh" clone ssh://user@dummy/remote hookout
638 $ cd hookout
638 $ cd hookout
639 $ touch hookfailure
639 $ touch hookfailure
640 $ hg -q commit -A -m 'remote hook failure'
640 $ hg -q commit -A -m 'remote hook failure'
641 $ hg --config ui.ssh="\"$PYTHON\" $TESTDIR/dummyssh" push
641 $ hg --config ui.ssh="\"$PYTHON\" $TESTDIR/dummyssh" push
642 pushing to ssh://user@dummy/remote
642 pushing to ssh://user@dummy/remote
643 searching for changes
643 searching for changes
644 remote: adding changesets
644 remote: adding changesets
645 remote: adding manifests
645 remote: adding manifests
646 remote: adding file changes
646 remote: adding file changes
647 remote: hook failure!
647 remote: hook failure!
648 remote: transaction abort!
648 remote: transaction abort!
649 remote: rollback completed
649 remote: rollback completed
650 remote: pretxnchangegroup.fail hook failed
650 remote: pretxnchangegroup.fail hook failed
651 abort: push failed on remote
651 abort: push failed on remote
652 [255]
652 [255]
653
653
654 abort during pull is properly reported as such
654 abort during pull is properly reported as such
655
655
656 $ echo morefoo >> ../remote/foo
656 $ echo morefoo >> ../remote/foo
657 $ hg -R ../remote commit --message "more foo to be pulled"
657 $ hg -R ../remote commit --message "more foo to be pulled"
658 $ cat >> ../remote/.hg/hgrc << EOF
658 $ cat >> ../remote/.hg/hgrc << EOF
659 > [extensions]
659 > [extensions]
660 > crash = ${TESTDIR}/crashgetbundler.py
660 > crash = ${TESTDIR}/crashgetbundler.py
661 > EOF
661 > EOF
662 $ hg --config ui.ssh="\"$PYTHON\" $TESTDIR/dummyssh" pull
662 $ hg --config ui.ssh="\"$PYTHON\" $TESTDIR/dummyssh" pull
663 pulling from ssh://user@dummy/remote
663 pulling from ssh://user@dummy/remote
664 searching for changes
664 searching for changes
665 remote: abort: this is an exercise
665 remote: abort: this is an exercise
666 abort: pull failed on remote
666 abort: pull failed on remote
667 [255]
667 [255]
668
668
669 abort with no error hint when there is a ssh problem when pulling
669 abort with no error hint when there is a ssh problem when pulling
670
670
671 $ hg pull ssh://brokenrepository -e "\"$PYTHON\" \"$TESTDIR/dummyssh\""
671 $ hg pull ssh://brokenrepository -e "\"$PYTHON\" \"$TESTDIR/dummyssh\""
672 pulling from ssh://brokenrepository/
672 pulling from ssh://brokenrepository/
673 abort: no suitable response from remote hg!
673 abort: no suitable response from remote hg!
674 [255]
674 [255]
675
675
676 abort with configured error hint when there is a ssh problem when pulling
676 abort with configured error hint when there is a ssh problem when pulling
677
677
678 $ hg pull ssh://brokenrepository -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" \
678 $ hg pull ssh://brokenrepository -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" \
679 > --config ui.ssherrorhint="Please see http://company/internalwiki/ssh.html"
679 > --config ui.ssherrorhint="Please see http://company/internalwiki/ssh.html"
680 pulling from ssh://brokenrepository/
680 pulling from ssh://brokenrepository/
681 abort: no suitable response from remote hg!
681 abort: no suitable response from remote hg!
682 (Please see http://company/internalwiki/ssh.html)
682 (Please see http://company/internalwiki/ssh.html)
683 [255]
683 [255]
684
684
685 test that custom environment is passed down to ssh executable
685 test that custom environment is passed down to ssh executable
686 $ cat >>dumpenv <<EOF
686 $ cat >>dumpenv <<EOF
687 > #! /bin/sh
687 > #! /bin/sh
688 > echo \$VAR >&2
688 > echo \$VAR >&2
689 > EOF
689 > EOF
690 $ chmod +x dumpenv
690 $ chmod +x dumpenv
691 $ hg pull ssh://something --config ui.ssh="sh dumpenv"
691 $ hg pull ssh://something --config ui.ssh="sh dumpenv"
692 pulling from ssh://something/
692 pulling from ssh://something/
693 remote:
693 remote:
694 abort: no suitable response from remote hg!
694 abort: no suitable response from remote hg!
695 [255]
695 [255]
696 $ hg pull ssh://something --config ui.ssh="sh dumpenv" --config sshenv.VAR=17
696 $ hg pull ssh://something --config ui.ssh="sh dumpenv" --config sshenv.VAR=17
697 pulling from ssh://something/
697 pulling from ssh://something/
698 remote: 17
698 remote: 17
699 abort: no suitable response from remote hg!
699 abort: no suitable response from remote hg!
700 [255]
700 [255]
701
701
@@ -1,176 +1,176 b''
1 #require no-reposimplestore
1 #require no-reposimplestore
2
2
3 Test creating a consuming stream bundle v2
3 Test creating a consuming stream bundle v2
4
4
5 $ getmainid() {
5 $ getmainid() {
6 > hg -R main log --template '{node}\n' --rev "$1"
6 > hg -R main log --template '{node}\n' --rev "$1"
7 > }
7 > }
8
8
9 $ cp $HGRCPATH $TESTTMP/hgrc.orig
9 $ cp $HGRCPATH $TESTTMP/hgrc.orig
10
10
11 $ cat >> $HGRCPATH << EOF
11 $ cat >> $HGRCPATH << EOF
12 > [experimental]
12 > [experimental]
13 > evolution.createmarkers=True
13 > evolution.createmarkers=True
14 > evolution.exchange=True
14 > evolution.exchange=True
15 > bundle2-output-capture=True
15 > bundle2-output-capture=True
16 > [ui]
16 > [ui]
17 > ssh="$PYTHON" "$TESTDIR/dummyssh"
17 > ssh="$PYTHON" "$TESTDIR/dummyssh"
18 > logtemplate={rev}:{node|short} {phase} {author} {bookmarks} {desc|firstline}
18 > logtemplate={rev}:{node|short} {phase} {author} {bookmarks} {desc|firstline}
19 > [web]
19 > [web]
20 > push_ssl = false
20 > push_ssl = false
21 > allow_push = *
21 > allow_push = *
22 > [phases]
22 > [phases]
23 > publish=False
23 > publish=False
24 > [extensions]
24 > [extensions]
25 > drawdag=$TESTDIR/drawdag.py
25 > drawdag=$TESTDIR/drawdag.py
26 > clonebundles=
26 > clonebundles=
27 > EOF
27 > EOF
28
28
29 The extension requires a repo (currently unused)
29 The extension requires a repo (currently unused)
30
30
31 $ hg init main
31 $ hg init main
32 $ cd main
32 $ cd main
33
33
34 $ hg debugdrawdag <<'EOF'
34 $ hg debugdrawdag <<'EOF'
35 > E
35 > E
36 > |
36 > |
37 > D
37 > D
38 > |
38 > |
39 > C
39 > C
40 > |
40 > |
41 > B
41 > B
42 > |
42 > |
43 > A
43 > A
44 > EOF
44 > EOF
45
45
46 $ hg bundle -a --type="none-v2;stream=v2" bundle.hg
46 $ hg bundle -a --type="none-v2;stream=v2" bundle.hg
47 $ hg debugbundle bundle.hg
47 $ hg debugbundle bundle.hg
48 Stream params: {}
48 Stream params: {}
49 stream2 -- {bytecount: 1693, filecount: 11, requirements: dotencode%2Cfncache%2Cgeneraldelta%2Crevlogv1%2Csparserevlog%2Cstore} (mandatory: True)
49 stream2 -- {bytecount: 1693, filecount: 11, requirements: dotencode%2Cfncache%2Cgeneraldelta%2Crevlogv1%2Csparserevlog%2Cstore} (mandatory: True)
50 $ hg debugbundle --spec bundle.hg
50 $ hg debugbundle --spec bundle.hg
51 none-v2;stream=v2;requirements%3Ddotencode%2Cfncache%2Cgeneraldelta%2Crevlogv1%2Csparserevlog%2Cstore
51 none-v2;stream=v2;requirements%3Ddotencode%2Cfncache%2Cgeneraldelta%2Crevlogv1%2Csparserevlog%2Cstore
52
52
53 Test that we can apply the bundle as a stream clone bundle
53 Test that we can apply the bundle as a stream clone bundle
54
54
55 $ cat > .hg/clonebundles.manifest << EOF
55 $ cat > .hg/clonebundles.manifest << EOF
56 > http://localhost:$HGPORT1/bundle.hg BUNDLESPEC=`hg debugbundle --spec bundle.hg`
56 > http://localhost:$HGPORT1/bundle.hg BUNDLESPEC=`hg debugbundle --spec bundle.hg`
57 > EOF
57 > EOF
58
58
59 $ hg serve -d -p $HGPORT --pid-file hg.pid --accesslog access.log
59 $ hg serve -d -p $HGPORT --pid-file hg.pid --accesslog access.log
60 $ cat hg.pid >> $DAEMON_PIDS
60 $ cat hg.pid >> $DAEMON_PIDS
61
61
62 $ "$PYTHON" $TESTDIR/dumbhttp.py -p $HGPORT1 --pid http.pid
62 $ "$PYTHON" $TESTDIR/dumbhttp.py -p $HGPORT1 --pid http.pid
63 $ cat http.pid >> $DAEMON_PIDS
63 $ cat http.pid >> $DAEMON_PIDS
64
64
65 $ cd ..
65 $ cd ..
66 $ hg clone http://localhost:$HGPORT streamv2-clone-implicit --debug
66 $ hg clone http://localhost:$HGPORT streamv2-clone-implicit --debug
67 using http://localhost:$HGPORT/
67 using http://localhost:$HGPORT/
68 sending capabilities command
68 sending capabilities command
69 sending clonebundles command
69 sending clonebundles command
70 applying clone bundle from http://localhost:$HGPORT1/bundle.hg
70 applying clone bundle from http://localhost:$HGPORT1/bundle.hg
71 bundle2-input-bundle: with-transaction
71 bundle2-input-bundle: with-transaction
72 bundle2-input-part: "stream2" (params: 3 mandatory) supported
72 bundle2-input-part: "stream2" (params: 3 mandatory) supported
73 applying stream bundle
73 applying stream bundle
74 11 files to transfer, 1.65 KB of data
74 11 files to transfer, 1.65 KB of data
75 starting 4 threads for background file closing (?)
75 starting 4 threads for background file closing (?)
76 starting 4 threads for background file closing (?)
76 starting 4 threads for background file closing (?)
77 adding [s] data/A.i (66 bytes)
77 adding [s] data/A.i (66 bytes)
78 adding [s] data/B.i (66 bytes)
78 adding [s] data/B.i (66 bytes)
79 adding [s] data/C.i (66 bytes)
79 adding [s] data/C.i (66 bytes)
80 adding [s] data/D.i (66 bytes)
80 adding [s] data/D.i (66 bytes)
81 adding [s] data/E.i (66 bytes)
81 adding [s] data/E.i (66 bytes)
82 adding [s] 00manifest.i (584 bytes)
82 adding [s] 00manifest.i (584 bytes)
83 adding [s] 00changelog.i (595 bytes)
83 adding [s] 00changelog.i (595 bytes)
84 adding [s] phaseroots (43 bytes)
84 adding [s] phaseroots (43 bytes)
85 adding [c] branch2-served (94 bytes)
85 adding [c] branch2-served (94 bytes)
86 adding [c] rbc-names-v1 (7 bytes)
86 adding [c] rbc-names-v1 (7 bytes)
87 adding [c] rbc-revs-v1 (40 bytes)
87 adding [c] rbc-revs-v1 (40 bytes)
88 transferred 1.65 KB in \d\.\d seconds \(.*/sec\) (re)
88 transferred 1.65 KB in \d\.\d seconds \(.*/sec\) (re)
89 bundle2-input-part: total payload size 1840
89 bundle2-input-part: total payload size 1840
90 bundle2-input-bundle: 0 parts total
90 bundle2-input-bundle: 1 parts total
91 updating the branch cache
91 updating the branch cache
92 finished applying clone bundle
92 finished applying clone bundle
93 query 1; heads
93 query 1; heads
94 sending batch command
94 sending batch command
95 searching for changes
95 searching for changes
96 all remote heads known locally
96 all remote heads known locally
97 no changes found
97 no changes found
98 sending getbundle command
98 sending getbundle command
99 bundle2-input-bundle: with-transaction
99 bundle2-input-bundle: with-transaction
100 bundle2-input-part: "listkeys" (params: 1 mandatory) supported
100 bundle2-input-part: "listkeys" (params: 1 mandatory) supported
101 bundle2-input-part: "phase-heads" supported
101 bundle2-input-part: "phase-heads" supported
102 bundle2-input-part: total payload size 24
102 bundle2-input-part: total payload size 24
103 bundle2-input-bundle: 1 parts total
103 bundle2-input-bundle: 2 parts total
104 checking for updated bookmarks
104 checking for updated bookmarks
105 updating to branch default
105 updating to branch default
106 resolving manifests
106 resolving manifests
107 branchmerge: False, force: False, partial: False
107 branchmerge: False, force: False, partial: False
108 ancestor: 000000000000, local: 000000000000+, remote: 9bc730a19041
108 ancestor: 000000000000, local: 000000000000+, remote: 9bc730a19041
109 A: remote created -> g
109 A: remote created -> g
110 getting A
110 getting A
111 B: remote created -> g
111 B: remote created -> g
112 getting B
112 getting B
113 C: remote created -> g
113 C: remote created -> g
114 getting C
114 getting C
115 D: remote created -> g
115 D: remote created -> g
116 getting D
116 getting D
117 E: remote created -> g
117 E: remote created -> g
118 getting E
118 getting E
119 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
119 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
120 (sent 4 HTTP requests and * bytes; received * bytes in responses) (glob)
120 (sent 4 HTTP requests and * bytes; received * bytes in responses) (glob)
121
121
122 $ hg clone --stream http://localhost:$HGPORT streamv2-clone-explicit --debug
122 $ hg clone --stream http://localhost:$HGPORT streamv2-clone-explicit --debug
123 using http://localhost:$HGPORT/
123 using http://localhost:$HGPORT/
124 sending capabilities command
124 sending capabilities command
125 sending clonebundles command
125 sending clonebundles command
126 applying clone bundle from http://localhost:$HGPORT1/bundle.hg
126 applying clone bundle from http://localhost:$HGPORT1/bundle.hg
127 bundle2-input-bundle: with-transaction
127 bundle2-input-bundle: with-transaction
128 bundle2-input-part: "stream2" (params: 3 mandatory) supported
128 bundle2-input-part: "stream2" (params: 3 mandatory) supported
129 applying stream bundle
129 applying stream bundle
130 11 files to transfer, 1.65 KB of data
130 11 files to transfer, 1.65 KB of data
131 starting 4 threads for background file closing (?)
131 starting 4 threads for background file closing (?)
132 starting 4 threads for background file closing (?)
132 starting 4 threads for background file closing (?)
133 adding [s] data/A.i (66 bytes)
133 adding [s] data/A.i (66 bytes)
134 adding [s] data/B.i (66 bytes)
134 adding [s] data/B.i (66 bytes)
135 adding [s] data/C.i (66 bytes)
135 adding [s] data/C.i (66 bytes)
136 adding [s] data/D.i (66 bytes)
136 adding [s] data/D.i (66 bytes)
137 adding [s] data/E.i (66 bytes)
137 adding [s] data/E.i (66 bytes)
138 adding [s] 00manifest.i (584 bytes)
138 adding [s] 00manifest.i (584 bytes)
139 adding [s] 00changelog.i (595 bytes)
139 adding [s] 00changelog.i (595 bytes)
140 adding [s] phaseroots (43 bytes)
140 adding [s] phaseroots (43 bytes)
141 adding [c] branch2-served (94 bytes)
141 adding [c] branch2-served (94 bytes)
142 adding [c] rbc-names-v1 (7 bytes)
142 adding [c] rbc-names-v1 (7 bytes)
143 adding [c] rbc-revs-v1 (40 bytes)
143 adding [c] rbc-revs-v1 (40 bytes)
144 transferred 1.65 KB in *.* seconds (*/sec) (glob)
144 transferred 1.65 KB in *.* seconds (*/sec) (glob)
145 bundle2-input-part: total payload size 1840
145 bundle2-input-part: total payload size 1840
146 bundle2-input-bundle: 0 parts total
146 bundle2-input-bundle: 1 parts total
147 updating the branch cache
147 updating the branch cache
148 finished applying clone bundle
148 finished applying clone bundle
149 query 1; heads
149 query 1; heads
150 sending batch command
150 sending batch command
151 searching for changes
151 searching for changes
152 all remote heads known locally
152 all remote heads known locally
153 no changes found
153 no changes found
154 sending getbundle command
154 sending getbundle command
155 bundle2-input-bundle: with-transaction
155 bundle2-input-bundle: with-transaction
156 bundle2-input-part: "listkeys" (params: 1 mandatory) supported
156 bundle2-input-part: "listkeys" (params: 1 mandatory) supported
157 bundle2-input-part: "phase-heads" supported
157 bundle2-input-part: "phase-heads" supported
158 bundle2-input-part: total payload size 24
158 bundle2-input-part: total payload size 24
159 bundle2-input-bundle: 1 parts total
159 bundle2-input-bundle: 2 parts total
160 checking for updated bookmarks
160 checking for updated bookmarks
161 updating to branch default
161 updating to branch default
162 resolving manifests
162 resolving manifests
163 branchmerge: False, force: False, partial: False
163 branchmerge: False, force: False, partial: False
164 ancestor: 000000000000, local: 000000000000+, remote: 9bc730a19041
164 ancestor: 000000000000, local: 000000000000+, remote: 9bc730a19041
165 A: remote created -> g
165 A: remote created -> g
166 getting A
166 getting A
167 B: remote created -> g
167 B: remote created -> g
168 getting B
168 getting B
169 C: remote created -> g
169 C: remote created -> g
170 getting C
170 getting C
171 D: remote created -> g
171 D: remote created -> g
172 getting D
172 getting D
173 E: remote created -> g
173 E: remote created -> g
174 getting E
174 getting E
175 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
175 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
176 (sent 4 HTTP requests and * bytes; received * bytes in responses) (glob)
176 (sent 4 HTTP requests and * bytes; received * bytes in responses) (glob)
General Comments 0
You need to be logged in to leave comments. Login now