##// END OF EJS Templates
bundle2: store changeset count when creating file bundles...
Gregory Szorc -
r29593:953839de default
parent child Browse files
Show More
@@ -1,1608 +1,1611 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
148 from __future__ import absolute_import
149
149
150 import errno
150 import errno
151 import re
151 import re
152 import string
152 import string
153 import struct
153 import struct
154 import sys
154 import sys
155
155
156 from .i18n import _
156 from .i18n import _
157 from . import (
157 from . import (
158 changegroup,
158 changegroup,
159 error,
159 error,
160 obsolete,
160 obsolete,
161 pushkey,
161 pushkey,
162 tags,
162 tags,
163 url,
163 url,
164 util,
164 util,
165 )
165 )
166
166
167 urlerr = util.urlerr
167 urlerr = util.urlerr
168 urlreq = util.urlreq
168 urlreq = util.urlreq
169
169
170 _pack = struct.pack
170 _pack = struct.pack
171 _unpack = struct.unpack
171 _unpack = struct.unpack
172
172
173 _fstreamparamsize = '>i'
173 _fstreamparamsize = '>i'
174 _fpartheadersize = '>i'
174 _fpartheadersize = '>i'
175 _fparttypesize = '>B'
175 _fparttypesize = '>B'
176 _fpartid = '>I'
176 _fpartid = '>I'
177 _fpayloadsize = '>i'
177 _fpayloadsize = '>i'
178 _fpartparamcount = '>BB'
178 _fpartparamcount = '>BB'
179
179
180 preferedchunksize = 4096
180 preferedchunksize = 4096
181
181
182 _parttypeforbidden = re.compile('[^a-zA-Z0-9_:-]')
182 _parttypeforbidden = re.compile('[^a-zA-Z0-9_:-]')
183
183
184 def outdebug(ui, message):
184 def outdebug(ui, message):
185 """debug regarding output stream (bundling)"""
185 """debug regarding output stream (bundling)"""
186 if ui.configbool('devel', 'bundle2.debug', False):
186 if ui.configbool('devel', 'bundle2.debug', False):
187 ui.debug('bundle2-output: %s\n' % message)
187 ui.debug('bundle2-output: %s\n' % message)
188
188
189 def indebug(ui, message):
189 def indebug(ui, message):
190 """debug on input stream (unbundling)"""
190 """debug on input stream (unbundling)"""
191 if ui.configbool('devel', 'bundle2.debug', False):
191 if ui.configbool('devel', 'bundle2.debug', False):
192 ui.debug('bundle2-input: %s\n' % message)
192 ui.debug('bundle2-input: %s\n' % message)
193
193
194 def validateparttype(parttype):
194 def validateparttype(parttype):
195 """raise ValueError if a parttype contains invalid character"""
195 """raise ValueError if a parttype contains invalid character"""
196 if _parttypeforbidden.search(parttype):
196 if _parttypeforbidden.search(parttype):
197 raise ValueError(parttype)
197 raise ValueError(parttype)
198
198
199 def _makefpartparamsizes(nbparams):
199 def _makefpartparamsizes(nbparams):
200 """return a struct format to read part parameter sizes
200 """return a struct format to read part parameter sizes
201
201
202 The number parameters is variable so we need to build that format
202 The number parameters is variable so we need to build that format
203 dynamically.
203 dynamically.
204 """
204 """
205 return '>'+('BB'*nbparams)
205 return '>'+('BB'*nbparams)
206
206
207 parthandlermapping = {}
207 parthandlermapping = {}
208
208
209 def parthandler(parttype, params=()):
209 def parthandler(parttype, params=()):
210 """decorator that register a function as a bundle2 part handler
210 """decorator that register a function as a bundle2 part handler
211
211
212 eg::
212 eg::
213
213
214 @parthandler('myparttype', ('mandatory', 'param', 'handled'))
214 @parthandler('myparttype', ('mandatory', 'param', 'handled'))
215 def myparttypehandler(...):
215 def myparttypehandler(...):
216 '''process a part of type "my part".'''
216 '''process a part of type "my part".'''
217 ...
217 ...
218 """
218 """
219 validateparttype(parttype)
219 validateparttype(parttype)
220 def _decorator(func):
220 def _decorator(func):
221 lparttype = parttype.lower() # enforce lower case matching.
221 lparttype = parttype.lower() # enforce lower case matching.
222 assert lparttype not in parthandlermapping
222 assert lparttype not in parthandlermapping
223 parthandlermapping[lparttype] = func
223 parthandlermapping[lparttype] = func
224 func.params = frozenset(params)
224 func.params = frozenset(params)
225 return func
225 return func
226 return _decorator
226 return _decorator
227
227
228 class unbundlerecords(object):
228 class unbundlerecords(object):
229 """keep record of what happens during and unbundle
229 """keep record of what happens during and unbundle
230
230
231 New records are added using `records.add('cat', obj)`. Where 'cat' is a
231 New records are added using `records.add('cat', obj)`. Where 'cat' is a
232 category of record and obj is an arbitrary object.
232 category of record and obj is an arbitrary object.
233
233
234 `records['cat']` will return all entries of this category 'cat'.
234 `records['cat']` will return all entries of this category 'cat'.
235
235
236 Iterating on the object itself will yield `('category', obj)` tuples
236 Iterating on the object itself will yield `('category', obj)` tuples
237 for all entries.
237 for all entries.
238
238
239 All iterations happens in chronological order.
239 All iterations happens in chronological order.
240 """
240 """
241
241
242 def __init__(self):
242 def __init__(self):
243 self._categories = {}
243 self._categories = {}
244 self._sequences = []
244 self._sequences = []
245 self._replies = {}
245 self._replies = {}
246
246
247 def add(self, category, entry, inreplyto=None):
247 def add(self, category, entry, inreplyto=None):
248 """add a new record of a given category.
248 """add a new record of a given category.
249
249
250 The entry can then be retrieved in the list returned by
250 The entry can then be retrieved in the list returned by
251 self['category']."""
251 self['category']."""
252 self._categories.setdefault(category, []).append(entry)
252 self._categories.setdefault(category, []).append(entry)
253 self._sequences.append((category, entry))
253 self._sequences.append((category, entry))
254 if inreplyto is not None:
254 if inreplyto is not None:
255 self.getreplies(inreplyto).add(category, entry)
255 self.getreplies(inreplyto).add(category, entry)
256
256
257 def getreplies(self, partid):
257 def getreplies(self, partid):
258 """get the records that are replies to a specific part"""
258 """get the records that are replies to a specific part"""
259 return self._replies.setdefault(partid, unbundlerecords())
259 return self._replies.setdefault(partid, unbundlerecords())
260
260
261 def __getitem__(self, cat):
261 def __getitem__(self, cat):
262 return tuple(self._categories.get(cat, ()))
262 return tuple(self._categories.get(cat, ()))
263
263
264 def __iter__(self):
264 def __iter__(self):
265 return iter(self._sequences)
265 return iter(self._sequences)
266
266
267 def __len__(self):
267 def __len__(self):
268 return len(self._sequences)
268 return len(self._sequences)
269
269
270 def __nonzero__(self):
270 def __nonzero__(self):
271 return bool(self._sequences)
271 return bool(self._sequences)
272
272
273 class bundleoperation(object):
273 class bundleoperation(object):
274 """an object that represents a single bundling process
274 """an object that represents a single bundling process
275
275
276 Its purpose is to carry unbundle-related objects and states.
276 Its purpose is to carry unbundle-related objects and states.
277
277
278 A new object should be created at the beginning of each bundle processing.
278 A new object should be created at the beginning of each bundle processing.
279 The object is to be returned by the processing function.
279 The object is to be returned by the processing function.
280
280
281 The object has very little content now it will ultimately contain:
281 The object has very little content now it will ultimately contain:
282 * an access to the repo the bundle is applied to,
282 * an access to the repo the bundle is applied to,
283 * a ui object,
283 * a ui object,
284 * a way to retrieve a transaction to add changes to the repo,
284 * a way to retrieve a transaction to add changes to the repo,
285 * a way to record the result of processing each part,
285 * a way to record the result of processing each part,
286 * a way to construct a bundle response when applicable.
286 * a way to construct a bundle response when applicable.
287 """
287 """
288
288
289 def __init__(self, repo, transactiongetter, captureoutput=True):
289 def __init__(self, repo, transactiongetter, captureoutput=True):
290 self.repo = repo
290 self.repo = repo
291 self.ui = repo.ui
291 self.ui = repo.ui
292 self.records = unbundlerecords()
292 self.records = unbundlerecords()
293 self.gettransaction = transactiongetter
293 self.gettransaction = transactiongetter
294 self.reply = None
294 self.reply = None
295 self.captureoutput = captureoutput
295 self.captureoutput = captureoutput
296
296
297 class TransactionUnavailable(RuntimeError):
297 class TransactionUnavailable(RuntimeError):
298 pass
298 pass
299
299
300 def _notransaction():
300 def _notransaction():
301 """default method to get a transaction while processing a bundle
301 """default method to get a transaction while processing a bundle
302
302
303 Raise an exception to highlight the fact that no transaction was expected
303 Raise an exception to highlight the fact that no transaction was expected
304 to be created"""
304 to be created"""
305 raise TransactionUnavailable()
305 raise TransactionUnavailable()
306
306
307 def applybundle(repo, unbundler, tr, source=None, url=None, op=None):
307 def applybundle(repo, unbundler, tr, source=None, url=None, op=None):
308 # transform me into unbundler.apply() as soon as the freeze is lifted
308 # transform me into unbundler.apply() as soon as the freeze is lifted
309 tr.hookargs['bundle2'] = '1'
309 tr.hookargs['bundle2'] = '1'
310 if source is not None and 'source' not in tr.hookargs:
310 if source is not None and 'source' not in tr.hookargs:
311 tr.hookargs['source'] = source
311 tr.hookargs['source'] = source
312 if url is not None and 'url' not in tr.hookargs:
312 if url is not None and 'url' not in tr.hookargs:
313 tr.hookargs['url'] = url
313 tr.hookargs['url'] = url
314 return processbundle(repo, unbundler, lambda: tr, op=op)
314 return processbundle(repo, unbundler, lambda: tr, op=op)
315
315
316 def processbundle(repo, unbundler, transactiongetter=None, op=None):
316 def processbundle(repo, unbundler, transactiongetter=None, op=None):
317 """This function process a bundle, apply effect to/from a repo
317 """This function process a bundle, apply effect to/from a repo
318
318
319 It iterates over each part then searches for and uses the proper handling
319 It iterates over each part then searches for and uses the proper handling
320 code to process the part. Parts are processed in order.
320 code to process the part. Parts are processed in order.
321
321
322 This is very early version of this function that will be strongly reworked
322 This is very early version of this function that will be strongly reworked
323 before final usage.
323 before final usage.
324
324
325 Unknown Mandatory part will abort the process.
325 Unknown Mandatory part will abort the process.
326
326
327 It is temporarily possible to provide a prebuilt bundleoperation to the
327 It is temporarily possible to provide a prebuilt bundleoperation to the
328 function. This is used to ensure output is properly propagated in case of
328 function. This is used to ensure output is properly propagated in case of
329 an error during the unbundling. This output capturing part will likely be
329 an error during the unbundling. This output capturing part will likely be
330 reworked and this ability will probably go away in the process.
330 reworked and this ability will probably go away in the process.
331 """
331 """
332 if op is None:
332 if op is None:
333 if transactiongetter is None:
333 if transactiongetter is None:
334 transactiongetter = _notransaction
334 transactiongetter = _notransaction
335 op = bundleoperation(repo, transactiongetter)
335 op = bundleoperation(repo, transactiongetter)
336 # todo:
336 # todo:
337 # - replace this is a init function soon.
337 # - replace this is a init function soon.
338 # - exception catching
338 # - exception catching
339 unbundler.params
339 unbundler.params
340 if repo.ui.debugflag:
340 if repo.ui.debugflag:
341 msg = ['bundle2-input-bundle:']
341 msg = ['bundle2-input-bundle:']
342 if unbundler.params:
342 if unbundler.params:
343 msg.append(' %i params')
343 msg.append(' %i params')
344 if op.gettransaction is None:
344 if op.gettransaction is None:
345 msg.append(' no-transaction')
345 msg.append(' no-transaction')
346 else:
346 else:
347 msg.append(' with-transaction')
347 msg.append(' with-transaction')
348 msg.append('\n')
348 msg.append('\n')
349 repo.ui.debug(''.join(msg))
349 repo.ui.debug(''.join(msg))
350 iterparts = enumerate(unbundler.iterparts())
350 iterparts = enumerate(unbundler.iterparts())
351 part = None
351 part = None
352 nbpart = 0
352 nbpart = 0
353 try:
353 try:
354 for nbpart, part in iterparts:
354 for nbpart, part in iterparts:
355 _processpart(op, part)
355 _processpart(op, part)
356 except BaseException as exc:
356 except BaseException as exc:
357 for nbpart, part in iterparts:
357 for nbpart, part in iterparts:
358 # consume the bundle content
358 # consume the bundle content
359 part.seek(0, 2)
359 part.seek(0, 2)
360 # Small hack to let caller code distinguish exceptions from bundle2
360 # Small hack to let caller code distinguish exceptions from bundle2
361 # processing from processing the old format. This is mostly
361 # processing from processing the old format. This is mostly
362 # needed to handle different return codes to unbundle according to the
362 # needed to handle different return codes to unbundle according to the
363 # type of bundle. We should probably clean up or drop this return code
363 # type of bundle. We should probably clean up or drop this return code
364 # craziness in a future version.
364 # craziness in a future version.
365 exc.duringunbundle2 = True
365 exc.duringunbundle2 = True
366 salvaged = []
366 salvaged = []
367 replycaps = None
367 replycaps = None
368 if op.reply is not None:
368 if op.reply is not None:
369 salvaged = op.reply.salvageoutput()
369 salvaged = op.reply.salvageoutput()
370 replycaps = op.reply.capabilities
370 replycaps = op.reply.capabilities
371 exc._replycaps = replycaps
371 exc._replycaps = replycaps
372 exc._bundle2salvagedoutput = salvaged
372 exc._bundle2salvagedoutput = salvaged
373 raise
373 raise
374 finally:
374 finally:
375 repo.ui.debug('bundle2-input-bundle: %i parts total\n' % nbpart)
375 repo.ui.debug('bundle2-input-bundle: %i parts total\n' % nbpart)
376
376
377 return op
377 return op
378
378
379 def _processpart(op, part):
379 def _processpart(op, part):
380 """process a single part from a bundle
380 """process a single part from a bundle
381
381
382 The part is guaranteed to have been fully consumed when the function exits
382 The part is guaranteed to have been fully consumed when the function exits
383 (even if an exception is raised)."""
383 (even if an exception is raised)."""
384 status = 'unknown' # used by debug output
384 status = 'unknown' # used by debug output
385 try:
385 try:
386 try:
386 try:
387 handler = parthandlermapping.get(part.type)
387 handler = parthandlermapping.get(part.type)
388 if handler is None:
388 if handler is None:
389 status = 'unsupported-type'
389 status = 'unsupported-type'
390 raise error.BundleUnknownFeatureError(parttype=part.type)
390 raise error.BundleUnknownFeatureError(parttype=part.type)
391 indebug(op.ui, 'found a handler for part %r' % part.type)
391 indebug(op.ui, 'found a handler for part %r' % part.type)
392 unknownparams = part.mandatorykeys - handler.params
392 unknownparams = part.mandatorykeys - handler.params
393 if unknownparams:
393 if unknownparams:
394 unknownparams = list(unknownparams)
394 unknownparams = list(unknownparams)
395 unknownparams.sort()
395 unknownparams.sort()
396 status = 'unsupported-params (%s)' % unknownparams
396 status = 'unsupported-params (%s)' % unknownparams
397 raise error.BundleUnknownFeatureError(parttype=part.type,
397 raise error.BundleUnknownFeatureError(parttype=part.type,
398 params=unknownparams)
398 params=unknownparams)
399 status = 'supported'
399 status = 'supported'
400 except error.BundleUnknownFeatureError as exc:
400 except error.BundleUnknownFeatureError as exc:
401 if part.mandatory: # mandatory parts
401 if part.mandatory: # mandatory parts
402 raise
402 raise
403 indebug(op.ui, 'ignoring unsupported advisory part %s' % exc)
403 indebug(op.ui, 'ignoring unsupported advisory part %s' % exc)
404 return # skip to part processing
404 return # skip to part processing
405 finally:
405 finally:
406 if op.ui.debugflag:
406 if op.ui.debugflag:
407 msg = ['bundle2-input-part: "%s"' % part.type]
407 msg = ['bundle2-input-part: "%s"' % part.type]
408 if not part.mandatory:
408 if not part.mandatory:
409 msg.append(' (advisory)')
409 msg.append(' (advisory)')
410 nbmp = len(part.mandatorykeys)
410 nbmp = len(part.mandatorykeys)
411 nbap = len(part.params) - nbmp
411 nbap = len(part.params) - nbmp
412 if nbmp or nbap:
412 if nbmp or nbap:
413 msg.append(' (params:')
413 msg.append(' (params:')
414 if nbmp:
414 if nbmp:
415 msg.append(' %i mandatory' % nbmp)
415 msg.append(' %i mandatory' % nbmp)
416 if nbap:
416 if nbap:
417 msg.append(' %i advisory' % nbmp)
417 msg.append(' %i advisory' % nbmp)
418 msg.append(')')
418 msg.append(')')
419 msg.append(' %s\n' % status)
419 msg.append(' %s\n' % status)
420 op.ui.debug(''.join(msg))
420 op.ui.debug(''.join(msg))
421
421
422 # handler is called outside the above try block so that we don't
422 # handler is called outside the above try block so that we don't
423 # risk catching KeyErrors from anything other than the
423 # risk catching KeyErrors from anything other than the
424 # parthandlermapping lookup (any KeyError raised by handler()
424 # parthandlermapping lookup (any KeyError raised by handler()
425 # itself represents a defect of a different variety).
425 # itself represents a defect of a different variety).
426 output = None
426 output = None
427 if op.captureoutput and op.reply is not None:
427 if op.captureoutput and op.reply is not None:
428 op.ui.pushbuffer(error=True, subproc=True)
428 op.ui.pushbuffer(error=True, subproc=True)
429 output = ''
429 output = ''
430 try:
430 try:
431 handler(op, part)
431 handler(op, part)
432 finally:
432 finally:
433 if output is not None:
433 if output is not None:
434 output = op.ui.popbuffer()
434 output = op.ui.popbuffer()
435 if output:
435 if output:
436 outpart = op.reply.newpart('output', data=output,
436 outpart = op.reply.newpart('output', data=output,
437 mandatory=False)
437 mandatory=False)
438 outpart.addparam('in-reply-to', str(part.id), mandatory=False)
438 outpart.addparam('in-reply-to', str(part.id), mandatory=False)
439 finally:
439 finally:
440 # consume the part content to not corrupt the stream.
440 # consume the part content to not corrupt the stream.
441 part.seek(0, 2)
441 part.seek(0, 2)
442
442
443
443
444 def decodecaps(blob):
444 def decodecaps(blob):
445 """decode a bundle2 caps bytes blob into a dictionary
445 """decode a bundle2 caps bytes blob into a dictionary
446
446
447 The blob is a list of capabilities (one per line)
447 The blob is a list of capabilities (one per line)
448 Capabilities may have values using a line of the form::
448 Capabilities may have values using a line of the form::
449
449
450 capability=value1,value2,value3
450 capability=value1,value2,value3
451
451
452 The values are always a list."""
452 The values are always a list."""
453 caps = {}
453 caps = {}
454 for line in blob.splitlines():
454 for line in blob.splitlines():
455 if not line:
455 if not line:
456 continue
456 continue
457 if '=' not in line:
457 if '=' not in line:
458 key, vals = line, ()
458 key, vals = line, ()
459 else:
459 else:
460 key, vals = line.split('=', 1)
460 key, vals = line.split('=', 1)
461 vals = vals.split(',')
461 vals = vals.split(',')
462 key = urlreq.unquote(key)
462 key = urlreq.unquote(key)
463 vals = [urlreq.unquote(v) for v in vals]
463 vals = [urlreq.unquote(v) for v in vals]
464 caps[key] = vals
464 caps[key] = vals
465 return caps
465 return caps
466
466
467 def encodecaps(caps):
467 def encodecaps(caps):
468 """encode a bundle2 caps dictionary into a bytes blob"""
468 """encode a bundle2 caps dictionary into a bytes blob"""
469 chunks = []
469 chunks = []
470 for ca in sorted(caps):
470 for ca in sorted(caps):
471 vals = caps[ca]
471 vals = caps[ca]
472 ca = urlreq.quote(ca)
472 ca = urlreq.quote(ca)
473 vals = [urlreq.quote(v) for v in vals]
473 vals = [urlreq.quote(v) for v in vals]
474 if vals:
474 if vals:
475 ca = "%s=%s" % (ca, ','.join(vals))
475 ca = "%s=%s" % (ca, ','.join(vals))
476 chunks.append(ca)
476 chunks.append(ca)
477 return '\n'.join(chunks)
477 return '\n'.join(chunks)
478
478
479 bundletypes = {
479 bundletypes = {
480 "": ("", None), # only when using unbundle on ssh and old http servers
480 "": ("", None), # only when using unbundle on ssh and old http servers
481 # since the unification ssh accepts a header but there
481 # since the unification ssh accepts a header but there
482 # is no capability signaling it.
482 # is no capability signaling it.
483 "HG20": (), # special-cased below
483 "HG20": (), # special-cased below
484 "HG10UN": ("HG10UN", None),
484 "HG10UN": ("HG10UN", None),
485 "HG10BZ": ("HG10", 'BZ'),
485 "HG10BZ": ("HG10", 'BZ'),
486 "HG10GZ": ("HG10GZ", 'GZ'),
486 "HG10GZ": ("HG10GZ", 'GZ'),
487 }
487 }
488
488
489 # hgweb uses this list to communicate its preferred type
489 # hgweb uses this list to communicate its preferred type
490 bundlepriority = ['HG10GZ', 'HG10BZ', 'HG10UN']
490 bundlepriority = ['HG10GZ', 'HG10BZ', 'HG10UN']
491
491
492 class bundle20(object):
492 class bundle20(object):
493 """represent an outgoing bundle2 container
493 """represent an outgoing bundle2 container
494
494
495 Use the `addparam` method to add stream level parameter. and `newpart` to
495 Use the `addparam` method to add stream level parameter. and `newpart` to
496 populate it. Then call `getchunks` to retrieve all the binary chunks of
496 populate it. Then call `getchunks` to retrieve all the binary chunks of
497 data that compose the bundle2 container."""
497 data that compose the bundle2 container."""
498
498
499 _magicstring = 'HG20'
499 _magicstring = 'HG20'
500
500
501 def __init__(self, ui, capabilities=()):
501 def __init__(self, ui, capabilities=()):
502 self.ui = ui
502 self.ui = ui
503 self._params = []
503 self._params = []
504 self._parts = []
504 self._parts = []
505 self.capabilities = dict(capabilities)
505 self.capabilities = dict(capabilities)
506 self._compressor = util.compressors[None]()
506 self._compressor = util.compressors[None]()
507
507
508 def setcompression(self, alg):
508 def setcompression(self, alg):
509 """setup core part compression to <alg>"""
509 """setup core part compression to <alg>"""
510 if alg is None:
510 if alg is None:
511 return
511 return
512 assert not any(n.lower() == 'Compression' for n, v in self._params)
512 assert not any(n.lower() == 'Compression' for n, v in self._params)
513 self.addparam('Compression', alg)
513 self.addparam('Compression', alg)
514 self._compressor = util.compressors[alg]()
514 self._compressor = util.compressors[alg]()
515
515
516 @property
516 @property
517 def nbparts(self):
517 def nbparts(self):
518 """total number of parts added to the bundler"""
518 """total number of parts added to the bundler"""
519 return len(self._parts)
519 return len(self._parts)
520
520
521 # methods used to defines the bundle2 content
521 # methods used to defines the bundle2 content
522 def addparam(self, name, value=None):
522 def addparam(self, name, value=None):
523 """add a stream level parameter"""
523 """add a stream level parameter"""
524 if not name:
524 if not name:
525 raise ValueError('empty parameter name')
525 raise ValueError('empty parameter name')
526 if name[0] not in string.letters:
526 if name[0] not in string.letters:
527 raise ValueError('non letter first character: %r' % name)
527 raise ValueError('non letter first character: %r' % name)
528 self._params.append((name, value))
528 self._params.append((name, value))
529
529
530 def addpart(self, part):
530 def addpart(self, part):
531 """add a new part to the bundle2 container
531 """add a new part to the bundle2 container
532
532
533 Parts contains the actual applicative payload."""
533 Parts contains the actual applicative payload."""
534 assert part.id is None
534 assert part.id is None
535 part.id = len(self._parts) # very cheap counter
535 part.id = len(self._parts) # very cheap counter
536 self._parts.append(part)
536 self._parts.append(part)
537
537
538 def newpart(self, typeid, *args, **kwargs):
538 def newpart(self, typeid, *args, **kwargs):
539 """create a new part and add it to the containers
539 """create a new part and add it to the containers
540
540
541 As the part is directly added to the containers. For now, this means
541 As the part is directly added to the containers. For now, this means
542 that any failure to properly initialize the part after calling
542 that any failure to properly initialize the part after calling
543 ``newpart`` should result in a failure of the whole bundling process.
543 ``newpart`` should result in a failure of the whole bundling process.
544
544
545 You can still fall back to manually create and add if you need better
545 You can still fall back to manually create and add if you need better
546 control."""
546 control."""
547 part = bundlepart(typeid, *args, **kwargs)
547 part = bundlepart(typeid, *args, **kwargs)
548 self.addpart(part)
548 self.addpart(part)
549 return part
549 return part
550
550
551 # methods used to generate the bundle2 stream
551 # methods used to generate the bundle2 stream
552 def getchunks(self):
552 def getchunks(self):
553 if self.ui.debugflag:
553 if self.ui.debugflag:
554 msg = ['bundle2-output-bundle: "%s",' % self._magicstring]
554 msg = ['bundle2-output-bundle: "%s",' % self._magicstring]
555 if self._params:
555 if self._params:
556 msg.append(' (%i params)' % len(self._params))
556 msg.append(' (%i params)' % len(self._params))
557 msg.append(' %i parts total\n' % len(self._parts))
557 msg.append(' %i parts total\n' % len(self._parts))
558 self.ui.debug(''.join(msg))
558 self.ui.debug(''.join(msg))
559 outdebug(self.ui, 'start emission of %s stream' % self._magicstring)
559 outdebug(self.ui, 'start emission of %s stream' % self._magicstring)
560 yield self._magicstring
560 yield self._magicstring
561 param = self._paramchunk()
561 param = self._paramchunk()
562 outdebug(self.ui, 'bundle parameter: %s' % param)
562 outdebug(self.ui, 'bundle parameter: %s' % param)
563 yield _pack(_fstreamparamsize, len(param))
563 yield _pack(_fstreamparamsize, len(param))
564 if param:
564 if param:
565 yield param
565 yield param
566 # starting compression
566 # starting compression
567 for chunk in self._getcorechunk():
567 for chunk in self._getcorechunk():
568 yield self._compressor.compress(chunk)
568 yield self._compressor.compress(chunk)
569 yield self._compressor.flush()
569 yield self._compressor.flush()
570
570
571 def _paramchunk(self):
571 def _paramchunk(self):
572 """return a encoded version of all stream parameters"""
572 """return a encoded version of all stream parameters"""
573 blocks = []
573 blocks = []
574 for par, value in self._params:
574 for par, value in self._params:
575 par = urlreq.quote(par)
575 par = urlreq.quote(par)
576 if value is not None:
576 if value is not None:
577 value = urlreq.quote(value)
577 value = urlreq.quote(value)
578 par = '%s=%s' % (par, value)
578 par = '%s=%s' % (par, value)
579 blocks.append(par)
579 blocks.append(par)
580 return ' '.join(blocks)
580 return ' '.join(blocks)
581
581
582 def _getcorechunk(self):
582 def _getcorechunk(self):
583 """yield chunk for the core part of the bundle
583 """yield chunk for the core part of the bundle
584
584
585 (all but headers and parameters)"""
585 (all but headers and parameters)"""
586 outdebug(self.ui, 'start of parts')
586 outdebug(self.ui, 'start of parts')
587 for part in self._parts:
587 for part in self._parts:
588 outdebug(self.ui, 'bundle part: "%s"' % part.type)
588 outdebug(self.ui, 'bundle part: "%s"' % part.type)
589 for chunk in part.getchunks(ui=self.ui):
589 for chunk in part.getchunks(ui=self.ui):
590 yield chunk
590 yield chunk
591 outdebug(self.ui, 'end of bundle')
591 outdebug(self.ui, 'end of bundle')
592 yield _pack(_fpartheadersize, 0)
592 yield _pack(_fpartheadersize, 0)
593
593
594
594
595 def salvageoutput(self):
595 def salvageoutput(self):
596 """return a list with a copy of all output parts in the bundle
596 """return a list with a copy of all output parts in the bundle
597
597
598 This is meant to be used during error handling to make sure we preserve
598 This is meant to be used during error handling to make sure we preserve
599 server output"""
599 server output"""
600 salvaged = []
600 salvaged = []
601 for part in self._parts:
601 for part in self._parts:
602 if part.type.startswith('output'):
602 if part.type.startswith('output'):
603 salvaged.append(part.copy())
603 salvaged.append(part.copy())
604 return salvaged
604 return salvaged
605
605
606
606
607 class unpackermixin(object):
607 class unpackermixin(object):
608 """A mixin to extract bytes and struct data from a stream"""
608 """A mixin to extract bytes and struct data from a stream"""
609
609
610 def __init__(self, fp):
610 def __init__(self, fp):
611 self._fp = fp
611 self._fp = fp
612 self._seekable = (util.safehasattr(fp, 'seek') and
612 self._seekable = (util.safehasattr(fp, 'seek') and
613 util.safehasattr(fp, 'tell'))
613 util.safehasattr(fp, 'tell'))
614
614
615 def _unpack(self, format):
615 def _unpack(self, format):
616 """unpack this struct format from the stream"""
616 """unpack this struct format from the stream"""
617 data = self._readexact(struct.calcsize(format))
617 data = self._readexact(struct.calcsize(format))
618 return _unpack(format, data)
618 return _unpack(format, data)
619
619
620 def _readexact(self, size):
620 def _readexact(self, size):
621 """read exactly <size> bytes from the stream"""
621 """read exactly <size> bytes from the stream"""
622 return changegroup.readexactly(self._fp, size)
622 return changegroup.readexactly(self._fp, size)
623
623
624 def seek(self, offset, whence=0):
624 def seek(self, offset, whence=0):
625 """move the underlying file pointer"""
625 """move the underlying file pointer"""
626 if self._seekable:
626 if self._seekable:
627 return self._fp.seek(offset, whence)
627 return self._fp.seek(offset, whence)
628 else:
628 else:
629 raise NotImplementedError(_('File pointer is not seekable'))
629 raise NotImplementedError(_('File pointer is not seekable'))
630
630
631 def tell(self):
631 def tell(self):
632 """return the file offset, or None if file is not seekable"""
632 """return the file offset, or None if file is not seekable"""
633 if self._seekable:
633 if self._seekable:
634 try:
634 try:
635 return self._fp.tell()
635 return self._fp.tell()
636 except IOError as e:
636 except IOError as e:
637 if e.errno == errno.ESPIPE:
637 if e.errno == errno.ESPIPE:
638 self._seekable = False
638 self._seekable = False
639 else:
639 else:
640 raise
640 raise
641 return None
641 return None
642
642
643 def close(self):
643 def close(self):
644 """close underlying file"""
644 """close underlying file"""
645 if util.safehasattr(self._fp, 'close'):
645 if util.safehasattr(self._fp, 'close'):
646 return self._fp.close()
646 return self._fp.close()
647
647
648 def getunbundler(ui, fp, magicstring=None):
648 def getunbundler(ui, fp, magicstring=None):
649 """return a valid unbundler object for a given magicstring"""
649 """return a valid unbundler object for a given magicstring"""
650 if magicstring is None:
650 if magicstring is None:
651 magicstring = changegroup.readexactly(fp, 4)
651 magicstring = changegroup.readexactly(fp, 4)
652 magic, version = magicstring[0:2], magicstring[2:4]
652 magic, version = magicstring[0:2], magicstring[2:4]
653 if magic != 'HG':
653 if magic != 'HG':
654 raise error.Abort(_('not a Mercurial bundle'))
654 raise error.Abort(_('not a Mercurial bundle'))
655 unbundlerclass = formatmap.get(version)
655 unbundlerclass = formatmap.get(version)
656 if unbundlerclass is None:
656 if unbundlerclass is None:
657 raise error.Abort(_('unknown bundle version %s') % version)
657 raise error.Abort(_('unknown bundle version %s') % version)
658 unbundler = unbundlerclass(ui, fp)
658 unbundler = unbundlerclass(ui, fp)
659 indebug(ui, 'start processing of %s stream' % magicstring)
659 indebug(ui, 'start processing of %s stream' % magicstring)
660 return unbundler
660 return unbundler
661
661
662 class unbundle20(unpackermixin):
662 class unbundle20(unpackermixin):
663 """interpret a bundle2 stream
663 """interpret a bundle2 stream
664
664
665 This class is fed with a binary stream and yields parts through its
665 This class is fed with a binary stream and yields parts through its
666 `iterparts` methods."""
666 `iterparts` methods."""
667
667
668 _magicstring = 'HG20'
668 _magicstring = 'HG20'
669
669
670 def __init__(self, ui, fp):
670 def __init__(self, ui, fp):
671 """If header is specified, we do not read it out of the stream."""
671 """If header is specified, we do not read it out of the stream."""
672 self.ui = ui
672 self.ui = ui
673 self._decompressor = util.decompressors[None]
673 self._decompressor = util.decompressors[None]
674 self._compressed = None
674 self._compressed = None
675 super(unbundle20, self).__init__(fp)
675 super(unbundle20, self).__init__(fp)
676
676
677 @util.propertycache
677 @util.propertycache
678 def params(self):
678 def params(self):
679 """dictionary of stream level parameters"""
679 """dictionary of stream level parameters"""
680 indebug(self.ui, 'reading bundle2 stream parameters')
680 indebug(self.ui, 'reading bundle2 stream parameters')
681 params = {}
681 params = {}
682 paramssize = self._unpack(_fstreamparamsize)[0]
682 paramssize = self._unpack(_fstreamparamsize)[0]
683 if paramssize < 0:
683 if paramssize < 0:
684 raise error.BundleValueError('negative bundle param size: %i'
684 raise error.BundleValueError('negative bundle param size: %i'
685 % paramssize)
685 % paramssize)
686 if paramssize:
686 if paramssize:
687 params = self._readexact(paramssize)
687 params = self._readexact(paramssize)
688 params = self._processallparams(params)
688 params = self._processallparams(params)
689 return params
689 return params
690
690
691 def _processallparams(self, paramsblock):
691 def _processallparams(self, paramsblock):
692 """"""
692 """"""
693 params = util.sortdict()
693 params = util.sortdict()
694 for p in paramsblock.split(' '):
694 for p in paramsblock.split(' '):
695 p = p.split('=', 1)
695 p = p.split('=', 1)
696 p = [urlreq.unquote(i) for i in p]
696 p = [urlreq.unquote(i) for i in p]
697 if len(p) < 2:
697 if len(p) < 2:
698 p.append(None)
698 p.append(None)
699 self._processparam(*p)
699 self._processparam(*p)
700 params[p[0]] = p[1]
700 params[p[0]] = p[1]
701 return params
701 return params
702
702
703
703
704 def _processparam(self, name, value):
704 def _processparam(self, name, value):
705 """process a parameter, applying its effect if needed
705 """process a parameter, applying its effect if needed
706
706
707 Parameter starting with a lower case letter are advisory and will be
707 Parameter starting with a lower case letter are advisory and will be
708 ignored when unknown. Those starting with an upper case letter are
708 ignored when unknown. Those starting with an upper case letter are
709 mandatory and will this function will raise a KeyError when unknown.
709 mandatory and will this function will raise a KeyError when unknown.
710
710
711 Note: no option are currently supported. Any input will be either
711 Note: no option are currently supported. Any input will be either
712 ignored or failing.
712 ignored or failing.
713 """
713 """
714 if not name:
714 if not name:
715 raise ValueError('empty parameter name')
715 raise ValueError('empty parameter name')
716 if name[0] not in string.letters:
716 if name[0] not in string.letters:
717 raise ValueError('non letter first character: %r' % name)
717 raise ValueError('non letter first character: %r' % name)
718 try:
718 try:
719 handler = b2streamparamsmap[name.lower()]
719 handler = b2streamparamsmap[name.lower()]
720 except KeyError:
720 except KeyError:
721 if name[0].islower():
721 if name[0].islower():
722 indebug(self.ui, "ignoring unknown parameter %r" % name)
722 indebug(self.ui, "ignoring unknown parameter %r" % name)
723 else:
723 else:
724 raise error.BundleUnknownFeatureError(params=(name,))
724 raise error.BundleUnknownFeatureError(params=(name,))
725 else:
725 else:
726 handler(self, name, value)
726 handler(self, name, value)
727
727
728 def _forwardchunks(self):
728 def _forwardchunks(self):
729 """utility to transfer a bundle2 as binary
729 """utility to transfer a bundle2 as binary
730
730
731 This is made necessary by the fact the 'getbundle' command over 'ssh'
731 This is made necessary by the fact the 'getbundle' command over 'ssh'
732 have no way to know then the reply end, relying on the bundle to be
732 have no way to know then the reply end, relying on the bundle to be
733 interpreted to know its end. This is terrible and we are sorry, but we
733 interpreted to know its end. This is terrible and we are sorry, but we
734 needed to move forward to get general delta enabled.
734 needed to move forward to get general delta enabled.
735 """
735 """
736 yield self._magicstring
736 yield self._magicstring
737 assert 'params' not in vars(self)
737 assert 'params' not in vars(self)
738 paramssize = self._unpack(_fstreamparamsize)[0]
738 paramssize = self._unpack(_fstreamparamsize)[0]
739 if paramssize < 0:
739 if paramssize < 0:
740 raise error.BundleValueError('negative bundle param size: %i'
740 raise error.BundleValueError('negative bundle param size: %i'
741 % paramssize)
741 % paramssize)
742 yield _pack(_fstreamparamsize, paramssize)
742 yield _pack(_fstreamparamsize, paramssize)
743 if paramssize:
743 if paramssize:
744 params = self._readexact(paramssize)
744 params = self._readexact(paramssize)
745 self._processallparams(params)
745 self._processallparams(params)
746 yield params
746 yield params
747 assert self._decompressor is util.decompressors[None]
747 assert self._decompressor is util.decompressors[None]
748 # From there, payload might need to be decompressed
748 # From there, payload might need to be decompressed
749 self._fp = self._decompressor(self._fp)
749 self._fp = self._decompressor(self._fp)
750 emptycount = 0
750 emptycount = 0
751 while emptycount < 2:
751 while emptycount < 2:
752 # so we can brainlessly loop
752 # so we can brainlessly loop
753 assert _fpartheadersize == _fpayloadsize
753 assert _fpartheadersize == _fpayloadsize
754 size = self._unpack(_fpartheadersize)[0]
754 size = self._unpack(_fpartheadersize)[0]
755 yield _pack(_fpartheadersize, size)
755 yield _pack(_fpartheadersize, size)
756 if size:
756 if size:
757 emptycount = 0
757 emptycount = 0
758 else:
758 else:
759 emptycount += 1
759 emptycount += 1
760 continue
760 continue
761 if size == flaginterrupt:
761 if size == flaginterrupt:
762 continue
762 continue
763 elif size < 0:
763 elif size < 0:
764 raise error.BundleValueError('negative chunk size: %i')
764 raise error.BundleValueError('negative chunk size: %i')
765 yield self._readexact(size)
765 yield self._readexact(size)
766
766
767
767
768 def iterparts(self):
768 def iterparts(self):
769 """yield all parts contained in the stream"""
769 """yield all parts contained in the stream"""
770 # make sure param have been loaded
770 # make sure param have been loaded
771 self.params
771 self.params
772 # From there, payload need to be decompressed
772 # From there, payload need to be decompressed
773 self._fp = self._decompressor(self._fp)
773 self._fp = self._decompressor(self._fp)
774 indebug(self.ui, 'start extraction of bundle2 parts')
774 indebug(self.ui, 'start extraction of bundle2 parts')
775 headerblock = self._readpartheader()
775 headerblock = self._readpartheader()
776 while headerblock is not None:
776 while headerblock is not None:
777 part = unbundlepart(self.ui, headerblock, self._fp)
777 part = unbundlepart(self.ui, headerblock, self._fp)
778 yield part
778 yield part
779 part.seek(0, 2)
779 part.seek(0, 2)
780 headerblock = self._readpartheader()
780 headerblock = self._readpartheader()
781 indebug(self.ui, 'end of bundle2 stream')
781 indebug(self.ui, 'end of bundle2 stream')
782
782
783 def _readpartheader(self):
783 def _readpartheader(self):
784 """reads a part header size and return the bytes blob
784 """reads a part header size and return the bytes blob
785
785
786 returns None if empty"""
786 returns None if empty"""
787 headersize = self._unpack(_fpartheadersize)[0]
787 headersize = self._unpack(_fpartheadersize)[0]
788 if headersize < 0:
788 if headersize < 0:
789 raise error.BundleValueError('negative part header size: %i'
789 raise error.BundleValueError('negative part header size: %i'
790 % headersize)
790 % headersize)
791 indebug(self.ui, 'part header size: %i' % headersize)
791 indebug(self.ui, 'part header size: %i' % headersize)
792 if headersize:
792 if headersize:
793 return self._readexact(headersize)
793 return self._readexact(headersize)
794 return None
794 return None
795
795
796 def compressed(self):
796 def compressed(self):
797 self.params # load params
797 self.params # load params
798 return self._compressed
798 return self._compressed
799
799
800 formatmap = {'20': unbundle20}
800 formatmap = {'20': unbundle20}
801
801
802 b2streamparamsmap = {}
802 b2streamparamsmap = {}
803
803
804 def b2streamparamhandler(name):
804 def b2streamparamhandler(name):
805 """register a handler for a stream level parameter"""
805 """register a handler for a stream level parameter"""
806 def decorator(func):
806 def decorator(func):
807 assert name not in formatmap
807 assert name not in formatmap
808 b2streamparamsmap[name] = func
808 b2streamparamsmap[name] = func
809 return func
809 return func
810 return decorator
810 return decorator
811
811
812 @b2streamparamhandler('compression')
812 @b2streamparamhandler('compression')
813 def processcompression(unbundler, param, value):
813 def processcompression(unbundler, param, value):
814 """read compression parameter and install payload decompression"""
814 """read compression parameter and install payload decompression"""
815 if value not in util.decompressors:
815 if value not in util.decompressors:
816 raise error.BundleUnknownFeatureError(params=(param,),
816 raise error.BundleUnknownFeatureError(params=(param,),
817 values=(value,))
817 values=(value,))
818 unbundler._decompressor = util.decompressors[value]
818 unbundler._decompressor = util.decompressors[value]
819 if value is not None:
819 if value is not None:
820 unbundler._compressed = True
820 unbundler._compressed = True
821
821
822 class bundlepart(object):
822 class bundlepart(object):
823 """A bundle2 part contains application level payload
823 """A bundle2 part contains application level payload
824
824
825 The part `type` is used to route the part to the application level
825 The part `type` is used to route the part to the application level
826 handler.
826 handler.
827
827
828 The part payload is contained in ``part.data``. It could be raw bytes or a
828 The part payload is contained in ``part.data``. It could be raw bytes or a
829 generator of byte chunks.
829 generator of byte chunks.
830
830
831 You can add parameters to the part using the ``addparam`` method.
831 You can add parameters to the part using the ``addparam`` method.
832 Parameters can be either mandatory (default) or advisory. Remote side
832 Parameters can be either mandatory (default) or advisory. Remote side
833 should be able to safely ignore the advisory ones.
833 should be able to safely ignore the advisory ones.
834
834
835 Both data and parameters cannot be modified after the generation has begun.
835 Both data and parameters cannot be modified after the generation has begun.
836 """
836 """
837
837
838 def __init__(self, parttype, mandatoryparams=(), advisoryparams=(),
838 def __init__(self, parttype, mandatoryparams=(), advisoryparams=(),
839 data='', mandatory=True):
839 data='', mandatory=True):
840 validateparttype(parttype)
840 validateparttype(parttype)
841 self.id = None
841 self.id = None
842 self.type = parttype
842 self.type = parttype
843 self._data = data
843 self._data = data
844 self._mandatoryparams = list(mandatoryparams)
844 self._mandatoryparams = list(mandatoryparams)
845 self._advisoryparams = list(advisoryparams)
845 self._advisoryparams = list(advisoryparams)
846 # checking for duplicated entries
846 # checking for duplicated entries
847 self._seenparams = set()
847 self._seenparams = set()
848 for pname, __ in self._mandatoryparams + self._advisoryparams:
848 for pname, __ in self._mandatoryparams + self._advisoryparams:
849 if pname in self._seenparams:
849 if pname in self._seenparams:
850 raise RuntimeError('duplicated params: %s' % pname)
850 raise RuntimeError('duplicated params: %s' % pname)
851 self._seenparams.add(pname)
851 self._seenparams.add(pname)
852 # status of the part's generation:
852 # status of the part's generation:
853 # - None: not started,
853 # - None: not started,
854 # - False: currently generated,
854 # - False: currently generated,
855 # - True: generation done.
855 # - True: generation done.
856 self._generated = None
856 self._generated = None
857 self.mandatory = mandatory
857 self.mandatory = mandatory
858
858
859 def copy(self):
859 def copy(self):
860 """return a copy of the part
860 """return a copy of the part
861
861
862 The new part have the very same content but no partid assigned yet.
862 The new part have the very same content but no partid assigned yet.
863 Parts with generated data cannot be copied."""
863 Parts with generated data cannot be copied."""
864 assert not util.safehasattr(self.data, 'next')
864 assert not util.safehasattr(self.data, 'next')
865 return self.__class__(self.type, self._mandatoryparams,
865 return self.__class__(self.type, self._mandatoryparams,
866 self._advisoryparams, self._data, self.mandatory)
866 self._advisoryparams, self._data, self.mandatory)
867
867
868 # methods used to defines the part content
868 # methods used to defines the part content
869 @property
869 @property
870 def data(self):
870 def data(self):
871 return self._data
871 return self._data
872
872
873 @data.setter
873 @data.setter
874 def data(self, data):
874 def data(self, data):
875 if self._generated is not None:
875 if self._generated is not None:
876 raise error.ReadOnlyPartError('part is being generated')
876 raise error.ReadOnlyPartError('part is being generated')
877 self._data = data
877 self._data = data
878
878
879 @property
879 @property
880 def mandatoryparams(self):
880 def mandatoryparams(self):
881 # make it an immutable tuple to force people through ``addparam``
881 # make it an immutable tuple to force people through ``addparam``
882 return tuple(self._mandatoryparams)
882 return tuple(self._mandatoryparams)
883
883
884 @property
884 @property
885 def advisoryparams(self):
885 def advisoryparams(self):
886 # make it an immutable tuple to force people through ``addparam``
886 # make it an immutable tuple to force people through ``addparam``
887 return tuple(self._advisoryparams)
887 return tuple(self._advisoryparams)
888
888
889 def addparam(self, name, value='', mandatory=True):
889 def addparam(self, name, value='', mandatory=True):
890 if self._generated is not None:
890 if self._generated is not None:
891 raise error.ReadOnlyPartError('part is being generated')
891 raise error.ReadOnlyPartError('part is being generated')
892 if name in self._seenparams:
892 if name in self._seenparams:
893 raise ValueError('duplicated params: %s' % name)
893 raise ValueError('duplicated params: %s' % name)
894 self._seenparams.add(name)
894 self._seenparams.add(name)
895 params = self._advisoryparams
895 params = self._advisoryparams
896 if mandatory:
896 if mandatory:
897 params = self._mandatoryparams
897 params = self._mandatoryparams
898 params.append((name, value))
898 params.append((name, value))
899
899
900 # methods used to generates the bundle2 stream
900 # methods used to generates the bundle2 stream
901 def getchunks(self, ui):
901 def getchunks(self, ui):
902 if self._generated is not None:
902 if self._generated is not None:
903 raise RuntimeError('part can only be consumed once')
903 raise RuntimeError('part can only be consumed once')
904 self._generated = False
904 self._generated = False
905
905
906 if ui.debugflag:
906 if ui.debugflag:
907 msg = ['bundle2-output-part: "%s"' % self.type]
907 msg = ['bundle2-output-part: "%s"' % self.type]
908 if not self.mandatory:
908 if not self.mandatory:
909 msg.append(' (advisory)')
909 msg.append(' (advisory)')
910 nbmp = len(self.mandatoryparams)
910 nbmp = len(self.mandatoryparams)
911 nbap = len(self.advisoryparams)
911 nbap = len(self.advisoryparams)
912 if nbmp or nbap:
912 if nbmp or nbap:
913 msg.append(' (params:')
913 msg.append(' (params:')
914 if nbmp:
914 if nbmp:
915 msg.append(' %i mandatory' % nbmp)
915 msg.append(' %i mandatory' % nbmp)
916 if nbap:
916 if nbap:
917 msg.append(' %i advisory' % nbmp)
917 msg.append(' %i advisory' % nbmp)
918 msg.append(')')
918 msg.append(')')
919 if not self.data:
919 if not self.data:
920 msg.append(' empty payload')
920 msg.append(' empty payload')
921 elif util.safehasattr(self.data, 'next'):
921 elif util.safehasattr(self.data, 'next'):
922 msg.append(' streamed payload')
922 msg.append(' streamed payload')
923 else:
923 else:
924 msg.append(' %i bytes payload' % len(self.data))
924 msg.append(' %i bytes payload' % len(self.data))
925 msg.append('\n')
925 msg.append('\n')
926 ui.debug(''.join(msg))
926 ui.debug(''.join(msg))
927
927
928 #### header
928 #### header
929 if self.mandatory:
929 if self.mandatory:
930 parttype = self.type.upper()
930 parttype = self.type.upper()
931 else:
931 else:
932 parttype = self.type.lower()
932 parttype = self.type.lower()
933 outdebug(ui, 'part %s: "%s"' % (self.id, parttype))
933 outdebug(ui, 'part %s: "%s"' % (self.id, parttype))
934 ## parttype
934 ## parttype
935 header = [_pack(_fparttypesize, len(parttype)),
935 header = [_pack(_fparttypesize, len(parttype)),
936 parttype, _pack(_fpartid, self.id),
936 parttype, _pack(_fpartid, self.id),
937 ]
937 ]
938 ## parameters
938 ## parameters
939 # count
939 # count
940 manpar = self.mandatoryparams
940 manpar = self.mandatoryparams
941 advpar = self.advisoryparams
941 advpar = self.advisoryparams
942 header.append(_pack(_fpartparamcount, len(manpar), len(advpar)))
942 header.append(_pack(_fpartparamcount, len(manpar), len(advpar)))
943 # size
943 # size
944 parsizes = []
944 parsizes = []
945 for key, value in manpar:
945 for key, value in manpar:
946 parsizes.append(len(key))
946 parsizes.append(len(key))
947 parsizes.append(len(value))
947 parsizes.append(len(value))
948 for key, value in advpar:
948 for key, value in advpar:
949 parsizes.append(len(key))
949 parsizes.append(len(key))
950 parsizes.append(len(value))
950 parsizes.append(len(value))
951 paramsizes = _pack(_makefpartparamsizes(len(parsizes) / 2), *parsizes)
951 paramsizes = _pack(_makefpartparamsizes(len(parsizes) / 2), *parsizes)
952 header.append(paramsizes)
952 header.append(paramsizes)
953 # key, value
953 # key, value
954 for key, value in manpar:
954 for key, value in manpar:
955 header.append(key)
955 header.append(key)
956 header.append(value)
956 header.append(value)
957 for key, value in advpar:
957 for key, value in advpar:
958 header.append(key)
958 header.append(key)
959 header.append(value)
959 header.append(value)
960 ## finalize header
960 ## finalize header
961 headerchunk = ''.join(header)
961 headerchunk = ''.join(header)
962 outdebug(ui, 'header chunk size: %i' % len(headerchunk))
962 outdebug(ui, 'header chunk size: %i' % len(headerchunk))
963 yield _pack(_fpartheadersize, len(headerchunk))
963 yield _pack(_fpartheadersize, len(headerchunk))
964 yield headerchunk
964 yield headerchunk
965 ## payload
965 ## payload
966 try:
966 try:
967 for chunk in self._payloadchunks():
967 for chunk in self._payloadchunks():
968 outdebug(ui, 'payload chunk size: %i' % len(chunk))
968 outdebug(ui, 'payload chunk size: %i' % len(chunk))
969 yield _pack(_fpayloadsize, len(chunk))
969 yield _pack(_fpayloadsize, len(chunk))
970 yield chunk
970 yield chunk
971 except GeneratorExit:
971 except GeneratorExit:
972 # GeneratorExit means that nobody is listening for our
972 # GeneratorExit means that nobody is listening for our
973 # results anyway, so just bail quickly rather than trying
973 # results anyway, so just bail quickly rather than trying
974 # to produce an error part.
974 # to produce an error part.
975 ui.debug('bundle2-generatorexit\n')
975 ui.debug('bundle2-generatorexit\n')
976 raise
976 raise
977 except BaseException as exc:
977 except BaseException as exc:
978 # backup exception data for later
978 # backup exception data for later
979 ui.debug('bundle2-input-stream-interrupt: encoding exception %s'
979 ui.debug('bundle2-input-stream-interrupt: encoding exception %s'
980 % exc)
980 % exc)
981 exc_info = sys.exc_info()
981 exc_info = sys.exc_info()
982 msg = 'unexpected error: %s' % exc
982 msg = 'unexpected error: %s' % exc
983 interpart = bundlepart('error:abort', [('message', msg)],
983 interpart = bundlepart('error:abort', [('message', msg)],
984 mandatory=False)
984 mandatory=False)
985 interpart.id = 0
985 interpart.id = 0
986 yield _pack(_fpayloadsize, -1)
986 yield _pack(_fpayloadsize, -1)
987 for chunk in interpart.getchunks(ui=ui):
987 for chunk in interpart.getchunks(ui=ui):
988 yield chunk
988 yield chunk
989 outdebug(ui, 'closing payload chunk')
989 outdebug(ui, 'closing payload chunk')
990 # abort current part payload
990 # abort current part payload
991 yield _pack(_fpayloadsize, 0)
991 yield _pack(_fpayloadsize, 0)
992 raise exc_info[0], exc_info[1], exc_info[2]
992 raise exc_info[0], exc_info[1], exc_info[2]
993 # end of payload
993 # end of payload
994 outdebug(ui, 'closing payload chunk')
994 outdebug(ui, 'closing payload chunk')
995 yield _pack(_fpayloadsize, 0)
995 yield _pack(_fpayloadsize, 0)
996 self._generated = True
996 self._generated = True
997
997
998 def _payloadchunks(self):
998 def _payloadchunks(self):
999 """yield chunks of a the part payload
999 """yield chunks of a the part payload
1000
1000
1001 Exists to handle the different methods to provide data to a part."""
1001 Exists to handle the different methods to provide data to a part."""
1002 # we only support fixed size data now.
1002 # we only support fixed size data now.
1003 # This will be improved in the future.
1003 # This will be improved in the future.
1004 if util.safehasattr(self.data, 'next'):
1004 if util.safehasattr(self.data, 'next'):
1005 buff = util.chunkbuffer(self.data)
1005 buff = util.chunkbuffer(self.data)
1006 chunk = buff.read(preferedchunksize)
1006 chunk = buff.read(preferedchunksize)
1007 while chunk:
1007 while chunk:
1008 yield chunk
1008 yield chunk
1009 chunk = buff.read(preferedchunksize)
1009 chunk = buff.read(preferedchunksize)
1010 elif len(self.data):
1010 elif len(self.data):
1011 yield self.data
1011 yield self.data
1012
1012
1013
1013
1014 flaginterrupt = -1
1014 flaginterrupt = -1
1015
1015
1016 class interrupthandler(unpackermixin):
1016 class interrupthandler(unpackermixin):
1017 """read one part and process it with restricted capability
1017 """read one part and process it with restricted capability
1018
1018
1019 This allows to transmit exception raised on the producer size during part
1019 This allows to transmit exception raised on the producer size during part
1020 iteration while the consumer is reading a part.
1020 iteration while the consumer is reading a part.
1021
1021
1022 Part processed in this manner only have access to a ui object,"""
1022 Part processed in this manner only have access to a ui object,"""
1023
1023
1024 def __init__(self, ui, fp):
1024 def __init__(self, ui, fp):
1025 super(interrupthandler, self).__init__(fp)
1025 super(interrupthandler, self).__init__(fp)
1026 self.ui = ui
1026 self.ui = ui
1027
1027
1028 def _readpartheader(self):
1028 def _readpartheader(self):
1029 """reads a part header size and return the bytes blob
1029 """reads a part header size and return the bytes blob
1030
1030
1031 returns None if empty"""
1031 returns None if empty"""
1032 headersize = self._unpack(_fpartheadersize)[0]
1032 headersize = self._unpack(_fpartheadersize)[0]
1033 if headersize < 0:
1033 if headersize < 0:
1034 raise error.BundleValueError('negative part header size: %i'
1034 raise error.BundleValueError('negative part header size: %i'
1035 % headersize)
1035 % headersize)
1036 indebug(self.ui, 'part header size: %i\n' % headersize)
1036 indebug(self.ui, 'part header size: %i\n' % headersize)
1037 if headersize:
1037 if headersize:
1038 return self._readexact(headersize)
1038 return self._readexact(headersize)
1039 return None
1039 return None
1040
1040
1041 def __call__(self):
1041 def __call__(self):
1042
1042
1043 self.ui.debug('bundle2-input-stream-interrupt:'
1043 self.ui.debug('bundle2-input-stream-interrupt:'
1044 ' opening out of band context\n')
1044 ' opening out of band context\n')
1045 indebug(self.ui, 'bundle2 stream interruption, looking for a part.')
1045 indebug(self.ui, 'bundle2 stream interruption, looking for a part.')
1046 headerblock = self._readpartheader()
1046 headerblock = self._readpartheader()
1047 if headerblock is None:
1047 if headerblock is None:
1048 indebug(self.ui, 'no part found during interruption.')
1048 indebug(self.ui, 'no part found during interruption.')
1049 return
1049 return
1050 part = unbundlepart(self.ui, headerblock, self._fp)
1050 part = unbundlepart(self.ui, headerblock, self._fp)
1051 op = interruptoperation(self.ui)
1051 op = interruptoperation(self.ui)
1052 _processpart(op, part)
1052 _processpart(op, part)
1053 self.ui.debug('bundle2-input-stream-interrupt:'
1053 self.ui.debug('bundle2-input-stream-interrupt:'
1054 ' closing out of band context\n')
1054 ' closing out of band context\n')
1055
1055
1056 class interruptoperation(object):
1056 class interruptoperation(object):
1057 """A limited operation to be use by part handler during interruption
1057 """A limited operation to be use by part handler during interruption
1058
1058
1059 It only have access to an ui object.
1059 It only have access to an ui object.
1060 """
1060 """
1061
1061
1062 def __init__(self, ui):
1062 def __init__(self, ui):
1063 self.ui = ui
1063 self.ui = ui
1064 self.reply = None
1064 self.reply = None
1065 self.captureoutput = False
1065 self.captureoutput = False
1066
1066
1067 @property
1067 @property
1068 def repo(self):
1068 def repo(self):
1069 raise RuntimeError('no repo access from stream interruption')
1069 raise RuntimeError('no repo access from stream interruption')
1070
1070
1071 def gettransaction(self):
1071 def gettransaction(self):
1072 raise TransactionUnavailable('no repo access from stream interruption')
1072 raise TransactionUnavailable('no repo access from stream interruption')
1073
1073
1074 class unbundlepart(unpackermixin):
1074 class unbundlepart(unpackermixin):
1075 """a bundle part read from a bundle"""
1075 """a bundle part read from a bundle"""
1076
1076
1077 def __init__(self, ui, header, fp):
1077 def __init__(self, ui, header, fp):
1078 super(unbundlepart, self).__init__(fp)
1078 super(unbundlepart, self).__init__(fp)
1079 self.ui = ui
1079 self.ui = ui
1080 # unbundle state attr
1080 # unbundle state attr
1081 self._headerdata = header
1081 self._headerdata = header
1082 self._headeroffset = 0
1082 self._headeroffset = 0
1083 self._initialized = False
1083 self._initialized = False
1084 self.consumed = False
1084 self.consumed = False
1085 # part data
1085 # part data
1086 self.id = None
1086 self.id = None
1087 self.type = None
1087 self.type = None
1088 self.mandatoryparams = None
1088 self.mandatoryparams = None
1089 self.advisoryparams = None
1089 self.advisoryparams = None
1090 self.params = None
1090 self.params = None
1091 self.mandatorykeys = ()
1091 self.mandatorykeys = ()
1092 self._payloadstream = None
1092 self._payloadstream = None
1093 self._readheader()
1093 self._readheader()
1094 self._mandatory = None
1094 self._mandatory = None
1095 self._chunkindex = [] #(payload, file) position tuples for chunk starts
1095 self._chunkindex = [] #(payload, file) position tuples for chunk starts
1096 self._pos = 0
1096 self._pos = 0
1097
1097
1098 def _fromheader(self, size):
1098 def _fromheader(self, size):
1099 """return the next <size> byte from the header"""
1099 """return the next <size> byte from the header"""
1100 offset = self._headeroffset
1100 offset = self._headeroffset
1101 data = self._headerdata[offset:(offset + size)]
1101 data = self._headerdata[offset:(offset + size)]
1102 self._headeroffset = offset + size
1102 self._headeroffset = offset + size
1103 return data
1103 return data
1104
1104
1105 def _unpackheader(self, format):
1105 def _unpackheader(self, format):
1106 """read given format from header
1106 """read given format from header
1107
1107
1108 This automatically compute the size of the format to read."""
1108 This automatically compute the size of the format to read."""
1109 data = self._fromheader(struct.calcsize(format))
1109 data = self._fromheader(struct.calcsize(format))
1110 return _unpack(format, data)
1110 return _unpack(format, data)
1111
1111
1112 def _initparams(self, mandatoryparams, advisoryparams):
1112 def _initparams(self, mandatoryparams, advisoryparams):
1113 """internal function to setup all logic related parameters"""
1113 """internal function to setup all logic related parameters"""
1114 # make it read only to prevent people touching it by mistake.
1114 # make it read only to prevent people touching it by mistake.
1115 self.mandatoryparams = tuple(mandatoryparams)
1115 self.mandatoryparams = tuple(mandatoryparams)
1116 self.advisoryparams = tuple(advisoryparams)
1116 self.advisoryparams = tuple(advisoryparams)
1117 # user friendly UI
1117 # user friendly UI
1118 self.params = util.sortdict(self.mandatoryparams)
1118 self.params = util.sortdict(self.mandatoryparams)
1119 self.params.update(self.advisoryparams)
1119 self.params.update(self.advisoryparams)
1120 self.mandatorykeys = frozenset(p[0] for p in mandatoryparams)
1120 self.mandatorykeys = frozenset(p[0] for p in mandatoryparams)
1121
1121
1122 def _payloadchunks(self, chunknum=0):
1122 def _payloadchunks(self, chunknum=0):
1123 '''seek to specified chunk and start yielding data'''
1123 '''seek to specified chunk and start yielding data'''
1124 if len(self._chunkindex) == 0:
1124 if len(self._chunkindex) == 0:
1125 assert chunknum == 0, 'Must start with chunk 0'
1125 assert chunknum == 0, 'Must start with chunk 0'
1126 self._chunkindex.append((0, super(unbundlepart, self).tell()))
1126 self._chunkindex.append((0, super(unbundlepart, self).tell()))
1127 else:
1127 else:
1128 assert chunknum < len(self._chunkindex), \
1128 assert chunknum < len(self._chunkindex), \
1129 'Unknown chunk %d' % chunknum
1129 'Unknown chunk %d' % chunknum
1130 super(unbundlepart, self).seek(self._chunkindex[chunknum][1])
1130 super(unbundlepart, self).seek(self._chunkindex[chunknum][1])
1131
1131
1132 pos = self._chunkindex[chunknum][0]
1132 pos = self._chunkindex[chunknum][0]
1133 payloadsize = self._unpack(_fpayloadsize)[0]
1133 payloadsize = self._unpack(_fpayloadsize)[0]
1134 indebug(self.ui, 'payload chunk size: %i' % payloadsize)
1134 indebug(self.ui, 'payload chunk size: %i' % payloadsize)
1135 while payloadsize:
1135 while payloadsize:
1136 if payloadsize == flaginterrupt:
1136 if payloadsize == flaginterrupt:
1137 # interruption detection, the handler will now read a
1137 # interruption detection, the handler will now read a
1138 # single part and process it.
1138 # single part and process it.
1139 interrupthandler(self.ui, self._fp)()
1139 interrupthandler(self.ui, self._fp)()
1140 elif payloadsize < 0:
1140 elif payloadsize < 0:
1141 msg = 'negative payload chunk size: %i' % payloadsize
1141 msg = 'negative payload chunk size: %i' % payloadsize
1142 raise error.BundleValueError(msg)
1142 raise error.BundleValueError(msg)
1143 else:
1143 else:
1144 result = self._readexact(payloadsize)
1144 result = self._readexact(payloadsize)
1145 chunknum += 1
1145 chunknum += 1
1146 pos += payloadsize
1146 pos += payloadsize
1147 if chunknum == len(self._chunkindex):
1147 if chunknum == len(self._chunkindex):
1148 self._chunkindex.append((pos,
1148 self._chunkindex.append((pos,
1149 super(unbundlepart, self).tell()))
1149 super(unbundlepart, self).tell()))
1150 yield result
1150 yield result
1151 payloadsize = self._unpack(_fpayloadsize)[0]
1151 payloadsize = self._unpack(_fpayloadsize)[0]
1152 indebug(self.ui, 'payload chunk size: %i' % payloadsize)
1152 indebug(self.ui, 'payload chunk size: %i' % payloadsize)
1153
1153
1154 def _findchunk(self, pos):
1154 def _findchunk(self, pos):
1155 '''for a given payload position, return a chunk number and offset'''
1155 '''for a given payload position, return a chunk number and offset'''
1156 for chunk, (ppos, fpos) in enumerate(self._chunkindex):
1156 for chunk, (ppos, fpos) in enumerate(self._chunkindex):
1157 if ppos == pos:
1157 if ppos == pos:
1158 return chunk, 0
1158 return chunk, 0
1159 elif ppos > pos:
1159 elif ppos > pos:
1160 return chunk - 1, pos - self._chunkindex[chunk - 1][0]
1160 return chunk - 1, pos - self._chunkindex[chunk - 1][0]
1161 raise ValueError('Unknown chunk')
1161 raise ValueError('Unknown chunk')
1162
1162
1163 def _readheader(self):
1163 def _readheader(self):
1164 """read the header and setup the object"""
1164 """read the header and setup the object"""
1165 typesize = self._unpackheader(_fparttypesize)[0]
1165 typesize = self._unpackheader(_fparttypesize)[0]
1166 self.type = self._fromheader(typesize)
1166 self.type = self._fromheader(typesize)
1167 indebug(self.ui, 'part type: "%s"' % self.type)
1167 indebug(self.ui, 'part type: "%s"' % self.type)
1168 self.id = self._unpackheader(_fpartid)[0]
1168 self.id = self._unpackheader(_fpartid)[0]
1169 indebug(self.ui, 'part id: "%s"' % self.id)
1169 indebug(self.ui, 'part id: "%s"' % self.id)
1170 # extract mandatory bit from type
1170 # extract mandatory bit from type
1171 self.mandatory = (self.type != self.type.lower())
1171 self.mandatory = (self.type != self.type.lower())
1172 self.type = self.type.lower()
1172 self.type = self.type.lower()
1173 ## reading parameters
1173 ## reading parameters
1174 # param count
1174 # param count
1175 mancount, advcount = self._unpackheader(_fpartparamcount)
1175 mancount, advcount = self._unpackheader(_fpartparamcount)
1176 indebug(self.ui, 'part parameters: %i' % (mancount + advcount))
1176 indebug(self.ui, 'part parameters: %i' % (mancount + advcount))
1177 # param size
1177 # param size
1178 fparamsizes = _makefpartparamsizes(mancount + advcount)
1178 fparamsizes = _makefpartparamsizes(mancount + advcount)
1179 paramsizes = self._unpackheader(fparamsizes)
1179 paramsizes = self._unpackheader(fparamsizes)
1180 # make it a list of couple again
1180 # make it a list of couple again
1181 paramsizes = zip(paramsizes[::2], paramsizes[1::2])
1181 paramsizes = zip(paramsizes[::2], paramsizes[1::2])
1182 # split mandatory from advisory
1182 # split mandatory from advisory
1183 mansizes = paramsizes[:mancount]
1183 mansizes = paramsizes[:mancount]
1184 advsizes = paramsizes[mancount:]
1184 advsizes = paramsizes[mancount:]
1185 # retrieve param value
1185 # retrieve param value
1186 manparams = []
1186 manparams = []
1187 for key, value in mansizes:
1187 for key, value in mansizes:
1188 manparams.append((self._fromheader(key), self._fromheader(value)))
1188 manparams.append((self._fromheader(key), self._fromheader(value)))
1189 advparams = []
1189 advparams = []
1190 for key, value in advsizes:
1190 for key, value in advsizes:
1191 advparams.append((self._fromheader(key), self._fromheader(value)))
1191 advparams.append((self._fromheader(key), self._fromheader(value)))
1192 self._initparams(manparams, advparams)
1192 self._initparams(manparams, advparams)
1193 ## part payload
1193 ## part payload
1194 self._payloadstream = util.chunkbuffer(self._payloadchunks())
1194 self._payloadstream = util.chunkbuffer(self._payloadchunks())
1195 # we read the data, tell it
1195 # we read the data, tell it
1196 self._initialized = True
1196 self._initialized = True
1197
1197
1198 def read(self, size=None):
1198 def read(self, size=None):
1199 """read payload data"""
1199 """read payload data"""
1200 if not self._initialized:
1200 if not self._initialized:
1201 self._readheader()
1201 self._readheader()
1202 if size is None:
1202 if size is None:
1203 data = self._payloadstream.read()
1203 data = self._payloadstream.read()
1204 else:
1204 else:
1205 data = self._payloadstream.read(size)
1205 data = self._payloadstream.read(size)
1206 self._pos += len(data)
1206 self._pos += len(data)
1207 if size is None or len(data) < size:
1207 if size is None or len(data) < size:
1208 if not self.consumed and self._pos:
1208 if not self.consumed and self._pos:
1209 self.ui.debug('bundle2-input-part: total payload size %i\n'
1209 self.ui.debug('bundle2-input-part: total payload size %i\n'
1210 % self._pos)
1210 % self._pos)
1211 self.consumed = True
1211 self.consumed = True
1212 return data
1212 return data
1213
1213
1214 def tell(self):
1214 def tell(self):
1215 return self._pos
1215 return self._pos
1216
1216
1217 def seek(self, offset, whence=0):
1217 def seek(self, offset, whence=0):
1218 if whence == 0:
1218 if whence == 0:
1219 newpos = offset
1219 newpos = offset
1220 elif whence == 1:
1220 elif whence == 1:
1221 newpos = self._pos + offset
1221 newpos = self._pos + offset
1222 elif whence == 2:
1222 elif whence == 2:
1223 if not self.consumed:
1223 if not self.consumed:
1224 self.read()
1224 self.read()
1225 newpos = self._chunkindex[-1][0] - offset
1225 newpos = self._chunkindex[-1][0] - offset
1226 else:
1226 else:
1227 raise ValueError('Unknown whence value: %r' % (whence,))
1227 raise ValueError('Unknown whence value: %r' % (whence,))
1228
1228
1229 if newpos > self._chunkindex[-1][0] and not self.consumed:
1229 if newpos > self._chunkindex[-1][0] and not self.consumed:
1230 self.read()
1230 self.read()
1231 if not 0 <= newpos <= self._chunkindex[-1][0]:
1231 if not 0 <= newpos <= self._chunkindex[-1][0]:
1232 raise ValueError('Offset out of range')
1232 raise ValueError('Offset out of range')
1233
1233
1234 if self._pos != newpos:
1234 if self._pos != newpos:
1235 chunk, internaloffset = self._findchunk(newpos)
1235 chunk, internaloffset = self._findchunk(newpos)
1236 self._payloadstream = util.chunkbuffer(self._payloadchunks(chunk))
1236 self._payloadstream = util.chunkbuffer(self._payloadchunks(chunk))
1237 adjust = self.read(internaloffset)
1237 adjust = self.read(internaloffset)
1238 if len(adjust) != internaloffset:
1238 if len(adjust) != internaloffset:
1239 raise error.Abort(_('Seek failed\n'))
1239 raise error.Abort(_('Seek failed\n'))
1240 self._pos = newpos
1240 self._pos = newpos
1241
1241
1242 # These are only the static capabilities.
1242 # These are only the static capabilities.
1243 # Check the 'getrepocaps' function for the rest.
1243 # Check the 'getrepocaps' function for the rest.
1244 capabilities = {'HG20': (),
1244 capabilities = {'HG20': (),
1245 'error': ('abort', 'unsupportedcontent', 'pushraced',
1245 'error': ('abort', 'unsupportedcontent', 'pushraced',
1246 'pushkey'),
1246 'pushkey'),
1247 'listkeys': (),
1247 'listkeys': (),
1248 'pushkey': (),
1248 'pushkey': (),
1249 'digests': tuple(sorted(util.DIGESTS.keys())),
1249 'digests': tuple(sorted(util.DIGESTS.keys())),
1250 'remote-changegroup': ('http', 'https'),
1250 'remote-changegroup': ('http', 'https'),
1251 'hgtagsfnodes': (),
1251 'hgtagsfnodes': (),
1252 }
1252 }
1253
1253
1254 def getrepocaps(repo, allowpushback=False):
1254 def getrepocaps(repo, allowpushback=False):
1255 """return the bundle2 capabilities for a given repo
1255 """return the bundle2 capabilities for a given repo
1256
1256
1257 Exists to allow extensions (like evolution) to mutate the capabilities.
1257 Exists to allow extensions (like evolution) to mutate the capabilities.
1258 """
1258 """
1259 caps = capabilities.copy()
1259 caps = capabilities.copy()
1260 caps['changegroup'] = tuple(sorted(
1260 caps['changegroup'] = tuple(sorted(
1261 changegroup.supportedincomingversions(repo)))
1261 changegroup.supportedincomingversions(repo)))
1262 if obsolete.isenabled(repo, obsolete.exchangeopt):
1262 if obsolete.isenabled(repo, obsolete.exchangeopt):
1263 supportedformat = tuple('V%i' % v for v in obsolete.formats)
1263 supportedformat = tuple('V%i' % v for v in obsolete.formats)
1264 caps['obsmarkers'] = supportedformat
1264 caps['obsmarkers'] = supportedformat
1265 if allowpushback:
1265 if allowpushback:
1266 caps['pushback'] = ()
1266 caps['pushback'] = ()
1267 return caps
1267 return caps
1268
1268
1269 def bundle2caps(remote):
1269 def bundle2caps(remote):
1270 """return the bundle capabilities of a peer as dict"""
1270 """return the bundle capabilities of a peer as dict"""
1271 raw = remote.capable('bundle2')
1271 raw = remote.capable('bundle2')
1272 if not raw and raw != '':
1272 if not raw and raw != '':
1273 return {}
1273 return {}
1274 capsblob = urlreq.unquote(remote.capable('bundle2'))
1274 capsblob = urlreq.unquote(remote.capable('bundle2'))
1275 return decodecaps(capsblob)
1275 return decodecaps(capsblob)
1276
1276
1277 def obsmarkersversion(caps):
1277 def obsmarkersversion(caps):
1278 """extract the list of supported obsmarkers versions from a bundle2caps dict
1278 """extract the list of supported obsmarkers versions from a bundle2caps dict
1279 """
1279 """
1280 obscaps = caps.get('obsmarkers', ())
1280 obscaps = caps.get('obsmarkers', ())
1281 return [int(c[1:]) for c in obscaps if c.startswith('V')]
1281 return [int(c[1:]) for c in obscaps if c.startswith('V')]
1282
1282
1283 def writebundle(ui, cg, filename, bundletype, vfs=None, compression=None):
1283 def writebundle(ui, cg, filename, bundletype, vfs=None, compression=None):
1284 """Write a bundle file and return its filename.
1284 """Write a bundle file and return its filename.
1285
1285
1286 Existing files will not be overwritten.
1286 Existing files will not be overwritten.
1287 If no filename is specified, a temporary file is created.
1287 If no filename is specified, a temporary file is created.
1288 bz2 compression can be turned off.
1288 bz2 compression can be turned off.
1289 The bundle file will be deleted in case of errors.
1289 The bundle file will be deleted in case of errors.
1290 """
1290 """
1291
1291
1292 if bundletype == "HG20":
1292 if bundletype == "HG20":
1293 bundle = bundle20(ui)
1293 bundle = bundle20(ui)
1294 bundle.setcompression(compression)
1294 bundle.setcompression(compression)
1295 part = bundle.newpart('changegroup', data=cg.getchunks())
1295 part = bundle.newpart('changegroup', data=cg.getchunks())
1296 part.addparam('version', cg.version)
1296 part.addparam('version', cg.version)
1297 if 'clcount' in cg.extras:
1298 part.addparam('nbchanges', str(cg.extras['clcount']),
1299 mandatory=False)
1297 chunkiter = bundle.getchunks()
1300 chunkiter = bundle.getchunks()
1298 else:
1301 else:
1299 # compression argument is only for the bundle2 case
1302 # compression argument is only for the bundle2 case
1300 assert compression is None
1303 assert compression is None
1301 if cg.version != '01':
1304 if cg.version != '01':
1302 raise error.Abort(_('old bundle types only supports v1 '
1305 raise error.Abort(_('old bundle types only supports v1 '
1303 'changegroups'))
1306 'changegroups'))
1304 header, comp = bundletypes[bundletype]
1307 header, comp = bundletypes[bundletype]
1305 if comp not in util.compressors:
1308 if comp not in util.compressors:
1306 raise error.Abort(_('unknown stream compression type: %s')
1309 raise error.Abort(_('unknown stream compression type: %s')
1307 % comp)
1310 % comp)
1308 z = util.compressors[comp]()
1311 z = util.compressors[comp]()
1309 subchunkiter = cg.getchunks()
1312 subchunkiter = cg.getchunks()
1310 def chunkiter():
1313 def chunkiter():
1311 yield header
1314 yield header
1312 for chunk in subchunkiter:
1315 for chunk in subchunkiter:
1313 yield z.compress(chunk)
1316 yield z.compress(chunk)
1314 yield z.flush()
1317 yield z.flush()
1315 chunkiter = chunkiter()
1318 chunkiter = chunkiter()
1316
1319
1317 # parse the changegroup data, otherwise we will block
1320 # parse the changegroup data, otherwise we will block
1318 # in case of sshrepo because we don't know the end of the stream
1321 # in case of sshrepo because we don't know the end of the stream
1319 return changegroup.writechunks(ui, chunkiter, filename, vfs=vfs)
1322 return changegroup.writechunks(ui, chunkiter, filename, vfs=vfs)
1320
1323
1321 @parthandler('changegroup', ('version', 'nbchanges', 'treemanifest'))
1324 @parthandler('changegroup', ('version', 'nbchanges', 'treemanifest'))
1322 def handlechangegroup(op, inpart):
1325 def handlechangegroup(op, inpart):
1323 """apply a changegroup part on the repo
1326 """apply a changegroup part on the repo
1324
1327
1325 This is a very early implementation that will massive rework before being
1328 This is a very early implementation that will massive rework before being
1326 inflicted to any end-user.
1329 inflicted to any end-user.
1327 """
1330 """
1328 # Make sure we trigger a transaction creation
1331 # Make sure we trigger a transaction creation
1329 #
1332 #
1330 # The addchangegroup function will get a transaction object by itself, but
1333 # The addchangegroup function will get a transaction object by itself, but
1331 # we need to make sure we trigger the creation of a transaction object used
1334 # we need to make sure we trigger the creation of a transaction object used
1332 # for the whole processing scope.
1335 # for the whole processing scope.
1333 op.gettransaction()
1336 op.gettransaction()
1334 unpackerversion = inpart.params.get('version', '01')
1337 unpackerversion = inpart.params.get('version', '01')
1335 # We should raise an appropriate exception here
1338 # We should raise an appropriate exception here
1336 cg = changegroup.getunbundler(unpackerversion, inpart, None)
1339 cg = changegroup.getunbundler(unpackerversion, inpart, None)
1337 # the source and url passed here are overwritten by the one contained in
1340 # the source and url passed here are overwritten by the one contained in
1338 # the transaction.hookargs argument. So 'bundle2' is a placeholder
1341 # the transaction.hookargs argument. So 'bundle2' is a placeholder
1339 nbchangesets = None
1342 nbchangesets = None
1340 if 'nbchanges' in inpart.params:
1343 if 'nbchanges' in inpart.params:
1341 nbchangesets = int(inpart.params.get('nbchanges'))
1344 nbchangesets = int(inpart.params.get('nbchanges'))
1342 if ('treemanifest' in inpart.params and
1345 if ('treemanifest' in inpart.params and
1343 'treemanifest' not in op.repo.requirements):
1346 'treemanifest' not in op.repo.requirements):
1344 if len(op.repo.changelog) != 0:
1347 if len(op.repo.changelog) != 0:
1345 raise error.Abort(_(
1348 raise error.Abort(_(
1346 "bundle contains tree manifests, but local repo is "
1349 "bundle contains tree manifests, but local repo is "
1347 "non-empty and does not use tree manifests"))
1350 "non-empty and does not use tree manifests"))
1348 op.repo.requirements.add('treemanifest')
1351 op.repo.requirements.add('treemanifest')
1349 op.repo._applyopenerreqs()
1352 op.repo._applyopenerreqs()
1350 op.repo._writerequirements()
1353 op.repo._writerequirements()
1351 ret = cg.apply(op.repo, 'bundle2', 'bundle2', expectedtotal=nbchangesets)
1354 ret = cg.apply(op.repo, 'bundle2', 'bundle2', expectedtotal=nbchangesets)
1352 op.records.add('changegroup', {'return': ret})
1355 op.records.add('changegroup', {'return': ret})
1353 if op.reply is not None:
1356 if op.reply is not None:
1354 # This is definitely not the final form of this
1357 # This is definitely not the final form of this
1355 # return. But one need to start somewhere.
1358 # return. But one need to start somewhere.
1356 part = op.reply.newpart('reply:changegroup', mandatory=False)
1359 part = op.reply.newpart('reply:changegroup', mandatory=False)
1357 part.addparam('in-reply-to', str(inpart.id), mandatory=False)
1360 part.addparam('in-reply-to', str(inpart.id), mandatory=False)
1358 part.addparam('return', '%i' % ret, mandatory=False)
1361 part.addparam('return', '%i' % ret, mandatory=False)
1359 assert not inpart.read()
1362 assert not inpart.read()
1360
1363
1361 _remotechangegroupparams = tuple(['url', 'size', 'digests'] +
1364 _remotechangegroupparams = tuple(['url', 'size', 'digests'] +
1362 ['digest:%s' % k for k in util.DIGESTS.keys()])
1365 ['digest:%s' % k for k in util.DIGESTS.keys()])
1363 @parthandler('remote-changegroup', _remotechangegroupparams)
1366 @parthandler('remote-changegroup', _remotechangegroupparams)
1364 def handleremotechangegroup(op, inpart):
1367 def handleremotechangegroup(op, inpart):
1365 """apply a bundle10 on the repo, given an url and validation information
1368 """apply a bundle10 on the repo, given an url and validation information
1366
1369
1367 All the information about the remote bundle to import are given as
1370 All the information about the remote bundle to import are given as
1368 parameters. The parameters include:
1371 parameters. The parameters include:
1369 - url: the url to the bundle10.
1372 - url: the url to the bundle10.
1370 - size: the bundle10 file size. It is used to validate what was
1373 - size: the bundle10 file size. It is used to validate what was
1371 retrieved by the client matches the server knowledge about the bundle.
1374 retrieved by the client matches the server knowledge about the bundle.
1372 - digests: a space separated list of the digest types provided as
1375 - digests: a space separated list of the digest types provided as
1373 parameters.
1376 parameters.
1374 - digest:<digest-type>: the hexadecimal representation of the digest with
1377 - digest:<digest-type>: the hexadecimal representation of the digest with
1375 that name. Like the size, it is used to validate what was retrieved by
1378 that name. Like the size, it is used to validate what was retrieved by
1376 the client matches what the server knows about the bundle.
1379 the client matches what the server knows about the bundle.
1377
1380
1378 When multiple digest types are given, all of them are checked.
1381 When multiple digest types are given, all of them are checked.
1379 """
1382 """
1380 try:
1383 try:
1381 raw_url = inpart.params['url']
1384 raw_url = inpart.params['url']
1382 except KeyError:
1385 except KeyError:
1383 raise error.Abort(_('remote-changegroup: missing "%s" param') % 'url')
1386 raise error.Abort(_('remote-changegroup: missing "%s" param') % 'url')
1384 parsed_url = util.url(raw_url)
1387 parsed_url = util.url(raw_url)
1385 if parsed_url.scheme not in capabilities['remote-changegroup']:
1388 if parsed_url.scheme not in capabilities['remote-changegroup']:
1386 raise error.Abort(_('remote-changegroup does not support %s urls') %
1389 raise error.Abort(_('remote-changegroup does not support %s urls') %
1387 parsed_url.scheme)
1390 parsed_url.scheme)
1388
1391
1389 try:
1392 try:
1390 size = int(inpart.params['size'])
1393 size = int(inpart.params['size'])
1391 except ValueError:
1394 except ValueError:
1392 raise error.Abort(_('remote-changegroup: invalid value for param "%s"')
1395 raise error.Abort(_('remote-changegroup: invalid value for param "%s"')
1393 % 'size')
1396 % 'size')
1394 except KeyError:
1397 except KeyError:
1395 raise error.Abort(_('remote-changegroup: missing "%s" param') % 'size')
1398 raise error.Abort(_('remote-changegroup: missing "%s" param') % 'size')
1396
1399
1397 digests = {}
1400 digests = {}
1398 for typ in inpart.params.get('digests', '').split():
1401 for typ in inpart.params.get('digests', '').split():
1399 param = 'digest:%s' % typ
1402 param = 'digest:%s' % typ
1400 try:
1403 try:
1401 value = inpart.params[param]
1404 value = inpart.params[param]
1402 except KeyError:
1405 except KeyError:
1403 raise error.Abort(_('remote-changegroup: missing "%s" param') %
1406 raise error.Abort(_('remote-changegroup: missing "%s" param') %
1404 param)
1407 param)
1405 digests[typ] = value
1408 digests[typ] = value
1406
1409
1407 real_part = util.digestchecker(url.open(op.ui, raw_url), size, digests)
1410 real_part = util.digestchecker(url.open(op.ui, raw_url), size, digests)
1408
1411
1409 # Make sure we trigger a transaction creation
1412 # Make sure we trigger a transaction creation
1410 #
1413 #
1411 # The addchangegroup function will get a transaction object by itself, but
1414 # The addchangegroup function will get a transaction object by itself, but
1412 # we need to make sure we trigger the creation of a transaction object used
1415 # we need to make sure we trigger the creation of a transaction object used
1413 # for the whole processing scope.
1416 # for the whole processing scope.
1414 op.gettransaction()
1417 op.gettransaction()
1415 from . import exchange
1418 from . import exchange
1416 cg = exchange.readbundle(op.repo.ui, real_part, raw_url)
1419 cg = exchange.readbundle(op.repo.ui, real_part, raw_url)
1417 if not isinstance(cg, changegroup.cg1unpacker):
1420 if not isinstance(cg, changegroup.cg1unpacker):
1418 raise error.Abort(_('%s: not a bundle version 1.0') %
1421 raise error.Abort(_('%s: not a bundle version 1.0') %
1419 util.hidepassword(raw_url))
1422 util.hidepassword(raw_url))
1420 ret = cg.apply(op.repo, 'bundle2', 'bundle2')
1423 ret = cg.apply(op.repo, 'bundle2', 'bundle2')
1421 op.records.add('changegroup', {'return': ret})
1424 op.records.add('changegroup', {'return': ret})
1422 if op.reply is not None:
1425 if op.reply is not None:
1423 # This is definitely not the final form of this
1426 # This is definitely not the final form of this
1424 # return. But one need to start somewhere.
1427 # return. But one need to start somewhere.
1425 part = op.reply.newpart('reply:changegroup')
1428 part = op.reply.newpart('reply:changegroup')
1426 part.addparam('in-reply-to', str(inpart.id), mandatory=False)
1429 part.addparam('in-reply-to', str(inpart.id), mandatory=False)
1427 part.addparam('return', '%i' % ret, mandatory=False)
1430 part.addparam('return', '%i' % ret, mandatory=False)
1428 try:
1431 try:
1429 real_part.validate()
1432 real_part.validate()
1430 except error.Abort as e:
1433 except error.Abort as e:
1431 raise error.Abort(_('bundle at %s is corrupted:\n%s') %
1434 raise error.Abort(_('bundle at %s is corrupted:\n%s') %
1432 (util.hidepassword(raw_url), str(e)))
1435 (util.hidepassword(raw_url), str(e)))
1433 assert not inpart.read()
1436 assert not inpart.read()
1434
1437
1435 @parthandler('reply:changegroup', ('return', 'in-reply-to'))
1438 @parthandler('reply:changegroup', ('return', 'in-reply-to'))
1436 def handlereplychangegroup(op, inpart):
1439 def handlereplychangegroup(op, inpart):
1437 ret = int(inpart.params['return'])
1440 ret = int(inpart.params['return'])
1438 replyto = int(inpart.params['in-reply-to'])
1441 replyto = int(inpart.params['in-reply-to'])
1439 op.records.add('changegroup', {'return': ret}, replyto)
1442 op.records.add('changegroup', {'return': ret}, replyto)
1440
1443
1441 @parthandler('check:heads')
1444 @parthandler('check:heads')
1442 def handlecheckheads(op, inpart):
1445 def handlecheckheads(op, inpart):
1443 """check that head of the repo did not change
1446 """check that head of the repo did not change
1444
1447
1445 This is used to detect a push race when using unbundle.
1448 This is used to detect a push race when using unbundle.
1446 This replaces the "heads" argument of unbundle."""
1449 This replaces the "heads" argument of unbundle."""
1447 h = inpart.read(20)
1450 h = inpart.read(20)
1448 heads = []
1451 heads = []
1449 while len(h) == 20:
1452 while len(h) == 20:
1450 heads.append(h)
1453 heads.append(h)
1451 h = inpart.read(20)
1454 h = inpart.read(20)
1452 assert not h
1455 assert not h
1453 # Trigger a transaction so that we are guaranteed to have the lock now.
1456 # Trigger a transaction so that we are guaranteed to have the lock now.
1454 if op.ui.configbool('experimental', 'bundle2lazylocking'):
1457 if op.ui.configbool('experimental', 'bundle2lazylocking'):
1455 op.gettransaction()
1458 op.gettransaction()
1456 if sorted(heads) != sorted(op.repo.heads()):
1459 if sorted(heads) != sorted(op.repo.heads()):
1457 raise error.PushRaced('repository changed while pushing - '
1460 raise error.PushRaced('repository changed while pushing - '
1458 'please try again')
1461 'please try again')
1459
1462
1460 @parthandler('output')
1463 @parthandler('output')
1461 def handleoutput(op, inpart):
1464 def handleoutput(op, inpart):
1462 """forward output captured on the server to the client"""
1465 """forward output captured on the server to the client"""
1463 for line in inpart.read().splitlines():
1466 for line in inpart.read().splitlines():
1464 op.ui.status(('remote: %s\n' % line))
1467 op.ui.status(('remote: %s\n' % line))
1465
1468
1466 @parthandler('replycaps')
1469 @parthandler('replycaps')
1467 def handlereplycaps(op, inpart):
1470 def handlereplycaps(op, inpart):
1468 """Notify that a reply bundle should be created
1471 """Notify that a reply bundle should be created
1469
1472
1470 The payload contains the capabilities information for the reply"""
1473 The payload contains the capabilities information for the reply"""
1471 caps = decodecaps(inpart.read())
1474 caps = decodecaps(inpart.read())
1472 if op.reply is None:
1475 if op.reply is None:
1473 op.reply = bundle20(op.ui, caps)
1476 op.reply = bundle20(op.ui, caps)
1474
1477
1475 class AbortFromPart(error.Abort):
1478 class AbortFromPart(error.Abort):
1476 """Sub-class of Abort that denotes an error from a bundle2 part."""
1479 """Sub-class of Abort that denotes an error from a bundle2 part."""
1477
1480
1478 @parthandler('error:abort', ('message', 'hint'))
1481 @parthandler('error:abort', ('message', 'hint'))
1479 def handleerrorabort(op, inpart):
1482 def handleerrorabort(op, inpart):
1480 """Used to transmit abort error over the wire"""
1483 """Used to transmit abort error over the wire"""
1481 raise AbortFromPart(inpart.params['message'],
1484 raise AbortFromPart(inpart.params['message'],
1482 hint=inpart.params.get('hint'))
1485 hint=inpart.params.get('hint'))
1483
1486
1484 @parthandler('error:pushkey', ('namespace', 'key', 'new', 'old', 'ret',
1487 @parthandler('error:pushkey', ('namespace', 'key', 'new', 'old', 'ret',
1485 'in-reply-to'))
1488 'in-reply-to'))
1486 def handleerrorpushkey(op, inpart):
1489 def handleerrorpushkey(op, inpart):
1487 """Used to transmit failure of a mandatory pushkey over the wire"""
1490 """Used to transmit failure of a mandatory pushkey over the wire"""
1488 kwargs = {}
1491 kwargs = {}
1489 for name in ('namespace', 'key', 'new', 'old', 'ret'):
1492 for name in ('namespace', 'key', 'new', 'old', 'ret'):
1490 value = inpart.params.get(name)
1493 value = inpart.params.get(name)
1491 if value is not None:
1494 if value is not None:
1492 kwargs[name] = value
1495 kwargs[name] = value
1493 raise error.PushkeyFailed(inpart.params['in-reply-to'], **kwargs)
1496 raise error.PushkeyFailed(inpart.params['in-reply-to'], **kwargs)
1494
1497
1495 @parthandler('error:unsupportedcontent', ('parttype', 'params'))
1498 @parthandler('error:unsupportedcontent', ('parttype', 'params'))
1496 def handleerrorunsupportedcontent(op, inpart):
1499 def handleerrorunsupportedcontent(op, inpart):
1497 """Used to transmit unknown content error over the wire"""
1500 """Used to transmit unknown content error over the wire"""
1498 kwargs = {}
1501 kwargs = {}
1499 parttype = inpart.params.get('parttype')
1502 parttype = inpart.params.get('parttype')
1500 if parttype is not None:
1503 if parttype is not None:
1501 kwargs['parttype'] = parttype
1504 kwargs['parttype'] = parttype
1502 params = inpart.params.get('params')
1505 params = inpart.params.get('params')
1503 if params is not None:
1506 if params is not None:
1504 kwargs['params'] = params.split('\0')
1507 kwargs['params'] = params.split('\0')
1505
1508
1506 raise error.BundleUnknownFeatureError(**kwargs)
1509 raise error.BundleUnknownFeatureError(**kwargs)
1507
1510
1508 @parthandler('error:pushraced', ('message',))
1511 @parthandler('error:pushraced', ('message',))
1509 def handleerrorpushraced(op, inpart):
1512 def handleerrorpushraced(op, inpart):
1510 """Used to transmit push race error over the wire"""
1513 """Used to transmit push race error over the wire"""
1511 raise error.ResponseError(_('push failed:'), inpart.params['message'])
1514 raise error.ResponseError(_('push failed:'), inpart.params['message'])
1512
1515
1513 @parthandler('listkeys', ('namespace',))
1516 @parthandler('listkeys', ('namespace',))
1514 def handlelistkeys(op, inpart):
1517 def handlelistkeys(op, inpart):
1515 """retrieve pushkey namespace content stored in a bundle2"""
1518 """retrieve pushkey namespace content stored in a bundle2"""
1516 namespace = inpart.params['namespace']
1519 namespace = inpart.params['namespace']
1517 r = pushkey.decodekeys(inpart.read())
1520 r = pushkey.decodekeys(inpart.read())
1518 op.records.add('listkeys', (namespace, r))
1521 op.records.add('listkeys', (namespace, r))
1519
1522
1520 @parthandler('pushkey', ('namespace', 'key', 'old', 'new'))
1523 @parthandler('pushkey', ('namespace', 'key', 'old', 'new'))
1521 def handlepushkey(op, inpart):
1524 def handlepushkey(op, inpart):
1522 """process a pushkey request"""
1525 """process a pushkey request"""
1523 dec = pushkey.decode
1526 dec = pushkey.decode
1524 namespace = dec(inpart.params['namespace'])
1527 namespace = dec(inpart.params['namespace'])
1525 key = dec(inpart.params['key'])
1528 key = dec(inpart.params['key'])
1526 old = dec(inpart.params['old'])
1529 old = dec(inpart.params['old'])
1527 new = dec(inpart.params['new'])
1530 new = dec(inpart.params['new'])
1528 # Grab the transaction to ensure that we have the lock before performing the
1531 # Grab the transaction to ensure that we have the lock before performing the
1529 # pushkey.
1532 # pushkey.
1530 if op.ui.configbool('experimental', 'bundle2lazylocking'):
1533 if op.ui.configbool('experimental', 'bundle2lazylocking'):
1531 op.gettransaction()
1534 op.gettransaction()
1532 ret = op.repo.pushkey(namespace, key, old, new)
1535 ret = op.repo.pushkey(namespace, key, old, new)
1533 record = {'namespace': namespace,
1536 record = {'namespace': namespace,
1534 'key': key,
1537 'key': key,
1535 'old': old,
1538 'old': old,
1536 'new': new}
1539 'new': new}
1537 op.records.add('pushkey', record)
1540 op.records.add('pushkey', record)
1538 if op.reply is not None:
1541 if op.reply is not None:
1539 rpart = op.reply.newpart('reply:pushkey')
1542 rpart = op.reply.newpart('reply:pushkey')
1540 rpart.addparam('in-reply-to', str(inpart.id), mandatory=False)
1543 rpart.addparam('in-reply-to', str(inpart.id), mandatory=False)
1541 rpart.addparam('return', '%i' % ret, mandatory=False)
1544 rpart.addparam('return', '%i' % ret, mandatory=False)
1542 if inpart.mandatory and not ret:
1545 if inpart.mandatory and not ret:
1543 kwargs = {}
1546 kwargs = {}
1544 for key in ('namespace', 'key', 'new', 'old', 'ret'):
1547 for key in ('namespace', 'key', 'new', 'old', 'ret'):
1545 if key in inpart.params:
1548 if key in inpart.params:
1546 kwargs[key] = inpart.params[key]
1549 kwargs[key] = inpart.params[key]
1547 raise error.PushkeyFailed(partid=str(inpart.id), **kwargs)
1550 raise error.PushkeyFailed(partid=str(inpart.id), **kwargs)
1548
1551
1549 @parthandler('reply:pushkey', ('return', 'in-reply-to'))
1552 @parthandler('reply:pushkey', ('return', 'in-reply-to'))
1550 def handlepushkeyreply(op, inpart):
1553 def handlepushkeyreply(op, inpart):
1551 """retrieve the result of a pushkey request"""
1554 """retrieve the result of a pushkey request"""
1552 ret = int(inpart.params['return'])
1555 ret = int(inpart.params['return'])
1553 partid = int(inpart.params['in-reply-to'])
1556 partid = int(inpart.params['in-reply-to'])
1554 op.records.add('pushkey', {'return': ret}, partid)
1557 op.records.add('pushkey', {'return': ret}, partid)
1555
1558
1556 @parthandler('obsmarkers')
1559 @parthandler('obsmarkers')
1557 def handleobsmarker(op, inpart):
1560 def handleobsmarker(op, inpart):
1558 """add a stream of obsmarkers to the repo"""
1561 """add a stream of obsmarkers to the repo"""
1559 tr = op.gettransaction()
1562 tr = op.gettransaction()
1560 markerdata = inpart.read()
1563 markerdata = inpart.read()
1561 if op.ui.config('experimental', 'obsmarkers-exchange-debug', False):
1564 if op.ui.config('experimental', 'obsmarkers-exchange-debug', False):
1562 op.ui.write(('obsmarker-exchange: %i bytes received\n')
1565 op.ui.write(('obsmarker-exchange: %i bytes received\n')
1563 % len(markerdata))
1566 % len(markerdata))
1564 # The mergemarkers call will crash if marker creation is not enabled.
1567 # The mergemarkers call will crash if marker creation is not enabled.
1565 # we want to avoid this if the part is advisory.
1568 # we want to avoid this if the part is advisory.
1566 if not inpart.mandatory and op.repo.obsstore.readonly:
1569 if not inpart.mandatory and op.repo.obsstore.readonly:
1567 op.repo.ui.debug('ignoring obsolescence markers, feature not enabled')
1570 op.repo.ui.debug('ignoring obsolescence markers, feature not enabled')
1568 return
1571 return
1569 new = op.repo.obsstore.mergemarkers(tr, markerdata)
1572 new = op.repo.obsstore.mergemarkers(tr, markerdata)
1570 if new:
1573 if new:
1571 op.repo.ui.status(_('%i new obsolescence markers\n') % new)
1574 op.repo.ui.status(_('%i new obsolescence markers\n') % new)
1572 op.records.add('obsmarkers', {'new': new})
1575 op.records.add('obsmarkers', {'new': new})
1573 if op.reply is not None:
1576 if op.reply is not None:
1574 rpart = op.reply.newpart('reply:obsmarkers')
1577 rpart = op.reply.newpart('reply:obsmarkers')
1575 rpart.addparam('in-reply-to', str(inpart.id), mandatory=False)
1578 rpart.addparam('in-reply-to', str(inpart.id), mandatory=False)
1576 rpart.addparam('new', '%i' % new, mandatory=False)
1579 rpart.addparam('new', '%i' % new, mandatory=False)
1577
1580
1578
1581
1579 @parthandler('reply:obsmarkers', ('new', 'in-reply-to'))
1582 @parthandler('reply:obsmarkers', ('new', 'in-reply-to'))
1580 def handleobsmarkerreply(op, inpart):
1583 def handleobsmarkerreply(op, inpart):
1581 """retrieve the result of a pushkey request"""
1584 """retrieve the result of a pushkey request"""
1582 ret = int(inpart.params['new'])
1585 ret = int(inpart.params['new'])
1583 partid = int(inpart.params['in-reply-to'])
1586 partid = int(inpart.params['in-reply-to'])
1584 op.records.add('obsmarkers', {'new': ret}, partid)
1587 op.records.add('obsmarkers', {'new': ret}, partid)
1585
1588
1586 @parthandler('hgtagsfnodes')
1589 @parthandler('hgtagsfnodes')
1587 def handlehgtagsfnodes(op, inpart):
1590 def handlehgtagsfnodes(op, inpart):
1588 """Applies .hgtags fnodes cache entries to the local repo.
1591 """Applies .hgtags fnodes cache entries to the local repo.
1589
1592
1590 Payload is pairs of 20 byte changeset nodes and filenodes.
1593 Payload is pairs of 20 byte changeset nodes and filenodes.
1591 """
1594 """
1592 # Grab the transaction so we ensure that we have the lock at this point.
1595 # Grab the transaction so we ensure that we have the lock at this point.
1593 if op.ui.configbool('experimental', 'bundle2lazylocking'):
1596 if op.ui.configbool('experimental', 'bundle2lazylocking'):
1594 op.gettransaction()
1597 op.gettransaction()
1595 cache = tags.hgtagsfnodescache(op.repo.unfiltered())
1598 cache = tags.hgtagsfnodescache(op.repo.unfiltered())
1596
1599
1597 count = 0
1600 count = 0
1598 while True:
1601 while True:
1599 node = inpart.read(20)
1602 node = inpart.read(20)
1600 fnode = inpart.read(20)
1603 fnode = inpart.read(20)
1601 if len(node) < 20 or len(fnode) < 20:
1604 if len(node) < 20 or len(fnode) < 20:
1602 op.ui.debug('ignoring incomplete received .hgtags fnodes data\n')
1605 op.ui.debug('ignoring incomplete received .hgtags fnodes data\n')
1603 break
1606 break
1604 cache.setfnode(node, fnode)
1607 cache.setfnode(node, fnode)
1605 count += 1
1608 count += 1
1606
1609
1607 cache.write()
1610 cache.write()
1608 op.ui.debug('applied %i hgtags fnodes cache entries\n' % count)
1611 op.ui.debug('applied %i hgtags fnodes cache entries\n' % count)
@@ -1,1063 +1,1065 b''
1 # changegroup.py - Mercurial changegroup manipulation functions
1 # changegroup.py - Mercurial changegroup manipulation functions
2 #
2 #
3 # Copyright 2006 Matt Mackall <mpm@selenic.com>
3 # Copyright 2006 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 import os
10 import os
11 import struct
11 import struct
12 import tempfile
12 import tempfile
13 import weakref
13 import weakref
14
14
15 from .i18n import _
15 from .i18n import _
16 from .node import (
16 from .node import (
17 hex,
17 hex,
18 nullid,
18 nullid,
19 nullrev,
19 nullrev,
20 short,
20 short,
21 )
21 )
22
22
23 from . import (
23 from . import (
24 branchmap,
24 branchmap,
25 dagutil,
25 dagutil,
26 discovery,
26 discovery,
27 error,
27 error,
28 mdiff,
28 mdiff,
29 phases,
29 phases,
30 util,
30 util,
31 )
31 )
32
32
33 _CHANGEGROUPV1_DELTA_HEADER = "20s20s20s20s"
33 _CHANGEGROUPV1_DELTA_HEADER = "20s20s20s20s"
34 _CHANGEGROUPV2_DELTA_HEADER = "20s20s20s20s20s"
34 _CHANGEGROUPV2_DELTA_HEADER = "20s20s20s20s20s"
35 _CHANGEGROUPV3_DELTA_HEADER = ">20s20s20s20s20sH"
35 _CHANGEGROUPV3_DELTA_HEADER = ">20s20s20s20s20sH"
36
36
37 def readexactly(stream, n):
37 def readexactly(stream, n):
38 '''read n bytes from stream.read and abort if less was available'''
38 '''read n bytes from stream.read and abort if less was available'''
39 s = stream.read(n)
39 s = stream.read(n)
40 if len(s) < n:
40 if len(s) < n:
41 raise error.Abort(_("stream ended unexpectedly"
41 raise error.Abort(_("stream ended unexpectedly"
42 " (got %d bytes, expected %d)")
42 " (got %d bytes, expected %d)")
43 % (len(s), n))
43 % (len(s), n))
44 return s
44 return s
45
45
46 def getchunk(stream):
46 def getchunk(stream):
47 """return the next chunk from stream as a string"""
47 """return the next chunk from stream as a string"""
48 d = readexactly(stream, 4)
48 d = readexactly(stream, 4)
49 l = struct.unpack(">l", d)[0]
49 l = struct.unpack(">l", d)[0]
50 if l <= 4:
50 if l <= 4:
51 if l:
51 if l:
52 raise error.Abort(_("invalid chunk length %d") % l)
52 raise error.Abort(_("invalid chunk length %d") % l)
53 return ""
53 return ""
54 return readexactly(stream, l - 4)
54 return readexactly(stream, l - 4)
55
55
56 def chunkheader(length):
56 def chunkheader(length):
57 """return a changegroup chunk header (string)"""
57 """return a changegroup chunk header (string)"""
58 return struct.pack(">l", length + 4)
58 return struct.pack(">l", length + 4)
59
59
60 def closechunk():
60 def closechunk():
61 """return a changegroup chunk header (string) for a zero-length chunk"""
61 """return a changegroup chunk header (string) for a zero-length chunk"""
62 return struct.pack(">l", 0)
62 return struct.pack(">l", 0)
63
63
64 def combineresults(results):
64 def combineresults(results):
65 """logic to combine 0 or more addchangegroup results into one"""
65 """logic to combine 0 or more addchangegroup results into one"""
66 changedheads = 0
66 changedheads = 0
67 result = 1
67 result = 1
68 for ret in results:
68 for ret in results:
69 # If any changegroup result is 0, return 0
69 # If any changegroup result is 0, return 0
70 if ret == 0:
70 if ret == 0:
71 result = 0
71 result = 0
72 break
72 break
73 if ret < -1:
73 if ret < -1:
74 changedheads += ret + 1
74 changedheads += ret + 1
75 elif ret > 1:
75 elif ret > 1:
76 changedheads += ret - 1
76 changedheads += ret - 1
77 if changedheads > 0:
77 if changedheads > 0:
78 result = 1 + changedheads
78 result = 1 + changedheads
79 elif changedheads < 0:
79 elif changedheads < 0:
80 result = -1 + changedheads
80 result = -1 + changedheads
81 return result
81 return result
82
82
83 def writechunks(ui, chunks, filename, vfs=None):
83 def writechunks(ui, chunks, filename, vfs=None):
84 """Write chunks to a file and return its filename.
84 """Write chunks to a file and return its filename.
85
85
86 The stream is assumed to be a bundle file.
86 The stream is assumed to be a bundle file.
87 Existing files will not be overwritten.
87 Existing files will not be overwritten.
88 If no filename is specified, a temporary file is created.
88 If no filename is specified, a temporary file is created.
89 """
89 """
90 fh = None
90 fh = None
91 cleanup = None
91 cleanup = None
92 try:
92 try:
93 if filename:
93 if filename:
94 if vfs:
94 if vfs:
95 fh = vfs.open(filename, "wb")
95 fh = vfs.open(filename, "wb")
96 else:
96 else:
97 fh = open(filename, "wb")
97 fh = open(filename, "wb")
98 else:
98 else:
99 fd, filename = tempfile.mkstemp(prefix="hg-bundle-", suffix=".hg")
99 fd, filename = tempfile.mkstemp(prefix="hg-bundle-", suffix=".hg")
100 fh = os.fdopen(fd, "wb")
100 fh = os.fdopen(fd, "wb")
101 cleanup = filename
101 cleanup = filename
102 for c in chunks:
102 for c in chunks:
103 fh.write(c)
103 fh.write(c)
104 cleanup = None
104 cleanup = None
105 return filename
105 return filename
106 finally:
106 finally:
107 if fh is not None:
107 if fh is not None:
108 fh.close()
108 fh.close()
109 if cleanup is not None:
109 if cleanup is not None:
110 if filename and vfs:
110 if filename and vfs:
111 vfs.unlink(cleanup)
111 vfs.unlink(cleanup)
112 else:
112 else:
113 os.unlink(cleanup)
113 os.unlink(cleanup)
114
114
115 class cg1unpacker(object):
115 class cg1unpacker(object):
116 """Unpacker for cg1 changegroup streams.
116 """Unpacker for cg1 changegroup streams.
117
117
118 A changegroup unpacker handles the framing of the revision data in
118 A changegroup unpacker handles the framing of the revision data in
119 the wire format. Most consumers will want to use the apply()
119 the wire format. Most consumers will want to use the apply()
120 method to add the changes from the changegroup to a repository.
120 method to add the changes from the changegroup to a repository.
121
121
122 If you're forwarding a changegroup unmodified to another consumer,
122 If you're forwarding a changegroup unmodified to another consumer,
123 use getchunks(), which returns an iterator of changegroup
123 use getchunks(), which returns an iterator of changegroup
124 chunks. This is mostly useful for cases where you need to know the
124 chunks. This is mostly useful for cases where you need to know the
125 data stream has ended by observing the end of the changegroup.
125 data stream has ended by observing the end of the changegroup.
126
126
127 deltachunk() is useful only if you're applying delta data. Most
127 deltachunk() is useful only if you're applying delta data. Most
128 consumers should prefer apply() instead.
128 consumers should prefer apply() instead.
129
129
130 A few other public methods exist. Those are used only for
130 A few other public methods exist. Those are used only for
131 bundlerepo and some debug commands - their use is discouraged.
131 bundlerepo and some debug commands - their use is discouraged.
132 """
132 """
133 deltaheader = _CHANGEGROUPV1_DELTA_HEADER
133 deltaheader = _CHANGEGROUPV1_DELTA_HEADER
134 deltaheadersize = struct.calcsize(deltaheader)
134 deltaheadersize = struct.calcsize(deltaheader)
135 version = '01'
135 version = '01'
136 _grouplistcount = 1 # One list of files after the manifests
136 _grouplistcount = 1 # One list of files after the manifests
137
137
138 def __init__(self, fh, alg):
138 def __init__(self, fh, alg, extras=None):
139 if alg == 'UN':
139 if alg == 'UN':
140 alg = None # get more modern without breaking too much
140 alg = None # get more modern without breaking too much
141 if not alg in util.decompressors:
141 if not alg in util.decompressors:
142 raise error.Abort(_('unknown stream compression type: %s')
142 raise error.Abort(_('unknown stream compression type: %s')
143 % alg)
143 % alg)
144 if alg == 'BZ':
144 if alg == 'BZ':
145 alg = '_truncatedBZ'
145 alg = '_truncatedBZ'
146 self._stream = util.decompressors[alg](fh)
146 self._stream = util.decompressors[alg](fh)
147 self._type = alg
147 self._type = alg
148 self.extras = extras or {}
148 self.callback = None
149 self.callback = None
149
150
150 # These methods (compressed, read, seek, tell) all appear to only
151 # These methods (compressed, read, seek, tell) all appear to only
151 # be used by bundlerepo, but it's a little hard to tell.
152 # be used by bundlerepo, but it's a little hard to tell.
152 def compressed(self):
153 def compressed(self):
153 return self._type is not None
154 return self._type is not None
154 def read(self, l):
155 def read(self, l):
155 return self._stream.read(l)
156 return self._stream.read(l)
156 def seek(self, pos):
157 def seek(self, pos):
157 return self._stream.seek(pos)
158 return self._stream.seek(pos)
158 def tell(self):
159 def tell(self):
159 return self._stream.tell()
160 return self._stream.tell()
160 def close(self):
161 def close(self):
161 return self._stream.close()
162 return self._stream.close()
162
163
163 def _chunklength(self):
164 def _chunklength(self):
164 d = readexactly(self._stream, 4)
165 d = readexactly(self._stream, 4)
165 l = struct.unpack(">l", d)[0]
166 l = struct.unpack(">l", d)[0]
166 if l <= 4:
167 if l <= 4:
167 if l:
168 if l:
168 raise error.Abort(_("invalid chunk length %d") % l)
169 raise error.Abort(_("invalid chunk length %d") % l)
169 return 0
170 return 0
170 if self.callback:
171 if self.callback:
171 self.callback()
172 self.callback()
172 return l - 4
173 return l - 4
173
174
174 def changelogheader(self):
175 def changelogheader(self):
175 """v10 does not have a changelog header chunk"""
176 """v10 does not have a changelog header chunk"""
176 return {}
177 return {}
177
178
178 def manifestheader(self):
179 def manifestheader(self):
179 """v10 does not have a manifest header chunk"""
180 """v10 does not have a manifest header chunk"""
180 return {}
181 return {}
181
182
182 def filelogheader(self):
183 def filelogheader(self):
183 """return the header of the filelogs chunk, v10 only has the filename"""
184 """return the header of the filelogs chunk, v10 only has the filename"""
184 l = self._chunklength()
185 l = self._chunklength()
185 if not l:
186 if not l:
186 return {}
187 return {}
187 fname = readexactly(self._stream, l)
188 fname = readexactly(self._stream, l)
188 return {'filename': fname}
189 return {'filename': fname}
189
190
190 def _deltaheader(self, headertuple, prevnode):
191 def _deltaheader(self, headertuple, prevnode):
191 node, p1, p2, cs = headertuple
192 node, p1, p2, cs = headertuple
192 if prevnode is None:
193 if prevnode is None:
193 deltabase = p1
194 deltabase = p1
194 else:
195 else:
195 deltabase = prevnode
196 deltabase = prevnode
196 flags = 0
197 flags = 0
197 return node, p1, p2, deltabase, cs, flags
198 return node, p1, p2, deltabase, cs, flags
198
199
199 def deltachunk(self, prevnode):
200 def deltachunk(self, prevnode):
200 l = self._chunklength()
201 l = self._chunklength()
201 if not l:
202 if not l:
202 return {}
203 return {}
203 headerdata = readexactly(self._stream, self.deltaheadersize)
204 headerdata = readexactly(self._stream, self.deltaheadersize)
204 header = struct.unpack(self.deltaheader, headerdata)
205 header = struct.unpack(self.deltaheader, headerdata)
205 delta = readexactly(self._stream, l - self.deltaheadersize)
206 delta = readexactly(self._stream, l - self.deltaheadersize)
206 node, p1, p2, deltabase, cs, flags = self._deltaheader(header, prevnode)
207 node, p1, p2, deltabase, cs, flags = self._deltaheader(header, prevnode)
207 return {'node': node, 'p1': p1, 'p2': p2, 'cs': cs,
208 return {'node': node, 'p1': p1, 'p2': p2, 'cs': cs,
208 'deltabase': deltabase, 'delta': delta, 'flags': flags}
209 'deltabase': deltabase, 'delta': delta, 'flags': flags}
209
210
210 def getchunks(self):
211 def getchunks(self):
211 """returns all the chunks contains in the bundle
212 """returns all the chunks contains in the bundle
212
213
213 Used when you need to forward the binary stream to a file or another
214 Used when you need to forward the binary stream to a file or another
214 network API. To do so, it parse the changegroup data, otherwise it will
215 network API. To do so, it parse the changegroup data, otherwise it will
215 block in case of sshrepo because it don't know the end of the stream.
216 block in case of sshrepo because it don't know the end of the stream.
216 """
217 """
217 # an empty chunkgroup is the end of the changegroup
218 # an empty chunkgroup is the end of the changegroup
218 # a changegroup has at least 2 chunkgroups (changelog and manifest).
219 # a changegroup has at least 2 chunkgroups (changelog and manifest).
219 # after that, changegroup versions 1 and 2 have a series of groups
220 # after that, changegroup versions 1 and 2 have a series of groups
220 # with one group per file. changegroup 3 has a series of directory
221 # with one group per file. changegroup 3 has a series of directory
221 # manifests before the files.
222 # manifests before the files.
222 count = 0
223 count = 0
223 emptycount = 0
224 emptycount = 0
224 while emptycount < self._grouplistcount:
225 while emptycount < self._grouplistcount:
225 empty = True
226 empty = True
226 count += 1
227 count += 1
227 while True:
228 while True:
228 chunk = getchunk(self)
229 chunk = getchunk(self)
229 if not chunk:
230 if not chunk:
230 if empty and count > 2:
231 if empty and count > 2:
231 emptycount += 1
232 emptycount += 1
232 break
233 break
233 empty = False
234 empty = False
234 yield chunkheader(len(chunk))
235 yield chunkheader(len(chunk))
235 pos = 0
236 pos = 0
236 while pos < len(chunk):
237 while pos < len(chunk):
237 next = pos + 2**20
238 next = pos + 2**20
238 yield chunk[pos:next]
239 yield chunk[pos:next]
239 pos = next
240 pos = next
240 yield closechunk()
241 yield closechunk()
241
242
242 def _unpackmanifests(self, repo, revmap, trp, prog, numchanges):
243 def _unpackmanifests(self, repo, revmap, trp, prog, numchanges):
243 # We know that we'll never have more manifests than we had
244 # We know that we'll never have more manifests than we had
244 # changesets.
245 # changesets.
245 self.callback = prog(_('manifests'), numchanges)
246 self.callback = prog(_('manifests'), numchanges)
246 # no need to check for empty manifest group here:
247 # no need to check for empty manifest group here:
247 # if the result of the merge of 1 and 2 is the same in 3 and 4,
248 # if the result of the merge of 1 and 2 is the same in 3 and 4,
248 # no new manifest will be created and the manifest group will
249 # no new manifest will be created and the manifest group will
249 # be empty during the pull
250 # be empty during the pull
250 self.manifestheader()
251 self.manifestheader()
251 repo.manifest.addgroup(self, revmap, trp)
252 repo.manifest.addgroup(self, revmap, trp)
252 repo.ui.progress(_('manifests'), None)
253 repo.ui.progress(_('manifests'), None)
253 self.callback = None
254 self.callback = None
254
255
255 def apply(self, repo, srctype, url, emptyok=False,
256 def apply(self, repo, srctype, url, emptyok=False,
256 targetphase=phases.draft, expectedtotal=None):
257 targetphase=phases.draft, expectedtotal=None):
257 """Add the changegroup returned by source.read() to this repo.
258 """Add the changegroup returned by source.read() to this repo.
258 srctype is a string like 'push', 'pull', or 'unbundle'. url is
259 srctype is a string like 'push', 'pull', or 'unbundle'. url is
259 the URL of the repo where this changegroup is coming from.
260 the URL of the repo where this changegroup is coming from.
260
261
261 Return an integer summarizing the change to this repo:
262 Return an integer summarizing the change to this repo:
262 - nothing changed or no source: 0
263 - nothing changed or no source: 0
263 - more heads than before: 1+added heads (2..n)
264 - more heads than before: 1+added heads (2..n)
264 - fewer heads than before: -1-removed heads (-2..-n)
265 - fewer heads than before: -1-removed heads (-2..-n)
265 - number of heads stays the same: 1
266 - number of heads stays the same: 1
266 """
267 """
267 repo = repo.unfiltered()
268 repo = repo.unfiltered()
268 def csmap(x):
269 def csmap(x):
269 repo.ui.debug("add changeset %s\n" % short(x))
270 repo.ui.debug("add changeset %s\n" % short(x))
270 return len(cl)
271 return len(cl)
271
272
272 def revmap(x):
273 def revmap(x):
273 return cl.rev(x)
274 return cl.rev(x)
274
275
275 changesets = files = revisions = 0
276 changesets = files = revisions = 0
276
277
277 try:
278 try:
278 with repo.transaction("\n".join([srctype,
279 with repo.transaction("\n".join([srctype,
279 util.hidepassword(url)])) as tr:
280 util.hidepassword(url)])) as tr:
280 # The transaction could have been created before and already
281 # The transaction could have been created before and already
281 # carries source information. In this case we use the top
282 # carries source information. In this case we use the top
282 # level data. We overwrite the argument because we need to use
283 # level data. We overwrite the argument because we need to use
283 # the top level value (if they exist) in this function.
284 # the top level value (if they exist) in this function.
284 srctype = tr.hookargs.setdefault('source', srctype)
285 srctype = tr.hookargs.setdefault('source', srctype)
285 url = tr.hookargs.setdefault('url', url)
286 url = tr.hookargs.setdefault('url', url)
286 repo.hook('prechangegroup', throw=True, **tr.hookargs)
287 repo.hook('prechangegroup', throw=True, **tr.hookargs)
287
288
288 # write changelog data to temp files so concurrent readers
289 # write changelog data to temp files so concurrent readers
289 # will not see an inconsistent view
290 # will not see an inconsistent view
290 cl = repo.changelog
291 cl = repo.changelog
291 cl.delayupdate(tr)
292 cl.delayupdate(tr)
292 oldheads = cl.heads()
293 oldheads = cl.heads()
293
294
294 trp = weakref.proxy(tr)
295 trp = weakref.proxy(tr)
295 # pull off the changeset group
296 # pull off the changeset group
296 repo.ui.status(_("adding changesets\n"))
297 repo.ui.status(_("adding changesets\n"))
297 clstart = len(cl)
298 clstart = len(cl)
298 class prog(object):
299 class prog(object):
299 def __init__(self, step, total):
300 def __init__(self, step, total):
300 self._step = step
301 self._step = step
301 self._total = total
302 self._total = total
302 self._count = 1
303 self._count = 1
303 def __call__(self):
304 def __call__(self):
304 repo.ui.progress(self._step, self._count,
305 repo.ui.progress(self._step, self._count,
305 unit=_('chunks'), total=self._total)
306 unit=_('chunks'), total=self._total)
306 self._count += 1
307 self._count += 1
307 self.callback = prog(_('changesets'), expectedtotal)
308 self.callback = prog(_('changesets'), expectedtotal)
308
309
309 efiles = set()
310 efiles = set()
310 def onchangelog(cl, node):
311 def onchangelog(cl, node):
311 efiles.update(cl.readfiles(node))
312 efiles.update(cl.readfiles(node))
312
313
313 self.changelogheader()
314 self.changelogheader()
314 srccontent = cl.addgroup(self, csmap, trp,
315 srccontent = cl.addgroup(self, csmap, trp,
315 addrevisioncb=onchangelog)
316 addrevisioncb=onchangelog)
316 efiles = len(efiles)
317 efiles = len(efiles)
317
318
318 if not (srccontent or emptyok):
319 if not (srccontent or emptyok):
319 raise error.Abort(_("received changelog group is empty"))
320 raise error.Abort(_("received changelog group is empty"))
320 clend = len(cl)
321 clend = len(cl)
321 changesets = clend - clstart
322 changesets = clend - clstart
322 repo.ui.progress(_('changesets'), None)
323 repo.ui.progress(_('changesets'), None)
323 self.callback = None
324 self.callback = None
324
325
325 # pull off the manifest group
326 # pull off the manifest group
326 repo.ui.status(_("adding manifests\n"))
327 repo.ui.status(_("adding manifests\n"))
327 self._unpackmanifests(repo, revmap, trp, prog, changesets)
328 self._unpackmanifests(repo, revmap, trp, prog, changesets)
328
329
329 needfiles = {}
330 needfiles = {}
330 if repo.ui.configbool('server', 'validate', default=False):
331 if repo.ui.configbool('server', 'validate', default=False):
331 # validate incoming csets have their manifests
332 # validate incoming csets have their manifests
332 for cset in xrange(clstart, clend):
333 for cset in xrange(clstart, clend):
333 mfnode = repo.changelog.read(
334 mfnode = repo.changelog.read(
334 repo.changelog.node(cset))[0]
335 repo.changelog.node(cset))[0]
335 mfest = repo.manifest.readdelta(mfnode)
336 mfest = repo.manifest.readdelta(mfnode)
336 # store file nodes we must see
337 # store file nodes we must see
337 for f, n in mfest.iteritems():
338 for f, n in mfest.iteritems():
338 needfiles.setdefault(f, set()).add(n)
339 needfiles.setdefault(f, set()).add(n)
339
340
340 # process the files
341 # process the files
341 repo.ui.status(_("adding file changes\n"))
342 repo.ui.status(_("adding file changes\n"))
342 newrevs, newfiles = _addchangegroupfiles(
343 newrevs, newfiles = _addchangegroupfiles(
343 repo, self, revmap, trp, efiles, needfiles)
344 repo, self, revmap, trp, efiles, needfiles)
344 revisions += newrevs
345 revisions += newrevs
345 files += newfiles
346 files += newfiles
346
347
347 dh = 0
348 dh = 0
348 if oldheads:
349 if oldheads:
349 heads = cl.heads()
350 heads = cl.heads()
350 dh = len(heads) - len(oldheads)
351 dh = len(heads) - len(oldheads)
351 for h in heads:
352 for h in heads:
352 if h not in oldheads and repo[h].closesbranch():
353 if h not in oldheads and repo[h].closesbranch():
353 dh -= 1
354 dh -= 1
354 htext = ""
355 htext = ""
355 if dh:
356 if dh:
356 htext = _(" (%+d heads)") % dh
357 htext = _(" (%+d heads)") % dh
357
358
358 repo.ui.status(_("added %d changesets"
359 repo.ui.status(_("added %d changesets"
359 " with %d changes to %d files%s\n")
360 " with %d changes to %d files%s\n")
360 % (changesets, revisions, files, htext))
361 % (changesets, revisions, files, htext))
361 repo.invalidatevolatilesets()
362 repo.invalidatevolatilesets()
362
363
363 if changesets > 0:
364 if changesets > 0:
364 if 'node' not in tr.hookargs:
365 if 'node' not in tr.hookargs:
365 tr.hookargs['node'] = hex(cl.node(clstart))
366 tr.hookargs['node'] = hex(cl.node(clstart))
366 tr.hookargs['node_last'] = hex(cl.node(clend - 1))
367 tr.hookargs['node_last'] = hex(cl.node(clend - 1))
367 hookargs = dict(tr.hookargs)
368 hookargs = dict(tr.hookargs)
368 else:
369 else:
369 hookargs = dict(tr.hookargs)
370 hookargs = dict(tr.hookargs)
370 hookargs['node'] = hex(cl.node(clstart))
371 hookargs['node'] = hex(cl.node(clstart))
371 hookargs['node_last'] = hex(cl.node(clend - 1))
372 hookargs['node_last'] = hex(cl.node(clend - 1))
372 repo.hook('pretxnchangegroup', throw=True, **hookargs)
373 repo.hook('pretxnchangegroup', throw=True, **hookargs)
373
374
374 added = [cl.node(r) for r in xrange(clstart, clend)]
375 added = [cl.node(r) for r in xrange(clstart, clend)]
375 publishing = repo.publishing()
376 publishing = repo.publishing()
376 if srctype in ('push', 'serve'):
377 if srctype in ('push', 'serve'):
377 # Old servers can not push the boundary themselves.
378 # Old servers can not push the boundary themselves.
378 # New servers won't push the boundary if changeset already
379 # New servers won't push the boundary if changeset already
379 # exists locally as secret
380 # exists locally as secret
380 #
381 #
381 # We should not use added here but the list of all change in
382 # We should not use added here but the list of all change in
382 # the bundle
383 # the bundle
383 if publishing:
384 if publishing:
384 phases.advanceboundary(repo, tr, phases.public,
385 phases.advanceboundary(repo, tr, phases.public,
385 srccontent)
386 srccontent)
386 else:
387 else:
387 # Those changesets have been pushed from the
388 # Those changesets have been pushed from the
388 # outside, their phases are going to be pushed
389 # outside, their phases are going to be pushed
389 # alongside. Therefor `targetphase` is
390 # alongside. Therefor `targetphase` is
390 # ignored.
391 # ignored.
391 phases.advanceboundary(repo, tr, phases.draft,
392 phases.advanceboundary(repo, tr, phases.draft,
392 srccontent)
393 srccontent)
393 phases.retractboundary(repo, tr, phases.draft, added)
394 phases.retractboundary(repo, tr, phases.draft, added)
394 elif srctype != 'strip':
395 elif srctype != 'strip':
395 # publishing only alter behavior during push
396 # publishing only alter behavior during push
396 #
397 #
397 # strip should not touch boundary at all
398 # strip should not touch boundary at all
398 phases.retractboundary(repo, tr, targetphase, added)
399 phases.retractboundary(repo, tr, targetphase, added)
399
400
400 if changesets > 0:
401 if changesets > 0:
401 if srctype != 'strip':
402 if srctype != 'strip':
402 # During strip, branchcache is invalid but
403 # During strip, branchcache is invalid but
403 # coming call to `destroyed` will repair it.
404 # coming call to `destroyed` will repair it.
404 # In other case we can safely update cache on
405 # In other case we can safely update cache on
405 # disk.
406 # disk.
406 branchmap.updatecache(repo.filtered('served'))
407 branchmap.updatecache(repo.filtered('served'))
407
408
408 def runhooks():
409 def runhooks():
409 # These hooks run when the lock releases, not when the
410 # These hooks run when the lock releases, not when the
410 # transaction closes. So it's possible for the changelog
411 # transaction closes. So it's possible for the changelog
411 # to have changed since we last saw it.
412 # to have changed since we last saw it.
412 if clstart >= len(repo):
413 if clstart >= len(repo):
413 return
414 return
414
415
415 # forcefully update the on-disk branch cache
416 # forcefully update the on-disk branch cache
416 repo.ui.debug("updating the branch cache\n")
417 repo.ui.debug("updating the branch cache\n")
417 repo.hook("changegroup", **hookargs)
418 repo.hook("changegroup", **hookargs)
418
419
419 for n in added:
420 for n in added:
420 args = hookargs.copy()
421 args = hookargs.copy()
421 args['node'] = hex(n)
422 args['node'] = hex(n)
422 del args['node_last']
423 del args['node_last']
423 repo.hook("incoming", **args)
424 repo.hook("incoming", **args)
424
425
425 newheads = [h for h in repo.heads()
426 newheads = [h for h in repo.heads()
426 if h not in oldheads]
427 if h not in oldheads]
427 repo.ui.log("incoming",
428 repo.ui.log("incoming",
428 "%s incoming changes - new heads: %s\n",
429 "%s incoming changes - new heads: %s\n",
429 len(added),
430 len(added),
430 ', '.join([hex(c[:6]) for c in newheads]))
431 ', '.join([hex(c[:6]) for c in newheads]))
431
432
432 tr.addpostclose('changegroup-runhooks-%020i' % clstart,
433 tr.addpostclose('changegroup-runhooks-%020i' % clstart,
433 lambda tr: repo._afterlock(runhooks))
434 lambda tr: repo._afterlock(runhooks))
434 finally:
435 finally:
435 repo.ui.flush()
436 repo.ui.flush()
436 # never return 0 here:
437 # never return 0 here:
437 if dh < 0:
438 if dh < 0:
438 return dh - 1
439 return dh - 1
439 else:
440 else:
440 return dh + 1
441 return dh + 1
441
442
442 class cg2unpacker(cg1unpacker):
443 class cg2unpacker(cg1unpacker):
443 """Unpacker for cg2 streams.
444 """Unpacker for cg2 streams.
444
445
445 cg2 streams add support for generaldelta, so the delta header
446 cg2 streams add support for generaldelta, so the delta header
446 format is slightly different. All other features about the data
447 format is slightly different. All other features about the data
447 remain the same.
448 remain the same.
448 """
449 """
449 deltaheader = _CHANGEGROUPV2_DELTA_HEADER
450 deltaheader = _CHANGEGROUPV2_DELTA_HEADER
450 deltaheadersize = struct.calcsize(deltaheader)
451 deltaheadersize = struct.calcsize(deltaheader)
451 version = '02'
452 version = '02'
452
453
453 def _deltaheader(self, headertuple, prevnode):
454 def _deltaheader(self, headertuple, prevnode):
454 node, p1, p2, deltabase, cs = headertuple
455 node, p1, p2, deltabase, cs = headertuple
455 flags = 0
456 flags = 0
456 return node, p1, p2, deltabase, cs, flags
457 return node, p1, p2, deltabase, cs, flags
457
458
458 class cg3unpacker(cg2unpacker):
459 class cg3unpacker(cg2unpacker):
459 """Unpacker for cg3 streams.
460 """Unpacker for cg3 streams.
460
461
461 cg3 streams add support for exchanging treemanifests and revlog
462 cg3 streams add support for exchanging treemanifests and revlog
462 flags. It adds the revlog flags to the delta header and an empty chunk
463 flags. It adds the revlog flags to the delta header and an empty chunk
463 separating manifests and files.
464 separating manifests and files.
464 """
465 """
465 deltaheader = _CHANGEGROUPV3_DELTA_HEADER
466 deltaheader = _CHANGEGROUPV3_DELTA_HEADER
466 deltaheadersize = struct.calcsize(deltaheader)
467 deltaheadersize = struct.calcsize(deltaheader)
467 version = '03'
468 version = '03'
468 _grouplistcount = 2 # One list of manifests and one list of files
469 _grouplistcount = 2 # One list of manifests and one list of files
469
470
470 def _deltaheader(self, headertuple, prevnode):
471 def _deltaheader(self, headertuple, prevnode):
471 node, p1, p2, deltabase, cs, flags = headertuple
472 node, p1, p2, deltabase, cs, flags = headertuple
472 return node, p1, p2, deltabase, cs, flags
473 return node, p1, p2, deltabase, cs, flags
473
474
474 def _unpackmanifests(self, repo, revmap, trp, prog, numchanges):
475 def _unpackmanifests(self, repo, revmap, trp, prog, numchanges):
475 super(cg3unpacker, self)._unpackmanifests(repo, revmap, trp, prog,
476 super(cg3unpacker, self)._unpackmanifests(repo, revmap, trp, prog,
476 numchanges)
477 numchanges)
477 while True:
478 while True:
478 chunkdata = self.filelogheader()
479 chunkdata = self.filelogheader()
479 if not chunkdata:
480 if not chunkdata:
480 break
481 break
481 # If we get here, there are directory manifests in the changegroup
482 # If we get here, there are directory manifests in the changegroup
482 d = chunkdata["filename"]
483 d = chunkdata["filename"]
483 repo.ui.debug("adding %s revisions\n" % d)
484 repo.ui.debug("adding %s revisions\n" % d)
484 dirlog = repo.manifest.dirlog(d)
485 dirlog = repo.manifest.dirlog(d)
485 if not dirlog.addgroup(self, revmap, trp):
486 if not dirlog.addgroup(self, revmap, trp):
486 raise error.Abort(_("received dir revlog group is empty"))
487 raise error.Abort(_("received dir revlog group is empty"))
487
488
488 class headerlessfixup(object):
489 class headerlessfixup(object):
489 def __init__(self, fh, h):
490 def __init__(self, fh, h):
490 self._h = h
491 self._h = h
491 self._fh = fh
492 self._fh = fh
492 def read(self, n):
493 def read(self, n):
493 if self._h:
494 if self._h:
494 d, self._h = self._h[:n], self._h[n:]
495 d, self._h = self._h[:n], self._h[n:]
495 if len(d) < n:
496 if len(d) < n:
496 d += readexactly(self._fh, n - len(d))
497 d += readexactly(self._fh, n - len(d))
497 return d
498 return d
498 return readexactly(self._fh, n)
499 return readexactly(self._fh, n)
499
500
500 class cg1packer(object):
501 class cg1packer(object):
501 deltaheader = _CHANGEGROUPV1_DELTA_HEADER
502 deltaheader = _CHANGEGROUPV1_DELTA_HEADER
502 version = '01'
503 version = '01'
503 def __init__(self, repo, bundlecaps=None):
504 def __init__(self, repo, bundlecaps=None):
504 """Given a source repo, construct a bundler.
505 """Given a source repo, construct a bundler.
505
506
506 bundlecaps is optional and can be used to specify the set of
507 bundlecaps is optional and can be used to specify the set of
507 capabilities which can be used to build the bundle.
508 capabilities which can be used to build the bundle.
508 """
509 """
509 # Set of capabilities we can use to build the bundle.
510 # Set of capabilities we can use to build the bundle.
510 if bundlecaps is None:
511 if bundlecaps is None:
511 bundlecaps = set()
512 bundlecaps = set()
512 self._bundlecaps = bundlecaps
513 self._bundlecaps = bundlecaps
513 # experimental config: bundle.reorder
514 # experimental config: bundle.reorder
514 reorder = repo.ui.config('bundle', 'reorder', 'auto')
515 reorder = repo.ui.config('bundle', 'reorder', 'auto')
515 if reorder == 'auto':
516 if reorder == 'auto':
516 reorder = None
517 reorder = None
517 else:
518 else:
518 reorder = util.parsebool(reorder)
519 reorder = util.parsebool(reorder)
519 self._repo = repo
520 self._repo = repo
520 self._reorder = reorder
521 self._reorder = reorder
521 self._progress = repo.ui.progress
522 self._progress = repo.ui.progress
522 if self._repo.ui.verbose and not self._repo.ui.debugflag:
523 if self._repo.ui.verbose and not self._repo.ui.debugflag:
523 self._verbosenote = self._repo.ui.note
524 self._verbosenote = self._repo.ui.note
524 else:
525 else:
525 self._verbosenote = lambda s: None
526 self._verbosenote = lambda s: None
526
527
527 def close(self):
528 def close(self):
528 return closechunk()
529 return closechunk()
529
530
530 def fileheader(self, fname):
531 def fileheader(self, fname):
531 return chunkheader(len(fname)) + fname
532 return chunkheader(len(fname)) + fname
532
533
533 # Extracted both for clarity and for overriding in extensions.
534 # Extracted both for clarity and for overriding in extensions.
534 def _sortgroup(self, revlog, nodelist, lookup):
535 def _sortgroup(self, revlog, nodelist, lookup):
535 """Sort nodes for change group and turn them into revnums."""
536 """Sort nodes for change group and turn them into revnums."""
536 # for generaldelta revlogs, we linearize the revs; this will both be
537 # for generaldelta revlogs, we linearize the revs; this will both be
537 # much quicker and generate a much smaller bundle
538 # much quicker and generate a much smaller bundle
538 if (revlog._generaldelta and self._reorder is None) or self._reorder:
539 if (revlog._generaldelta and self._reorder is None) or self._reorder:
539 dag = dagutil.revlogdag(revlog)
540 dag = dagutil.revlogdag(revlog)
540 return dag.linearize(set(revlog.rev(n) for n in nodelist))
541 return dag.linearize(set(revlog.rev(n) for n in nodelist))
541 else:
542 else:
542 return sorted([revlog.rev(n) for n in nodelist])
543 return sorted([revlog.rev(n) for n in nodelist])
543
544
544 def group(self, nodelist, revlog, lookup, units=None):
545 def group(self, nodelist, revlog, lookup, units=None):
545 """Calculate a delta group, yielding a sequence of changegroup chunks
546 """Calculate a delta group, yielding a sequence of changegroup chunks
546 (strings).
547 (strings).
547
548
548 Given a list of changeset revs, return a set of deltas and
549 Given a list of changeset revs, return a set of deltas and
549 metadata corresponding to nodes. The first delta is
550 metadata corresponding to nodes. The first delta is
550 first parent(nodelist[0]) -> nodelist[0], the receiver is
551 first parent(nodelist[0]) -> nodelist[0], the receiver is
551 guaranteed to have this parent as it has all history before
552 guaranteed to have this parent as it has all history before
552 these changesets. In the case firstparent is nullrev the
553 these changesets. In the case firstparent is nullrev the
553 changegroup starts with a full revision.
554 changegroup starts with a full revision.
554
555
555 If units is not None, progress detail will be generated, units specifies
556 If units is not None, progress detail will be generated, units specifies
556 the type of revlog that is touched (changelog, manifest, etc.).
557 the type of revlog that is touched (changelog, manifest, etc.).
557 """
558 """
558 # if we don't have any revisions touched by these changesets, bail
559 # if we don't have any revisions touched by these changesets, bail
559 if len(nodelist) == 0:
560 if len(nodelist) == 0:
560 yield self.close()
561 yield self.close()
561 return
562 return
562
563
563 revs = self._sortgroup(revlog, nodelist, lookup)
564 revs = self._sortgroup(revlog, nodelist, lookup)
564
565
565 # add the parent of the first rev
566 # add the parent of the first rev
566 p = revlog.parentrevs(revs[0])[0]
567 p = revlog.parentrevs(revs[0])[0]
567 revs.insert(0, p)
568 revs.insert(0, p)
568
569
569 # build deltas
570 # build deltas
570 total = len(revs) - 1
571 total = len(revs) - 1
571 msgbundling = _('bundling')
572 msgbundling = _('bundling')
572 for r in xrange(len(revs) - 1):
573 for r in xrange(len(revs) - 1):
573 if units is not None:
574 if units is not None:
574 self._progress(msgbundling, r + 1, unit=units, total=total)
575 self._progress(msgbundling, r + 1, unit=units, total=total)
575 prev, curr = revs[r], revs[r + 1]
576 prev, curr = revs[r], revs[r + 1]
576 linknode = lookup(revlog.node(curr))
577 linknode = lookup(revlog.node(curr))
577 for c in self.revchunk(revlog, curr, prev, linknode):
578 for c in self.revchunk(revlog, curr, prev, linknode):
578 yield c
579 yield c
579
580
580 if units is not None:
581 if units is not None:
581 self._progress(msgbundling, None)
582 self._progress(msgbundling, None)
582 yield self.close()
583 yield self.close()
583
584
584 # filter any nodes that claim to be part of the known set
585 # filter any nodes that claim to be part of the known set
585 def prune(self, revlog, missing, commonrevs):
586 def prune(self, revlog, missing, commonrevs):
586 rr, rl = revlog.rev, revlog.linkrev
587 rr, rl = revlog.rev, revlog.linkrev
587 return [n for n in missing if rl(rr(n)) not in commonrevs]
588 return [n for n in missing if rl(rr(n)) not in commonrevs]
588
589
589 def _packmanifests(self, dir, mfnodes, lookuplinknode):
590 def _packmanifests(self, dir, mfnodes, lookuplinknode):
590 """Pack flat manifests into a changegroup stream."""
591 """Pack flat manifests into a changegroup stream."""
591 assert not dir
592 assert not dir
592 for chunk in self.group(mfnodes, self._repo.manifest,
593 for chunk in self.group(mfnodes, self._repo.manifest,
593 lookuplinknode, units=_('manifests')):
594 lookuplinknode, units=_('manifests')):
594 yield chunk
595 yield chunk
595
596
596 def _manifestsdone(self):
597 def _manifestsdone(self):
597 return ''
598 return ''
598
599
599 def generate(self, commonrevs, clnodes, fastpathlinkrev, source):
600 def generate(self, commonrevs, clnodes, fastpathlinkrev, source):
600 '''yield a sequence of changegroup chunks (strings)'''
601 '''yield a sequence of changegroup chunks (strings)'''
601 repo = self._repo
602 repo = self._repo
602 cl = repo.changelog
603 cl = repo.changelog
603
604
604 clrevorder = {}
605 clrevorder = {}
605 mfs = {} # needed manifests
606 mfs = {} # needed manifests
606 fnodes = {} # needed file nodes
607 fnodes = {} # needed file nodes
607 changedfiles = set()
608 changedfiles = set()
608
609
609 # Callback for the changelog, used to collect changed files and manifest
610 # Callback for the changelog, used to collect changed files and manifest
610 # nodes.
611 # nodes.
611 # Returns the linkrev node (identity in the changelog case).
612 # Returns the linkrev node (identity in the changelog case).
612 def lookupcl(x):
613 def lookupcl(x):
613 c = cl.read(x)
614 c = cl.read(x)
614 clrevorder[x] = len(clrevorder)
615 clrevorder[x] = len(clrevorder)
615 n = c[0]
616 n = c[0]
616 # record the first changeset introducing this manifest version
617 # record the first changeset introducing this manifest version
617 mfs.setdefault(n, x)
618 mfs.setdefault(n, x)
618 # Record a complete list of potentially-changed files in
619 # Record a complete list of potentially-changed files in
619 # this manifest.
620 # this manifest.
620 changedfiles.update(c[3])
621 changedfiles.update(c[3])
621 return x
622 return x
622
623
623 self._verbosenote(_('uncompressed size of bundle content:\n'))
624 self._verbosenote(_('uncompressed size of bundle content:\n'))
624 size = 0
625 size = 0
625 for chunk in self.group(clnodes, cl, lookupcl, units=_('changesets')):
626 for chunk in self.group(clnodes, cl, lookupcl, units=_('changesets')):
626 size += len(chunk)
627 size += len(chunk)
627 yield chunk
628 yield chunk
628 self._verbosenote(_('%8.i (changelog)\n') % size)
629 self._verbosenote(_('%8.i (changelog)\n') % size)
629
630
630 # We need to make sure that the linkrev in the changegroup refers to
631 # We need to make sure that the linkrev in the changegroup refers to
631 # the first changeset that introduced the manifest or file revision.
632 # the first changeset that introduced the manifest or file revision.
632 # The fastpath is usually safer than the slowpath, because the filelogs
633 # The fastpath is usually safer than the slowpath, because the filelogs
633 # are walked in revlog order.
634 # are walked in revlog order.
634 #
635 #
635 # When taking the slowpath with reorder=None and the manifest revlog
636 # When taking the slowpath with reorder=None and the manifest revlog
636 # uses generaldelta, the manifest may be walked in the "wrong" order.
637 # uses generaldelta, the manifest may be walked in the "wrong" order.
637 # Without 'clrevorder', we would get an incorrect linkrev (see fix in
638 # Without 'clrevorder', we would get an incorrect linkrev (see fix in
638 # cc0ff93d0c0c).
639 # cc0ff93d0c0c).
639 #
640 #
640 # When taking the fastpath, we are only vulnerable to reordering
641 # When taking the fastpath, we are only vulnerable to reordering
641 # of the changelog itself. The changelog never uses generaldelta, so
642 # of the changelog itself. The changelog never uses generaldelta, so
642 # it is only reordered when reorder=True. To handle this case, we
643 # it is only reordered when reorder=True. To handle this case, we
643 # simply take the slowpath, which already has the 'clrevorder' logic.
644 # simply take the slowpath, which already has the 'clrevorder' logic.
644 # This was also fixed in cc0ff93d0c0c.
645 # This was also fixed in cc0ff93d0c0c.
645 fastpathlinkrev = fastpathlinkrev and not self._reorder
646 fastpathlinkrev = fastpathlinkrev and not self._reorder
646 # Treemanifests don't work correctly with fastpathlinkrev
647 # Treemanifests don't work correctly with fastpathlinkrev
647 # either, because we don't discover which directory nodes to
648 # either, because we don't discover which directory nodes to
648 # send along with files. This could probably be fixed.
649 # send along with files. This could probably be fixed.
649 fastpathlinkrev = fastpathlinkrev and (
650 fastpathlinkrev = fastpathlinkrev and (
650 'treemanifest' not in repo.requirements)
651 'treemanifest' not in repo.requirements)
651
652
652 for chunk in self.generatemanifests(commonrevs, clrevorder,
653 for chunk in self.generatemanifests(commonrevs, clrevorder,
653 fastpathlinkrev, mfs, fnodes):
654 fastpathlinkrev, mfs, fnodes):
654 yield chunk
655 yield chunk
655 mfs.clear()
656 mfs.clear()
656 clrevs = set(cl.rev(x) for x in clnodes)
657 clrevs = set(cl.rev(x) for x in clnodes)
657
658
658 if not fastpathlinkrev:
659 if not fastpathlinkrev:
659 def linknodes(unused, fname):
660 def linknodes(unused, fname):
660 return fnodes.get(fname, {})
661 return fnodes.get(fname, {})
661 else:
662 else:
662 cln = cl.node
663 cln = cl.node
663 def linknodes(filerevlog, fname):
664 def linknodes(filerevlog, fname):
664 llr = filerevlog.linkrev
665 llr = filerevlog.linkrev
665 fln = filerevlog.node
666 fln = filerevlog.node
666 revs = ((r, llr(r)) for r in filerevlog)
667 revs = ((r, llr(r)) for r in filerevlog)
667 return dict((fln(r), cln(lr)) for r, lr in revs if lr in clrevs)
668 return dict((fln(r), cln(lr)) for r, lr in revs if lr in clrevs)
668
669
669 for chunk in self.generatefiles(changedfiles, linknodes, commonrevs,
670 for chunk in self.generatefiles(changedfiles, linknodes, commonrevs,
670 source):
671 source):
671 yield chunk
672 yield chunk
672
673
673 yield self.close()
674 yield self.close()
674
675
675 if clnodes:
676 if clnodes:
676 repo.hook('outgoing', node=hex(clnodes[0]), source=source)
677 repo.hook('outgoing', node=hex(clnodes[0]), source=source)
677
678
678 def generatemanifests(self, commonrevs, clrevorder, fastpathlinkrev, mfs,
679 def generatemanifests(self, commonrevs, clrevorder, fastpathlinkrev, mfs,
679 fnodes):
680 fnodes):
680 repo = self._repo
681 repo = self._repo
681 dirlog = repo.manifest.dirlog
682 dirlog = repo.manifest.dirlog
682 tmfnodes = {'': mfs}
683 tmfnodes = {'': mfs}
683
684
684 # Callback for the manifest, used to collect linkrevs for filelog
685 # Callback for the manifest, used to collect linkrevs for filelog
685 # revisions.
686 # revisions.
686 # Returns the linkrev node (collected in lookupcl).
687 # Returns the linkrev node (collected in lookupcl).
687 def makelookupmflinknode(dir):
688 def makelookupmflinknode(dir):
688 if fastpathlinkrev:
689 if fastpathlinkrev:
689 assert not dir
690 assert not dir
690 return mfs.__getitem__
691 return mfs.__getitem__
691
692
692 def lookupmflinknode(x):
693 def lookupmflinknode(x):
693 """Callback for looking up the linknode for manifests.
694 """Callback for looking up the linknode for manifests.
694
695
695 Returns the linkrev node for the specified manifest.
696 Returns the linkrev node for the specified manifest.
696
697
697 SIDE EFFECT:
698 SIDE EFFECT:
698
699
699 1) fclnodes gets populated with the list of relevant
700 1) fclnodes gets populated with the list of relevant
700 file nodes if we're not using fastpathlinkrev
701 file nodes if we're not using fastpathlinkrev
701 2) When treemanifests are in use, collects treemanifest nodes
702 2) When treemanifests are in use, collects treemanifest nodes
702 to send
703 to send
703
704
704 Note that this means manifests must be completely sent to
705 Note that this means manifests must be completely sent to
705 the client before you can trust the list of files and
706 the client before you can trust the list of files and
706 treemanifests to send.
707 treemanifests to send.
707 """
708 """
708 clnode = tmfnodes[dir][x]
709 clnode = tmfnodes[dir][x]
709 mdata = dirlog(dir).readshallowfast(x)
710 mdata = dirlog(dir).readshallowfast(x)
710 for p, n, fl in mdata.iterentries():
711 for p, n, fl in mdata.iterentries():
711 if fl == 't': # subdirectory manifest
712 if fl == 't': # subdirectory manifest
712 subdir = dir + p + '/'
713 subdir = dir + p + '/'
713 tmfclnodes = tmfnodes.setdefault(subdir, {})
714 tmfclnodes = tmfnodes.setdefault(subdir, {})
714 tmfclnode = tmfclnodes.setdefault(n, clnode)
715 tmfclnode = tmfclnodes.setdefault(n, clnode)
715 if clrevorder[clnode] < clrevorder[tmfclnode]:
716 if clrevorder[clnode] < clrevorder[tmfclnode]:
716 tmfclnodes[n] = clnode
717 tmfclnodes[n] = clnode
717 else:
718 else:
718 f = dir + p
719 f = dir + p
719 fclnodes = fnodes.setdefault(f, {})
720 fclnodes = fnodes.setdefault(f, {})
720 fclnode = fclnodes.setdefault(n, clnode)
721 fclnode = fclnodes.setdefault(n, clnode)
721 if clrevorder[clnode] < clrevorder[fclnode]:
722 if clrevorder[clnode] < clrevorder[fclnode]:
722 fclnodes[n] = clnode
723 fclnodes[n] = clnode
723 return clnode
724 return clnode
724 return lookupmflinknode
725 return lookupmflinknode
725
726
726 size = 0
727 size = 0
727 while tmfnodes:
728 while tmfnodes:
728 dir = min(tmfnodes)
729 dir = min(tmfnodes)
729 nodes = tmfnodes[dir]
730 nodes = tmfnodes[dir]
730 prunednodes = self.prune(dirlog(dir), nodes, commonrevs)
731 prunednodes = self.prune(dirlog(dir), nodes, commonrevs)
731 if not dir or prunednodes:
732 if not dir or prunednodes:
732 for x in self._packmanifests(dir, prunednodes,
733 for x in self._packmanifests(dir, prunednodes,
733 makelookupmflinknode(dir)):
734 makelookupmflinknode(dir)):
734 size += len(x)
735 size += len(x)
735 yield x
736 yield x
736 del tmfnodes[dir]
737 del tmfnodes[dir]
737 self._verbosenote(_('%8.i (manifests)\n') % size)
738 self._verbosenote(_('%8.i (manifests)\n') % size)
738 yield self._manifestsdone()
739 yield self._manifestsdone()
739
740
740 # The 'source' parameter is useful for extensions
741 # The 'source' parameter is useful for extensions
741 def generatefiles(self, changedfiles, linknodes, commonrevs, source):
742 def generatefiles(self, changedfiles, linknodes, commonrevs, source):
742 repo = self._repo
743 repo = self._repo
743 progress = self._progress
744 progress = self._progress
744 msgbundling = _('bundling')
745 msgbundling = _('bundling')
745
746
746 total = len(changedfiles)
747 total = len(changedfiles)
747 # for progress output
748 # for progress output
748 msgfiles = _('files')
749 msgfiles = _('files')
749 for i, fname in enumerate(sorted(changedfiles)):
750 for i, fname in enumerate(sorted(changedfiles)):
750 filerevlog = repo.file(fname)
751 filerevlog = repo.file(fname)
751 if not filerevlog:
752 if not filerevlog:
752 raise error.Abort(_("empty or missing revlog for %s") % fname)
753 raise error.Abort(_("empty or missing revlog for %s") % fname)
753
754
754 linkrevnodes = linknodes(filerevlog, fname)
755 linkrevnodes = linknodes(filerevlog, fname)
755 # Lookup for filenodes, we collected the linkrev nodes above in the
756 # Lookup for filenodes, we collected the linkrev nodes above in the
756 # fastpath case and with lookupmf in the slowpath case.
757 # fastpath case and with lookupmf in the slowpath case.
757 def lookupfilelog(x):
758 def lookupfilelog(x):
758 return linkrevnodes[x]
759 return linkrevnodes[x]
759
760
760 filenodes = self.prune(filerevlog, linkrevnodes, commonrevs)
761 filenodes = self.prune(filerevlog, linkrevnodes, commonrevs)
761 if filenodes:
762 if filenodes:
762 progress(msgbundling, i + 1, item=fname, unit=msgfiles,
763 progress(msgbundling, i + 1, item=fname, unit=msgfiles,
763 total=total)
764 total=total)
764 h = self.fileheader(fname)
765 h = self.fileheader(fname)
765 size = len(h)
766 size = len(h)
766 yield h
767 yield h
767 for chunk in self.group(filenodes, filerevlog, lookupfilelog):
768 for chunk in self.group(filenodes, filerevlog, lookupfilelog):
768 size += len(chunk)
769 size += len(chunk)
769 yield chunk
770 yield chunk
770 self._verbosenote(_('%8.i %s\n') % (size, fname))
771 self._verbosenote(_('%8.i %s\n') % (size, fname))
771 progress(msgbundling, None)
772 progress(msgbundling, None)
772
773
773 def deltaparent(self, revlog, rev, p1, p2, prev):
774 def deltaparent(self, revlog, rev, p1, p2, prev):
774 return prev
775 return prev
775
776
776 def revchunk(self, revlog, rev, prev, linknode):
777 def revchunk(self, revlog, rev, prev, linknode):
777 node = revlog.node(rev)
778 node = revlog.node(rev)
778 p1, p2 = revlog.parentrevs(rev)
779 p1, p2 = revlog.parentrevs(rev)
779 base = self.deltaparent(revlog, rev, p1, p2, prev)
780 base = self.deltaparent(revlog, rev, p1, p2, prev)
780
781
781 prefix = ''
782 prefix = ''
782 if revlog.iscensored(base) or revlog.iscensored(rev):
783 if revlog.iscensored(base) or revlog.iscensored(rev):
783 try:
784 try:
784 delta = revlog.revision(node)
785 delta = revlog.revision(node)
785 except error.CensoredNodeError as e:
786 except error.CensoredNodeError as e:
786 delta = e.tombstone
787 delta = e.tombstone
787 if base == nullrev:
788 if base == nullrev:
788 prefix = mdiff.trivialdiffheader(len(delta))
789 prefix = mdiff.trivialdiffheader(len(delta))
789 else:
790 else:
790 baselen = revlog.rawsize(base)
791 baselen = revlog.rawsize(base)
791 prefix = mdiff.replacediffheader(baselen, len(delta))
792 prefix = mdiff.replacediffheader(baselen, len(delta))
792 elif base == nullrev:
793 elif base == nullrev:
793 delta = revlog.revision(node)
794 delta = revlog.revision(node)
794 prefix = mdiff.trivialdiffheader(len(delta))
795 prefix = mdiff.trivialdiffheader(len(delta))
795 else:
796 else:
796 delta = revlog.revdiff(base, rev)
797 delta = revlog.revdiff(base, rev)
797 p1n, p2n = revlog.parents(node)
798 p1n, p2n = revlog.parents(node)
798 basenode = revlog.node(base)
799 basenode = revlog.node(base)
799 flags = revlog.flags(rev)
800 flags = revlog.flags(rev)
800 meta = self.builddeltaheader(node, p1n, p2n, basenode, linknode, flags)
801 meta = self.builddeltaheader(node, p1n, p2n, basenode, linknode, flags)
801 meta += prefix
802 meta += prefix
802 l = len(meta) + len(delta)
803 l = len(meta) + len(delta)
803 yield chunkheader(l)
804 yield chunkheader(l)
804 yield meta
805 yield meta
805 yield delta
806 yield delta
806 def builddeltaheader(self, node, p1n, p2n, basenode, linknode, flags):
807 def builddeltaheader(self, node, p1n, p2n, basenode, linknode, flags):
807 # do nothing with basenode, it is implicitly the previous one in HG10
808 # do nothing with basenode, it is implicitly the previous one in HG10
808 # do nothing with flags, it is implicitly 0 for cg1 and cg2
809 # do nothing with flags, it is implicitly 0 for cg1 and cg2
809 return struct.pack(self.deltaheader, node, p1n, p2n, linknode)
810 return struct.pack(self.deltaheader, node, p1n, p2n, linknode)
810
811
811 class cg2packer(cg1packer):
812 class cg2packer(cg1packer):
812 version = '02'
813 version = '02'
813 deltaheader = _CHANGEGROUPV2_DELTA_HEADER
814 deltaheader = _CHANGEGROUPV2_DELTA_HEADER
814
815
815 def __init__(self, repo, bundlecaps=None):
816 def __init__(self, repo, bundlecaps=None):
816 super(cg2packer, self).__init__(repo, bundlecaps)
817 super(cg2packer, self).__init__(repo, bundlecaps)
817 if self._reorder is None:
818 if self._reorder is None:
818 # Since generaldelta is directly supported by cg2, reordering
819 # Since generaldelta is directly supported by cg2, reordering
819 # generally doesn't help, so we disable it by default (treating
820 # generally doesn't help, so we disable it by default (treating
820 # bundle.reorder=auto just like bundle.reorder=False).
821 # bundle.reorder=auto just like bundle.reorder=False).
821 self._reorder = False
822 self._reorder = False
822
823
823 def deltaparent(self, revlog, rev, p1, p2, prev):
824 def deltaparent(self, revlog, rev, p1, p2, prev):
824 dp = revlog.deltaparent(rev)
825 dp = revlog.deltaparent(rev)
825 # avoid storing full revisions; pick prev in those cases
826 # avoid storing full revisions; pick prev in those cases
826 # also pick prev when we can't be sure remote has dp
827 # also pick prev when we can't be sure remote has dp
827 if dp == nullrev or (dp != p1 and dp != p2 and dp != prev):
828 if dp == nullrev or (dp != p1 and dp != p2 and dp != prev):
828 return prev
829 return prev
829 return dp
830 return dp
830
831
831 def builddeltaheader(self, node, p1n, p2n, basenode, linknode, flags):
832 def builddeltaheader(self, node, p1n, p2n, basenode, linknode, flags):
832 # Do nothing with flags, it is implicitly 0 in cg1 and cg2
833 # Do nothing with flags, it is implicitly 0 in cg1 and cg2
833 return struct.pack(self.deltaheader, node, p1n, p2n, basenode, linknode)
834 return struct.pack(self.deltaheader, node, p1n, p2n, basenode, linknode)
834
835
835 class cg3packer(cg2packer):
836 class cg3packer(cg2packer):
836 version = '03'
837 version = '03'
837 deltaheader = _CHANGEGROUPV3_DELTA_HEADER
838 deltaheader = _CHANGEGROUPV3_DELTA_HEADER
838
839
839 def _packmanifests(self, dir, mfnodes, lookuplinknode):
840 def _packmanifests(self, dir, mfnodes, lookuplinknode):
840 if dir:
841 if dir:
841 yield self.fileheader(dir)
842 yield self.fileheader(dir)
842 for chunk in self.group(mfnodes, self._repo.manifest.dirlog(dir),
843 for chunk in self.group(mfnodes, self._repo.manifest.dirlog(dir),
843 lookuplinknode, units=_('manifests')):
844 lookuplinknode, units=_('manifests')):
844 yield chunk
845 yield chunk
845
846
846 def _manifestsdone(self):
847 def _manifestsdone(self):
847 return self.close()
848 return self.close()
848
849
849 def builddeltaheader(self, node, p1n, p2n, basenode, linknode, flags):
850 def builddeltaheader(self, node, p1n, p2n, basenode, linknode, flags):
850 return struct.pack(
851 return struct.pack(
851 self.deltaheader, node, p1n, p2n, basenode, linknode, flags)
852 self.deltaheader, node, p1n, p2n, basenode, linknode, flags)
852
853
853 _packermap = {'01': (cg1packer, cg1unpacker),
854 _packermap = {'01': (cg1packer, cg1unpacker),
854 # cg2 adds support for exchanging generaldelta
855 # cg2 adds support for exchanging generaldelta
855 '02': (cg2packer, cg2unpacker),
856 '02': (cg2packer, cg2unpacker),
856 # cg3 adds support for exchanging revlog flags and treemanifests
857 # cg3 adds support for exchanging revlog flags and treemanifests
857 '03': (cg3packer, cg3unpacker),
858 '03': (cg3packer, cg3unpacker),
858 }
859 }
859
860
860 def allsupportedversions(ui):
861 def allsupportedversions(ui):
861 versions = set(_packermap.keys())
862 versions = set(_packermap.keys())
862 versions.discard('03')
863 versions.discard('03')
863 if (ui.configbool('experimental', 'changegroup3') or
864 if (ui.configbool('experimental', 'changegroup3') or
864 ui.configbool('experimental', 'treemanifest')):
865 ui.configbool('experimental', 'treemanifest')):
865 versions.add('03')
866 versions.add('03')
866 return versions
867 return versions
867
868
868 # Changegroup versions that can be applied to the repo
869 # Changegroup versions that can be applied to the repo
869 def supportedincomingversions(repo):
870 def supportedincomingversions(repo):
870 versions = allsupportedversions(repo.ui)
871 versions = allsupportedversions(repo.ui)
871 if 'treemanifest' in repo.requirements:
872 if 'treemanifest' in repo.requirements:
872 versions.add('03')
873 versions.add('03')
873 return versions
874 return versions
874
875
875 # Changegroup versions that can be created from the repo
876 # Changegroup versions that can be created from the repo
876 def supportedoutgoingversions(repo):
877 def supportedoutgoingversions(repo):
877 versions = allsupportedversions(repo.ui)
878 versions = allsupportedversions(repo.ui)
878 if 'treemanifest' in repo.requirements:
879 if 'treemanifest' in repo.requirements:
879 # Versions 01 and 02 support only flat manifests and it's just too
880 # Versions 01 and 02 support only flat manifests and it's just too
880 # expensive to convert between the flat manifest and tree manifest on
881 # expensive to convert between the flat manifest and tree manifest on
881 # the fly. Since tree manifests are hashed differently, all of history
882 # the fly. Since tree manifests are hashed differently, all of history
882 # would have to be converted. Instead, we simply don't even pretend to
883 # would have to be converted. Instead, we simply don't even pretend to
883 # support versions 01 and 02.
884 # support versions 01 and 02.
884 versions.discard('01')
885 versions.discard('01')
885 versions.discard('02')
886 versions.discard('02')
886 versions.add('03')
887 versions.add('03')
887 return versions
888 return versions
888
889
889 def safeversion(repo):
890 def safeversion(repo):
890 # Finds the smallest version that it's safe to assume clients of the repo
891 # Finds the smallest version that it's safe to assume clients of the repo
891 # will support. For example, all hg versions that support generaldelta also
892 # will support. For example, all hg versions that support generaldelta also
892 # support changegroup 02.
893 # support changegroup 02.
893 versions = supportedoutgoingversions(repo)
894 versions = supportedoutgoingversions(repo)
894 if 'generaldelta' in repo.requirements:
895 if 'generaldelta' in repo.requirements:
895 versions.discard('01')
896 versions.discard('01')
896 assert versions
897 assert versions
897 return min(versions)
898 return min(versions)
898
899
899 def getbundler(version, repo, bundlecaps=None):
900 def getbundler(version, repo, bundlecaps=None):
900 assert version in supportedoutgoingversions(repo)
901 assert version in supportedoutgoingversions(repo)
901 return _packermap[version][0](repo, bundlecaps)
902 return _packermap[version][0](repo, bundlecaps)
902
903
903 def getunbundler(version, fh, alg):
904 def getunbundler(version, fh, alg, extras=None):
904 return _packermap[version][1](fh, alg)
905 return _packermap[version][1](fh, alg, extras=extras)
905
906
906 def _changegroupinfo(repo, nodes, source):
907 def _changegroupinfo(repo, nodes, source):
907 if repo.ui.verbose or source == 'bundle':
908 if repo.ui.verbose or source == 'bundle':
908 repo.ui.status(_("%d changesets found\n") % len(nodes))
909 repo.ui.status(_("%d changesets found\n") % len(nodes))
909 if repo.ui.debugflag:
910 if repo.ui.debugflag:
910 repo.ui.debug("list of changesets:\n")
911 repo.ui.debug("list of changesets:\n")
911 for node in nodes:
912 for node in nodes:
912 repo.ui.debug("%s\n" % hex(node))
913 repo.ui.debug("%s\n" % hex(node))
913
914
914 def getsubsetraw(repo, outgoing, bundler, source, fastpath=False):
915 def getsubsetraw(repo, outgoing, bundler, source, fastpath=False):
915 repo = repo.unfiltered()
916 repo = repo.unfiltered()
916 commonrevs = outgoing.common
917 commonrevs = outgoing.common
917 csets = outgoing.missing
918 csets = outgoing.missing
918 heads = outgoing.missingheads
919 heads = outgoing.missingheads
919 # We go through the fast path if we get told to, or if all (unfiltered
920 # We go through the fast path if we get told to, or if all (unfiltered
920 # heads have been requested (since we then know there all linkrevs will
921 # heads have been requested (since we then know there all linkrevs will
921 # be pulled by the client).
922 # be pulled by the client).
922 heads.sort()
923 heads.sort()
923 fastpathlinkrev = fastpath or (
924 fastpathlinkrev = fastpath or (
924 repo.filtername is None and heads == sorted(repo.heads()))
925 repo.filtername is None and heads == sorted(repo.heads()))
925
926
926 repo.hook('preoutgoing', throw=True, source=source)
927 repo.hook('preoutgoing', throw=True, source=source)
927 _changegroupinfo(repo, csets, source)
928 _changegroupinfo(repo, csets, source)
928 return bundler.generate(commonrevs, csets, fastpathlinkrev, source)
929 return bundler.generate(commonrevs, csets, fastpathlinkrev, source)
929
930
930 def getsubset(repo, outgoing, bundler, source, fastpath=False):
931 def getsubset(repo, outgoing, bundler, source, fastpath=False):
931 gengroup = getsubsetraw(repo, outgoing, bundler, source, fastpath)
932 gengroup = getsubsetraw(repo, outgoing, bundler, source, fastpath)
932 return getunbundler(bundler.version, util.chunkbuffer(gengroup), None)
933 return getunbundler(bundler.version, util.chunkbuffer(gengroup), None,
934 {'clcount': len(outgoing.missing)})
933
935
934 def changegroupsubset(repo, roots, heads, source, version='01'):
936 def changegroupsubset(repo, roots, heads, source, version='01'):
935 """Compute a changegroup consisting of all the nodes that are
937 """Compute a changegroup consisting of all the nodes that are
936 descendants of any of the roots and ancestors of any of the heads.
938 descendants of any of the roots and ancestors of any of the heads.
937 Return a chunkbuffer object whose read() method will return
939 Return a chunkbuffer object whose read() method will return
938 successive changegroup chunks.
940 successive changegroup chunks.
939
941
940 It is fairly complex as determining which filenodes and which
942 It is fairly complex as determining which filenodes and which
941 manifest nodes need to be included for the changeset to be complete
943 manifest nodes need to be included for the changeset to be complete
942 is non-trivial.
944 is non-trivial.
943
945
944 Another wrinkle is doing the reverse, figuring out which changeset in
946 Another wrinkle is doing the reverse, figuring out which changeset in
945 the changegroup a particular filenode or manifestnode belongs to.
947 the changegroup a particular filenode or manifestnode belongs to.
946 """
948 """
947 cl = repo.changelog
949 cl = repo.changelog
948 if not roots:
950 if not roots:
949 roots = [nullid]
951 roots = [nullid]
950 discbases = []
952 discbases = []
951 for n in roots:
953 for n in roots:
952 discbases.extend([p for p in cl.parents(n) if p != nullid])
954 discbases.extend([p for p in cl.parents(n) if p != nullid])
953 # TODO: remove call to nodesbetween.
955 # TODO: remove call to nodesbetween.
954 csets, roots, heads = cl.nodesbetween(roots, heads)
956 csets, roots, heads = cl.nodesbetween(roots, heads)
955 included = set(csets)
957 included = set(csets)
956 discbases = [n for n in discbases if n not in included]
958 discbases = [n for n in discbases if n not in included]
957 outgoing = discovery.outgoing(cl, discbases, heads)
959 outgoing = discovery.outgoing(cl, discbases, heads)
958 bundler = getbundler(version, repo)
960 bundler = getbundler(version, repo)
959 return getsubset(repo, outgoing, bundler, source)
961 return getsubset(repo, outgoing, bundler, source)
960
962
961 def getlocalchangegroupraw(repo, source, outgoing, bundlecaps=None,
963 def getlocalchangegroupraw(repo, source, outgoing, bundlecaps=None,
962 version='01'):
964 version='01'):
963 """Like getbundle, but taking a discovery.outgoing as an argument.
965 """Like getbundle, but taking a discovery.outgoing as an argument.
964
966
965 This is only implemented for local repos and reuses potentially
967 This is only implemented for local repos and reuses potentially
966 precomputed sets in outgoing. Returns a raw changegroup generator."""
968 precomputed sets in outgoing. Returns a raw changegroup generator."""
967 if not outgoing.missing:
969 if not outgoing.missing:
968 return None
970 return None
969 bundler = getbundler(version, repo, bundlecaps)
971 bundler = getbundler(version, repo, bundlecaps)
970 return getsubsetraw(repo, outgoing, bundler, source)
972 return getsubsetraw(repo, outgoing, bundler, source)
971
973
972 def getlocalchangegroup(repo, source, outgoing, bundlecaps=None,
974 def getlocalchangegroup(repo, source, outgoing, bundlecaps=None,
973 version='01'):
975 version='01'):
974 """Like getbundle, but taking a discovery.outgoing as an argument.
976 """Like getbundle, but taking a discovery.outgoing as an argument.
975
977
976 This is only implemented for local repos and reuses potentially
978 This is only implemented for local repos and reuses potentially
977 precomputed sets in outgoing."""
979 precomputed sets in outgoing."""
978 if not outgoing.missing:
980 if not outgoing.missing:
979 return None
981 return None
980 bundler = getbundler(version, repo, bundlecaps)
982 bundler = getbundler(version, repo, bundlecaps)
981 return getsubset(repo, outgoing, bundler, source)
983 return getsubset(repo, outgoing, bundler, source)
982
984
983 def computeoutgoing(repo, heads, common):
985 def computeoutgoing(repo, heads, common):
984 """Computes which revs are outgoing given a set of common
986 """Computes which revs are outgoing given a set of common
985 and a set of heads.
987 and a set of heads.
986
988
987 This is a separate function so extensions can have access to
989 This is a separate function so extensions can have access to
988 the logic.
990 the logic.
989
991
990 Returns a discovery.outgoing object.
992 Returns a discovery.outgoing object.
991 """
993 """
992 cl = repo.changelog
994 cl = repo.changelog
993 if common:
995 if common:
994 hasnode = cl.hasnode
996 hasnode = cl.hasnode
995 common = [n for n in common if hasnode(n)]
997 common = [n for n in common if hasnode(n)]
996 else:
998 else:
997 common = [nullid]
999 common = [nullid]
998 if not heads:
1000 if not heads:
999 heads = cl.heads()
1001 heads = cl.heads()
1000 return discovery.outgoing(cl, common, heads)
1002 return discovery.outgoing(cl, common, heads)
1001
1003
1002 def getchangegroup(repo, source, heads=None, common=None, bundlecaps=None,
1004 def getchangegroup(repo, source, heads=None, common=None, bundlecaps=None,
1003 version='01'):
1005 version='01'):
1004 """Like changegroupsubset, but returns the set difference between the
1006 """Like changegroupsubset, but returns the set difference between the
1005 ancestors of heads and the ancestors common.
1007 ancestors of heads and the ancestors common.
1006
1008
1007 If heads is None, use the local heads. If common is None, use [nullid].
1009 If heads is None, use the local heads. If common is None, use [nullid].
1008
1010
1009 The nodes in common might not all be known locally due to the way the
1011 The nodes in common might not all be known locally due to the way the
1010 current discovery protocol works.
1012 current discovery protocol works.
1011 """
1013 """
1012 outgoing = computeoutgoing(repo, heads, common)
1014 outgoing = computeoutgoing(repo, heads, common)
1013 return getlocalchangegroup(repo, source, outgoing, bundlecaps=bundlecaps,
1015 return getlocalchangegroup(repo, source, outgoing, bundlecaps=bundlecaps,
1014 version=version)
1016 version=version)
1015
1017
1016 def changegroup(repo, basenodes, source):
1018 def changegroup(repo, basenodes, source):
1017 # to avoid a race we use changegroupsubset() (issue1320)
1019 # to avoid a race we use changegroupsubset() (issue1320)
1018 return changegroupsubset(repo, basenodes, repo.heads(), source)
1020 return changegroupsubset(repo, basenodes, repo.heads(), source)
1019
1021
1020 def _addchangegroupfiles(repo, source, revmap, trp, expectedfiles, needfiles):
1022 def _addchangegroupfiles(repo, source, revmap, trp, expectedfiles, needfiles):
1021 revisions = 0
1023 revisions = 0
1022 files = 0
1024 files = 0
1023 while True:
1025 while True:
1024 chunkdata = source.filelogheader()
1026 chunkdata = source.filelogheader()
1025 if not chunkdata:
1027 if not chunkdata:
1026 break
1028 break
1027 files += 1
1029 files += 1
1028 f = chunkdata["filename"]
1030 f = chunkdata["filename"]
1029 repo.ui.debug("adding %s revisions\n" % f)
1031 repo.ui.debug("adding %s revisions\n" % f)
1030 repo.ui.progress(_('files'), files, unit=_('files'),
1032 repo.ui.progress(_('files'), files, unit=_('files'),
1031 total=expectedfiles)
1033 total=expectedfiles)
1032 fl = repo.file(f)
1034 fl = repo.file(f)
1033 o = len(fl)
1035 o = len(fl)
1034 try:
1036 try:
1035 if not fl.addgroup(source, revmap, trp):
1037 if not fl.addgroup(source, revmap, trp):
1036 raise error.Abort(_("received file revlog group is empty"))
1038 raise error.Abort(_("received file revlog group is empty"))
1037 except error.CensoredBaseError as e:
1039 except error.CensoredBaseError as e:
1038 raise error.Abort(_("received delta base is censored: %s") % e)
1040 raise error.Abort(_("received delta base is censored: %s") % e)
1039 revisions += len(fl) - o
1041 revisions += len(fl) - o
1040 if f in needfiles:
1042 if f in needfiles:
1041 needs = needfiles[f]
1043 needs = needfiles[f]
1042 for new in xrange(o, len(fl)):
1044 for new in xrange(o, len(fl)):
1043 n = fl.node(new)
1045 n = fl.node(new)
1044 if n in needs:
1046 if n in needs:
1045 needs.remove(n)
1047 needs.remove(n)
1046 else:
1048 else:
1047 raise error.Abort(
1049 raise error.Abort(
1048 _("received spurious file revlog entry"))
1050 _("received spurious file revlog entry"))
1049 if not needs:
1051 if not needs:
1050 del needfiles[f]
1052 del needfiles[f]
1051 repo.ui.progress(_('files'), None)
1053 repo.ui.progress(_('files'), None)
1052
1054
1053 for f, needs in needfiles.iteritems():
1055 for f, needs in needfiles.iteritems():
1054 fl = repo.file(f)
1056 fl = repo.file(f)
1055 for n in needs:
1057 for n in needs:
1056 try:
1058 try:
1057 fl.rev(n)
1059 fl.rev(n)
1058 except error.LookupError:
1060 except error.LookupError:
1059 raise error.Abort(
1061 raise error.Abort(
1060 _('missing file data for %s:%s - run hg verify') %
1062 _('missing file data for %s:%s - run hg verify') %
1061 (f, hex(n)))
1063 (f, hex(n)))
1062
1064
1063 return revisions, files
1065 return revisions, files
@@ -1,128 +1,128 b''
1
1
2 $ cat << EOF >> $HGRCPATH
2 $ cat << EOF >> $HGRCPATH
3 > [format]
3 > [format]
4 > usegeneraldelta=yes
4 > usegeneraldelta=yes
5 > EOF
5 > EOF
6
6
7 bundle w/o type option
7 bundle w/o type option
8
8
9 $ hg init t1
9 $ hg init t1
10 $ hg init t2
10 $ hg init t2
11 $ cd t1
11 $ cd t1
12 $ echo blablablablabla > file.txt
12 $ echo blablablablabla > file.txt
13 $ hg ci -Ama
13 $ hg ci -Ama
14 adding file.txt
14 adding file.txt
15 $ hg log | grep summary
15 $ hg log | grep summary
16 summary: a
16 summary: a
17 $ hg bundle ../b1 ../t2
17 $ hg bundle ../b1 ../t2
18 searching for changes
18 searching for changes
19 1 changesets found
19 1 changesets found
20
20
21 $ cd ../t2
21 $ cd ../t2
22 $ hg pull ../b1
22 $ hg pull ../b1
23 pulling from ../b1
23 pulling from ../b1
24 requesting all changes
24 requesting all changes
25 adding changesets
25 adding changesets
26 adding manifests
26 adding manifests
27 adding file changes
27 adding file changes
28 added 1 changesets with 1 changes to 1 files
28 added 1 changesets with 1 changes to 1 files
29 (run 'hg update' to get a working copy)
29 (run 'hg update' to get a working copy)
30 $ hg up
30 $ hg up
31 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
31 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
32 $ hg log | grep summary
32 $ hg log | grep summary
33 summary: a
33 summary: a
34 $ cd ..
34 $ cd ..
35
35
36 test bundle types
36 test bundle types
37
37
38 $ for t in "None" "bzip2" "gzip" "none-v2" "v2" "v1" "gzip-v1"; do
38 $ for t in "None" "bzip2" "gzip" "none-v2" "v2" "v1" "gzip-v1"; do
39 > echo % test bundle type $t
39 > echo % test bundle type $t
40 > hg init t$t
40 > hg init t$t
41 > cd t1
41 > cd t1
42 > hg bundle -t $t ../b$t ../t$t
42 > hg bundle -t $t ../b$t ../t$t
43 > f -q -B6 -D ../b$t; echo
43 > f -q -B6 -D ../b$t; echo
44 > cd ../t$t
44 > cd ../t$t
45 > hg debugbundle ../b$t
45 > hg debugbundle ../b$t
46 > hg debugbundle --spec ../b$t
46 > hg debugbundle --spec ../b$t
47 > echo
47 > echo
48 > cd ..
48 > cd ..
49 > done
49 > done
50 % test bundle type None
50 % test bundle type None
51 searching for changes
51 searching for changes
52 1 changesets found
52 1 changesets found
53 HG20\x00\x00 (esc)
53 HG20\x00\x00 (esc)
54 Stream params: {}
54 Stream params: {}
55 changegroup -- "sortdict([('version', '02')])"
55 changegroup -- "sortdict([('version', '02'), ('nbchanges', '1')])"
56 c35a0f9217e65d1fdb90c936ffa7dbe679f83ddf
56 c35a0f9217e65d1fdb90c936ffa7dbe679f83ddf
57 none-v2
57 none-v2
58
58
59 % test bundle type bzip2
59 % test bundle type bzip2
60 searching for changes
60 searching for changes
61 1 changesets found
61 1 changesets found
62 HG20\x00\x00 (esc)
62 HG20\x00\x00 (esc)
63 Stream params: sortdict([('Compression', 'BZ')])
63 Stream params: sortdict([('Compression', 'BZ')])
64 changegroup -- "sortdict([('version', '02')])"
64 changegroup -- "sortdict([('version', '02'), ('nbchanges', '1')])"
65 c35a0f9217e65d1fdb90c936ffa7dbe679f83ddf
65 c35a0f9217e65d1fdb90c936ffa7dbe679f83ddf
66 bzip2-v2
66 bzip2-v2
67
67
68 % test bundle type gzip
68 % test bundle type gzip
69 searching for changes
69 searching for changes
70 1 changesets found
70 1 changesets found
71 HG20\x00\x00 (esc)
71 HG20\x00\x00 (esc)
72 Stream params: sortdict([('Compression', 'GZ')])
72 Stream params: sortdict([('Compression', 'GZ')])
73 changegroup -- "sortdict([('version', '02')])"
73 changegroup -- "sortdict([('version', '02'), ('nbchanges', '1')])"
74 c35a0f9217e65d1fdb90c936ffa7dbe679f83ddf
74 c35a0f9217e65d1fdb90c936ffa7dbe679f83ddf
75 gzip-v2
75 gzip-v2
76
76
77 % test bundle type none-v2
77 % test bundle type none-v2
78 searching for changes
78 searching for changes
79 1 changesets found
79 1 changesets found
80 HG20\x00\x00 (esc)
80 HG20\x00\x00 (esc)
81 Stream params: {}
81 Stream params: {}
82 changegroup -- "sortdict([('version', '02')])"
82 changegroup -- "sortdict([('version', '02'), ('nbchanges', '1')])"
83 c35a0f9217e65d1fdb90c936ffa7dbe679f83ddf
83 c35a0f9217e65d1fdb90c936ffa7dbe679f83ddf
84 none-v2
84 none-v2
85
85
86 % test bundle type v2
86 % test bundle type v2
87 searching for changes
87 searching for changes
88 1 changesets found
88 1 changesets found
89 HG20\x00\x00 (esc)
89 HG20\x00\x00 (esc)
90 Stream params: sortdict([('Compression', 'BZ')])
90 Stream params: sortdict([('Compression', 'BZ')])
91 changegroup -- "sortdict([('version', '02')])"
91 changegroup -- "sortdict([('version', '02'), ('nbchanges', '1')])"
92 c35a0f9217e65d1fdb90c936ffa7dbe679f83ddf
92 c35a0f9217e65d1fdb90c936ffa7dbe679f83ddf
93 bzip2-v2
93 bzip2-v2
94
94
95 % test bundle type v1
95 % test bundle type v1
96 searching for changes
96 searching for changes
97 1 changesets found
97 1 changesets found
98 HG10BZ
98 HG10BZ
99 c35a0f9217e65d1fdb90c936ffa7dbe679f83ddf
99 c35a0f9217e65d1fdb90c936ffa7dbe679f83ddf
100 bzip2-v1
100 bzip2-v1
101
101
102 % test bundle type gzip-v1
102 % test bundle type gzip-v1
103 searching for changes
103 searching for changes
104 1 changesets found
104 1 changesets found
105 HG10GZ
105 HG10GZ
106 c35a0f9217e65d1fdb90c936ffa7dbe679f83ddf
106 c35a0f9217e65d1fdb90c936ffa7dbe679f83ddf
107 gzip-v1
107 gzip-v1
108
108
109
109
110 test garbage file
110 test garbage file
111
111
112 $ echo garbage > bgarbage
112 $ echo garbage > bgarbage
113 $ hg init tgarbage
113 $ hg init tgarbage
114 $ cd tgarbage
114 $ cd tgarbage
115 $ hg pull ../bgarbage
115 $ hg pull ../bgarbage
116 pulling from ../bgarbage
116 pulling from ../bgarbage
117 abort: ../bgarbage: not a Mercurial bundle
117 abort: ../bgarbage: not a Mercurial bundle
118 [255]
118 [255]
119 $ cd ..
119 $ cd ..
120
120
121 test invalid bundle type
121 test invalid bundle type
122
122
123 $ cd t1
123 $ cd t1
124 $ hg bundle -a -t garbage ../bgarbage
124 $ hg bundle -a -t garbage ../bgarbage
125 abort: garbage is not a recognized bundle specification
125 abort: garbage is not a recognized bundle specification
126 (see "hg help bundle" for supported values for --type)
126 (see "hg help bundle" for supported values for --type)
127 [255]
127 [255]
128 $ cd ..
128 $ cd ..
@@ -1,809 +1,809 b''
1
1
2 $ cat << EOF >> $HGRCPATH
2 $ cat << EOF >> $HGRCPATH
3 > [format]
3 > [format]
4 > usegeneraldelta=yes
4 > usegeneraldelta=yes
5 > EOF
5 > EOF
6
6
7 Setting up test
7 Setting up test
8
8
9 $ hg init test
9 $ hg init test
10 $ cd test
10 $ cd test
11 $ echo 0 > afile
11 $ echo 0 > afile
12 $ hg add afile
12 $ hg add afile
13 $ hg commit -m "0.0"
13 $ hg commit -m "0.0"
14 $ echo 1 >> afile
14 $ echo 1 >> afile
15 $ hg commit -m "0.1"
15 $ hg commit -m "0.1"
16 $ echo 2 >> afile
16 $ echo 2 >> afile
17 $ hg commit -m "0.2"
17 $ hg commit -m "0.2"
18 $ echo 3 >> afile
18 $ echo 3 >> afile
19 $ hg commit -m "0.3"
19 $ hg commit -m "0.3"
20 $ hg update -C 0
20 $ hg update -C 0
21 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
21 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
22 $ echo 1 >> afile
22 $ echo 1 >> afile
23 $ hg commit -m "1.1"
23 $ hg commit -m "1.1"
24 created new head
24 created new head
25 $ echo 2 >> afile
25 $ echo 2 >> afile
26 $ hg commit -m "1.2"
26 $ hg commit -m "1.2"
27 $ echo "a line" > fred
27 $ echo "a line" > fred
28 $ echo 3 >> afile
28 $ echo 3 >> afile
29 $ hg add fred
29 $ hg add fred
30 $ hg commit -m "1.3"
30 $ hg commit -m "1.3"
31 $ hg mv afile adifferentfile
31 $ hg mv afile adifferentfile
32 $ hg commit -m "1.3m"
32 $ hg commit -m "1.3m"
33 $ hg update -C 3
33 $ hg update -C 3
34 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
34 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
35 $ hg mv afile anotherfile
35 $ hg mv afile anotherfile
36 $ hg commit -m "0.3m"
36 $ hg commit -m "0.3m"
37 $ hg verify
37 $ hg verify
38 checking changesets
38 checking changesets
39 checking manifests
39 checking manifests
40 crosschecking files in changesets and manifests
40 crosschecking files in changesets and manifests
41 checking files
41 checking files
42 4 files, 9 changesets, 7 total revisions
42 4 files, 9 changesets, 7 total revisions
43 $ cd ..
43 $ cd ..
44 $ hg init empty
44 $ hg init empty
45
45
46 Bundle and phase
46 Bundle and phase
47
47
48 $ hg -R test phase --force --secret 0
48 $ hg -R test phase --force --secret 0
49 $ hg -R test bundle phase.hg empty
49 $ hg -R test bundle phase.hg empty
50 searching for changes
50 searching for changes
51 no changes found (ignored 9 secret changesets)
51 no changes found (ignored 9 secret changesets)
52 [1]
52 [1]
53 $ hg -R test phase --draft -r 'head()'
53 $ hg -R test phase --draft -r 'head()'
54
54
55 Bundle --all
55 Bundle --all
56
56
57 $ hg -R test bundle --all all.hg
57 $ hg -R test bundle --all all.hg
58 9 changesets found
58 9 changesets found
59
59
60 Bundle test to full.hg
60 Bundle test to full.hg
61
61
62 $ hg -R test bundle full.hg empty
62 $ hg -R test bundle full.hg empty
63 searching for changes
63 searching for changes
64 9 changesets found
64 9 changesets found
65
65
66 Unbundle full.hg in test
66 Unbundle full.hg in test
67
67
68 $ hg -R test unbundle full.hg
68 $ hg -R test unbundle full.hg
69 adding changesets
69 adding changesets
70 adding manifests
70 adding manifests
71 adding file changes
71 adding file changes
72 added 0 changesets with 0 changes to 4 files
72 added 0 changesets with 0 changes to 4 files
73 (run 'hg update' to get a working copy)
73 (run 'hg update' to get a working copy)
74
74
75 Verify empty
75 Verify empty
76
76
77 $ hg -R empty heads
77 $ hg -R empty heads
78 [1]
78 [1]
79 $ hg -R empty verify
79 $ hg -R empty verify
80 checking changesets
80 checking changesets
81 checking manifests
81 checking manifests
82 crosschecking files in changesets and manifests
82 crosschecking files in changesets and manifests
83 checking files
83 checking files
84 0 files, 0 changesets, 0 total revisions
84 0 files, 0 changesets, 0 total revisions
85
85
86 Pull full.hg into test (using --cwd)
86 Pull full.hg into test (using --cwd)
87
87
88 $ hg --cwd test pull ../full.hg
88 $ hg --cwd test pull ../full.hg
89 pulling from ../full.hg
89 pulling from ../full.hg
90 searching for changes
90 searching for changes
91 no changes found
91 no changes found
92
92
93 Verify that there are no leaked temporary files after pull (issue2797)
93 Verify that there are no leaked temporary files after pull (issue2797)
94
94
95 $ ls test/.hg | grep .hg10un
95 $ ls test/.hg | grep .hg10un
96 [1]
96 [1]
97
97
98 Pull full.hg into empty (using --cwd)
98 Pull full.hg into empty (using --cwd)
99
99
100 $ hg --cwd empty pull ../full.hg
100 $ hg --cwd empty pull ../full.hg
101 pulling from ../full.hg
101 pulling from ../full.hg
102 requesting all changes
102 requesting all changes
103 adding changesets
103 adding changesets
104 adding manifests
104 adding manifests
105 adding file changes
105 adding file changes
106 added 9 changesets with 7 changes to 4 files (+1 heads)
106 added 9 changesets with 7 changes to 4 files (+1 heads)
107 (run 'hg heads' to see heads, 'hg merge' to merge)
107 (run 'hg heads' to see heads, 'hg merge' to merge)
108
108
109 Rollback empty
109 Rollback empty
110
110
111 $ hg -R empty rollback
111 $ hg -R empty rollback
112 repository tip rolled back to revision -1 (undo pull)
112 repository tip rolled back to revision -1 (undo pull)
113
113
114 Pull full.hg into empty again (using --cwd)
114 Pull full.hg into empty again (using --cwd)
115
115
116 $ hg --cwd empty pull ../full.hg
116 $ hg --cwd empty pull ../full.hg
117 pulling from ../full.hg
117 pulling from ../full.hg
118 requesting all changes
118 requesting all changes
119 adding changesets
119 adding changesets
120 adding manifests
120 adding manifests
121 adding file changes
121 adding file changes
122 added 9 changesets with 7 changes to 4 files (+1 heads)
122 added 9 changesets with 7 changes to 4 files (+1 heads)
123 (run 'hg heads' to see heads, 'hg merge' to merge)
123 (run 'hg heads' to see heads, 'hg merge' to merge)
124
124
125 Pull full.hg into test (using -R)
125 Pull full.hg into test (using -R)
126
126
127 $ hg -R test pull full.hg
127 $ hg -R test pull full.hg
128 pulling from full.hg
128 pulling from full.hg
129 searching for changes
129 searching for changes
130 no changes found
130 no changes found
131
131
132 Pull full.hg into empty (using -R)
132 Pull full.hg into empty (using -R)
133
133
134 $ hg -R empty pull full.hg
134 $ hg -R empty pull full.hg
135 pulling from full.hg
135 pulling from full.hg
136 searching for changes
136 searching for changes
137 no changes found
137 no changes found
138
138
139 Rollback empty
139 Rollback empty
140
140
141 $ hg -R empty rollback
141 $ hg -R empty rollback
142 repository tip rolled back to revision -1 (undo pull)
142 repository tip rolled back to revision -1 (undo pull)
143
143
144 Pull full.hg into empty again (using -R)
144 Pull full.hg into empty again (using -R)
145
145
146 $ hg -R empty pull full.hg
146 $ hg -R empty pull full.hg
147 pulling from full.hg
147 pulling from full.hg
148 requesting all changes
148 requesting all changes
149 adding changesets
149 adding changesets
150 adding manifests
150 adding manifests
151 adding file changes
151 adding file changes
152 added 9 changesets with 7 changes to 4 files (+1 heads)
152 added 9 changesets with 7 changes to 4 files (+1 heads)
153 (run 'hg heads' to see heads, 'hg merge' to merge)
153 (run 'hg heads' to see heads, 'hg merge' to merge)
154
154
155 Log -R full.hg in fresh empty
155 Log -R full.hg in fresh empty
156
156
157 $ rm -r empty
157 $ rm -r empty
158 $ hg init empty
158 $ hg init empty
159 $ cd empty
159 $ cd empty
160 $ hg -R bundle://../full.hg log
160 $ hg -R bundle://../full.hg log
161 changeset: 8:aa35859c02ea
161 changeset: 8:aa35859c02ea
162 tag: tip
162 tag: tip
163 parent: 3:eebf5a27f8ca
163 parent: 3:eebf5a27f8ca
164 user: test
164 user: test
165 date: Thu Jan 01 00:00:00 1970 +0000
165 date: Thu Jan 01 00:00:00 1970 +0000
166 summary: 0.3m
166 summary: 0.3m
167
167
168 changeset: 7:a6a34bfa0076
168 changeset: 7:a6a34bfa0076
169 user: test
169 user: test
170 date: Thu Jan 01 00:00:00 1970 +0000
170 date: Thu Jan 01 00:00:00 1970 +0000
171 summary: 1.3m
171 summary: 1.3m
172
172
173 changeset: 6:7373c1169842
173 changeset: 6:7373c1169842
174 user: test
174 user: test
175 date: Thu Jan 01 00:00:00 1970 +0000
175 date: Thu Jan 01 00:00:00 1970 +0000
176 summary: 1.3
176 summary: 1.3
177
177
178 changeset: 5:1bb50a9436a7
178 changeset: 5:1bb50a9436a7
179 user: test
179 user: test
180 date: Thu Jan 01 00:00:00 1970 +0000
180 date: Thu Jan 01 00:00:00 1970 +0000
181 summary: 1.2
181 summary: 1.2
182
182
183 changeset: 4:095197eb4973
183 changeset: 4:095197eb4973
184 parent: 0:f9ee2f85a263
184 parent: 0:f9ee2f85a263
185 user: test
185 user: test
186 date: Thu Jan 01 00:00:00 1970 +0000
186 date: Thu Jan 01 00:00:00 1970 +0000
187 summary: 1.1
187 summary: 1.1
188
188
189 changeset: 3:eebf5a27f8ca
189 changeset: 3:eebf5a27f8ca
190 user: test
190 user: test
191 date: Thu Jan 01 00:00:00 1970 +0000
191 date: Thu Jan 01 00:00:00 1970 +0000
192 summary: 0.3
192 summary: 0.3
193
193
194 changeset: 2:e38ba6f5b7e0
194 changeset: 2:e38ba6f5b7e0
195 user: test
195 user: test
196 date: Thu Jan 01 00:00:00 1970 +0000
196 date: Thu Jan 01 00:00:00 1970 +0000
197 summary: 0.2
197 summary: 0.2
198
198
199 changeset: 1:34c2bf6b0626
199 changeset: 1:34c2bf6b0626
200 user: test
200 user: test
201 date: Thu Jan 01 00:00:00 1970 +0000
201 date: Thu Jan 01 00:00:00 1970 +0000
202 summary: 0.1
202 summary: 0.1
203
203
204 changeset: 0:f9ee2f85a263
204 changeset: 0:f9ee2f85a263
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: 0.0
207 summary: 0.0
208
208
209 Make sure bundlerepo doesn't leak tempfiles (issue2491)
209 Make sure bundlerepo doesn't leak tempfiles (issue2491)
210
210
211 $ ls .hg
211 $ ls .hg
212 00changelog.i
212 00changelog.i
213 cache
213 cache
214 requires
214 requires
215 store
215 store
216
216
217 Pull ../full.hg into empty (with hook)
217 Pull ../full.hg into empty (with hook)
218
218
219 $ echo "[hooks]" >> .hg/hgrc
219 $ echo "[hooks]" >> .hg/hgrc
220 $ echo "changegroup = printenv.py changegroup" >> .hg/hgrc
220 $ echo "changegroup = printenv.py changegroup" >> .hg/hgrc
221
221
222 doesn't work (yet ?)
222 doesn't work (yet ?)
223
223
224 hg -R bundle://../full.hg verify
224 hg -R bundle://../full.hg verify
225
225
226 $ hg pull bundle://../full.hg
226 $ hg pull bundle://../full.hg
227 pulling from bundle:../full.hg
227 pulling from bundle:../full.hg
228 requesting all changes
228 requesting all changes
229 adding changesets
229 adding changesets
230 adding manifests
230 adding manifests
231 adding file changes
231 adding file changes
232 added 9 changesets with 7 changes to 4 files (+1 heads)
232 added 9 changesets with 7 changes to 4 files (+1 heads)
233 changegroup hook: HG_NODE=f9ee2f85a263049e9ae6d37a0e67e96194ffb735 HG_NODE_LAST=aa35859c02ea8bd48da5da68cd2740ac71afcbaf HG_SOURCE=pull HG_TXNID=TXN:* HG_URL=bundle:../full.hg (glob)
233 changegroup hook: HG_NODE=f9ee2f85a263049e9ae6d37a0e67e96194ffb735 HG_NODE_LAST=aa35859c02ea8bd48da5da68cd2740ac71afcbaf HG_SOURCE=pull HG_TXNID=TXN:* HG_URL=bundle:../full.hg (glob)
234 (run 'hg heads' to see heads, 'hg merge' to merge)
234 (run 'hg heads' to see heads, 'hg merge' to merge)
235
235
236 Rollback empty
236 Rollback empty
237
237
238 $ hg rollback
238 $ hg rollback
239 repository tip rolled back to revision -1 (undo pull)
239 repository tip rolled back to revision -1 (undo pull)
240 $ cd ..
240 $ cd ..
241
241
242 Log -R bundle:empty+full.hg
242 Log -R bundle:empty+full.hg
243
243
244 $ hg -R bundle:empty+full.hg log --template="{rev} "; echo ""
244 $ hg -R bundle:empty+full.hg log --template="{rev} "; echo ""
245 8 7 6 5 4 3 2 1 0
245 8 7 6 5 4 3 2 1 0
246
246
247 Pull full.hg into empty again (using -R; with hook)
247 Pull full.hg into empty again (using -R; with hook)
248
248
249 $ hg -R empty pull full.hg
249 $ hg -R empty pull full.hg
250 pulling from full.hg
250 pulling from full.hg
251 requesting all changes
251 requesting all changes
252 adding changesets
252 adding changesets
253 adding manifests
253 adding manifests
254 adding file changes
254 adding file changes
255 added 9 changesets with 7 changes to 4 files (+1 heads)
255 added 9 changesets with 7 changes to 4 files (+1 heads)
256 changegroup hook: HG_NODE=f9ee2f85a263049e9ae6d37a0e67e96194ffb735 HG_NODE_LAST=aa35859c02ea8bd48da5da68cd2740ac71afcbaf HG_SOURCE=pull HG_TXNID=TXN:* HG_URL=bundle:empty+full.hg (glob)
256 changegroup hook: HG_NODE=f9ee2f85a263049e9ae6d37a0e67e96194ffb735 HG_NODE_LAST=aa35859c02ea8bd48da5da68cd2740ac71afcbaf HG_SOURCE=pull HG_TXNID=TXN:* HG_URL=bundle:empty+full.hg (glob)
257 (run 'hg heads' to see heads, 'hg merge' to merge)
257 (run 'hg heads' to see heads, 'hg merge' to merge)
258
258
259 Cannot produce streaming clone bundles with "hg bundle"
259 Cannot produce streaming clone bundles with "hg bundle"
260
260
261 $ hg -R test bundle -t packed1 packed.hg
261 $ hg -R test bundle -t packed1 packed.hg
262 abort: packed bundles cannot be produced by "hg bundle"
262 abort: packed bundles cannot be produced by "hg bundle"
263 (use 'hg debugcreatestreamclonebundle')
263 (use 'hg debugcreatestreamclonebundle')
264 [255]
264 [255]
265
265
266 packed1 is produced properly
266 packed1 is produced properly
267
267
268 $ hg -R test debugcreatestreamclonebundle packed.hg
268 $ hg -R test debugcreatestreamclonebundle packed.hg
269 writing 2663 bytes for 6 files
269 writing 2663 bytes for 6 files
270 bundle requirements: generaldelta, revlogv1
270 bundle requirements: generaldelta, revlogv1
271
271
272 $ f -B 64 --size --sha1 --hexdump packed.hg
272 $ f -B 64 --size --sha1 --hexdump packed.hg
273 packed.hg: size=2826, sha1=e139f97692a142b19cdcff64a69697d5307ce6d4
273 packed.hg: size=2826, sha1=e139f97692a142b19cdcff64a69697d5307ce6d4
274 0000: 48 47 53 31 55 4e 00 00 00 00 00 00 00 06 00 00 |HGS1UN..........|
274 0000: 48 47 53 31 55 4e 00 00 00 00 00 00 00 06 00 00 |HGS1UN..........|
275 0010: 00 00 00 00 0a 67 00 16 67 65 6e 65 72 61 6c 64 |.....g..generald|
275 0010: 00 00 00 00 0a 67 00 16 67 65 6e 65 72 61 6c 64 |.....g..generald|
276 0020: 65 6c 74 61 2c 72 65 76 6c 6f 67 76 31 00 64 61 |elta,revlogv1.da|
276 0020: 65 6c 74 61 2c 72 65 76 6c 6f 67 76 31 00 64 61 |elta,revlogv1.da|
277 0030: 74 61 2f 61 64 69 66 66 65 72 65 6e 74 66 69 6c |ta/adifferentfil|
277 0030: 74 61 2f 61 64 69 66 66 65 72 65 6e 74 66 69 6c |ta/adifferentfil|
278
278
279 $ hg debugbundle --spec packed.hg
279 $ hg debugbundle --spec packed.hg
280 none-packed1;requirements%3Dgeneraldelta%2Crevlogv1
280 none-packed1;requirements%3Dgeneraldelta%2Crevlogv1
281
281
282 generaldelta requirement is listed in stream clone bundles
282 generaldelta requirement is listed in stream clone bundles
283
283
284 $ hg --config format.generaldelta=true init testgd
284 $ hg --config format.generaldelta=true init testgd
285 $ cd testgd
285 $ cd testgd
286 $ touch foo
286 $ touch foo
287 $ hg -q commit -A -m initial
287 $ hg -q commit -A -m initial
288 $ cd ..
288 $ cd ..
289 $ hg -R testgd debugcreatestreamclonebundle packedgd.hg
289 $ hg -R testgd debugcreatestreamclonebundle packedgd.hg
290 writing 301 bytes for 3 files
290 writing 301 bytes for 3 files
291 bundle requirements: generaldelta, revlogv1
291 bundle requirements: generaldelta, revlogv1
292
292
293 $ f -B 64 --size --sha1 --hexdump packedgd.hg
293 $ f -B 64 --size --sha1 --hexdump packedgd.hg
294 packedgd.hg: size=396, sha1=981f9e589799335304a5a9a44caa3623a48d2a9f
294 packedgd.hg: size=396, sha1=981f9e589799335304a5a9a44caa3623a48d2a9f
295 0000: 48 47 53 31 55 4e 00 00 00 00 00 00 00 03 00 00 |HGS1UN..........|
295 0000: 48 47 53 31 55 4e 00 00 00 00 00 00 00 03 00 00 |HGS1UN..........|
296 0010: 00 00 00 00 01 2d 00 16 67 65 6e 65 72 61 6c 64 |.....-..generald|
296 0010: 00 00 00 00 01 2d 00 16 67 65 6e 65 72 61 6c 64 |.....-..generald|
297 0020: 65 6c 74 61 2c 72 65 76 6c 6f 67 76 31 00 64 61 |elta,revlogv1.da|
297 0020: 65 6c 74 61 2c 72 65 76 6c 6f 67 76 31 00 64 61 |elta,revlogv1.da|
298 0030: 74 61 2f 66 6f 6f 2e 69 00 36 34 0a 00 03 00 01 |ta/foo.i.64.....|
298 0030: 74 61 2f 66 6f 6f 2e 69 00 36 34 0a 00 03 00 01 |ta/foo.i.64.....|
299
299
300 $ hg debugbundle --spec packedgd.hg
300 $ hg debugbundle --spec packedgd.hg
301 none-packed1;requirements%3Dgeneraldelta%2Crevlogv1
301 none-packed1;requirements%3Dgeneraldelta%2Crevlogv1
302
302
303 Unpacking packed1 bundles with "hg unbundle" isn't allowed
303 Unpacking packed1 bundles with "hg unbundle" isn't allowed
304
304
305 $ hg init packed
305 $ hg init packed
306 $ hg -R packed unbundle packed.hg
306 $ hg -R packed unbundle packed.hg
307 abort: packed bundles cannot be applied with "hg unbundle"
307 abort: packed bundles cannot be applied with "hg unbundle"
308 (use "hg debugapplystreamclonebundle")
308 (use "hg debugapplystreamclonebundle")
309 [255]
309 [255]
310
310
311 packed1 can be consumed from debug command
311 packed1 can be consumed from debug command
312
312
313 $ hg -R packed debugapplystreamclonebundle packed.hg
313 $ hg -R packed debugapplystreamclonebundle packed.hg
314 6 files to transfer, 2.60 KB of data
314 6 files to transfer, 2.60 KB of data
315 transferred 2.60 KB in *.* seconds (* */sec) (glob)
315 transferred 2.60 KB in *.* seconds (* */sec) (glob)
316
316
317 Does not work on non-empty repo
317 Does not work on non-empty repo
318
318
319 $ hg -R packed debugapplystreamclonebundle packed.hg
319 $ hg -R packed debugapplystreamclonebundle packed.hg
320 abort: cannot apply stream clone bundle on non-empty repo
320 abort: cannot apply stream clone bundle on non-empty repo
321 [255]
321 [255]
322
322
323 Create partial clones
323 Create partial clones
324
324
325 $ rm -r empty
325 $ rm -r empty
326 $ hg init empty
326 $ hg init empty
327 $ hg clone -r 3 test partial
327 $ hg clone -r 3 test partial
328 adding changesets
328 adding changesets
329 adding manifests
329 adding manifests
330 adding file changes
330 adding file changes
331 added 4 changesets with 4 changes to 1 files
331 added 4 changesets with 4 changes to 1 files
332 updating to branch default
332 updating to branch default
333 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
333 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
334 $ hg clone partial partial2
334 $ hg clone partial partial2
335 updating to branch default
335 updating to branch default
336 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
336 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
337 $ cd partial
337 $ cd partial
338
338
339 Log -R full.hg in partial
339 Log -R full.hg in partial
340
340
341 $ hg -R bundle://../full.hg log -T phases
341 $ hg -R bundle://../full.hg log -T phases
342 changeset: 8:aa35859c02ea
342 changeset: 8:aa35859c02ea
343 tag: tip
343 tag: tip
344 phase: draft
344 phase: draft
345 parent: 3:eebf5a27f8ca
345 parent: 3:eebf5a27f8ca
346 user: test
346 user: test
347 date: Thu Jan 01 00:00:00 1970 +0000
347 date: Thu Jan 01 00:00:00 1970 +0000
348 summary: 0.3m
348 summary: 0.3m
349
349
350 changeset: 7:a6a34bfa0076
350 changeset: 7:a6a34bfa0076
351 phase: draft
351 phase: draft
352 user: test
352 user: test
353 date: Thu Jan 01 00:00:00 1970 +0000
353 date: Thu Jan 01 00:00:00 1970 +0000
354 summary: 1.3m
354 summary: 1.3m
355
355
356 changeset: 6:7373c1169842
356 changeset: 6:7373c1169842
357 phase: draft
357 phase: draft
358 user: test
358 user: test
359 date: Thu Jan 01 00:00:00 1970 +0000
359 date: Thu Jan 01 00:00:00 1970 +0000
360 summary: 1.3
360 summary: 1.3
361
361
362 changeset: 5:1bb50a9436a7
362 changeset: 5:1bb50a9436a7
363 phase: draft
363 phase: draft
364 user: test
364 user: test
365 date: Thu Jan 01 00:00:00 1970 +0000
365 date: Thu Jan 01 00:00:00 1970 +0000
366 summary: 1.2
366 summary: 1.2
367
367
368 changeset: 4:095197eb4973
368 changeset: 4:095197eb4973
369 phase: draft
369 phase: draft
370 parent: 0:f9ee2f85a263
370 parent: 0:f9ee2f85a263
371 user: test
371 user: test
372 date: Thu Jan 01 00:00:00 1970 +0000
372 date: Thu Jan 01 00:00:00 1970 +0000
373 summary: 1.1
373 summary: 1.1
374
374
375 changeset: 3:eebf5a27f8ca
375 changeset: 3:eebf5a27f8ca
376 phase: public
376 phase: public
377 user: test
377 user: test
378 date: Thu Jan 01 00:00:00 1970 +0000
378 date: Thu Jan 01 00:00:00 1970 +0000
379 summary: 0.3
379 summary: 0.3
380
380
381 changeset: 2:e38ba6f5b7e0
381 changeset: 2:e38ba6f5b7e0
382 phase: public
382 phase: public
383 user: test
383 user: test
384 date: Thu Jan 01 00:00:00 1970 +0000
384 date: Thu Jan 01 00:00:00 1970 +0000
385 summary: 0.2
385 summary: 0.2
386
386
387 changeset: 1:34c2bf6b0626
387 changeset: 1:34c2bf6b0626
388 phase: public
388 phase: public
389 user: test
389 user: test
390 date: Thu Jan 01 00:00:00 1970 +0000
390 date: Thu Jan 01 00:00:00 1970 +0000
391 summary: 0.1
391 summary: 0.1
392
392
393 changeset: 0:f9ee2f85a263
393 changeset: 0:f9ee2f85a263
394 phase: public
394 phase: public
395 user: test
395 user: test
396 date: Thu Jan 01 00:00:00 1970 +0000
396 date: Thu Jan 01 00:00:00 1970 +0000
397 summary: 0.0
397 summary: 0.0
398
398
399
399
400 Incoming full.hg in partial
400 Incoming full.hg in partial
401
401
402 $ hg incoming bundle://../full.hg
402 $ hg incoming bundle://../full.hg
403 comparing with bundle:../full.hg
403 comparing with bundle:../full.hg
404 searching for changes
404 searching for changes
405 changeset: 4:095197eb4973
405 changeset: 4:095197eb4973
406 parent: 0:f9ee2f85a263
406 parent: 0:f9ee2f85a263
407 user: test
407 user: test
408 date: Thu Jan 01 00:00:00 1970 +0000
408 date: Thu Jan 01 00:00:00 1970 +0000
409 summary: 1.1
409 summary: 1.1
410
410
411 changeset: 5:1bb50a9436a7
411 changeset: 5:1bb50a9436a7
412 user: test
412 user: test
413 date: Thu Jan 01 00:00:00 1970 +0000
413 date: Thu Jan 01 00:00:00 1970 +0000
414 summary: 1.2
414 summary: 1.2
415
415
416 changeset: 6:7373c1169842
416 changeset: 6:7373c1169842
417 user: test
417 user: test
418 date: Thu Jan 01 00:00:00 1970 +0000
418 date: Thu Jan 01 00:00:00 1970 +0000
419 summary: 1.3
419 summary: 1.3
420
420
421 changeset: 7:a6a34bfa0076
421 changeset: 7:a6a34bfa0076
422 user: test
422 user: test
423 date: Thu Jan 01 00:00:00 1970 +0000
423 date: Thu Jan 01 00:00:00 1970 +0000
424 summary: 1.3m
424 summary: 1.3m
425
425
426 changeset: 8:aa35859c02ea
426 changeset: 8:aa35859c02ea
427 tag: tip
427 tag: tip
428 parent: 3:eebf5a27f8ca
428 parent: 3:eebf5a27f8ca
429 user: test
429 user: test
430 date: Thu Jan 01 00:00:00 1970 +0000
430 date: Thu Jan 01 00:00:00 1970 +0000
431 summary: 0.3m
431 summary: 0.3m
432
432
433
433
434 Outgoing -R full.hg vs partial2 in partial
434 Outgoing -R full.hg vs partial2 in partial
435
435
436 $ hg -R bundle://../full.hg outgoing ../partial2
436 $ hg -R bundle://../full.hg outgoing ../partial2
437 comparing with ../partial2
437 comparing with ../partial2
438 searching for changes
438 searching for changes
439 changeset: 4:095197eb4973
439 changeset: 4:095197eb4973
440 parent: 0:f9ee2f85a263
440 parent: 0:f9ee2f85a263
441 user: test
441 user: test
442 date: Thu Jan 01 00:00:00 1970 +0000
442 date: Thu Jan 01 00:00:00 1970 +0000
443 summary: 1.1
443 summary: 1.1
444
444
445 changeset: 5:1bb50a9436a7
445 changeset: 5:1bb50a9436a7
446 user: test
446 user: test
447 date: Thu Jan 01 00:00:00 1970 +0000
447 date: Thu Jan 01 00:00:00 1970 +0000
448 summary: 1.2
448 summary: 1.2
449
449
450 changeset: 6:7373c1169842
450 changeset: 6:7373c1169842
451 user: test
451 user: test
452 date: Thu Jan 01 00:00:00 1970 +0000
452 date: Thu Jan 01 00:00:00 1970 +0000
453 summary: 1.3
453 summary: 1.3
454
454
455 changeset: 7:a6a34bfa0076
455 changeset: 7:a6a34bfa0076
456 user: test
456 user: test
457 date: Thu Jan 01 00:00:00 1970 +0000
457 date: Thu Jan 01 00:00:00 1970 +0000
458 summary: 1.3m
458 summary: 1.3m
459
459
460 changeset: 8:aa35859c02ea
460 changeset: 8:aa35859c02ea
461 tag: tip
461 tag: tip
462 parent: 3:eebf5a27f8ca
462 parent: 3:eebf5a27f8ca
463 user: test
463 user: test
464 date: Thu Jan 01 00:00:00 1970 +0000
464 date: Thu Jan 01 00:00:00 1970 +0000
465 summary: 0.3m
465 summary: 0.3m
466
466
467
467
468 Outgoing -R does-not-exist.hg vs partial2 in partial
468 Outgoing -R does-not-exist.hg vs partial2 in partial
469
469
470 $ hg -R bundle://../does-not-exist.hg outgoing ../partial2
470 $ hg -R bundle://../does-not-exist.hg outgoing ../partial2
471 abort: *../does-not-exist.hg* (glob)
471 abort: *../does-not-exist.hg* (glob)
472 [255]
472 [255]
473 $ cd ..
473 $ cd ..
474
474
475 hide outer repo
475 hide outer repo
476 $ hg init
476 $ hg init
477
477
478 Direct clone from bundle (all-history)
478 Direct clone from bundle (all-history)
479
479
480 $ hg clone full.hg full-clone
480 $ hg clone full.hg full-clone
481 requesting all changes
481 requesting all changes
482 adding changesets
482 adding changesets
483 adding manifests
483 adding manifests
484 adding file changes
484 adding file changes
485 added 9 changesets with 7 changes to 4 files (+1 heads)
485 added 9 changesets with 7 changes to 4 files (+1 heads)
486 updating to branch default
486 updating to branch default
487 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
487 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
488 $ hg -R full-clone heads
488 $ hg -R full-clone heads
489 changeset: 8:aa35859c02ea
489 changeset: 8:aa35859c02ea
490 tag: tip
490 tag: tip
491 parent: 3:eebf5a27f8ca
491 parent: 3:eebf5a27f8ca
492 user: test
492 user: test
493 date: Thu Jan 01 00:00:00 1970 +0000
493 date: Thu Jan 01 00:00:00 1970 +0000
494 summary: 0.3m
494 summary: 0.3m
495
495
496 changeset: 7:a6a34bfa0076
496 changeset: 7:a6a34bfa0076
497 user: test
497 user: test
498 date: Thu Jan 01 00:00:00 1970 +0000
498 date: Thu Jan 01 00:00:00 1970 +0000
499 summary: 1.3m
499 summary: 1.3m
500
500
501 $ rm -r full-clone
501 $ rm -r full-clone
502
502
503 When cloning from a non-copiable repository into '', do not
503 When cloning from a non-copiable repository into '', do not
504 recurse infinitely (issue2528)
504 recurse infinitely (issue2528)
505
505
506 $ hg clone full.hg ''
506 $ hg clone full.hg ''
507 abort: empty destination path is not valid
507 abort: empty destination path is not valid
508 [255]
508 [255]
509
509
510 test for https://bz.mercurial-scm.org/216
510 test for https://bz.mercurial-scm.org/216
511
511
512 Unbundle incremental bundles into fresh empty in one go
512 Unbundle incremental bundles into fresh empty in one go
513
513
514 $ rm -r empty
514 $ rm -r empty
515 $ hg init empty
515 $ hg init empty
516 $ hg -R test bundle --base null -r 0 ../0.hg
516 $ hg -R test bundle --base null -r 0 ../0.hg
517 1 changesets found
517 1 changesets found
518 $ hg -R test bundle --base 0 -r 1 ../1.hg
518 $ hg -R test bundle --base 0 -r 1 ../1.hg
519 1 changesets found
519 1 changesets found
520 $ hg -R empty unbundle -u ../0.hg ../1.hg
520 $ hg -R empty unbundle -u ../0.hg ../1.hg
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
524 added 1 changesets with 1 changes to 1 files
525 adding changesets
525 adding changesets
526 adding manifests
526 adding manifests
527 adding file changes
527 adding file changes
528 added 1 changesets with 1 changes to 1 files
528 added 1 changesets with 1 changes to 1 files
529 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
529 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
530
530
531 View full contents of the bundle
531 View full contents of the bundle
532 $ hg -R test bundle --base null -r 3 ../partial.hg
532 $ hg -R test bundle --base null -r 3 ../partial.hg
533 4 changesets found
533 4 changesets found
534 $ cd test
534 $ cd test
535 $ hg -R ../../partial.hg log -r "bundle()"
535 $ hg -R ../../partial.hg log -r "bundle()"
536 changeset: 0:f9ee2f85a263
536 changeset: 0:f9ee2f85a263
537 user: test
537 user: test
538 date: Thu Jan 01 00:00:00 1970 +0000
538 date: Thu Jan 01 00:00:00 1970 +0000
539 summary: 0.0
539 summary: 0.0
540
540
541 changeset: 1:34c2bf6b0626
541 changeset: 1:34c2bf6b0626
542 user: test
542 user: test
543 date: Thu Jan 01 00:00:00 1970 +0000
543 date: Thu Jan 01 00:00:00 1970 +0000
544 summary: 0.1
544 summary: 0.1
545
545
546 changeset: 2:e38ba6f5b7e0
546 changeset: 2:e38ba6f5b7e0
547 user: test
547 user: test
548 date: Thu Jan 01 00:00:00 1970 +0000
548 date: Thu Jan 01 00:00:00 1970 +0000
549 summary: 0.2
549 summary: 0.2
550
550
551 changeset: 3:eebf5a27f8ca
551 changeset: 3:eebf5a27f8ca
552 user: test
552 user: test
553 date: Thu Jan 01 00:00:00 1970 +0000
553 date: Thu Jan 01 00:00:00 1970 +0000
554 summary: 0.3
554 summary: 0.3
555
555
556 $ cd ..
556 $ cd ..
557
557
558 test for 540d1059c802
558 test for 540d1059c802
559
559
560 test for 540d1059c802
560 test for 540d1059c802
561
561
562 $ hg init orig
562 $ hg init orig
563 $ cd orig
563 $ cd orig
564 $ echo foo > foo
564 $ echo foo > foo
565 $ hg add foo
565 $ hg add foo
566 $ hg ci -m 'add foo'
566 $ hg ci -m 'add foo'
567
567
568 $ hg clone . ../copy
568 $ hg clone . ../copy
569 updating to branch default
569 updating to branch default
570 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
570 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
571 $ hg tag foo
571 $ hg tag foo
572
572
573 $ cd ../copy
573 $ cd ../copy
574 $ echo >> foo
574 $ echo >> foo
575 $ hg ci -m 'change foo'
575 $ hg ci -m 'change foo'
576 $ hg bundle ../bundle.hg ../orig
576 $ hg bundle ../bundle.hg ../orig
577 searching for changes
577 searching for changes
578 1 changesets found
578 1 changesets found
579
579
580 $ cd ../orig
580 $ cd ../orig
581 $ hg incoming ../bundle.hg
581 $ hg incoming ../bundle.hg
582 comparing with ../bundle.hg
582 comparing with ../bundle.hg
583 searching for changes
583 searching for changes
584 changeset: 2:ed1b79f46b9a
584 changeset: 2:ed1b79f46b9a
585 tag: tip
585 tag: tip
586 parent: 0:bbd179dfa0a7
586 parent: 0:bbd179dfa0a7
587 user: test
587 user: test
588 date: Thu Jan 01 00:00:00 1970 +0000
588 date: Thu Jan 01 00:00:00 1970 +0000
589 summary: change foo
589 summary: change foo
590
590
591 $ cd ..
591 $ cd ..
592
592
593 test bundle with # in the filename (issue2154):
593 test bundle with # in the filename (issue2154):
594
594
595 $ cp bundle.hg 'test#bundle.hg'
595 $ cp bundle.hg 'test#bundle.hg'
596 $ cd orig
596 $ cd orig
597 $ hg incoming '../test#bundle.hg'
597 $ hg incoming '../test#bundle.hg'
598 comparing with ../test
598 comparing with ../test
599 abort: unknown revision 'bundle.hg'!
599 abort: unknown revision 'bundle.hg'!
600 [255]
600 [255]
601
601
602 note that percent encoding is not handled:
602 note that percent encoding is not handled:
603
603
604 $ hg incoming ../test%23bundle.hg
604 $ hg incoming ../test%23bundle.hg
605 abort: repository ../test%23bundle.hg not found!
605 abort: repository ../test%23bundle.hg not found!
606 [255]
606 [255]
607 $ cd ..
607 $ cd ..
608
608
609 test to bundle revisions on the newly created branch (issue3828):
609 test to bundle revisions on the newly created branch (issue3828):
610
610
611 $ hg -q clone -U test test-clone
611 $ hg -q clone -U test test-clone
612 $ cd test
612 $ cd test
613
613
614 $ hg -q branch foo
614 $ hg -q branch foo
615 $ hg commit -m "create foo branch"
615 $ hg commit -m "create foo branch"
616 $ hg -q outgoing ../test-clone
616 $ hg -q outgoing ../test-clone
617 9:b4f5acb1ee27
617 9:b4f5acb1ee27
618 $ hg -q bundle --branch foo foo.hg ../test-clone
618 $ hg -q bundle --branch foo foo.hg ../test-clone
619 $ hg -R foo.hg -q log -r "bundle()"
619 $ hg -R foo.hg -q log -r "bundle()"
620 9:b4f5acb1ee27
620 9:b4f5acb1ee27
621
621
622 $ cd ..
622 $ cd ..
623
623
624 test for https://bz.mercurial-scm.org/1144
624 test for https://bz.mercurial-scm.org/1144
625
625
626 test that verify bundle does not traceback
626 test that verify bundle does not traceback
627
627
628 partial history bundle, fails w/ unknown parent
628 partial history bundle, fails w/ unknown parent
629
629
630 $ hg -R bundle.hg verify
630 $ hg -R bundle.hg verify
631 abort: 00changelog.i@bbd179dfa0a7: unknown parent!
631 abort: 00changelog.i@bbd179dfa0a7: unknown parent!
632 [255]
632 [255]
633
633
634 full history bundle, refuses to verify non-local repo
634 full history bundle, refuses to verify non-local repo
635
635
636 $ hg -R all.hg verify
636 $ hg -R all.hg verify
637 abort: cannot verify bundle or remote repos
637 abort: cannot verify bundle or remote repos
638 [255]
638 [255]
639
639
640 but, regular verify must continue to work
640 but, regular verify must continue to work
641
641
642 $ hg -R orig verify
642 $ hg -R orig verify
643 checking changesets
643 checking changesets
644 checking manifests
644 checking manifests
645 crosschecking files in changesets and manifests
645 crosschecking files in changesets and manifests
646 checking files
646 checking files
647 2 files, 2 changesets, 2 total revisions
647 2 files, 2 changesets, 2 total revisions
648
648
649 diff against bundle
649 diff against bundle
650
650
651 $ hg init b
651 $ hg init b
652 $ cd b
652 $ cd b
653 $ hg -R ../all.hg diff -r tip
653 $ hg -R ../all.hg diff -r tip
654 diff -r aa35859c02ea anotherfile
654 diff -r aa35859c02ea anotherfile
655 --- a/anotherfile Thu Jan 01 00:00:00 1970 +0000
655 --- a/anotherfile Thu Jan 01 00:00:00 1970 +0000
656 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
656 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
657 @@ -1,4 +0,0 @@
657 @@ -1,4 +0,0 @@
658 -0
658 -0
659 -1
659 -1
660 -2
660 -2
661 -3
661 -3
662 $ cd ..
662 $ cd ..
663
663
664 bundle single branch
664 bundle single branch
665
665
666 $ hg init branchy
666 $ hg init branchy
667 $ cd branchy
667 $ cd branchy
668 $ echo a >a
668 $ echo a >a
669 $ echo x >x
669 $ echo x >x
670 $ hg ci -Ama
670 $ hg ci -Ama
671 adding a
671 adding a
672 adding x
672 adding x
673 $ echo c >c
673 $ echo c >c
674 $ echo xx >x
674 $ echo xx >x
675 $ hg ci -Amc
675 $ hg ci -Amc
676 adding c
676 adding c
677 $ echo c1 >c1
677 $ echo c1 >c1
678 $ hg ci -Amc1
678 $ hg ci -Amc1
679 adding c1
679 adding c1
680 $ hg up 0
680 $ hg up 0
681 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
681 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
682 $ echo b >b
682 $ echo b >b
683 $ hg ci -Amb
683 $ hg ci -Amb
684 adding b
684 adding b
685 created new head
685 created new head
686 $ echo b1 >b1
686 $ echo b1 >b1
687 $ echo xx >x
687 $ echo xx >x
688 $ hg ci -Amb1
688 $ hg ci -Amb1
689 adding b1
689 adding b1
690 $ hg clone -q -r2 . part
690 $ hg clone -q -r2 . part
691
691
692 == bundling via incoming
692 == bundling via incoming
693
693
694 $ hg in -R part --bundle incoming.hg --template "{node}\n" .
694 $ hg in -R part --bundle incoming.hg --template "{node}\n" .
695 comparing with .
695 comparing with .
696 searching for changes
696 searching for changes
697 1a38c1b849e8b70c756d2d80b0b9a3ac0b7ea11a
697 1a38c1b849e8b70c756d2d80b0b9a3ac0b7ea11a
698 057f4db07f61970e1c11e83be79e9d08adc4dc31
698 057f4db07f61970e1c11e83be79e9d08adc4dc31
699
699
700 == bundling
700 == bundling
701
701
702 $ hg bundle bundle.hg part --debug --config progress.debug=true
702 $ hg bundle bundle.hg part --debug --config progress.debug=true
703 query 1; heads
703 query 1; heads
704 searching for changes
704 searching for changes
705 all remote heads known locally
705 all remote heads known locally
706 2 changesets found
706 2 changesets found
707 list of changesets:
707 list of changesets:
708 1a38c1b849e8b70c756d2d80b0b9a3ac0b7ea11a
708 1a38c1b849e8b70c756d2d80b0b9a3ac0b7ea11a
709 057f4db07f61970e1c11e83be79e9d08adc4dc31
709 057f4db07f61970e1c11e83be79e9d08adc4dc31
710 bundle2-output-bundle: "HG20", (1 params) 1 parts total
710 bundle2-output-bundle: "HG20", (1 params) 1 parts total
711 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
711 bundle2-output-part: "changegroup" (params: 1 mandatory 1 advisory) streamed payload
712 bundling: 1/2 changesets (50.00%)
712 bundling: 1/2 changesets (50.00%)
713 bundling: 2/2 changesets (100.00%)
713 bundling: 2/2 changesets (100.00%)
714 bundling: 1/2 manifests (50.00%)
714 bundling: 1/2 manifests (50.00%)
715 bundling: 2/2 manifests (100.00%)
715 bundling: 2/2 manifests (100.00%)
716 bundling: b 1/3 files (33.33%)
716 bundling: b 1/3 files (33.33%)
717 bundling: b1 2/3 files (66.67%)
717 bundling: b1 2/3 files (66.67%)
718 bundling: x 3/3 files (100.00%)
718 bundling: x 3/3 files (100.00%)
719
719
720 == Test for issue3441
720 == Test for issue3441
721
721
722 $ hg clone -q -r0 . part2
722 $ hg clone -q -r0 . part2
723 $ hg -q -R part2 pull bundle.hg
723 $ hg -q -R part2 pull bundle.hg
724 $ hg -R part2 verify
724 $ hg -R part2 verify
725 checking changesets
725 checking changesets
726 checking manifests
726 checking manifests
727 crosschecking files in changesets and manifests
727 crosschecking files in changesets and manifests
728 checking files
728 checking files
729 4 files, 3 changesets, 5 total revisions
729 4 files, 3 changesets, 5 total revisions
730
730
731 == Test bundling no commits
731 == Test bundling no commits
732
732
733 $ hg bundle -r 'public()' no-output.hg
733 $ hg bundle -r 'public()' no-output.hg
734 abort: no commits to bundle
734 abort: no commits to bundle
735 [255]
735 [255]
736
736
737 $ cd ..
737 $ cd ..
738
738
739 When user merges to the revision existing only in the bundle,
739 When user merges to the revision existing only in the bundle,
740 it should show warning that second parent of the working
740 it should show warning that second parent of the working
741 directory does not exist
741 directory does not exist
742
742
743 $ hg init update2bundled
743 $ hg init update2bundled
744 $ cd update2bundled
744 $ cd update2bundled
745 $ cat <<EOF >> .hg/hgrc
745 $ cat <<EOF >> .hg/hgrc
746 > [extensions]
746 > [extensions]
747 > strip =
747 > strip =
748 > EOF
748 > EOF
749 $ echo "aaa" >> a
749 $ echo "aaa" >> a
750 $ hg commit -A -m 0
750 $ hg commit -A -m 0
751 adding a
751 adding a
752 $ echo "bbb" >> b
752 $ echo "bbb" >> b
753 $ hg commit -A -m 1
753 $ hg commit -A -m 1
754 adding b
754 adding b
755 $ echo "ccc" >> c
755 $ echo "ccc" >> c
756 $ hg commit -A -m 2
756 $ hg commit -A -m 2
757 adding c
757 adding c
758 $ hg update -r 1
758 $ hg update -r 1
759 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
759 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
760 $ echo "ddd" >> d
760 $ echo "ddd" >> d
761 $ hg commit -A -m 3
761 $ hg commit -A -m 3
762 adding d
762 adding d
763 created new head
763 created new head
764 $ hg update -r 2
764 $ hg update -r 2
765 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
765 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
766 $ hg log -G
766 $ hg log -G
767 o changeset: 3:8bd3e1f196af
767 o changeset: 3:8bd3e1f196af
768 | tag: tip
768 | tag: tip
769 | parent: 1:a01eca7af26d
769 | parent: 1:a01eca7af26d
770 | user: test
770 | user: test
771 | date: Thu Jan 01 00:00:00 1970 +0000
771 | date: Thu Jan 01 00:00:00 1970 +0000
772 | summary: 3
772 | summary: 3
773 |
773 |
774 | @ changeset: 2:4652c276ac4f
774 | @ changeset: 2:4652c276ac4f
775 |/ user: test
775 |/ user: test
776 | date: Thu Jan 01 00:00:00 1970 +0000
776 | date: Thu Jan 01 00:00:00 1970 +0000
777 | summary: 2
777 | summary: 2
778 |
778 |
779 o changeset: 1:a01eca7af26d
779 o changeset: 1:a01eca7af26d
780 | user: test
780 | user: test
781 | date: Thu Jan 01 00:00:00 1970 +0000
781 | date: Thu Jan 01 00:00:00 1970 +0000
782 | summary: 1
782 | summary: 1
783 |
783 |
784 o changeset: 0:4fe08cd4693e
784 o changeset: 0:4fe08cd4693e
785 user: test
785 user: test
786 date: Thu Jan 01 00:00:00 1970 +0000
786 date: Thu Jan 01 00:00:00 1970 +0000
787 summary: 0
787 summary: 0
788
788
789 $ hg bundle --base 1 -r 3 ../update2bundled.hg
789 $ hg bundle --base 1 -r 3 ../update2bundled.hg
790 1 changesets found
790 1 changesets found
791 $ hg strip -r 3
791 $ hg strip -r 3
792 saved backup bundle to $TESTTMP/update2bundled/.hg/strip-backup/8bd3e1f196af-017e56d8-backup.hg (glob)
792 saved backup bundle to $TESTTMP/update2bundled/.hg/strip-backup/8bd3e1f196af-017e56d8-backup.hg (glob)
793 $ hg merge -R ../update2bundled.hg -r 3
793 $ hg merge -R ../update2bundled.hg -r 3
794 setting parent to node 8bd3e1f196af289b2b121be08031e76d7ae92098 that only exists in the bundle
794 setting parent to node 8bd3e1f196af289b2b121be08031e76d7ae92098 that only exists in the bundle
795 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
795 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
796 (branch merge, don't forget to commit)
796 (branch merge, don't forget to commit)
797
797
798 When user updates to the revision existing only in the bundle,
798 When user updates to the revision existing only in the bundle,
799 it should show warning
799 it should show warning
800
800
801 $ hg update -R ../update2bundled.hg --clean -r 3
801 $ hg update -R ../update2bundled.hg --clean -r 3
802 setting parent to node 8bd3e1f196af289b2b121be08031e76d7ae92098 that only exists in the bundle
802 setting parent to node 8bd3e1f196af289b2b121be08031e76d7ae92098 that only exists in the bundle
803 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
803 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
804
804
805 When user updates to the revision existing in the local repository
805 When user updates to the revision existing in the local repository
806 the warning shouldn't be emitted
806 the warning shouldn't be emitted
807
807
808 $ hg update -R ../update2bundled.hg -r 0
808 $ hg update -R ../update2bundled.hg -r 0
809 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
809 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
@@ -1,433 +1,434 b''
1 Set up a server
1 Set up a server
2
2
3 $ cat >> $HGRCPATH << EOF
3 $ cat >> $HGRCPATH << EOF
4 > [format]
4 > [format]
5 > usegeneraldelta=yes
5 > usegeneraldelta=yes
6 > EOF
6 > EOF
7 $ hg init server
7 $ hg init server
8 $ cd server
8 $ cd server
9 $ cat >> .hg/hgrc << EOF
9 $ cat >> .hg/hgrc << EOF
10 > [extensions]
10 > [extensions]
11 > clonebundles =
11 > clonebundles =
12 > EOF
12 > EOF
13
13
14 $ touch foo
14 $ touch foo
15 $ hg -q commit -A -m 'add foo'
15 $ hg -q commit -A -m 'add foo'
16 $ touch bar
16 $ touch bar
17 $ hg -q commit -A -m 'add bar'
17 $ hg -q commit -A -m 'add bar'
18
18
19 $ hg serve -d -p $HGPORT --pid-file hg.pid --accesslog access.log
19 $ hg serve -d -p $HGPORT --pid-file hg.pid --accesslog access.log
20 $ cat hg.pid >> $DAEMON_PIDS
20 $ cat hg.pid >> $DAEMON_PIDS
21 $ cd ..
21 $ cd ..
22
22
23 Missing manifest should not result in server lookup
23 Missing manifest should not result in server lookup
24
24
25 $ hg --verbose clone -U http://localhost:$HGPORT no-manifest
25 $ hg --verbose clone -U http://localhost:$HGPORT no-manifest
26 requesting all changes
26 requesting all changes
27 adding changesets
27 adding changesets
28 adding manifests
28 adding manifests
29 adding file changes
29 adding file changes
30 added 2 changesets with 2 changes to 2 files
30 added 2 changesets with 2 changes to 2 files
31
31
32 $ cat server/access.log
32 $ cat server/access.log
33 * - - [*] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
33 * - - [*] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
34 * - - [*] "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D (glob)
34 * - - [*] "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D (glob)
35 * - - [*] "GET /?cmd=getbundle HTTP/1.1" 200 - x-hgarg-1:bundlecaps=HG20%2Cbundle2%3DHG20%250Achangegroup%253D01%252C02%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps&cg=1&common=0000000000000000000000000000000000000000&heads=aaff8d2ffbbf07a46dd1f05d8ae7877e3f56e2a2&listkeys=phases%2Cbookmarks (glob)
35 * - - [*] "GET /?cmd=getbundle HTTP/1.1" 200 - x-hgarg-1:bundlecaps=HG20%2Cbundle2%3DHG20%250Achangegroup%253D01%252C02%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps&cg=1&common=0000000000000000000000000000000000000000&heads=aaff8d2ffbbf07a46dd1f05d8ae7877e3f56e2a2&listkeys=phases%2Cbookmarks (glob)
36
36
37 Empty manifest file results in retrieval
37 Empty manifest file results in retrieval
38 (the extension only checks if the manifest file exists)
38 (the extension only checks if the manifest file exists)
39
39
40 $ touch server/.hg/clonebundles.manifest
40 $ touch server/.hg/clonebundles.manifest
41 $ hg --verbose clone -U http://localhost:$HGPORT empty-manifest
41 $ hg --verbose clone -U http://localhost:$HGPORT empty-manifest
42 no clone bundles available on remote; falling back to regular clone
42 no clone bundles available on remote; falling back to regular clone
43 requesting all changes
43 requesting all changes
44 adding changesets
44 adding changesets
45 adding manifests
45 adding manifests
46 adding file changes
46 adding file changes
47 added 2 changesets with 2 changes to 2 files
47 added 2 changesets with 2 changes to 2 files
48
48
49 Manifest file with invalid URL aborts
49 Manifest file with invalid URL aborts
50
50
51 $ echo 'http://does.not.exist/bundle.hg' > server/.hg/clonebundles.manifest
51 $ echo 'http://does.not.exist/bundle.hg' > server/.hg/clonebundles.manifest
52 $ hg clone http://localhost:$HGPORT 404-url
52 $ hg clone http://localhost:$HGPORT 404-url
53 applying clone bundle from http://does.not.exist/bundle.hg
53 applying clone bundle from http://does.not.exist/bundle.hg
54 error fetching bundle: (.* not known|getaddrinfo failed|No address associated with hostname) (re)
54 error fetching bundle: (.* not known|getaddrinfo failed|No address associated with hostname) (re)
55 abort: error applying bundle
55 abort: error applying bundle
56 (if this error persists, consider contacting the server operator or disable clone bundles via "--config ui.clonebundles=false")
56 (if this error persists, consider contacting the server operator or disable clone bundles via "--config ui.clonebundles=false")
57 [255]
57 [255]
58
58
59 Server is not running aborts
59 Server is not running aborts
60
60
61 $ echo "http://localhost:$HGPORT1/bundle.hg" > server/.hg/clonebundles.manifest
61 $ echo "http://localhost:$HGPORT1/bundle.hg" > server/.hg/clonebundles.manifest
62 $ hg clone http://localhost:$HGPORT server-not-runner
62 $ hg clone http://localhost:$HGPORT server-not-runner
63 applying clone bundle from http://localhost:$HGPORT1/bundle.hg
63 applying clone bundle from http://localhost:$HGPORT1/bundle.hg
64 error fetching bundle: * refused* (glob)
64 error fetching bundle: * refused* (glob)
65 abort: error applying bundle
65 abort: error applying bundle
66 (if this error persists, consider contacting the server operator or disable clone bundles via "--config ui.clonebundles=false")
66 (if this error persists, consider contacting the server operator or disable clone bundles via "--config ui.clonebundles=false")
67 [255]
67 [255]
68
68
69 Server returns 404
69 Server returns 404
70
70
71 $ python $TESTDIR/dumbhttp.py -p $HGPORT1 --pid http.pid
71 $ python $TESTDIR/dumbhttp.py -p $HGPORT1 --pid http.pid
72 $ cat http.pid >> $DAEMON_PIDS
72 $ cat http.pid >> $DAEMON_PIDS
73 $ hg clone http://localhost:$HGPORT running-404
73 $ hg clone http://localhost:$HGPORT running-404
74 applying clone bundle from http://localhost:$HGPORT1/bundle.hg
74 applying clone bundle from http://localhost:$HGPORT1/bundle.hg
75 HTTP error fetching bundle: HTTP Error 404: File not found
75 HTTP error fetching bundle: HTTP Error 404: File not found
76 abort: error applying bundle
76 abort: error applying bundle
77 (if this error persists, consider contacting the server operator or disable clone bundles via "--config ui.clonebundles=false")
77 (if this error persists, consider contacting the server operator or disable clone bundles via "--config ui.clonebundles=false")
78 [255]
78 [255]
79
79
80 We can override failure to fall back to regular clone
80 We can override failure to fall back to regular clone
81
81
82 $ hg --config ui.clonebundlefallback=true clone -U http://localhost:$HGPORT 404-fallback
82 $ hg --config ui.clonebundlefallback=true clone -U http://localhost:$HGPORT 404-fallback
83 applying clone bundle from http://localhost:$HGPORT1/bundle.hg
83 applying clone bundle from http://localhost:$HGPORT1/bundle.hg
84 HTTP error fetching bundle: HTTP Error 404: File not found
84 HTTP error fetching bundle: HTTP Error 404: File not found
85 falling back to normal clone
85 falling back to normal clone
86 requesting all changes
86 requesting all changes
87 adding changesets
87 adding changesets
88 adding manifests
88 adding manifests
89 adding file changes
89 adding file changes
90 added 2 changesets with 2 changes to 2 files
90 added 2 changesets with 2 changes to 2 files
91
91
92 Bundle with partial content works
92 Bundle with partial content works
93
93
94 $ hg -R server bundle --type gzip-v1 --base null -r 53245c60e682 partial.hg
94 $ hg -R server bundle --type gzip-v1 --base null -r 53245c60e682 partial.hg
95 1 changesets found
95 1 changesets found
96
96
97 We verify exact bundle content as an extra check against accidental future
97 We verify exact bundle content as an extra check against accidental future
98 changes. If this output changes, we could break old clients.
98 changes. If this output changes, we could break old clients.
99
99
100 $ f --size --hexdump partial.hg
100 $ f --size --hexdump partial.hg
101 partial.hg: size=207
101 partial.hg: size=207
102 0000: 48 47 31 30 47 5a 78 9c 63 60 60 98 17 ac 12 93 |HG10GZx.c``.....|
102 0000: 48 47 31 30 47 5a 78 9c 63 60 60 98 17 ac 12 93 |HG10GZx.c``.....|
103 0010: f0 ac a9 23 45 70 cb bf 0d 5f 59 4e 4a 7f 79 21 |...#Ep..._YNJ.y!|
103 0010: f0 ac a9 23 45 70 cb bf 0d 5f 59 4e 4a 7f 79 21 |...#Ep..._YNJ.y!|
104 0020: 9b cc 40 24 20 a0 d7 ce 2c d1 38 25 cd 24 25 d5 |..@$ ...,.8%.$%.|
104 0020: 9b cc 40 24 20 a0 d7 ce 2c d1 38 25 cd 24 25 d5 |..@$ ...,.8%.$%.|
105 0030: d8 c2 22 cd 38 d9 24 cd 22 d5 c8 22 cd 24 cd 32 |..".8.$."..".$.2|
105 0030: d8 c2 22 cd 38 d9 24 cd 22 d5 c8 22 cd 24 cd 32 |..".8.$."..".$.2|
106 0040: d1 c2 d0 c4 c8 d2 32 d1 38 39 29 c9 34 cd d4 80 |......2.89).4...|
106 0040: d1 c2 d0 c4 c8 d2 32 d1 38 39 29 c9 34 cd d4 80 |......2.89).4...|
107 0050: ab 24 b5 b8 84 cb 40 c1 80 2b 2d 3f 9f 8b 2b 31 |.$....@..+-?..+1|
107 0050: ab 24 b5 b8 84 cb 40 c1 80 2b 2d 3f 9f 8b 2b 31 |.$....@..+-?..+1|
108 0060: 25 45 01 c8 80 9a d2 9b 65 fb e5 9e 45 bf 8d 7f |%E......e...E...|
108 0060: 25 45 01 c8 80 9a d2 9b 65 fb e5 9e 45 bf 8d 7f |%E......e...E...|
109 0070: 9f c6 97 9f 2b 44 34 67 d9 ec 8e 0f a0 92 0b 75 |....+D4g.......u|
109 0070: 9f c6 97 9f 2b 44 34 67 d9 ec 8e 0f a0 92 0b 75 |....+D4g.......u|
110 0080: 41 d6 24 59 18 a4 a4 9a a6 18 1a 5b 98 9b 5a 98 |A.$Y.......[..Z.|
110 0080: 41 d6 24 59 18 a4 a4 9a a6 18 1a 5b 98 9b 5a 98 |A.$Y.......[..Z.|
111 0090: 9a 18 26 9b a6 19 98 1a 99 99 26 a6 18 9a 98 24 |..&.......&....$|
111 0090: 9a 18 26 9b a6 19 98 1a 99 99 26 a6 18 9a 98 24 |..&.......&....$|
112 00a0: 26 59 a6 25 5a 98 a5 18 a6 24 71 41 35 b1 43 dc |&Y.%Z....$qA5.C.|
112 00a0: 26 59 a6 25 5a 98 a5 18 a6 24 71 41 35 b1 43 dc |&Y.%Z....$qA5.C.|
113 00b0: 16 b2 83 f7 e9 45 8b d2 56 c7 a3 1f 82 52 d7 8a |.....E..V....R..|
113 00b0: 16 b2 83 f7 e9 45 8b d2 56 c7 a3 1f 82 52 d7 8a |.....E..V....R..|
114 00c0: 78 ed fc d5 76 f1 36 35 dc 05 00 36 ed 5e c7 |x...v.65...6.^.|
114 00c0: 78 ed fc d5 76 f1 36 35 dc 05 00 36 ed 5e c7 |x...v.65...6.^.|
115
115
116 $ echo "http://localhost:$HGPORT1/partial.hg" > server/.hg/clonebundles.manifest
116 $ echo "http://localhost:$HGPORT1/partial.hg" > server/.hg/clonebundles.manifest
117 $ hg clone -U http://localhost:$HGPORT partial-bundle
117 $ hg clone -U http://localhost:$HGPORT partial-bundle
118 applying clone bundle from http://localhost:$HGPORT1/partial.hg
118 applying clone bundle from http://localhost:$HGPORT1/partial.hg
119 adding changesets
119 adding changesets
120 adding manifests
120 adding manifests
121 adding file changes
121 adding file changes
122 added 1 changesets with 1 changes to 1 files
122 added 1 changesets with 1 changes to 1 files
123 finished applying clone bundle
123 finished applying clone bundle
124 searching for changes
124 searching for changes
125 adding changesets
125 adding changesets
126 adding manifests
126 adding manifests
127 adding file changes
127 adding file changes
128 added 1 changesets with 1 changes to 1 files
128 added 1 changesets with 1 changes to 1 files
129
129
130 Incremental pull doesn't fetch bundle
130 Incremental pull doesn't fetch bundle
131
131
132 $ hg clone -r 53245c60e682 -U http://localhost:$HGPORT partial-clone
132 $ hg clone -r 53245c60e682 -U http://localhost:$HGPORT partial-clone
133 adding changesets
133 adding changesets
134 adding manifests
134 adding manifests
135 adding file changes
135 adding file changes
136 added 1 changesets with 1 changes to 1 files
136 added 1 changesets with 1 changes to 1 files
137
137
138 $ cd partial-clone
138 $ cd partial-clone
139 $ hg pull
139 $ hg pull
140 pulling from http://localhost:$HGPORT/
140 pulling from http://localhost:$HGPORT/
141 searching for changes
141 searching for changes
142 adding changesets
142 adding changesets
143 adding manifests
143 adding manifests
144 adding file changes
144 adding file changes
145 added 1 changesets with 1 changes to 1 files
145 added 1 changesets with 1 changes to 1 files
146 (run 'hg update' to get a working copy)
146 (run 'hg update' to get a working copy)
147 $ cd ..
147 $ cd ..
148
148
149 Bundle with full content works
149 Bundle with full content works
150
150
151 $ hg -R server bundle --type gzip-v2 --base null -r tip full.hg
151 $ hg -R server bundle --type gzip-v2 --base null -r tip full.hg
152 2 changesets found
152 2 changesets found
153
153
154 Again, we perform an extra check against bundle content changes. If this content
154 Again, we perform an extra check against bundle content changes. If this content
155 changes, clone bundles produced by new Mercurial versions may not be readable
155 changes, clone bundles produced by new Mercurial versions may not be readable
156 by old clients.
156 by old clients.
157
157
158 $ f --size --hexdump full.hg
158 $ f --size --hexdump full.hg
159 full.hg: size=406
159 full.hg: size=418
160 0000: 48 47 32 30 00 00 00 0e 43 6f 6d 70 72 65 73 73 |HG20....Compress|
160 0000: 48 47 32 30 00 00 00 0e 43 6f 6d 70 72 65 73 73 |HG20....Compress|
161 0010: 69 6f 6e 3d 47 5a 78 9c 63 60 60 90 e5 76 f6 70 |ion=GZx.c``..v.p|
161 0010: 69 6f 6e 3d 47 5a 78 9c 63 60 60 d0 e4 76 f6 70 |ion=GZx.c``..v.p|
162 0020: f4 73 77 75 0f f2 0f 0d 60 00 02 46 06 76 a6 b2 |.swu....`..F.v..|
162 0020: f4 73 77 75 0f f2 0f 0d 60 00 02 46 46 76 26 4e |.swu....`..FFv&N|
163 0030: d4 a2 e2 cc fc 3c 03 23 06 06 e6 65 40 b1 4d c1 |.....<.#...e@.M.|
163 0030: c6 b2 d4 a2 e2 cc fc 3c 03 a3 bc a4 e4 8c c4 bc |.......<........|
164 0040: 2a 31 09 cf 9a 3a 52 04 b7 fc db f0 95 e5 a4 f4 |*1...:R.........|
164 0040: f4 d4 62 23 06 06 e6 65 40 f9 4d c1 2a 31 09 cf |..b#...e@.M.*1..|
165 0050: 97 17 b2 c9 0c 14 00 02 e6 d9 99 25 1a a7 a4 99 |...........%....|
165 0050: 9a 3a 52 04 b7 fc db f0 95 e5 a4 f4 97 17 b2 c9 |.:R.............|
166 0060: a4 a4 1a 5b 58 a4 19 27 9b a4 59 a4 1a 59 a4 99 |...[X..'..Y..Y..|
166 0060: 0c 14 00 02 e6 d9 99 25 1a a7 a4 99 a4 a4 1a 5b |.......%.......[|
167 0070: a4 59 26 5a 18 9a 18 59 5a 26 1a 27 27 25 99 a6 |.Y&Z...YZ&.''%..|
167 0070: 58 a4 19 27 9b a4 59 a4 1a 59 a4 99 a4 59 26 5a |X..'..Y..Y...Y&Z|
168 0080: 99 1a 70 95 a4 16 97 70 19 28 18 70 a5 e5 e7 73 |..p....p.(.p...s|
168 0080: 18 9a 18 59 5a 26 1a 27 27 25 99 a6 99 1a 70 95 |...YZ&.''%....p.|
169 0090: 71 25 a6 a4 28 00 19 40 13 0e ac fa df ab ff 7b |q%..(..@.......{|
169 0090: a4 16 97 70 19 28 18 70 a5 e5 e7 73 71 25 a6 a4 |...p.(.p...sq%..|
170 00a0: 3f fb 92 dc 8b 1f 62 bb 9e b7 d7 d9 87 3d 5a 44 |?.....b......=ZD|
170 00a0: 28 00 19 40 13 0e ac fa df ab ff 7b 3f fb 92 dc |(..@.......{?...|
171 00b0: ac 2f b0 a9 c3 66 1e 54 b9 26 08 a7 1a 1b 1a a7 |./...f.T.&......|
171 00b0: 8b 1f 62 bb 9e b7 d7 d9 87 3d 5a 44 ac 2f b0 a9 |..b......=ZD./..|
172 00c0: 25 1b 9a 1b 99 19 9a 5a 18 9b a6 18 19 00 dd 67 |%......Z.......g|
172 00c0: c3 66 1e 54 b9 26 08 a7 1a 1b 1a a7 25 1b 9a 1b |.f.T.&......%...|
173 00d0: 61 61 98 06 f4 80 49 4a 8a 65 52 92 41 9a 81 81 |aa....IJ.eR.A...|
173 00d0: 99 19 9a 5a 18 9b a6 18 19 00 dd 67 61 61 98 06 |...Z.......gaa..|
174 00e0: a5 11 17 50 31 30 58 19 cc 80 98 25 29 b1 08 c4 |...P10X....%)...|
174 00e0: f4 80 49 4a 8a 65 52 92 41 9a 81 81 a5 11 17 50 |..IJ.eR.A......P|
175 00f0: 37 07 79 19 88 d9 41 ee 07 8a 41 cd 5d 98 65 fb |7.y...A...A.].e.|
175 00f0: 31 30 58 19 cc 80 98 25 29 b1 08 c4 37 07 79 19 |10X....%)...7.y.|
176 0100: e5 9e 45 bf 8d 7f 9f c6 97 9f 2b 44 34 67 d9 ec |..E.......+D4g..|
176 0100: 88 d9 41 ee 07 8a 41 cd 5d 98 65 fb e5 9e 45 bf |..A...A.].e...E.|
177 0110: 8e 0f a0 61 a8 eb 82 82 2e c9 c2 20 25 d5 34 c5 |...a....... %.4.|
177 0110: 8d 7f 9f c6 97 9f 2b 44 34 67 d9 ec 8e 0f a0 61 |......+D4g.....a|
178 0120: d0 d8 c2 dc d4 c2 d4 c4 30 d9 34 cd c0 d4 c8 cc |........0.4.....|
178 0120: a8 eb 82 82 2e c9 c2 20 25 d5 34 c5 d0 d8 c2 dc |....... %.4.....|
179 0130: 34 31 c5 d0 c4 24 31 c9 32 2d d1 c2 2c c5 30 25 |41...$1.2-..,.0%|
179 0130: d4 c2 d4 c4 30 d9 34 cd c0 d4 c8 cc 34 31 c5 d0 |....0.4.....41..|
180 0140: 09 e4 ee 85 8f 85 ff 88 ab 89 36 c7 2a c4 47 34 |..........6.*.G4|
180 0140: c4 24 31 c9 32 2d d1 c2 2c c5 30 25 09 e4 ee 85 |.$1.2-..,.0%....|
181 0150: fe f8 ec 7b 73 37 3f c3 24 62 1d 8d 4d 1d 9e 40 |...{s7?.$b..M..@|
181 0150: 8f 85 ff 88 ab 89 36 c7 2a c4 47 34 fe f8 ec 7b |......6.*.G4...{|
182 0160: 06 3b 10 14 36 a4 38 10 04 d8 21 01 9a b1 83 f7 |.;..6.8...!.....|
182 0160: 73 37 3f c3 24 62 1d 8d 4d 1d 9e 40 06 3b 10 14 |s7?.$b..M..@.;..|
183 0170: e9 45 8b d2 56 c7 a3 1f 82 52 d7 8a 78 ed fc d5 |.E..V....R..x...|
183 0170: 36 a4 38 10 04 d8 21 01 9a b1 83 f7 e9 45 8b d2 |6.8...!......E..|
184 0180: 76 f1 36 25 81 89 c7 ad ec 90 34 48 75 2b 89 49 |v.6%......4Hu+.I|
184 0180: 56 c7 a3 1f 82 52 d7 8a 78 ed fc d5 76 f1 36 25 |V....R..x...v.6%|
185 0190: bf 00 d6 97 f0 8d |......|
185 0190: 81 89 c7 ad ec 90 34 48 75 2b 89 49 bf 00 cf 72 |......4Hu+.I...r|
186 01a0: f4 7f |..|
186
187
187 $ echo "http://localhost:$HGPORT1/full.hg" > server/.hg/clonebundles.manifest
188 $ echo "http://localhost:$HGPORT1/full.hg" > server/.hg/clonebundles.manifest
188 $ hg clone -U http://localhost:$HGPORT full-bundle
189 $ hg clone -U http://localhost:$HGPORT full-bundle
189 applying clone bundle from http://localhost:$HGPORT1/full.hg
190 applying clone bundle from http://localhost:$HGPORT1/full.hg
190 adding changesets
191 adding changesets
191 adding manifests
192 adding manifests
192 adding file changes
193 adding file changes
193 added 2 changesets with 2 changes to 2 files
194 added 2 changesets with 2 changes to 2 files
194 finished applying clone bundle
195 finished applying clone bundle
195 searching for changes
196 searching for changes
196 no changes found
197 no changes found
197
198
198 Feature works over SSH
199 Feature works over SSH
199
200
200 $ hg clone -U -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/server ssh-full-clone
201 $ hg clone -U -e "python \"$TESTDIR/dummyssh\"" ssh://user@dummy/server ssh-full-clone
201 applying clone bundle from http://localhost:$HGPORT1/full.hg
202 applying clone bundle from http://localhost:$HGPORT1/full.hg
202 adding changesets
203 adding changesets
203 adding manifests
204 adding manifests
204 adding file changes
205 adding file changes
205 added 2 changesets with 2 changes to 2 files
206 added 2 changesets with 2 changes to 2 files
206 finished applying clone bundle
207 finished applying clone bundle
207 searching for changes
208 searching for changes
208 no changes found
209 no changes found
209
210
210 Entry with unknown BUNDLESPEC is filtered and not used
211 Entry with unknown BUNDLESPEC is filtered and not used
211
212
212 $ cat > server/.hg/clonebundles.manifest << EOF
213 $ cat > server/.hg/clonebundles.manifest << EOF
213 > http://bad.entry1 BUNDLESPEC=UNKNOWN
214 > http://bad.entry1 BUNDLESPEC=UNKNOWN
214 > http://bad.entry2 BUNDLESPEC=xz-v1
215 > http://bad.entry2 BUNDLESPEC=xz-v1
215 > http://bad.entry3 BUNDLESPEC=none-v100
216 > http://bad.entry3 BUNDLESPEC=none-v100
216 > http://localhost:$HGPORT1/full.hg BUNDLESPEC=gzip-v2
217 > http://localhost:$HGPORT1/full.hg BUNDLESPEC=gzip-v2
217 > EOF
218 > EOF
218
219
219 $ hg clone -U http://localhost:$HGPORT filter-unknown-type
220 $ hg clone -U http://localhost:$HGPORT filter-unknown-type
220 applying clone bundle from http://localhost:$HGPORT1/full.hg
221 applying clone bundle from http://localhost:$HGPORT1/full.hg
221 adding changesets
222 adding changesets
222 adding manifests
223 adding manifests
223 adding file changes
224 adding file changes
224 added 2 changesets with 2 changes to 2 files
225 added 2 changesets with 2 changes to 2 files
225 finished applying clone bundle
226 finished applying clone bundle
226 searching for changes
227 searching for changes
227 no changes found
228 no changes found
228
229
229 Automatic fallback when all entries are filtered
230 Automatic fallback when all entries are filtered
230
231
231 $ cat > server/.hg/clonebundles.manifest << EOF
232 $ cat > server/.hg/clonebundles.manifest << EOF
232 > http://bad.entry BUNDLESPEC=UNKNOWN
233 > http://bad.entry BUNDLESPEC=UNKNOWN
233 > EOF
234 > EOF
234
235
235 $ hg clone -U http://localhost:$HGPORT filter-all
236 $ hg clone -U http://localhost:$HGPORT filter-all
236 no compatible clone bundles available on server; falling back to regular clone
237 no compatible clone bundles available on server; falling back to regular clone
237 (you may want to report this to the server operator)
238 (you may want to report this to the server operator)
238 requesting all changes
239 requesting all changes
239 adding changesets
240 adding changesets
240 adding manifests
241 adding manifests
241 adding file changes
242 adding file changes
242 added 2 changesets with 2 changes to 2 files
243 added 2 changesets with 2 changes to 2 files
243
244
244 URLs requiring SNI are filtered in Python <2.7.9
245 URLs requiring SNI are filtered in Python <2.7.9
245
246
246 $ cp full.hg sni.hg
247 $ cp full.hg sni.hg
247 $ cat > server/.hg/clonebundles.manifest << EOF
248 $ cat > server/.hg/clonebundles.manifest << EOF
248 > http://localhost:$HGPORT1/sni.hg REQUIRESNI=true
249 > http://localhost:$HGPORT1/sni.hg REQUIRESNI=true
249 > http://localhost:$HGPORT1/full.hg
250 > http://localhost:$HGPORT1/full.hg
250 > EOF
251 > EOF
251
252
252 #if sslcontext
253 #if sslcontext
253 Python 2.7.9+ support SNI
254 Python 2.7.9+ support SNI
254
255
255 $ hg clone -U http://localhost:$HGPORT sni-supported
256 $ hg clone -U http://localhost:$HGPORT sni-supported
256 applying clone bundle from http://localhost:$HGPORT1/sni.hg
257 applying clone bundle from http://localhost:$HGPORT1/sni.hg
257 adding changesets
258 adding changesets
258 adding manifests
259 adding manifests
259 adding file changes
260 adding file changes
260 added 2 changesets with 2 changes to 2 files
261 added 2 changesets with 2 changes to 2 files
261 finished applying clone bundle
262 finished applying clone bundle
262 searching for changes
263 searching for changes
263 no changes found
264 no changes found
264 #else
265 #else
265 Python <2.7.9 will filter SNI URLs
266 Python <2.7.9 will filter SNI URLs
266
267
267 $ hg clone -U http://localhost:$HGPORT sni-unsupported
268 $ hg clone -U http://localhost:$HGPORT sni-unsupported
268 applying clone bundle from http://localhost:$HGPORT1/full.hg
269 applying clone bundle from http://localhost:$HGPORT1/full.hg
269 adding changesets
270 adding changesets
270 adding manifests
271 adding manifests
271 adding file changes
272 adding file changes
272 added 2 changesets with 2 changes to 2 files
273 added 2 changesets with 2 changes to 2 files
273 finished applying clone bundle
274 finished applying clone bundle
274 searching for changes
275 searching for changes
275 no changes found
276 no changes found
276 #endif
277 #endif
277
278
278 Stream clone bundles are supported
279 Stream clone bundles are supported
279
280
280 $ hg -R server debugcreatestreamclonebundle packed.hg
281 $ hg -R server debugcreatestreamclonebundle packed.hg
281 writing 613 bytes for 4 files
282 writing 613 bytes for 4 files
282 bundle requirements: generaldelta, revlogv1
283 bundle requirements: generaldelta, revlogv1
283
284
284 No bundle spec should work
285 No bundle spec should work
285
286
286 $ cat > server/.hg/clonebundles.manifest << EOF
287 $ cat > server/.hg/clonebundles.manifest << EOF
287 > http://localhost:$HGPORT1/packed.hg
288 > http://localhost:$HGPORT1/packed.hg
288 > EOF
289 > EOF
289
290
290 $ hg clone -U http://localhost:$HGPORT stream-clone-no-spec
291 $ hg clone -U http://localhost:$HGPORT stream-clone-no-spec
291 applying clone bundle from http://localhost:$HGPORT1/packed.hg
292 applying clone bundle from http://localhost:$HGPORT1/packed.hg
292 4 files to transfer, 613 bytes of data
293 4 files to transfer, 613 bytes of data
293 transferred 613 bytes in *.* seconds (*) (glob)
294 transferred 613 bytes in *.* seconds (*) (glob)
294 finished applying clone bundle
295 finished applying clone bundle
295 searching for changes
296 searching for changes
296 no changes found
297 no changes found
297
298
298 Bundle spec without parameters should work
299 Bundle spec without parameters should work
299
300
300 $ cat > server/.hg/clonebundles.manifest << EOF
301 $ cat > server/.hg/clonebundles.manifest << EOF
301 > http://localhost:$HGPORT1/packed.hg BUNDLESPEC=none-packed1
302 > http://localhost:$HGPORT1/packed.hg BUNDLESPEC=none-packed1
302 > EOF
303 > EOF
303
304
304 $ hg clone -U http://localhost:$HGPORT stream-clone-vanilla-spec
305 $ hg clone -U http://localhost:$HGPORT stream-clone-vanilla-spec
305 applying clone bundle from http://localhost:$HGPORT1/packed.hg
306 applying clone bundle from http://localhost:$HGPORT1/packed.hg
306 4 files to transfer, 613 bytes of data
307 4 files to transfer, 613 bytes of data
307 transferred 613 bytes in *.* seconds (*) (glob)
308 transferred 613 bytes in *.* seconds (*) (glob)
308 finished applying clone bundle
309 finished applying clone bundle
309 searching for changes
310 searching for changes
310 no changes found
311 no changes found
311
312
312 Bundle spec with format requirements should work
313 Bundle spec with format requirements should work
313
314
314 $ cat > server/.hg/clonebundles.manifest << EOF
315 $ cat > server/.hg/clonebundles.manifest << EOF
315 > http://localhost:$HGPORT1/packed.hg BUNDLESPEC=none-packed1;requirements%3Drevlogv1
316 > http://localhost:$HGPORT1/packed.hg BUNDLESPEC=none-packed1;requirements%3Drevlogv1
316 > EOF
317 > EOF
317
318
318 $ hg clone -U http://localhost:$HGPORT stream-clone-supported-requirements
319 $ hg clone -U http://localhost:$HGPORT stream-clone-supported-requirements
319 applying clone bundle from http://localhost:$HGPORT1/packed.hg
320 applying clone bundle from http://localhost:$HGPORT1/packed.hg
320 4 files to transfer, 613 bytes of data
321 4 files to transfer, 613 bytes of data
321 transferred 613 bytes in *.* seconds (*) (glob)
322 transferred 613 bytes in *.* seconds (*) (glob)
322 finished applying clone bundle
323 finished applying clone bundle
323 searching for changes
324 searching for changes
324 no changes found
325 no changes found
325
326
326 Stream bundle spec with unknown requirements should be filtered out
327 Stream bundle spec with unknown requirements should be filtered out
327
328
328 $ cat > server/.hg/clonebundles.manifest << EOF
329 $ cat > server/.hg/clonebundles.manifest << EOF
329 > http://localhost:$HGPORT1/packed.hg BUNDLESPEC=none-packed1;requirements%3Drevlogv42
330 > http://localhost:$HGPORT1/packed.hg BUNDLESPEC=none-packed1;requirements%3Drevlogv42
330 > EOF
331 > EOF
331
332
332 $ hg clone -U http://localhost:$HGPORT stream-clone-unsupported-requirements
333 $ hg clone -U http://localhost:$HGPORT stream-clone-unsupported-requirements
333 no compatible clone bundles available on server; falling back to regular clone
334 no compatible clone bundles available on server; falling back to regular clone
334 (you may want to report this to the server operator)
335 (you may want to report this to the server operator)
335 requesting all changes
336 requesting all changes
336 adding changesets
337 adding changesets
337 adding manifests
338 adding manifests
338 adding file changes
339 adding file changes
339 added 2 changesets with 2 changes to 2 files
340 added 2 changesets with 2 changes to 2 files
340
341
341 Set up manifest for testing preferences
342 Set up manifest for testing preferences
342 (Remember, the TYPE does not have to match reality - the URL is
343 (Remember, the TYPE does not have to match reality - the URL is
343 important)
344 important)
344
345
345 $ cp full.hg gz-a.hg
346 $ cp full.hg gz-a.hg
346 $ cp full.hg gz-b.hg
347 $ cp full.hg gz-b.hg
347 $ cp full.hg bz2-a.hg
348 $ cp full.hg bz2-a.hg
348 $ cp full.hg bz2-b.hg
349 $ cp full.hg bz2-b.hg
349 $ cat > server/.hg/clonebundles.manifest << EOF
350 $ cat > server/.hg/clonebundles.manifest << EOF
350 > http://localhost:$HGPORT1/gz-a.hg BUNDLESPEC=gzip-v2 extra=a
351 > http://localhost:$HGPORT1/gz-a.hg BUNDLESPEC=gzip-v2 extra=a
351 > http://localhost:$HGPORT1/bz2-a.hg BUNDLESPEC=bzip2-v2 extra=a
352 > http://localhost:$HGPORT1/bz2-a.hg BUNDLESPEC=bzip2-v2 extra=a
352 > http://localhost:$HGPORT1/gz-b.hg BUNDLESPEC=gzip-v2 extra=b
353 > http://localhost:$HGPORT1/gz-b.hg BUNDLESPEC=gzip-v2 extra=b
353 > http://localhost:$HGPORT1/bz2-b.hg BUNDLESPEC=bzip2-v2 extra=b
354 > http://localhost:$HGPORT1/bz2-b.hg BUNDLESPEC=bzip2-v2 extra=b
354 > EOF
355 > EOF
355
356
356 Preferring an undefined attribute will take first entry
357 Preferring an undefined attribute will take first entry
357
358
358 $ hg --config ui.clonebundleprefers=foo=bar clone -U http://localhost:$HGPORT prefer-foo
359 $ hg --config ui.clonebundleprefers=foo=bar clone -U http://localhost:$HGPORT prefer-foo
359 applying clone bundle from http://localhost:$HGPORT1/gz-a.hg
360 applying clone bundle from http://localhost:$HGPORT1/gz-a.hg
360 adding changesets
361 adding changesets
361 adding manifests
362 adding manifests
362 adding file changes
363 adding file changes
363 added 2 changesets with 2 changes to 2 files
364 added 2 changesets with 2 changes to 2 files
364 finished applying clone bundle
365 finished applying clone bundle
365 searching for changes
366 searching for changes
366 no changes found
367 no changes found
367
368
368 Preferring bz2 type will download first entry of that type
369 Preferring bz2 type will download first entry of that type
369
370
370 $ hg --config ui.clonebundleprefers=COMPRESSION=bzip2 clone -U http://localhost:$HGPORT prefer-bz
371 $ hg --config ui.clonebundleprefers=COMPRESSION=bzip2 clone -U http://localhost:$HGPORT prefer-bz
371 applying clone bundle from http://localhost:$HGPORT1/bz2-a.hg
372 applying clone bundle from http://localhost:$HGPORT1/bz2-a.hg
372 adding changesets
373 adding changesets
373 adding manifests
374 adding manifests
374 adding file changes
375 adding file changes
375 added 2 changesets with 2 changes to 2 files
376 added 2 changesets with 2 changes to 2 files
376 finished applying clone bundle
377 finished applying clone bundle
377 searching for changes
378 searching for changes
378 no changes found
379 no changes found
379
380
380 Preferring multiple values of an option works
381 Preferring multiple values of an option works
381
382
382 $ hg --config ui.clonebundleprefers=COMPRESSION=unknown,COMPRESSION=bzip2 clone -U http://localhost:$HGPORT prefer-multiple-bz
383 $ hg --config ui.clonebundleprefers=COMPRESSION=unknown,COMPRESSION=bzip2 clone -U http://localhost:$HGPORT prefer-multiple-bz
383 applying clone bundle from http://localhost:$HGPORT1/bz2-a.hg
384 applying clone bundle from http://localhost:$HGPORT1/bz2-a.hg
384 adding changesets
385 adding changesets
385 adding manifests
386 adding manifests
386 adding file changes
387 adding file changes
387 added 2 changesets with 2 changes to 2 files
388 added 2 changesets with 2 changes to 2 files
388 finished applying clone bundle
389 finished applying clone bundle
389 searching for changes
390 searching for changes
390 no changes found
391 no changes found
391
392
392 Sorting multiple values should get us back to original first entry
393 Sorting multiple values should get us back to original first entry
393
394
394 $ hg --config ui.clonebundleprefers=BUNDLESPEC=unknown,BUNDLESPEC=gzip-v2,BUNDLESPEC=bzip2-v2 clone -U http://localhost:$HGPORT prefer-multiple-gz
395 $ hg --config ui.clonebundleprefers=BUNDLESPEC=unknown,BUNDLESPEC=gzip-v2,BUNDLESPEC=bzip2-v2 clone -U http://localhost:$HGPORT prefer-multiple-gz
395 applying clone bundle from http://localhost:$HGPORT1/gz-a.hg
396 applying clone bundle from http://localhost:$HGPORT1/gz-a.hg
396 adding changesets
397 adding changesets
397 adding manifests
398 adding manifests
398 adding file changes
399 adding file changes
399 added 2 changesets with 2 changes to 2 files
400 added 2 changesets with 2 changes to 2 files
400 finished applying clone bundle
401 finished applying clone bundle
401 searching for changes
402 searching for changes
402 no changes found
403 no changes found
403
404
404 Preferring multiple attributes has correct order
405 Preferring multiple attributes has correct order
405
406
406 $ hg --config ui.clonebundleprefers=extra=b,BUNDLESPEC=bzip2-v2 clone -U http://localhost:$HGPORT prefer-separate-attributes
407 $ hg --config ui.clonebundleprefers=extra=b,BUNDLESPEC=bzip2-v2 clone -U http://localhost:$HGPORT prefer-separate-attributes
407 applying clone bundle from http://localhost:$HGPORT1/bz2-b.hg
408 applying clone bundle from http://localhost:$HGPORT1/bz2-b.hg
408 adding changesets
409 adding changesets
409 adding manifests
410 adding manifests
410 adding file changes
411 adding file changes
411 added 2 changesets with 2 changes to 2 files
412 added 2 changesets with 2 changes to 2 files
412 finished applying clone bundle
413 finished applying clone bundle
413 searching for changes
414 searching for changes
414 no changes found
415 no changes found
415
416
416 Test where attribute is missing from some entries
417 Test where attribute is missing from some entries
417
418
418 $ cat > server/.hg/clonebundles.manifest << EOF
419 $ cat > server/.hg/clonebundles.manifest << EOF
419 > http://localhost:$HGPORT1/gz-a.hg BUNDLESPEC=gzip-v2
420 > http://localhost:$HGPORT1/gz-a.hg BUNDLESPEC=gzip-v2
420 > http://localhost:$HGPORT1/bz2-a.hg BUNDLESPEC=bzip2-v2
421 > http://localhost:$HGPORT1/bz2-a.hg BUNDLESPEC=bzip2-v2
421 > http://localhost:$HGPORT1/gz-b.hg BUNDLESPEC=gzip-v2 extra=b
422 > http://localhost:$HGPORT1/gz-b.hg BUNDLESPEC=gzip-v2 extra=b
422 > http://localhost:$HGPORT1/bz2-b.hg BUNDLESPEC=bzip2-v2 extra=b
423 > http://localhost:$HGPORT1/bz2-b.hg BUNDLESPEC=bzip2-v2 extra=b
423 > EOF
424 > EOF
424
425
425 $ hg --config ui.clonebundleprefers=extra=b clone -U http://localhost:$HGPORT prefer-partially-defined-attribute
426 $ hg --config ui.clonebundleprefers=extra=b clone -U http://localhost:$HGPORT prefer-partially-defined-attribute
426 applying clone bundle from http://localhost:$HGPORT1/gz-b.hg
427 applying clone bundle from http://localhost:$HGPORT1/gz-b.hg
427 adding changesets
428 adding changesets
428 adding manifests
429 adding manifests
429 adding file changes
430 adding file changes
430 added 2 changesets with 2 changes to 2 files
431 added 2 changesets with 2 changes to 2 files
431 finished applying clone bundle
432 finished applying clone bundle
432 searching for changes
433 searching for changes
433 no changes found
434 no changes found
@@ -1,76 +1,76 b''
1
1
2 Create a test repository:
2 Create a test repository:
3
3
4 $ hg init repo
4 $ hg init repo
5 $ cd repo
5 $ cd repo
6 $ touch a ; hg add a ; hg ci -ma
6 $ touch a ; hg add a ; hg ci -ma
7 $ touch b ; hg add b ; hg ci -mb
7 $ touch b ; hg add b ; hg ci -mb
8 $ touch c ; hg add c ; hg ci -mc
8 $ touch c ; hg add c ; hg ci -mc
9 $ hg bundle --base 0 --rev tip bundle.hg -v --type v1
9 $ hg bundle --base 0 --rev tip bundle.hg -v --type v1
10 2 changesets found
10 2 changesets found
11 uncompressed size of bundle content:
11 uncompressed size of bundle content:
12 332 (changelog)
12 332 (changelog)
13 282 (manifests)
13 282 (manifests)
14 93 b
14 93 b
15 93 c
15 93 c
16 $ hg bundle --base 0 --rev tip bundle2.hg -v --type none-v2
16 $ hg bundle --base 0 --rev tip bundle2.hg -v --type none-v2
17 2 changesets found
17 2 changesets found
18 uncompressed size of bundle content:
18 uncompressed size of bundle content:
19 372 (changelog)
19 372 (changelog)
20 322 (manifests)
20 322 (manifests)
21 113 b
21 113 b
22 113 c
22 113 c
23
23
24 Terse output:
24 Terse output:
25
25
26 $ hg debugbundle bundle.hg
26 $ hg debugbundle bundle.hg
27 0e067c57feba1a5694ca4844f05588bb1bf82342
27 0e067c57feba1a5694ca4844f05588bb1bf82342
28 991a3460af53952d10ec8a295d3d2cc2e5fa9690
28 991a3460af53952d10ec8a295d3d2cc2e5fa9690
29
29
30 Terse output:
30 Terse output:
31
31
32 $ hg debugbundle bundle2.hg
32 $ hg debugbundle bundle2.hg
33 Stream params: {}
33 Stream params: {}
34 changegroup -- "sortdict([('version', '02')])"
34 changegroup -- "sortdict([('version', '02'), ('nbchanges', '2')])"
35 0e067c57feba1a5694ca4844f05588bb1bf82342
35 0e067c57feba1a5694ca4844f05588bb1bf82342
36 991a3460af53952d10ec8a295d3d2cc2e5fa9690
36 991a3460af53952d10ec8a295d3d2cc2e5fa9690
37
37
38 Verbose output:
38 Verbose output:
39
39
40 $ hg debugbundle --all bundle.hg
40 $ hg debugbundle --all bundle.hg
41 format: id, p1, p2, cset, delta base, len(delta)
41 format: id, p1, p2, cset, delta base, len(delta)
42
42
43 changelog
43 changelog
44 0e067c57feba1a5694ca4844f05588bb1bf82342 3903775176ed42b1458a6281db4a0ccf4d9f287a 0000000000000000000000000000000000000000 0e067c57feba1a5694ca4844f05588bb1bf82342 3903775176ed42b1458a6281db4a0ccf4d9f287a 80
44 0e067c57feba1a5694ca4844f05588bb1bf82342 3903775176ed42b1458a6281db4a0ccf4d9f287a 0000000000000000000000000000000000000000 0e067c57feba1a5694ca4844f05588bb1bf82342 3903775176ed42b1458a6281db4a0ccf4d9f287a 80
45 991a3460af53952d10ec8a295d3d2cc2e5fa9690 0e067c57feba1a5694ca4844f05588bb1bf82342 0000000000000000000000000000000000000000 991a3460af53952d10ec8a295d3d2cc2e5fa9690 0e067c57feba1a5694ca4844f05588bb1bf82342 80
45 991a3460af53952d10ec8a295d3d2cc2e5fa9690 0e067c57feba1a5694ca4844f05588bb1bf82342 0000000000000000000000000000000000000000 991a3460af53952d10ec8a295d3d2cc2e5fa9690 0e067c57feba1a5694ca4844f05588bb1bf82342 80
46
46
47 manifest
47 manifest
48 686dbf0aeca417636fa26a9121c681eabbb15a20 8515d4bfda768e04af4c13a69a72e28c7effbea7 0000000000000000000000000000000000000000 0e067c57feba1a5694ca4844f05588bb1bf82342 8515d4bfda768e04af4c13a69a72e28c7effbea7 55
48 686dbf0aeca417636fa26a9121c681eabbb15a20 8515d4bfda768e04af4c13a69a72e28c7effbea7 0000000000000000000000000000000000000000 0e067c57feba1a5694ca4844f05588bb1bf82342 8515d4bfda768e04af4c13a69a72e28c7effbea7 55
49 ae25a31b30b3490a981e7b96a3238cc69583fda1 686dbf0aeca417636fa26a9121c681eabbb15a20 0000000000000000000000000000000000000000 991a3460af53952d10ec8a295d3d2cc2e5fa9690 686dbf0aeca417636fa26a9121c681eabbb15a20 55
49 ae25a31b30b3490a981e7b96a3238cc69583fda1 686dbf0aeca417636fa26a9121c681eabbb15a20 0000000000000000000000000000000000000000 991a3460af53952d10ec8a295d3d2cc2e5fa9690 686dbf0aeca417636fa26a9121c681eabbb15a20 55
50
50
51 b
51 b
52 b80de5d138758541c5f05265ad144ab9fa86d1db 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 0e067c57feba1a5694ca4844f05588bb1bf82342 0000000000000000000000000000000000000000 0
52 b80de5d138758541c5f05265ad144ab9fa86d1db 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 0e067c57feba1a5694ca4844f05588bb1bf82342 0000000000000000000000000000000000000000 0
53
53
54 c
54 c
55 b80de5d138758541c5f05265ad144ab9fa86d1db 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 991a3460af53952d10ec8a295d3d2cc2e5fa9690 0000000000000000000000000000000000000000 0
55 b80de5d138758541c5f05265ad144ab9fa86d1db 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 991a3460af53952d10ec8a295d3d2cc2e5fa9690 0000000000000000000000000000000000000000 0
56
56
57 $ hg debugbundle --all bundle2.hg
57 $ hg debugbundle --all bundle2.hg
58 Stream params: {}
58 Stream params: {}
59 changegroup -- "sortdict([('version', '02')])"
59 changegroup -- "sortdict([('version', '02'), ('nbchanges', '2')])"
60 format: id, p1, p2, cset, delta base, len(delta)
60 format: id, p1, p2, cset, delta base, len(delta)
61
61
62 changelog
62 changelog
63 0e067c57feba1a5694ca4844f05588bb1bf82342 3903775176ed42b1458a6281db4a0ccf4d9f287a 0000000000000000000000000000000000000000 0e067c57feba1a5694ca4844f05588bb1bf82342 3903775176ed42b1458a6281db4a0ccf4d9f287a 80
63 0e067c57feba1a5694ca4844f05588bb1bf82342 3903775176ed42b1458a6281db4a0ccf4d9f287a 0000000000000000000000000000000000000000 0e067c57feba1a5694ca4844f05588bb1bf82342 3903775176ed42b1458a6281db4a0ccf4d9f287a 80
64 991a3460af53952d10ec8a295d3d2cc2e5fa9690 0e067c57feba1a5694ca4844f05588bb1bf82342 0000000000000000000000000000000000000000 991a3460af53952d10ec8a295d3d2cc2e5fa9690 0e067c57feba1a5694ca4844f05588bb1bf82342 80
64 991a3460af53952d10ec8a295d3d2cc2e5fa9690 0e067c57feba1a5694ca4844f05588bb1bf82342 0000000000000000000000000000000000000000 991a3460af53952d10ec8a295d3d2cc2e5fa9690 0e067c57feba1a5694ca4844f05588bb1bf82342 80
65
65
66 manifest
66 manifest
67 686dbf0aeca417636fa26a9121c681eabbb15a20 8515d4bfda768e04af4c13a69a72e28c7effbea7 0000000000000000000000000000000000000000 0e067c57feba1a5694ca4844f05588bb1bf82342 8515d4bfda768e04af4c13a69a72e28c7effbea7 55
67 686dbf0aeca417636fa26a9121c681eabbb15a20 8515d4bfda768e04af4c13a69a72e28c7effbea7 0000000000000000000000000000000000000000 0e067c57feba1a5694ca4844f05588bb1bf82342 8515d4bfda768e04af4c13a69a72e28c7effbea7 55
68 ae25a31b30b3490a981e7b96a3238cc69583fda1 686dbf0aeca417636fa26a9121c681eabbb15a20 0000000000000000000000000000000000000000 991a3460af53952d10ec8a295d3d2cc2e5fa9690 686dbf0aeca417636fa26a9121c681eabbb15a20 55
68 ae25a31b30b3490a981e7b96a3238cc69583fda1 686dbf0aeca417636fa26a9121c681eabbb15a20 0000000000000000000000000000000000000000 991a3460af53952d10ec8a295d3d2cc2e5fa9690 686dbf0aeca417636fa26a9121c681eabbb15a20 55
69
69
70 b
70 b
71 b80de5d138758541c5f05265ad144ab9fa86d1db 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 0e067c57feba1a5694ca4844f05588bb1bf82342 0000000000000000000000000000000000000000 0
71 b80de5d138758541c5f05265ad144ab9fa86d1db 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 0e067c57feba1a5694ca4844f05588bb1bf82342 0000000000000000000000000000000000000000 0
72
72
73 c
73 c
74 b80de5d138758541c5f05265ad144ab9fa86d1db 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 991a3460af53952d10ec8a295d3d2cc2e5fa9690 0000000000000000000000000000000000000000 0
74 b80de5d138758541c5f05265ad144ab9fa86d1db 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 991a3460af53952d10ec8a295d3d2cc2e5fa9690 0000000000000000000000000000000000000000 0
75
75
76 $ cd ..
76 $ cd ..
@@ -1,161 +1,161 b''
1 Check whether size of generaldelta revlog is not bigger than its
1 Check whether size of generaldelta revlog is not bigger than its
2 regular equivalent. Test would fail if generaldelta was naive
2 regular equivalent. Test would fail if generaldelta was naive
3 implementation of parentdelta: third manifest revision would be fully
3 implementation of parentdelta: third manifest revision would be fully
4 inserted due to big distance from its paren revision (zero).
4 inserted due to big distance from its paren revision (zero).
5
5
6 $ hg init repo --config format.generaldelta=no --config format.usegeneraldelta=no
6 $ hg init repo --config format.generaldelta=no --config format.usegeneraldelta=no
7 $ cd repo
7 $ cd repo
8 $ echo foo > foo
8 $ echo foo > foo
9 $ echo bar > bar
9 $ echo bar > bar
10 $ echo baz > baz
10 $ echo baz > baz
11 $ hg commit -q -Am boo
11 $ hg commit -q -Am boo
12 $ hg clone --pull . ../gdrepo -q --config format.generaldelta=yes
12 $ hg clone --pull . ../gdrepo -q --config format.generaldelta=yes
13 $ for r in 1 2 3; do
13 $ for r in 1 2 3; do
14 > echo $r > foo
14 > echo $r > foo
15 > hg commit -q -m $r
15 > hg commit -q -m $r
16 > hg up -q -r 0
16 > hg up -q -r 0
17 > hg pull . -q -r $r -R ../gdrepo
17 > hg pull . -q -r $r -R ../gdrepo
18 > done
18 > done
19
19
20 $ cd ..
20 $ cd ..
21 >>> from __future__ import print_function
21 >>> from __future__ import print_function
22 >>> import os
22 >>> import os
23 >>> regsize = os.stat("repo/.hg/store/00manifest.i").st_size
23 >>> regsize = os.stat("repo/.hg/store/00manifest.i").st_size
24 >>> gdsize = os.stat("gdrepo/.hg/store/00manifest.i").st_size
24 >>> gdsize = os.stat("gdrepo/.hg/store/00manifest.i").st_size
25 >>> if regsize < gdsize:
25 >>> if regsize < gdsize:
26 ... print('generaldata increased size of manifest')
26 ... print('generaldata increased size of manifest')
27
27
28 Verify rev reordering doesnt create invalid bundles (issue4462)
28 Verify rev reordering doesnt create invalid bundles (issue4462)
29 This requires a commit tree that when pulled will reorder manifest revs such
29 This requires a commit tree that when pulled will reorder manifest revs such
30 that the second manifest to create a file rev will be ordered before the first
30 that the second manifest to create a file rev will be ordered before the first
31 manifest to create that file rev. We also need to do a partial pull to ensure
31 manifest to create that file rev. We also need to do a partial pull to ensure
32 reordering happens. At the end we verify the linkrev points at the earliest
32 reordering happens. At the end we verify the linkrev points at the earliest
33 commit.
33 commit.
34
34
35 $ hg init server --config format.generaldelta=True
35 $ hg init server --config format.generaldelta=True
36 $ cd server
36 $ cd server
37 $ touch a
37 $ touch a
38 $ hg commit -Aqm a
38 $ hg commit -Aqm a
39 $ echo x > x
39 $ echo x > x
40 $ echo y > y
40 $ echo y > y
41 $ hg commit -Aqm xy
41 $ hg commit -Aqm xy
42 $ hg up -q '.^'
42 $ hg up -q '.^'
43 $ echo x > x
43 $ echo x > x
44 $ echo z > z
44 $ echo z > z
45 $ hg commit -Aqm xz
45 $ hg commit -Aqm xz
46 $ hg up -q 1
46 $ hg up -q 1
47 $ echo b > b
47 $ echo b > b
48 $ hg commit -Aqm b
48 $ hg commit -Aqm b
49 $ hg merge -q 2
49 $ hg merge -q 2
50 $ hg commit -Aqm merge
50 $ hg commit -Aqm merge
51 $ echo c > c
51 $ echo c > c
52 $ hg commit -Aqm c
52 $ hg commit -Aqm c
53 $ hg log -G -T '{rev} {shortest(node)} {desc}'
53 $ hg log -G -T '{rev} {shortest(node)} {desc}'
54 @ 5 ebb8 c
54 @ 5 ebb8 c
55 |
55 |
56 o 4 baf7 merge
56 o 4 baf7 merge
57 |\
57 |\
58 | o 3 a129 b
58 | o 3 a129 b
59 | |
59 | |
60 o | 2 958c xz
60 o | 2 958c xz
61 | |
61 | |
62 | o 1 f00c xy
62 | o 1 f00c xy
63 |/
63 |/
64 o 0 3903 a
64 o 0 3903 a
65
65
66 $ cd ..
66 $ cd ..
67 $ hg init client --config format.generaldelta=false --config format.usegeneraldelta=false
67 $ hg init client --config format.generaldelta=false --config format.usegeneraldelta=false
68 $ cd client
68 $ cd client
69 $ hg pull -q ../server -r 4
69 $ hg pull -q ../server -r 4
70 $ hg debugindex x
70 $ hg debugindex x
71 rev offset length base linkrev nodeid p1 p2
71 rev offset length base linkrev nodeid p1 p2
72 0 0 3 0 1 1406e7411862 000000000000 000000000000
72 0 0 3 0 1 1406e7411862 000000000000 000000000000
73
73
74 $ cd ..
74 $ cd ..
75
75
76 Test "usegeneraldelta" config
76 Test "usegeneraldelta" config
77 (repo are general delta, but incoming bundle are not re-deltified)
77 (repo are general delta, but incoming bundle are not re-deltified)
78
78
79 delta coming from the server base delta server are not recompressed.
79 delta coming from the server base delta server are not recompressed.
80 (also include the aggressive version for comparison)
80 (also include the aggressive version for comparison)
81
81
82 $ hg clone repo --pull --config format.usegeneraldelta=1 usegd
82 $ hg clone repo --pull --config format.usegeneraldelta=1 usegd
83 requesting all changes
83 requesting all changes
84 adding changesets
84 adding changesets
85 adding manifests
85 adding manifests
86 adding file changes
86 adding file changes
87 added 4 changesets with 6 changes to 3 files (+2 heads)
87 added 4 changesets with 6 changes to 3 files (+2 heads)
88 updating to branch default
88 updating to branch default
89 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
89 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
90 $ hg clone repo --pull --config format.generaldelta=1 full
90 $ hg clone repo --pull --config format.generaldelta=1 full
91 requesting all changes
91 requesting all changes
92 adding changesets
92 adding changesets
93 adding manifests
93 adding manifests
94 adding file changes
94 adding file changes
95 added 4 changesets with 6 changes to 3 files (+2 heads)
95 added 4 changesets with 6 changes to 3 files (+2 heads)
96 updating to branch default
96 updating to branch default
97 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
97 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
98 $ hg -R repo debugindex -m
98 $ hg -R repo debugindex -m
99 rev offset length base linkrev nodeid p1 p2
99 rev offset length base linkrev nodeid p1 p2
100 0 0 104 0 0 cef96823c800 000000000000 000000000000
100 0 0 104 0 0 cef96823c800 000000000000 000000000000
101 1 104 57 0 1 58ab9a8d541d cef96823c800 000000000000
101 1 104 57 0 1 58ab9a8d541d cef96823c800 000000000000
102 2 161 57 0 2 134fdc6fd680 cef96823c800 000000000000
102 2 161 57 0 2 134fdc6fd680 cef96823c800 000000000000
103 3 218 104 3 3 723508934dad cef96823c800 000000000000
103 3 218 104 3 3 723508934dad cef96823c800 000000000000
104 $ hg -R usegd debugindex -m
104 $ hg -R usegd debugindex -m
105 rev offset length delta linkrev nodeid p1 p2
105 rev offset length delta linkrev nodeid p1 p2
106 0 0 104 -1 0 cef96823c800 000000000000 000000000000
106 0 0 104 -1 0 cef96823c800 000000000000 000000000000
107 1 104 57 0 1 58ab9a8d541d cef96823c800 000000000000
107 1 104 57 0 1 58ab9a8d541d cef96823c800 000000000000
108 2 161 57 1 2 134fdc6fd680 cef96823c800 000000000000
108 2 161 57 1 2 134fdc6fd680 cef96823c800 000000000000
109 3 218 57 0 3 723508934dad cef96823c800 000000000000
109 3 218 57 0 3 723508934dad cef96823c800 000000000000
110 $ hg -R full debugindex -m
110 $ hg -R full debugindex -m
111 rev offset length delta linkrev nodeid p1 p2
111 rev offset length delta linkrev nodeid p1 p2
112 0 0 104 -1 0 cef96823c800 000000000000 000000000000
112 0 0 104 -1 0 cef96823c800 000000000000 000000000000
113 1 104 57 0 1 58ab9a8d541d cef96823c800 000000000000
113 1 104 57 0 1 58ab9a8d541d cef96823c800 000000000000
114 2 161 57 0 2 134fdc6fd680 cef96823c800 000000000000
114 2 161 57 0 2 134fdc6fd680 cef96823c800 000000000000
115 3 218 57 0 3 723508934dad cef96823c800 000000000000
115 3 218 57 0 3 723508934dad cef96823c800 000000000000
116
116
117 Test format.aggressivemergedeltas
117 Test format.aggressivemergedeltas
118
118
119 $ hg init --config format.generaldelta=1 aggressive
119 $ hg init --config format.generaldelta=1 aggressive
120 $ cd aggressive
120 $ cd aggressive
121 $ cat << EOF >> .hg/hgrc
121 $ cat << EOF >> .hg/hgrc
122 > [format]
122 > [format]
123 > generaldelta = 1
123 > generaldelta = 1
124 > EOF
124 > EOF
125 $ touch a b c d e
125 $ touch a b c d e
126 $ hg commit -Aqm side1
126 $ hg commit -Aqm side1
127 $ hg up -q null
127 $ hg up -q null
128 $ touch x y
128 $ touch x y
129 $ hg commit -Aqm side2
129 $ hg commit -Aqm side2
130
130
131 - Verify non-aggressive merge uses p1 (commit 1) as delta parent
131 - Verify non-aggressive merge uses p1 (commit 1) as delta parent
132 $ hg merge -q 0
132 $ hg merge -q 0
133 $ hg commit -q -m merge
133 $ hg commit -q -m merge
134 $ hg debugindex -m
134 $ hg debugindex -m
135 rev offset length delta linkrev nodeid p1 p2
135 rev offset length delta linkrev nodeid p1 p2
136 0 0 59 -1 0 8dde941edb6e 000000000000 000000000000
136 0 0 59 -1 0 8dde941edb6e 000000000000 000000000000
137 1 59 61 0 1 315c023f341d 000000000000 000000000000
137 1 59 61 0 1 315c023f341d 000000000000 000000000000
138 2 120 65 1 2 2ab389a983eb 315c023f341d 8dde941edb6e
138 2 120 65 1 2 2ab389a983eb 315c023f341d 8dde941edb6e
139
139
140 $ hg strip -q -r . --config extensions.strip=
140 $ hg strip -q -r . --config extensions.strip=
141
141
142 - Verify aggressive merge uses p2 (commit 0) as delta parent
142 - Verify aggressive merge uses p2 (commit 0) as delta parent
143 $ hg up -q -C 1
143 $ hg up -q -C 1
144 $ hg merge -q 0
144 $ hg merge -q 0
145 $ hg commit -q -m merge --config format.aggressivemergedeltas=True
145 $ hg commit -q -m merge --config format.aggressivemergedeltas=True
146 $ hg debugindex -m
146 $ hg debugindex -m
147 rev offset length delta linkrev nodeid p1 p2
147 rev offset length delta linkrev nodeid p1 p2
148 0 0 59 -1 0 8dde941edb6e 000000000000 000000000000
148 0 0 59 -1 0 8dde941edb6e 000000000000 000000000000
149 1 59 61 0 1 315c023f341d 000000000000 000000000000
149 1 59 61 0 1 315c023f341d 000000000000 000000000000
150 2 120 62 0 2 2ab389a983eb 315c023f341d 8dde941edb6e
150 2 120 62 0 2 2ab389a983eb 315c023f341d 8dde941edb6e
151
151
152 Test that strip bundle use bundle2
152 Test that strip bundle use bundle2
153 $ hg --config extensions.strip= strip .
153 $ hg --config extensions.strip= strip .
154 0 files updated, 0 files merged, 5 files removed, 0 files unresolved
154 0 files updated, 0 files merged, 5 files removed, 0 files unresolved
155 saved backup bundle to $TESTTMP/aggressive/.hg/strip-backup/1c5d4dc9a8b8-6c68e60c-backup.hg (glob)
155 saved backup bundle to $TESTTMP/aggressive/.hg/strip-backup/1c5d4dc9a8b8-6c68e60c-backup.hg (glob)
156 $ hg debugbundle .hg/strip-backup/*
156 $ hg debugbundle .hg/strip-backup/*
157 Stream params: sortdict([('Compression', 'BZ')])
157 Stream params: sortdict([('Compression', 'BZ')])
158 changegroup -- "sortdict([('version', '02')])"
158 changegroup -- "sortdict([('version', '02'), ('nbchanges', '1')])"
159 1c5d4dc9a8b8d6e1750966d343e94db665e7a1e9
159 1c5d4dc9a8b8d6e1750966d343e94db665e7a1e9
160
160
161 $ cd ..
161 $ cd ..
@@ -1,272 +1,272 b''
1 #require serve
1 #require serve
2
2
3 = Test the getbundle() protocol function =
3 = Test the getbundle() protocol function =
4
4
5 Create a test repository:
5 Create a test repository:
6
6
7 $ hg init repo
7 $ hg init repo
8 $ cd repo
8 $ cd repo
9 $ hg debugbuilddag -n -m '+2 :fork +5 :p1 *fork +6 :p2 /p1 :m1 +3' > /dev/null
9 $ hg debugbuilddag -n -m '+2 :fork +5 :p1 *fork +6 :p2 /p1 :m1 +3' > /dev/null
10 $ hg log -G --template '{node}\n'
10 $ hg log -G --template '{node}\n'
11 o 10c14a2cc935e1d8c31f9e98587dcf27fb08a6da
11 o 10c14a2cc935e1d8c31f9e98587dcf27fb08a6da
12 |
12 |
13 o 4801a72e5d88cb515b0c7e40fae34180f3f837f2
13 o 4801a72e5d88cb515b0c7e40fae34180f3f837f2
14 |
14 |
15 o 0b2f73f04880d9cb6a5cd8a757f0db0ad01e32c3
15 o 0b2f73f04880d9cb6a5cd8a757f0db0ad01e32c3
16 |
16 |
17 o 8365676dbab05860ce0d9110f2af51368b961bbd
17 o 8365676dbab05860ce0d9110f2af51368b961bbd
18 |\
18 |\
19 | o 5686dbbd9fc46cb806599c878d02fe1cb56b83d3
19 | o 5686dbbd9fc46cb806599c878d02fe1cb56b83d3
20 | |
20 | |
21 | o 13c0170174366b441dc68e8e33757232fa744458
21 | o 13c0170174366b441dc68e8e33757232fa744458
22 | |
22 | |
23 | o 63476832d8ec6558cf9bbe3cbe0c757e5cf18043
23 | o 63476832d8ec6558cf9bbe3cbe0c757e5cf18043
24 | |
24 | |
25 | o 700b7e19db54103633c4bf4a6a6b6d55f4d50c03
25 | o 700b7e19db54103633c4bf4a6a6b6d55f4d50c03
26 | |
26 | |
27 | o 928b5f94cdb278bb536eba552de348a4e92ef24d
27 | o 928b5f94cdb278bb536eba552de348a4e92ef24d
28 | |
28 | |
29 | o f34414c64173e0ecb61b25dc55e116dbbcc89bee
29 | o f34414c64173e0ecb61b25dc55e116dbbcc89bee
30 | |
30 | |
31 | o 8931463777131cd73923e560b760061f2aa8a4bc
31 | o 8931463777131cd73923e560b760061f2aa8a4bc
32 | |
32 | |
33 o | 6621d79f61b23ec74cf4b69464343d9e0980ec8b
33 o | 6621d79f61b23ec74cf4b69464343d9e0980ec8b
34 | |
34 | |
35 o | bac16991d12ff45f9dc43c52da1946dfadb83e80
35 o | bac16991d12ff45f9dc43c52da1946dfadb83e80
36 | |
36 | |
37 o | ff42371d57168345fdf1a3aac66a51f6a45d41d2
37 o | ff42371d57168345fdf1a3aac66a51f6a45d41d2
38 | |
38 | |
39 o | d5f6e1ea452285324836a49d7d3c2a63cfed1d31
39 o | d5f6e1ea452285324836a49d7d3c2a63cfed1d31
40 | |
40 | |
41 o | 713346a995c363120712aed1aee7e04afd867638
41 o | 713346a995c363120712aed1aee7e04afd867638
42 |/
42 |/
43 o 29a4d1f17bd3f0779ca0525bebb1cfb51067c738
43 o 29a4d1f17bd3f0779ca0525bebb1cfb51067c738
44 |
44 |
45 o 7704483d56b2a7b5db54dcee7c62378ac629b348
45 o 7704483d56b2a7b5db54dcee7c62378ac629b348
46
46
47 $ cd ..
47 $ cd ..
48
48
49
49
50 = Test locally =
50 = Test locally =
51
51
52 Get everything:
52 Get everything:
53
53
54 $ hg debuggetbundle repo bundle
54 $ hg debuggetbundle repo bundle
55 $ hg debugbundle bundle
55 $ hg debugbundle bundle
56 7704483d56b2a7b5db54dcee7c62378ac629b348
56 7704483d56b2a7b5db54dcee7c62378ac629b348
57 29a4d1f17bd3f0779ca0525bebb1cfb51067c738
57 29a4d1f17bd3f0779ca0525bebb1cfb51067c738
58 713346a995c363120712aed1aee7e04afd867638
58 713346a995c363120712aed1aee7e04afd867638
59 d5f6e1ea452285324836a49d7d3c2a63cfed1d31
59 d5f6e1ea452285324836a49d7d3c2a63cfed1d31
60 ff42371d57168345fdf1a3aac66a51f6a45d41d2
60 ff42371d57168345fdf1a3aac66a51f6a45d41d2
61 bac16991d12ff45f9dc43c52da1946dfadb83e80
61 bac16991d12ff45f9dc43c52da1946dfadb83e80
62 6621d79f61b23ec74cf4b69464343d9e0980ec8b
62 6621d79f61b23ec74cf4b69464343d9e0980ec8b
63 8931463777131cd73923e560b760061f2aa8a4bc
63 8931463777131cd73923e560b760061f2aa8a4bc
64 f34414c64173e0ecb61b25dc55e116dbbcc89bee
64 f34414c64173e0ecb61b25dc55e116dbbcc89bee
65 928b5f94cdb278bb536eba552de348a4e92ef24d
65 928b5f94cdb278bb536eba552de348a4e92ef24d
66 700b7e19db54103633c4bf4a6a6b6d55f4d50c03
66 700b7e19db54103633c4bf4a6a6b6d55f4d50c03
67 63476832d8ec6558cf9bbe3cbe0c757e5cf18043
67 63476832d8ec6558cf9bbe3cbe0c757e5cf18043
68 13c0170174366b441dc68e8e33757232fa744458
68 13c0170174366b441dc68e8e33757232fa744458
69 5686dbbd9fc46cb806599c878d02fe1cb56b83d3
69 5686dbbd9fc46cb806599c878d02fe1cb56b83d3
70 8365676dbab05860ce0d9110f2af51368b961bbd
70 8365676dbab05860ce0d9110f2af51368b961bbd
71 0b2f73f04880d9cb6a5cd8a757f0db0ad01e32c3
71 0b2f73f04880d9cb6a5cd8a757f0db0ad01e32c3
72 4801a72e5d88cb515b0c7e40fae34180f3f837f2
72 4801a72e5d88cb515b0c7e40fae34180f3f837f2
73 10c14a2cc935e1d8c31f9e98587dcf27fb08a6da
73 10c14a2cc935e1d8c31f9e98587dcf27fb08a6da
74
74
75 Get part of linear run:
75 Get part of linear run:
76
76
77 $ hg debuggetbundle repo bundle -H 4801a72e5d88cb515b0c7e40fae34180f3f837f2 -C 8365676dbab05860ce0d9110f2af51368b961bbd
77 $ hg debuggetbundle repo bundle -H 4801a72e5d88cb515b0c7e40fae34180f3f837f2 -C 8365676dbab05860ce0d9110f2af51368b961bbd
78 $ hg debugbundle bundle
78 $ hg debugbundle bundle
79 0b2f73f04880d9cb6a5cd8a757f0db0ad01e32c3
79 0b2f73f04880d9cb6a5cd8a757f0db0ad01e32c3
80 4801a72e5d88cb515b0c7e40fae34180f3f837f2
80 4801a72e5d88cb515b0c7e40fae34180f3f837f2
81
81
82 Get missing branch and merge:
82 Get missing branch and merge:
83
83
84 $ hg debuggetbundle repo bundle -H 4801a72e5d88cb515b0c7e40fae34180f3f837f2 -C 13c0170174366b441dc68e8e33757232fa744458
84 $ hg debuggetbundle repo bundle -H 4801a72e5d88cb515b0c7e40fae34180f3f837f2 -C 13c0170174366b441dc68e8e33757232fa744458
85 $ hg debugbundle bundle
85 $ hg debugbundle bundle
86 713346a995c363120712aed1aee7e04afd867638
86 713346a995c363120712aed1aee7e04afd867638
87 d5f6e1ea452285324836a49d7d3c2a63cfed1d31
87 d5f6e1ea452285324836a49d7d3c2a63cfed1d31
88 ff42371d57168345fdf1a3aac66a51f6a45d41d2
88 ff42371d57168345fdf1a3aac66a51f6a45d41d2
89 bac16991d12ff45f9dc43c52da1946dfadb83e80
89 bac16991d12ff45f9dc43c52da1946dfadb83e80
90 6621d79f61b23ec74cf4b69464343d9e0980ec8b
90 6621d79f61b23ec74cf4b69464343d9e0980ec8b
91 5686dbbd9fc46cb806599c878d02fe1cb56b83d3
91 5686dbbd9fc46cb806599c878d02fe1cb56b83d3
92 8365676dbab05860ce0d9110f2af51368b961bbd
92 8365676dbab05860ce0d9110f2af51368b961bbd
93 0b2f73f04880d9cb6a5cd8a757f0db0ad01e32c3
93 0b2f73f04880d9cb6a5cd8a757f0db0ad01e32c3
94 4801a72e5d88cb515b0c7e40fae34180f3f837f2
94 4801a72e5d88cb515b0c7e40fae34180f3f837f2
95
95
96 Get from only one head:
96 Get from only one head:
97
97
98 $ hg debuggetbundle repo bundle -H 928b5f94cdb278bb536eba552de348a4e92ef24d -C 29a4d1f17bd3f0779ca0525bebb1cfb51067c738
98 $ hg debuggetbundle repo bundle -H 928b5f94cdb278bb536eba552de348a4e92ef24d -C 29a4d1f17bd3f0779ca0525bebb1cfb51067c738
99 $ hg debugbundle bundle
99 $ hg debugbundle bundle
100 8931463777131cd73923e560b760061f2aa8a4bc
100 8931463777131cd73923e560b760061f2aa8a4bc
101 f34414c64173e0ecb61b25dc55e116dbbcc89bee
101 f34414c64173e0ecb61b25dc55e116dbbcc89bee
102 928b5f94cdb278bb536eba552de348a4e92ef24d
102 928b5f94cdb278bb536eba552de348a4e92ef24d
103
103
104 Get parts of two branches:
104 Get parts of two branches:
105
105
106 $ hg debuggetbundle repo bundle -H 13c0170174366b441dc68e8e33757232fa744458 -C 700b7e19db54103633c4bf4a6a6b6d55f4d50c03 -H bac16991d12ff45f9dc43c52da1946dfadb83e80 -C d5f6e1ea452285324836a49d7d3c2a63cfed1d31
106 $ hg debuggetbundle repo bundle -H 13c0170174366b441dc68e8e33757232fa744458 -C 700b7e19db54103633c4bf4a6a6b6d55f4d50c03 -H bac16991d12ff45f9dc43c52da1946dfadb83e80 -C d5f6e1ea452285324836a49d7d3c2a63cfed1d31
107 $ hg debugbundle bundle
107 $ hg debugbundle bundle
108 ff42371d57168345fdf1a3aac66a51f6a45d41d2
108 ff42371d57168345fdf1a3aac66a51f6a45d41d2
109 bac16991d12ff45f9dc43c52da1946dfadb83e80
109 bac16991d12ff45f9dc43c52da1946dfadb83e80
110 63476832d8ec6558cf9bbe3cbe0c757e5cf18043
110 63476832d8ec6558cf9bbe3cbe0c757e5cf18043
111 13c0170174366b441dc68e8e33757232fa744458
111 13c0170174366b441dc68e8e33757232fa744458
112
112
113 Check that we get all needed file changes:
113 Check that we get all needed file changes:
114
114
115 $ hg debugbundle bundle --all
115 $ hg debugbundle bundle --all
116 format: id, p1, p2, cset, delta base, len(delta)
116 format: id, p1, p2, cset, delta base, len(delta)
117
117
118 changelog
118 changelog
119 ff42371d57168345fdf1a3aac66a51f6a45d41d2 d5f6e1ea452285324836a49d7d3c2a63cfed1d31 0000000000000000000000000000000000000000 ff42371d57168345fdf1a3aac66a51f6a45d41d2 d5f6e1ea452285324836a49d7d3c2a63cfed1d31 99
119 ff42371d57168345fdf1a3aac66a51f6a45d41d2 d5f6e1ea452285324836a49d7d3c2a63cfed1d31 0000000000000000000000000000000000000000 ff42371d57168345fdf1a3aac66a51f6a45d41d2 d5f6e1ea452285324836a49d7d3c2a63cfed1d31 99
120 bac16991d12ff45f9dc43c52da1946dfadb83e80 ff42371d57168345fdf1a3aac66a51f6a45d41d2 0000000000000000000000000000000000000000 bac16991d12ff45f9dc43c52da1946dfadb83e80 ff42371d57168345fdf1a3aac66a51f6a45d41d2 99
120 bac16991d12ff45f9dc43c52da1946dfadb83e80 ff42371d57168345fdf1a3aac66a51f6a45d41d2 0000000000000000000000000000000000000000 bac16991d12ff45f9dc43c52da1946dfadb83e80 ff42371d57168345fdf1a3aac66a51f6a45d41d2 99
121 63476832d8ec6558cf9bbe3cbe0c757e5cf18043 700b7e19db54103633c4bf4a6a6b6d55f4d50c03 0000000000000000000000000000000000000000 63476832d8ec6558cf9bbe3cbe0c757e5cf18043 bac16991d12ff45f9dc43c52da1946dfadb83e80 102
121 63476832d8ec6558cf9bbe3cbe0c757e5cf18043 700b7e19db54103633c4bf4a6a6b6d55f4d50c03 0000000000000000000000000000000000000000 63476832d8ec6558cf9bbe3cbe0c757e5cf18043 bac16991d12ff45f9dc43c52da1946dfadb83e80 102
122 13c0170174366b441dc68e8e33757232fa744458 63476832d8ec6558cf9bbe3cbe0c757e5cf18043 0000000000000000000000000000000000000000 13c0170174366b441dc68e8e33757232fa744458 63476832d8ec6558cf9bbe3cbe0c757e5cf18043 102
122 13c0170174366b441dc68e8e33757232fa744458 63476832d8ec6558cf9bbe3cbe0c757e5cf18043 0000000000000000000000000000000000000000 13c0170174366b441dc68e8e33757232fa744458 63476832d8ec6558cf9bbe3cbe0c757e5cf18043 102
123
123
124 manifest
124 manifest
125 dac7984588fc4eea7acbf39693a9c1b06f5b175d 591f732a3faf1fb903815273f3c199a514a61ccb 0000000000000000000000000000000000000000 ff42371d57168345fdf1a3aac66a51f6a45d41d2 591f732a3faf1fb903815273f3c199a514a61ccb 113
125 dac7984588fc4eea7acbf39693a9c1b06f5b175d 591f732a3faf1fb903815273f3c199a514a61ccb 0000000000000000000000000000000000000000 ff42371d57168345fdf1a3aac66a51f6a45d41d2 591f732a3faf1fb903815273f3c199a514a61ccb 113
126 0772616e6b48a76afb6c1458e193cbb3dae2e4ff dac7984588fc4eea7acbf39693a9c1b06f5b175d 0000000000000000000000000000000000000000 bac16991d12ff45f9dc43c52da1946dfadb83e80 dac7984588fc4eea7acbf39693a9c1b06f5b175d 113
126 0772616e6b48a76afb6c1458e193cbb3dae2e4ff dac7984588fc4eea7acbf39693a9c1b06f5b175d 0000000000000000000000000000000000000000 bac16991d12ff45f9dc43c52da1946dfadb83e80 dac7984588fc4eea7acbf39693a9c1b06f5b175d 113
127 eb498cd9af6c44108e43041e951ce829e29f6c80 bff2f4817ced57b386caf7c4e3e36a4bc9af7e93 0000000000000000000000000000000000000000 63476832d8ec6558cf9bbe3cbe0c757e5cf18043 0772616e6b48a76afb6c1458e193cbb3dae2e4ff 295
127 eb498cd9af6c44108e43041e951ce829e29f6c80 bff2f4817ced57b386caf7c4e3e36a4bc9af7e93 0000000000000000000000000000000000000000 63476832d8ec6558cf9bbe3cbe0c757e5cf18043 0772616e6b48a76afb6c1458e193cbb3dae2e4ff 295
128 b15709c071ddd2d93188508ba156196ab4f19620 eb498cd9af6c44108e43041e951ce829e29f6c80 0000000000000000000000000000000000000000 13c0170174366b441dc68e8e33757232fa744458 eb498cd9af6c44108e43041e951ce829e29f6c80 114
128 b15709c071ddd2d93188508ba156196ab4f19620 eb498cd9af6c44108e43041e951ce829e29f6c80 0000000000000000000000000000000000000000 13c0170174366b441dc68e8e33757232fa744458 eb498cd9af6c44108e43041e951ce829e29f6c80 114
129
129
130 mf
130 mf
131 4f73f97080266ab8e0c0561ca8d0da3eaf65b695 301ca08d026bb72cb4258a9d211bdf7ca0bcd810 0000000000000000000000000000000000000000 ff42371d57168345fdf1a3aac66a51f6a45d41d2 301ca08d026bb72cb4258a9d211bdf7ca0bcd810 17
131 4f73f97080266ab8e0c0561ca8d0da3eaf65b695 301ca08d026bb72cb4258a9d211bdf7ca0bcd810 0000000000000000000000000000000000000000 ff42371d57168345fdf1a3aac66a51f6a45d41d2 301ca08d026bb72cb4258a9d211bdf7ca0bcd810 17
132 c7b583de053293870e145f45bd2d61643563fd06 4f73f97080266ab8e0c0561ca8d0da3eaf65b695 0000000000000000000000000000000000000000 bac16991d12ff45f9dc43c52da1946dfadb83e80 4f73f97080266ab8e0c0561ca8d0da3eaf65b695 18
132 c7b583de053293870e145f45bd2d61643563fd06 4f73f97080266ab8e0c0561ca8d0da3eaf65b695 0000000000000000000000000000000000000000 bac16991d12ff45f9dc43c52da1946dfadb83e80 4f73f97080266ab8e0c0561ca8d0da3eaf65b695 18
133 266ee3c0302a5a18f1cf96817ac79a51836179e9 edc0f6b8db80d68ae6aff2b19f7e5347ab68fa63 0000000000000000000000000000000000000000 63476832d8ec6558cf9bbe3cbe0c757e5cf18043 c7b583de053293870e145f45bd2d61643563fd06 149
133 266ee3c0302a5a18f1cf96817ac79a51836179e9 edc0f6b8db80d68ae6aff2b19f7e5347ab68fa63 0000000000000000000000000000000000000000 63476832d8ec6558cf9bbe3cbe0c757e5cf18043 c7b583de053293870e145f45bd2d61643563fd06 149
134 698c6a36220548cd3903ca7dada27c59aa500c52 266ee3c0302a5a18f1cf96817ac79a51836179e9 0000000000000000000000000000000000000000 13c0170174366b441dc68e8e33757232fa744458 266ee3c0302a5a18f1cf96817ac79a51836179e9 19
134 698c6a36220548cd3903ca7dada27c59aa500c52 266ee3c0302a5a18f1cf96817ac79a51836179e9 0000000000000000000000000000000000000000 13c0170174366b441dc68e8e33757232fa744458 266ee3c0302a5a18f1cf96817ac79a51836179e9 19
135
135
136 nf11
136 nf11
137 33fbc651630ffa7ccbebfe4eb91320a873e7291c 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 63476832d8ec6558cf9bbe3cbe0c757e5cf18043 0000000000000000000000000000000000000000 16
137 33fbc651630ffa7ccbebfe4eb91320a873e7291c 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 63476832d8ec6558cf9bbe3cbe0c757e5cf18043 0000000000000000000000000000000000000000 16
138
138
139 nf12
139 nf12
140 ddce0544363f037e9fb889faca058f52dc01c0a5 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 13c0170174366b441dc68e8e33757232fa744458 0000000000000000000000000000000000000000 16
140 ddce0544363f037e9fb889faca058f52dc01c0a5 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 13c0170174366b441dc68e8e33757232fa744458 0000000000000000000000000000000000000000 16
141
141
142 nf4
142 nf4
143 3c1407305701051cbed9f9cb9a68bdfb5997c235 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 ff42371d57168345fdf1a3aac66a51f6a45d41d2 0000000000000000000000000000000000000000 15
143 3c1407305701051cbed9f9cb9a68bdfb5997c235 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 ff42371d57168345fdf1a3aac66a51f6a45d41d2 0000000000000000000000000000000000000000 15
144
144
145 nf5
145 nf5
146 0dbd89c185f53a1727c54cd1ce256482fa23968e 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 bac16991d12ff45f9dc43c52da1946dfadb83e80 0000000000000000000000000000000000000000 15
146 0dbd89c185f53a1727c54cd1ce256482fa23968e 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 bac16991d12ff45f9dc43c52da1946dfadb83e80 0000000000000000000000000000000000000000 15
147
147
148 Get branch and merge:
148 Get branch and merge:
149
149
150 $ hg debuggetbundle repo bundle -C 7704483d56b2a7b5db54dcee7c62378ac629b348 -H 0b2f73f04880d9cb6a5cd8a757f0db0ad01e32c3
150 $ hg debuggetbundle repo bundle -C 7704483d56b2a7b5db54dcee7c62378ac629b348 -H 0b2f73f04880d9cb6a5cd8a757f0db0ad01e32c3
151 $ hg debugbundle bundle
151 $ hg debugbundle bundle
152 29a4d1f17bd3f0779ca0525bebb1cfb51067c738
152 29a4d1f17bd3f0779ca0525bebb1cfb51067c738
153 713346a995c363120712aed1aee7e04afd867638
153 713346a995c363120712aed1aee7e04afd867638
154 d5f6e1ea452285324836a49d7d3c2a63cfed1d31
154 d5f6e1ea452285324836a49d7d3c2a63cfed1d31
155 ff42371d57168345fdf1a3aac66a51f6a45d41d2
155 ff42371d57168345fdf1a3aac66a51f6a45d41d2
156 bac16991d12ff45f9dc43c52da1946dfadb83e80
156 bac16991d12ff45f9dc43c52da1946dfadb83e80
157 6621d79f61b23ec74cf4b69464343d9e0980ec8b
157 6621d79f61b23ec74cf4b69464343d9e0980ec8b
158 8931463777131cd73923e560b760061f2aa8a4bc
158 8931463777131cd73923e560b760061f2aa8a4bc
159 f34414c64173e0ecb61b25dc55e116dbbcc89bee
159 f34414c64173e0ecb61b25dc55e116dbbcc89bee
160 928b5f94cdb278bb536eba552de348a4e92ef24d
160 928b5f94cdb278bb536eba552de348a4e92ef24d
161 700b7e19db54103633c4bf4a6a6b6d55f4d50c03
161 700b7e19db54103633c4bf4a6a6b6d55f4d50c03
162 63476832d8ec6558cf9bbe3cbe0c757e5cf18043
162 63476832d8ec6558cf9bbe3cbe0c757e5cf18043
163 13c0170174366b441dc68e8e33757232fa744458
163 13c0170174366b441dc68e8e33757232fa744458
164 5686dbbd9fc46cb806599c878d02fe1cb56b83d3
164 5686dbbd9fc46cb806599c878d02fe1cb56b83d3
165 8365676dbab05860ce0d9110f2af51368b961bbd
165 8365676dbab05860ce0d9110f2af51368b961bbd
166 0b2f73f04880d9cb6a5cd8a757f0db0ad01e32c3
166 0b2f73f04880d9cb6a5cd8a757f0db0ad01e32c3
167
167
168 = Test bundle2 =
168 = Test bundle2 =
169
169
170 $ hg debuggetbundle repo bundle -t bundle2
170 $ hg debuggetbundle repo bundle -t bundle2
171 $ hg debugbundle bundle
171 $ hg debugbundle bundle
172 Stream params: {}
172 Stream params: {}
173 changegroup -- "sortdict([('version', '01')])"
173 changegroup -- "sortdict([('version', '01'), ('nbchanges', '18')])"
174 7704483d56b2a7b5db54dcee7c62378ac629b348
174 7704483d56b2a7b5db54dcee7c62378ac629b348
175 29a4d1f17bd3f0779ca0525bebb1cfb51067c738
175 29a4d1f17bd3f0779ca0525bebb1cfb51067c738
176 713346a995c363120712aed1aee7e04afd867638
176 713346a995c363120712aed1aee7e04afd867638
177 d5f6e1ea452285324836a49d7d3c2a63cfed1d31
177 d5f6e1ea452285324836a49d7d3c2a63cfed1d31
178 ff42371d57168345fdf1a3aac66a51f6a45d41d2
178 ff42371d57168345fdf1a3aac66a51f6a45d41d2
179 bac16991d12ff45f9dc43c52da1946dfadb83e80
179 bac16991d12ff45f9dc43c52da1946dfadb83e80
180 6621d79f61b23ec74cf4b69464343d9e0980ec8b
180 6621d79f61b23ec74cf4b69464343d9e0980ec8b
181 8931463777131cd73923e560b760061f2aa8a4bc
181 8931463777131cd73923e560b760061f2aa8a4bc
182 f34414c64173e0ecb61b25dc55e116dbbcc89bee
182 f34414c64173e0ecb61b25dc55e116dbbcc89bee
183 928b5f94cdb278bb536eba552de348a4e92ef24d
183 928b5f94cdb278bb536eba552de348a4e92ef24d
184 700b7e19db54103633c4bf4a6a6b6d55f4d50c03
184 700b7e19db54103633c4bf4a6a6b6d55f4d50c03
185 63476832d8ec6558cf9bbe3cbe0c757e5cf18043
185 63476832d8ec6558cf9bbe3cbe0c757e5cf18043
186 13c0170174366b441dc68e8e33757232fa744458
186 13c0170174366b441dc68e8e33757232fa744458
187 5686dbbd9fc46cb806599c878d02fe1cb56b83d3
187 5686dbbd9fc46cb806599c878d02fe1cb56b83d3
188 8365676dbab05860ce0d9110f2af51368b961bbd
188 8365676dbab05860ce0d9110f2af51368b961bbd
189 0b2f73f04880d9cb6a5cd8a757f0db0ad01e32c3
189 0b2f73f04880d9cb6a5cd8a757f0db0ad01e32c3
190 4801a72e5d88cb515b0c7e40fae34180f3f837f2
190 4801a72e5d88cb515b0c7e40fae34180f3f837f2
191 10c14a2cc935e1d8c31f9e98587dcf27fb08a6da
191 10c14a2cc935e1d8c31f9e98587dcf27fb08a6da
192 = Test via HTTP =
192 = Test via HTTP =
193
193
194 Get everything:
194 Get everything:
195
195
196 $ hg serve -R repo -p $HGPORT -d --pid-file=hg.pid -E error.log -A access.log
196 $ hg serve -R repo -p $HGPORT -d --pid-file=hg.pid -E error.log -A access.log
197 $ cat hg.pid >> $DAEMON_PIDS
197 $ cat hg.pid >> $DAEMON_PIDS
198 $ hg debuggetbundle http://localhost:$HGPORT/ bundle
198 $ hg debuggetbundle http://localhost:$HGPORT/ bundle
199 $ hg debugbundle bundle
199 $ hg debugbundle bundle
200 7704483d56b2a7b5db54dcee7c62378ac629b348
200 7704483d56b2a7b5db54dcee7c62378ac629b348
201 29a4d1f17bd3f0779ca0525bebb1cfb51067c738
201 29a4d1f17bd3f0779ca0525bebb1cfb51067c738
202 713346a995c363120712aed1aee7e04afd867638
202 713346a995c363120712aed1aee7e04afd867638
203 d5f6e1ea452285324836a49d7d3c2a63cfed1d31
203 d5f6e1ea452285324836a49d7d3c2a63cfed1d31
204 ff42371d57168345fdf1a3aac66a51f6a45d41d2
204 ff42371d57168345fdf1a3aac66a51f6a45d41d2
205 bac16991d12ff45f9dc43c52da1946dfadb83e80
205 bac16991d12ff45f9dc43c52da1946dfadb83e80
206 6621d79f61b23ec74cf4b69464343d9e0980ec8b
206 6621d79f61b23ec74cf4b69464343d9e0980ec8b
207 8931463777131cd73923e560b760061f2aa8a4bc
207 8931463777131cd73923e560b760061f2aa8a4bc
208 f34414c64173e0ecb61b25dc55e116dbbcc89bee
208 f34414c64173e0ecb61b25dc55e116dbbcc89bee
209 928b5f94cdb278bb536eba552de348a4e92ef24d
209 928b5f94cdb278bb536eba552de348a4e92ef24d
210 700b7e19db54103633c4bf4a6a6b6d55f4d50c03
210 700b7e19db54103633c4bf4a6a6b6d55f4d50c03
211 63476832d8ec6558cf9bbe3cbe0c757e5cf18043
211 63476832d8ec6558cf9bbe3cbe0c757e5cf18043
212 13c0170174366b441dc68e8e33757232fa744458
212 13c0170174366b441dc68e8e33757232fa744458
213 5686dbbd9fc46cb806599c878d02fe1cb56b83d3
213 5686dbbd9fc46cb806599c878d02fe1cb56b83d3
214 8365676dbab05860ce0d9110f2af51368b961bbd
214 8365676dbab05860ce0d9110f2af51368b961bbd
215 0b2f73f04880d9cb6a5cd8a757f0db0ad01e32c3
215 0b2f73f04880d9cb6a5cd8a757f0db0ad01e32c3
216 4801a72e5d88cb515b0c7e40fae34180f3f837f2
216 4801a72e5d88cb515b0c7e40fae34180f3f837f2
217 10c14a2cc935e1d8c31f9e98587dcf27fb08a6da
217 10c14a2cc935e1d8c31f9e98587dcf27fb08a6da
218
218
219 Get parts of two branches:
219 Get parts of two branches:
220
220
221 $ hg debuggetbundle http://localhost:$HGPORT/ bundle -H 13c0170174366b441dc68e8e33757232fa744458 -C 700b7e19db54103633c4bf4a6a6b6d55f4d50c03 -H bac16991d12ff45f9dc43c52da1946dfadb83e80 -C d5f6e1ea452285324836a49d7d3c2a63cfed1d31
221 $ hg debuggetbundle http://localhost:$HGPORT/ bundle -H 13c0170174366b441dc68e8e33757232fa744458 -C 700b7e19db54103633c4bf4a6a6b6d55f4d50c03 -H bac16991d12ff45f9dc43c52da1946dfadb83e80 -C d5f6e1ea452285324836a49d7d3c2a63cfed1d31
222 $ hg debugbundle bundle
222 $ hg debugbundle bundle
223 ff42371d57168345fdf1a3aac66a51f6a45d41d2
223 ff42371d57168345fdf1a3aac66a51f6a45d41d2
224 bac16991d12ff45f9dc43c52da1946dfadb83e80
224 bac16991d12ff45f9dc43c52da1946dfadb83e80
225 63476832d8ec6558cf9bbe3cbe0c757e5cf18043
225 63476832d8ec6558cf9bbe3cbe0c757e5cf18043
226 13c0170174366b441dc68e8e33757232fa744458
226 13c0170174366b441dc68e8e33757232fa744458
227
227
228 Check that we get all needed file changes:
228 Check that we get all needed file changes:
229
229
230 $ hg debugbundle bundle --all
230 $ hg debugbundle bundle --all
231 format: id, p1, p2, cset, delta base, len(delta)
231 format: id, p1, p2, cset, delta base, len(delta)
232
232
233 changelog
233 changelog
234 ff42371d57168345fdf1a3aac66a51f6a45d41d2 d5f6e1ea452285324836a49d7d3c2a63cfed1d31 0000000000000000000000000000000000000000 ff42371d57168345fdf1a3aac66a51f6a45d41d2 d5f6e1ea452285324836a49d7d3c2a63cfed1d31 99
234 ff42371d57168345fdf1a3aac66a51f6a45d41d2 d5f6e1ea452285324836a49d7d3c2a63cfed1d31 0000000000000000000000000000000000000000 ff42371d57168345fdf1a3aac66a51f6a45d41d2 d5f6e1ea452285324836a49d7d3c2a63cfed1d31 99
235 bac16991d12ff45f9dc43c52da1946dfadb83e80 ff42371d57168345fdf1a3aac66a51f6a45d41d2 0000000000000000000000000000000000000000 bac16991d12ff45f9dc43c52da1946dfadb83e80 ff42371d57168345fdf1a3aac66a51f6a45d41d2 99
235 bac16991d12ff45f9dc43c52da1946dfadb83e80 ff42371d57168345fdf1a3aac66a51f6a45d41d2 0000000000000000000000000000000000000000 bac16991d12ff45f9dc43c52da1946dfadb83e80 ff42371d57168345fdf1a3aac66a51f6a45d41d2 99
236 63476832d8ec6558cf9bbe3cbe0c757e5cf18043 700b7e19db54103633c4bf4a6a6b6d55f4d50c03 0000000000000000000000000000000000000000 63476832d8ec6558cf9bbe3cbe0c757e5cf18043 bac16991d12ff45f9dc43c52da1946dfadb83e80 102
236 63476832d8ec6558cf9bbe3cbe0c757e5cf18043 700b7e19db54103633c4bf4a6a6b6d55f4d50c03 0000000000000000000000000000000000000000 63476832d8ec6558cf9bbe3cbe0c757e5cf18043 bac16991d12ff45f9dc43c52da1946dfadb83e80 102
237 13c0170174366b441dc68e8e33757232fa744458 63476832d8ec6558cf9bbe3cbe0c757e5cf18043 0000000000000000000000000000000000000000 13c0170174366b441dc68e8e33757232fa744458 63476832d8ec6558cf9bbe3cbe0c757e5cf18043 102
237 13c0170174366b441dc68e8e33757232fa744458 63476832d8ec6558cf9bbe3cbe0c757e5cf18043 0000000000000000000000000000000000000000 13c0170174366b441dc68e8e33757232fa744458 63476832d8ec6558cf9bbe3cbe0c757e5cf18043 102
238
238
239 manifest
239 manifest
240 dac7984588fc4eea7acbf39693a9c1b06f5b175d 591f732a3faf1fb903815273f3c199a514a61ccb 0000000000000000000000000000000000000000 ff42371d57168345fdf1a3aac66a51f6a45d41d2 591f732a3faf1fb903815273f3c199a514a61ccb 113
240 dac7984588fc4eea7acbf39693a9c1b06f5b175d 591f732a3faf1fb903815273f3c199a514a61ccb 0000000000000000000000000000000000000000 ff42371d57168345fdf1a3aac66a51f6a45d41d2 591f732a3faf1fb903815273f3c199a514a61ccb 113
241 0772616e6b48a76afb6c1458e193cbb3dae2e4ff dac7984588fc4eea7acbf39693a9c1b06f5b175d 0000000000000000000000000000000000000000 bac16991d12ff45f9dc43c52da1946dfadb83e80 dac7984588fc4eea7acbf39693a9c1b06f5b175d 113
241 0772616e6b48a76afb6c1458e193cbb3dae2e4ff dac7984588fc4eea7acbf39693a9c1b06f5b175d 0000000000000000000000000000000000000000 bac16991d12ff45f9dc43c52da1946dfadb83e80 dac7984588fc4eea7acbf39693a9c1b06f5b175d 113
242 eb498cd9af6c44108e43041e951ce829e29f6c80 bff2f4817ced57b386caf7c4e3e36a4bc9af7e93 0000000000000000000000000000000000000000 63476832d8ec6558cf9bbe3cbe0c757e5cf18043 0772616e6b48a76afb6c1458e193cbb3dae2e4ff 295
242 eb498cd9af6c44108e43041e951ce829e29f6c80 bff2f4817ced57b386caf7c4e3e36a4bc9af7e93 0000000000000000000000000000000000000000 63476832d8ec6558cf9bbe3cbe0c757e5cf18043 0772616e6b48a76afb6c1458e193cbb3dae2e4ff 295
243 b15709c071ddd2d93188508ba156196ab4f19620 eb498cd9af6c44108e43041e951ce829e29f6c80 0000000000000000000000000000000000000000 13c0170174366b441dc68e8e33757232fa744458 eb498cd9af6c44108e43041e951ce829e29f6c80 114
243 b15709c071ddd2d93188508ba156196ab4f19620 eb498cd9af6c44108e43041e951ce829e29f6c80 0000000000000000000000000000000000000000 13c0170174366b441dc68e8e33757232fa744458 eb498cd9af6c44108e43041e951ce829e29f6c80 114
244
244
245 mf
245 mf
246 4f73f97080266ab8e0c0561ca8d0da3eaf65b695 301ca08d026bb72cb4258a9d211bdf7ca0bcd810 0000000000000000000000000000000000000000 ff42371d57168345fdf1a3aac66a51f6a45d41d2 301ca08d026bb72cb4258a9d211bdf7ca0bcd810 17
246 4f73f97080266ab8e0c0561ca8d0da3eaf65b695 301ca08d026bb72cb4258a9d211bdf7ca0bcd810 0000000000000000000000000000000000000000 ff42371d57168345fdf1a3aac66a51f6a45d41d2 301ca08d026bb72cb4258a9d211bdf7ca0bcd810 17
247 c7b583de053293870e145f45bd2d61643563fd06 4f73f97080266ab8e0c0561ca8d0da3eaf65b695 0000000000000000000000000000000000000000 bac16991d12ff45f9dc43c52da1946dfadb83e80 4f73f97080266ab8e0c0561ca8d0da3eaf65b695 18
247 c7b583de053293870e145f45bd2d61643563fd06 4f73f97080266ab8e0c0561ca8d0da3eaf65b695 0000000000000000000000000000000000000000 bac16991d12ff45f9dc43c52da1946dfadb83e80 4f73f97080266ab8e0c0561ca8d0da3eaf65b695 18
248 266ee3c0302a5a18f1cf96817ac79a51836179e9 edc0f6b8db80d68ae6aff2b19f7e5347ab68fa63 0000000000000000000000000000000000000000 63476832d8ec6558cf9bbe3cbe0c757e5cf18043 c7b583de053293870e145f45bd2d61643563fd06 149
248 266ee3c0302a5a18f1cf96817ac79a51836179e9 edc0f6b8db80d68ae6aff2b19f7e5347ab68fa63 0000000000000000000000000000000000000000 63476832d8ec6558cf9bbe3cbe0c757e5cf18043 c7b583de053293870e145f45bd2d61643563fd06 149
249 698c6a36220548cd3903ca7dada27c59aa500c52 266ee3c0302a5a18f1cf96817ac79a51836179e9 0000000000000000000000000000000000000000 13c0170174366b441dc68e8e33757232fa744458 266ee3c0302a5a18f1cf96817ac79a51836179e9 19
249 698c6a36220548cd3903ca7dada27c59aa500c52 266ee3c0302a5a18f1cf96817ac79a51836179e9 0000000000000000000000000000000000000000 13c0170174366b441dc68e8e33757232fa744458 266ee3c0302a5a18f1cf96817ac79a51836179e9 19
250
250
251 nf11
251 nf11
252 33fbc651630ffa7ccbebfe4eb91320a873e7291c 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 63476832d8ec6558cf9bbe3cbe0c757e5cf18043 0000000000000000000000000000000000000000 16
252 33fbc651630ffa7ccbebfe4eb91320a873e7291c 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 63476832d8ec6558cf9bbe3cbe0c757e5cf18043 0000000000000000000000000000000000000000 16
253
253
254 nf12
254 nf12
255 ddce0544363f037e9fb889faca058f52dc01c0a5 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 13c0170174366b441dc68e8e33757232fa744458 0000000000000000000000000000000000000000 16
255 ddce0544363f037e9fb889faca058f52dc01c0a5 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 13c0170174366b441dc68e8e33757232fa744458 0000000000000000000000000000000000000000 16
256
256
257 nf4
257 nf4
258 3c1407305701051cbed9f9cb9a68bdfb5997c235 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 ff42371d57168345fdf1a3aac66a51f6a45d41d2 0000000000000000000000000000000000000000 15
258 3c1407305701051cbed9f9cb9a68bdfb5997c235 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 ff42371d57168345fdf1a3aac66a51f6a45d41d2 0000000000000000000000000000000000000000 15
259
259
260 nf5
260 nf5
261 0dbd89c185f53a1727c54cd1ce256482fa23968e 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 bac16991d12ff45f9dc43c52da1946dfadb83e80 0000000000000000000000000000000000000000 15
261 0dbd89c185f53a1727c54cd1ce256482fa23968e 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 bac16991d12ff45f9dc43c52da1946dfadb83e80 0000000000000000000000000000000000000000 15
262
262
263 Verify we hit the HTTP server:
263 Verify we hit the HTTP server:
264
264
265 $ cat access.log
265 $ cat access.log
266 * - - [*] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
266 * - - [*] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
267 * - - [*] "GET /?cmd=getbundle HTTP/1.1" 200 - (glob)
267 * - - [*] "GET /?cmd=getbundle HTTP/1.1" 200 - (glob)
268 * - - [*] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
268 * - - [*] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
269 * - - [*] "GET /?cmd=getbundle HTTP/1.1" 200 - x-hgarg-1:common=700b7e19db54103633c4bf4a6a6b6d55f4d50c03+d5f6e1ea452285324836a49d7d3c2a63cfed1d31&heads=13c0170174366b441dc68e8e33757232fa744458+bac16991d12ff45f9dc43c52da1946dfadb83e80 (glob)
269 * - - [*] "GET /?cmd=getbundle HTTP/1.1" 200 - x-hgarg-1:common=700b7e19db54103633c4bf4a6a6b6d55f4d50c03+d5f6e1ea452285324836a49d7d3c2a63cfed1d31&heads=13c0170174366b441dc68e8e33757232fa744458+bac16991d12ff45f9dc43c52da1946dfadb83e80 (glob)
270
270
271 $ cat error.log
271 $ cat error.log
272
272
@@ -1,2909 +1,2909 b''
1 Note for future hackers of patchbomb: this file is a bit heavy on
1 Note for future hackers of patchbomb: this file is a bit heavy on
2 wildcards in test expectations due to how many things like hostnames
2 wildcards in test expectations due to how many things like hostnames
3 tend to make it into outputs. As a result, you may need to perform the
3 tend to make it into outputs. As a result, you may need to perform the
4 following regular expression substitutions:
4 following regular expression substitutions:
5 @$HOSTNAME> -> @*> (glob)
5 @$HOSTNAME> -> @*> (glob)
6 Mercurial-patchbomb/.* -> Mercurial-patchbomb/* (glob)
6 Mercurial-patchbomb/.* -> Mercurial-patchbomb/* (glob)
7 /mixed; boundary="===+[0-9]+==" -> /mixed; boundary="===*== (glob)"
7 /mixed; boundary="===+[0-9]+==" -> /mixed; boundary="===*== (glob)"
8 --===+[0-9]+=+--$ -> --===*=-- (glob)
8 --===+[0-9]+=+--$ -> --===*=-- (glob)
9 --===+[0-9]+=+$ -> --===*= (glob)
9 --===+[0-9]+=+$ -> --===*= (glob)
10
10
11 $ cat > prune-blank-after-boundary.py <<EOF
11 $ cat > prune-blank-after-boundary.py <<EOF
12 > import sys
12 > import sys
13 > skipblank = False
13 > skipblank = False
14 > trim = lambda x: x.strip(' \r\n')
14 > trim = lambda x: x.strip(' \r\n')
15 > for l in sys.stdin:
15 > for l in sys.stdin:
16 > if trim(l).endswith('=--') or trim(l).endswith('=='):
16 > if trim(l).endswith('=--') or trim(l).endswith('=='):
17 > skipblank = True
17 > skipblank = True
18 > print l,
18 > print l,
19 > continue
19 > continue
20 > if not trim(l) and skipblank:
20 > if not trim(l) and skipblank:
21 > continue
21 > continue
22 > skipblank = False
22 > skipblank = False
23 > print l,
23 > print l,
24 > EOF
24 > EOF
25 $ FILTERBOUNDARY="python `pwd`/prune-blank-after-boundary.py"
25 $ FILTERBOUNDARY="python `pwd`/prune-blank-after-boundary.py"
26 $ echo "[format]" >> $HGRCPATH
26 $ echo "[format]" >> $HGRCPATH
27 $ echo "usegeneraldelta=yes" >> $HGRCPATH
27 $ echo "usegeneraldelta=yes" >> $HGRCPATH
28 $ echo "[extensions]" >> $HGRCPATH
28 $ echo "[extensions]" >> $HGRCPATH
29 $ echo "patchbomb=" >> $HGRCPATH
29 $ echo "patchbomb=" >> $HGRCPATH
30
30
31 Ensure hg email output is sent to stdout
31 Ensure hg email output is sent to stdout
32 $ unset PAGER
32 $ unset PAGER
33
33
34 $ hg init t
34 $ hg init t
35 $ cd t
35 $ cd t
36 $ echo a > a
36 $ echo a > a
37 $ hg commit -Ama -d '1 0'
37 $ hg commit -Ama -d '1 0'
38 adding a
38 adding a
39
39
40 $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -r tip
40 $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -r tip
41 this patch series consists of 1 patches.
41 this patch series consists of 1 patches.
42
42
43
43
44 displaying [PATCH] a ...
44 displaying [PATCH] a ...
45 Content-Type: text/plain; charset="us-ascii"
45 Content-Type: text/plain; charset="us-ascii"
46 MIME-Version: 1.0
46 MIME-Version: 1.0
47 Content-Transfer-Encoding: 7bit
47 Content-Transfer-Encoding: 7bit
48 Subject: [PATCH] a
48 Subject: [PATCH] a
49 X-Mercurial-Node: 8580ff50825a50c8f716709acdf8de0deddcd6ab
49 X-Mercurial-Node: 8580ff50825a50c8f716709acdf8de0deddcd6ab
50 X-Mercurial-Series-Index: 1
50 X-Mercurial-Series-Index: 1
51 X-Mercurial-Series-Total: 1
51 X-Mercurial-Series-Total: 1
52 Message-Id: <8580ff50825a50c8f716.60@*> (glob)
52 Message-Id: <8580ff50825a50c8f716.60@*> (glob)
53 X-Mercurial-Series-Id: <8580ff50825a50c8f716.60@*> (glob)
53 X-Mercurial-Series-Id: <8580ff50825a50c8f716.60@*> (glob)
54 User-Agent: Mercurial-patchbomb/* (glob)
54 User-Agent: Mercurial-patchbomb/* (glob)
55 Date: Thu, 01 Jan 1970 00:01:00 +0000
55 Date: Thu, 01 Jan 1970 00:01:00 +0000
56 From: quux
56 From: quux
57 To: foo
57 To: foo
58 Cc: bar
58 Cc: bar
59
59
60 # HG changeset patch
60 # HG changeset patch
61 # User test
61 # User test
62 # Date 1 0
62 # Date 1 0
63 # Thu Jan 01 00:00:01 1970 +0000
63 # Thu Jan 01 00:00:01 1970 +0000
64 # Node ID 8580ff50825a50c8f716709acdf8de0deddcd6ab
64 # Node ID 8580ff50825a50c8f716709acdf8de0deddcd6ab
65 # Parent 0000000000000000000000000000000000000000
65 # Parent 0000000000000000000000000000000000000000
66 a
66 a
67
67
68 diff -r 000000000000 -r 8580ff50825a a
68 diff -r 000000000000 -r 8580ff50825a a
69 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
69 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
70 +++ b/a Thu Jan 01 00:00:01 1970 +0000
70 +++ b/a Thu Jan 01 00:00:01 1970 +0000
71 @@ -0,0 +1,1 @@
71 @@ -0,0 +1,1 @@
72 +a
72 +a
73
73
74
74
75 $ hg --config ui.interactive=1 email --confirm -n -f quux -t foo -c bar -r tip<<EOF
75 $ hg --config ui.interactive=1 email --confirm -n -f quux -t foo -c bar -r tip<<EOF
76 > n
76 > n
77 > EOF
77 > EOF
78 this patch series consists of 1 patches.
78 this patch series consists of 1 patches.
79
79
80
80
81 Final summary:
81 Final summary:
82
82
83 From: quux
83 From: quux
84 To: foo
84 To: foo
85 Cc: bar
85 Cc: bar
86 Subject: [PATCH] a
86 Subject: [PATCH] a
87 a | 1 +
87 a | 1 +
88 1 files changed, 1 insertions(+), 0 deletions(-)
88 1 files changed, 1 insertions(+), 0 deletions(-)
89
89
90 are you sure you want to send (yn)? n
90 are you sure you want to send (yn)? n
91 abort: patchbomb canceled
91 abort: patchbomb canceled
92 [255]
92 [255]
93
93
94 $ hg --config ui.interactive=1 --config patchbomb.confirm=true email -n -f quux -t foo -c bar -r tip<<EOF
94 $ hg --config ui.interactive=1 --config patchbomb.confirm=true email -n -f quux -t foo -c bar -r tip<<EOF
95 > n
95 > n
96 > EOF
96 > EOF
97 this patch series consists of 1 patches.
97 this patch series consists of 1 patches.
98
98
99
99
100 Final summary:
100 Final summary:
101
101
102 From: quux
102 From: quux
103 To: foo
103 To: foo
104 Cc: bar
104 Cc: bar
105 Subject: [PATCH] a
105 Subject: [PATCH] a
106 a | 1 +
106 a | 1 +
107 1 files changed, 1 insertions(+), 0 deletions(-)
107 1 files changed, 1 insertions(+), 0 deletions(-)
108
108
109 are you sure you want to send (yn)? n
109 are you sure you want to send (yn)? n
110 abort: patchbomb canceled
110 abort: patchbomb canceled
111 [255]
111 [255]
112
112
113
113
114 Test diff.git is respected
114 Test diff.git is respected
115 $ hg --config diff.git=True email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -r tip
115 $ hg --config diff.git=True email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -r tip
116 this patch series consists of 1 patches.
116 this patch series consists of 1 patches.
117
117
118
118
119 displaying [PATCH] a ...
119 displaying [PATCH] a ...
120 Content-Type: text/plain; charset="us-ascii"
120 Content-Type: text/plain; charset="us-ascii"
121 MIME-Version: 1.0
121 MIME-Version: 1.0
122 Content-Transfer-Encoding: 7bit
122 Content-Transfer-Encoding: 7bit
123 Subject: [PATCH] a
123 Subject: [PATCH] a
124 X-Mercurial-Node: 8580ff50825a50c8f716709acdf8de0deddcd6ab
124 X-Mercurial-Node: 8580ff50825a50c8f716709acdf8de0deddcd6ab
125 X-Mercurial-Series-Index: 1
125 X-Mercurial-Series-Index: 1
126 X-Mercurial-Series-Total: 1
126 X-Mercurial-Series-Total: 1
127 Message-Id: <8580ff50825a50c8f716.60@*> (glob)
127 Message-Id: <8580ff50825a50c8f716.60@*> (glob)
128 X-Mercurial-Series-Id: <8580ff50825a50c8f716.60@*> (glob)
128 X-Mercurial-Series-Id: <8580ff50825a50c8f716.60@*> (glob)
129 User-Agent: Mercurial-patchbomb/* (glob)
129 User-Agent: Mercurial-patchbomb/* (glob)
130 Date: Thu, 01 Jan 1970 00:01:00 +0000
130 Date: Thu, 01 Jan 1970 00:01:00 +0000
131 From: quux
131 From: quux
132 To: foo
132 To: foo
133 Cc: bar
133 Cc: bar
134
134
135 # HG changeset patch
135 # HG changeset patch
136 # User test
136 # User test
137 # Date 1 0
137 # Date 1 0
138 # Thu Jan 01 00:00:01 1970 +0000
138 # Thu Jan 01 00:00:01 1970 +0000
139 # Node ID 8580ff50825a50c8f716709acdf8de0deddcd6ab
139 # Node ID 8580ff50825a50c8f716709acdf8de0deddcd6ab
140 # Parent 0000000000000000000000000000000000000000
140 # Parent 0000000000000000000000000000000000000000
141 a
141 a
142
142
143 diff --git a/a b/a
143 diff --git a/a b/a
144 new file mode 100644
144 new file mode 100644
145 --- /dev/null
145 --- /dev/null
146 +++ b/a
146 +++ b/a
147 @@ -0,0 +1,1 @@
147 @@ -0,0 +1,1 @@
148 +a
148 +a
149
149
150
150
151
151
152 Test breaking format changes aren't
152 Test breaking format changes aren't
153 $ hg --config diff.noprefix=True email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -r tip
153 $ hg --config diff.noprefix=True email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -r tip
154 this patch series consists of 1 patches.
154 this patch series consists of 1 patches.
155
155
156
156
157 displaying [PATCH] a ...
157 displaying [PATCH] a ...
158 Content-Type: text/plain; charset="us-ascii"
158 Content-Type: text/plain; charset="us-ascii"
159 MIME-Version: 1.0
159 MIME-Version: 1.0
160 Content-Transfer-Encoding: 7bit
160 Content-Transfer-Encoding: 7bit
161 Subject: [PATCH] a
161 Subject: [PATCH] a
162 X-Mercurial-Node: 8580ff50825a50c8f716709acdf8de0deddcd6ab
162 X-Mercurial-Node: 8580ff50825a50c8f716709acdf8de0deddcd6ab
163 X-Mercurial-Series-Index: 1
163 X-Mercurial-Series-Index: 1
164 X-Mercurial-Series-Total: 1
164 X-Mercurial-Series-Total: 1
165 Message-Id: <8580ff50825a50c8f716.60@*> (glob)
165 Message-Id: <8580ff50825a50c8f716.60@*> (glob)
166 X-Mercurial-Series-Id: <8580ff50825a50c8f716.60@*> (glob)
166 X-Mercurial-Series-Id: <8580ff50825a50c8f716.60@*> (glob)
167 User-Agent: Mercurial-patchbomb/* (glob)
167 User-Agent: Mercurial-patchbomb/* (glob)
168 Date: Thu, 01 Jan 1970 00:01:00 +0000
168 Date: Thu, 01 Jan 1970 00:01:00 +0000
169 From: quux
169 From: quux
170 To: foo
170 To: foo
171 Cc: bar
171 Cc: bar
172
172
173 # HG changeset patch
173 # HG changeset patch
174 # User test
174 # User test
175 # Date 1 0
175 # Date 1 0
176 # Thu Jan 01 00:00:01 1970 +0000
176 # Thu Jan 01 00:00:01 1970 +0000
177 # Node ID 8580ff50825a50c8f716709acdf8de0deddcd6ab
177 # Node ID 8580ff50825a50c8f716709acdf8de0deddcd6ab
178 # Parent 0000000000000000000000000000000000000000
178 # Parent 0000000000000000000000000000000000000000
179 a
179 a
180
180
181 diff -r 000000000000 -r 8580ff50825a a
181 diff -r 000000000000 -r 8580ff50825a a
182 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
182 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
183 +++ b/a Thu Jan 01 00:00:01 1970 +0000
183 +++ b/a Thu Jan 01 00:00:01 1970 +0000
184 @@ -0,0 +1,1 @@
184 @@ -0,0 +1,1 @@
185 +a
185 +a
186
186
187
187
188 $ echo b > b
188 $ echo b > b
189 $ hg commit -Amb -d '2 0'
189 $ hg commit -Amb -d '2 0'
190 adding b
190 adding b
191
191
192 $ hg email --date '1970-1-1 0:2' -n -f quux -t foo -c bar -s test -r 0:tip
192 $ hg email --date '1970-1-1 0:2' -n -f quux -t foo -c bar -s test -r 0:tip
193 this patch series consists of 2 patches.
193 this patch series consists of 2 patches.
194
194
195
195
196 Write the introductory message for the patch series.
196 Write the introductory message for the patch series.
197
197
198
198
199 displaying [PATCH 0 of 2] test ...
199 displaying [PATCH 0 of 2] test ...
200 Content-Type: text/plain; charset="us-ascii"
200 Content-Type: text/plain; charset="us-ascii"
201 MIME-Version: 1.0
201 MIME-Version: 1.0
202 Content-Transfer-Encoding: 7bit
202 Content-Transfer-Encoding: 7bit
203 Subject: [PATCH 0 of 2] test
203 Subject: [PATCH 0 of 2] test
204 Message-Id: <patchbomb.120@*> (glob)
204 Message-Id: <patchbomb.120@*> (glob)
205 User-Agent: Mercurial-patchbomb/* (glob)
205 User-Agent: Mercurial-patchbomb/* (glob)
206 Date: Thu, 01 Jan 1970 00:02:00 +0000
206 Date: Thu, 01 Jan 1970 00:02:00 +0000
207 From: quux
207 From: quux
208 To: foo
208 To: foo
209 Cc: bar
209 Cc: bar
210
210
211
211
212 displaying [PATCH 1 of 2] a ...
212 displaying [PATCH 1 of 2] a ...
213 Content-Type: text/plain; charset="us-ascii"
213 Content-Type: text/plain; charset="us-ascii"
214 MIME-Version: 1.0
214 MIME-Version: 1.0
215 Content-Transfer-Encoding: 7bit
215 Content-Transfer-Encoding: 7bit
216 Subject: [PATCH 1 of 2] a
216 Subject: [PATCH 1 of 2] a
217 X-Mercurial-Node: 8580ff50825a50c8f716709acdf8de0deddcd6ab
217 X-Mercurial-Node: 8580ff50825a50c8f716709acdf8de0deddcd6ab
218 X-Mercurial-Series-Index: 1
218 X-Mercurial-Series-Index: 1
219 X-Mercurial-Series-Total: 2
219 X-Mercurial-Series-Total: 2
220 Message-Id: <8580ff50825a50c8f716.121@*> (glob)
220 Message-Id: <8580ff50825a50c8f716.121@*> (glob)
221 X-Mercurial-Series-Id: <8580ff50825a50c8f716.121@*> (glob)
221 X-Mercurial-Series-Id: <8580ff50825a50c8f716.121@*> (glob)
222 In-Reply-To: <patchbomb.120@*> (glob)
222 In-Reply-To: <patchbomb.120@*> (glob)
223 References: <patchbomb.120@*> (glob)
223 References: <patchbomb.120@*> (glob)
224 User-Agent: Mercurial-patchbomb/* (glob)
224 User-Agent: Mercurial-patchbomb/* (glob)
225 Date: Thu, 01 Jan 1970 00:02:01 +0000
225 Date: Thu, 01 Jan 1970 00:02:01 +0000
226 From: quux
226 From: quux
227 To: foo
227 To: foo
228 Cc: bar
228 Cc: bar
229
229
230 # HG changeset patch
230 # HG changeset patch
231 # User test
231 # User test
232 # Date 1 0
232 # Date 1 0
233 # Thu Jan 01 00:00:01 1970 +0000
233 # Thu Jan 01 00:00:01 1970 +0000
234 # Node ID 8580ff50825a50c8f716709acdf8de0deddcd6ab
234 # Node ID 8580ff50825a50c8f716709acdf8de0deddcd6ab
235 # Parent 0000000000000000000000000000000000000000
235 # Parent 0000000000000000000000000000000000000000
236 a
236 a
237
237
238 diff -r 000000000000 -r 8580ff50825a a
238 diff -r 000000000000 -r 8580ff50825a a
239 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
239 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
240 +++ b/a Thu Jan 01 00:00:01 1970 +0000
240 +++ b/a Thu Jan 01 00:00:01 1970 +0000
241 @@ -0,0 +1,1 @@
241 @@ -0,0 +1,1 @@
242 +a
242 +a
243
243
244 displaying [PATCH 2 of 2] b ...
244 displaying [PATCH 2 of 2] b ...
245 Content-Type: text/plain; charset="us-ascii"
245 Content-Type: text/plain; charset="us-ascii"
246 MIME-Version: 1.0
246 MIME-Version: 1.0
247 Content-Transfer-Encoding: 7bit
247 Content-Transfer-Encoding: 7bit
248 Subject: [PATCH 2 of 2] b
248 Subject: [PATCH 2 of 2] b
249 X-Mercurial-Node: 97d72e5f12c7e84f85064aa72e5a297142c36ed9
249 X-Mercurial-Node: 97d72e5f12c7e84f85064aa72e5a297142c36ed9
250 X-Mercurial-Series-Index: 2
250 X-Mercurial-Series-Index: 2
251 X-Mercurial-Series-Total: 2
251 X-Mercurial-Series-Total: 2
252 Message-Id: <97d72e5f12c7e84f8506.122@*> (glob)
252 Message-Id: <97d72e5f12c7e84f8506.122@*> (glob)
253 X-Mercurial-Series-Id: <8580ff50825a50c8f716.121@*> (glob)
253 X-Mercurial-Series-Id: <8580ff50825a50c8f716.121@*> (glob)
254 In-Reply-To: <patchbomb.120@*> (glob)
254 In-Reply-To: <patchbomb.120@*> (glob)
255 References: <patchbomb.120@*> (glob)
255 References: <patchbomb.120@*> (glob)
256 User-Agent: Mercurial-patchbomb/* (glob)
256 User-Agent: Mercurial-patchbomb/* (glob)
257 Date: Thu, 01 Jan 1970 00:02:02 +0000
257 Date: Thu, 01 Jan 1970 00:02:02 +0000
258 From: quux
258 From: quux
259 To: foo
259 To: foo
260 Cc: bar
260 Cc: bar
261
261
262 # HG changeset patch
262 # HG changeset patch
263 # User test
263 # User test
264 # Date 2 0
264 # Date 2 0
265 # Thu Jan 01 00:00:02 1970 +0000
265 # Thu Jan 01 00:00:02 1970 +0000
266 # Node ID 97d72e5f12c7e84f85064aa72e5a297142c36ed9
266 # Node ID 97d72e5f12c7e84f85064aa72e5a297142c36ed9
267 # Parent 8580ff50825a50c8f716709acdf8de0deddcd6ab
267 # Parent 8580ff50825a50c8f716709acdf8de0deddcd6ab
268 b
268 b
269
269
270 diff -r 8580ff50825a -r 97d72e5f12c7 b
270 diff -r 8580ff50825a -r 97d72e5f12c7 b
271 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
271 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
272 +++ b/b Thu Jan 01 00:00:02 1970 +0000
272 +++ b/b Thu Jan 01 00:00:02 1970 +0000
273 @@ -0,0 +1,1 @@
273 @@ -0,0 +1,1 @@
274 +b
274 +b
275
275
276
276
277 .hg/last-email.txt
277 .hg/last-email.txt
278
278
279 $ cat > editor.sh << '__EOF__'
279 $ cat > editor.sh << '__EOF__'
280 > echo "a precious introductory message" > "$1"
280 > echo "a precious introductory message" > "$1"
281 > __EOF__
281 > __EOF__
282 $ HGEDITOR="\"sh\" \"`pwd`/editor.sh\"" hg email -n -t foo -s test -r 0:tip > /dev/null
282 $ HGEDITOR="\"sh\" \"`pwd`/editor.sh\"" hg email -n -t foo -s test -r 0:tip > /dev/null
283 $ cat .hg/last-email.txt
283 $ cat .hg/last-email.txt
284 a precious introductory message
284 a precious introductory message
285
285
286 $ hg email -m test.mbox -f quux -t foo -c bar -s test 0:tip \
286 $ hg email -m test.mbox -f quux -t foo -c bar -s test 0:tip \
287 > --config extensions.progress= --config progress.assume-tty=1 \
287 > --config extensions.progress= --config progress.assume-tty=1 \
288 > --config progress.delay=0 --config progress.refresh=0 \
288 > --config progress.delay=0 --config progress.refresh=0 \
289 > --config progress.width=60
289 > --config progress.width=60
290 this patch series consists of 2 patches.
290 this patch series consists of 2 patches.
291
291
292
292
293 Write the introductory message for the patch series.
293 Write the introductory message for the patch series.
294
294
295 \r (no-eol) (esc)
295 \r (no-eol) (esc)
296 sending [ ] 0/3\r (no-eol) (esc)
296 sending [ ] 0/3\r (no-eol) (esc)
297 \r (no-eol) (esc)
297 \r (no-eol) (esc)
298 \r (no-eol) (esc)
298 \r (no-eol) (esc)
299 sending [==============> ] 1/3\r (no-eol) (esc)
299 sending [==============> ] 1/3\r (no-eol) (esc)
300 \r (no-eol) (esc)
300 \r (no-eol) (esc)
301 \r (no-eol) (esc)
301 \r (no-eol) (esc)
302 sending [=============================> ] 2/3\r (no-eol) (esc)
302 sending [=============================> ] 2/3\r (no-eol) (esc)
303 \r (esc)
303 \r (esc)
304 sending [PATCH 0 of 2] test ...
304 sending [PATCH 0 of 2] test ...
305 sending [PATCH 1 of 2] a ...
305 sending [PATCH 1 of 2] a ...
306 sending [PATCH 2 of 2] b ...
306 sending [PATCH 2 of 2] b ...
307
307
308 $ cd ..
308 $ cd ..
309
309
310 $ hg clone -q t t2
310 $ hg clone -q t t2
311 $ cd t2
311 $ cd t2
312 $ echo c > c
312 $ echo c > c
313 $ hg commit -Amc -d '3 0'
313 $ hg commit -Amc -d '3 0'
314 adding c
314 adding c
315
315
316 $ cat > description <<EOF
316 $ cat > description <<EOF
317 > a multiline
317 > a multiline
318 >
318 >
319 > description
319 > description
320 > EOF
320 > EOF
321
321
322
322
323 test bundle and description:
323 test bundle and description:
324 $ hg email --date '1970-1-1 0:3' -n -f quux -t foo \
324 $ hg email --date '1970-1-1 0:3' -n -f quux -t foo \
325 > -c bar -s test -r tip -b --desc description | $FILTERBOUNDARY
325 > -c bar -s test -r tip -b --desc description | $FILTERBOUNDARY
326 searching for changes
326 searching for changes
327 1 changesets found
327 1 changesets found
328
328
329 displaying test ...
329 displaying test ...
330 Content-Type: multipart/mixed; boundary="===*==" (glob)
330 Content-Type: multipart/mixed; boundary="===*==" (glob)
331 MIME-Version: 1.0
331 MIME-Version: 1.0
332 Subject: test
332 Subject: test
333 Message-Id: <patchbomb.180@*> (glob)
333 Message-Id: <patchbomb.180@*> (glob)
334 User-Agent: Mercurial-patchbomb/* (glob)
334 User-Agent: Mercurial-patchbomb/* (glob)
335 Date: Thu, 01 Jan 1970 00:03:00 +0000
335 Date: Thu, 01 Jan 1970 00:03:00 +0000
336 From: quux
336 From: quux
337 To: foo
337 To: foo
338 Cc: bar
338 Cc: bar
339
339
340 --===*= (glob)
340 --===*= (glob)
341 Content-Type: text/plain; charset="us-ascii"
341 Content-Type: text/plain; charset="us-ascii"
342 MIME-Version: 1.0
342 MIME-Version: 1.0
343 Content-Transfer-Encoding: 7bit
343 Content-Transfer-Encoding: 7bit
344
344
345 a multiline
345 a multiline
346
346
347 description
347 description
348
348
349 --===*= (glob)
349 --===*= (glob)
350 Content-Type: application/x-mercurial-bundle
350 Content-Type: application/x-mercurial-bundle
351 MIME-Version: 1.0
351 MIME-Version: 1.0
352 Content-Disposition: attachment; filename="bundle.hg"
352 Content-Disposition: attachment; filename="bundle.hg"
353 Content-Transfer-Encoding: base64
353 Content-Transfer-Encoding: base64
354
354
355 SEcyMAAAAA5Db21wcmVzc2lvbj1CWkJaaDkxQVkmU1lCZFwPAAAKf//7nFYSWD1/4H7R09C/I70I
355 SEcyMAAAAA5Db21wcmVzc2lvbj1CWkJaaDkxQVkmU1kIqE7KAAAKf//7vFYQWD1/4H7R09C/470I
356 Ak0E4peoSIYIgQCgGUQOcLABGY2hqoAAAaBMTTAAAahgTCZoAAAAAMQaqn5GmapojQ00DEGI/VGJ
356 Ak0E4peoSIYIgQCgGUQOcLABGY2hqoTTCYaBqaYAAACaaMAATIwAA1MIYDaQaqn6p+jRop+oJkA2
357 kDAJoGTDUAAyM0QaAEqalPTUaMhoyDIDR6IxAGEGmgAehMRhDRsoyB6TYTC8JyLN+jTGqitRAgRJ
357 oNqD1PU0PUBoxqaMmjMUepoBoDT1GmQNBKmlTT1GTCNMEAYTQ0NNDI0BoMQHpAZAA8o2pkyNJHfX
358 b3SRlhd8/+VxlAUqAilLoKPEEyxFQkaEGo+DzItFeNiFAo8NMMweVtvXJFIMhjoKC18DeYwjLKBz
358 RRbXoyxKRUlAg41B3lpmMOnr77dEpFKAvEUGEkWuC4wioiMjC2Y2a84EXhsNCFIrbXUGId07PJnS
359 wrMcs86qJrctDNJorwBMuLcqvTVWHh1IlsIaaaYSUIP2IZsogT1+pSSZS+bSTJrgfKsO9go/f0HF
359 ELAOIpL/gE8R8CUeXuw2NKMtkFoLPkcTSomXtgHSg1IKaCNlWwVU3CpmMYqh5gkFYJKOD4UhVVQ6
360 uW4Yr2vXpxDreOgSIAdK/xC8Yay48SLpxIuqc/BZ6rVZCgG21rr0zhCaEgXOTqNaYEvANvg0B0Qo
360 SiF1DpE8ghWvF1ih+fYgagfYHI96w/QsrRATpYiP7VRbINFrQy2c21mZ7M4pXXrPBypoXAIhtum7
361 dgtqAs1FDcZgzYitwJh6ZAG0C4mA7FPrp9b7h0h/A44Xgd+0it1gvF0mFE/CCPwymXS+OisOOCAF
361 aKDJCpUqMDF5dfiDChMfgH9nQ4B60Uvgb4AK9dsbSYc+O3tEyNq9g9gZeA5Je2T82GzjC4DbY4F2
362 mDUDAC1pBvsXckU4UJBCZFwP
362 0kdrTBwslErFshCgDzeEBwICg13oQaQawQA1WWd3F3JFOFCQCKhOyg==
363 --===============*==-- (glob)
363 --===============*==-- (glob)
364
364
365 with a specific bundle type
365 with a specific bundle type
366 (binary part must be different)
366 (binary part must be different)
367
367
368 $ hg email --date '1970-1-1 0:3' -n -f quux -t foo \
368 $ hg email --date '1970-1-1 0:3' -n -f quux -t foo \
369 > -c bar -s test -r tip -b --desc description \
369 > -c bar -s test -r tip -b --desc description \
370 > --config patchbomb.bundletype=gzip-v1 | $FILTERBOUNDARY
370 > --config patchbomb.bundletype=gzip-v1 | $FILTERBOUNDARY
371 searching for changes
371 searching for changes
372 1 changesets found
372 1 changesets found
373
373
374 displaying test ...
374 displaying test ...
375 Content-Type: multipart/mixed; boundary="===*==" (glob)
375 Content-Type: multipart/mixed; boundary="===*==" (glob)
376 MIME-Version: 1.0
376 MIME-Version: 1.0
377 Subject: test
377 Subject: test
378 Message-Id: <patchbomb.180@*> (glob)
378 Message-Id: <patchbomb.180@*> (glob)
379 User-Agent: Mercurial-patchbomb/* (glob)
379 User-Agent: Mercurial-patchbomb/* (glob)
380 Date: Thu, 01 Jan 1970 00:03:00 +0000
380 Date: Thu, 01 Jan 1970 00:03:00 +0000
381 From: quux
381 From: quux
382 To: foo
382 To: foo
383 Cc: bar
383 Cc: bar
384
384
385 --===*= (glob)
385 --===*= (glob)
386 Content-Type: text/plain; charset="us-ascii"
386 Content-Type: text/plain; charset="us-ascii"
387 MIME-Version: 1.0
387 MIME-Version: 1.0
388 Content-Transfer-Encoding: 7bit
388 Content-Transfer-Encoding: 7bit
389
389
390 a multiline
390 a multiline
391
391
392 description
392 description
393
393
394 --===*= (glob)
394 --===*= (glob)
395 Content-Type: application/x-mercurial-bundle
395 Content-Type: application/x-mercurial-bundle
396 MIME-Version: 1.0
396 MIME-Version: 1.0
397 Content-Disposition: attachment; filename="bundle.hg"
397 Content-Disposition: attachment; filename="bundle.hg"
398 Content-Transfer-Encoding: base64
398 Content-Transfer-Encoding: base64
399
399
400 SEcxMEdaeJxjYGBY8V9n/iLGbtFfJZuNk/euDCpWfrRy/vTrevFCx1/4t7J5LdeL0ix0Opx3kwEL
400 SEcxMEdaeJxjYGBY8V9n/iLGbtFfJZuNk/euDCpWfrRy/vTrevFCx1/4t7J5LdeL0ix0Opx3kwEL
401 wKYXKqUJwqnG5sYWSWmmJsaWlqYWaRaWJpaWiWamZpYWRgZGxolJiabmSQbmZqlcQMV6QGwCxGzG
401 wKYXKqUJwqnG5sYWSWmmJsaWlqYWaRaWJpaWiWamZpYWRgZGxolJiabmSQbmZqlcQMV6QGwCxGzG
402 CgZcySARUyA2A2LGZKiZ3Y+Lu786z4z4MWXmsrAZCsqrl1az5y21PMcjpbThzWeXGT+/nutbmvvz
402 CgZcySARUyA2A2LGZKiZ3Y+Lu786z4z4MWXmsrAZCsqrl1az5y21PMcjpbThzWeXGT+/nutbmvvz
403 zXYS3BoGxdrJDIYmlimJJiZpRokmqYYmaSYWFknmSSkmhqbmliamiZYWxuYmBhbJBgZcUBNZQe5K
403 zXYS3BoGxdrJDIYmlimJJiZpRokmqYYmaSYWFknmSSkmhqbmliamiZYWxuYmBhbJBgZcUBNZQe5K
404 Epm7xF/LT+RLx/a9juFTomaYO/Rgsx4rwBN+IMCUDLOKAQBrsmti
404 Epm7xF/LT+RLx/a9juFTomaYO/Rgsx4rwBN+IMCUDLOKAQBrsmti
405 --===============*==-- (glob)
405 --===============*==-- (glob)
406
406
407 utf-8 patch:
407 utf-8 patch:
408 $ $PYTHON -c 'fp = open("utf", "wb"); fp.write("h\xC3\xB6mma!\n"); fp.close();'
408 $ $PYTHON -c 'fp = open("utf", "wb"); fp.write("h\xC3\xB6mma!\n"); fp.close();'
409 $ hg commit -A -d '4 0' -m 'utf-8 content'
409 $ hg commit -A -d '4 0' -m 'utf-8 content'
410 adding description
410 adding description
411 adding utf
411 adding utf
412
412
413 no mime encoding for email --test:
413 no mime encoding for email --test:
414 $ hg email --date '1970-1-1 0:4' -f quux -t foo -c bar -r tip -n
414 $ hg email --date '1970-1-1 0:4' -f quux -t foo -c bar -r tip -n
415 this patch series consists of 1 patches.
415 this patch series consists of 1 patches.
416
416
417
417
418 displaying [PATCH] utf-8 content ...
418 displaying [PATCH] utf-8 content ...
419 Content-Type: text/plain; charset="us-ascii"
419 Content-Type: text/plain; charset="us-ascii"
420 MIME-Version: 1.0
420 MIME-Version: 1.0
421 Content-Transfer-Encoding: 8bit
421 Content-Transfer-Encoding: 8bit
422 Subject: [PATCH] utf-8 content
422 Subject: [PATCH] utf-8 content
423 X-Mercurial-Node: 909a00e13e9d78b575aeee23dddbada46d5a143f
423 X-Mercurial-Node: 909a00e13e9d78b575aeee23dddbada46d5a143f
424 X-Mercurial-Series-Index: 1
424 X-Mercurial-Series-Index: 1
425 X-Mercurial-Series-Total: 1
425 X-Mercurial-Series-Total: 1
426 Message-Id: <909a00e13e9d78b575ae.240@*> (glob)
426 Message-Id: <909a00e13e9d78b575ae.240@*> (glob)
427 X-Mercurial-Series-Id: <909a00e13e9d78b575ae.240@*> (glob)
427 X-Mercurial-Series-Id: <909a00e13e9d78b575ae.240@*> (glob)
428 User-Agent: Mercurial-patchbomb/* (glob)
428 User-Agent: Mercurial-patchbomb/* (glob)
429 Date: Thu, 01 Jan 1970 00:04:00 +0000
429 Date: Thu, 01 Jan 1970 00:04:00 +0000
430 From: quux
430 From: quux
431 To: foo
431 To: foo
432 Cc: bar
432 Cc: bar
433
433
434 # HG changeset patch
434 # HG changeset patch
435 # User test
435 # User test
436 # Date 4 0
436 # Date 4 0
437 # Thu Jan 01 00:00:04 1970 +0000
437 # Thu Jan 01 00:00:04 1970 +0000
438 # Node ID 909a00e13e9d78b575aeee23dddbada46d5a143f
438 # Node ID 909a00e13e9d78b575aeee23dddbada46d5a143f
439 # Parent ff2c9fa2018b15fa74b33363bda9527323e2a99f
439 # Parent ff2c9fa2018b15fa74b33363bda9527323e2a99f
440 utf-8 content
440 utf-8 content
441
441
442 diff -r ff2c9fa2018b -r 909a00e13e9d description
442 diff -r ff2c9fa2018b -r 909a00e13e9d description
443 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
443 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
444 +++ b/description Thu Jan 01 00:00:04 1970 +0000
444 +++ b/description Thu Jan 01 00:00:04 1970 +0000
445 @@ -0,0 +1,3 @@
445 @@ -0,0 +1,3 @@
446 +a multiline
446 +a multiline
447 +
447 +
448 +description
448 +description
449 diff -r ff2c9fa2018b -r 909a00e13e9d utf
449 diff -r ff2c9fa2018b -r 909a00e13e9d utf
450 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
450 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
451 +++ b/utf Thu Jan 01 00:00:04 1970 +0000
451 +++ b/utf Thu Jan 01 00:00:04 1970 +0000
452 @@ -0,0 +1,1 @@
452 @@ -0,0 +1,1 @@
453 +h\xc3\xb6mma! (esc)
453 +h\xc3\xb6mma! (esc)
454
454
455
455
456 mime encoded mbox (base64):
456 mime encoded mbox (base64):
457 $ hg email --date '1970-1-1 0:4' -f 'Q <quux>' -t foo -c bar -r tip -m mbox
457 $ hg email --date '1970-1-1 0:4' -f 'Q <quux>' -t foo -c bar -r tip -m mbox
458 this patch series consists of 1 patches.
458 this patch series consists of 1 patches.
459
459
460
460
461 sending [PATCH] utf-8 content ...
461 sending [PATCH] utf-8 content ...
462
462
463 $ cat mbox
463 $ cat mbox
464 From quux ... ... .. ..:..:.. .... (re)
464 From quux ... ... .. ..:..:.. .... (re)
465 Content-Type: text/plain; charset="utf-8"
465 Content-Type: text/plain; charset="utf-8"
466 MIME-Version: 1.0
466 MIME-Version: 1.0
467 Content-Transfer-Encoding: base64
467 Content-Transfer-Encoding: base64
468 Subject: [PATCH] utf-8 content
468 Subject: [PATCH] utf-8 content
469 X-Mercurial-Node: 909a00e13e9d78b575aeee23dddbada46d5a143f
469 X-Mercurial-Node: 909a00e13e9d78b575aeee23dddbada46d5a143f
470 X-Mercurial-Series-Index: 1
470 X-Mercurial-Series-Index: 1
471 X-Mercurial-Series-Total: 1
471 X-Mercurial-Series-Total: 1
472 Message-Id: <909a00e13e9d78b575ae.240@*> (glob)
472 Message-Id: <909a00e13e9d78b575ae.240@*> (glob)
473 X-Mercurial-Series-Id: <909a00e13e9d78b575ae.240@*> (glob)
473 X-Mercurial-Series-Id: <909a00e13e9d78b575ae.240@*> (glob)
474 User-Agent: Mercurial-patchbomb/* (glob)
474 User-Agent: Mercurial-patchbomb/* (glob)
475 Date: Thu, 01 Jan 1970 00:04:00 +0000
475 Date: Thu, 01 Jan 1970 00:04:00 +0000
476 From: Q <quux>
476 From: Q <quux>
477 To: foo
477 To: foo
478 Cc: bar
478 Cc: bar
479
479
480 IyBIRyBjaGFuZ2VzZXQgcGF0Y2gKIyBVc2VyIHRlc3QKIyBEYXRlIDQgMAojICAgICAgVGh1IEph
480 IyBIRyBjaGFuZ2VzZXQgcGF0Y2gKIyBVc2VyIHRlc3QKIyBEYXRlIDQgMAojICAgICAgVGh1IEph
481 biAwMSAwMDowMDowNCAxOTcwICswMDAwCiMgTm9kZSBJRCA5MDlhMDBlMTNlOWQ3OGI1NzVhZWVl
481 biAwMSAwMDowMDowNCAxOTcwICswMDAwCiMgTm9kZSBJRCA5MDlhMDBlMTNlOWQ3OGI1NzVhZWVl
482 MjNkZGRiYWRhNDZkNWExNDNmCiMgUGFyZW50ICBmZjJjOWZhMjAxOGIxNWZhNzRiMzMzNjNiZGE5
482 MjNkZGRiYWRhNDZkNWExNDNmCiMgUGFyZW50ICBmZjJjOWZhMjAxOGIxNWZhNzRiMzMzNjNiZGE5
483 NTI3MzIzZTJhOTlmCnV0Zi04IGNvbnRlbnQKCmRpZmYgLXIgZmYyYzlmYTIwMThiIC1yIDkwOWEw
483 NTI3MzIzZTJhOTlmCnV0Zi04IGNvbnRlbnQKCmRpZmYgLXIgZmYyYzlmYTIwMThiIC1yIDkwOWEw
484 MGUxM2U5ZCBkZXNjcmlwdGlvbgotLS0gL2Rldi9udWxsCVRodSBKYW4gMDEgMDA6MDA6MDAgMTk3
484 MGUxM2U5ZCBkZXNjcmlwdGlvbgotLS0gL2Rldi9udWxsCVRodSBKYW4gMDEgMDA6MDA6MDAgMTk3
485 MCArMDAwMAorKysgYi9kZXNjcmlwdGlvbglUaHUgSmFuIDAxIDAwOjAwOjA0IDE5NzAgKzAwMDAK
485 MCArMDAwMAorKysgYi9kZXNjcmlwdGlvbglUaHUgSmFuIDAxIDAwOjAwOjA0IDE5NzAgKzAwMDAK
486 QEAgLTAsMCArMSwzIEBACithIG11bHRpbGluZQorCitkZXNjcmlwdGlvbgpkaWZmIC1yIGZmMmM5
486 QEAgLTAsMCArMSwzIEBACithIG11bHRpbGluZQorCitkZXNjcmlwdGlvbgpkaWZmIC1yIGZmMmM5
487 ZmEyMDE4YiAtciA5MDlhMDBlMTNlOWQgdXRmCi0tLSAvZGV2L251bGwJVGh1IEphbiAwMSAwMDow
487 ZmEyMDE4YiAtciA5MDlhMDBlMTNlOWQgdXRmCi0tLSAvZGV2L251bGwJVGh1IEphbiAwMSAwMDow
488 MDowMCAxOTcwICswMDAwCisrKyBiL3V0ZglUaHUgSmFuIDAxIDAwOjAwOjA0IDE5NzAgKzAwMDAK
488 MDowMCAxOTcwICswMDAwCisrKyBiL3V0ZglUaHUgSmFuIDAxIDAwOjAwOjA0IDE5NzAgKzAwMDAK
489 QEAgLTAsMCArMSwxIEBACitow7ZtbWEhCg==
489 QEAgLTAsMCArMSwxIEBACitow7ZtbWEhCg==
490
490
491
491
492 $ $PYTHON -c 'print open("mbox").read().split("\n\n")[1].decode("base64")'
492 $ $PYTHON -c 'print open("mbox").read().split("\n\n")[1].decode("base64")'
493 # HG changeset patch
493 # HG changeset patch
494 # User test
494 # User test
495 # Date 4 0
495 # Date 4 0
496 # Thu Jan 01 00:00:04 1970 +0000
496 # Thu Jan 01 00:00:04 1970 +0000
497 # Node ID 909a00e13e9d78b575aeee23dddbada46d5a143f
497 # Node ID 909a00e13e9d78b575aeee23dddbada46d5a143f
498 # Parent ff2c9fa2018b15fa74b33363bda9527323e2a99f
498 # Parent ff2c9fa2018b15fa74b33363bda9527323e2a99f
499 utf-8 content
499 utf-8 content
500
500
501 diff -r ff2c9fa2018b -r 909a00e13e9d description
501 diff -r ff2c9fa2018b -r 909a00e13e9d description
502 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
502 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
503 +++ b/description Thu Jan 01 00:00:04 1970 +0000
503 +++ b/description Thu Jan 01 00:00:04 1970 +0000
504 @@ -0,0 +1,3 @@
504 @@ -0,0 +1,3 @@
505 +a multiline
505 +a multiline
506 +
506 +
507 +description
507 +description
508 diff -r ff2c9fa2018b -r 909a00e13e9d utf
508 diff -r ff2c9fa2018b -r 909a00e13e9d utf
509 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
509 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
510 +++ b/utf Thu Jan 01 00:00:04 1970 +0000
510 +++ b/utf Thu Jan 01 00:00:04 1970 +0000
511 @@ -0,0 +1,1 @@
511 @@ -0,0 +1,1 @@
512 +h\xc3\xb6mma! (esc)
512 +h\xc3\xb6mma! (esc)
513
513
514 $ rm mbox
514 $ rm mbox
515
515
516 mime encoded mbox (quoted-printable):
516 mime encoded mbox (quoted-printable):
517 $ $PYTHON -c 'fp = open("long", "wb"); fp.write("%s\nfoo\n\nbar\n" % ("x" * 1024)); fp.close();'
517 $ $PYTHON -c 'fp = open("long", "wb"); fp.write("%s\nfoo\n\nbar\n" % ("x" * 1024)); fp.close();'
518 $ hg commit -A -d '4 0' -m 'long line'
518 $ hg commit -A -d '4 0' -m 'long line'
519 adding long
519 adding long
520
520
521 no mime encoding for email --test:
521 no mime encoding for email --test:
522 $ hg email --date '1970-1-1 0:4' -f quux -t foo -c bar -r tip -n
522 $ hg email --date '1970-1-1 0:4' -f quux -t foo -c bar -r tip -n
523 this patch series consists of 1 patches.
523 this patch series consists of 1 patches.
524
524
525
525
526 displaying [PATCH] long line ...
526 displaying [PATCH] long line ...
527 Content-Type: text/plain; charset="us-ascii"
527 Content-Type: text/plain; charset="us-ascii"
528 MIME-Version: 1.0
528 MIME-Version: 1.0
529 Content-Transfer-Encoding: quoted-printable
529 Content-Transfer-Encoding: quoted-printable
530 Subject: [PATCH] long line
530 Subject: [PATCH] long line
531 X-Mercurial-Node: a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
531 X-Mercurial-Node: a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
532 X-Mercurial-Series-Index: 1
532 X-Mercurial-Series-Index: 1
533 X-Mercurial-Series-Total: 1
533 X-Mercurial-Series-Total: 1
534 Message-Id: <a2ea8fc83dd8b93cfd86.240@*> (glob)
534 Message-Id: <a2ea8fc83dd8b93cfd86.240@*> (glob)
535 X-Mercurial-Series-Id: <a2ea8fc83dd8b93cfd86.240@*> (glob)
535 X-Mercurial-Series-Id: <a2ea8fc83dd8b93cfd86.240@*> (glob)
536 User-Agent: Mercurial-patchbomb/* (glob)
536 User-Agent: Mercurial-patchbomb/* (glob)
537 Date: Thu, 01 Jan 1970 00:04:00 +0000
537 Date: Thu, 01 Jan 1970 00:04:00 +0000
538 From: quux
538 From: quux
539 To: foo
539 To: foo
540 Cc: bar
540 Cc: bar
541
541
542 # HG changeset patch
542 # HG changeset patch
543 # User test
543 # User test
544 # Date 4 0
544 # Date 4 0
545 # Thu Jan 01 00:00:04 1970 +0000
545 # Thu Jan 01 00:00:04 1970 +0000
546 # Node ID a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
546 # Node ID a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
547 # Parent 909a00e13e9d78b575aeee23dddbada46d5a143f
547 # Parent 909a00e13e9d78b575aeee23dddbada46d5a143f
548 long line
548 long line
549
549
550 diff -r 909a00e13e9d -r a2ea8fc83dd8 long
550 diff -r 909a00e13e9d -r a2ea8fc83dd8 long
551 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
551 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
552 +++ b/long Thu Jan 01 00:00:04 1970 +0000
552 +++ b/long Thu Jan 01 00:00:04 1970 +0000
553 @@ -0,0 +1,4 @@
553 @@ -0,0 +1,4 @@
554 +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
554 +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
555 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
555 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
556 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
556 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
557 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
557 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
558 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
558 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
559 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
559 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
560 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
560 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
561 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
561 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
562 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
562 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
563 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
563 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
564 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
564 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
565 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
565 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
566 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
566 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
567 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
567 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
568 +foo
568 +foo
569 +
569 +
570 +bar
570 +bar
571
571
572
572
573 mime encoded mbox (quoted-printable):
573 mime encoded mbox (quoted-printable):
574 $ hg email --date '1970-1-1 0:4' -f quux -t foo -c bar -r tip -m mbox
574 $ hg email --date '1970-1-1 0:4' -f quux -t foo -c bar -r tip -m mbox
575 this patch series consists of 1 patches.
575 this patch series consists of 1 patches.
576
576
577
577
578 sending [PATCH] long line ...
578 sending [PATCH] long line ...
579 $ cat mbox
579 $ cat mbox
580 From quux ... ... .. ..:..:.. .... (re)
580 From quux ... ... .. ..:..:.. .... (re)
581 Content-Type: text/plain; charset="us-ascii"
581 Content-Type: text/plain; charset="us-ascii"
582 MIME-Version: 1.0
582 MIME-Version: 1.0
583 Content-Transfer-Encoding: quoted-printable
583 Content-Transfer-Encoding: quoted-printable
584 Subject: [PATCH] long line
584 Subject: [PATCH] long line
585 X-Mercurial-Node: a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
585 X-Mercurial-Node: a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
586 X-Mercurial-Series-Index: 1
586 X-Mercurial-Series-Index: 1
587 X-Mercurial-Series-Total: 1
587 X-Mercurial-Series-Total: 1
588 Message-Id: <a2ea8fc83dd8b93cfd86.240@*> (glob)
588 Message-Id: <a2ea8fc83dd8b93cfd86.240@*> (glob)
589 X-Mercurial-Series-Id: <a2ea8fc83dd8b93cfd86.240@*> (glob)
589 X-Mercurial-Series-Id: <a2ea8fc83dd8b93cfd86.240@*> (glob)
590 User-Agent: Mercurial-patchbomb/* (glob)
590 User-Agent: Mercurial-patchbomb/* (glob)
591 Date: Thu, 01 Jan 1970 00:04:00 +0000
591 Date: Thu, 01 Jan 1970 00:04:00 +0000
592 From: quux
592 From: quux
593 To: foo
593 To: foo
594 Cc: bar
594 Cc: bar
595
595
596 # HG changeset patch
596 # HG changeset patch
597 # User test
597 # User test
598 # Date 4 0
598 # Date 4 0
599 # Thu Jan 01 00:00:04 1970 +0000
599 # Thu Jan 01 00:00:04 1970 +0000
600 # Node ID a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
600 # Node ID a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
601 # Parent 909a00e13e9d78b575aeee23dddbada46d5a143f
601 # Parent 909a00e13e9d78b575aeee23dddbada46d5a143f
602 long line
602 long line
603
603
604 diff -r 909a00e13e9d -r a2ea8fc83dd8 long
604 diff -r 909a00e13e9d -r a2ea8fc83dd8 long
605 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
605 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
606 +++ b/long Thu Jan 01 00:00:04 1970 +0000
606 +++ b/long Thu Jan 01 00:00:04 1970 +0000
607 @@ -0,0 +1,4 @@
607 @@ -0,0 +1,4 @@
608 +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
608 +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
609 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
609 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
610 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
610 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
611 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
611 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
612 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
612 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
613 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
613 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
614 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
614 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
615 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
615 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
616 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
616 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
617 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
617 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
618 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
618 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
619 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
619 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
620 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
620 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
621 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
621 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
622 +foo
622 +foo
623 +
623 +
624 +bar
624 +bar
625
625
626
626
627
627
628 $ rm mbox
628 $ rm mbox
629
629
630 iso-8859-1 patch:
630 iso-8859-1 patch:
631 $ $PYTHON -c 'fp = open("isolatin", "wb"); fp.write("h\xF6mma!\n"); fp.close();'
631 $ $PYTHON -c 'fp = open("isolatin", "wb"); fp.write("h\xF6mma!\n"); fp.close();'
632 $ hg commit -A -d '5 0' -m 'isolatin 8-bit encoding'
632 $ hg commit -A -d '5 0' -m 'isolatin 8-bit encoding'
633 adding isolatin
633 adding isolatin
634
634
635 fake ascii mbox:
635 fake ascii mbox:
636 $ hg email --date '1970-1-1 0:5' -f quux -t foo -c bar -r tip -m mbox
636 $ hg email --date '1970-1-1 0:5' -f quux -t foo -c bar -r tip -m mbox
637 this patch series consists of 1 patches.
637 this patch series consists of 1 patches.
638
638
639
639
640 sending [PATCH] isolatin 8-bit encoding ...
640 sending [PATCH] isolatin 8-bit encoding ...
641 $ cat mbox
641 $ cat mbox
642 From quux ... ... .. ..:..:.. .... (re)
642 From quux ... ... .. ..:..:.. .... (re)
643 Content-Type: text/plain; charset="us-ascii"
643 Content-Type: text/plain; charset="us-ascii"
644 MIME-Version: 1.0
644 MIME-Version: 1.0
645 Content-Transfer-Encoding: 8bit
645 Content-Transfer-Encoding: 8bit
646 Subject: [PATCH] isolatin 8-bit encoding
646 Subject: [PATCH] isolatin 8-bit encoding
647 X-Mercurial-Node: 240fb913fc1b7ff15ddb9f33e73d82bf5277c720
647 X-Mercurial-Node: 240fb913fc1b7ff15ddb9f33e73d82bf5277c720
648 X-Mercurial-Series-Index: 1
648 X-Mercurial-Series-Index: 1
649 X-Mercurial-Series-Total: 1
649 X-Mercurial-Series-Total: 1
650 Message-Id: <240fb913fc1b7ff15ddb.300@*> (glob)
650 Message-Id: <240fb913fc1b7ff15ddb.300@*> (glob)
651 X-Mercurial-Series-Id: <240fb913fc1b7ff15ddb.300@*> (glob)
651 X-Mercurial-Series-Id: <240fb913fc1b7ff15ddb.300@*> (glob)
652 User-Agent: Mercurial-patchbomb/* (glob)
652 User-Agent: Mercurial-patchbomb/* (glob)
653 Date: Thu, 01 Jan 1970 00:05:00 +0000
653 Date: Thu, 01 Jan 1970 00:05:00 +0000
654 From: quux
654 From: quux
655 To: foo
655 To: foo
656 Cc: bar
656 Cc: bar
657
657
658 # HG changeset patch
658 # HG changeset patch
659 # User test
659 # User test
660 # Date 5 0
660 # Date 5 0
661 # Thu Jan 01 00:00:05 1970 +0000
661 # Thu Jan 01 00:00:05 1970 +0000
662 # Node ID 240fb913fc1b7ff15ddb9f33e73d82bf5277c720
662 # Node ID 240fb913fc1b7ff15ddb9f33e73d82bf5277c720
663 # Parent a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
663 # Parent a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
664 isolatin 8-bit encoding
664 isolatin 8-bit encoding
665
665
666 diff -r a2ea8fc83dd8 -r 240fb913fc1b isolatin
666 diff -r a2ea8fc83dd8 -r 240fb913fc1b isolatin
667 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
667 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
668 +++ b/isolatin Thu Jan 01 00:00:05 1970 +0000
668 +++ b/isolatin Thu Jan 01 00:00:05 1970 +0000
669 @@ -0,0 +1,1 @@
669 @@ -0,0 +1,1 @@
670 +h\xf6mma! (esc)
670 +h\xf6mma! (esc)
671
671
672
672
673
673
674 test diffstat for single patch:
674 test diffstat for single patch:
675 $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -d -y -r 2
675 $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -d -y -r 2
676 this patch series consists of 1 patches.
676 this patch series consists of 1 patches.
677
677
678
678
679 Final summary:
679 Final summary:
680
680
681 From: quux
681 From: quux
682 To: foo
682 To: foo
683 Cc: bar
683 Cc: bar
684 Subject: [PATCH] test
684 Subject: [PATCH] test
685 c | 1 +
685 c | 1 +
686 1 files changed, 1 insertions(+), 0 deletions(-)
686 1 files changed, 1 insertions(+), 0 deletions(-)
687
687
688 are you sure you want to send (yn)? y
688 are you sure you want to send (yn)? y
689
689
690 displaying [PATCH] test ...
690 displaying [PATCH] test ...
691 Content-Type: text/plain; charset="us-ascii"
691 Content-Type: text/plain; charset="us-ascii"
692 MIME-Version: 1.0
692 MIME-Version: 1.0
693 Content-Transfer-Encoding: 7bit
693 Content-Transfer-Encoding: 7bit
694 Subject: [PATCH] test
694 Subject: [PATCH] test
695 X-Mercurial-Node: ff2c9fa2018b15fa74b33363bda9527323e2a99f
695 X-Mercurial-Node: ff2c9fa2018b15fa74b33363bda9527323e2a99f
696 X-Mercurial-Series-Index: 1
696 X-Mercurial-Series-Index: 1
697 X-Mercurial-Series-Total: 1
697 X-Mercurial-Series-Total: 1
698 Message-Id: <ff2c9fa2018b15fa74b3.60@*> (glob)
698 Message-Id: <ff2c9fa2018b15fa74b3.60@*> (glob)
699 X-Mercurial-Series-Id: <ff2c9fa2018b15fa74b3.60@*> (glob)
699 X-Mercurial-Series-Id: <ff2c9fa2018b15fa74b3.60@*> (glob)
700 User-Agent: Mercurial-patchbomb/* (glob)
700 User-Agent: Mercurial-patchbomb/* (glob)
701 Date: Thu, 01 Jan 1970 00:01:00 +0000
701 Date: Thu, 01 Jan 1970 00:01:00 +0000
702 From: quux
702 From: quux
703 To: foo
703 To: foo
704 Cc: bar
704 Cc: bar
705
705
706 c | 1 +
706 c | 1 +
707 1 files changed, 1 insertions(+), 0 deletions(-)
707 1 files changed, 1 insertions(+), 0 deletions(-)
708
708
709
709
710 # HG changeset patch
710 # HG changeset patch
711 # User test
711 # User test
712 # Date 3 0
712 # Date 3 0
713 # Thu Jan 01 00:00:03 1970 +0000
713 # Thu Jan 01 00:00:03 1970 +0000
714 # Node ID ff2c9fa2018b15fa74b33363bda9527323e2a99f
714 # Node ID ff2c9fa2018b15fa74b33363bda9527323e2a99f
715 # Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9
715 # Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9
716 c
716 c
717
717
718 diff -r 97d72e5f12c7 -r ff2c9fa2018b c
718 diff -r 97d72e5f12c7 -r ff2c9fa2018b c
719 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
719 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
720 +++ b/c Thu Jan 01 00:00:03 1970 +0000
720 +++ b/c Thu Jan 01 00:00:03 1970 +0000
721 @@ -0,0 +1,1 @@
721 @@ -0,0 +1,1 @@
722 +c
722 +c
723
723
724
724
725 test diffstat for multiple patches:
725 test diffstat for multiple patches:
726 $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -d -y \
726 $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -d -y \
727 > -r 0:1
727 > -r 0:1
728 this patch series consists of 2 patches.
728 this patch series consists of 2 patches.
729
729
730
730
731 Write the introductory message for the patch series.
731 Write the introductory message for the patch series.
732
732
733
733
734 Final summary:
734 Final summary:
735
735
736 From: quux
736 From: quux
737 To: foo
737 To: foo
738 Cc: bar
738 Cc: bar
739 Subject: [PATCH 0 of 2] test
739 Subject: [PATCH 0 of 2] test
740 a | 1 +
740 a | 1 +
741 b | 1 +
741 b | 1 +
742 2 files changed, 2 insertions(+), 0 deletions(-)
742 2 files changed, 2 insertions(+), 0 deletions(-)
743 Subject: [PATCH 1 of 2] a
743 Subject: [PATCH 1 of 2] a
744 a | 1 +
744 a | 1 +
745 1 files changed, 1 insertions(+), 0 deletions(-)
745 1 files changed, 1 insertions(+), 0 deletions(-)
746 Subject: [PATCH 2 of 2] b
746 Subject: [PATCH 2 of 2] b
747 b | 1 +
747 b | 1 +
748 1 files changed, 1 insertions(+), 0 deletions(-)
748 1 files changed, 1 insertions(+), 0 deletions(-)
749
749
750 are you sure you want to send (yn)? y
750 are you sure you want to send (yn)? y
751
751
752 displaying [PATCH 0 of 2] test ...
752 displaying [PATCH 0 of 2] test ...
753 Content-Type: text/plain; charset="us-ascii"
753 Content-Type: text/plain; charset="us-ascii"
754 MIME-Version: 1.0
754 MIME-Version: 1.0
755 Content-Transfer-Encoding: 7bit
755 Content-Transfer-Encoding: 7bit
756 Subject: [PATCH 0 of 2] test
756 Subject: [PATCH 0 of 2] test
757 Message-Id: <patchbomb.60@*> (glob)
757 Message-Id: <patchbomb.60@*> (glob)
758 User-Agent: Mercurial-patchbomb/* (glob)
758 User-Agent: Mercurial-patchbomb/* (glob)
759 Date: Thu, 01 Jan 1970 00:01:00 +0000
759 Date: Thu, 01 Jan 1970 00:01:00 +0000
760 From: quux
760 From: quux
761 To: foo
761 To: foo
762 Cc: bar
762 Cc: bar
763
763
764
764
765 a | 1 +
765 a | 1 +
766 b | 1 +
766 b | 1 +
767 2 files changed, 2 insertions(+), 0 deletions(-)
767 2 files changed, 2 insertions(+), 0 deletions(-)
768
768
769 displaying [PATCH 1 of 2] a ...
769 displaying [PATCH 1 of 2] a ...
770 Content-Type: text/plain; charset="us-ascii"
770 Content-Type: text/plain; charset="us-ascii"
771 MIME-Version: 1.0
771 MIME-Version: 1.0
772 Content-Transfer-Encoding: 7bit
772 Content-Transfer-Encoding: 7bit
773 Subject: [PATCH 1 of 2] a
773 Subject: [PATCH 1 of 2] a
774 X-Mercurial-Node: 8580ff50825a50c8f716709acdf8de0deddcd6ab
774 X-Mercurial-Node: 8580ff50825a50c8f716709acdf8de0deddcd6ab
775 X-Mercurial-Series-Index: 1
775 X-Mercurial-Series-Index: 1
776 X-Mercurial-Series-Total: 2
776 X-Mercurial-Series-Total: 2
777 Message-Id: <8580ff50825a50c8f716.61@*> (glob)
777 Message-Id: <8580ff50825a50c8f716.61@*> (glob)
778 X-Mercurial-Series-Id: <8580ff50825a50c8f716.61@*> (glob)
778 X-Mercurial-Series-Id: <8580ff50825a50c8f716.61@*> (glob)
779 In-Reply-To: <patchbomb.60@*> (glob)
779 In-Reply-To: <patchbomb.60@*> (glob)
780 References: <patchbomb.60@*> (glob)
780 References: <patchbomb.60@*> (glob)
781 User-Agent: Mercurial-patchbomb/* (glob)
781 User-Agent: Mercurial-patchbomb/* (glob)
782 Date: Thu, 01 Jan 1970 00:01:01 +0000
782 Date: Thu, 01 Jan 1970 00:01:01 +0000
783 From: quux
783 From: quux
784 To: foo
784 To: foo
785 Cc: bar
785 Cc: bar
786
786
787 a | 1 +
787 a | 1 +
788 1 files changed, 1 insertions(+), 0 deletions(-)
788 1 files changed, 1 insertions(+), 0 deletions(-)
789
789
790
790
791 # HG changeset patch
791 # HG changeset patch
792 # User test
792 # User test
793 # Date 1 0
793 # Date 1 0
794 # Thu Jan 01 00:00:01 1970 +0000
794 # Thu Jan 01 00:00:01 1970 +0000
795 # Node ID 8580ff50825a50c8f716709acdf8de0deddcd6ab
795 # Node ID 8580ff50825a50c8f716709acdf8de0deddcd6ab
796 # Parent 0000000000000000000000000000000000000000
796 # Parent 0000000000000000000000000000000000000000
797 a
797 a
798
798
799 diff -r 000000000000 -r 8580ff50825a a
799 diff -r 000000000000 -r 8580ff50825a a
800 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
800 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
801 +++ b/a Thu Jan 01 00:00:01 1970 +0000
801 +++ b/a Thu Jan 01 00:00:01 1970 +0000
802 @@ -0,0 +1,1 @@
802 @@ -0,0 +1,1 @@
803 +a
803 +a
804
804
805 displaying [PATCH 2 of 2] b ...
805 displaying [PATCH 2 of 2] b ...
806 Content-Type: text/plain; charset="us-ascii"
806 Content-Type: text/plain; charset="us-ascii"
807 MIME-Version: 1.0
807 MIME-Version: 1.0
808 Content-Transfer-Encoding: 7bit
808 Content-Transfer-Encoding: 7bit
809 Subject: [PATCH 2 of 2] b
809 Subject: [PATCH 2 of 2] b
810 X-Mercurial-Node: 97d72e5f12c7e84f85064aa72e5a297142c36ed9
810 X-Mercurial-Node: 97d72e5f12c7e84f85064aa72e5a297142c36ed9
811 X-Mercurial-Series-Index: 2
811 X-Mercurial-Series-Index: 2
812 X-Mercurial-Series-Total: 2
812 X-Mercurial-Series-Total: 2
813 Message-Id: <97d72e5f12c7e84f8506.62@*> (glob)
813 Message-Id: <97d72e5f12c7e84f8506.62@*> (glob)
814 X-Mercurial-Series-Id: <8580ff50825a50c8f716.61@*> (glob)
814 X-Mercurial-Series-Id: <8580ff50825a50c8f716.61@*> (glob)
815 In-Reply-To: <patchbomb.60@*> (glob)
815 In-Reply-To: <patchbomb.60@*> (glob)
816 References: <patchbomb.60@*> (glob)
816 References: <patchbomb.60@*> (glob)
817 User-Agent: Mercurial-patchbomb/* (glob)
817 User-Agent: Mercurial-patchbomb/* (glob)
818 Date: Thu, 01 Jan 1970 00:01:02 +0000
818 Date: Thu, 01 Jan 1970 00:01:02 +0000
819 From: quux
819 From: quux
820 To: foo
820 To: foo
821 Cc: bar
821 Cc: bar
822
822
823 b | 1 +
823 b | 1 +
824 1 files changed, 1 insertions(+), 0 deletions(-)
824 1 files changed, 1 insertions(+), 0 deletions(-)
825
825
826
826
827 # HG changeset patch
827 # HG changeset patch
828 # User test
828 # User test
829 # Date 2 0
829 # Date 2 0
830 # Thu Jan 01 00:00:02 1970 +0000
830 # Thu Jan 01 00:00:02 1970 +0000
831 # Node ID 97d72e5f12c7e84f85064aa72e5a297142c36ed9
831 # Node ID 97d72e5f12c7e84f85064aa72e5a297142c36ed9
832 # Parent 8580ff50825a50c8f716709acdf8de0deddcd6ab
832 # Parent 8580ff50825a50c8f716709acdf8de0deddcd6ab
833 b
833 b
834
834
835 diff -r 8580ff50825a -r 97d72e5f12c7 b
835 diff -r 8580ff50825a -r 97d72e5f12c7 b
836 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
836 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
837 +++ b/b Thu Jan 01 00:00:02 1970 +0000
837 +++ b/b Thu Jan 01 00:00:02 1970 +0000
838 @@ -0,0 +1,1 @@
838 @@ -0,0 +1,1 @@
839 +b
839 +b
840
840
841
841
842 test inline for single patch:
842 test inline for single patch:
843 $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -i -r 2 | $FILTERBOUNDARY
843 $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -i -r 2 | $FILTERBOUNDARY
844 this patch series consists of 1 patches.
844 this patch series consists of 1 patches.
845
845
846
846
847 displaying [PATCH] test ...
847 displaying [PATCH] test ...
848 Content-Type: multipart/mixed; boundary="===*==" (glob)
848 Content-Type: multipart/mixed; boundary="===*==" (glob)
849 MIME-Version: 1.0
849 MIME-Version: 1.0
850 Subject: [PATCH] test
850 Subject: [PATCH] test
851 X-Mercurial-Node: ff2c9fa2018b15fa74b33363bda9527323e2a99f
851 X-Mercurial-Node: ff2c9fa2018b15fa74b33363bda9527323e2a99f
852 X-Mercurial-Series-Index: 1
852 X-Mercurial-Series-Index: 1
853 X-Mercurial-Series-Total: 1
853 X-Mercurial-Series-Total: 1
854 Message-Id: <ff2c9fa2018b15fa74b3.60@*> (glob)
854 Message-Id: <ff2c9fa2018b15fa74b3.60@*> (glob)
855 X-Mercurial-Series-Id: <ff2c9fa2018b15fa74b3.60@*> (glob)
855 X-Mercurial-Series-Id: <ff2c9fa2018b15fa74b3.60@*> (glob)
856 User-Agent: Mercurial-patchbomb/* (glob)
856 User-Agent: Mercurial-patchbomb/* (glob)
857 Date: Thu, 01 Jan 1970 00:01:00 +0000
857 Date: Thu, 01 Jan 1970 00:01:00 +0000
858 From: quux
858 From: quux
859 To: foo
859 To: foo
860 Cc: bar
860 Cc: bar
861
861
862 --===*= (glob)
862 --===*= (glob)
863 Content-Type: text/x-patch; charset="us-ascii"
863 Content-Type: text/x-patch; charset="us-ascii"
864 MIME-Version: 1.0
864 MIME-Version: 1.0
865 Content-Transfer-Encoding: 7bit
865 Content-Transfer-Encoding: 7bit
866 Content-Disposition: inline; filename=t2.patch
866 Content-Disposition: inline; filename=t2.patch
867
867
868 # HG changeset patch
868 # HG changeset patch
869 # User test
869 # User test
870 # Date 3 0
870 # Date 3 0
871 # Thu Jan 01 00:00:03 1970 +0000
871 # Thu Jan 01 00:00:03 1970 +0000
872 # Node ID ff2c9fa2018b15fa74b33363bda9527323e2a99f
872 # Node ID ff2c9fa2018b15fa74b33363bda9527323e2a99f
873 # Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9
873 # Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9
874 c
874 c
875
875
876 diff -r 97d72e5f12c7 -r ff2c9fa2018b c
876 diff -r 97d72e5f12c7 -r ff2c9fa2018b c
877 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
877 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
878 +++ b/c Thu Jan 01 00:00:03 1970 +0000
878 +++ b/c Thu Jan 01 00:00:03 1970 +0000
879 @@ -0,0 +1,1 @@
879 @@ -0,0 +1,1 @@
880 +c
880 +c
881
881
882 --===*=-- (glob)
882 --===*=-- (glob)
883
883
884
884
885 test inline for single patch (quoted-printable):
885 test inline for single patch (quoted-printable):
886 $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -i -r 4 | $FILTERBOUNDARY
886 $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -i -r 4 | $FILTERBOUNDARY
887 this patch series consists of 1 patches.
887 this patch series consists of 1 patches.
888
888
889
889
890 displaying [PATCH] test ...
890 displaying [PATCH] test ...
891 Content-Type: multipart/mixed; boundary="===*==" (glob)
891 Content-Type: multipart/mixed; boundary="===*==" (glob)
892 MIME-Version: 1.0
892 MIME-Version: 1.0
893 Subject: [PATCH] test
893 Subject: [PATCH] test
894 X-Mercurial-Node: a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
894 X-Mercurial-Node: a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
895 X-Mercurial-Series-Index: 1
895 X-Mercurial-Series-Index: 1
896 X-Mercurial-Series-Total: 1
896 X-Mercurial-Series-Total: 1
897 Message-Id: <a2ea8fc83dd8b93cfd86.60@*> (glob)
897 Message-Id: <a2ea8fc83dd8b93cfd86.60@*> (glob)
898 X-Mercurial-Series-Id: <a2ea8fc83dd8b93cfd86.60@*> (glob)
898 X-Mercurial-Series-Id: <a2ea8fc83dd8b93cfd86.60@*> (glob)
899 User-Agent: Mercurial-patchbomb/* (glob)
899 User-Agent: Mercurial-patchbomb/* (glob)
900 Date: Thu, 01 Jan 1970 00:01:00 +0000
900 Date: Thu, 01 Jan 1970 00:01:00 +0000
901 From: quux
901 From: quux
902 To: foo
902 To: foo
903 Cc: bar
903 Cc: bar
904
904
905 --===*= (glob)
905 --===*= (glob)
906 Content-Type: text/x-patch; charset="us-ascii"
906 Content-Type: text/x-patch; charset="us-ascii"
907 MIME-Version: 1.0
907 MIME-Version: 1.0
908 Content-Transfer-Encoding: quoted-printable
908 Content-Transfer-Encoding: quoted-printable
909 Content-Disposition: inline; filename=t2.patch
909 Content-Disposition: inline; filename=t2.patch
910
910
911 # HG changeset patch
911 # HG changeset patch
912 # User test
912 # User test
913 # Date 4 0
913 # Date 4 0
914 # Thu Jan 01 00:00:04 1970 +0000
914 # Thu Jan 01 00:00:04 1970 +0000
915 # Node ID a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
915 # Node ID a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
916 # Parent 909a00e13e9d78b575aeee23dddbada46d5a143f
916 # Parent 909a00e13e9d78b575aeee23dddbada46d5a143f
917 long line
917 long line
918
918
919 diff -r 909a00e13e9d -r a2ea8fc83dd8 long
919 diff -r 909a00e13e9d -r a2ea8fc83dd8 long
920 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
920 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
921 +++ b/long Thu Jan 01 00:00:04 1970 +0000
921 +++ b/long Thu Jan 01 00:00:04 1970 +0000
922 @@ -0,0 +1,4 @@
922 @@ -0,0 +1,4 @@
923 +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
923 +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
924 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
924 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
925 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
925 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
926 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
926 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
927 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
927 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
928 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
928 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
929 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
929 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
930 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
930 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
931 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
931 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
932 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
932 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
933 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
933 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
934 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
934 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
935 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
935 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
936 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
936 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
937 +foo
937 +foo
938 +
938 +
939 +bar
939 +bar
940
940
941 --===*=-- (glob)
941 --===*=-- (glob)
942
942
943 test inline for multiple patches:
943 test inline for multiple patches:
944 $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -i \
944 $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -i \
945 > -r 0:1 -r 4 | $FILTERBOUNDARY
945 > -r 0:1 -r 4 | $FILTERBOUNDARY
946 this patch series consists of 3 patches.
946 this patch series consists of 3 patches.
947
947
948
948
949 Write the introductory message for the patch series.
949 Write the introductory message for the patch series.
950
950
951
951
952 displaying [PATCH 0 of 3] test ...
952 displaying [PATCH 0 of 3] test ...
953 Content-Type: text/plain; charset="us-ascii"
953 Content-Type: text/plain; charset="us-ascii"
954 MIME-Version: 1.0
954 MIME-Version: 1.0
955 Content-Transfer-Encoding: 7bit
955 Content-Transfer-Encoding: 7bit
956 Subject: [PATCH 0 of 3] test
956 Subject: [PATCH 0 of 3] test
957 Message-Id: <patchbomb.60@*> (glob)
957 Message-Id: <patchbomb.60@*> (glob)
958 User-Agent: Mercurial-patchbomb/* (glob)
958 User-Agent: Mercurial-patchbomb/* (glob)
959 Date: Thu, 01 Jan 1970 00:01:00 +0000
959 Date: Thu, 01 Jan 1970 00:01:00 +0000
960 From: quux
960 From: quux
961 To: foo
961 To: foo
962 Cc: bar
962 Cc: bar
963
963
964
964
965 displaying [PATCH 1 of 3] a ...
965 displaying [PATCH 1 of 3] a ...
966 Content-Type: multipart/mixed; boundary="===*==" (glob)
966 Content-Type: multipart/mixed; boundary="===*==" (glob)
967 MIME-Version: 1.0
967 MIME-Version: 1.0
968 Subject: [PATCH 1 of 3] a
968 Subject: [PATCH 1 of 3] a
969 X-Mercurial-Node: 8580ff50825a50c8f716709acdf8de0deddcd6ab
969 X-Mercurial-Node: 8580ff50825a50c8f716709acdf8de0deddcd6ab
970 X-Mercurial-Series-Index: 1
970 X-Mercurial-Series-Index: 1
971 X-Mercurial-Series-Total: 3
971 X-Mercurial-Series-Total: 3
972 Message-Id: <8580ff50825a50c8f716.61@*> (glob)
972 Message-Id: <8580ff50825a50c8f716.61@*> (glob)
973 X-Mercurial-Series-Id: <8580ff50825a50c8f716.61@*> (glob)
973 X-Mercurial-Series-Id: <8580ff50825a50c8f716.61@*> (glob)
974 In-Reply-To: <patchbomb.60@*> (glob)
974 In-Reply-To: <patchbomb.60@*> (glob)
975 References: <patchbomb.60@*> (glob)
975 References: <patchbomb.60@*> (glob)
976 User-Agent: Mercurial-patchbomb/* (glob)
976 User-Agent: Mercurial-patchbomb/* (glob)
977 Date: Thu, 01 Jan 1970 00:01:01 +0000
977 Date: Thu, 01 Jan 1970 00:01:01 +0000
978 From: quux
978 From: quux
979 To: foo
979 To: foo
980 Cc: bar
980 Cc: bar
981
981
982 --===*= (glob)
982 --===*= (glob)
983 Content-Type: text/x-patch; charset="us-ascii"
983 Content-Type: text/x-patch; charset="us-ascii"
984 MIME-Version: 1.0
984 MIME-Version: 1.0
985 Content-Transfer-Encoding: 7bit
985 Content-Transfer-Encoding: 7bit
986 Content-Disposition: inline; filename=t2-1.patch
986 Content-Disposition: inline; filename=t2-1.patch
987
987
988 # HG changeset patch
988 # HG changeset patch
989 # User test
989 # User test
990 # Date 1 0
990 # Date 1 0
991 # Thu Jan 01 00:00:01 1970 +0000
991 # Thu Jan 01 00:00:01 1970 +0000
992 # Node ID 8580ff50825a50c8f716709acdf8de0deddcd6ab
992 # Node ID 8580ff50825a50c8f716709acdf8de0deddcd6ab
993 # Parent 0000000000000000000000000000000000000000
993 # Parent 0000000000000000000000000000000000000000
994 a
994 a
995
995
996 diff -r 000000000000 -r 8580ff50825a a
996 diff -r 000000000000 -r 8580ff50825a a
997 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
997 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
998 +++ b/a Thu Jan 01 00:00:01 1970 +0000
998 +++ b/a Thu Jan 01 00:00:01 1970 +0000
999 @@ -0,0 +1,1 @@
999 @@ -0,0 +1,1 @@
1000 +a
1000 +a
1001
1001
1002 --===*=-- (glob)
1002 --===*=-- (glob)
1003 displaying [PATCH 2 of 3] b ...
1003 displaying [PATCH 2 of 3] b ...
1004 Content-Type: multipart/mixed; boundary="===*==" (glob)
1004 Content-Type: multipart/mixed; boundary="===*==" (glob)
1005 MIME-Version: 1.0
1005 MIME-Version: 1.0
1006 Subject: [PATCH 2 of 3] b
1006 Subject: [PATCH 2 of 3] b
1007 X-Mercurial-Node: 97d72e5f12c7e84f85064aa72e5a297142c36ed9
1007 X-Mercurial-Node: 97d72e5f12c7e84f85064aa72e5a297142c36ed9
1008 X-Mercurial-Series-Index: 2
1008 X-Mercurial-Series-Index: 2
1009 X-Mercurial-Series-Total: 3
1009 X-Mercurial-Series-Total: 3
1010 Message-Id: <97d72e5f12c7e84f8506.62@*> (glob)
1010 Message-Id: <97d72e5f12c7e84f8506.62@*> (glob)
1011 X-Mercurial-Series-Id: <8580ff50825a50c8f716.61@*> (glob)
1011 X-Mercurial-Series-Id: <8580ff50825a50c8f716.61@*> (glob)
1012 In-Reply-To: <patchbomb.60@*> (glob)
1012 In-Reply-To: <patchbomb.60@*> (glob)
1013 References: <patchbomb.60@*> (glob)
1013 References: <patchbomb.60@*> (glob)
1014 User-Agent: Mercurial-patchbomb/* (glob)
1014 User-Agent: Mercurial-patchbomb/* (glob)
1015 Date: Thu, 01 Jan 1970 00:01:02 +0000
1015 Date: Thu, 01 Jan 1970 00:01:02 +0000
1016 From: quux
1016 From: quux
1017 To: foo
1017 To: foo
1018 Cc: bar
1018 Cc: bar
1019
1019
1020 --===*= (glob)
1020 --===*= (glob)
1021 Content-Type: text/x-patch; charset="us-ascii"
1021 Content-Type: text/x-patch; charset="us-ascii"
1022 MIME-Version: 1.0
1022 MIME-Version: 1.0
1023 Content-Transfer-Encoding: 7bit
1023 Content-Transfer-Encoding: 7bit
1024 Content-Disposition: inline; filename=t2-2.patch
1024 Content-Disposition: inline; filename=t2-2.patch
1025
1025
1026 # HG changeset patch
1026 # HG changeset patch
1027 # User test
1027 # User test
1028 # Date 2 0
1028 # Date 2 0
1029 # Thu Jan 01 00:00:02 1970 +0000
1029 # Thu Jan 01 00:00:02 1970 +0000
1030 # Node ID 97d72e5f12c7e84f85064aa72e5a297142c36ed9
1030 # Node ID 97d72e5f12c7e84f85064aa72e5a297142c36ed9
1031 # Parent 8580ff50825a50c8f716709acdf8de0deddcd6ab
1031 # Parent 8580ff50825a50c8f716709acdf8de0deddcd6ab
1032 b
1032 b
1033
1033
1034 diff -r 8580ff50825a -r 97d72e5f12c7 b
1034 diff -r 8580ff50825a -r 97d72e5f12c7 b
1035 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1035 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1036 +++ b/b Thu Jan 01 00:00:02 1970 +0000
1036 +++ b/b Thu Jan 01 00:00:02 1970 +0000
1037 @@ -0,0 +1,1 @@
1037 @@ -0,0 +1,1 @@
1038 +b
1038 +b
1039
1039
1040 --===*=-- (glob)
1040 --===*=-- (glob)
1041 displaying [PATCH 3 of 3] long line ...
1041 displaying [PATCH 3 of 3] long line ...
1042 Content-Type: multipart/mixed; boundary="===*==" (glob)
1042 Content-Type: multipart/mixed; boundary="===*==" (glob)
1043 MIME-Version: 1.0
1043 MIME-Version: 1.0
1044 Subject: [PATCH 3 of 3] long line
1044 Subject: [PATCH 3 of 3] long line
1045 X-Mercurial-Node: a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
1045 X-Mercurial-Node: a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
1046 X-Mercurial-Series-Index: 3
1046 X-Mercurial-Series-Index: 3
1047 X-Mercurial-Series-Total: 3
1047 X-Mercurial-Series-Total: 3
1048 Message-Id: <a2ea8fc83dd8b93cfd86.63@*> (glob)
1048 Message-Id: <a2ea8fc83dd8b93cfd86.63@*> (glob)
1049 X-Mercurial-Series-Id: <8580ff50825a50c8f716.61@*> (glob)
1049 X-Mercurial-Series-Id: <8580ff50825a50c8f716.61@*> (glob)
1050 In-Reply-To: <patchbomb.60@*> (glob)
1050 In-Reply-To: <patchbomb.60@*> (glob)
1051 References: <patchbomb.60@*> (glob)
1051 References: <patchbomb.60@*> (glob)
1052 User-Agent: Mercurial-patchbomb/* (glob)
1052 User-Agent: Mercurial-patchbomb/* (glob)
1053 Date: Thu, 01 Jan 1970 00:01:03 +0000
1053 Date: Thu, 01 Jan 1970 00:01:03 +0000
1054 From: quux
1054 From: quux
1055 To: foo
1055 To: foo
1056 Cc: bar
1056 Cc: bar
1057
1057
1058 --===*= (glob)
1058 --===*= (glob)
1059 Content-Type: text/x-patch; charset="us-ascii"
1059 Content-Type: text/x-patch; charset="us-ascii"
1060 MIME-Version: 1.0
1060 MIME-Version: 1.0
1061 Content-Transfer-Encoding: quoted-printable
1061 Content-Transfer-Encoding: quoted-printable
1062 Content-Disposition: inline; filename=t2-3.patch
1062 Content-Disposition: inline; filename=t2-3.patch
1063
1063
1064 # HG changeset patch
1064 # HG changeset patch
1065 # User test
1065 # User test
1066 # Date 4 0
1066 # Date 4 0
1067 # Thu Jan 01 00:00:04 1970 +0000
1067 # Thu Jan 01 00:00:04 1970 +0000
1068 # Node ID a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
1068 # Node ID a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
1069 # Parent 909a00e13e9d78b575aeee23dddbada46d5a143f
1069 # Parent 909a00e13e9d78b575aeee23dddbada46d5a143f
1070 long line
1070 long line
1071
1071
1072 diff -r 909a00e13e9d -r a2ea8fc83dd8 long
1072 diff -r 909a00e13e9d -r a2ea8fc83dd8 long
1073 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1073 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1074 +++ b/long Thu Jan 01 00:00:04 1970 +0000
1074 +++ b/long Thu Jan 01 00:00:04 1970 +0000
1075 @@ -0,0 +1,4 @@
1075 @@ -0,0 +1,4 @@
1076 +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1076 +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1077 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1077 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1078 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1078 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1079 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1079 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1080 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1080 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1081 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1081 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1082 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1082 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1083 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1083 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1084 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1084 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1085 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1085 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1086 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1086 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1087 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1087 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1088 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1088 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1089 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
1089 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
1090 +foo
1090 +foo
1091 +
1091 +
1092 +bar
1092 +bar
1093
1093
1094 --===*=-- (glob)
1094 --===*=-- (glob)
1095
1095
1096 test attach for single patch:
1096 test attach for single patch:
1097 $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -a -r 2 | $FILTERBOUNDARY
1097 $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -a -r 2 | $FILTERBOUNDARY
1098 this patch series consists of 1 patches.
1098 this patch series consists of 1 patches.
1099
1099
1100
1100
1101 displaying [PATCH] test ...
1101 displaying [PATCH] test ...
1102 Content-Type: multipart/mixed; boundary="===*==" (glob)
1102 Content-Type: multipart/mixed; boundary="===*==" (glob)
1103 MIME-Version: 1.0
1103 MIME-Version: 1.0
1104 Subject: [PATCH] test
1104 Subject: [PATCH] test
1105 X-Mercurial-Node: ff2c9fa2018b15fa74b33363bda9527323e2a99f
1105 X-Mercurial-Node: ff2c9fa2018b15fa74b33363bda9527323e2a99f
1106 X-Mercurial-Series-Index: 1
1106 X-Mercurial-Series-Index: 1
1107 X-Mercurial-Series-Total: 1
1107 X-Mercurial-Series-Total: 1
1108 Message-Id: <ff2c9fa2018b15fa74b3.60@*> (glob)
1108 Message-Id: <ff2c9fa2018b15fa74b3.60@*> (glob)
1109 X-Mercurial-Series-Id: <ff2c9fa2018b15fa74b3.60@*> (glob)
1109 X-Mercurial-Series-Id: <ff2c9fa2018b15fa74b3.60@*> (glob)
1110 User-Agent: Mercurial-patchbomb/* (glob)
1110 User-Agent: Mercurial-patchbomb/* (glob)
1111 Date: Thu, 01 Jan 1970 00:01:00 +0000
1111 Date: Thu, 01 Jan 1970 00:01:00 +0000
1112 From: quux
1112 From: quux
1113 To: foo
1113 To: foo
1114 Cc: bar
1114 Cc: bar
1115
1115
1116 --===*= (glob)
1116 --===*= (glob)
1117 Content-Type: text/plain; charset="us-ascii"
1117 Content-Type: text/plain; charset="us-ascii"
1118 MIME-Version: 1.0
1118 MIME-Version: 1.0
1119 Content-Transfer-Encoding: 7bit
1119 Content-Transfer-Encoding: 7bit
1120
1120
1121 Patch subject is complete summary.
1121 Patch subject is complete summary.
1122
1122
1123
1123
1124
1124
1125 --===*= (glob)
1125 --===*= (glob)
1126 Content-Type: text/x-patch; charset="us-ascii"
1126 Content-Type: text/x-patch; charset="us-ascii"
1127 MIME-Version: 1.0
1127 MIME-Version: 1.0
1128 Content-Transfer-Encoding: 7bit
1128 Content-Transfer-Encoding: 7bit
1129 Content-Disposition: attachment; filename=t2.patch
1129 Content-Disposition: attachment; filename=t2.patch
1130
1130
1131 # HG changeset patch
1131 # HG changeset patch
1132 # User test
1132 # User test
1133 # Date 3 0
1133 # Date 3 0
1134 # Thu Jan 01 00:00:03 1970 +0000
1134 # Thu Jan 01 00:00:03 1970 +0000
1135 # Node ID ff2c9fa2018b15fa74b33363bda9527323e2a99f
1135 # Node ID ff2c9fa2018b15fa74b33363bda9527323e2a99f
1136 # Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9
1136 # Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9
1137 c
1137 c
1138
1138
1139 diff -r 97d72e5f12c7 -r ff2c9fa2018b c
1139 diff -r 97d72e5f12c7 -r ff2c9fa2018b c
1140 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1140 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1141 +++ b/c Thu Jan 01 00:00:03 1970 +0000
1141 +++ b/c Thu Jan 01 00:00:03 1970 +0000
1142 @@ -0,0 +1,1 @@
1142 @@ -0,0 +1,1 @@
1143 +c
1143 +c
1144
1144
1145 --===*=-- (glob)
1145 --===*=-- (glob)
1146
1146
1147 test attach for single patch (quoted-printable):
1147 test attach for single patch (quoted-printable):
1148 $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -a -r 4 | $FILTERBOUNDARY
1148 $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -a -r 4 | $FILTERBOUNDARY
1149 this patch series consists of 1 patches.
1149 this patch series consists of 1 patches.
1150
1150
1151
1151
1152 displaying [PATCH] test ...
1152 displaying [PATCH] test ...
1153 Content-Type: multipart/mixed; boundary="===*==" (glob)
1153 Content-Type: multipart/mixed; boundary="===*==" (glob)
1154 MIME-Version: 1.0
1154 MIME-Version: 1.0
1155 Subject: [PATCH] test
1155 Subject: [PATCH] test
1156 X-Mercurial-Node: a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
1156 X-Mercurial-Node: a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
1157 X-Mercurial-Series-Index: 1
1157 X-Mercurial-Series-Index: 1
1158 X-Mercurial-Series-Total: 1
1158 X-Mercurial-Series-Total: 1
1159 Message-Id: <a2ea8fc83dd8b93cfd86.60@*> (glob)
1159 Message-Id: <a2ea8fc83dd8b93cfd86.60@*> (glob)
1160 X-Mercurial-Series-Id: <a2ea8fc83dd8b93cfd86.60@*> (glob)
1160 X-Mercurial-Series-Id: <a2ea8fc83dd8b93cfd86.60@*> (glob)
1161 User-Agent: Mercurial-patchbomb/* (glob)
1161 User-Agent: Mercurial-patchbomb/* (glob)
1162 Date: Thu, 01 Jan 1970 00:01:00 +0000
1162 Date: Thu, 01 Jan 1970 00:01:00 +0000
1163 From: quux
1163 From: quux
1164 To: foo
1164 To: foo
1165 Cc: bar
1165 Cc: bar
1166
1166
1167 --===*= (glob)
1167 --===*= (glob)
1168 Content-Type: text/plain; charset="us-ascii"
1168 Content-Type: text/plain; charset="us-ascii"
1169 MIME-Version: 1.0
1169 MIME-Version: 1.0
1170 Content-Transfer-Encoding: 7bit
1170 Content-Transfer-Encoding: 7bit
1171
1171
1172 Patch subject is complete summary.
1172 Patch subject is complete summary.
1173
1173
1174
1174
1175
1175
1176 --===*= (glob)
1176 --===*= (glob)
1177 Content-Type: text/x-patch; charset="us-ascii"
1177 Content-Type: text/x-patch; charset="us-ascii"
1178 MIME-Version: 1.0
1178 MIME-Version: 1.0
1179 Content-Transfer-Encoding: quoted-printable
1179 Content-Transfer-Encoding: quoted-printable
1180 Content-Disposition: attachment; filename=t2.patch
1180 Content-Disposition: attachment; filename=t2.patch
1181
1181
1182 # HG changeset patch
1182 # HG changeset patch
1183 # User test
1183 # User test
1184 # Date 4 0
1184 # Date 4 0
1185 # Thu Jan 01 00:00:04 1970 +0000
1185 # Thu Jan 01 00:00:04 1970 +0000
1186 # Node ID a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
1186 # Node ID a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
1187 # Parent 909a00e13e9d78b575aeee23dddbada46d5a143f
1187 # Parent 909a00e13e9d78b575aeee23dddbada46d5a143f
1188 long line
1188 long line
1189
1189
1190 diff -r 909a00e13e9d -r a2ea8fc83dd8 long
1190 diff -r 909a00e13e9d -r a2ea8fc83dd8 long
1191 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1191 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1192 +++ b/long Thu Jan 01 00:00:04 1970 +0000
1192 +++ b/long Thu Jan 01 00:00:04 1970 +0000
1193 @@ -0,0 +1,4 @@
1193 @@ -0,0 +1,4 @@
1194 +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1194 +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1195 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1195 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1196 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1196 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1197 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1197 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1198 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1198 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1199 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1199 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1200 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1200 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1201 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1201 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1202 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1202 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1203 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1203 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1204 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1204 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1205 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1205 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1206 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1206 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1207 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
1207 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
1208 +foo
1208 +foo
1209 +
1209 +
1210 +bar
1210 +bar
1211
1211
1212 --===*=-- (glob)
1212 --===*=-- (glob)
1213
1213
1214 test attach and body for single patch:
1214 test attach and body for single patch:
1215 $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -a --body -r 2 | $FILTERBOUNDARY
1215 $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -a --body -r 2 | $FILTERBOUNDARY
1216 this patch series consists of 1 patches.
1216 this patch series consists of 1 patches.
1217
1217
1218
1218
1219 displaying [PATCH] test ...
1219 displaying [PATCH] test ...
1220 Content-Type: multipart/mixed; boundary="===*==" (glob)
1220 Content-Type: multipart/mixed; boundary="===*==" (glob)
1221 MIME-Version: 1.0
1221 MIME-Version: 1.0
1222 Subject: [PATCH] test
1222 Subject: [PATCH] test
1223 X-Mercurial-Node: ff2c9fa2018b15fa74b33363bda9527323e2a99f
1223 X-Mercurial-Node: ff2c9fa2018b15fa74b33363bda9527323e2a99f
1224 X-Mercurial-Series-Index: 1
1224 X-Mercurial-Series-Index: 1
1225 X-Mercurial-Series-Total: 1
1225 X-Mercurial-Series-Total: 1
1226 Message-Id: <ff2c9fa2018b15fa74b3.60@*> (glob)
1226 Message-Id: <ff2c9fa2018b15fa74b3.60@*> (glob)
1227 X-Mercurial-Series-Id: <ff2c9fa2018b15fa74b3.60@*> (glob)
1227 X-Mercurial-Series-Id: <ff2c9fa2018b15fa74b3.60@*> (glob)
1228 User-Agent: Mercurial-patchbomb/* (glob)
1228 User-Agent: Mercurial-patchbomb/* (glob)
1229 Date: Thu, 01 Jan 1970 00:01:00 +0000
1229 Date: Thu, 01 Jan 1970 00:01:00 +0000
1230 From: quux
1230 From: quux
1231 To: foo
1231 To: foo
1232 Cc: bar
1232 Cc: bar
1233
1233
1234 --===*= (glob)
1234 --===*= (glob)
1235 Content-Type: text/plain; charset="us-ascii"
1235 Content-Type: text/plain; charset="us-ascii"
1236 MIME-Version: 1.0
1236 MIME-Version: 1.0
1237 Content-Transfer-Encoding: 7bit
1237 Content-Transfer-Encoding: 7bit
1238
1238
1239 # HG changeset patch
1239 # HG changeset patch
1240 # User test
1240 # User test
1241 # Date 3 0
1241 # Date 3 0
1242 # Thu Jan 01 00:00:03 1970 +0000
1242 # Thu Jan 01 00:00:03 1970 +0000
1243 # Node ID ff2c9fa2018b15fa74b33363bda9527323e2a99f
1243 # Node ID ff2c9fa2018b15fa74b33363bda9527323e2a99f
1244 # Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9
1244 # Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9
1245 c
1245 c
1246
1246
1247 diff -r 97d72e5f12c7 -r ff2c9fa2018b c
1247 diff -r 97d72e5f12c7 -r ff2c9fa2018b c
1248 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1248 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1249 +++ b/c Thu Jan 01 00:00:03 1970 +0000
1249 +++ b/c Thu Jan 01 00:00:03 1970 +0000
1250 @@ -0,0 +1,1 @@
1250 @@ -0,0 +1,1 @@
1251 +c
1251 +c
1252
1252
1253 --===*= (glob)
1253 --===*= (glob)
1254 Content-Type: text/x-patch; charset="us-ascii"
1254 Content-Type: text/x-patch; charset="us-ascii"
1255 MIME-Version: 1.0
1255 MIME-Version: 1.0
1256 Content-Transfer-Encoding: 7bit
1256 Content-Transfer-Encoding: 7bit
1257 Content-Disposition: attachment; filename=t2.patch
1257 Content-Disposition: attachment; filename=t2.patch
1258
1258
1259 # HG changeset patch
1259 # HG changeset patch
1260 # User test
1260 # User test
1261 # Date 3 0
1261 # Date 3 0
1262 # Thu Jan 01 00:00:03 1970 +0000
1262 # Thu Jan 01 00:00:03 1970 +0000
1263 # Node ID ff2c9fa2018b15fa74b33363bda9527323e2a99f
1263 # Node ID ff2c9fa2018b15fa74b33363bda9527323e2a99f
1264 # Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9
1264 # Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9
1265 c
1265 c
1266
1266
1267 diff -r 97d72e5f12c7 -r ff2c9fa2018b c
1267 diff -r 97d72e5f12c7 -r ff2c9fa2018b c
1268 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1268 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1269 +++ b/c Thu Jan 01 00:00:03 1970 +0000
1269 +++ b/c Thu Jan 01 00:00:03 1970 +0000
1270 @@ -0,0 +1,1 @@
1270 @@ -0,0 +1,1 @@
1271 +c
1271 +c
1272
1272
1273 --===*=-- (glob)
1273 --===*=-- (glob)
1274
1274
1275 test attach for multiple patches:
1275 test attach for multiple patches:
1276 $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -a \
1276 $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -a \
1277 > -r 0:1 -r 4 | $FILTERBOUNDARY
1277 > -r 0:1 -r 4 | $FILTERBOUNDARY
1278 this patch series consists of 3 patches.
1278 this patch series consists of 3 patches.
1279
1279
1280
1280
1281 Write the introductory message for the patch series.
1281 Write the introductory message for the patch series.
1282
1282
1283
1283
1284 displaying [PATCH 0 of 3] test ...
1284 displaying [PATCH 0 of 3] test ...
1285 Content-Type: text/plain; charset="us-ascii"
1285 Content-Type: text/plain; charset="us-ascii"
1286 MIME-Version: 1.0
1286 MIME-Version: 1.0
1287 Content-Transfer-Encoding: 7bit
1287 Content-Transfer-Encoding: 7bit
1288 Subject: [PATCH 0 of 3] test
1288 Subject: [PATCH 0 of 3] test
1289 Message-Id: <patchbomb.60@*> (glob)
1289 Message-Id: <patchbomb.60@*> (glob)
1290 User-Agent: Mercurial-patchbomb/* (glob)
1290 User-Agent: Mercurial-patchbomb/* (glob)
1291 Date: Thu, 01 Jan 1970 00:01:00 +0000
1291 Date: Thu, 01 Jan 1970 00:01:00 +0000
1292 From: quux
1292 From: quux
1293 To: foo
1293 To: foo
1294 Cc: bar
1294 Cc: bar
1295
1295
1296
1296
1297 displaying [PATCH 1 of 3] a ...
1297 displaying [PATCH 1 of 3] a ...
1298 Content-Type: multipart/mixed; boundary="===*==" (glob)
1298 Content-Type: multipart/mixed; boundary="===*==" (glob)
1299 MIME-Version: 1.0
1299 MIME-Version: 1.0
1300 Subject: [PATCH 1 of 3] a
1300 Subject: [PATCH 1 of 3] a
1301 X-Mercurial-Node: 8580ff50825a50c8f716709acdf8de0deddcd6ab
1301 X-Mercurial-Node: 8580ff50825a50c8f716709acdf8de0deddcd6ab
1302 X-Mercurial-Series-Index: 1
1302 X-Mercurial-Series-Index: 1
1303 X-Mercurial-Series-Total: 3
1303 X-Mercurial-Series-Total: 3
1304 Message-Id: <8580ff50825a50c8f716.61@*> (glob)
1304 Message-Id: <8580ff50825a50c8f716.61@*> (glob)
1305 X-Mercurial-Series-Id: <8580ff50825a50c8f716.61@*> (glob)
1305 X-Mercurial-Series-Id: <8580ff50825a50c8f716.61@*> (glob)
1306 In-Reply-To: <patchbomb.60@*> (glob)
1306 In-Reply-To: <patchbomb.60@*> (glob)
1307 References: <patchbomb.60@*> (glob)
1307 References: <patchbomb.60@*> (glob)
1308 User-Agent: Mercurial-patchbomb/* (glob)
1308 User-Agent: Mercurial-patchbomb/* (glob)
1309 Date: Thu, 01 Jan 1970 00:01:01 +0000
1309 Date: Thu, 01 Jan 1970 00:01:01 +0000
1310 From: quux
1310 From: quux
1311 To: foo
1311 To: foo
1312 Cc: bar
1312 Cc: bar
1313
1313
1314 --===*= (glob)
1314 --===*= (glob)
1315 Content-Type: text/plain; charset="us-ascii"
1315 Content-Type: text/plain; charset="us-ascii"
1316 MIME-Version: 1.0
1316 MIME-Version: 1.0
1317 Content-Transfer-Encoding: 7bit
1317 Content-Transfer-Encoding: 7bit
1318
1318
1319 Patch subject is complete summary.
1319 Patch subject is complete summary.
1320
1320
1321
1321
1322
1322
1323 --===*= (glob)
1323 --===*= (glob)
1324 Content-Type: text/x-patch; charset="us-ascii"
1324 Content-Type: text/x-patch; charset="us-ascii"
1325 MIME-Version: 1.0
1325 MIME-Version: 1.0
1326 Content-Transfer-Encoding: 7bit
1326 Content-Transfer-Encoding: 7bit
1327 Content-Disposition: attachment; filename=t2-1.patch
1327 Content-Disposition: attachment; filename=t2-1.patch
1328
1328
1329 # HG changeset patch
1329 # HG changeset patch
1330 # User test
1330 # User test
1331 # Date 1 0
1331 # Date 1 0
1332 # Thu Jan 01 00:00:01 1970 +0000
1332 # Thu Jan 01 00:00:01 1970 +0000
1333 # Node ID 8580ff50825a50c8f716709acdf8de0deddcd6ab
1333 # Node ID 8580ff50825a50c8f716709acdf8de0deddcd6ab
1334 # Parent 0000000000000000000000000000000000000000
1334 # Parent 0000000000000000000000000000000000000000
1335 a
1335 a
1336
1336
1337 diff -r 000000000000 -r 8580ff50825a a
1337 diff -r 000000000000 -r 8580ff50825a a
1338 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1338 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1339 +++ b/a Thu Jan 01 00:00:01 1970 +0000
1339 +++ b/a Thu Jan 01 00:00:01 1970 +0000
1340 @@ -0,0 +1,1 @@
1340 @@ -0,0 +1,1 @@
1341 +a
1341 +a
1342
1342
1343 --===*=-- (glob)
1343 --===*=-- (glob)
1344 displaying [PATCH 2 of 3] b ...
1344 displaying [PATCH 2 of 3] b ...
1345 Content-Type: multipart/mixed; boundary="===*==" (glob)
1345 Content-Type: multipart/mixed; boundary="===*==" (glob)
1346 MIME-Version: 1.0
1346 MIME-Version: 1.0
1347 Subject: [PATCH 2 of 3] b
1347 Subject: [PATCH 2 of 3] b
1348 X-Mercurial-Node: 97d72e5f12c7e84f85064aa72e5a297142c36ed9
1348 X-Mercurial-Node: 97d72e5f12c7e84f85064aa72e5a297142c36ed9
1349 X-Mercurial-Series-Index: 2
1349 X-Mercurial-Series-Index: 2
1350 X-Mercurial-Series-Total: 3
1350 X-Mercurial-Series-Total: 3
1351 Message-Id: <97d72e5f12c7e84f8506.62@*> (glob)
1351 Message-Id: <97d72e5f12c7e84f8506.62@*> (glob)
1352 X-Mercurial-Series-Id: <8580ff50825a50c8f716.61@*> (glob)
1352 X-Mercurial-Series-Id: <8580ff50825a50c8f716.61@*> (glob)
1353 In-Reply-To: <patchbomb.60@*> (glob)
1353 In-Reply-To: <patchbomb.60@*> (glob)
1354 References: <patchbomb.60@*> (glob)
1354 References: <patchbomb.60@*> (glob)
1355 User-Agent: Mercurial-patchbomb/* (glob)
1355 User-Agent: Mercurial-patchbomb/* (glob)
1356 Date: Thu, 01 Jan 1970 00:01:02 +0000
1356 Date: Thu, 01 Jan 1970 00:01:02 +0000
1357 From: quux
1357 From: quux
1358 To: foo
1358 To: foo
1359 Cc: bar
1359 Cc: bar
1360
1360
1361 --===*= (glob)
1361 --===*= (glob)
1362 Content-Type: text/plain; charset="us-ascii"
1362 Content-Type: text/plain; charset="us-ascii"
1363 MIME-Version: 1.0
1363 MIME-Version: 1.0
1364 Content-Transfer-Encoding: 7bit
1364 Content-Transfer-Encoding: 7bit
1365
1365
1366 Patch subject is complete summary.
1366 Patch subject is complete summary.
1367
1367
1368
1368
1369
1369
1370 --===*= (glob)
1370 --===*= (glob)
1371 Content-Type: text/x-patch; charset="us-ascii"
1371 Content-Type: text/x-patch; charset="us-ascii"
1372 MIME-Version: 1.0
1372 MIME-Version: 1.0
1373 Content-Transfer-Encoding: 7bit
1373 Content-Transfer-Encoding: 7bit
1374 Content-Disposition: attachment; filename=t2-2.patch
1374 Content-Disposition: attachment; filename=t2-2.patch
1375
1375
1376 # HG changeset patch
1376 # HG changeset patch
1377 # User test
1377 # User test
1378 # Date 2 0
1378 # Date 2 0
1379 # Thu Jan 01 00:00:02 1970 +0000
1379 # Thu Jan 01 00:00:02 1970 +0000
1380 # Node ID 97d72e5f12c7e84f85064aa72e5a297142c36ed9
1380 # Node ID 97d72e5f12c7e84f85064aa72e5a297142c36ed9
1381 # Parent 8580ff50825a50c8f716709acdf8de0deddcd6ab
1381 # Parent 8580ff50825a50c8f716709acdf8de0deddcd6ab
1382 b
1382 b
1383
1383
1384 diff -r 8580ff50825a -r 97d72e5f12c7 b
1384 diff -r 8580ff50825a -r 97d72e5f12c7 b
1385 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1385 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1386 +++ b/b Thu Jan 01 00:00:02 1970 +0000
1386 +++ b/b Thu Jan 01 00:00:02 1970 +0000
1387 @@ -0,0 +1,1 @@
1387 @@ -0,0 +1,1 @@
1388 +b
1388 +b
1389
1389
1390 --===*=-- (glob)
1390 --===*=-- (glob)
1391 displaying [PATCH 3 of 3] long line ...
1391 displaying [PATCH 3 of 3] long line ...
1392 Content-Type: multipart/mixed; boundary="===*==" (glob)
1392 Content-Type: multipart/mixed; boundary="===*==" (glob)
1393 MIME-Version: 1.0
1393 MIME-Version: 1.0
1394 Subject: [PATCH 3 of 3] long line
1394 Subject: [PATCH 3 of 3] long line
1395 X-Mercurial-Node: a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
1395 X-Mercurial-Node: a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
1396 X-Mercurial-Series-Index: 3
1396 X-Mercurial-Series-Index: 3
1397 X-Mercurial-Series-Total: 3
1397 X-Mercurial-Series-Total: 3
1398 Message-Id: <a2ea8fc83dd8b93cfd86.63@*> (glob)
1398 Message-Id: <a2ea8fc83dd8b93cfd86.63@*> (glob)
1399 X-Mercurial-Series-Id: <8580ff50825a50c8f716.61@*> (glob)
1399 X-Mercurial-Series-Id: <8580ff50825a50c8f716.61@*> (glob)
1400 In-Reply-To: <patchbomb.60@*> (glob)
1400 In-Reply-To: <patchbomb.60@*> (glob)
1401 References: <patchbomb.60@*> (glob)
1401 References: <patchbomb.60@*> (glob)
1402 User-Agent: Mercurial-patchbomb/* (glob)
1402 User-Agent: Mercurial-patchbomb/* (glob)
1403 Date: Thu, 01 Jan 1970 00:01:03 +0000
1403 Date: Thu, 01 Jan 1970 00:01:03 +0000
1404 From: quux
1404 From: quux
1405 To: foo
1405 To: foo
1406 Cc: bar
1406 Cc: bar
1407
1407
1408 --===*= (glob)
1408 --===*= (glob)
1409 Content-Type: text/plain; charset="us-ascii"
1409 Content-Type: text/plain; charset="us-ascii"
1410 MIME-Version: 1.0
1410 MIME-Version: 1.0
1411 Content-Transfer-Encoding: 7bit
1411 Content-Transfer-Encoding: 7bit
1412
1412
1413 Patch subject is complete summary.
1413 Patch subject is complete summary.
1414
1414
1415
1415
1416
1416
1417 --===*= (glob)
1417 --===*= (glob)
1418 Content-Type: text/x-patch; charset="us-ascii"
1418 Content-Type: text/x-patch; charset="us-ascii"
1419 MIME-Version: 1.0
1419 MIME-Version: 1.0
1420 Content-Transfer-Encoding: quoted-printable
1420 Content-Transfer-Encoding: quoted-printable
1421 Content-Disposition: attachment; filename=t2-3.patch
1421 Content-Disposition: attachment; filename=t2-3.patch
1422
1422
1423 # HG changeset patch
1423 # HG changeset patch
1424 # User test
1424 # User test
1425 # Date 4 0
1425 # Date 4 0
1426 # Thu Jan 01 00:00:04 1970 +0000
1426 # Thu Jan 01 00:00:04 1970 +0000
1427 # Node ID a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
1427 # Node ID a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
1428 # Parent 909a00e13e9d78b575aeee23dddbada46d5a143f
1428 # Parent 909a00e13e9d78b575aeee23dddbada46d5a143f
1429 long line
1429 long line
1430
1430
1431 diff -r 909a00e13e9d -r a2ea8fc83dd8 long
1431 diff -r 909a00e13e9d -r a2ea8fc83dd8 long
1432 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1432 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1433 +++ b/long Thu Jan 01 00:00:04 1970 +0000
1433 +++ b/long Thu Jan 01 00:00:04 1970 +0000
1434 @@ -0,0 +1,4 @@
1434 @@ -0,0 +1,4 @@
1435 +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1435 +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1436 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1436 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1437 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1437 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1438 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1438 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1439 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1439 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1440 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1440 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1441 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1441 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1442 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1442 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1443 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1443 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1444 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1444 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1445 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1445 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1446 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1446 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1447 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1447 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1448 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
1448 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
1449 +foo
1449 +foo
1450 +
1450 +
1451 +bar
1451 +bar
1452
1452
1453 --===*=-- (glob)
1453 --===*=-- (glob)
1454
1454
1455 test intro for single patch:
1455 test intro for single patch:
1456 $ hg email --date '1970-1-1 0:1' -n --intro -f quux -t foo -c bar -s test \
1456 $ hg email --date '1970-1-1 0:1' -n --intro -f quux -t foo -c bar -s test \
1457 > -r 2
1457 > -r 2
1458 this patch series consists of 1 patches.
1458 this patch series consists of 1 patches.
1459
1459
1460
1460
1461 Write the introductory message for the patch series.
1461 Write the introductory message for the patch series.
1462
1462
1463
1463
1464 displaying [PATCH 0 of 1] test ...
1464 displaying [PATCH 0 of 1] test ...
1465 Content-Type: text/plain; charset="us-ascii"
1465 Content-Type: text/plain; charset="us-ascii"
1466 MIME-Version: 1.0
1466 MIME-Version: 1.0
1467 Content-Transfer-Encoding: 7bit
1467 Content-Transfer-Encoding: 7bit
1468 Subject: [PATCH 0 of 1] test
1468 Subject: [PATCH 0 of 1] test
1469 Message-Id: <patchbomb.60@*> (glob)
1469 Message-Id: <patchbomb.60@*> (glob)
1470 User-Agent: Mercurial-patchbomb/* (glob)
1470 User-Agent: Mercurial-patchbomb/* (glob)
1471 Date: Thu, 01 Jan 1970 00:01:00 +0000
1471 Date: Thu, 01 Jan 1970 00:01:00 +0000
1472 From: quux
1472 From: quux
1473 To: foo
1473 To: foo
1474 Cc: bar
1474 Cc: bar
1475
1475
1476
1476
1477 displaying [PATCH 1 of 1] c ...
1477 displaying [PATCH 1 of 1] c ...
1478 Content-Type: text/plain; charset="us-ascii"
1478 Content-Type: text/plain; charset="us-ascii"
1479 MIME-Version: 1.0
1479 MIME-Version: 1.0
1480 Content-Transfer-Encoding: 7bit
1480 Content-Transfer-Encoding: 7bit
1481 Subject: [PATCH 1 of 1] c
1481 Subject: [PATCH 1 of 1] c
1482 X-Mercurial-Node: ff2c9fa2018b15fa74b33363bda9527323e2a99f
1482 X-Mercurial-Node: ff2c9fa2018b15fa74b33363bda9527323e2a99f
1483 X-Mercurial-Series-Index: 1
1483 X-Mercurial-Series-Index: 1
1484 X-Mercurial-Series-Total: 1
1484 X-Mercurial-Series-Total: 1
1485 Message-Id: <ff2c9fa2018b15fa74b3.61@*> (glob)
1485 Message-Id: <ff2c9fa2018b15fa74b3.61@*> (glob)
1486 X-Mercurial-Series-Id: <ff2c9fa2018b15fa74b3.61@*> (glob)
1486 X-Mercurial-Series-Id: <ff2c9fa2018b15fa74b3.61@*> (glob)
1487 In-Reply-To: <patchbomb.60@*> (glob)
1487 In-Reply-To: <patchbomb.60@*> (glob)
1488 References: <patchbomb.60@*> (glob)
1488 References: <patchbomb.60@*> (glob)
1489 User-Agent: Mercurial-patchbomb/* (glob)
1489 User-Agent: Mercurial-patchbomb/* (glob)
1490 Date: Thu, 01 Jan 1970 00:01:01 +0000
1490 Date: Thu, 01 Jan 1970 00:01:01 +0000
1491 From: quux
1491 From: quux
1492 To: foo
1492 To: foo
1493 Cc: bar
1493 Cc: bar
1494
1494
1495 # HG changeset patch
1495 # HG changeset patch
1496 # User test
1496 # User test
1497 # Date 3 0
1497 # Date 3 0
1498 # Thu Jan 01 00:00:03 1970 +0000
1498 # Thu Jan 01 00:00:03 1970 +0000
1499 # Node ID ff2c9fa2018b15fa74b33363bda9527323e2a99f
1499 # Node ID ff2c9fa2018b15fa74b33363bda9527323e2a99f
1500 # Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9
1500 # Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9
1501 c
1501 c
1502
1502
1503 diff -r 97d72e5f12c7 -r ff2c9fa2018b c
1503 diff -r 97d72e5f12c7 -r ff2c9fa2018b c
1504 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1504 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1505 +++ b/c Thu Jan 01 00:00:03 1970 +0000
1505 +++ b/c Thu Jan 01 00:00:03 1970 +0000
1506 @@ -0,0 +1,1 @@
1506 @@ -0,0 +1,1 @@
1507 +c
1507 +c
1508
1508
1509
1509
1510 test --desc without --intro for a single patch:
1510 test --desc without --intro for a single patch:
1511 $ echo foo > intro.text
1511 $ echo foo > intro.text
1512 $ hg email --date '1970-1-1 0:1' -n --desc intro.text -f quux -t foo -c bar \
1512 $ hg email --date '1970-1-1 0:1' -n --desc intro.text -f quux -t foo -c bar \
1513 > -s test -r 2
1513 > -s test -r 2
1514 this patch series consists of 1 patches.
1514 this patch series consists of 1 patches.
1515
1515
1516
1516
1517 displaying [PATCH 0 of 1] test ...
1517 displaying [PATCH 0 of 1] test ...
1518 Content-Type: text/plain; charset="us-ascii"
1518 Content-Type: text/plain; charset="us-ascii"
1519 MIME-Version: 1.0
1519 MIME-Version: 1.0
1520 Content-Transfer-Encoding: 7bit
1520 Content-Transfer-Encoding: 7bit
1521 Subject: [PATCH 0 of 1] test
1521 Subject: [PATCH 0 of 1] test
1522 Message-Id: <patchbomb.60@*> (glob)
1522 Message-Id: <patchbomb.60@*> (glob)
1523 User-Agent: Mercurial-patchbomb/* (glob)
1523 User-Agent: Mercurial-patchbomb/* (glob)
1524 Date: Thu, 01 Jan 1970 00:01:00 +0000
1524 Date: Thu, 01 Jan 1970 00:01:00 +0000
1525 From: quux
1525 From: quux
1526 To: foo
1526 To: foo
1527 Cc: bar
1527 Cc: bar
1528
1528
1529 foo
1529 foo
1530
1530
1531 displaying [PATCH 1 of 1] c ...
1531 displaying [PATCH 1 of 1] c ...
1532 Content-Type: text/plain; charset="us-ascii"
1532 Content-Type: text/plain; charset="us-ascii"
1533 MIME-Version: 1.0
1533 MIME-Version: 1.0
1534 Content-Transfer-Encoding: 7bit
1534 Content-Transfer-Encoding: 7bit
1535 Subject: [PATCH 1 of 1] c
1535 Subject: [PATCH 1 of 1] c
1536 X-Mercurial-Node: ff2c9fa2018b15fa74b33363bda9527323e2a99f
1536 X-Mercurial-Node: ff2c9fa2018b15fa74b33363bda9527323e2a99f
1537 X-Mercurial-Series-Index: 1
1537 X-Mercurial-Series-Index: 1
1538 X-Mercurial-Series-Total: 1
1538 X-Mercurial-Series-Total: 1
1539 Message-Id: <ff2c9fa2018b15fa74b3.61@*> (glob)
1539 Message-Id: <ff2c9fa2018b15fa74b3.61@*> (glob)
1540 X-Mercurial-Series-Id: <ff2c9fa2018b15fa74b3.61@*> (glob)
1540 X-Mercurial-Series-Id: <ff2c9fa2018b15fa74b3.61@*> (glob)
1541 In-Reply-To: <patchbomb.60@*> (glob)
1541 In-Reply-To: <patchbomb.60@*> (glob)
1542 References: <patchbomb.60@*> (glob)
1542 References: <patchbomb.60@*> (glob)
1543 User-Agent: Mercurial-patchbomb/* (glob)
1543 User-Agent: Mercurial-patchbomb/* (glob)
1544 Date: Thu, 01 Jan 1970 00:01:01 +0000
1544 Date: Thu, 01 Jan 1970 00:01:01 +0000
1545 From: quux
1545 From: quux
1546 To: foo
1546 To: foo
1547 Cc: bar
1547 Cc: bar
1548
1548
1549 # HG changeset patch
1549 # HG changeset patch
1550 # User test
1550 # User test
1551 # Date 3 0
1551 # Date 3 0
1552 # Thu Jan 01 00:00:03 1970 +0000
1552 # Thu Jan 01 00:00:03 1970 +0000
1553 # Node ID ff2c9fa2018b15fa74b33363bda9527323e2a99f
1553 # Node ID ff2c9fa2018b15fa74b33363bda9527323e2a99f
1554 # Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9
1554 # Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9
1555 c
1555 c
1556
1556
1557 diff -r 97d72e5f12c7 -r ff2c9fa2018b c
1557 diff -r 97d72e5f12c7 -r ff2c9fa2018b c
1558 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1558 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1559 +++ b/c Thu Jan 01 00:00:03 1970 +0000
1559 +++ b/c Thu Jan 01 00:00:03 1970 +0000
1560 @@ -0,0 +1,1 @@
1560 @@ -0,0 +1,1 @@
1561 +c
1561 +c
1562
1562
1563
1563
1564 test intro for multiple patches:
1564 test intro for multiple patches:
1565 $ hg email --date '1970-1-1 0:1' -n --intro -f quux -t foo -c bar -s test \
1565 $ hg email --date '1970-1-1 0:1' -n --intro -f quux -t foo -c bar -s test \
1566 > -r 0:1
1566 > -r 0:1
1567 this patch series consists of 2 patches.
1567 this patch series consists of 2 patches.
1568
1568
1569
1569
1570 Write the introductory message for the patch series.
1570 Write the introductory message for the patch series.
1571
1571
1572
1572
1573 displaying [PATCH 0 of 2] test ...
1573 displaying [PATCH 0 of 2] test ...
1574 Content-Type: text/plain; charset="us-ascii"
1574 Content-Type: text/plain; charset="us-ascii"
1575 MIME-Version: 1.0
1575 MIME-Version: 1.0
1576 Content-Transfer-Encoding: 7bit
1576 Content-Transfer-Encoding: 7bit
1577 Subject: [PATCH 0 of 2] test
1577 Subject: [PATCH 0 of 2] test
1578 Message-Id: <patchbomb.60@*> (glob)
1578 Message-Id: <patchbomb.60@*> (glob)
1579 User-Agent: Mercurial-patchbomb/* (glob)
1579 User-Agent: Mercurial-patchbomb/* (glob)
1580 Date: Thu, 01 Jan 1970 00:01:00 +0000
1580 Date: Thu, 01 Jan 1970 00:01:00 +0000
1581 From: quux
1581 From: quux
1582 To: foo
1582 To: foo
1583 Cc: bar
1583 Cc: bar
1584
1584
1585
1585
1586 displaying [PATCH 1 of 2] a ...
1586 displaying [PATCH 1 of 2] a ...
1587 Content-Type: text/plain; charset="us-ascii"
1587 Content-Type: text/plain; charset="us-ascii"
1588 MIME-Version: 1.0
1588 MIME-Version: 1.0
1589 Content-Transfer-Encoding: 7bit
1589 Content-Transfer-Encoding: 7bit
1590 Subject: [PATCH 1 of 2] a
1590 Subject: [PATCH 1 of 2] a
1591 X-Mercurial-Node: 8580ff50825a50c8f716709acdf8de0deddcd6ab
1591 X-Mercurial-Node: 8580ff50825a50c8f716709acdf8de0deddcd6ab
1592 X-Mercurial-Series-Index: 1
1592 X-Mercurial-Series-Index: 1
1593 X-Mercurial-Series-Total: 2
1593 X-Mercurial-Series-Total: 2
1594 Message-Id: <8580ff50825a50c8f716.61@*> (glob)
1594 Message-Id: <8580ff50825a50c8f716.61@*> (glob)
1595 X-Mercurial-Series-Id: <8580ff50825a50c8f716.61@*> (glob)
1595 X-Mercurial-Series-Id: <8580ff50825a50c8f716.61@*> (glob)
1596 In-Reply-To: <patchbomb.60@*> (glob)
1596 In-Reply-To: <patchbomb.60@*> (glob)
1597 References: <patchbomb.60@*> (glob)
1597 References: <patchbomb.60@*> (glob)
1598 User-Agent: Mercurial-patchbomb/* (glob)
1598 User-Agent: Mercurial-patchbomb/* (glob)
1599 Date: Thu, 01 Jan 1970 00:01:01 +0000
1599 Date: Thu, 01 Jan 1970 00:01:01 +0000
1600 From: quux
1600 From: quux
1601 To: foo
1601 To: foo
1602 Cc: bar
1602 Cc: bar
1603
1603
1604 # HG changeset patch
1604 # HG changeset patch
1605 # User test
1605 # User test
1606 # Date 1 0
1606 # Date 1 0
1607 # Thu Jan 01 00:00:01 1970 +0000
1607 # Thu Jan 01 00:00:01 1970 +0000
1608 # Node ID 8580ff50825a50c8f716709acdf8de0deddcd6ab
1608 # Node ID 8580ff50825a50c8f716709acdf8de0deddcd6ab
1609 # Parent 0000000000000000000000000000000000000000
1609 # Parent 0000000000000000000000000000000000000000
1610 a
1610 a
1611
1611
1612 diff -r 000000000000 -r 8580ff50825a a
1612 diff -r 000000000000 -r 8580ff50825a a
1613 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1613 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1614 +++ b/a Thu Jan 01 00:00:01 1970 +0000
1614 +++ b/a Thu Jan 01 00:00:01 1970 +0000
1615 @@ -0,0 +1,1 @@
1615 @@ -0,0 +1,1 @@
1616 +a
1616 +a
1617
1617
1618 displaying [PATCH 2 of 2] b ...
1618 displaying [PATCH 2 of 2] b ...
1619 Content-Type: text/plain; charset="us-ascii"
1619 Content-Type: text/plain; charset="us-ascii"
1620 MIME-Version: 1.0
1620 MIME-Version: 1.0
1621 Content-Transfer-Encoding: 7bit
1621 Content-Transfer-Encoding: 7bit
1622 Subject: [PATCH 2 of 2] b
1622 Subject: [PATCH 2 of 2] b
1623 X-Mercurial-Node: 97d72e5f12c7e84f85064aa72e5a297142c36ed9
1623 X-Mercurial-Node: 97d72e5f12c7e84f85064aa72e5a297142c36ed9
1624 X-Mercurial-Series-Index: 2
1624 X-Mercurial-Series-Index: 2
1625 X-Mercurial-Series-Total: 2
1625 X-Mercurial-Series-Total: 2
1626 Message-Id: <97d72e5f12c7e84f8506.62@*> (glob)
1626 Message-Id: <97d72e5f12c7e84f8506.62@*> (glob)
1627 X-Mercurial-Series-Id: <8580ff50825a50c8f716.61@*> (glob)
1627 X-Mercurial-Series-Id: <8580ff50825a50c8f716.61@*> (glob)
1628 In-Reply-To: <patchbomb.60@*> (glob)
1628 In-Reply-To: <patchbomb.60@*> (glob)
1629 References: <patchbomb.60@*> (glob)
1629 References: <patchbomb.60@*> (glob)
1630 User-Agent: Mercurial-patchbomb/* (glob)
1630 User-Agent: Mercurial-patchbomb/* (glob)
1631 Date: Thu, 01 Jan 1970 00:01:02 +0000
1631 Date: Thu, 01 Jan 1970 00:01:02 +0000
1632 From: quux
1632 From: quux
1633 To: foo
1633 To: foo
1634 Cc: bar
1634 Cc: bar
1635
1635
1636 # HG changeset patch
1636 # HG changeset patch
1637 # User test
1637 # User test
1638 # Date 2 0
1638 # Date 2 0
1639 # Thu Jan 01 00:00:02 1970 +0000
1639 # Thu Jan 01 00:00:02 1970 +0000
1640 # Node ID 97d72e5f12c7e84f85064aa72e5a297142c36ed9
1640 # Node ID 97d72e5f12c7e84f85064aa72e5a297142c36ed9
1641 # Parent 8580ff50825a50c8f716709acdf8de0deddcd6ab
1641 # Parent 8580ff50825a50c8f716709acdf8de0deddcd6ab
1642 b
1642 b
1643
1643
1644 diff -r 8580ff50825a -r 97d72e5f12c7 b
1644 diff -r 8580ff50825a -r 97d72e5f12c7 b
1645 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1645 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1646 +++ b/b Thu Jan 01 00:00:02 1970 +0000
1646 +++ b/b Thu Jan 01 00:00:02 1970 +0000
1647 @@ -0,0 +1,1 @@
1647 @@ -0,0 +1,1 @@
1648 +b
1648 +b
1649
1649
1650
1650
1651 test reply-to via config:
1651 test reply-to via config:
1652 $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -r 2 \
1652 $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -r 2 \
1653 > --config patchbomb.reply-to='baz@example.com'
1653 > --config patchbomb.reply-to='baz@example.com'
1654 this patch series consists of 1 patches.
1654 this patch series consists of 1 patches.
1655
1655
1656
1656
1657 displaying [PATCH] test ...
1657 displaying [PATCH] test ...
1658 Content-Type: text/plain; charset="us-ascii"
1658 Content-Type: text/plain; charset="us-ascii"
1659 MIME-Version: 1.0
1659 MIME-Version: 1.0
1660 Content-Transfer-Encoding: 7bit
1660 Content-Transfer-Encoding: 7bit
1661 Subject: [PATCH] test
1661 Subject: [PATCH] test
1662 X-Mercurial-Node: ff2c9fa2018b15fa74b33363bda9527323e2a99f
1662 X-Mercurial-Node: ff2c9fa2018b15fa74b33363bda9527323e2a99f
1663 X-Mercurial-Series-Index: 1
1663 X-Mercurial-Series-Index: 1
1664 X-Mercurial-Series-Total: 1
1664 X-Mercurial-Series-Total: 1
1665 Message-Id: <ff2c9fa2018b15fa74b3.60@*> (glob)
1665 Message-Id: <ff2c9fa2018b15fa74b3.60@*> (glob)
1666 X-Mercurial-Series-Id: <ff2c9fa2018b15fa74b3.60@*> (glob)
1666 X-Mercurial-Series-Id: <ff2c9fa2018b15fa74b3.60@*> (glob)
1667 User-Agent: Mercurial-patchbomb/* (glob)
1667 User-Agent: Mercurial-patchbomb/* (glob)
1668 Date: Thu, 01 Jan 1970 00:01:00 +0000
1668 Date: Thu, 01 Jan 1970 00:01:00 +0000
1669 From: quux
1669 From: quux
1670 To: foo
1670 To: foo
1671 Cc: bar
1671 Cc: bar
1672 Reply-To: baz@example.com
1672 Reply-To: baz@example.com
1673
1673
1674 # HG changeset patch
1674 # HG changeset patch
1675 # User test
1675 # User test
1676 # Date 3 0
1676 # Date 3 0
1677 # Thu Jan 01 00:00:03 1970 +0000
1677 # Thu Jan 01 00:00:03 1970 +0000
1678 # Node ID ff2c9fa2018b15fa74b33363bda9527323e2a99f
1678 # Node ID ff2c9fa2018b15fa74b33363bda9527323e2a99f
1679 # Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9
1679 # Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9
1680 c
1680 c
1681
1681
1682 diff -r 97d72e5f12c7 -r ff2c9fa2018b c
1682 diff -r 97d72e5f12c7 -r ff2c9fa2018b c
1683 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1683 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1684 +++ b/c Thu Jan 01 00:00:03 1970 +0000
1684 +++ b/c Thu Jan 01 00:00:03 1970 +0000
1685 @@ -0,0 +1,1 @@
1685 @@ -0,0 +1,1 @@
1686 +c
1686 +c
1687
1687
1688
1688
1689 test reply-to via command line:
1689 test reply-to via command line:
1690 $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -r 2 \
1690 $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -r 2 \
1691 > --reply-to baz --reply-to fred
1691 > --reply-to baz --reply-to fred
1692 this patch series consists of 1 patches.
1692 this patch series consists of 1 patches.
1693
1693
1694
1694
1695 displaying [PATCH] test ...
1695 displaying [PATCH] test ...
1696 Content-Type: text/plain; charset="us-ascii"
1696 Content-Type: text/plain; charset="us-ascii"
1697 MIME-Version: 1.0
1697 MIME-Version: 1.0
1698 Content-Transfer-Encoding: 7bit
1698 Content-Transfer-Encoding: 7bit
1699 Subject: [PATCH] test
1699 Subject: [PATCH] test
1700 X-Mercurial-Node: ff2c9fa2018b15fa74b33363bda9527323e2a99f
1700 X-Mercurial-Node: ff2c9fa2018b15fa74b33363bda9527323e2a99f
1701 X-Mercurial-Series-Index: 1
1701 X-Mercurial-Series-Index: 1
1702 X-Mercurial-Series-Total: 1
1702 X-Mercurial-Series-Total: 1
1703 Message-Id: <ff2c9fa2018b15fa74b3.60@*> (glob)
1703 Message-Id: <ff2c9fa2018b15fa74b3.60@*> (glob)
1704 X-Mercurial-Series-Id: <ff2c9fa2018b15fa74b3.60@*> (glob)
1704 X-Mercurial-Series-Id: <ff2c9fa2018b15fa74b3.60@*> (glob)
1705 User-Agent: Mercurial-patchbomb/* (glob)
1705 User-Agent: Mercurial-patchbomb/* (glob)
1706 Date: Thu, 01 Jan 1970 00:01:00 +0000
1706 Date: Thu, 01 Jan 1970 00:01:00 +0000
1707 From: quux
1707 From: quux
1708 To: foo
1708 To: foo
1709 Cc: bar
1709 Cc: bar
1710 Reply-To: baz, fred
1710 Reply-To: baz, fred
1711
1711
1712 # HG changeset patch
1712 # HG changeset patch
1713 # User test
1713 # User test
1714 # Date 3 0
1714 # Date 3 0
1715 # Thu Jan 01 00:00:03 1970 +0000
1715 # Thu Jan 01 00:00:03 1970 +0000
1716 # Node ID ff2c9fa2018b15fa74b33363bda9527323e2a99f
1716 # Node ID ff2c9fa2018b15fa74b33363bda9527323e2a99f
1717 # Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9
1717 # Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9
1718 c
1718 c
1719
1719
1720 diff -r 97d72e5f12c7 -r ff2c9fa2018b c
1720 diff -r 97d72e5f12c7 -r ff2c9fa2018b c
1721 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1721 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1722 +++ b/c Thu Jan 01 00:00:03 1970 +0000
1722 +++ b/c Thu Jan 01 00:00:03 1970 +0000
1723 @@ -0,0 +1,1 @@
1723 @@ -0,0 +1,1 @@
1724 +c
1724 +c
1725
1725
1726
1726
1727 tagging csets:
1727 tagging csets:
1728 $ hg tag -r0 zero zero.foo
1728 $ hg tag -r0 zero zero.foo
1729 $ hg tag -r1 one one.patch
1729 $ hg tag -r1 one one.patch
1730 $ hg tag -r2 two two.diff
1730 $ hg tag -r2 two two.diff
1731
1731
1732 test inline for single named patch:
1732 test inline for single named patch:
1733 $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -i \
1733 $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -i \
1734 > -r 2 | $FILTERBOUNDARY
1734 > -r 2 | $FILTERBOUNDARY
1735 this patch series consists of 1 patches.
1735 this patch series consists of 1 patches.
1736
1736
1737
1737
1738 displaying [PATCH] test ...
1738 displaying [PATCH] test ...
1739 Content-Type: multipart/mixed; boundary="===*==" (glob)
1739 Content-Type: multipart/mixed; boundary="===*==" (glob)
1740 MIME-Version: 1.0
1740 MIME-Version: 1.0
1741 Subject: [PATCH] test
1741 Subject: [PATCH] test
1742 X-Mercurial-Node: ff2c9fa2018b15fa74b33363bda9527323e2a99f
1742 X-Mercurial-Node: ff2c9fa2018b15fa74b33363bda9527323e2a99f
1743 X-Mercurial-Series-Index: 1
1743 X-Mercurial-Series-Index: 1
1744 X-Mercurial-Series-Total: 1
1744 X-Mercurial-Series-Total: 1
1745 Message-Id: <ff2c9fa2018b15fa74b3.60@*> (glob)
1745 Message-Id: <ff2c9fa2018b15fa74b3.60@*> (glob)
1746 X-Mercurial-Series-Id: <ff2c9fa2018b15fa74b3.60@*> (glob)
1746 X-Mercurial-Series-Id: <ff2c9fa2018b15fa74b3.60@*> (glob)
1747 User-Agent: Mercurial-patchbomb/* (glob)
1747 User-Agent: Mercurial-patchbomb/* (glob)
1748 Date: Thu, 01 Jan 1970 00:01:00 +0000
1748 Date: Thu, 01 Jan 1970 00:01:00 +0000
1749 From: quux
1749 From: quux
1750 To: foo
1750 To: foo
1751 Cc: bar
1751 Cc: bar
1752
1752
1753 --===*= (glob)
1753 --===*= (glob)
1754 Content-Type: text/x-patch; charset="us-ascii"
1754 Content-Type: text/x-patch; charset="us-ascii"
1755 MIME-Version: 1.0
1755 MIME-Version: 1.0
1756 Content-Transfer-Encoding: 7bit
1756 Content-Transfer-Encoding: 7bit
1757 Content-Disposition: inline; filename=two.diff
1757 Content-Disposition: inline; filename=two.diff
1758
1758
1759 # HG changeset patch
1759 # HG changeset patch
1760 # User test
1760 # User test
1761 # Date 3 0
1761 # Date 3 0
1762 # Thu Jan 01 00:00:03 1970 +0000
1762 # Thu Jan 01 00:00:03 1970 +0000
1763 # Node ID ff2c9fa2018b15fa74b33363bda9527323e2a99f
1763 # Node ID ff2c9fa2018b15fa74b33363bda9527323e2a99f
1764 # Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9
1764 # Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9
1765 c
1765 c
1766
1766
1767 diff -r 97d72e5f12c7 -r ff2c9fa2018b c
1767 diff -r 97d72e5f12c7 -r ff2c9fa2018b c
1768 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1768 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1769 +++ b/c Thu Jan 01 00:00:03 1970 +0000
1769 +++ b/c Thu Jan 01 00:00:03 1970 +0000
1770 @@ -0,0 +1,1 @@
1770 @@ -0,0 +1,1 @@
1771 +c
1771 +c
1772
1772
1773 --===*=-- (glob)
1773 --===*=-- (glob)
1774
1774
1775 test inline for multiple named/unnamed patches:
1775 test inline for multiple named/unnamed patches:
1776 $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -i \
1776 $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -i \
1777 > -r 0:1 | $FILTERBOUNDARY
1777 > -r 0:1 | $FILTERBOUNDARY
1778 this patch series consists of 2 patches.
1778 this patch series consists of 2 patches.
1779
1779
1780
1780
1781 Write the introductory message for the patch series.
1781 Write the introductory message for the patch series.
1782
1782
1783
1783
1784 displaying [PATCH 0 of 2] test ...
1784 displaying [PATCH 0 of 2] test ...
1785 Content-Type: text/plain; charset="us-ascii"
1785 Content-Type: text/plain; charset="us-ascii"
1786 MIME-Version: 1.0
1786 MIME-Version: 1.0
1787 Content-Transfer-Encoding: 7bit
1787 Content-Transfer-Encoding: 7bit
1788 Subject: [PATCH 0 of 2] test
1788 Subject: [PATCH 0 of 2] test
1789 Message-Id: <patchbomb.60@*> (glob)
1789 Message-Id: <patchbomb.60@*> (glob)
1790 User-Agent: Mercurial-patchbomb/* (glob)
1790 User-Agent: Mercurial-patchbomb/* (glob)
1791 Date: Thu, 01 Jan 1970 00:01:00 +0000
1791 Date: Thu, 01 Jan 1970 00:01:00 +0000
1792 From: quux
1792 From: quux
1793 To: foo
1793 To: foo
1794 Cc: bar
1794 Cc: bar
1795
1795
1796
1796
1797 displaying [PATCH 1 of 2] a ...
1797 displaying [PATCH 1 of 2] a ...
1798 Content-Type: multipart/mixed; boundary="===*==" (glob)
1798 Content-Type: multipart/mixed; boundary="===*==" (glob)
1799 MIME-Version: 1.0
1799 MIME-Version: 1.0
1800 Subject: [PATCH 1 of 2] a
1800 Subject: [PATCH 1 of 2] a
1801 X-Mercurial-Node: 8580ff50825a50c8f716709acdf8de0deddcd6ab
1801 X-Mercurial-Node: 8580ff50825a50c8f716709acdf8de0deddcd6ab
1802 X-Mercurial-Series-Index: 1
1802 X-Mercurial-Series-Index: 1
1803 X-Mercurial-Series-Total: 2
1803 X-Mercurial-Series-Total: 2
1804 Message-Id: <8580ff50825a50c8f716.61@*> (glob)
1804 Message-Id: <8580ff50825a50c8f716.61@*> (glob)
1805 X-Mercurial-Series-Id: <8580ff50825a50c8f716.61@*> (glob)
1805 X-Mercurial-Series-Id: <8580ff50825a50c8f716.61@*> (glob)
1806 In-Reply-To: <patchbomb.60@*> (glob)
1806 In-Reply-To: <patchbomb.60@*> (glob)
1807 References: <patchbomb.60@*> (glob)
1807 References: <patchbomb.60@*> (glob)
1808 User-Agent: Mercurial-patchbomb/* (glob)
1808 User-Agent: Mercurial-patchbomb/* (glob)
1809 Date: Thu, 01 Jan 1970 00:01:01 +0000
1809 Date: Thu, 01 Jan 1970 00:01:01 +0000
1810 From: quux
1810 From: quux
1811 To: foo
1811 To: foo
1812 Cc: bar
1812 Cc: bar
1813
1813
1814 --===*= (glob)
1814 --===*= (glob)
1815 Content-Type: text/x-patch; charset="us-ascii"
1815 Content-Type: text/x-patch; charset="us-ascii"
1816 MIME-Version: 1.0
1816 MIME-Version: 1.0
1817 Content-Transfer-Encoding: 7bit
1817 Content-Transfer-Encoding: 7bit
1818 Content-Disposition: inline; filename=t2-1.patch
1818 Content-Disposition: inline; filename=t2-1.patch
1819
1819
1820 # HG changeset patch
1820 # HG changeset patch
1821 # User test
1821 # User test
1822 # Date 1 0
1822 # Date 1 0
1823 # Thu Jan 01 00:00:01 1970 +0000
1823 # Thu Jan 01 00:00:01 1970 +0000
1824 # Node ID 8580ff50825a50c8f716709acdf8de0deddcd6ab
1824 # Node ID 8580ff50825a50c8f716709acdf8de0deddcd6ab
1825 # Parent 0000000000000000000000000000000000000000
1825 # Parent 0000000000000000000000000000000000000000
1826 a
1826 a
1827
1827
1828 diff -r 000000000000 -r 8580ff50825a a
1828 diff -r 000000000000 -r 8580ff50825a a
1829 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1829 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1830 +++ b/a Thu Jan 01 00:00:01 1970 +0000
1830 +++ b/a Thu Jan 01 00:00:01 1970 +0000
1831 @@ -0,0 +1,1 @@
1831 @@ -0,0 +1,1 @@
1832 +a
1832 +a
1833
1833
1834 --===*=-- (glob)
1834 --===*=-- (glob)
1835 displaying [PATCH 2 of 2] b ...
1835 displaying [PATCH 2 of 2] b ...
1836 Content-Type: multipart/mixed; boundary="===*==" (glob)
1836 Content-Type: multipart/mixed; boundary="===*==" (glob)
1837 MIME-Version: 1.0
1837 MIME-Version: 1.0
1838 Subject: [PATCH 2 of 2] b
1838 Subject: [PATCH 2 of 2] b
1839 X-Mercurial-Node: 97d72e5f12c7e84f85064aa72e5a297142c36ed9
1839 X-Mercurial-Node: 97d72e5f12c7e84f85064aa72e5a297142c36ed9
1840 X-Mercurial-Series-Index: 2
1840 X-Mercurial-Series-Index: 2
1841 X-Mercurial-Series-Total: 2
1841 X-Mercurial-Series-Total: 2
1842 Message-Id: <97d72e5f12c7e84f8506.62@*> (glob)
1842 Message-Id: <97d72e5f12c7e84f8506.62@*> (glob)
1843 X-Mercurial-Series-Id: <8580ff50825a50c8f716.61@*> (glob)
1843 X-Mercurial-Series-Id: <8580ff50825a50c8f716.61@*> (glob)
1844 In-Reply-To: <patchbomb.60@*> (glob)
1844 In-Reply-To: <patchbomb.60@*> (glob)
1845 References: <patchbomb.60@*> (glob)
1845 References: <patchbomb.60@*> (glob)
1846 User-Agent: Mercurial-patchbomb/* (glob)
1846 User-Agent: Mercurial-patchbomb/* (glob)
1847 Date: Thu, 01 Jan 1970 00:01:02 +0000
1847 Date: Thu, 01 Jan 1970 00:01:02 +0000
1848 From: quux
1848 From: quux
1849 To: foo
1849 To: foo
1850 Cc: bar
1850 Cc: bar
1851
1851
1852 --===*= (glob)
1852 --===*= (glob)
1853 Content-Type: text/x-patch; charset="us-ascii"
1853 Content-Type: text/x-patch; charset="us-ascii"
1854 MIME-Version: 1.0
1854 MIME-Version: 1.0
1855 Content-Transfer-Encoding: 7bit
1855 Content-Transfer-Encoding: 7bit
1856 Content-Disposition: inline; filename=one.patch
1856 Content-Disposition: inline; filename=one.patch
1857
1857
1858 # HG changeset patch
1858 # HG changeset patch
1859 # User test
1859 # User test
1860 # Date 2 0
1860 # Date 2 0
1861 # Thu Jan 01 00:00:02 1970 +0000
1861 # Thu Jan 01 00:00:02 1970 +0000
1862 # Node ID 97d72e5f12c7e84f85064aa72e5a297142c36ed9
1862 # Node ID 97d72e5f12c7e84f85064aa72e5a297142c36ed9
1863 # Parent 8580ff50825a50c8f716709acdf8de0deddcd6ab
1863 # Parent 8580ff50825a50c8f716709acdf8de0deddcd6ab
1864 b
1864 b
1865
1865
1866 diff -r 8580ff50825a -r 97d72e5f12c7 b
1866 diff -r 8580ff50825a -r 97d72e5f12c7 b
1867 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1867 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1868 +++ b/b Thu Jan 01 00:00:02 1970 +0000
1868 +++ b/b Thu Jan 01 00:00:02 1970 +0000
1869 @@ -0,0 +1,1 @@
1869 @@ -0,0 +1,1 @@
1870 +b
1870 +b
1871
1871
1872 --===*=-- (glob)
1872 --===*=-- (glob)
1873
1873
1874
1874
1875 test inreplyto:
1875 test inreplyto:
1876 $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar --in-reply-to baz \
1876 $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar --in-reply-to baz \
1877 > -r tip
1877 > -r tip
1878 this patch series consists of 1 patches.
1878 this patch series consists of 1 patches.
1879
1879
1880
1880
1881 displaying [PATCH] Added tag two, two.diff for changeset ff2c9fa2018b ...
1881 displaying [PATCH] Added tag two, two.diff for changeset ff2c9fa2018b ...
1882 Content-Type: text/plain; charset="us-ascii"
1882 Content-Type: text/plain; charset="us-ascii"
1883 MIME-Version: 1.0
1883 MIME-Version: 1.0
1884 Content-Transfer-Encoding: 7bit
1884 Content-Transfer-Encoding: 7bit
1885 Subject: [PATCH] Added tag two, two.diff for changeset ff2c9fa2018b
1885 Subject: [PATCH] Added tag two, two.diff for changeset ff2c9fa2018b
1886 X-Mercurial-Node: 7aead2484924c445ad8ce2613df91f52f9e502ed
1886 X-Mercurial-Node: 7aead2484924c445ad8ce2613df91f52f9e502ed
1887 X-Mercurial-Series-Index: 1
1887 X-Mercurial-Series-Index: 1
1888 X-Mercurial-Series-Total: 1
1888 X-Mercurial-Series-Total: 1
1889 Message-Id: <7aead2484924c445ad8c.60@*> (glob)
1889 Message-Id: <7aead2484924c445ad8c.60@*> (glob)
1890 X-Mercurial-Series-Id: <7aead2484924c445ad8c.60@*> (glob)
1890 X-Mercurial-Series-Id: <7aead2484924c445ad8c.60@*> (glob)
1891 In-Reply-To: <baz>
1891 In-Reply-To: <baz>
1892 References: <baz>
1892 References: <baz>
1893 User-Agent: Mercurial-patchbomb/* (glob)
1893 User-Agent: Mercurial-patchbomb/* (glob)
1894 Date: Thu, 01 Jan 1970 00:01:00 +0000
1894 Date: Thu, 01 Jan 1970 00:01:00 +0000
1895 From: quux
1895 From: quux
1896 To: foo
1896 To: foo
1897 Cc: bar
1897 Cc: bar
1898
1898
1899 # HG changeset patch
1899 # HG changeset patch
1900 # User test
1900 # User test
1901 # Date 0 0
1901 # Date 0 0
1902 # Thu Jan 01 00:00:00 1970 +0000
1902 # Thu Jan 01 00:00:00 1970 +0000
1903 # Node ID 7aead2484924c445ad8ce2613df91f52f9e502ed
1903 # Node ID 7aead2484924c445ad8ce2613df91f52f9e502ed
1904 # Parent 045ca29b1ea20e4940411e695e20e521f2f0f98e
1904 # Parent 045ca29b1ea20e4940411e695e20e521f2f0f98e
1905 Added tag two, two.diff for changeset ff2c9fa2018b
1905 Added tag two, two.diff for changeset ff2c9fa2018b
1906
1906
1907 diff -r 045ca29b1ea2 -r 7aead2484924 .hgtags
1907 diff -r 045ca29b1ea2 -r 7aead2484924 .hgtags
1908 --- a/.hgtags Thu Jan 01 00:00:00 1970 +0000
1908 --- a/.hgtags Thu Jan 01 00:00:00 1970 +0000
1909 +++ b/.hgtags Thu Jan 01 00:00:00 1970 +0000
1909 +++ b/.hgtags Thu Jan 01 00:00:00 1970 +0000
1910 @@ -2,3 +2,5 @@
1910 @@ -2,3 +2,5 @@
1911 8580ff50825a50c8f716709acdf8de0deddcd6ab zero.foo
1911 8580ff50825a50c8f716709acdf8de0deddcd6ab zero.foo
1912 97d72e5f12c7e84f85064aa72e5a297142c36ed9 one
1912 97d72e5f12c7e84f85064aa72e5a297142c36ed9 one
1913 97d72e5f12c7e84f85064aa72e5a297142c36ed9 one.patch
1913 97d72e5f12c7e84f85064aa72e5a297142c36ed9 one.patch
1914 +ff2c9fa2018b15fa74b33363bda9527323e2a99f two
1914 +ff2c9fa2018b15fa74b33363bda9527323e2a99f two
1915 +ff2c9fa2018b15fa74b33363bda9527323e2a99f two.diff
1915 +ff2c9fa2018b15fa74b33363bda9527323e2a99f two.diff
1916
1916
1917 no intro message in non-interactive mode
1917 no intro message in non-interactive mode
1918 $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar --in-reply-to baz \
1918 $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar --in-reply-to baz \
1919 > -r 0:1
1919 > -r 0:1
1920 this patch series consists of 2 patches.
1920 this patch series consists of 2 patches.
1921
1921
1922 (optional) Subject: [PATCH 0 of 2]
1922 (optional) Subject: [PATCH 0 of 2]
1923
1923
1924 displaying [PATCH 1 of 2] a ...
1924 displaying [PATCH 1 of 2] a ...
1925 Content-Type: text/plain; charset="us-ascii"
1925 Content-Type: text/plain; charset="us-ascii"
1926 MIME-Version: 1.0
1926 MIME-Version: 1.0
1927 Content-Transfer-Encoding: 7bit
1927 Content-Transfer-Encoding: 7bit
1928 Subject: [PATCH 1 of 2] a
1928 Subject: [PATCH 1 of 2] a
1929 X-Mercurial-Node: 8580ff50825a50c8f716709acdf8de0deddcd6ab
1929 X-Mercurial-Node: 8580ff50825a50c8f716709acdf8de0deddcd6ab
1930 X-Mercurial-Series-Index: 1
1930 X-Mercurial-Series-Index: 1
1931 X-Mercurial-Series-Total: 2
1931 X-Mercurial-Series-Total: 2
1932 Message-Id: <8580ff50825a50c8f716.60@*> (glob)
1932 Message-Id: <8580ff50825a50c8f716.60@*> (glob)
1933 X-Mercurial-Series-Id: <8580ff50825a50c8f716.60@*> (glob)
1933 X-Mercurial-Series-Id: <8580ff50825a50c8f716.60@*> (glob)
1934 In-Reply-To: <baz>
1934 In-Reply-To: <baz>
1935 References: <baz>
1935 References: <baz>
1936 User-Agent: Mercurial-patchbomb/* (glob)
1936 User-Agent: Mercurial-patchbomb/* (glob)
1937 Date: Thu, 01 Jan 1970 00:01:00 +0000
1937 Date: Thu, 01 Jan 1970 00:01:00 +0000
1938 From: quux
1938 From: quux
1939 To: foo
1939 To: foo
1940 Cc: bar
1940 Cc: bar
1941
1941
1942 # HG changeset patch
1942 # HG changeset patch
1943 # User test
1943 # User test
1944 # Date 1 0
1944 # Date 1 0
1945 # Thu Jan 01 00:00:01 1970 +0000
1945 # Thu Jan 01 00:00:01 1970 +0000
1946 # Node ID 8580ff50825a50c8f716709acdf8de0deddcd6ab
1946 # Node ID 8580ff50825a50c8f716709acdf8de0deddcd6ab
1947 # Parent 0000000000000000000000000000000000000000
1947 # Parent 0000000000000000000000000000000000000000
1948 a
1948 a
1949
1949
1950 diff -r 000000000000 -r 8580ff50825a a
1950 diff -r 000000000000 -r 8580ff50825a a
1951 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1951 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1952 +++ b/a Thu Jan 01 00:00:01 1970 +0000
1952 +++ b/a Thu Jan 01 00:00:01 1970 +0000
1953 @@ -0,0 +1,1 @@
1953 @@ -0,0 +1,1 @@
1954 +a
1954 +a
1955
1955
1956 displaying [PATCH 2 of 2] b ...
1956 displaying [PATCH 2 of 2] b ...
1957 Content-Type: text/plain; charset="us-ascii"
1957 Content-Type: text/plain; charset="us-ascii"
1958 MIME-Version: 1.0
1958 MIME-Version: 1.0
1959 Content-Transfer-Encoding: 7bit
1959 Content-Transfer-Encoding: 7bit
1960 Subject: [PATCH 2 of 2] b
1960 Subject: [PATCH 2 of 2] b
1961 X-Mercurial-Node: 97d72e5f12c7e84f85064aa72e5a297142c36ed9
1961 X-Mercurial-Node: 97d72e5f12c7e84f85064aa72e5a297142c36ed9
1962 X-Mercurial-Series-Index: 2
1962 X-Mercurial-Series-Index: 2
1963 X-Mercurial-Series-Total: 2
1963 X-Mercurial-Series-Total: 2
1964 Message-Id: <97d72e5f12c7e84f8506.61@*> (glob)
1964 Message-Id: <97d72e5f12c7e84f8506.61@*> (glob)
1965 X-Mercurial-Series-Id: <8580ff50825a50c8f716.60@*> (glob)
1965 X-Mercurial-Series-Id: <8580ff50825a50c8f716.60@*> (glob)
1966 In-Reply-To: <baz>
1966 In-Reply-To: <baz>
1967 References: <baz>
1967 References: <baz>
1968 User-Agent: Mercurial-patchbomb/* (glob)
1968 User-Agent: Mercurial-patchbomb/* (glob)
1969 Date: Thu, 01 Jan 1970 00:01:01 +0000
1969 Date: Thu, 01 Jan 1970 00:01:01 +0000
1970 From: quux
1970 From: quux
1971 To: foo
1971 To: foo
1972 Cc: bar
1972 Cc: bar
1973
1973
1974 # HG changeset patch
1974 # HG changeset patch
1975 # User test
1975 # User test
1976 # Date 2 0
1976 # Date 2 0
1977 # Thu Jan 01 00:00:02 1970 +0000
1977 # Thu Jan 01 00:00:02 1970 +0000
1978 # Node ID 97d72e5f12c7e84f85064aa72e5a297142c36ed9
1978 # Node ID 97d72e5f12c7e84f85064aa72e5a297142c36ed9
1979 # Parent 8580ff50825a50c8f716709acdf8de0deddcd6ab
1979 # Parent 8580ff50825a50c8f716709acdf8de0deddcd6ab
1980 b
1980 b
1981
1981
1982 diff -r 8580ff50825a -r 97d72e5f12c7 b
1982 diff -r 8580ff50825a -r 97d72e5f12c7 b
1983 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1983 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1984 +++ b/b Thu Jan 01 00:00:02 1970 +0000
1984 +++ b/b Thu Jan 01 00:00:02 1970 +0000
1985 @@ -0,0 +1,1 @@
1985 @@ -0,0 +1,1 @@
1986 +b
1986 +b
1987
1987
1988
1988
1989
1989
1990
1990
1991 $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar --in-reply-to baz \
1991 $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar --in-reply-to baz \
1992 > -s test -r 0:1
1992 > -s test -r 0:1
1993 this patch series consists of 2 patches.
1993 this patch series consists of 2 patches.
1994
1994
1995
1995
1996 Write the introductory message for the patch series.
1996 Write the introductory message for the patch series.
1997
1997
1998
1998
1999 displaying [PATCH 0 of 2] test ...
1999 displaying [PATCH 0 of 2] test ...
2000 Content-Type: text/plain; charset="us-ascii"
2000 Content-Type: text/plain; charset="us-ascii"
2001 MIME-Version: 1.0
2001 MIME-Version: 1.0
2002 Content-Transfer-Encoding: 7bit
2002 Content-Transfer-Encoding: 7bit
2003 Subject: [PATCH 0 of 2] test
2003 Subject: [PATCH 0 of 2] test
2004 Message-Id: <patchbomb.60@*> (glob)
2004 Message-Id: <patchbomb.60@*> (glob)
2005 In-Reply-To: <baz>
2005 In-Reply-To: <baz>
2006 References: <baz>
2006 References: <baz>
2007 User-Agent: Mercurial-patchbomb/* (glob)
2007 User-Agent: Mercurial-patchbomb/* (glob)
2008 Date: Thu, 01 Jan 1970 00:01:00 +0000
2008 Date: Thu, 01 Jan 1970 00:01:00 +0000
2009 From: quux
2009 From: quux
2010 To: foo
2010 To: foo
2011 Cc: bar
2011 Cc: bar
2012
2012
2013
2013
2014 displaying [PATCH 1 of 2] a ...
2014 displaying [PATCH 1 of 2] a ...
2015 Content-Type: text/plain; charset="us-ascii"
2015 Content-Type: text/plain; charset="us-ascii"
2016 MIME-Version: 1.0
2016 MIME-Version: 1.0
2017 Content-Transfer-Encoding: 7bit
2017 Content-Transfer-Encoding: 7bit
2018 Subject: [PATCH 1 of 2] a
2018 Subject: [PATCH 1 of 2] a
2019 X-Mercurial-Node: 8580ff50825a50c8f716709acdf8de0deddcd6ab
2019 X-Mercurial-Node: 8580ff50825a50c8f716709acdf8de0deddcd6ab
2020 X-Mercurial-Series-Index: 1
2020 X-Mercurial-Series-Index: 1
2021 X-Mercurial-Series-Total: 2
2021 X-Mercurial-Series-Total: 2
2022 Message-Id: <8580ff50825a50c8f716.61@*> (glob)
2022 Message-Id: <8580ff50825a50c8f716.61@*> (glob)
2023 X-Mercurial-Series-Id: <8580ff50825a50c8f716.61@*> (glob)
2023 X-Mercurial-Series-Id: <8580ff50825a50c8f716.61@*> (glob)
2024 In-Reply-To: <patchbomb.60@*> (glob)
2024 In-Reply-To: <patchbomb.60@*> (glob)
2025 References: <patchbomb.60@*> (glob)
2025 References: <patchbomb.60@*> (glob)
2026 User-Agent: Mercurial-patchbomb/* (glob)
2026 User-Agent: Mercurial-patchbomb/* (glob)
2027 Date: Thu, 01 Jan 1970 00:01:01 +0000
2027 Date: Thu, 01 Jan 1970 00:01:01 +0000
2028 From: quux
2028 From: quux
2029 To: foo
2029 To: foo
2030 Cc: bar
2030 Cc: bar
2031
2031
2032 # HG changeset patch
2032 # HG changeset patch
2033 # User test
2033 # User test
2034 # Date 1 0
2034 # Date 1 0
2035 # Thu Jan 01 00:00:01 1970 +0000
2035 # Thu Jan 01 00:00:01 1970 +0000
2036 # Node ID 8580ff50825a50c8f716709acdf8de0deddcd6ab
2036 # Node ID 8580ff50825a50c8f716709acdf8de0deddcd6ab
2037 # Parent 0000000000000000000000000000000000000000
2037 # Parent 0000000000000000000000000000000000000000
2038 a
2038 a
2039
2039
2040 diff -r 000000000000 -r 8580ff50825a a
2040 diff -r 000000000000 -r 8580ff50825a a
2041 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2041 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2042 +++ b/a Thu Jan 01 00:00:01 1970 +0000
2042 +++ b/a Thu Jan 01 00:00:01 1970 +0000
2043 @@ -0,0 +1,1 @@
2043 @@ -0,0 +1,1 @@
2044 +a
2044 +a
2045
2045
2046 displaying [PATCH 2 of 2] b ...
2046 displaying [PATCH 2 of 2] b ...
2047 Content-Type: text/plain; charset="us-ascii"
2047 Content-Type: text/plain; charset="us-ascii"
2048 MIME-Version: 1.0
2048 MIME-Version: 1.0
2049 Content-Transfer-Encoding: 7bit
2049 Content-Transfer-Encoding: 7bit
2050 Subject: [PATCH 2 of 2] b
2050 Subject: [PATCH 2 of 2] b
2051 X-Mercurial-Node: 97d72e5f12c7e84f85064aa72e5a297142c36ed9
2051 X-Mercurial-Node: 97d72e5f12c7e84f85064aa72e5a297142c36ed9
2052 X-Mercurial-Series-Index: 2
2052 X-Mercurial-Series-Index: 2
2053 X-Mercurial-Series-Total: 2
2053 X-Mercurial-Series-Total: 2
2054 Message-Id: <97d72e5f12c7e84f8506.62@*> (glob)
2054 Message-Id: <97d72e5f12c7e84f8506.62@*> (glob)
2055 X-Mercurial-Series-Id: <8580ff50825a50c8f716.61@*> (glob)
2055 X-Mercurial-Series-Id: <8580ff50825a50c8f716.61@*> (glob)
2056 In-Reply-To: <patchbomb.60@*> (glob)
2056 In-Reply-To: <patchbomb.60@*> (glob)
2057 References: <patchbomb.60@*> (glob)
2057 References: <patchbomb.60@*> (glob)
2058 User-Agent: Mercurial-patchbomb/* (glob)
2058 User-Agent: Mercurial-patchbomb/* (glob)
2059 Date: Thu, 01 Jan 1970 00:01:02 +0000
2059 Date: Thu, 01 Jan 1970 00:01:02 +0000
2060 From: quux
2060 From: quux
2061 To: foo
2061 To: foo
2062 Cc: bar
2062 Cc: bar
2063
2063
2064 # HG changeset patch
2064 # HG changeset patch
2065 # User test
2065 # User test
2066 # Date 2 0
2066 # Date 2 0
2067 # Thu Jan 01 00:00:02 1970 +0000
2067 # Thu Jan 01 00:00:02 1970 +0000
2068 # Node ID 97d72e5f12c7e84f85064aa72e5a297142c36ed9
2068 # Node ID 97d72e5f12c7e84f85064aa72e5a297142c36ed9
2069 # Parent 8580ff50825a50c8f716709acdf8de0deddcd6ab
2069 # Parent 8580ff50825a50c8f716709acdf8de0deddcd6ab
2070 b
2070 b
2071
2071
2072 diff -r 8580ff50825a -r 97d72e5f12c7 b
2072 diff -r 8580ff50825a -r 97d72e5f12c7 b
2073 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2073 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2074 +++ b/b Thu Jan 01 00:00:02 1970 +0000
2074 +++ b/b Thu Jan 01 00:00:02 1970 +0000
2075 @@ -0,0 +1,1 @@
2075 @@ -0,0 +1,1 @@
2076 +b
2076 +b
2077
2077
2078
2078
2079 test single flag for single patch (and no warning when not mailing dirty rev):
2079 test single flag for single patch (and no warning when not mailing dirty rev):
2080 $ hg up -qr1
2080 $ hg up -qr1
2081 $ echo dirt > a
2081 $ echo dirt > a
2082 $ hg email --date '1970-1-1 0:1' -n --flag fooFlag -f quux -t foo -c bar -s test \
2082 $ hg email --date '1970-1-1 0:1' -n --flag fooFlag -f quux -t foo -c bar -s test \
2083 > -r 2 | $FILTERBOUNDARY
2083 > -r 2 | $FILTERBOUNDARY
2084 this patch series consists of 1 patches.
2084 this patch series consists of 1 patches.
2085
2085
2086
2086
2087 displaying [PATCH fooFlag] test ...
2087 displaying [PATCH fooFlag] test ...
2088 Content-Type: text/plain; charset="us-ascii"
2088 Content-Type: text/plain; charset="us-ascii"
2089 MIME-Version: 1.0
2089 MIME-Version: 1.0
2090 Content-Transfer-Encoding: 7bit
2090 Content-Transfer-Encoding: 7bit
2091 Subject: [PATCH fooFlag] test
2091 Subject: [PATCH fooFlag] test
2092 X-Mercurial-Node: ff2c9fa2018b15fa74b33363bda9527323e2a99f
2092 X-Mercurial-Node: ff2c9fa2018b15fa74b33363bda9527323e2a99f
2093 X-Mercurial-Series-Index: 1
2093 X-Mercurial-Series-Index: 1
2094 X-Mercurial-Series-Total: 1
2094 X-Mercurial-Series-Total: 1
2095 Message-Id: <ff2c9fa2018b15fa74b3.60@*> (glob)
2095 Message-Id: <ff2c9fa2018b15fa74b3.60@*> (glob)
2096 X-Mercurial-Series-Id: <ff2c9fa2018b15fa74b3.60@*> (glob)
2096 X-Mercurial-Series-Id: <ff2c9fa2018b15fa74b3.60@*> (glob)
2097 User-Agent: Mercurial-patchbomb/* (glob)
2097 User-Agent: Mercurial-patchbomb/* (glob)
2098 Date: Thu, 01 Jan 1970 00:01:00 +0000
2098 Date: Thu, 01 Jan 1970 00:01:00 +0000
2099 From: quux
2099 From: quux
2100 To: foo
2100 To: foo
2101 Cc: bar
2101 Cc: bar
2102
2102
2103 # HG changeset patch
2103 # HG changeset patch
2104 # User test
2104 # User test
2105 # Date 3 0
2105 # Date 3 0
2106 # Thu Jan 01 00:00:03 1970 +0000
2106 # Thu Jan 01 00:00:03 1970 +0000
2107 # Node ID ff2c9fa2018b15fa74b33363bda9527323e2a99f
2107 # Node ID ff2c9fa2018b15fa74b33363bda9527323e2a99f
2108 # Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9
2108 # Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9
2109 c
2109 c
2110
2110
2111 diff -r 97d72e5f12c7 -r ff2c9fa2018b c
2111 diff -r 97d72e5f12c7 -r ff2c9fa2018b c
2112 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2112 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2113 +++ b/c Thu Jan 01 00:00:03 1970 +0000
2113 +++ b/c Thu Jan 01 00:00:03 1970 +0000
2114 @@ -0,0 +1,1 @@
2114 @@ -0,0 +1,1 @@
2115 +c
2115 +c
2116
2116
2117
2117
2118 test single flag for multiple patches (and warning when mailing dirty rev):
2118 test single flag for multiple patches (and warning when mailing dirty rev):
2119 $ hg email --date '1970-1-1 0:1' -n --flag fooFlag -f quux -t foo -c bar -s test \
2119 $ hg email --date '1970-1-1 0:1' -n --flag fooFlag -f quux -t foo -c bar -s test \
2120 > -r 0:1
2120 > -r 0:1
2121 warning: working directory has uncommitted changes
2121 warning: working directory has uncommitted changes
2122 this patch series consists of 2 patches.
2122 this patch series consists of 2 patches.
2123
2123
2124
2124
2125 Write the introductory message for the patch series.
2125 Write the introductory message for the patch series.
2126
2126
2127
2127
2128 displaying [PATCH 0 of 2 fooFlag] test ...
2128 displaying [PATCH 0 of 2 fooFlag] test ...
2129 Content-Type: text/plain; charset="us-ascii"
2129 Content-Type: text/plain; charset="us-ascii"
2130 MIME-Version: 1.0
2130 MIME-Version: 1.0
2131 Content-Transfer-Encoding: 7bit
2131 Content-Transfer-Encoding: 7bit
2132 Subject: [PATCH 0 of 2 fooFlag] test
2132 Subject: [PATCH 0 of 2 fooFlag] test
2133 Message-Id: <patchbomb.60@*> (glob)
2133 Message-Id: <patchbomb.60@*> (glob)
2134 User-Agent: Mercurial-patchbomb/* (glob)
2134 User-Agent: Mercurial-patchbomb/* (glob)
2135 Date: Thu, 01 Jan 1970 00:01:00 +0000
2135 Date: Thu, 01 Jan 1970 00:01:00 +0000
2136 From: quux
2136 From: quux
2137 To: foo
2137 To: foo
2138 Cc: bar
2138 Cc: bar
2139
2139
2140
2140
2141 displaying [PATCH 1 of 2 fooFlag] a ...
2141 displaying [PATCH 1 of 2 fooFlag] a ...
2142 Content-Type: text/plain; charset="us-ascii"
2142 Content-Type: text/plain; charset="us-ascii"
2143 MIME-Version: 1.0
2143 MIME-Version: 1.0
2144 Content-Transfer-Encoding: 7bit
2144 Content-Transfer-Encoding: 7bit
2145 Subject: [PATCH 1 of 2 fooFlag] a
2145 Subject: [PATCH 1 of 2 fooFlag] a
2146 X-Mercurial-Node: 8580ff50825a50c8f716709acdf8de0deddcd6ab
2146 X-Mercurial-Node: 8580ff50825a50c8f716709acdf8de0deddcd6ab
2147 X-Mercurial-Series-Index: 1
2147 X-Mercurial-Series-Index: 1
2148 X-Mercurial-Series-Total: 2
2148 X-Mercurial-Series-Total: 2
2149 Message-Id: <8580ff50825a50c8f716.61@*> (glob)
2149 Message-Id: <8580ff50825a50c8f716.61@*> (glob)
2150 X-Mercurial-Series-Id: <8580ff50825a50c8f716.61@*> (glob)
2150 X-Mercurial-Series-Id: <8580ff50825a50c8f716.61@*> (glob)
2151 In-Reply-To: <patchbomb.60@*> (glob)
2151 In-Reply-To: <patchbomb.60@*> (glob)
2152 References: <patchbomb.60@*> (glob)
2152 References: <patchbomb.60@*> (glob)
2153 User-Agent: Mercurial-patchbomb/* (glob)
2153 User-Agent: Mercurial-patchbomb/* (glob)
2154 Date: Thu, 01 Jan 1970 00:01:01 +0000
2154 Date: Thu, 01 Jan 1970 00:01:01 +0000
2155 From: quux
2155 From: quux
2156 To: foo
2156 To: foo
2157 Cc: bar
2157 Cc: bar
2158
2158
2159 # HG changeset patch
2159 # HG changeset patch
2160 # User test
2160 # User test
2161 # Date 1 0
2161 # Date 1 0
2162 # Thu Jan 01 00:00:01 1970 +0000
2162 # Thu Jan 01 00:00:01 1970 +0000
2163 # Node ID 8580ff50825a50c8f716709acdf8de0deddcd6ab
2163 # Node ID 8580ff50825a50c8f716709acdf8de0deddcd6ab
2164 # Parent 0000000000000000000000000000000000000000
2164 # Parent 0000000000000000000000000000000000000000
2165 a
2165 a
2166
2166
2167 diff -r 000000000000 -r 8580ff50825a a
2167 diff -r 000000000000 -r 8580ff50825a a
2168 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2168 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2169 +++ b/a Thu Jan 01 00:00:01 1970 +0000
2169 +++ b/a Thu Jan 01 00:00:01 1970 +0000
2170 @@ -0,0 +1,1 @@
2170 @@ -0,0 +1,1 @@
2171 +a
2171 +a
2172
2172
2173 displaying [PATCH 2 of 2 fooFlag] b ...
2173 displaying [PATCH 2 of 2 fooFlag] b ...
2174 Content-Type: text/plain; charset="us-ascii"
2174 Content-Type: text/plain; charset="us-ascii"
2175 MIME-Version: 1.0
2175 MIME-Version: 1.0
2176 Content-Transfer-Encoding: 7bit
2176 Content-Transfer-Encoding: 7bit
2177 Subject: [PATCH 2 of 2 fooFlag] b
2177 Subject: [PATCH 2 of 2 fooFlag] b
2178 X-Mercurial-Node: 97d72e5f12c7e84f85064aa72e5a297142c36ed9
2178 X-Mercurial-Node: 97d72e5f12c7e84f85064aa72e5a297142c36ed9
2179 X-Mercurial-Series-Index: 2
2179 X-Mercurial-Series-Index: 2
2180 X-Mercurial-Series-Total: 2
2180 X-Mercurial-Series-Total: 2
2181 Message-Id: <97d72e5f12c7e84f8506.62@*> (glob)
2181 Message-Id: <97d72e5f12c7e84f8506.62@*> (glob)
2182 X-Mercurial-Series-Id: <8580ff50825a50c8f716.61@*> (glob)
2182 X-Mercurial-Series-Id: <8580ff50825a50c8f716.61@*> (glob)
2183 In-Reply-To: <patchbomb.60@*> (glob)
2183 In-Reply-To: <patchbomb.60@*> (glob)
2184 References: <patchbomb.60@*> (glob)
2184 References: <patchbomb.60@*> (glob)
2185 User-Agent: Mercurial-patchbomb/* (glob)
2185 User-Agent: Mercurial-patchbomb/* (glob)
2186 Date: Thu, 01 Jan 1970 00:01:02 +0000
2186 Date: Thu, 01 Jan 1970 00:01:02 +0000
2187 From: quux
2187 From: quux
2188 To: foo
2188 To: foo
2189 Cc: bar
2189 Cc: bar
2190
2190
2191 # HG changeset patch
2191 # HG changeset patch
2192 # User test
2192 # User test
2193 # Date 2 0
2193 # Date 2 0
2194 # Thu Jan 01 00:00:02 1970 +0000
2194 # Thu Jan 01 00:00:02 1970 +0000
2195 # Node ID 97d72e5f12c7e84f85064aa72e5a297142c36ed9
2195 # Node ID 97d72e5f12c7e84f85064aa72e5a297142c36ed9
2196 # Parent 8580ff50825a50c8f716709acdf8de0deddcd6ab
2196 # Parent 8580ff50825a50c8f716709acdf8de0deddcd6ab
2197 b
2197 b
2198
2198
2199 diff -r 8580ff50825a -r 97d72e5f12c7 b
2199 diff -r 8580ff50825a -r 97d72e5f12c7 b
2200 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2200 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2201 +++ b/b Thu Jan 01 00:00:02 1970 +0000
2201 +++ b/b Thu Jan 01 00:00:02 1970 +0000
2202 @@ -0,0 +1,1 @@
2202 @@ -0,0 +1,1 @@
2203 +b
2203 +b
2204
2204
2205 $ hg revert --no-b a
2205 $ hg revert --no-b a
2206 $ hg up -q
2206 $ hg up -q
2207
2207
2208 test multiple flags for single patch:
2208 test multiple flags for single patch:
2209 $ hg email --date '1970-1-1 0:1' -n --flag fooFlag --flag barFlag -f quux -t foo \
2209 $ hg email --date '1970-1-1 0:1' -n --flag fooFlag --flag barFlag -f quux -t foo \
2210 > -c bar -s test -r 2
2210 > -c bar -s test -r 2
2211 this patch series consists of 1 patches.
2211 this patch series consists of 1 patches.
2212
2212
2213
2213
2214 displaying [PATCH fooFlag barFlag] test ...
2214 displaying [PATCH fooFlag barFlag] test ...
2215 Content-Type: text/plain; charset="us-ascii"
2215 Content-Type: text/plain; charset="us-ascii"
2216 MIME-Version: 1.0
2216 MIME-Version: 1.0
2217 Content-Transfer-Encoding: 7bit
2217 Content-Transfer-Encoding: 7bit
2218 Subject: [PATCH fooFlag barFlag] test
2218 Subject: [PATCH fooFlag barFlag] test
2219 X-Mercurial-Node: ff2c9fa2018b15fa74b33363bda9527323e2a99f
2219 X-Mercurial-Node: ff2c9fa2018b15fa74b33363bda9527323e2a99f
2220 X-Mercurial-Series-Index: 1
2220 X-Mercurial-Series-Index: 1
2221 X-Mercurial-Series-Total: 1
2221 X-Mercurial-Series-Total: 1
2222 Message-Id: <ff2c9fa2018b15fa74b3.60@*> (glob)
2222 Message-Id: <ff2c9fa2018b15fa74b3.60@*> (glob)
2223 X-Mercurial-Series-Id: <ff2c9fa2018b15fa74b3.60@*> (glob)
2223 X-Mercurial-Series-Id: <ff2c9fa2018b15fa74b3.60@*> (glob)
2224 User-Agent: Mercurial-patchbomb/* (glob)
2224 User-Agent: Mercurial-patchbomb/* (glob)
2225 Date: Thu, 01 Jan 1970 00:01:00 +0000
2225 Date: Thu, 01 Jan 1970 00:01:00 +0000
2226 From: quux
2226 From: quux
2227 To: foo
2227 To: foo
2228 Cc: bar
2228 Cc: bar
2229
2229
2230 # HG changeset patch
2230 # HG changeset patch
2231 # User test
2231 # User test
2232 # Date 3 0
2232 # Date 3 0
2233 # Thu Jan 01 00:00:03 1970 +0000
2233 # Thu Jan 01 00:00:03 1970 +0000
2234 # Node ID ff2c9fa2018b15fa74b33363bda9527323e2a99f
2234 # Node ID ff2c9fa2018b15fa74b33363bda9527323e2a99f
2235 # Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9
2235 # Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9
2236 c
2236 c
2237
2237
2238 diff -r 97d72e5f12c7 -r ff2c9fa2018b c
2238 diff -r 97d72e5f12c7 -r ff2c9fa2018b c
2239 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2239 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2240 +++ b/c Thu Jan 01 00:00:03 1970 +0000
2240 +++ b/c Thu Jan 01 00:00:03 1970 +0000
2241 @@ -0,0 +1,1 @@
2241 @@ -0,0 +1,1 @@
2242 +c
2242 +c
2243
2243
2244
2244
2245 test multiple flags for multiple patches:
2245 test multiple flags for multiple patches:
2246 $ hg email --date '1970-1-1 0:1' -n --flag fooFlag --flag barFlag -f quux -t foo \
2246 $ hg email --date '1970-1-1 0:1' -n --flag fooFlag --flag barFlag -f quux -t foo \
2247 > -c bar -s test -r 0:1
2247 > -c bar -s test -r 0:1
2248 this patch series consists of 2 patches.
2248 this patch series consists of 2 patches.
2249
2249
2250
2250
2251 Write the introductory message for the patch series.
2251 Write the introductory message for the patch series.
2252
2252
2253
2253
2254 displaying [PATCH 0 of 2 fooFlag barFlag] test ...
2254 displaying [PATCH 0 of 2 fooFlag barFlag] test ...
2255 Content-Type: text/plain; charset="us-ascii"
2255 Content-Type: text/plain; charset="us-ascii"
2256 MIME-Version: 1.0
2256 MIME-Version: 1.0
2257 Content-Transfer-Encoding: 7bit
2257 Content-Transfer-Encoding: 7bit
2258 Subject: [PATCH 0 of 2 fooFlag barFlag] test
2258 Subject: [PATCH 0 of 2 fooFlag barFlag] test
2259 Message-Id: <patchbomb.60@*> (glob)
2259 Message-Id: <patchbomb.60@*> (glob)
2260 User-Agent: Mercurial-patchbomb/* (glob)
2260 User-Agent: Mercurial-patchbomb/* (glob)
2261 Date: Thu, 01 Jan 1970 00:01:00 +0000
2261 Date: Thu, 01 Jan 1970 00:01:00 +0000
2262 From: quux
2262 From: quux
2263 To: foo
2263 To: foo
2264 Cc: bar
2264 Cc: bar
2265
2265
2266
2266
2267 displaying [PATCH 1 of 2 fooFlag barFlag] a ...
2267 displaying [PATCH 1 of 2 fooFlag barFlag] a ...
2268 Content-Type: text/plain; charset="us-ascii"
2268 Content-Type: text/plain; charset="us-ascii"
2269 MIME-Version: 1.0
2269 MIME-Version: 1.0
2270 Content-Transfer-Encoding: 7bit
2270 Content-Transfer-Encoding: 7bit
2271 Subject: [PATCH 1 of 2 fooFlag barFlag] a
2271 Subject: [PATCH 1 of 2 fooFlag barFlag] a
2272 X-Mercurial-Node: 8580ff50825a50c8f716709acdf8de0deddcd6ab
2272 X-Mercurial-Node: 8580ff50825a50c8f716709acdf8de0deddcd6ab
2273 X-Mercurial-Series-Index: 1
2273 X-Mercurial-Series-Index: 1
2274 X-Mercurial-Series-Total: 2
2274 X-Mercurial-Series-Total: 2
2275 Message-Id: <8580ff50825a50c8f716.61@*> (glob)
2275 Message-Id: <8580ff50825a50c8f716.61@*> (glob)
2276 X-Mercurial-Series-Id: <8580ff50825a50c8f716.61@*> (glob)
2276 X-Mercurial-Series-Id: <8580ff50825a50c8f716.61@*> (glob)
2277 In-Reply-To: <patchbomb.60@*> (glob)
2277 In-Reply-To: <patchbomb.60@*> (glob)
2278 References: <patchbomb.60@*> (glob)
2278 References: <patchbomb.60@*> (glob)
2279 User-Agent: Mercurial-patchbomb/* (glob)
2279 User-Agent: Mercurial-patchbomb/* (glob)
2280 Date: Thu, 01 Jan 1970 00:01:01 +0000
2280 Date: Thu, 01 Jan 1970 00:01:01 +0000
2281 From: quux
2281 From: quux
2282 To: foo
2282 To: foo
2283 Cc: bar
2283 Cc: bar
2284
2284
2285 # HG changeset patch
2285 # HG changeset patch
2286 # User test
2286 # User test
2287 # Date 1 0
2287 # Date 1 0
2288 # Thu Jan 01 00:00:01 1970 +0000
2288 # Thu Jan 01 00:00:01 1970 +0000
2289 # Node ID 8580ff50825a50c8f716709acdf8de0deddcd6ab
2289 # Node ID 8580ff50825a50c8f716709acdf8de0deddcd6ab
2290 # Parent 0000000000000000000000000000000000000000
2290 # Parent 0000000000000000000000000000000000000000
2291 a
2291 a
2292
2292
2293 diff -r 000000000000 -r 8580ff50825a a
2293 diff -r 000000000000 -r 8580ff50825a a
2294 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2294 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2295 +++ b/a Thu Jan 01 00:00:01 1970 +0000
2295 +++ b/a Thu Jan 01 00:00:01 1970 +0000
2296 @@ -0,0 +1,1 @@
2296 @@ -0,0 +1,1 @@
2297 +a
2297 +a
2298
2298
2299 displaying [PATCH 2 of 2 fooFlag barFlag] b ...
2299 displaying [PATCH 2 of 2 fooFlag barFlag] b ...
2300 Content-Type: text/plain; charset="us-ascii"
2300 Content-Type: text/plain; charset="us-ascii"
2301 MIME-Version: 1.0
2301 MIME-Version: 1.0
2302 Content-Transfer-Encoding: 7bit
2302 Content-Transfer-Encoding: 7bit
2303 Subject: [PATCH 2 of 2 fooFlag barFlag] b
2303 Subject: [PATCH 2 of 2 fooFlag barFlag] b
2304 X-Mercurial-Node: 97d72e5f12c7e84f85064aa72e5a297142c36ed9
2304 X-Mercurial-Node: 97d72e5f12c7e84f85064aa72e5a297142c36ed9
2305 X-Mercurial-Series-Index: 2
2305 X-Mercurial-Series-Index: 2
2306 X-Mercurial-Series-Total: 2
2306 X-Mercurial-Series-Total: 2
2307 Message-Id: <97d72e5f12c7e84f8506.62@*> (glob)
2307 Message-Id: <97d72e5f12c7e84f8506.62@*> (glob)
2308 X-Mercurial-Series-Id: <8580ff50825a50c8f716.61@*> (glob)
2308 X-Mercurial-Series-Id: <8580ff50825a50c8f716.61@*> (glob)
2309 In-Reply-To: <patchbomb.60@*> (glob)
2309 In-Reply-To: <patchbomb.60@*> (glob)
2310 References: <patchbomb.60@*> (glob)
2310 References: <patchbomb.60@*> (glob)
2311 User-Agent: Mercurial-patchbomb/* (glob)
2311 User-Agent: Mercurial-patchbomb/* (glob)
2312 Date: Thu, 01 Jan 1970 00:01:02 +0000
2312 Date: Thu, 01 Jan 1970 00:01:02 +0000
2313 From: quux
2313 From: quux
2314 To: foo
2314 To: foo
2315 Cc: bar
2315 Cc: bar
2316
2316
2317 # HG changeset patch
2317 # HG changeset patch
2318 # User test
2318 # User test
2319 # Date 2 0
2319 # Date 2 0
2320 # Thu Jan 01 00:00:02 1970 +0000
2320 # Thu Jan 01 00:00:02 1970 +0000
2321 # Node ID 97d72e5f12c7e84f85064aa72e5a297142c36ed9
2321 # Node ID 97d72e5f12c7e84f85064aa72e5a297142c36ed9
2322 # Parent 8580ff50825a50c8f716709acdf8de0deddcd6ab
2322 # Parent 8580ff50825a50c8f716709acdf8de0deddcd6ab
2323 b
2323 b
2324
2324
2325 diff -r 8580ff50825a -r 97d72e5f12c7 b
2325 diff -r 8580ff50825a -r 97d72e5f12c7 b
2326 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2326 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2327 +++ b/b Thu Jan 01 00:00:02 1970 +0000
2327 +++ b/b Thu Jan 01 00:00:02 1970 +0000
2328 @@ -0,0 +1,1 @@
2328 @@ -0,0 +1,1 @@
2329 +b
2329 +b
2330
2330
2331
2331
2332 test multi-address parsing:
2332 test multi-address parsing:
2333 $ hg email --date '1980-1-1 0:1' -m tmp.mbox -f quux -t 'spam<spam><eggs>' \
2333 $ hg email --date '1980-1-1 0:1' -m tmp.mbox -f quux -t 'spam<spam><eggs>' \
2334 > -t toast -c 'foo,bar@example.com' -c '"A, B <>" <a@example.com>' -s test -r 0 \
2334 > -t toast -c 'foo,bar@example.com' -c '"A, B <>" <a@example.com>' -s test -r 0 \
2335 > --config email.bcc='"Quux, A." <quux>'
2335 > --config email.bcc='"Quux, A." <quux>'
2336 this patch series consists of 1 patches.
2336 this patch series consists of 1 patches.
2337
2337
2338
2338
2339 sending [PATCH] test ...
2339 sending [PATCH] test ...
2340 $ cat < tmp.mbox
2340 $ cat < tmp.mbox
2341 From quux ... ... .. ..:..:.. .... (re)
2341 From quux ... ... .. ..:..:.. .... (re)
2342 Content-Type: text/plain; charset="us-ascii"
2342 Content-Type: text/plain; charset="us-ascii"
2343 MIME-Version: 1.0
2343 MIME-Version: 1.0
2344 Content-Transfer-Encoding: 7bit
2344 Content-Transfer-Encoding: 7bit
2345 Subject: [PATCH] test
2345 Subject: [PATCH] test
2346 X-Mercurial-Node: 8580ff50825a50c8f716709acdf8de0deddcd6ab
2346 X-Mercurial-Node: 8580ff50825a50c8f716709acdf8de0deddcd6ab
2347 X-Mercurial-Series-Index: 1
2347 X-Mercurial-Series-Index: 1
2348 X-Mercurial-Series-Total: 1
2348 X-Mercurial-Series-Total: 1
2349 Message-Id: <8580ff50825a50c8f716.315532860@*> (glob)
2349 Message-Id: <8580ff50825a50c8f716.315532860@*> (glob)
2350 X-Mercurial-Series-Id: <8580ff50825a50c8f716.315532860@*> (glob)
2350 X-Mercurial-Series-Id: <8580ff50825a50c8f716.315532860@*> (glob)
2351 User-Agent: Mercurial-patchbomb/* (glob)
2351 User-Agent: Mercurial-patchbomb/* (glob)
2352 Date: Tue, 01 Jan 1980 00:01:00 +0000
2352 Date: Tue, 01 Jan 1980 00:01:00 +0000
2353 From: quux
2353 From: quux
2354 To: spam <spam>, eggs, toast
2354 To: spam <spam>, eggs, toast
2355 Cc: foo, bar@example.com, "A, B <>" <a@example.com>
2355 Cc: foo, bar@example.com, "A, B <>" <a@example.com>
2356 Bcc: "Quux, A." <quux>
2356 Bcc: "Quux, A." <quux>
2357
2357
2358 # HG changeset patch
2358 # HG changeset patch
2359 # User test
2359 # User test
2360 # Date 1 0
2360 # Date 1 0
2361 # Thu Jan 01 00:00:01 1970 +0000
2361 # Thu Jan 01 00:00:01 1970 +0000
2362 # Node ID 8580ff50825a50c8f716709acdf8de0deddcd6ab
2362 # Node ID 8580ff50825a50c8f716709acdf8de0deddcd6ab
2363 # Parent 0000000000000000000000000000000000000000
2363 # Parent 0000000000000000000000000000000000000000
2364 a
2364 a
2365
2365
2366 diff -r 000000000000 -r 8580ff50825a a
2366 diff -r 000000000000 -r 8580ff50825a a
2367 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2367 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2368 +++ b/a Thu Jan 01 00:00:01 1970 +0000
2368 +++ b/a Thu Jan 01 00:00:01 1970 +0000
2369 @@ -0,0 +1,1 @@
2369 @@ -0,0 +1,1 @@
2370 +a
2370 +a
2371
2371
2372
2372
2373
2373
2374 test multi-byte domain parsing:
2374 test multi-byte domain parsing:
2375 $ UUML=`$PYTHON -c 'import sys; sys.stdout.write("\374")'`
2375 $ UUML=`$PYTHON -c 'import sys; sys.stdout.write("\374")'`
2376 $ HGENCODING=iso-8859-1
2376 $ HGENCODING=iso-8859-1
2377 $ export HGENCODING
2377 $ export HGENCODING
2378 $ hg email --date '1980-1-1 0:1' -m tmp.mbox -f quux -t "bar@${UUML}nicode.com" -s test -r 0
2378 $ hg email --date '1980-1-1 0:1' -m tmp.mbox -f quux -t "bar@${UUML}nicode.com" -s test -r 0
2379 this patch series consists of 1 patches.
2379 this patch series consists of 1 patches.
2380
2380
2381 Cc:
2381 Cc:
2382
2382
2383 sending [PATCH] test ...
2383 sending [PATCH] test ...
2384
2384
2385 $ cat tmp.mbox
2385 $ cat tmp.mbox
2386 From quux ... ... .. ..:..:.. .... (re)
2386 From quux ... ... .. ..:..:.. .... (re)
2387 Content-Type: text/plain; charset="us-ascii"
2387 Content-Type: text/plain; charset="us-ascii"
2388 MIME-Version: 1.0
2388 MIME-Version: 1.0
2389 Content-Transfer-Encoding: 7bit
2389 Content-Transfer-Encoding: 7bit
2390 Subject: [PATCH] test
2390 Subject: [PATCH] test
2391 X-Mercurial-Node: 8580ff50825a50c8f716709acdf8de0deddcd6ab
2391 X-Mercurial-Node: 8580ff50825a50c8f716709acdf8de0deddcd6ab
2392 X-Mercurial-Series-Index: 1
2392 X-Mercurial-Series-Index: 1
2393 X-Mercurial-Series-Total: 1
2393 X-Mercurial-Series-Total: 1
2394 Message-Id: <8580ff50825a50c8f716.315532860@*> (glob)
2394 Message-Id: <8580ff50825a50c8f716.315532860@*> (glob)
2395 X-Mercurial-Series-Id: <8580ff50825a50c8f716.315532860@*> (glob)
2395 X-Mercurial-Series-Id: <8580ff50825a50c8f716.315532860@*> (glob)
2396 User-Agent: Mercurial-patchbomb/* (glob)
2396 User-Agent: Mercurial-patchbomb/* (glob)
2397 Date: Tue, 01 Jan 1980 00:01:00 +0000
2397 Date: Tue, 01 Jan 1980 00:01:00 +0000
2398 From: quux
2398 From: quux
2399 To: bar@xn--nicode-2ya.com
2399 To: bar@xn--nicode-2ya.com
2400
2400
2401 # HG changeset patch
2401 # HG changeset patch
2402 # User test
2402 # User test
2403 # Date 1 0
2403 # Date 1 0
2404 # Thu Jan 01 00:00:01 1970 +0000
2404 # Thu Jan 01 00:00:01 1970 +0000
2405 # Node ID 8580ff50825a50c8f716709acdf8de0deddcd6ab
2405 # Node ID 8580ff50825a50c8f716709acdf8de0deddcd6ab
2406 # Parent 0000000000000000000000000000000000000000
2406 # Parent 0000000000000000000000000000000000000000
2407 a
2407 a
2408
2408
2409 diff -r 000000000000 -r 8580ff50825a a
2409 diff -r 000000000000 -r 8580ff50825a a
2410 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2410 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2411 +++ b/a Thu Jan 01 00:00:01 1970 +0000
2411 +++ b/a Thu Jan 01 00:00:01 1970 +0000
2412 @@ -0,0 +1,1 @@
2412 @@ -0,0 +1,1 @@
2413 +a
2413 +a
2414
2414
2415
2415
2416
2416
2417 test outgoing:
2417 test outgoing:
2418 $ hg up 1
2418 $ hg up 1
2419 0 files updated, 0 files merged, 6 files removed, 0 files unresolved
2419 0 files updated, 0 files merged, 6 files removed, 0 files unresolved
2420
2420
2421 $ hg branch test
2421 $ hg branch test
2422 marked working directory as branch test
2422 marked working directory as branch test
2423 (branches are permanent and global, did you want a bookmark?)
2423 (branches are permanent and global, did you want a bookmark?)
2424
2424
2425 $ echo d > d
2425 $ echo d > d
2426 $ hg add d
2426 $ hg add d
2427 $ hg ci -md -d '4 0'
2427 $ hg ci -md -d '4 0'
2428 $ echo d >> d
2428 $ echo d >> d
2429 $ hg ci -mdd -d '5 0'
2429 $ hg ci -mdd -d '5 0'
2430 $ hg log -G --template "{rev}:{node|short} {desc|firstline}\n"
2430 $ hg log -G --template "{rev}:{node|short} {desc|firstline}\n"
2431 @ 10:3b6f1ec9dde9 dd
2431 @ 10:3b6f1ec9dde9 dd
2432 |
2432 |
2433 o 9:2f9fa9b998c5 d
2433 o 9:2f9fa9b998c5 d
2434 |
2434 |
2435 | o 8:7aead2484924 Added tag two, two.diff for changeset ff2c9fa2018b
2435 | o 8:7aead2484924 Added tag two, two.diff for changeset ff2c9fa2018b
2436 | |
2436 | |
2437 | o 7:045ca29b1ea2 Added tag one, one.patch for changeset 97d72e5f12c7
2437 | o 7:045ca29b1ea2 Added tag one, one.patch for changeset 97d72e5f12c7
2438 | |
2438 | |
2439 | o 6:5d5ef15dfe5e Added tag zero, zero.foo for changeset 8580ff50825a
2439 | o 6:5d5ef15dfe5e Added tag zero, zero.foo for changeset 8580ff50825a
2440 | |
2440 | |
2441 | o 5:240fb913fc1b isolatin 8-bit encoding
2441 | o 5:240fb913fc1b isolatin 8-bit encoding
2442 | |
2442 | |
2443 | o 4:a2ea8fc83dd8 long line
2443 | o 4:a2ea8fc83dd8 long line
2444 | |
2444 | |
2445 | o 3:909a00e13e9d utf-8 content
2445 | o 3:909a00e13e9d utf-8 content
2446 | |
2446 | |
2447 | o 2:ff2c9fa2018b c
2447 | o 2:ff2c9fa2018b c
2448 |/
2448 |/
2449 o 1:97d72e5f12c7 b
2449 o 1:97d72e5f12c7 b
2450 |
2450 |
2451 o 0:8580ff50825a a
2451 o 0:8580ff50825a a
2452
2452
2453 $ hg phase --force --secret -r 10
2453 $ hg phase --force --secret -r 10
2454 $ hg email --date '1980-1-1 0:1' -n -t foo -s test -o ../t -r 'rev(10) or rev(6)'
2454 $ hg email --date '1980-1-1 0:1' -n -t foo -s test -o ../t -r 'rev(10) or rev(6)'
2455 comparing with ../t
2455 comparing with ../t
2456 From [test]: test
2456 From [test]: test
2457 this patch series consists of 6 patches.
2457 this patch series consists of 6 patches.
2458
2458
2459
2459
2460 Write the introductory message for the patch series.
2460 Write the introductory message for the patch series.
2461
2461
2462 Cc:
2462 Cc:
2463
2463
2464 displaying [PATCH 0 of 6] test ...
2464 displaying [PATCH 0 of 6] test ...
2465 Content-Type: text/plain; charset="us-ascii"
2465 Content-Type: text/plain; charset="us-ascii"
2466 MIME-Version: 1.0
2466 MIME-Version: 1.0
2467 Content-Transfer-Encoding: 7bit
2467 Content-Transfer-Encoding: 7bit
2468 Subject: [PATCH 0 of 6] test
2468 Subject: [PATCH 0 of 6] test
2469 Message-Id: <patchbomb.315532860@*> (glob)
2469 Message-Id: <patchbomb.315532860@*> (glob)
2470 User-Agent: Mercurial-patchbomb/* (glob)
2470 User-Agent: Mercurial-patchbomb/* (glob)
2471 Date: Tue, 01 Jan 1980 00:01:00 +0000
2471 Date: Tue, 01 Jan 1980 00:01:00 +0000
2472 From: test
2472 From: test
2473 To: foo
2473 To: foo
2474
2474
2475
2475
2476 displaying [PATCH 1 of 6] c ...
2476 displaying [PATCH 1 of 6] c ...
2477 Content-Type: text/plain; charset="us-ascii"
2477 Content-Type: text/plain; charset="us-ascii"
2478 MIME-Version: 1.0
2478 MIME-Version: 1.0
2479 Content-Transfer-Encoding: 7bit
2479 Content-Transfer-Encoding: 7bit
2480 Subject: [PATCH 1 of 6] c
2480 Subject: [PATCH 1 of 6] c
2481 X-Mercurial-Node: ff2c9fa2018b15fa74b33363bda9527323e2a99f
2481 X-Mercurial-Node: ff2c9fa2018b15fa74b33363bda9527323e2a99f
2482 X-Mercurial-Series-Index: 1
2482 X-Mercurial-Series-Index: 1
2483 X-Mercurial-Series-Total: 6
2483 X-Mercurial-Series-Total: 6
2484 Message-Id: <ff2c9fa2018b15fa74b3.315532861@*> (glob)
2484 Message-Id: <ff2c9fa2018b15fa74b3.315532861@*> (glob)
2485 X-Mercurial-Series-Id: <ff2c9fa2018b15fa74b3.315532861@*> (glob)
2485 X-Mercurial-Series-Id: <ff2c9fa2018b15fa74b3.315532861@*> (glob)
2486 In-Reply-To: <patchbomb.315532860@*> (glob)
2486 In-Reply-To: <patchbomb.315532860@*> (glob)
2487 References: <patchbomb.315532860@*> (glob)
2487 References: <patchbomb.315532860@*> (glob)
2488 User-Agent: Mercurial-patchbomb/* (glob)
2488 User-Agent: Mercurial-patchbomb/* (glob)
2489 Date: Tue, 01 Jan 1980 00:01:01 +0000
2489 Date: Tue, 01 Jan 1980 00:01:01 +0000
2490 From: test
2490 From: test
2491 To: foo
2491 To: foo
2492
2492
2493 # HG changeset patch
2493 # HG changeset patch
2494 # User test
2494 # User test
2495 # Date 3 0
2495 # Date 3 0
2496 # Thu Jan 01 00:00:03 1970 +0000
2496 # Thu Jan 01 00:00:03 1970 +0000
2497 # Node ID ff2c9fa2018b15fa74b33363bda9527323e2a99f
2497 # Node ID ff2c9fa2018b15fa74b33363bda9527323e2a99f
2498 # Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9
2498 # Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9
2499 c
2499 c
2500
2500
2501 diff -r 97d72e5f12c7 -r ff2c9fa2018b c
2501 diff -r 97d72e5f12c7 -r ff2c9fa2018b c
2502 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2502 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2503 +++ b/c Thu Jan 01 00:00:03 1970 +0000
2503 +++ b/c Thu Jan 01 00:00:03 1970 +0000
2504 @@ -0,0 +1,1 @@
2504 @@ -0,0 +1,1 @@
2505 +c
2505 +c
2506
2506
2507 displaying [PATCH 2 of 6] utf-8 content ...
2507 displaying [PATCH 2 of 6] utf-8 content ...
2508 Content-Type: text/plain; charset="us-ascii"
2508 Content-Type: text/plain; charset="us-ascii"
2509 MIME-Version: 1.0
2509 MIME-Version: 1.0
2510 Content-Transfer-Encoding: 8bit
2510 Content-Transfer-Encoding: 8bit
2511 Subject: [PATCH 2 of 6] utf-8 content
2511 Subject: [PATCH 2 of 6] utf-8 content
2512 X-Mercurial-Node: 909a00e13e9d78b575aeee23dddbada46d5a143f
2512 X-Mercurial-Node: 909a00e13e9d78b575aeee23dddbada46d5a143f
2513 X-Mercurial-Series-Index: 2
2513 X-Mercurial-Series-Index: 2
2514 X-Mercurial-Series-Total: 6
2514 X-Mercurial-Series-Total: 6
2515 Message-Id: <909a00e13e9d78b575ae.315532862@*> (glob)
2515 Message-Id: <909a00e13e9d78b575ae.315532862@*> (glob)
2516 X-Mercurial-Series-Id: <ff2c9fa2018b15fa74b3.315532861@*> (glob)
2516 X-Mercurial-Series-Id: <ff2c9fa2018b15fa74b3.315532861@*> (glob)
2517 In-Reply-To: <patchbomb.315532860@*> (glob)
2517 In-Reply-To: <patchbomb.315532860@*> (glob)
2518 References: <patchbomb.315532860@*> (glob)
2518 References: <patchbomb.315532860@*> (glob)
2519 User-Agent: Mercurial-patchbomb/* (glob)
2519 User-Agent: Mercurial-patchbomb/* (glob)
2520 Date: Tue, 01 Jan 1980 00:01:02 +0000
2520 Date: Tue, 01 Jan 1980 00:01:02 +0000
2521 From: test
2521 From: test
2522 To: foo
2522 To: foo
2523
2523
2524 # HG changeset patch
2524 # HG changeset patch
2525 # User test
2525 # User test
2526 # Date 4 0
2526 # Date 4 0
2527 # Thu Jan 01 00:00:04 1970 +0000
2527 # Thu Jan 01 00:00:04 1970 +0000
2528 # Node ID 909a00e13e9d78b575aeee23dddbada46d5a143f
2528 # Node ID 909a00e13e9d78b575aeee23dddbada46d5a143f
2529 # Parent ff2c9fa2018b15fa74b33363bda9527323e2a99f
2529 # Parent ff2c9fa2018b15fa74b33363bda9527323e2a99f
2530 utf-8 content
2530 utf-8 content
2531
2531
2532 diff -r ff2c9fa2018b -r 909a00e13e9d description
2532 diff -r ff2c9fa2018b -r 909a00e13e9d description
2533 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2533 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2534 +++ b/description Thu Jan 01 00:00:04 1970 +0000
2534 +++ b/description Thu Jan 01 00:00:04 1970 +0000
2535 @@ -0,0 +1,3 @@
2535 @@ -0,0 +1,3 @@
2536 +a multiline
2536 +a multiline
2537 +
2537 +
2538 +description
2538 +description
2539 diff -r ff2c9fa2018b -r 909a00e13e9d utf
2539 diff -r ff2c9fa2018b -r 909a00e13e9d utf
2540 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2540 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2541 +++ b/utf Thu Jan 01 00:00:04 1970 +0000
2541 +++ b/utf Thu Jan 01 00:00:04 1970 +0000
2542 @@ -0,0 +1,1 @@
2542 @@ -0,0 +1,1 @@
2543 +h\xc3\xb6mma! (esc)
2543 +h\xc3\xb6mma! (esc)
2544
2544
2545 displaying [PATCH 3 of 6] long line ...
2545 displaying [PATCH 3 of 6] long line ...
2546 Content-Type: text/plain; charset="us-ascii"
2546 Content-Type: text/plain; charset="us-ascii"
2547 MIME-Version: 1.0
2547 MIME-Version: 1.0
2548 Content-Transfer-Encoding: quoted-printable
2548 Content-Transfer-Encoding: quoted-printable
2549 Subject: [PATCH 3 of 6] long line
2549 Subject: [PATCH 3 of 6] long line
2550 X-Mercurial-Node: a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
2550 X-Mercurial-Node: a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
2551 X-Mercurial-Series-Index: 3
2551 X-Mercurial-Series-Index: 3
2552 X-Mercurial-Series-Total: 6
2552 X-Mercurial-Series-Total: 6
2553 Message-Id: <a2ea8fc83dd8b93cfd86.315532863@*> (glob)
2553 Message-Id: <a2ea8fc83dd8b93cfd86.315532863@*> (glob)
2554 X-Mercurial-Series-Id: <ff2c9fa2018b15fa74b3.315532861@*> (glob)
2554 X-Mercurial-Series-Id: <ff2c9fa2018b15fa74b3.315532861@*> (glob)
2555 In-Reply-To: <patchbomb.315532860@*> (glob)
2555 In-Reply-To: <patchbomb.315532860@*> (glob)
2556 References: <patchbomb.315532860@*> (glob)
2556 References: <patchbomb.315532860@*> (glob)
2557 User-Agent: Mercurial-patchbomb/* (glob)
2557 User-Agent: Mercurial-patchbomb/* (glob)
2558 Date: Tue, 01 Jan 1980 00:01:03 +0000
2558 Date: Tue, 01 Jan 1980 00:01:03 +0000
2559 From: test
2559 From: test
2560 To: foo
2560 To: foo
2561
2561
2562 # HG changeset patch
2562 # HG changeset patch
2563 # User test
2563 # User test
2564 # Date 4 0
2564 # Date 4 0
2565 # Thu Jan 01 00:00:04 1970 +0000
2565 # Thu Jan 01 00:00:04 1970 +0000
2566 # Node ID a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
2566 # Node ID a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
2567 # Parent 909a00e13e9d78b575aeee23dddbada46d5a143f
2567 # Parent 909a00e13e9d78b575aeee23dddbada46d5a143f
2568 long line
2568 long line
2569
2569
2570 diff -r 909a00e13e9d -r a2ea8fc83dd8 long
2570 diff -r 909a00e13e9d -r a2ea8fc83dd8 long
2571 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2571 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2572 +++ b/long Thu Jan 01 00:00:04 1970 +0000
2572 +++ b/long Thu Jan 01 00:00:04 1970 +0000
2573 @@ -0,0 +1,4 @@
2573 @@ -0,0 +1,4 @@
2574 +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
2574 +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
2575 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
2575 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
2576 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
2576 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
2577 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
2577 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
2578 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
2578 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
2579 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
2579 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
2580 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
2580 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
2581 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
2581 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
2582 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
2582 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
2583 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
2583 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
2584 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
2584 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
2585 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
2585 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
2586 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
2586 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
2587 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
2587 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
2588 +foo
2588 +foo
2589 +
2589 +
2590 +bar
2590 +bar
2591
2591
2592 displaying [PATCH 4 of 6] isolatin 8-bit encoding ...
2592 displaying [PATCH 4 of 6] isolatin 8-bit encoding ...
2593 Content-Type: text/plain; charset="us-ascii"
2593 Content-Type: text/plain; charset="us-ascii"
2594 MIME-Version: 1.0
2594 MIME-Version: 1.0
2595 Content-Transfer-Encoding: 8bit
2595 Content-Transfer-Encoding: 8bit
2596 Subject: [PATCH 4 of 6] isolatin 8-bit encoding
2596 Subject: [PATCH 4 of 6] isolatin 8-bit encoding
2597 X-Mercurial-Node: 240fb913fc1b7ff15ddb9f33e73d82bf5277c720
2597 X-Mercurial-Node: 240fb913fc1b7ff15ddb9f33e73d82bf5277c720
2598 X-Mercurial-Series-Index: 4
2598 X-Mercurial-Series-Index: 4
2599 X-Mercurial-Series-Total: 6
2599 X-Mercurial-Series-Total: 6
2600 Message-Id: <240fb913fc1b7ff15ddb.315532864@*> (glob)
2600 Message-Id: <240fb913fc1b7ff15ddb.315532864@*> (glob)
2601 X-Mercurial-Series-Id: <ff2c9fa2018b15fa74b3.315532861@*> (glob)
2601 X-Mercurial-Series-Id: <ff2c9fa2018b15fa74b3.315532861@*> (glob)
2602 In-Reply-To: <patchbomb.315532860@*> (glob)
2602 In-Reply-To: <patchbomb.315532860@*> (glob)
2603 References: <patchbomb.315532860@*> (glob)
2603 References: <patchbomb.315532860@*> (glob)
2604 User-Agent: Mercurial-patchbomb/* (glob)
2604 User-Agent: Mercurial-patchbomb/* (glob)
2605 Date: Tue, 01 Jan 1980 00:01:04 +0000
2605 Date: Tue, 01 Jan 1980 00:01:04 +0000
2606 From: test
2606 From: test
2607 To: foo
2607 To: foo
2608
2608
2609 # HG changeset patch
2609 # HG changeset patch
2610 # User test
2610 # User test
2611 # Date 5 0
2611 # Date 5 0
2612 # Thu Jan 01 00:00:05 1970 +0000
2612 # Thu Jan 01 00:00:05 1970 +0000
2613 # Node ID 240fb913fc1b7ff15ddb9f33e73d82bf5277c720
2613 # Node ID 240fb913fc1b7ff15ddb9f33e73d82bf5277c720
2614 # Parent a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
2614 # Parent a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
2615 isolatin 8-bit encoding
2615 isolatin 8-bit encoding
2616
2616
2617 diff -r a2ea8fc83dd8 -r 240fb913fc1b isolatin
2617 diff -r a2ea8fc83dd8 -r 240fb913fc1b isolatin
2618 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2618 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2619 +++ b/isolatin Thu Jan 01 00:00:05 1970 +0000
2619 +++ b/isolatin Thu Jan 01 00:00:05 1970 +0000
2620 @@ -0,0 +1,1 @@
2620 @@ -0,0 +1,1 @@
2621 +h\xf6mma! (esc)
2621 +h\xf6mma! (esc)
2622
2622
2623 displaying [PATCH 5 of 6] Added tag zero, zero.foo for changeset 8580ff50825a ...
2623 displaying [PATCH 5 of 6] Added tag zero, zero.foo for changeset 8580ff50825a ...
2624 Content-Type: text/plain; charset="us-ascii"
2624 Content-Type: text/plain; charset="us-ascii"
2625 MIME-Version: 1.0
2625 MIME-Version: 1.0
2626 Content-Transfer-Encoding: 7bit
2626 Content-Transfer-Encoding: 7bit
2627 Subject: [PATCH 5 of 6] Added tag zero, zero.foo for changeset 8580ff50825a
2627 Subject: [PATCH 5 of 6] Added tag zero, zero.foo for changeset 8580ff50825a
2628 X-Mercurial-Node: 5d5ef15dfe5e7bd3a4ee154b5fff76c7945ec433
2628 X-Mercurial-Node: 5d5ef15dfe5e7bd3a4ee154b5fff76c7945ec433
2629 X-Mercurial-Series-Index: 5
2629 X-Mercurial-Series-Index: 5
2630 X-Mercurial-Series-Total: 6
2630 X-Mercurial-Series-Total: 6
2631 Message-Id: <5d5ef15dfe5e7bd3a4ee.315532865@*> (glob)
2631 Message-Id: <5d5ef15dfe5e7bd3a4ee.315532865@*> (glob)
2632 X-Mercurial-Series-Id: <ff2c9fa2018b15fa74b3.315532861@*> (glob)
2632 X-Mercurial-Series-Id: <ff2c9fa2018b15fa74b3.315532861@*> (glob)
2633 In-Reply-To: <patchbomb.315532860@*> (glob)
2633 In-Reply-To: <patchbomb.315532860@*> (glob)
2634 References: <patchbomb.315532860@*> (glob)
2634 References: <patchbomb.315532860@*> (glob)
2635 User-Agent: Mercurial-patchbomb/* (glob)
2635 User-Agent: Mercurial-patchbomb/* (glob)
2636 Date: Tue, 01 Jan 1980 00:01:05 +0000
2636 Date: Tue, 01 Jan 1980 00:01:05 +0000
2637 From: test
2637 From: test
2638 To: foo
2638 To: foo
2639
2639
2640 # HG changeset patch
2640 # HG changeset patch
2641 # User test
2641 # User test
2642 # Date 0 0
2642 # Date 0 0
2643 # Thu Jan 01 00:00:00 1970 +0000
2643 # Thu Jan 01 00:00:00 1970 +0000
2644 # Node ID 5d5ef15dfe5e7bd3a4ee154b5fff76c7945ec433
2644 # Node ID 5d5ef15dfe5e7bd3a4ee154b5fff76c7945ec433
2645 # Parent 240fb913fc1b7ff15ddb9f33e73d82bf5277c720
2645 # Parent 240fb913fc1b7ff15ddb9f33e73d82bf5277c720
2646 Added tag zero, zero.foo for changeset 8580ff50825a
2646 Added tag zero, zero.foo for changeset 8580ff50825a
2647
2647
2648 diff -r 240fb913fc1b -r 5d5ef15dfe5e .hgtags
2648 diff -r 240fb913fc1b -r 5d5ef15dfe5e .hgtags
2649 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2649 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2650 +++ b/.hgtags Thu Jan 01 00:00:00 1970 +0000
2650 +++ b/.hgtags Thu Jan 01 00:00:00 1970 +0000
2651 @@ -0,0 +1,2 @@
2651 @@ -0,0 +1,2 @@
2652 +8580ff50825a50c8f716709acdf8de0deddcd6ab zero
2652 +8580ff50825a50c8f716709acdf8de0deddcd6ab zero
2653 +8580ff50825a50c8f716709acdf8de0deddcd6ab zero.foo
2653 +8580ff50825a50c8f716709acdf8de0deddcd6ab zero.foo
2654
2654
2655 displaying [PATCH 6 of 6] d ...
2655 displaying [PATCH 6 of 6] d ...
2656 Content-Type: text/plain; charset="us-ascii"
2656 Content-Type: text/plain; charset="us-ascii"
2657 MIME-Version: 1.0
2657 MIME-Version: 1.0
2658 Content-Transfer-Encoding: 7bit
2658 Content-Transfer-Encoding: 7bit
2659 Subject: [PATCH 6 of 6] d
2659 Subject: [PATCH 6 of 6] d
2660 X-Mercurial-Node: 2f9fa9b998c5fe3ac2bd9a2b14bfcbeecbc7c268
2660 X-Mercurial-Node: 2f9fa9b998c5fe3ac2bd9a2b14bfcbeecbc7c268
2661 X-Mercurial-Series-Index: 6
2661 X-Mercurial-Series-Index: 6
2662 X-Mercurial-Series-Total: 6
2662 X-Mercurial-Series-Total: 6
2663 Message-Id: <2f9fa9b998c5fe3ac2bd.315532866@*> (glob)
2663 Message-Id: <2f9fa9b998c5fe3ac2bd.315532866@*> (glob)
2664 X-Mercurial-Series-Id: <ff2c9fa2018b15fa74b3.315532861@*> (glob)
2664 X-Mercurial-Series-Id: <ff2c9fa2018b15fa74b3.315532861@*> (glob)
2665 In-Reply-To: <patchbomb.315532860@*> (glob)
2665 In-Reply-To: <patchbomb.315532860@*> (glob)
2666 References: <patchbomb.315532860@*> (glob)
2666 References: <patchbomb.315532860@*> (glob)
2667 User-Agent: Mercurial-patchbomb/* (glob)
2667 User-Agent: Mercurial-patchbomb/* (glob)
2668 Date: Tue, 01 Jan 1980 00:01:06 +0000
2668 Date: Tue, 01 Jan 1980 00:01:06 +0000
2669 From: test
2669 From: test
2670 To: foo
2670 To: foo
2671
2671
2672 # HG changeset patch
2672 # HG changeset patch
2673 # User test
2673 # User test
2674 # Date 4 0
2674 # Date 4 0
2675 # Thu Jan 01 00:00:04 1970 +0000
2675 # Thu Jan 01 00:00:04 1970 +0000
2676 # Branch test
2676 # Branch test
2677 # Node ID 2f9fa9b998c5fe3ac2bd9a2b14bfcbeecbc7c268
2677 # Node ID 2f9fa9b998c5fe3ac2bd9a2b14bfcbeecbc7c268
2678 # Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9
2678 # Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9
2679 d
2679 d
2680
2680
2681 diff -r 97d72e5f12c7 -r 2f9fa9b998c5 d
2681 diff -r 97d72e5f12c7 -r 2f9fa9b998c5 d
2682 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2682 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2683 +++ b/d Thu Jan 01 00:00:04 1970 +0000
2683 +++ b/d Thu Jan 01 00:00:04 1970 +0000
2684 @@ -0,0 +1,1 @@
2684 @@ -0,0 +1,1 @@
2685 +d
2685 +d
2686
2686
2687
2687
2688 Don't prompt for a CC header.
2688 Don't prompt for a CC header.
2689
2689
2690 $ echo "[email]" >> $HGRCPATH
2690 $ echo "[email]" >> $HGRCPATH
2691 $ echo "cc=" >> $HGRCPATH
2691 $ echo "cc=" >> $HGRCPATH
2692
2692
2693 dest#branch URIs:
2693 dest#branch URIs:
2694 $ hg email --date '1980-1-1 0:1' -n -t foo -s test -o ../t#test
2694 $ hg email --date '1980-1-1 0:1' -n -t foo -s test -o ../t#test
2695 comparing with ../t
2695 comparing with ../t
2696 From [test]: test
2696 From [test]: test
2697 this patch series consists of 1 patches.
2697 this patch series consists of 1 patches.
2698
2698
2699
2699
2700 displaying [PATCH] test ...
2700 displaying [PATCH] test ...
2701 Content-Type: text/plain; charset="us-ascii"
2701 Content-Type: text/plain; charset="us-ascii"
2702 MIME-Version: 1.0
2702 MIME-Version: 1.0
2703 Content-Transfer-Encoding: 7bit
2703 Content-Transfer-Encoding: 7bit
2704 Subject: [PATCH] test
2704 Subject: [PATCH] test
2705 X-Mercurial-Node: 2f9fa9b998c5fe3ac2bd9a2b14bfcbeecbc7c268
2705 X-Mercurial-Node: 2f9fa9b998c5fe3ac2bd9a2b14bfcbeecbc7c268
2706 X-Mercurial-Series-Index: 1
2706 X-Mercurial-Series-Index: 1
2707 X-Mercurial-Series-Total: 1
2707 X-Mercurial-Series-Total: 1
2708 Message-Id: <2f9fa9b998c5fe3ac2bd.315532860@*> (glob)
2708 Message-Id: <2f9fa9b998c5fe3ac2bd.315532860@*> (glob)
2709 X-Mercurial-Series-Id: <2f9fa9b998c5fe3ac2bd.315532860@*> (glob)
2709 X-Mercurial-Series-Id: <2f9fa9b998c5fe3ac2bd.315532860@*> (glob)
2710 User-Agent: Mercurial-patchbomb/* (glob)
2710 User-Agent: Mercurial-patchbomb/* (glob)
2711 Date: Tue, 01 Jan 1980 00:01:00 +0000
2711 Date: Tue, 01 Jan 1980 00:01:00 +0000
2712 From: test
2712 From: test
2713 To: foo
2713 To: foo
2714
2714
2715 # HG changeset patch
2715 # HG changeset patch
2716 # User test
2716 # User test
2717 # Date 4 0
2717 # Date 4 0
2718 # Thu Jan 01 00:00:04 1970 +0000
2718 # Thu Jan 01 00:00:04 1970 +0000
2719 # Branch test
2719 # Branch test
2720 # Node ID 2f9fa9b998c5fe3ac2bd9a2b14bfcbeecbc7c268
2720 # Node ID 2f9fa9b998c5fe3ac2bd9a2b14bfcbeecbc7c268
2721 # Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9
2721 # Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9
2722 d
2722 d
2723
2723
2724 diff -r 97d72e5f12c7 -r 2f9fa9b998c5 d
2724 diff -r 97d72e5f12c7 -r 2f9fa9b998c5 d
2725 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2725 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2726 +++ b/d Thu Jan 01 00:00:04 1970 +0000
2726 +++ b/d Thu Jan 01 00:00:04 1970 +0000
2727 @@ -0,0 +1,1 @@
2727 @@ -0,0 +1,1 @@
2728 +d
2728 +d
2729
2729
2730
2730
2731 Set up a fake sendmail program
2731 Set up a fake sendmail program
2732
2732
2733 $ cat > pretendmail.sh << 'EOF'
2733 $ cat > pretendmail.sh << 'EOF'
2734 > #!/bin/sh
2734 > #!/bin/sh
2735 > echo "$@"
2735 > echo "$@"
2736 > cat
2736 > cat
2737 > EOF
2737 > EOF
2738 $ chmod +x pretendmail.sh
2738 $ chmod +x pretendmail.sh
2739
2739
2740 $ echo '[email]' >> $HGRCPATH
2740 $ echo '[email]' >> $HGRCPATH
2741 $ echo "method=`pwd`/pretendmail.sh" >> $HGRCPATH
2741 $ echo "method=`pwd`/pretendmail.sh" >> $HGRCPATH
2742
2742
2743 Test introduction configuration
2743 Test introduction configuration
2744 =================================
2744 =================================
2745
2745
2746 $ echo '[patchbomb]' >> $HGRCPATH
2746 $ echo '[patchbomb]' >> $HGRCPATH
2747
2747
2748 "auto" setting
2748 "auto" setting
2749 ----------------
2749 ----------------
2750
2750
2751 $ echo 'intro=auto' >> $HGRCPATH
2751 $ echo 'intro=auto' >> $HGRCPATH
2752
2752
2753 single rev
2753 single rev
2754
2754
2755 $ hg email --date '1980-1-1 0:1' -t foo -s test -r '10' | grep "Write the introductory message for the patch series."
2755 $ hg email --date '1980-1-1 0:1' -t foo -s test -r '10' | grep "Write the introductory message for the patch series."
2756 [1]
2756 [1]
2757
2757
2758 single rev + flag
2758 single rev + flag
2759
2759
2760 $ hg email --date '1980-1-1 0:1' -t foo -s test -r '10' --intro | grep "Write the introductory message for the patch series."
2760 $ hg email --date '1980-1-1 0:1' -t foo -s test -r '10' --intro | grep "Write the introductory message for the patch series."
2761 Write the introductory message for the patch series.
2761 Write the introductory message for the patch series.
2762
2762
2763
2763
2764 Multi rev
2764 Multi rev
2765
2765
2766 $ hg email --date '1980-1-1 0:1' -t foo -s test -r '9::' | grep "Write the introductory message for the patch series."
2766 $ hg email --date '1980-1-1 0:1' -t foo -s test -r '9::' | grep "Write the introductory message for the patch series."
2767 Write the introductory message for the patch series.
2767 Write the introductory message for the patch series.
2768
2768
2769 "never" setting
2769 "never" setting
2770 -----------------
2770 -----------------
2771
2771
2772 $ echo 'intro=never' >> $HGRCPATH
2772 $ echo 'intro=never' >> $HGRCPATH
2773
2773
2774 single rev
2774 single rev
2775
2775
2776 $ hg email --date '1980-1-1 0:1' -t foo -s test -r '10' | grep "Write the introductory message for the patch series."
2776 $ hg email --date '1980-1-1 0:1' -t foo -s test -r '10' | grep "Write the introductory message for the patch series."
2777 [1]
2777 [1]
2778
2778
2779 single rev + flag
2779 single rev + flag
2780
2780
2781 $ hg email --date '1980-1-1 0:1' -t foo -s test -r '10' --intro | grep "Write the introductory message for the patch series."
2781 $ hg email --date '1980-1-1 0:1' -t foo -s test -r '10' --intro | grep "Write the introductory message for the patch series."
2782 Write the introductory message for the patch series.
2782 Write the introductory message for the patch series.
2783
2783
2784
2784
2785 Multi rev
2785 Multi rev
2786
2786
2787 $ hg email --date '1980-1-1 0:1' -t foo -s test -r '9::' | grep "Write the introductory message for the patch series."
2787 $ hg email --date '1980-1-1 0:1' -t foo -s test -r '9::' | grep "Write the introductory message for the patch series."
2788 [1]
2788 [1]
2789
2789
2790 Multi rev + flag
2790 Multi rev + flag
2791
2791
2792 $ hg email --date '1980-1-1 0:1' -t foo -s test -r '9::' --intro | grep "Write the introductory message for the patch series."
2792 $ hg email --date '1980-1-1 0:1' -t foo -s test -r '9::' --intro | grep "Write the introductory message for the patch series."
2793 Write the introductory message for the patch series.
2793 Write the introductory message for the patch series.
2794
2794
2795 "always" setting
2795 "always" setting
2796 -----------------
2796 -----------------
2797
2797
2798 $ echo 'intro=always' >> $HGRCPATH
2798 $ echo 'intro=always' >> $HGRCPATH
2799
2799
2800 single rev
2800 single rev
2801
2801
2802 $ hg email --date '1980-1-1 0:1' -t foo -s test -r '10' | grep "Write the introductory message for the patch series."
2802 $ hg email --date '1980-1-1 0:1' -t foo -s test -r '10' | grep "Write the introductory message for the patch series."
2803 Write the introductory message for the patch series.
2803 Write the introductory message for the patch series.
2804
2804
2805 single rev + flag
2805 single rev + flag
2806
2806
2807 $ hg email --date '1980-1-1 0:1' -t foo -s test -r '10' --intro | grep "Write the introductory message for the patch series."
2807 $ hg email --date '1980-1-1 0:1' -t foo -s test -r '10' --intro | grep "Write the introductory message for the patch series."
2808 Write the introductory message for the patch series.
2808 Write the introductory message for the patch series.
2809
2809
2810
2810
2811 Multi rev
2811 Multi rev
2812
2812
2813 $ hg email --date '1980-1-1 0:1' -t foo -s test -r '9::' | grep "Write the introductory message for the patch series."
2813 $ hg email --date '1980-1-1 0:1' -t foo -s test -r '9::' | grep "Write the introductory message for the patch series."
2814 Write the introductory message for the patch series.
2814 Write the introductory message for the patch series.
2815
2815
2816 Multi rev + flag
2816 Multi rev + flag
2817
2817
2818 $ hg email --date '1980-1-1 0:1' -t foo -s test -r '9::' --intro | grep "Write the introductory message for the patch series."
2818 $ hg email --date '1980-1-1 0:1' -t foo -s test -r '9::' --intro | grep "Write the introductory message for the patch series."
2819 Write the introductory message for the patch series.
2819 Write the introductory message for the patch series.
2820
2820
2821 bad value setting
2821 bad value setting
2822 -----------------
2822 -----------------
2823
2823
2824 $ echo 'intro=mpmwearaclownnose' >> $HGRCPATH
2824 $ echo 'intro=mpmwearaclownnose' >> $HGRCPATH
2825
2825
2826 single rev
2826 single rev
2827
2827
2828 $ hg email --date '1980-1-1 0:1' -v -t foo -s test -r '10'
2828 $ hg email --date '1980-1-1 0:1' -v -t foo -s test -r '10'
2829 From [test]: test
2829 From [test]: test
2830 this patch series consists of 1 patches.
2830 this patch series consists of 1 patches.
2831
2831
2832 warning: invalid patchbomb.intro value "mpmwearaclownnose"
2832 warning: invalid patchbomb.intro value "mpmwearaclownnose"
2833 (should be one of always, never, auto)
2833 (should be one of always, never, auto)
2834 -f test foo
2834 -f test foo
2835 Content-Type: text/plain; charset="us-ascii"
2835 Content-Type: text/plain; charset="us-ascii"
2836 MIME-Version: 1.0
2836 MIME-Version: 1.0
2837 Content-Transfer-Encoding: 7bit
2837 Content-Transfer-Encoding: 7bit
2838 Subject: [PATCH] test
2838 Subject: [PATCH] test
2839 X-Mercurial-Node: 3b6f1ec9dde933a40a115a7990f8b320477231af
2839 X-Mercurial-Node: 3b6f1ec9dde933a40a115a7990f8b320477231af
2840 X-Mercurial-Series-Index: 1
2840 X-Mercurial-Series-Index: 1
2841 X-Mercurial-Series-Total: 1
2841 X-Mercurial-Series-Total: 1
2842 Message-Id: <3b6f1ec9dde933a40a11*> (glob)
2842 Message-Id: <3b6f1ec9dde933a40a11*> (glob)
2843 X-Mercurial-Series-Id: <3b6f1ec9dde933a40a11.*> (glob)
2843 X-Mercurial-Series-Id: <3b6f1ec9dde933a40a11.*> (glob)
2844 User-Agent: Mercurial-patchbomb/* (glob)
2844 User-Agent: Mercurial-patchbomb/* (glob)
2845 Date: Tue, 01 Jan 1980 00:01:00 +0000
2845 Date: Tue, 01 Jan 1980 00:01:00 +0000
2846 From: test
2846 From: test
2847 To: foo
2847 To: foo
2848
2848
2849 # HG changeset patch
2849 # HG changeset patch
2850 # User test
2850 # User test
2851 # Date 5 0
2851 # Date 5 0
2852 # Thu Jan 01 00:00:05 1970 +0000
2852 # Thu Jan 01 00:00:05 1970 +0000
2853 # Branch test
2853 # Branch test
2854 # Node ID 3b6f1ec9dde933a40a115a7990f8b320477231af
2854 # Node ID 3b6f1ec9dde933a40a115a7990f8b320477231af
2855 # Parent 2f9fa9b998c5fe3ac2bd9a2b14bfcbeecbc7c268
2855 # Parent 2f9fa9b998c5fe3ac2bd9a2b14bfcbeecbc7c268
2856 dd
2856 dd
2857
2857
2858 diff -r 2f9fa9b998c5 -r 3b6f1ec9dde9 d
2858 diff -r 2f9fa9b998c5 -r 3b6f1ec9dde9 d
2859 --- a/d Thu Jan 01 00:00:04 1970 +0000
2859 --- a/d Thu Jan 01 00:00:04 1970 +0000
2860 +++ b/d Thu Jan 01 00:00:05 1970 +0000
2860 +++ b/d Thu Jan 01 00:00:05 1970 +0000
2861 @@ -1,1 +1,2 @@
2861 @@ -1,1 +1,2 @@
2862 d
2862 d
2863 +d
2863 +d
2864
2864
2865 sending [PATCH] test ...
2865 sending [PATCH] test ...
2866 sending mail: $TESTTMP/t2/pretendmail.sh -f test foo
2866 sending mail: $TESTTMP/t2/pretendmail.sh -f test foo
2867
2867
2868 Test pull url header
2868 Test pull url header
2869 =================================
2869 =================================
2870
2870
2871 basic version
2871 basic version
2872
2872
2873 $ echo 'intro=auto' >> $HGRCPATH
2873 $ echo 'intro=auto' >> $HGRCPATH
2874 $ echo "publicurl=$TESTTMP/t2" >> $HGRCPATH
2874 $ echo "publicurl=$TESTTMP/t2" >> $HGRCPATH
2875 $ hg email --date '1980-1-1 0:1' -t foo -s test -r '10' | grep '^#'
2875 $ hg email --date '1980-1-1 0:1' -t foo -s test -r '10' | grep '^#'
2876 abort: public url $TESTTMP/t2 is missing 3b6f1ec9dde9
2876 abort: public url $TESTTMP/t2 is missing 3b6f1ec9dde9
2877 (use 'hg push $TESTTMP/t2 -r 3b6f1ec9dde9')
2877 (use 'hg push $TESTTMP/t2 -r 3b6f1ec9dde9')
2878 [1]
2878 [1]
2879
2879
2880 public missing
2880 public missing
2881
2881
2882 $ echo 'publicurl=$TESTTMP/missing' >> $HGRCPATH
2882 $ echo 'publicurl=$TESTTMP/missing' >> $HGRCPATH
2883 $ hg email --date '1980-1-1 0:1' -t foo -s test -r '10'
2883 $ hg email --date '1980-1-1 0:1' -t foo -s test -r '10'
2884 unable to access public repo: $TESTTMP/missing
2884 unable to access public repo: $TESTTMP/missing
2885 abort: repository $TESTTMP/missing not found!
2885 abort: repository $TESTTMP/missing not found!
2886 [255]
2886 [255]
2887
2887
2888 node missing at public
2888 node missing at public
2889
2889
2890 $ hg clone -r '9' . ../t3
2890 $ hg clone -r '9' . ../t3
2891 adding changesets
2891 adding changesets
2892 adding manifests
2892 adding manifests
2893 adding file changes
2893 adding file changes
2894 added 3 changesets with 3 changes to 3 files
2894 added 3 changesets with 3 changes to 3 files
2895 updating to branch test
2895 updating to branch test
2896 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
2896 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
2897 $ echo 'publicurl=$TESTTMP/t3' >> $HGRCPATH
2897 $ echo 'publicurl=$TESTTMP/t3' >> $HGRCPATH
2898 $ hg email --date '1980-1-1 0:1' -t foo -s test -r '10'
2898 $ hg email --date '1980-1-1 0:1' -t foo -s test -r '10'
2899 abort: public url $TESTTMP/t3 is missing 3b6f1ec9dde9
2899 abort: public url $TESTTMP/t3 is missing 3b6f1ec9dde9
2900 (use 'hg push $TESTTMP/t3 -r 3b6f1ec9dde9')
2900 (use 'hg push $TESTTMP/t3 -r 3b6f1ec9dde9')
2901 [255]
2901 [255]
2902
2902
2903 multiple heads are missing at public
2903 multiple heads are missing at public
2904
2904
2905 $ hg email --date '1980-1-1 0:1' -t foo -s test -r '2+10'
2905 $ hg email --date '1980-1-1 0:1' -t foo -s test -r '2+10'
2906 abort: public "$TESTTMP/t3" is missing ff2c9fa2018b and 1 others
2906 abort: public "$TESTTMP/t3" is missing ff2c9fa2018b and 1 others
2907 (use 'hg push $TESTTMP/t3 -r ff2c9fa2018b -r 3b6f1ec9dde9')
2907 (use 'hg push $TESTTMP/t3 -r ff2c9fa2018b -r 3b6f1ec9dde9')
2908 [255]
2908 [255]
2909
2909
@@ -1,359 +1,359 b''
1 $ cat >> $HGRCPATH <<EOF
1 $ cat >> $HGRCPATH <<EOF
2 > [format]
2 > [format]
3 > usegeneraldelta=yes
3 > usegeneraldelta=yes
4 > [extensions]
4 > [extensions]
5 > rebase=
5 > rebase=
6 >
6 >
7 > [phases]
7 > [phases]
8 > publish=False
8 > publish=False
9 >
9 >
10 > [alias]
10 > [alias]
11 > tglog = log -G --template "{rev}:{phase} '{desc}' {branches} {bookmarks}\n"
11 > tglog = log -G --template "{rev}:{phase} '{desc}' {branches} {bookmarks}\n"
12 > EOF
12 > EOF
13
13
14 $ hg init a
14 $ hg init a
15 $ cd a
15 $ cd a
16 $ echo c1 >common
16 $ echo c1 >common
17 $ hg add common
17 $ hg add common
18 $ hg ci -m C1
18 $ hg ci -m C1
19
19
20 $ echo c2 >>common
20 $ echo c2 >>common
21 $ hg ci -m C2
21 $ hg ci -m C2
22
22
23 $ echo c3 >>common
23 $ echo c3 >>common
24 $ hg ci -m C3
24 $ hg ci -m C3
25
25
26 $ hg up -q -C 1
26 $ hg up -q -C 1
27
27
28 $ echo l1 >>extra
28 $ echo l1 >>extra
29 $ hg add extra
29 $ hg add extra
30 $ hg ci -m L1
30 $ hg ci -m L1
31 created new head
31 created new head
32
32
33 $ sed -e 's/c2/l2/' common > common.new
33 $ sed -e 's/c2/l2/' common > common.new
34 $ mv common.new common
34 $ mv common.new common
35 $ hg ci -m L2
35 $ hg ci -m L2
36
36
37 $ echo l3 >> extra2
37 $ echo l3 >> extra2
38 $ hg add extra2
38 $ hg add extra2
39 $ hg ci -m L3
39 $ hg ci -m L3
40 $ hg bookmark mybook
40 $ hg bookmark mybook
41
41
42 $ hg phase --force --secret 4
42 $ hg phase --force --secret 4
43
43
44 $ hg tglog
44 $ hg tglog
45 @ 5:secret 'L3' mybook
45 @ 5:secret 'L3' mybook
46 |
46 |
47 o 4:secret 'L2'
47 o 4:secret 'L2'
48 |
48 |
49 o 3:draft 'L1'
49 o 3:draft 'L1'
50 |
50 |
51 | o 2:draft 'C3'
51 | o 2:draft 'C3'
52 |/
52 |/
53 o 1:draft 'C2'
53 o 1:draft 'C2'
54 |
54 |
55 o 0:draft 'C1'
55 o 0:draft 'C1'
56
56
57 Try to call --continue:
57 Try to call --continue:
58
58
59 $ hg rebase --continue
59 $ hg rebase --continue
60 abort: no rebase in progress
60 abort: no rebase in progress
61 [255]
61 [255]
62
62
63 Conflicting rebase:
63 Conflicting rebase:
64
64
65 $ hg rebase -s 3 -d 2
65 $ hg rebase -s 3 -d 2
66 rebasing 3:3163e20567cc "L1"
66 rebasing 3:3163e20567cc "L1"
67 rebasing 4:46f0b057b5c0 "L2"
67 rebasing 4:46f0b057b5c0 "L2"
68 merging common
68 merging common
69 warning: conflicts while merging common! (edit, then use 'hg resolve --mark')
69 warning: conflicts while merging common! (edit, then use 'hg resolve --mark')
70 unresolved conflicts (see hg resolve, then hg rebase --continue)
70 unresolved conflicts (see hg resolve, then hg rebase --continue)
71 [1]
71 [1]
72
72
73 Try to continue without solving the conflict:
73 Try to continue without solving the conflict:
74
74
75 $ hg rebase --continue
75 $ hg rebase --continue
76 already rebased 3:3163e20567cc "L1" as 3e046f2ecedb
76 already rebased 3:3163e20567cc "L1" as 3e046f2ecedb
77 rebasing 4:46f0b057b5c0 "L2"
77 rebasing 4:46f0b057b5c0 "L2"
78 abort: unresolved merge conflicts (see "hg help resolve")
78 abort: unresolved merge conflicts (see "hg help resolve")
79 [255]
79 [255]
80
80
81 Conclude rebase:
81 Conclude rebase:
82
82
83 $ echo 'resolved merge' >common
83 $ echo 'resolved merge' >common
84 $ hg resolve -m common
84 $ hg resolve -m common
85 (no more unresolved files)
85 (no more unresolved files)
86 continue: hg rebase --continue
86 continue: hg rebase --continue
87 $ hg rebase --continue
87 $ hg rebase --continue
88 already rebased 3:3163e20567cc "L1" as 3e046f2ecedb
88 already rebased 3:3163e20567cc "L1" as 3e046f2ecedb
89 rebasing 4:46f0b057b5c0 "L2"
89 rebasing 4:46f0b057b5c0 "L2"
90 rebasing 5:8029388f38dc "L3" (mybook)
90 rebasing 5:8029388f38dc "L3" (mybook)
91 saved backup bundle to $TESTTMP/a/.hg/strip-backup/3163e20567cc-5ca4656e-backup.hg (glob)
91 saved backup bundle to $TESTTMP/a/.hg/strip-backup/3163e20567cc-5ca4656e-backup.hg (glob)
92
92
93 $ hg tglog
93 $ hg tglog
94 @ 5:secret 'L3' mybook
94 @ 5:secret 'L3' mybook
95 |
95 |
96 o 4:secret 'L2'
96 o 4:secret 'L2'
97 |
97 |
98 o 3:draft 'L1'
98 o 3:draft 'L1'
99 |
99 |
100 o 2:draft 'C3'
100 o 2:draft 'C3'
101 |
101 |
102 o 1:draft 'C2'
102 o 1:draft 'C2'
103 |
103 |
104 o 0:draft 'C1'
104 o 0:draft 'C1'
105
105
106 Check correctness:
106 Check correctness:
107
107
108 $ hg cat -r 0 common
108 $ hg cat -r 0 common
109 c1
109 c1
110
110
111 $ hg cat -r 1 common
111 $ hg cat -r 1 common
112 c1
112 c1
113 c2
113 c2
114
114
115 $ hg cat -r 2 common
115 $ hg cat -r 2 common
116 c1
116 c1
117 c2
117 c2
118 c3
118 c3
119
119
120 $ hg cat -r 3 common
120 $ hg cat -r 3 common
121 c1
121 c1
122 c2
122 c2
123 c3
123 c3
124
124
125 $ hg cat -r 4 common
125 $ hg cat -r 4 common
126 resolved merge
126 resolved merge
127
127
128 $ hg cat -r 5 common
128 $ hg cat -r 5 common
129 resolved merge
129 resolved merge
130
130
131 Bookmark stays active after --continue
131 Bookmark stays active after --continue
132 $ hg bookmarks
132 $ hg bookmarks
133 * mybook 5:d67b21408fc0
133 * mybook 5:d67b21408fc0
134
134
135 $ cd ..
135 $ cd ..
136
136
137 Check that the right ancestors is used while rebasing a merge (issue4041)
137 Check that the right ancestors is used while rebasing a merge (issue4041)
138
138
139 $ hg clone "$TESTDIR/bundles/issue4041.hg" issue4041
139 $ hg clone "$TESTDIR/bundles/issue4041.hg" issue4041
140 requesting all changes
140 requesting all changes
141 adding changesets
141 adding changesets
142 adding manifests
142 adding manifests
143 adding file changes
143 adding file changes
144 added 11 changesets with 8 changes to 3 files (+1 heads)
144 added 11 changesets with 8 changes to 3 files (+1 heads)
145 updating to branch default
145 updating to branch default
146 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
146 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
147 $ cd issue4041
147 $ cd issue4041
148 $ hg log -G
148 $ hg log -G
149 o changeset: 10:2f2496ddf49d
149 o changeset: 10:2f2496ddf49d
150 |\ branch: f1
150 |\ branch: f1
151 | | tag: tip
151 | | tag: tip
152 | | parent: 7:4c9fbe56a16f
152 | | parent: 7:4c9fbe56a16f
153 | | parent: 9:e31216eec445
153 | | parent: 9:e31216eec445
154 | | user: szhang
154 | | user: szhang
155 | | date: Thu Sep 05 12:59:39 2013 -0400
155 | | date: Thu Sep 05 12:59:39 2013 -0400
156 | | summary: merge
156 | | summary: merge
157 | |
157 | |
158 | o changeset: 9:e31216eec445
158 | o changeset: 9:e31216eec445
159 | | branch: f1
159 | | branch: f1
160 | | user: szhang
160 | | user: szhang
161 | | date: Thu Sep 05 12:59:10 2013 -0400
161 | | date: Thu Sep 05 12:59:10 2013 -0400
162 | | summary: more changes to f1
162 | | summary: more changes to f1
163 | |
163 | |
164 | o changeset: 8:8e4e2c1a07ae
164 | o changeset: 8:8e4e2c1a07ae
165 | |\ branch: f1
165 | |\ branch: f1
166 | | | parent: 2:4bc80088dc6b
166 | | | parent: 2:4bc80088dc6b
167 | | | parent: 6:400110238667
167 | | | parent: 6:400110238667
168 | | | user: szhang
168 | | | user: szhang
169 | | | date: Thu Sep 05 12:57:59 2013 -0400
169 | | | date: Thu Sep 05 12:57:59 2013 -0400
170 | | | summary: bad merge
170 | | | summary: bad merge
171 | | |
171 | | |
172 o | | changeset: 7:4c9fbe56a16f
172 o | | changeset: 7:4c9fbe56a16f
173 |/ / branch: f1
173 |/ / branch: f1
174 | | parent: 2:4bc80088dc6b
174 | | parent: 2:4bc80088dc6b
175 | | user: szhang
175 | | user: szhang
176 | | date: Thu Sep 05 12:54:00 2013 -0400
176 | | date: Thu Sep 05 12:54:00 2013 -0400
177 | | summary: changed f1
177 | | summary: changed f1
178 | |
178 | |
179 | o changeset: 6:400110238667
179 | o changeset: 6:400110238667
180 | | branch: f2
180 | | branch: f2
181 | | parent: 4:12e8ec6bb010
181 | | parent: 4:12e8ec6bb010
182 | | user: szhang
182 | | user: szhang
183 | | date: Tue Sep 03 13:58:02 2013 -0400
183 | | date: Tue Sep 03 13:58:02 2013 -0400
184 | | summary: changed f2 on f2
184 | | summary: changed f2 on f2
185 | |
185 | |
186 | | @ changeset: 5:d79e2059b5c0
186 | | @ changeset: 5:d79e2059b5c0
187 | | | parent: 3:8a951942e016
187 | | | parent: 3:8a951942e016
188 | | | user: szhang
188 | | | user: szhang
189 | | | date: Tue Sep 03 13:57:39 2013 -0400
189 | | | date: Tue Sep 03 13:57:39 2013 -0400
190 | | | summary: changed f2 on default
190 | | | summary: changed f2 on default
191 | | |
191 | | |
192 | o | changeset: 4:12e8ec6bb010
192 | o | changeset: 4:12e8ec6bb010
193 | |/ branch: f2
193 | |/ branch: f2
194 | | user: szhang
194 | | user: szhang
195 | | date: Tue Sep 03 13:57:18 2013 -0400
195 | | date: Tue Sep 03 13:57:18 2013 -0400
196 | | summary: created f2 branch
196 | | summary: created f2 branch
197 | |
197 | |
198 | o changeset: 3:8a951942e016
198 | o changeset: 3:8a951942e016
199 | | parent: 0:24797d4f68de
199 | | parent: 0:24797d4f68de
200 | | user: szhang
200 | | user: szhang
201 | | date: Tue Sep 03 13:57:11 2013 -0400
201 | | date: Tue Sep 03 13:57:11 2013 -0400
202 | | summary: added f2.txt
202 | | summary: added f2.txt
203 | |
203 | |
204 o | changeset: 2:4bc80088dc6b
204 o | changeset: 2:4bc80088dc6b
205 | | branch: f1
205 | | branch: f1
206 | | user: szhang
206 | | user: szhang
207 | | date: Tue Sep 03 13:56:20 2013 -0400
207 | | date: Tue Sep 03 13:56:20 2013 -0400
208 | | summary: added f1.txt
208 | | summary: added f1.txt
209 | |
209 | |
210 o | changeset: 1:ef53c9e6b608
210 o | changeset: 1:ef53c9e6b608
211 |/ branch: f1
211 |/ branch: f1
212 | user: szhang
212 | user: szhang
213 | date: Tue Sep 03 13:55:26 2013 -0400
213 | date: Tue Sep 03 13:55:26 2013 -0400
214 | summary: created f1 branch
214 | summary: created f1 branch
215 |
215 |
216 o changeset: 0:24797d4f68de
216 o changeset: 0:24797d4f68de
217 user: szhang
217 user: szhang
218 date: Tue Sep 03 13:55:08 2013 -0400
218 date: Tue Sep 03 13:55:08 2013 -0400
219 summary: added default.txt
219 summary: added default.txt
220
220
221 $ hg rebase -s9 -d2 --debug # use debug to really check merge base used
221 $ hg rebase -s9 -d2 --debug # use debug to really check merge base used
222 rebase onto 2 starting from e31216eec445
222 rebase onto 2 starting from e31216eec445
223 ignoring null merge rebase of 3
223 ignoring null merge rebase of 3
224 ignoring null merge rebase of 4
224 ignoring null merge rebase of 4
225 ignoring null merge rebase of 6
225 ignoring null merge rebase of 6
226 ignoring null merge rebase of 8
226 ignoring null merge rebase of 8
227 rebasing 9:e31216eec445 "more changes to f1"
227 rebasing 9:e31216eec445 "more changes to f1"
228 future parents are 2 and -1
228 future parents are 2 and -1
229 rebase status stored
229 rebase status stored
230 update to 2:4bc80088dc6b
230 update to 2:4bc80088dc6b
231 resolving manifests
231 resolving manifests
232 branchmerge: False, force: True, partial: False
232 branchmerge: False, force: True, partial: False
233 ancestor: d79e2059b5c0+, local: d79e2059b5c0+, remote: 4bc80088dc6b
233 ancestor: d79e2059b5c0+, local: d79e2059b5c0+, remote: 4bc80088dc6b
234 f2.txt: other deleted -> r
234 f2.txt: other deleted -> r
235 removing f2.txt
235 removing f2.txt
236 f1.txt: remote created -> g
236 f1.txt: remote created -> g
237 getting f1.txt
237 getting f1.txt
238 merge against 9:e31216eec445
238 merge against 9:e31216eec445
239 detach base 8:8e4e2c1a07ae
239 detach base 8:8e4e2c1a07ae
240 searching for copies back to rev 3
240 searching for copies back to rev 3
241 resolving manifests
241 resolving manifests
242 branchmerge: True, force: True, partial: False
242 branchmerge: True, force: True, partial: False
243 ancestor: 8e4e2c1a07ae, local: 4bc80088dc6b+, remote: e31216eec445
243 ancestor: 8e4e2c1a07ae, local: 4bc80088dc6b+, remote: e31216eec445
244 f1.txt: remote is newer -> g
244 f1.txt: remote is newer -> g
245 getting f1.txt
245 getting f1.txt
246 committing files:
246 committing files:
247 f1.txt
247 f1.txt
248 committing manifest
248 committing manifest
249 committing changelog
249 committing changelog
250 rebased as 19c888675e13
250 rebased as 19c888675e13
251 rebasing 10:2f2496ddf49d "merge" (tip)
251 rebasing 10:2f2496ddf49d "merge" (tip)
252 future parents are 11 and 7
252 future parents are 11 and 7
253 rebase status stored
253 rebase status stored
254 already in target
254 already in target
255 merge against 10:2f2496ddf49d
255 merge against 10:2f2496ddf49d
256 detach base 9:e31216eec445
256 detach base 9:e31216eec445
257 searching for copies back to rev 3
257 searching for copies back to rev 3
258 resolving manifests
258 resolving manifests
259 branchmerge: True, force: True, partial: False
259 branchmerge: True, force: True, partial: False
260 ancestor: e31216eec445, local: 19c888675e13+, remote: 2f2496ddf49d
260 ancestor: e31216eec445, local: 19c888675e13+, remote: 2f2496ddf49d
261 f1.txt: remote is newer -> g
261 f1.txt: remote is newer -> g
262 getting f1.txt
262 getting f1.txt
263 committing files:
263 committing files:
264 f1.txt
264 f1.txt
265 committing manifest
265 committing manifest
266 committing changelog
266 committing changelog
267 rebased as 2a7f09cac94c
267 rebased as 2a7f09cac94c
268 rebase merging completed
268 rebase merging completed
269 update back to initial working directory parent
269 update back to initial working directory parent
270 resolving manifests
270 resolving manifests
271 branchmerge: False, force: False, partial: False
271 branchmerge: False, force: False, partial: False
272 ancestor: 2a7f09cac94c, local: 2a7f09cac94c+, remote: d79e2059b5c0
272 ancestor: 2a7f09cac94c, local: 2a7f09cac94c+, remote: d79e2059b5c0
273 f1.txt: other deleted -> r
273 f1.txt: other deleted -> r
274 removing f1.txt
274 removing f1.txt
275 f2.txt: remote created -> g
275 f2.txt: remote created -> g
276 getting f2.txt
276 getting f2.txt
277 2 changesets found
277 2 changesets found
278 list of changesets:
278 list of changesets:
279 e31216eec445e44352c5f01588856059466a24c9
279 e31216eec445e44352c5f01588856059466a24c9
280 2f2496ddf49d69b5ef23ad8cf9fb2e0e4faf0ac2
280 2f2496ddf49d69b5ef23ad8cf9fb2e0e4faf0ac2
281 bundle2-output-bundle: "HG20", (1 params) 1 parts total
281 bundle2-output-bundle: "HG20", (1 params) 1 parts total
282 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
282 bundle2-output-part: "changegroup" (params: 1 mandatory 1 advisory) streamed payload
283 saved backup bundle to $TESTTMP/issue4041/.hg/strip-backup/e31216eec445-15f7a814-backup.hg (glob)
283 saved backup bundle to $TESTTMP/issue4041/.hg/strip-backup/e31216eec445-15f7a814-backup.hg (glob)
284 3 changesets found
284 3 changesets found
285 list of changesets:
285 list of changesets:
286 4c9fbe56a16f30c0d5dcc40ec1a97bbe3325209c
286 4c9fbe56a16f30c0d5dcc40ec1a97bbe3325209c
287 19c888675e133ab5dff84516926a65672eaf04d9
287 19c888675e133ab5dff84516926a65672eaf04d9
288 2a7f09cac94c7f4b73ebd5cd1a62d3b2e8e336bf
288 2a7f09cac94c7f4b73ebd5cd1a62d3b2e8e336bf
289 bundle2-output-bundle: "HG20", 1 parts total
289 bundle2-output-bundle: "HG20", 1 parts total
290 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
290 bundle2-output-part: "changegroup" (params: 1 mandatory 1 advisory) streamed payload
291 adding branch
291 adding branch
292 bundle2-input-bundle: with-transaction
292 bundle2-input-bundle: with-transaction
293 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
293 bundle2-input-part: "changegroup" (params: 1 mandatory 1 advisory) supported
294 adding changesets
294 adding changesets
295 add changeset 4c9fbe56a16f
295 add changeset 4c9fbe56a16f
296 add changeset 19c888675e13
296 add changeset 19c888675e13
297 add changeset 2a7f09cac94c
297 add changeset 2a7f09cac94c
298 adding manifests
298 adding manifests
299 adding file changes
299 adding file changes
300 adding f1.txt revisions
300 adding f1.txt revisions
301 added 2 changesets with 2 changes to 1 files
301 added 2 changesets with 2 changes to 1 files
302 bundle2-input-part: total payload size 1713
302 bundle2-input-part: total payload size 1713
303 bundle2-input-bundle: 0 parts total
303 bundle2-input-bundle: 0 parts total
304 invalid branchheads cache (served): tip differs
304 invalid branchheads cache (served): tip differs
305 rebase completed
305 rebase completed
306 updating the branch cache
306 updating the branch cache
307 truncating cache/rbc-revs-v1 to 72
307 truncating cache/rbc-revs-v1 to 72
308
308
309 Test minimization of merge conflicts
309 Test minimization of merge conflicts
310 $ hg up -q null
310 $ hg up -q null
311 $ echo a > a
311 $ echo a > a
312 $ hg add a
312 $ hg add a
313 $ hg commit -q -m 'a'
313 $ hg commit -q -m 'a'
314 $ echo b >> a
314 $ echo b >> a
315 $ hg commit -q -m 'ab'
315 $ hg commit -q -m 'ab'
316 $ hg bookmark ab
316 $ hg bookmark ab
317 $ hg up -q '.^'
317 $ hg up -q '.^'
318 $ echo b >> a
318 $ echo b >> a
319 $ echo c >> a
319 $ echo c >> a
320 $ hg commit -q -m 'abc'
320 $ hg commit -q -m 'abc'
321 $ hg rebase -s 7bc217434fc1 -d ab --keep
321 $ hg rebase -s 7bc217434fc1 -d ab --keep
322 rebasing 13:7bc217434fc1 "abc" (tip)
322 rebasing 13:7bc217434fc1 "abc" (tip)
323 merging a
323 merging a
324 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
324 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
325 unresolved conflicts (see hg resolve, then hg rebase --continue)
325 unresolved conflicts (see hg resolve, then hg rebase --continue)
326 [1]
326 [1]
327 $ hg diff
327 $ hg diff
328 diff -r 328e4ab1f7cc a
328 diff -r 328e4ab1f7cc a
329 --- a/a Thu Jan 01 00:00:00 1970 +0000
329 --- a/a Thu Jan 01 00:00:00 1970 +0000
330 +++ b/a * (glob)
330 +++ b/a * (glob)
331 @@ -1,2 +1,6 @@
331 @@ -1,2 +1,6 @@
332 a
332 a
333 b
333 b
334 +<<<<<<< dest: 328e4ab1f7cc ab - test: ab
334 +<<<<<<< dest: 328e4ab1f7cc ab - test: ab
335 +=======
335 +=======
336 +c
336 +c
337 +>>>>>>> source: 7bc217434fc1 - test: abc
337 +>>>>>>> source: 7bc217434fc1 - test: abc
338 $ hg rebase --abort
338 $ hg rebase --abort
339 rebase aborted
339 rebase aborted
340 $ hg up -q -C 7bc217434fc1
340 $ hg up -q -C 7bc217434fc1
341 $ hg rebase -s . -d ab --keep -t internal:merge3
341 $ hg rebase -s . -d ab --keep -t internal:merge3
342 rebasing 13:7bc217434fc1 "abc" (tip)
342 rebasing 13:7bc217434fc1 "abc" (tip)
343 merging a
343 merging a
344 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
344 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
345 unresolved conflicts (see hg resolve, then hg rebase --continue)
345 unresolved conflicts (see hg resolve, then hg rebase --continue)
346 [1]
346 [1]
347 $ hg diff
347 $ hg diff
348 diff -r 328e4ab1f7cc a
348 diff -r 328e4ab1f7cc a
349 --- a/a Thu Jan 01 00:00:00 1970 +0000
349 --- a/a Thu Jan 01 00:00:00 1970 +0000
350 +++ b/a * (glob)
350 +++ b/a * (glob)
351 @@ -1,2 +1,8 @@
351 @@ -1,2 +1,8 @@
352 a
352 a
353 +<<<<<<< dest: 328e4ab1f7cc ab - test: ab
353 +<<<<<<< dest: 328e4ab1f7cc ab - test: ab
354 b
354 b
355 +||||||| base
355 +||||||| base
356 +=======
356 +=======
357 +b
357 +b
358 +c
358 +c
359 +>>>>>>> source: 7bc217434fc1 - test: abc
359 +>>>>>>> source: 7bc217434fc1 - test: abc
@@ -1,1624 +1,1624 b''
1 $ cat <<EOF >> $HGRCPATH
1 $ cat <<EOF >> $HGRCPATH
2 > [extensions]
2 > [extensions]
3 > mq =
3 > mq =
4 > shelve =
4 > shelve =
5 > [defaults]
5 > [defaults]
6 > diff = --nodates --git
6 > diff = --nodates --git
7 > qnew = --date '0 0'
7 > qnew = --date '0 0'
8 > [shelve]
8 > [shelve]
9 > maxbackups = 2
9 > maxbackups = 2
10 > EOF
10 > EOF
11
11
12 $ hg init repo
12 $ hg init repo
13 $ cd repo
13 $ cd repo
14 $ mkdir a b
14 $ mkdir a b
15 $ echo a > a/a
15 $ echo a > a/a
16 $ echo b > b/b
16 $ echo b > b/b
17 $ echo c > c
17 $ echo c > c
18 $ echo d > d
18 $ echo d > d
19 $ echo x > x
19 $ echo x > x
20 $ hg addremove -q
20 $ hg addremove -q
21
21
22 shelve has a help message
22 shelve has a help message
23 $ hg shelve -h
23 $ hg shelve -h
24 hg shelve [OPTION]... [FILE]...
24 hg shelve [OPTION]... [FILE]...
25
25
26 save and set aside changes from the working directory
26 save and set aside changes from the working directory
27
27
28 Shelving takes files that "hg status" reports as not clean, saves the
28 Shelving takes files that "hg status" reports as not clean, saves the
29 modifications to a bundle (a shelved change), and reverts the files so
29 modifications to a bundle (a shelved change), and reverts the files so
30 that their state in the working directory becomes clean.
30 that their state in the working directory becomes clean.
31
31
32 To restore these changes to the working directory, using "hg unshelve";
32 To restore these changes to the working directory, using "hg unshelve";
33 this will work even if you switch to a different commit.
33 this will work even if you switch to a different commit.
34
34
35 When no files are specified, "hg shelve" saves all not-clean files. If
35 When no files are specified, "hg shelve" saves all not-clean files. If
36 specific files or directories are named, only changes to those files are
36 specific files or directories are named, only changes to those files are
37 shelved.
37 shelved.
38
38
39 In bare shelve(when no files are specified, without interactive, include
39 In bare shelve(when no files are specified, without interactive, include
40 and exclude option), shelving remembers information if the working
40 and exclude option), shelving remembers information if the working
41 directory was on newly created branch, in other words working directory
41 directory was on newly created branch, in other words working directory
42 was on different branch than its first parent. In this situation
42 was on different branch than its first parent. In this situation
43 unshelving restores branch information to the working directory.
43 unshelving restores branch information to the working directory.
44
44
45 Each shelved change has a name that makes it easier to find later. The
45 Each shelved change has a name that makes it easier to find later. The
46 name of a shelved change defaults to being based on the active bookmark,
46 name of a shelved change defaults to being based on the active bookmark,
47 or if there is no active bookmark, the current named branch. To specify a
47 or if there is no active bookmark, the current named branch. To specify a
48 different name, use "--name".
48 different name, use "--name".
49
49
50 To see a list of existing shelved changes, use the "--list" option. For
50 To see a list of existing shelved changes, use the "--list" option. For
51 each shelved change, this will print its name, age, and description; use "
51 each shelved change, this will print its name, age, and description; use "
52 --patch" or "--stat" for more details.
52 --patch" or "--stat" for more details.
53
53
54 To delete specific shelved changes, use "--delete". To delete all shelved
54 To delete specific shelved changes, use "--delete". To delete all shelved
55 changes, use "--cleanup".
55 changes, use "--cleanup".
56
56
57 (use "hg help -e shelve" to show help for the shelve extension)
57 (use "hg help -e shelve" to show help for the shelve extension)
58
58
59 options ([+] can be repeated):
59 options ([+] can be repeated):
60
60
61 -A --addremove mark new/missing files as added/removed before
61 -A --addremove mark new/missing files as added/removed before
62 shelving
62 shelving
63 -u --unknown store unknown files in the shelve
63 -u --unknown store unknown files in the shelve
64 --cleanup delete all shelved changes
64 --cleanup delete all shelved changes
65 --date DATE shelve with the specified commit date
65 --date DATE shelve with the specified commit date
66 -d --delete delete the named shelved change(s)
66 -d --delete delete the named shelved change(s)
67 -e --edit invoke editor on commit messages
67 -e --edit invoke editor on commit messages
68 -l --list list current shelves
68 -l --list list current shelves
69 -m --message TEXT use text as shelve message
69 -m --message TEXT use text as shelve message
70 -n --name NAME use the given name for the shelved commit
70 -n --name NAME use the given name for the shelved commit
71 -p --patch show patch
71 -p --patch show patch
72 -i --interactive interactive mode, only works while creating a shelve
72 -i --interactive interactive mode, only works while creating a shelve
73 --stat output diffstat-style summary of changes
73 --stat output diffstat-style summary of changes
74 -I --include PATTERN [+] include names matching the given patterns
74 -I --include PATTERN [+] include names matching the given patterns
75 -X --exclude PATTERN [+] exclude names matching the given patterns
75 -X --exclude PATTERN [+] exclude names matching the given patterns
76 --mq operate on patch repository
76 --mq operate on patch repository
77
77
78 (some details hidden, use --verbose to show complete help)
78 (some details hidden, use --verbose to show complete help)
79
79
80 shelving in an empty repo should be possible
80 shelving in an empty repo should be possible
81 (this tests also that editor is not invoked, if '--edit' is not
81 (this tests also that editor is not invoked, if '--edit' is not
82 specified)
82 specified)
83
83
84 $ HGEDITOR=cat hg shelve
84 $ HGEDITOR=cat hg shelve
85 shelved as default
85 shelved as default
86 0 files updated, 0 files merged, 5 files removed, 0 files unresolved
86 0 files updated, 0 files merged, 5 files removed, 0 files unresolved
87
87
88 $ hg unshelve
88 $ hg unshelve
89 unshelving change 'default'
89 unshelving change 'default'
90
90
91 $ hg commit -q -m 'initial commit'
91 $ hg commit -q -m 'initial commit'
92
92
93 $ hg shelve
93 $ hg shelve
94 nothing changed
94 nothing changed
95 [1]
95 [1]
96
96
97 make sure shelve files were backed up
97 make sure shelve files were backed up
98
98
99 $ ls .hg/shelve-backup
99 $ ls .hg/shelve-backup
100 default.hg
100 default.hg
101 default.patch
101 default.patch
102
102
103 create an mq patch - shelving should work fine with a patch applied
103 create an mq patch - shelving should work fine with a patch applied
104
104
105 $ echo n > n
105 $ echo n > n
106 $ hg add n
106 $ hg add n
107 $ hg commit n -m second
107 $ hg commit n -m second
108 $ hg qnew second.patch
108 $ hg qnew second.patch
109
109
110 shelve a change that we will delete later
110 shelve a change that we will delete later
111
111
112 $ echo a >> a/a
112 $ echo a >> a/a
113 $ hg shelve
113 $ hg shelve
114 shelved as default
114 shelved as default
115 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
115 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
116
116
117 set up some more complex changes to shelve
117 set up some more complex changes to shelve
118
118
119 $ echo a >> a/a
119 $ echo a >> a/a
120 $ hg mv b b.rename
120 $ hg mv b b.rename
121 moving b/b to b.rename/b (glob)
121 moving b/b to b.rename/b (glob)
122 $ hg cp c c.copy
122 $ hg cp c c.copy
123 $ hg status -C
123 $ hg status -C
124 M a/a
124 M a/a
125 A b.rename/b
125 A b.rename/b
126 b/b
126 b/b
127 A c.copy
127 A c.copy
128 c
128 c
129 R b/b
129 R b/b
130
130
131 prevent some foot-shooting
131 prevent some foot-shooting
132
132
133 $ hg shelve -n foo/bar
133 $ hg shelve -n foo/bar
134 abort: shelved change names may not contain slashes
134 abort: shelved change names may not contain slashes
135 [255]
135 [255]
136 $ hg shelve -n .baz
136 $ hg shelve -n .baz
137 abort: shelved change names may not start with '.'
137 abort: shelved change names may not start with '.'
138 [255]
138 [255]
139
139
140 the common case - no options or filenames
140 the common case - no options or filenames
141
141
142 $ hg shelve
142 $ hg shelve
143 shelved as default-01
143 shelved as default-01
144 2 files updated, 0 files merged, 2 files removed, 0 files unresolved
144 2 files updated, 0 files merged, 2 files removed, 0 files unresolved
145 $ hg status -C
145 $ hg status -C
146
146
147 ensure that our shelved changes exist
147 ensure that our shelved changes exist
148
148
149 $ hg shelve -l
149 $ hg shelve -l
150 default-01 (*)* changes to: [mq]: second.patch (glob)
150 default-01 (*)* changes to: [mq]: second.patch (glob)
151 default (*)* changes to: [mq]: second.patch (glob)
151 default (*)* changes to: [mq]: second.patch (glob)
152
152
153 $ hg shelve -l -p default
153 $ hg shelve -l -p default
154 default (*)* changes to: [mq]: second.patch (glob)
154 default (*)* changes to: [mq]: second.patch (glob)
155
155
156 diff --git a/a/a b/a/a
156 diff --git a/a/a b/a/a
157 --- a/a/a
157 --- a/a/a
158 +++ b/a/a
158 +++ b/a/a
159 @@ -1,1 +1,2 @@
159 @@ -1,1 +1,2 @@
160 a
160 a
161 +a
161 +a
162
162
163 $ hg shelve --list --addremove
163 $ hg shelve --list --addremove
164 abort: options '--list' and '--addremove' may not be used together
164 abort: options '--list' and '--addremove' may not be used together
165 [255]
165 [255]
166
166
167 delete our older shelved change
167 delete our older shelved change
168
168
169 $ hg shelve -d default
169 $ hg shelve -d default
170 $ hg qfinish -a -q
170 $ hg qfinish -a -q
171
171
172 ensure shelve backups aren't overwritten
172 ensure shelve backups aren't overwritten
173
173
174 $ ls .hg/shelve-backup/
174 $ ls .hg/shelve-backup/
175 default-1.hg
175 default-1.hg
176 default-1.patch
176 default-1.patch
177 default.hg
177 default.hg
178 default.patch
178 default.patch
179
179
180 local edits should not prevent a shelved change from applying
180 local edits should not prevent a shelved change from applying
181
181
182 $ printf "z\na\n" > a/a
182 $ printf "z\na\n" > a/a
183 $ hg unshelve --keep
183 $ hg unshelve --keep
184 unshelving change 'default-01'
184 unshelving change 'default-01'
185 temporarily committing pending changes (restore with 'hg unshelve --abort')
185 temporarily committing pending changes (restore with 'hg unshelve --abort')
186 rebasing shelved changes
186 rebasing shelved changes
187 rebasing 4:32c69314e062 "changes to: [mq]: second.patch" (tip)
187 rebasing 4:32c69314e062 "changes to: [mq]: second.patch" (tip)
188 merging a/a
188 merging a/a
189
189
190 $ hg revert --all -q
190 $ hg revert --all -q
191 $ rm a/a.orig b.rename/b c.copy
191 $ rm a/a.orig b.rename/b c.copy
192
192
193 apply it and make sure our state is as expected
193 apply it and make sure our state is as expected
194
194
195 (this also tests that same timestamp prevents backups from being
195 (this also tests that same timestamp prevents backups from being
196 removed, even though there are more than 'maxbackups' backups)
196 removed, even though there are more than 'maxbackups' backups)
197
197
198 $ f -t .hg/shelve-backup/default.hg
198 $ f -t .hg/shelve-backup/default.hg
199 .hg/shelve-backup/default.hg: file
199 .hg/shelve-backup/default.hg: file
200 $ touch -t 200001010000 .hg/shelve-backup/default.hg
200 $ touch -t 200001010000 .hg/shelve-backup/default.hg
201 $ f -t .hg/shelve-backup/default-1.hg
201 $ f -t .hg/shelve-backup/default-1.hg
202 .hg/shelve-backup/default-1.hg: file
202 .hg/shelve-backup/default-1.hg: file
203 $ touch -t 200001010000 .hg/shelve-backup/default-1.hg
203 $ touch -t 200001010000 .hg/shelve-backup/default-1.hg
204
204
205 $ hg unshelve
205 $ hg unshelve
206 unshelving change 'default-01'
206 unshelving change 'default-01'
207 $ hg status -C
207 $ hg status -C
208 M a/a
208 M a/a
209 A b.rename/b
209 A b.rename/b
210 b/b
210 b/b
211 A c.copy
211 A c.copy
212 c
212 c
213 R b/b
213 R b/b
214 $ hg shelve -l
214 $ hg shelve -l
215
215
216 (both of default.hg and default-1.hg should be still kept, because it
216 (both of default.hg and default-1.hg should be still kept, because it
217 is difficult to decide actual order of them from same timestamp)
217 is difficult to decide actual order of them from same timestamp)
218
218
219 $ ls .hg/shelve-backup/
219 $ ls .hg/shelve-backup/
220 default-01.hg
220 default-01.hg
221 default-01.patch
221 default-01.patch
222 default-1.hg
222 default-1.hg
223 default-1.patch
223 default-1.patch
224 default.hg
224 default.hg
225 default.patch
225 default.patch
226
226
227 $ hg unshelve
227 $ hg unshelve
228 abort: no shelved changes to apply!
228 abort: no shelved changes to apply!
229 [255]
229 [255]
230 $ hg unshelve foo
230 $ hg unshelve foo
231 abort: shelved change 'foo' not found
231 abort: shelved change 'foo' not found
232 [255]
232 [255]
233
233
234 named shelves, specific filenames, and "commit messages" should all work
234 named shelves, specific filenames, and "commit messages" should all work
235 (this tests also that editor is invoked, if '--edit' is specified)
235 (this tests also that editor is invoked, if '--edit' is specified)
236
236
237 $ hg status -C
237 $ hg status -C
238 M a/a
238 M a/a
239 A b.rename/b
239 A b.rename/b
240 b/b
240 b/b
241 A c.copy
241 A c.copy
242 c
242 c
243 R b/b
243 R b/b
244 $ HGEDITOR=cat hg shelve -q -n wibble -m wat -e a
244 $ HGEDITOR=cat hg shelve -q -n wibble -m wat -e a
245 wat
245 wat
246
246
247
247
248 HG: Enter commit message. Lines beginning with 'HG:' are removed.
248 HG: Enter commit message. Lines beginning with 'HG:' are removed.
249 HG: Leave message empty to abort commit.
249 HG: Leave message empty to abort commit.
250 HG: --
250 HG: --
251 HG: user: shelve@localhost
251 HG: user: shelve@localhost
252 HG: branch 'default'
252 HG: branch 'default'
253 HG: changed a/a
253 HG: changed a/a
254
254
255 expect "a" to no longer be present, but status otherwise unchanged
255 expect "a" to no longer be present, but status otherwise unchanged
256
256
257 $ hg status -C
257 $ hg status -C
258 A b.rename/b
258 A b.rename/b
259 b/b
259 b/b
260 A c.copy
260 A c.copy
261 c
261 c
262 R b/b
262 R b/b
263 $ hg shelve -l --stat
263 $ hg shelve -l --stat
264 wibble (*) wat (glob)
264 wibble (*) wat (glob)
265 a/a | 1 +
265 a/a | 1 +
266 1 files changed, 1 insertions(+), 0 deletions(-)
266 1 files changed, 1 insertions(+), 0 deletions(-)
267
267
268 and now "a/a" should reappear
268 and now "a/a" should reappear
269
269
270 $ cd a
270 $ cd a
271 $ hg unshelve -q wibble
271 $ hg unshelve -q wibble
272 $ cd ..
272 $ cd ..
273 $ hg status -C
273 $ hg status -C
274 M a/a
274 M a/a
275 A b.rename/b
275 A b.rename/b
276 b/b
276 b/b
277 A c.copy
277 A c.copy
278 c
278 c
279 R b/b
279 R b/b
280
280
281 ensure old shelve backups are being deleted automatically
281 ensure old shelve backups are being deleted automatically
282
282
283 $ ls .hg/shelve-backup/
283 $ ls .hg/shelve-backup/
284 default-01.hg
284 default-01.hg
285 default-01.patch
285 default-01.patch
286 wibble.hg
286 wibble.hg
287 wibble.patch
287 wibble.patch
288
288
289 cause unshelving to result in a merge with 'a' conflicting
289 cause unshelving to result in a merge with 'a' conflicting
290
290
291 $ hg shelve -q
291 $ hg shelve -q
292 $ echo c>>a/a
292 $ echo c>>a/a
293 $ hg commit -m second
293 $ hg commit -m second
294 $ hg tip --template '{files}\n'
294 $ hg tip --template '{files}\n'
295 a/a
295 a/a
296
296
297 add an unrelated change that should be preserved
297 add an unrelated change that should be preserved
298
298
299 $ mkdir foo
299 $ mkdir foo
300 $ echo foo > foo/foo
300 $ echo foo > foo/foo
301 $ hg add foo/foo
301 $ hg add foo/foo
302
302
303 force a conflicted merge to occur
303 force a conflicted merge to occur
304
304
305 $ hg unshelve
305 $ hg unshelve
306 unshelving change 'default'
306 unshelving change 'default'
307 temporarily committing pending changes (restore with 'hg unshelve --abort')
307 temporarily committing pending changes (restore with 'hg unshelve --abort')
308 rebasing shelved changes
308 rebasing shelved changes
309 rebasing 5:32c69314e062 "changes to: [mq]: second.patch" (tip)
309 rebasing 5:32c69314e062 "changes to: [mq]: second.patch" (tip)
310 merging a/a
310 merging a/a
311 warning: conflicts while merging a/a! (edit, then use 'hg resolve --mark')
311 warning: conflicts while merging a/a! (edit, then use 'hg resolve --mark')
312 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
312 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
313 [1]
313 [1]
314
314
315 ensure that we have a merge with unresolved conflicts
315 ensure that we have a merge with unresolved conflicts
316
316
317 $ hg heads -q --template '{rev}\n'
317 $ hg heads -q --template '{rev}\n'
318 5
318 5
319 4
319 4
320 $ hg parents -q --template '{rev}\n'
320 $ hg parents -q --template '{rev}\n'
321 4
321 4
322 5
322 5
323 $ hg status
323 $ hg status
324 M a/a
324 M a/a
325 M b.rename/b
325 M b.rename/b
326 M c.copy
326 M c.copy
327 R b/b
327 R b/b
328 ? a/a.orig
328 ? a/a.orig
329 $ hg diff
329 $ hg diff
330 diff --git a/a/a b/a/a
330 diff --git a/a/a b/a/a
331 --- a/a/a
331 --- a/a/a
332 +++ b/a/a
332 +++ b/a/a
333 @@ -1,2 +1,6 @@
333 @@ -1,2 +1,6 @@
334 a
334 a
335 +<<<<<<< dest: * - shelve: pending changes temporary commit (glob)
335 +<<<<<<< dest: * - shelve: pending changes temporary commit (glob)
336 c
336 c
337 +=======
337 +=======
338 +a
338 +a
339 +>>>>>>> source: 32c69314e062 - shelve: changes to: [mq]: second.patch
339 +>>>>>>> source: 32c69314e062 - shelve: changes to: [mq]: second.patch
340 diff --git a/b/b b/b.rename/b
340 diff --git a/b/b b/b.rename/b
341 rename from b/b
341 rename from b/b
342 rename to b.rename/b
342 rename to b.rename/b
343 diff --git a/c b/c.copy
343 diff --git a/c b/c.copy
344 copy from c
344 copy from c
345 copy to c.copy
345 copy to c.copy
346 $ hg resolve -l
346 $ hg resolve -l
347 U a/a
347 U a/a
348
348
349 $ hg shelve
349 $ hg shelve
350 abort: unshelve already in progress
350 abort: unshelve already in progress
351 (use 'hg unshelve --continue' or 'hg unshelve --abort')
351 (use 'hg unshelve --continue' or 'hg unshelve --abort')
352 [255]
352 [255]
353
353
354 abort the unshelve and be happy
354 abort the unshelve and be happy
355
355
356 $ hg status
356 $ hg status
357 M a/a
357 M a/a
358 M b.rename/b
358 M b.rename/b
359 M c.copy
359 M c.copy
360 R b/b
360 R b/b
361 ? a/a.orig
361 ? a/a.orig
362 $ hg unshelve -a
362 $ hg unshelve -a
363 rebase aborted
363 rebase aborted
364 unshelve of 'default' aborted
364 unshelve of 'default' aborted
365 $ hg heads -q
365 $ hg heads -q
366 3:2e69b451d1ea
366 3:2e69b451d1ea
367 $ hg parents
367 $ hg parents
368 changeset: 3:2e69b451d1ea
368 changeset: 3:2e69b451d1ea
369 tag: tip
369 tag: tip
370 user: test
370 user: test
371 date: Thu Jan 01 00:00:00 1970 +0000
371 date: Thu Jan 01 00:00:00 1970 +0000
372 summary: second
372 summary: second
373
373
374 $ hg resolve -l
374 $ hg resolve -l
375 $ hg status
375 $ hg status
376 A foo/foo
376 A foo/foo
377 ? a/a.orig
377 ? a/a.orig
378
378
379 try to continue with no unshelve underway
379 try to continue with no unshelve underway
380
380
381 $ hg unshelve -c
381 $ hg unshelve -c
382 abort: no unshelve in progress
382 abort: no unshelve in progress
383 [255]
383 [255]
384 $ hg status
384 $ hg status
385 A foo/foo
385 A foo/foo
386 ? a/a.orig
386 ? a/a.orig
387
387
388 redo the unshelve to get a conflict
388 redo the unshelve to get a conflict
389
389
390 $ hg unshelve -q
390 $ hg unshelve -q
391 warning: conflicts while merging a/a! (edit, then use 'hg resolve --mark')
391 warning: conflicts while merging a/a! (edit, then use 'hg resolve --mark')
392 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
392 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
393 [1]
393 [1]
394
394
395 attempt to continue
395 attempt to continue
396
396
397 $ hg unshelve -c
397 $ hg unshelve -c
398 abort: unresolved conflicts, can't continue
398 abort: unresolved conflicts, can't continue
399 (see 'hg resolve', then 'hg unshelve --continue')
399 (see 'hg resolve', then 'hg unshelve --continue')
400 [255]
400 [255]
401
401
402 $ hg revert -r . a/a
402 $ hg revert -r . a/a
403 $ hg resolve -m a/a
403 $ hg resolve -m a/a
404 (no more unresolved files)
404 (no more unresolved files)
405 continue: hg unshelve --continue
405 continue: hg unshelve --continue
406
406
407 $ hg commit -m 'commit while unshelve in progress'
407 $ hg commit -m 'commit while unshelve in progress'
408 abort: unshelve already in progress
408 abort: unshelve already in progress
409 (use 'hg unshelve --continue' or 'hg unshelve --abort')
409 (use 'hg unshelve --continue' or 'hg unshelve --abort')
410 [255]
410 [255]
411
411
412 $ hg graft --continue
412 $ hg graft --continue
413 abort: no graft in progress
413 abort: no graft in progress
414 (continue: hg unshelve --continue)
414 (continue: hg unshelve --continue)
415 [255]
415 [255]
416 $ hg unshelve -c
416 $ hg unshelve -c
417 rebasing 5:32c69314e062 "changes to: [mq]: second.patch" (tip)
417 rebasing 5:32c69314e062 "changes to: [mq]: second.patch" (tip)
418 unshelve of 'default' complete
418 unshelve of 'default' complete
419
419
420 ensure the repo is as we hope
420 ensure the repo is as we hope
421
421
422 $ hg parents
422 $ hg parents
423 changeset: 3:2e69b451d1ea
423 changeset: 3:2e69b451d1ea
424 tag: tip
424 tag: tip
425 user: test
425 user: test
426 date: Thu Jan 01 00:00:00 1970 +0000
426 date: Thu Jan 01 00:00:00 1970 +0000
427 summary: second
427 summary: second
428
428
429 $ hg heads -q
429 $ hg heads -q
430 3:2e69b451d1ea
430 3:2e69b451d1ea
431
431
432 $ hg status -C
432 $ hg status -C
433 A b.rename/b
433 A b.rename/b
434 b/b
434 b/b
435 A c.copy
435 A c.copy
436 c
436 c
437 A foo/foo
437 A foo/foo
438 R b/b
438 R b/b
439 ? a/a.orig
439 ? a/a.orig
440
440
441 there should be no shelves left
441 there should be no shelves left
442
442
443 $ hg shelve -l
443 $ hg shelve -l
444
444
445 #if execbit
445 #if execbit
446
446
447 ensure that metadata-only changes are shelved
447 ensure that metadata-only changes are shelved
448
448
449 $ chmod +x a/a
449 $ chmod +x a/a
450 $ hg shelve -q -n execbit a/a
450 $ hg shelve -q -n execbit a/a
451 $ hg status a/a
451 $ hg status a/a
452 $ hg unshelve -q execbit
452 $ hg unshelve -q execbit
453 $ hg status a/a
453 $ hg status a/a
454 M a/a
454 M a/a
455 $ hg revert a/a
455 $ hg revert a/a
456
456
457 #endif
457 #endif
458
458
459 #if symlink
459 #if symlink
460
460
461 $ rm a/a
461 $ rm a/a
462 $ ln -s foo a/a
462 $ ln -s foo a/a
463 $ hg shelve -q -n symlink a/a
463 $ hg shelve -q -n symlink a/a
464 $ hg status a/a
464 $ hg status a/a
465 $ hg unshelve -q symlink
465 $ hg unshelve -q symlink
466 $ hg status a/a
466 $ hg status a/a
467 M a/a
467 M a/a
468 $ hg revert a/a
468 $ hg revert a/a
469
469
470 #endif
470 #endif
471
471
472 set up another conflict between a commit and a shelved change
472 set up another conflict between a commit and a shelved change
473
473
474 $ hg revert -q -C -a
474 $ hg revert -q -C -a
475 $ rm a/a.orig b.rename/b c.copy
475 $ rm a/a.orig b.rename/b c.copy
476 $ echo a >> a/a
476 $ echo a >> a/a
477 $ hg shelve -q
477 $ hg shelve -q
478 $ echo x >> a/a
478 $ echo x >> a/a
479 $ hg ci -m 'create conflict'
479 $ hg ci -m 'create conflict'
480 $ hg add foo/foo
480 $ hg add foo/foo
481
481
482 if we resolve a conflict while unshelving, the unshelve should succeed
482 if we resolve a conflict while unshelving, the unshelve should succeed
483
483
484 $ hg unshelve --tool :merge-other --keep
484 $ hg unshelve --tool :merge-other --keep
485 unshelving change 'default'
485 unshelving change 'default'
486 temporarily committing pending changes (restore with 'hg unshelve --abort')
486 temporarily committing pending changes (restore with 'hg unshelve --abort')
487 rebasing shelved changes
487 rebasing shelved changes
488 rebasing 6:2f694dd83a13 "changes to: second" (tip)
488 rebasing 6:2f694dd83a13 "changes to: second" (tip)
489 merging a/a
489 merging a/a
490 $ hg parents -q
490 $ hg parents -q
491 4:33f7f61e6c5e
491 4:33f7f61e6c5e
492 $ hg shelve -l
492 $ hg shelve -l
493 default (*)* changes to: second (glob)
493 default (*)* changes to: second (glob)
494 $ hg status
494 $ hg status
495 M a/a
495 M a/a
496 A foo/foo
496 A foo/foo
497 $ cat a/a
497 $ cat a/a
498 a
498 a
499 c
499 c
500 a
500 a
501 $ cat > a/a << EOF
501 $ cat > a/a << EOF
502 > a
502 > a
503 > c
503 > c
504 > x
504 > x
505 > EOF
505 > EOF
506
506
507 $ HGMERGE=true hg unshelve
507 $ HGMERGE=true hg unshelve
508 unshelving change 'default'
508 unshelving change 'default'
509 temporarily committing pending changes (restore with 'hg unshelve --abort')
509 temporarily committing pending changes (restore with 'hg unshelve --abort')
510 rebasing shelved changes
510 rebasing shelved changes
511 rebasing 6:2f694dd83a13 "changes to: second" (tip)
511 rebasing 6:2f694dd83a13 "changes to: second" (tip)
512 merging a/a
512 merging a/a
513 note: rebase of 6:2f694dd83a13 created no changes to commit
513 note: rebase of 6:2f694dd83a13 created no changes to commit
514 $ hg parents -q
514 $ hg parents -q
515 4:33f7f61e6c5e
515 4:33f7f61e6c5e
516 $ hg shelve -l
516 $ hg shelve -l
517 $ hg status
517 $ hg status
518 A foo/foo
518 A foo/foo
519 $ cat a/a
519 $ cat a/a
520 a
520 a
521 c
521 c
522 x
522 x
523
523
524 test keep and cleanup
524 test keep and cleanup
525
525
526 $ hg shelve
526 $ hg shelve
527 shelved as default
527 shelved as default
528 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
528 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
529 $ hg shelve --list
529 $ hg shelve --list
530 default (*)* changes to: create conflict (glob)
530 default (*)* changes to: create conflict (glob)
531 $ hg unshelve -k
531 $ hg unshelve -k
532 unshelving change 'default'
532 unshelving change 'default'
533 $ hg shelve --list
533 $ hg shelve --list
534 default (*)* changes to: create conflict (glob)
534 default (*)* changes to: create conflict (glob)
535 $ hg shelve --cleanup
535 $ hg shelve --cleanup
536 $ hg shelve --list
536 $ hg shelve --list
537
537
538 $ hg shelve --cleanup --delete
538 $ hg shelve --cleanup --delete
539 abort: options '--cleanup' and '--delete' may not be used together
539 abort: options '--cleanup' and '--delete' may not be used together
540 [255]
540 [255]
541 $ hg shelve --cleanup --patch
541 $ hg shelve --cleanup --patch
542 abort: options '--cleanup' and '--patch' may not be used together
542 abort: options '--cleanup' and '--patch' may not be used together
543 [255]
543 [255]
544 $ hg shelve --cleanup --message MESSAGE
544 $ hg shelve --cleanup --message MESSAGE
545 abort: options '--cleanup' and '--message' may not be used together
545 abort: options '--cleanup' and '--message' may not be used together
546 [255]
546 [255]
547
547
548 test bookmarks
548 test bookmarks
549
549
550 $ hg bookmark test
550 $ hg bookmark test
551 $ hg bookmark
551 $ hg bookmark
552 * test 4:33f7f61e6c5e
552 * test 4:33f7f61e6c5e
553 $ hg shelve
553 $ hg shelve
554 shelved as test
554 shelved as test
555 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
555 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
556 $ hg bookmark
556 $ hg bookmark
557 * test 4:33f7f61e6c5e
557 * test 4:33f7f61e6c5e
558 $ hg unshelve
558 $ hg unshelve
559 unshelving change 'test'
559 unshelving change 'test'
560 $ hg bookmark
560 $ hg bookmark
561 * test 4:33f7f61e6c5e
561 * test 4:33f7f61e6c5e
562
562
563 shelve should still work even if mq is disabled
563 shelve should still work even if mq is disabled
564
564
565 $ hg --config extensions.mq=! shelve
565 $ hg --config extensions.mq=! shelve
566 shelved as test
566 shelved as test
567 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
567 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
568 $ hg --config extensions.mq=! shelve --list
568 $ hg --config extensions.mq=! shelve --list
569 test (*)* changes to: create conflict (glob)
569 test (*)* changes to: create conflict (glob)
570 $ hg bookmark
570 $ hg bookmark
571 * test 4:33f7f61e6c5e
571 * test 4:33f7f61e6c5e
572 $ hg --config extensions.mq=! unshelve
572 $ hg --config extensions.mq=! unshelve
573 unshelving change 'test'
573 unshelving change 'test'
574 $ hg bookmark
574 $ hg bookmark
575 * test 4:33f7f61e6c5e
575 * test 4:33f7f61e6c5e
576
576
577 shelve should leave dirstate clean (issue4055)
577 shelve should leave dirstate clean (issue4055)
578
578
579 $ cd ..
579 $ cd ..
580 $ hg init shelverebase
580 $ hg init shelverebase
581 $ cd shelverebase
581 $ cd shelverebase
582 $ printf 'x\ny\n' > x
582 $ printf 'x\ny\n' > x
583 $ echo z > z
583 $ echo z > z
584 $ hg commit -Aqm xy
584 $ hg commit -Aqm xy
585 $ echo z >> x
585 $ echo z >> x
586 $ hg commit -Aqm z
586 $ hg commit -Aqm z
587 $ hg up 0
587 $ hg up 0
588 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
588 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
589 $ printf 'a\nx\ny\nz\n' > x
589 $ printf 'a\nx\ny\nz\n' > x
590 $ hg commit -Aqm xyz
590 $ hg commit -Aqm xyz
591 $ echo c >> z
591 $ echo c >> z
592 $ hg shelve
592 $ hg shelve
593 shelved as default
593 shelved as default
594 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
594 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
595 $ hg rebase -d 1 --config extensions.rebase=
595 $ hg rebase -d 1 --config extensions.rebase=
596 rebasing 2:323bfa07f744 "xyz" (tip)
596 rebasing 2:323bfa07f744 "xyz" (tip)
597 merging x
597 merging x
598 saved backup bundle to $TESTTMP/shelverebase/.hg/strip-backup/323bfa07f744-78114325-backup.hg (glob)
598 saved backup bundle to $TESTTMP/shelverebase/.hg/strip-backup/323bfa07f744-78114325-backup.hg (glob)
599 $ hg unshelve
599 $ hg unshelve
600 unshelving change 'default'
600 unshelving change 'default'
601 rebasing shelved changes
601 rebasing shelved changes
602 rebasing 4:82a0d7d6ba61 "changes to: xyz" (tip)
602 rebasing 4:82a0d7d6ba61 "changes to: xyz" (tip)
603 $ hg status
603 $ hg status
604 M z
604 M z
605
605
606 $ cd ..
606 $ cd ..
607
607
608 shelve should only unshelve pending changes (issue4068)
608 shelve should only unshelve pending changes (issue4068)
609
609
610 $ hg init onlypendingchanges
610 $ hg init onlypendingchanges
611 $ cd onlypendingchanges
611 $ cd onlypendingchanges
612 $ touch a
612 $ touch a
613 $ hg ci -Aqm a
613 $ hg ci -Aqm a
614 $ touch b
614 $ touch b
615 $ hg ci -Aqm b
615 $ hg ci -Aqm b
616 $ hg up -q 0
616 $ hg up -q 0
617 $ touch c
617 $ touch c
618 $ hg ci -Aqm c
618 $ hg ci -Aqm c
619
619
620 $ touch d
620 $ touch d
621 $ hg add d
621 $ hg add d
622 $ hg shelve
622 $ hg shelve
623 shelved as default
623 shelved as default
624 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
624 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
625 $ hg up -q 1
625 $ hg up -q 1
626 $ hg unshelve
626 $ hg unshelve
627 unshelving change 'default'
627 unshelving change 'default'
628 rebasing shelved changes
628 rebasing shelved changes
629 rebasing 3:958bcbd1776e "changes to: c" (tip)
629 rebasing 3:958bcbd1776e "changes to: c" (tip)
630 $ hg status
630 $ hg status
631 A d
631 A d
632
632
633 unshelve should work on an ancestor of the original commit
633 unshelve should work on an ancestor of the original commit
634
634
635 $ hg shelve
635 $ hg shelve
636 shelved as default
636 shelved as default
637 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
637 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
638 $ hg up 0
638 $ hg up 0
639 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
639 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
640 $ hg unshelve
640 $ hg unshelve
641 unshelving change 'default'
641 unshelving change 'default'
642 rebasing shelved changes
642 rebasing shelved changes
643 rebasing 3:013284d9655e "changes to: b" (tip)
643 rebasing 3:013284d9655e "changes to: b" (tip)
644 $ hg status
644 $ hg status
645 A d
645 A d
646
646
647 test bug 4073 we need to enable obsolete markers for it
647 test bug 4073 we need to enable obsolete markers for it
648
648
649 $ cat >> $HGRCPATH << EOF
649 $ cat >> $HGRCPATH << EOF
650 > [experimental]
650 > [experimental]
651 > evolution=createmarkers
651 > evolution=createmarkers
652 > EOF
652 > EOF
653 $ hg shelve
653 $ hg shelve
654 shelved as default
654 shelved as default
655 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
655 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
656 $ hg debugobsolete `hg --debug id -i -r 1`
656 $ hg debugobsolete `hg --debug id -i -r 1`
657 $ hg unshelve
657 $ hg unshelve
658 unshelving change 'default'
658 unshelving change 'default'
659
659
660 unshelve should leave unknown files alone (issue4113)
660 unshelve should leave unknown files alone (issue4113)
661
661
662 $ echo e > e
662 $ echo e > e
663 $ hg shelve
663 $ hg shelve
664 shelved as default
664 shelved as default
665 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
665 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
666 $ hg status
666 $ hg status
667 ? e
667 ? e
668 $ hg unshelve
668 $ hg unshelve
669 unshelving change 'default'
669 unshelving change 'default'
670 $ hg status
670 $ hg status
671 A d
671 A d
672 ? e
672 ? e
673 $ cat e
673 $ cat e
674 e
674 e
675
675
676 unshelve should keep a copy of unknown files
676 unshelve should keep a copy of unknown files
677
677
678 $ hg add e
678 $ hg add e
679 $ hg shelve
679 $ hg shelve
680 shelved as default
680 shelved as default
681 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
681 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
682 $ echo z > e
682 $ echo z > e
683 $ hg unshelve
683 $ hg unshelve
684 unshelving change 'default'
684 unshelving change 'default'
685 $ cat e
685 $ cat e
686 e
686 e
687 $ cat e.orig
687 $ cat e.orig
688 z
688 z
689
689
690
690
691 unshelve and conflicts with tracked and untracked files
691 unshelve and conflicts with tracked and untracked files
692
692
693 preparing:
693 preparing:
694
694
695 $ rm *.orig
695 $ rm *.orig
696 $ hg ci -qm 'commit stuff'
696 $ hg ci -qm 'commit stuff'
697 $ hg phase -p null:
697 $ hg phase -p null:
698
698
699 no other changes - no merge:
699 no other changes - no merge:
700
700
701 $ echo f > f
701 $ echo f > f
702 $ hg add f
702 $ hg add f
703 $ hg shelve
703 $ hg shelve
704 shelved as default
704 shelved as default
705 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
705 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
706 $ echo g > f
706 $ echo g > f
707 $ hg unshelve
707 $ hg unshelve
708 unshelving change 'default'
708 unshelving change 'default'
709 $ hg st
709 $ hg st
710 A f
710 A f
711 ? f.orig
711 ? f.orig
712 $ cat f
712 $ cat f
713 f
713 f
714 $ cat f.orig
714 $ cat f.orig
715 g
715 g
716
716
717 other uncommitted changes - merge:
717 other uncommitted changes - merge:
718
718
719 $ hg st
719 $ hg st
720 A f
720 A f
721 ? f.orig
721 ? f.orig
722 $ hg shelve
722 $ hg shelve
723 shelved as default
723 shelved as default
724 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
724 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
725 $ hg log -G --template '{rev} {desc|firstline} {author}' -R bundle://.hg/shelved/default.hg -r 'bundle()'
725 $ hg log -G --template '{rev} {desc|firstline} {author}' -R bundle://.hg/shelved/default.hg -r 'bundle()'
726 o 4 changes to: commit stuff shelve@localhost
726 o 4 changes to: commit stuff shelve@localhost
727 |
727 |
728 ~
728 ~
729 $ hg log -G --template '{rev} {desc|firstline} {author}'
729 $ hg log -G --template '{rev} {desc|firstline} {author}'
730 @ 3 commit stuff test
730 @ 3 commit stuff test
731 |
731 |
732 | o 2 c test
732 | o 2 c test
733 |/
733 |/
734 o 0 a test
734 o 0 a test
735
735
736 $ mv f.orig f
736 $ mv f.orig f
737 $ echo 1 > a
737 $ echo 1 > a
738 $ hg unshelve --date '1073741824 0'
738 $ hg unshelve --date '1073741824 0'
739 unshelving change 'default'
739 unshelving change 'default'
740 temporarily committing pending changes (restore with 'hg unshelve --abort')
740 temporarily committing pending changes (restore with 'hg unshelve --abort')
741 rebasing shelved changes
741 rebasing shelved changes
742 rebasing 5:81152db69da7 "changes to: commit stuff" (tip)
742 rebasing 5:81152db69da7 "changes to: commit stuff" (tip)
743 merging f
743 merging f
744 warning: conflicts while merging f! (edit, then use 'hg resolve --mark')
744 warning: conflicts while merging f! (edit, then use 'hg resolve --mark')
745 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
745 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
746 [1]
746 [1]
747 $ hg log -G --template '{rev} {desc|firstline} {author} {date|isodate}'
747 $ hg log -G --template '{rev} {desc|firstline} {author} {date|isodate}'
748 @ 5 changes to: commit stuff shelve@localhost 1970-01-01 00:00 +0000
748 @ 5 changes to: commit stuff shelve@localhost 1970-01-01 00:00 +0000
749 |
749 |
750 | @ 4 pending changes temporary commit shelve@localhost 2004-01-10 13:37 +0000
750 | @ 4 pending changes temporary commit shelve@localhost 2004-01-10 13:37 +0000
751 |/
751 |/
752 o 3 commit stuff test 1970-01-01 00:00 +0000
752 o 3 commit stuff test 1970-01-01 00:00 +0000
753 |
753 |
754 | o 2 c test 1970-01-01 00:00 +0000
754 | o 2 c test 1970-01-01 00:00 +0000
755 |/
755 |/
756 o 0 a test 1970-01-01 00:00 +0000
756 o 0 a test 1970-01-01 00:00 +0000
757
757
758 $ hg st
758 $ hg st
759 M f
759 M f
760 ? f.orig
760 ? f.orig
761 $ cat f
761 $ cat f
762 <<<<<<< dest: 5f6b880e719b - shelve: pending changes temporary commit
762 <<<<<<< dest: 5f6b880e719b - shelve: pending changes temporary commit
763 g
763 g
764 =======
764 =======
765 f
765 f
766 >>>>>>> source: 81152db69da7 - shelve: changes to: commit stuff
766 >>>>>>> source: 81152db69da7 - shelve: changes to: commit stuff
767 $ cat f.orig
767 $ cat f.orig
768 g
768 g
769 $ hg unshelve --abort -t false
769 $ hg unshelve --abort -t false
770 tool option will be ignored
770 tool option will be ignored
771 rebase aborted
771 rebase aborted
772 unshelve of 'default' aborted
772 unshelve of 'default' aborted
773 $ hg st
773 $ hg st
774 M a
774 M a
775 ? f.orig
775 ? f.orig
776 $ cat f.orig
776 $ cat f.orig
777 g
777 g
778 $ hg unshelve
778 $ hg unshelve
779 unshelving change 'default'
779 unshelving change 'default'
780 temporarily committing pending changes (restore with 'hg unshelve --abort')
780 temporarily committing pending changes (restore with 'hg unshelve --abort')
781 rebasing shelved changes
781 rebasing shelved changes
782 rebasing 5:81152db69da7 "changes to: commit stuff" (tip)
782 rebasing 5:81152db69da7 "changes to: commit stuff" (tip)
783 $ hg st
783 $ hg st
784 M a
784 M a
785 A f
785 A f
786 ? f.orig
786 ? f.orig
787
787
788 other committed changes - merge:
788 other committed changes - merge:
789
789
790 $ hg shelve f
790 $ hg shelve f
791 shelved as default
791 shelved as default
792 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
792 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
793 $ hg ci a -m 'intermediate other change'
793 $ hg ci a -m 'intermediate other change'
794 $ mv f.orig f
794 $ mv f.orig f
795 $ hg unshelve
795 $ hg unshelve
796 unshelving change 'default'
796 unshelving change 'default'
797 rebasing shelved changes
797 rebasing shelved changes
798 rebasing 5:81152db69da7 "changes to: commit stuff" (tip)
798 rebasing 5:81152db69da7 "changes to: commit stuff" (tip)
799 merging f
799 merging f
800 warning: conflicts while merging f! (edit, then use 'hg resolve --mark')
800 warning: conflicts while merging f! (edit, then use 'hg resolve --mark')
801 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
801 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
802 [1]
802 [1]
803 $ hg st
803 $ hg st
804 M f
804 M f
805 ? f.orig
805 ? f.orig
806 $ cat f
806 $ cat f
807 <<<<<<< dest: * - test: intermediate other change (glob)
807 <<<<<<< dest: * - test: intermediate other change (glob)
808 g
808 g
809 =======
809 =======
810 f
810 f
811 >>>>>>> source: 81152db69da7 - shelve: changes to: commit stuff
811 >>>>>>> source: 81152db69da7 - shelve: changes to: commit stuff
812 $ cat f.orig
812 $ cat f.orig
813 g
813 g
814 $ hg unshelve --abort
814 $ hg unshelve --abort
815 rebase aborted
815 rebase aborted
816 unshelve of 'default' aborted
816 unshelve of 'default' aborted
817 $ hg st
817 $ hg st
818 ? f.orig
818 ? f.orig
819 $ cat f.orig
819 $ cat f.orig
820 g
820 g
821 $ hg shelve --delete default
821 $ hg shelve --delete default
822
822
823 Recreate some conflict again
823 Recreate some conflict again
824
824
825 $ cd ../repo
825 $ cd ../repo
826 $ hg up -C -r 3
826 $ hg up -C -r 3
827 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
827 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
828 (leaving bookmark test)
828 (leaving bookmark test)
829 $ echo y >> a/a
829 $ echo y >> a/a
830 $ hg shelve
830 $ hg shelve
831 shelved as default
831 shelved as default
832 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
832 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
833 $ hg up test
833 $ hg up test
834 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
834 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
835 (activating bookmark test)
835 (activating bookmark test)
836 $ hg bookmark
836 $ hg bookmark
837 * test 4:33f7f61e6c5e
837 * test 4:33f7f61e6c5e
838 $ hg unshelve
838 $ hg unshelve
839 unshelving change 'default'
839 unshelving change 'default'
840 rebasing shelved changes
840 rebasing shelved changes
841 rebasing 5:e42a7da90865 "changes to: second" (tip)
841 rebasing 5:e42a7da90865 "changes to: second" (tip)
842 merging a/a
842 merging a/a
843 warning: conflicts while merging a/a! (edit, then use 'hg resolve --mark')
843 warning: conflicts while merging a/a! (edit, then use 'hg resolve --mark')
844 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
844 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
845 [1]
845 [1]
846 $ hg bookmark
846 $ hg bookmark
847 test 4:33f7f61e6c5e
847 test 4:33f7f61e6c5e
848
848
849 Test that resolving all conflicts in one direction (so that the rebase
849 Test that resolving all conflicts in one direction (so that the rebase
850 is a no-op), works (issue4398)
850 is a no-op), works (issue4398)
851
851
852 $ hg revert -a -r .
852 $ hg revert -a -r .
853 reverting a/a (glob)
853 reverting a/a (glob)
854 $ hg resolve -m a/a
854 $ hg resolve -m a/a
855 (no more unresolved files)
855 (no more unresolved files)
856 continue: hg unshelve --continue
856 continue: hg unshelve --continue
857 $ hg unshelve -c
857 $ hg unshelve -c
858 rebasing 5:e42a7da90865 "changes to: second" (tip)
858 rebasing 5:e42a7da90865 "changes to: second" (tip)
859 note: rebase of 5:e42a7da90865 created no changes to commit
859 note: rebase of 5:e42a7da90865 created no changes to commit
860 unshelve of 'default' complete
860 unshelve of 'default' complete
861 $ hg bookmark
861 $ hg bookmark
862 * test 4:33f7f61e6c5e
862 * test 4:33f7f61e6c5e
863 $ hg diff
863 $ hg diff
864 $ hg status
864 $ hg status
865 ? a/a.orig
865 ? a/a.orig
866 ? foo/foo
866 ? foo/foo
867 $ hg summary
867 $ hg summary
868 parent: 4:33f7f61e6c5e tip
868 parent: 4:33f7f61e6c5e tip
869 create conflict
869 create conflict
870 branch: default
870 branch: default
871 bookmarks: *test
871 bookmarks: *test
872 commit: 2 unknown (clean)
872 commit: 2 unknown (clean)
873 update: (current)
873 update: (current)
874 phases: 5 draft
874 phases: 5 draft
875
875
876 $ hg shelve --delete --stat
876 $ hg shelve --delete --stat
877 abort: options '--delete' and '--stat' may not be used together
877 abort: options '--delete' and '--stat' may not be used together
878 [255]
878 [255]
879 $ hg shelve --delete --name NAME
879 $ hg shelve --delete --name NAME
880 abort: options '--delete' and '--name' may not be used together
880 abort: options '--delete' and '--name' may not be used together
881 [255]
881 [255]
882
882
883 Test interactive shelve
883 Test interactive shelve
884 $ cat <<EOF >> $HGRCPATH
884 $ cat <<EOF >> $HGRCPATH
885 > [ui]
885 > [ui]
886 > interactive = true
886 > interactive = true
887 > EOF
887 > EOF
888 $ echo 'a' >> a/b
888 $ echo 'a' >> a/b
889 $ cat a/a >> a/b
889 $ cat a/a >> a/b
890 $ echo 'x' >> a/b
890 $ echo 'x' >> a/b
891 $ mv a/b a/a
891 $ mv a/b a/a
892 $ echo 'a' >> foo/foo
892 $ echo 'a' >> foo/foo
893 $ hg st
893 $ hg st
894 M a/a
894 M a/a
895 ? a/a.orig
895 ? a/a.orig
896 ? foo/foo
896 ? foo/foo
897 $ cat a/a
897 $ cat a/a
898 a
898 a
899 a
899 a
900 c
900 c
901 x
901 x
902 x
902 x
903 $ cat foo/foo
903 $ cat foo/foo
904 foo
904 foo
905 a
905 a
906 $ hg shelve --interactive --config ui.interactive=false
906 $ hg shelve --interactive --config ui.interactive=false
907 abort: running non-interactively
907 abort: running non-interactively
908 [255]
908 [255]
909 $ hg shelve --interactive << EOF
909 $ hg shelve --interactive << EOF
910 > y
910 > y
911 > y
911 > y
912 > n
912 > n
913 > EOF
913 > EOF
914 diff --git a/a/a b/a/a
914 diff --git a/a/a b/a/a
915 2 hunks, 2 lines changed
915 2 hunks, 2 lines changed
916 examine changes to 'a/a'? [Ynesfdaq?] y
916 examine changes to 'a/a'? [Ynesfdaq?] y
917
917
918 @@ -1,3 +1,4 @@
918 @@ -1,3 +1,4 @@
919 +a
919 +a
920 a
920 a
921 c
921 c
922 x
922 x
923 record change 1/2 to 'a/a'? [Ynesfdaq?] y
923 record change 1/2 to 'a/a'? [Ynesfdaq?] y
924
924
925 @@ -1,3 +2,4 @@
925 @@ -1,3 +2,4 @@
926 a
926 a
927 c
927 c
928 x
928 x
929 +x
929 +x
930 record change 2/2 to 'a/a'? [Ynesfdaq?] n
930 record change 2/2 to 'a/a'? [Ynesfdaq?] n
931
931
932 shelved as test
932 shelved as test
933 merging a/a
933 merging a/a
934 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
934 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
935 $ cat a/a
935 $ cat a/a
936 a
936 a
937 c
937 c
938 x
938 x
939 x
939 x
940 $ cat foo/foo
940 $ cat foo/foo
941 foo
941 foo
942 a
942 a
943 $ hg st
943 $ hg st
944 M a/a
944 M a/a
945 ? foo/foo
945 ? foo/foo
946 $ hg bookmark
946 $ hg bookmark
947 * test 4:33f7f61e6c5e
947 * test 4:33f7f61e6c5e
948 $ hg unshelve
948 $ hg unshelve
949 unshelving change 'test'
949 unshelving change 'test'
950 temporarily committing pending changes (restore with 'hg unshelve --abort')
950 temporarily committing pending changes (restore with 'hg unshelve --abort')
951 rebasing shelved changes
951 rebasing shelved changes
952 rebasing 6:96a1354f65f6 "changes to: create conflict" (tip)
952 rebasing 6:96a1354f65f6 "changes to: create conflict" (tip)
953 merging a/a
953 merging a/a
954 $ hg bookmark
954 $ hg bookmark
955 * test 4:33f7f61e6c5e
955 * test 4:33f7f61e6c5e
956 $ cat a/a
956 $ cat a/a
957 a
957 a
958 a
958 a
959 c
959 c
960 x
960 x
961 x
961 x
962
962
963 shelve --patch and shelve --stat should work with a single valid shelfname
963 shelve --patch and shelve --stat should work with a single valid shelfname
964
964
965 $ hg up --clean .
965 $ hg up --clean .
966 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
966 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
967 (leaving bookmark test)
967 (leaving bookmark test)
968 $ hg shelve --list
968 $ hg shelve --list
969 $ echo 'patch a' > shelf-patch-a
969 $ echo 'patch a' > shelf-patch-a
970 $ hg add shelf-patch-a
970 $ hg add shelf-patch-a
971 $ hg shelve
971 $ hg shelve
972 shelved as default
972 shelved as default
973 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
973 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
974 $ echo 'patch b' > shelf-patch-b
974 $ echo 'patch b' > shelf-patch-b
975 $ hg add shelf-patch-b
975 $ hg add shelf-patch-b
976 $ hg shelve
976 $ hg shelve
977 shelved as default-01
977 shelved as default-01
978 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
978 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
979 $ hg shelve --patch default default-01
979 $ hg shelve --patch default default-01
980 abort: --patch expects a single shelf
980 abort: --patch expects a single shelf
981 [255]
981 [255]
982 $ hg shelve --stat default default-01
982 $ hg shelve --stat default default-01
983 abort: --stat expects a single shelf
983 abort: --stat expects a single shelf
984 [255]
984 [255]
985 $ hg shelve --patch default
985 $ hg shelve --patch default
986 default (*)* changes to: create conflict (glob)
986 default (*)* changes to: create conflict (glob)
987
987
988 diff --git a/shelf-patch-a b/shelf-patch-a
988 diff --git a/shelf-patch-a b/shelf-patch-a
989 new file mode 100644
989 new file mode 100644
990 --- /dev/null
990 --- /dev/null
991 +++ b/shelf-patch-a
991 +++ b/shelf-patch-a
992 @@ -0,0 +1,1 @@
992 @@ -0,0 +1,1 @@
993 +patch a
993 +patch a
994 $ hg shelve --stat default
994 $ hg shelve --stat default
995 default (*)* changes to: create conflict (glob)
995 default (*)* changes to: create conflict (glob)
996 shelf-patch-a | 1 +
996 shelf-patch-a | 1 +
997 1 files changed, 1 insertions(+), 0 deletions(-)
997 1 files changed, 1 insertions(+), 0 deletions(-)
998 $ hg shelve --patch nonexistentshelf
998 $ hg shelve --patch nonexistentshelf
999 abort: cannot find shelf nonexistentshelf
999 abort: cannot find shelf nonexistentshelf
1000 [255]
1000 [255]
1001 $ hg shelve --stat nonexistentshelf
1001 $ hg shelve --stat nonexistentshelf
1002 abort: cannot find shelf nonexistentshelf
1002 abort: cannot find shelf nonexistentshelf
1003 [255]
1003 [255]
1004
1004
1005 $ cd ..
1005 $ cd ..
1006
1006
1007 Shelve from general delta repo uses bundle2 on disk
1007 Shelve from general delta repo uses bundle2 on disk
1008 --------------------------------------------------
1008 --------------------------------------------------
1009
1009
1010 no general delta
1010 no general delta
1011
1011
1012 $ hg clone --pull repo bundle1 --config format.usegeneraldelta=0
1012 $ hg clone --pull repo bundle1 --config format.usegeneraldelta=0
1013 requesting all changes
1013 requesting all changes
1014 adding changesets
1014 adding changesets
1015 adding manifests
1015 adding manifests
1016 adding file changes
1016 adding file changes
1017 added 5 changesets with 8 changes to 6 files
1017 added 5 changesets with 8 changes to 6 files
1018 updating to branch default
1018 updating to branch default
1019 6 files updated, 0 files merged, 0 files removed, 0 files unresolved
1019 6 files updated, 0 files merged, 0 files removed, 0 files unresolved
1020 $ cd bundle1
1020 $ cd bundle1
1021 $ echo babar > jungle
1021 $ echo babar > jungle
1022 $ hg add jungle
1022 $ hg add jungle
1023 $ hg shelve
1023 $ hg shelve
1024 shelved as default
1024 shelved as default
1025 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1025 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1026 $ hg debugbundle .hg/shelved/*.hg
1026 $ hg debugbundle .hg/shelved/*.hg
1027 45993d65fe9dc3c6d8764b9c3b07fa831ee7d92d
1027 45993d65fe9dc3c6d8764b9c3b07fa831ee7d92d
1028 $ cd ..
1028 $ cd ..
1029
1029
1030 with general delta
1030 with general delta
1031
1031
1032 $ hg clone --pull repo bundle2 --config format.usegeneraldelta=1
1032 $ hg clone --pull repo bundle2 --config format.usegeneraldelta=1
1033 requesting all changes
1033 requesting all changes
1034 adding changesets
1034 adding changesets
1035 adding manifests
1035 adding manifests
1036 adding file changes
1036 adding file changes
1037 added 5 changesets with 8 changes to 6 files
1037 added 5 changesets with 8 changes to 6 files
1038 updating to branch default
1038 updating to branch default
1039 6 files updated, 0 files merged, 0 files removed, 0 files unresolved
1039 6 files updated, 0 files merged, 0 files removed, 0 files unresolved
1040 $ cd bundle2
1040 $ cd bundle2
1041 $ echo babar > jungle
1041 $ echo babar > jungle
1042 $ hg add jungle
1042 $ hg add jungle
1043 $ hg shelve
1043 $ hg shelve
1044 shelved as default
1044 shelved as default
1045 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1045 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1046 $ hg debugbundle .hg/shelved/*.hg
1046 $ hg debugbundle .hg/shelved/*.hg
1047 Stream params: sortdict([('Compression', 'BZ')])
1047 Stream params: sortdict([('Compression', 'BZ')])
1048 changegroup -- "sortdict([('version', '02')])"
1048 changegroup -- "sortdict([('version', '02'), ('nbchanges', '1')])"
1049 45993d65fe9dc3c6d8764b9c3b07fa831ee7d92d
1049 45993d65fe9dc3c6d8764b9c3b07fa831ee7d92d
1050 $ cd ..
1050 $ cd ..
1051
1051
1052 Test visibility of in-memory changes inside transaction to external hook
1052 Test visibility of in-memory changes inside transaction to external hook
1053 ------------------------------------------------------------------------
1053 ------------------------------------------------------------------------
1054
1054
1055 $ cd repo
1055 $ cd repo
1056
1056
1057 $ echo xxxx >> x
1057 $ echo xxxx >> x
1058 $ hg commit -m "#5: changes to invoke rebase"
1058 $ hg commit -m "#5: changes to invoke rebase"
1059
1059
1060 $ cat > $TESTTMP/checkvisibility.sh <<EOF
1060 $ cat > $TESTTMP/checkvisibility.sh <<EOF
1061 > echo "==== \$1:"
1061 > echo "==== \$1:"
1062 > hg parents --template "VISIBLE {rev}:{node|short}\n"
1062 > hg parents --template "VISIBLE {rev}:{node|short}\n"
1063 > # test that pending changes are hidden
1063 > # test that pending changes are hidden
1064 > unset HG_PENDING
1064 > unset HG_PENDING
1065 > hg parents --template "ACTUAL {rev}:{node|short}\n"
1065 > hg parents --template "ACTUAL {rev}:{node|short}\n"
1066 > echo "===="
1066 > echo "===="
1067 > EOF
1067 > EOF
1068
1068
1069 $ cat >> .hg/hgrc <<EOF
1069 $ cat >> .hg/hgrc <<EOF
1070 > [defaults]
1070 > [defaults]
1071 > # to fix hash id of temporary revisions
1071 > # to fix hash id of temporary revisions
1072 > unshelve = --date '0 0'
1072 > unshelve = --date '0 0'
1073 > EOF
1073 > EOF
1074
1074
1075 "hg unshelve" at REV5 implies steps below:
1075 "hg unshelve" at REV5 implies steps below:
1076
1076
1077 (1) commit changes in the working directory (REV6)
1077 (1) commit changes in the working directory (REV6)
1078 (2) unbundle shelved revision (REV7)
1078 (2) unbundle shelved revision (REV7)
1079 (3) rebase: merge REV7 into REV6 (REV6 => REV6, REV7)
1079 (3) rebase: merge REV7 into REV6 (REV6 => REV6, REV7)
1080 (4) rebase: commit merged revision (REV8)
1080 (4) rebase: commit merged revision (REV8)
1081 (5) rebase: update to REV6 (REV8 => REV6)
1081 (5) rebase: update to REV6 (REV8 => REV6)
1082 (6) update to REV5 (REV6 => REV5)
1082 (6) update to REV5 (REV6 => REV5)
1083 (7) abort transaction
1083 (7) abort transaction
1084
1084
1085 == test visibility to external preupdate hook
1085 == test visibility to external preupdate hook
1086
1086
1087 $ cat >> .hg/hgrc <<EOF
1087 $ cat >> .hg/hgrc <<EOF
1088 > [hooks]
1088 > [hooks]
1089 > preupdate.visibility = sh $TESTTMP/checkvisibility.sh preupdate
1089 > preupdate.visibility = sh $TESTTMP/checkvisibility.sh preupdate
1090 > EOF
1090 > EOF
1091
1091
1092 $ echo nnnn >> n
1092 $ echo nnnn >> n
1093
1093
1094 $ sh $TESTTMP/checkvisibility.sh before-unshelving
1094 $ sh $TESTTMP/checkvisibility.sh before-unshelving
1095 ==== before-unshelving:
1095 ==== before-unshelving:
1096 VISIBLE 5:703117a2acfb
1096 VISIBLE 5:703117a2acfb
1097 ACTUAL 5:703117a2acfb
1097 ACTUAL 5:703117a2acfb
1098 ====
1098 ====
1099
1099
1100 $ hg unshelve --keep default
1100 $ hg unshelve --keep default
1101 temporarily committing pending changes (restore with 'hg unshelve --abort')
1101 temporarily committing pending changes (restore with 'hg unshelve --abort')
1102 rebasing shelved changes
1102 rebasing shelved changes
1103 rebasing 7:206bf5d4f922 "changes to: create conflict" (tip)
1103 rebasing 7:206bf5d4f922 "changes to: create conflict" (tip)
1104 ==== preupdate:
1104 ==== preupdate:
1105 VISIBLE 6:66b86db80ee4
1105 VISIBLE 6:66b86db80ee4
1106 ACTUAL 5:703117a2acfb
1106 ACTUAL 5:703117a2acfb
1107 ====
1107 ====
1108 ==== preupdate:
1108 ==== preupdate:
1109 VISIBLE 8:a0e04704317e
1109 VISIBLE 8:a0e04704317e
1110 ACTUAL 5:703117a2acfb
1110 ACTUAL 5:703117a2acfb
1111 ====
1111 ====
1112 ==== preupdate:
1112 ==== preupdate:
1113 VISIBLE 6:66b86db80ee4
1113 VISIBLE 6:66b86db80ee4
1114 ACTUAL 5:703117a2acfb
1114 ACTUAL 5:703117a2acfb
1115 ====
1115 ====
1116
1116
1117 $ cat >> .hg/hgrc <<EOF
1117 $ cat >> .hg/hgrc <<EOF
1118 > [hooks]
1118 > [hooks]
1119 > preupdate.visibility =
1119 > preupdate.visibility =
1120 > EOF
1120 > EOF
1121
1121
1122 $ sh $TESTTMP/checkvisibility.sh after-unshelving
1122 $ sh $TESTTMP/checkvisibility.sh after-unshelving
1123 ==== after-unshelving:
1123 ==== after-unshelving:
1124 VISIBLE 5:703117a2acfb
1124 VISIBLE 5:703117a2acfb
1125 ACTUAL 5:703117a2acfb
1125 ACTUAL 5:703117a2acfb
1126 ====
1126 ====
1127
1127
1128 == test visibility to external update hook
1128 == test visibility to external update hook
1129
1129
1130 $ hg update -q -C 5
1130 $ hg update -q -C 5
1131
1131
1132 $ cat >> .hg/hgrc <<EOF
1132 $ cat >> .hg/hgrc <<EOF
1133 > [hooks]
1133 > [hooks]
1134 > update.visibility = sh $TESTTMP/checkvisibility.sh update
1134 > update.visibility = sh $TESTTMP/checkvisibility.sh update
1135 > EOF
1135 > EOF
1136
1136
1137 $ echo nnnn >> n
1137 $ echo nnnn >> n
1138
1138
1139 $ sh $TESTTMP/checkvisibility.sh before-unshelving
1139 $ sh $TESTTMP/checkvisibility.sh before-unshelving
1140 ==== before-unshelving:
1140 ==== before-unshelving:
1141 VISIBLE 5:703117a2acfb
1141 VISIBLE 5:703117a2acfb
1142 ACTUAL 5:703117a2acfb
1142 ACTUAL 5:703117a2acfb
1143 ====
1143 ====
1144
1144
1145 $ hg unshelve --keep default
1145 $ hg unshelve --keep default
1146 temporarily committing pending changes (restore with 'hg unshelve --abort')
1146 temporarily committing pending changes (restore with 'hg unshelve --abort')
1147 rebasing shelved changes
1147 rebasing shelved changes
1148 rebasing 7:206bf5d4f922 "changes to: create conflict" (tip)
1148 rebasing 7:206bf5d4f922 "changes to: create conflict" (tip)
1149 ==== update:
1149 ==== update:
1150 VISIBLE 6:66b86db80ee4
1150 VISIBLE 6:66b86db80ee4
1151 VISIBLE 7:206bf5d4f922
1151 VISIBLE 7:206bf5d4f922
1152 ACTUAL 5:703117a2acfb
1152 ACTUAL 5:703117a2acfb
1153 ====
1153 ====
1154 ==== update:
1154 ==== update:
1155 VISIBLE 6:66b86db80ee4
1155 VISIBLE 6:66b86db80ee4
1156 ACTUAL 5:703117a2acfb
1156 ACTUAL 5:703117a2acfb
1157 ====
1157 ====
1158 ==== update:
1158 ==== update:
1159 VISIBLE 5:703117a2acfb
1159 VISIBLE 5:703117a2acfb
1160 ACTUAL 5:703117a2acfb
1160 ACTUAL 5:703117a2acfb
1161 ====
1161 ====
1162
1162
1163 $ cat >> .hg/hgrc <<EOF
1163 $ cat >> .hg/hgrc <<EOF
1164 > [hooks]
1164 > [hooks]
1165 > update.visibility =
1165 > update.visibility =
1166 > EOF
1166 > EOF
1167
1167
1168 $ sh $TESTTMP/checkvisibility.sh after-unshelving
1168 $ sh $TESTTMP/checkvisibility.sh after-unshelving
1169 ==== after-unshelving:
1169 ==== after-unshelving:
1170 VISIBLE 5:703117a2acfb
1170 VISIBLE 5:703117a2acfb
1171 ACTUAL 5:703117a2acfb
1171 ACTUAL 5:703117a2acfb
1172 ====
1172 ====
1173
1173
1174 $ cd ..
1174 $ cd ..
1175
1175
1176 test .orig files go where the user wants them to
1176 test .orig files go where the user wants them to
1177 ---------------------------------------------------------------
1177 ---------------------------------------------------------------
1178 $ hg init salvage
1178 $ hg init salvage
1179 $ cd salvage
1179 $ cd salvage
1180 $ echo 'content' > root
1180 $ echo 'content' > root
1181 $ hg commit -A -m 'root' -q
1181 $ hg commit -A -m 'root' -q
1182 $ echo '' > root
1182 $ echo '' > root
1183 $ hg shelve -q
1183 $ hg shelve -q
1184 $ echo 'contADDent' > root
1184 $ echo 'contADDent' > root
1185 $ hg unshelve -q --config 'ui.origbackuppath=.hg/origbackups'
1185 $ hg unshelve -q --config 'ui.origbackuppath=.hg/origbackups'
1186 warning: conflicts while merging root! (edit, then use 'hg resolve --mark')
1186 warning: conflicts while merging root! (edit, then use 'hg resolve --mark')
1187 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
1187 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
1188 [1]
1188 [1]
1189 $ ls .hg/origbackups
1189 $ ls .hg/origbackups
1190 root.orig
1190 root.orig
1191 $ rm -rf .hg/origbackups
1191 $ rm -rf .hg/origbackups
1192
1192
1193 test Abort unshelve always gets user out of the unshelved state
1193 test Abort unshelve always gets user out of the unshelved state
1194 ---------------------------------------------------------------
1194 ---------------------------------------------------------------
1195 Wreak havoc on the unshelve process
1195 Wreak havoc on the unshelve process
1196 $ rm .hg/unshelverebasestate
1196 $ rm .hg/unshelverebasestate
1197 $ hg unshelve --abort
1197 $ hg unshelve --abort
1198 unshelve of 'default' aborted
1198 unshelve of 'default' aborted
1199 abort: (No such file or directory|The system cannot find the file specified) (re)
1199 abort: (No such file or directory|The system cannot find the file specified) (re)
1200 [255]
1200 [255]
1201 Can the user leave the current state?
1201 Can the user leave the current state?
1202 $ hg up -C .
1202 $ hg up -C .
1203 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1203 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1204
1204
1205 Try again but with a corrupted shelve state file
1205 Try again but with a corrupted shelve state file
1206 $ hg strip -r 2 -r 1 -q
1206 $ hg strip -r 2 -r 1 -q
1207 $ hg up -r 0 -q
1207 $ hg up -r 0 -q
1208 $ echo '' > root
1208 $ echo '' > root
1209 $ hg shelve -q
1209 $ hg shelve -q
1210 $ echo 'contADDent' > root
1210 $ echo 'contADDent' > root
1211 $ hg unshelve -q
1211 $ hg unshelve -q
1212 warning: conflicts while merging root! (edit, then use 'hg resolve --mark')
1212 warning: conflicts while merging root! (edit, then use 'hg resolve --mark')
1213 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
1213 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
1214 [1]
1214 [1]
1215 $ sed 's/ae8c668541e8/123456789012/' .hg/shelvedstate > ../corrupt-shelvedstate
1215 $ sed 's/ae8c668541e8/123456789012/' .hg/shelvedstate > ../corrupt-shelvedstate
1216 $ mv ../corrupt-shelvedstate .hg/histedit-state
1216 $ mv ../corrupt-shelvedstate .hg/histedit-state
1217 $ hg unshelve --abort 2>&1 | grep 'rebase aborted'
1217 $ hg unshelve --abort 2>&1 | grep 'rebase aborted'
1218 rebase aborted
1218 rebase aborted
1219 $ hg up -C .
1219 $ hg up -C .
1220 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1220 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1221
1221
1222 $ cd ..
1222 $ cd ..
1223
1223
1224 Keep active bookmark while (un)shelving even on shared repo (issue4940)
1224 Keep active bookmark while (un)shelving even on shared repo (issue4940)
1225 -----------------------------------------------------------------------
1225 -----------------------------------------------------------------------
1226
1226
1227 $ cat <<EOF >> $HGRCPATH
1227 $ cat <<EOF >> $HGRCPATH
1228 > [extensions]
1228 > [extensions]
1229 > share =
1229 > share =
1230 > EOF
1230 > EOF
1231
1231
1232 $ hg bookmarks -R repo
1232 $ hg bookmarks -R repo
1233 test 4:33f7f61e6c5e
1233 test 4:33f7f61e6c5e
1234 $ hg share -B repo share
1234 $ hg share -B repo share
1235 updating working directory
1235 updating working directory
1236 6 files updated, 0 files merged, 0 files removed, 0 files unresolved
1236 6 files updated, 0 files merged, 0 files removed, 0 files unresolved
1237 $ cd share
1237 $ cd share
1238
1238
1239 $ hg bookmarks
1239 $ hg bookmarks
1240 test 4:33f7f61e6c5e
1240 test 4:33f7f61e6c5e
1241 $ hg bookmarks foo
1241 $ hg bookmarks foo
1242 $ hg bookmarks
1242 $ hg bookmarks
1243 * foo 5:703117a2acfb
1243 * foo 5:703117a2acfb
1244 test 4:33f7f61e6c5e
1244 test 4:33f7f61e6c5e
1245 $ echo x >> x
1245 $ echo x >> x
1246 $ hg shelve
1246 $ hg shelve
1247 shelved as foo
1247 shelved as foo
1248 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1248 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1249 $ hg bookmarks
1249 $ hg bookmarks
1250 * foo 5:703117a2acfb
1250 * foo 5:703117a2acfb
1251 test 4:33f7f61e6c5e
1251 test 4:33f7f61e6c5e
1252
1252
1253 $ hg unshelve
1253 $ hg unshelve
1254 unshelving change 'foo'
1254 unshelving change 'foo'
1255 $ hg bookmarks
1255 $ hg bookmarks
1256 * foo 5:703117a2acfb
1256 * foo 5:703117a2acfb
1257 test 4:33f7f61e6c5e
1257 test 4:33f7f61e6c5e
1258
1258
1259 $ cd ..
1259 $ cd ..
1260
1260
1261 Shelve and unshelve unknown files. For the purposes of unshelve, a shelved
1261 Shelve and unshelve unknown files. For the purposes of unshelve, a shelved
1262 unknown file is the same as a shelved added file, except that it will be in
1262 unknown file is the same as a shelved added file, except that it will be in
1263 unknown state after unshelve if and only if it was either absent or unknown
1263 unknown state after unshelve if and only if it was either absent or unknown
1264 before the unshelve operation.
1264 before the unshelve operation.
1265
1265
1266 $ hg init unknowns
1266 $ hg init unknowns
1267 $ cd unknowns
1267 $ cd unknowns
1268
1268
1269 The simplest case is if I simply have an unknown file that I shelve and unshelve
1269 The simplest case is if I simply have an unknown file that I shelve and unshelve
1270
1270
1271 $ echo unknown > unknown
1271 $ echo unknown > unknown
1272 $ hg status
1272 $ hg status
1273 ? unknown
1273 ? unknown
1274 $ hg shelve --unknown
1274 $ hg shelve --unknown
1275 shelved as default
1275 shelved as default
1276 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1276 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1277 $ hg status
1277 $ hg status
1278 $ hg unshelve
1278 $ hg unshelve
1279 unshelving change 'default'
1279 unshelving change 'default'
1280 $ hg status
1280 $ hg status
1281 ? unknown
1281 ? unknown
1282 $ rm unknown
1282 $ rm unknown
1283
1283
1284 If I shelve, add the file, and unshelve, does it stay added?
1284 If I shelve, add the file, and unshelve, does it stay added?
1285
1285
1286 $ echo unknown > unknown
1286 $ echo unknown > unknown
1287 $ hg shelve -u
1287 $ hg shelve -u
1288 shelved as default
1288 shelved as default
1289 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1289 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1290 $ hg status
1290 $ hg status
1291 $ touch unknown
1291 $ touch unknown
1292 $ hg add unknown
1292 $ hg add unknown
1293 $ hg status
1293 $ hg status
1294 A unknown
1294 A unknown
1295 $ hg unshelve
1295 $ hg unshelve
1296 unshelving change 'default'
1296 unshelving change 'default'
1297 temporarily committing pending changes (restore with 'hg unshelve --abort')
1297 temporarily committing pending changes (restore with 'hg unshelve --abort')
1298 rebasing shelved changes
1298 rebasing shelved changes
1299 rebasing 1:098df96e7410 "(changes in empty repository)" (tip)
1299 rebasing 1:098df96e7410 "(changes in empty repository)" (tip)
1300 merging unknown
1300 merging unknown
1301 $ hg status
1301 $ hg status
1302 A unknown
1302 A unknown
1303 $ hg forget unknown
1303 $ hg forget unknown
1304 $ rm unknown
1304 $ rm unknown
1305
1305
1306 And if I shelve, commit, then unshelve, does it become modified?
1306 And if I shelve, commit, then unshelve, does it become modified?
1307
1307
1308 $ echo unknown > unknown
1308 $ echo unknown > unknown
1309 $ hg shelve -u
1309 $ hg shelve -u
1310 shelved as default
1310 shelved as default
1311 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1311 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1312 $ hg status
1312 $ hg status
1313 $ touch unknown
1313 $ touch unknown
1314 $ hg add unknown
1314 $ hg add unknown
1315 $ hg commit -qm "Add unknown"
1315 $ hg commit -qm "Add unknown"
1316 $ hg status
1316 $ hg status
1317 $ hg unshelve
1317 $ hg unshelve
1318 unshelving change 'default'
1318 unshelving change 'default'
1319 rebasing shelved changes
1319 rebasing shelved changes
1320 rebasing 1:098df96e7410 "(changes in empty repository)" (tip)
1320 rebasing 1:098df96e7410 "(changes in empty repository)" (tip)
1321 merging unknown
1321 merging unknown
1322 $ hg status
1322 $ hg status
1323 M unknown
1323 M unknown
1324 $ hg remove --force unknown
1324 $ hg remove --force unknown
1325 $ hg commit -qm "Remove unknown"
1325 $ hg commit -qm "Remove unknown"
1326
1326
1327 $ cd ..
1327 $ cd ..
1328
1328
1329 We expects that non-bare shelve keeps newly created branch in
1329 We expects that non-bare shelve keeps newly created branch in
1330 working directory.
1330 working directory.
1331
1331
1332 $ hg init shelve-preserve-new-branch
1332 $ hg init shelve-preserve-new-branch
1333 $ cd shelve-preserve-new-branch
1333 $ cd shelve-preserve-new-branch
1334 $ echo "a" >> a
1334 $ echo "a" >> a
1335 $ hg add a
1335 $ hg add a
1336 $ echo "b" >> b
1336 $ echo "b" >> b
1337 $ hg add b
1337 $ hg add b
1338 $ hg commit -m "ab"
1338 $ hg commit -m "ab"
1339 $ echo "aa" >> a
1339 $ echo "aa" >> a
1340 $ echo "bb" >> b
1340 $ echo "bb" >> b
1341 $ hg branch new-branch
1341 $ hg branch new-branch
1342 marked working directory as branch new-branch
1342 marked working directory as branch new-branch
1343 (branches are permanent and global, did you want a bookmark?)
1343 (branches are permanent and global, did you want a bookmark?)
1344 $ hg status
1344 $ hg status
1345 M a
1345 M a
1346 M b
1346 M b
1347 $ hg branch
1347 $ hg branch
1348 new-branch
1348 new-branch
1349 $ hg shelve a
1349 $ hg shelve a
1350 shelved as default
1350 shelved as default
1351 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1351 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1352 $ hg branch
1352 $ hg branch
1353 new-branch
1353 new-branch
1354 $ hg status
1354 $ hg status
1355 M b
1355 M b
1356 $ touch "c" >> c
1356 $ touch "c" >> c
1357 $ hg add c
1357 $ hg add c
1358 $ hg status
1358 $ hg status
1359 M b
1359 M b
1360 A c
1360 A c
1361 $ hg shelve --exclude c
1361 $ hg shelve --exclude c
1362 shelved as default-01
1362 shelved as default-01
1363 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1363 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1364 $ hg branch
1364 $ hg branch
1365 new-branch
1365 new-branch
1366 $ hg status
1366 $ hg status
1367 A c
1367 A c
1368 $ hg shelve --include c
1368 $ hg shelve --include c
1369 shelved as default-02
1369 shelved as default-02
1370 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1370 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1371 $ hg branch
1371 $ hg branch
1372 new-branch
1372 new-branch
1373 $ hg status
1373 $ hg status
1374 $ echo "d" >> d
1374 $ echo "d" >> d
1375 $ hg add d
1375 $ hg add d
1376 $ hg status
1376 $ hg status
1377 A d
1377 A d
1378
1378
1379 We expect that bare-shelve will not keep branch in current working directory.
1379 We expect that bare-shelve will not keep branch in current working directory.
1380
1380
1381 $ hg shelve
1381 $ hg shelve
1382 shelved as default-03
1382 shelved as default-03
1383 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1383 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1384 $ hg branch
1384 $ hg branch
1385 default
1385 default
1386
1386
1387 When i shelve commit on newly created branch i expect
1387 When i shelve commit on newly created branch i expect
1388 that after unshelve newly created branch will be preserved.
1388 that after unshelve newly created branch will be preserved.
1389
1389
1390 $ hg init shelve_on_new_branch_simple
1390 $ hg init shelve_on_new_branch_simple
1391 $ cd shelve_on_new_branch_simple
1391 $ cd shelve_on_new_branch_simple
1392 $ echo "aaa" >> a
1392 $ echo "aaa" >> a
1393 $ hg commit -A -m "a"
1393 $ hg commit -A -m "a"
1394 adding a
1394 adding a
1395 $ hg branch
1395 $ hg branch
1396 default
1396 default
1397 $ hg branch test
1397 $ hg branch test
1398 marked working directory as branch test
1398 marked working directory as branch test
1399 (branches are permanent and global, did you want a bookmark?)
1399 (branches are permanent and global, did you want a bookmark?)
1400 $ echo "bbb" >> a
1400 $ echo "bbb" >> a
1401 $ hg status
1401 $ hg status
1402 M a
1402 M a
1403 $ hg shelve
1403 $ hg shelve
1404 shelved as default
1404 shelved as default
1405 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1405 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1406 $ hg branch
1406 $ hg branch
1407 default
1407 default
1408 $ echo "bbb" >> b
1408 $ echo "bbb" >> b
1409 $ hg status
1409 $ hg status
1410 ? b
1410 ? b
1411 $ hg unshelve
1411 $ hg unshelve
1412 unshelving change 'default'
1412 unshelving change 'default'
1413 marked working directory as branch test
1413 marked working directory as branch test
1414 $ hg status
1414 $ hg status
1415 M a
1415 M a
1416 ? b
1416 ? b
1417 $ hg branch
1417 $ hg branch
1418 test
1418 test
1419
1419
1420 When i shelve commit on newly created branch, make
1420 When i shelve commit on newly created branch, make
1421 some changes, unshelve it and running into merge
1421 some changes, unshelve it and running into merge
1422 conflicts i expect that after fixing them and
1422 conflicts i expect that after fixing them and
1423 running unshelve --continue newly created branch
1423 running unshelve --continue newly created branch
1424 will be preserved.
1424 will be preserved.
1425
1425
1426 $ hg init shelve_on_new_branch_conflict
1426 $ hg init shelve_on_new_branch_conflict
1427 $ cd shelve_on_new_branch_conflict
1427 $ cd shelve_on_new_branch_conflict
1428 $ echo "aaa" >> a
1428 $ echo "aaa" >> a
1429 $ hg commit -A -m "a"
1429 $ hg commit -A -m "a"
1430 adding a
1430 adding a
1431 $ hg branch
1431 $ hg branch
1432 default
1432 default
1433 $ hg branch test
1433 $ hg branch test
1434 marked working directory as branch test
1434 marked working directory as branch test
1435 (branches are permanent and global, did you want a bookmark?)
1435 (branches are permanent and global, did you want a bookmark?)
1436 $ echo "bbb" >> a
1436 $ echo "bbb" >> a
1437 $ hg status
1437 $ hg status
1438 M a
1438 M a
1439 $ hg shelve
1439 $ hg shelve
1440 shelved as default
1440 shelved as default
1441 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1441 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1442 $ hg branch
1442 $ hg branch
1443 default
1443 default
1444 $ echo "ccc" >> a
1444 $ echo "ccc" >> a
1445 $ hg status
1445 $ hg status
1446 M a
1446 M a
1447 $ hg unshelve
1447 $ hg unshelve
1448 unshelving change 'default'
1448 unshelving change 'default'
1449 temporarily committing pending changes (restore with 'hg unshelve --abort')
1449 temporarily committing pending changes (restore with 'hg unshelve --abort')
1450 rebasing shelved changes
1450 rebasing shelved changes
1451 rebasing 2:425c97ef07f3 "changes to: a" (tip)
1451 rebasing 2:425c97ef07f3 "changes to: a" (tip)
1452 merging a
1452 merging a
1453 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
1453 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
1454 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
1454 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
1455 [1]
1455 [1]
1456 $ echo "aaabbbccc" > a
1456 $ echo "aaabbbccc" > a
1457 $ rm a.orig
1457 $ rm a.orig
1458 $ hg resolve --mark a
1458 $ hg resolve --mark a
1459 (no more unresolved files)
1459 (no more unresolved files)
1460 continue: hg unshelve --continue
1460 continue: hg unshelve --continue
1461 $ hg unshelve --continue
1461 $ hg unshelve --continue
1462 rebasing 2:425c97ef07f3 "changes to: a" (tip)
1462 rebasing 2:425c97ef07f3 "changes to: a" (tip)
1463 marked working directory as branch test
1463 marked working directory as branch test
1464 unshelve of 'default' complete
1464 unshelve of 'default' complete
1465 $ cat a
1465 $ cat a
1466 aaabbbccc
1466 aaabbbccc
1467 $ hg status
1467 $ hg status
1468 M a
1468 M a
1469 $ hg branch
1469 $ hg branch
1470 test
1470 test
1471 $ hg commit -m "test-commit"
1471 $ hg commit -m "test-commit"
1472
1472
1473 When i shelve on test branch, update to default branch
1473 When i shelve on test branch, update to default branch
1474 and unshelve i expect that it will not preserve previous
1474 and unshelve i expect that it will not preserve previous
1475 test branch.
1475 test branch.
1476
1476
1477 $ echo "xxx" > b
1477 $ echo "xxx" > b
1478 $ hg add b
1478 $ hg add b
1479 $ hg shelve
1479 $ hg shelve
1480 shelved as test
1480 shelved as test
1481 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1481 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1482 $ hg update -r default
1482 $ hg update -r default
1483 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1483 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1484 $ hg unshelve
1484 $ hg unshelve
1485 unshelving change 'test'
1485 unshelving change 'test'
1486 rebasing shelved changes
1486 rebasing shelved changes
1487 rebasing 2:357525f34729 "changes to: test-commit" (tip)
1487 rebasing 2:357525f34729 "changes to: test-commit" (tip)
1488 $ hg status
1488 $ hg status
1489 A b
1489 A b
1490 $ hg branch
1490 $ hg branch
1491 default
1491 default
1492
1492
1493 When i unshelve resulting in merge conflicts and makes saved
1493 When i unshelve resulting in merge conflicts and makes saved
1494 file shelvedstate looks like in previous versions in
1494 file shelvedstate looks like in previous versions in
1495 mercurial(without restore branch information in 7th line) i
1495 mercurial(without restore branch information in 7th line) i
1496 expect that after resolving conflicts and succesfully
1496 expect that after resolving conflicts and succesfully
1497 running 'shelve --continue' the branch information won't be
1497 running 'shelve --continue' the branch information won't be
1498 restored and branch will be unchanged.
1498 restored and branch will be unchanged.
1499
1499
1500 shelve on new branch, conflict with previous shelvedstate
1500 shelve on new branch, conflict with previous shelvedstate
1501
1501
1502 $ hg init conflict
1502 $ hg init conflict
1503 $ cd conflict
1503 $ cd conflict
1504 $ echo "aaa" >> a
1504 $ echo "aaa" >> a
1505 $ hg commit -A -m "a"
1505 $ hg commit -A -m "a"
1506 adding a
1506 adding a
1507 $ hg branch
1507 $ hg branch
1508 default
1508 default
1509 $ hg branch test
1509 $ hg branch test
1510 marked working directory as branch test
1510 marked working directory as branch test
1511 (branches are permanent and global, did you want a bookmark?)
1511 (branches are permanent and global, did you want a bookmark?)
1512 $ echo "bbb" >> a
1512 $ echo "bbb" >> a
1513 $ hg status
1513 $ hg status
1514 M a
1514 M a
1515 $ hg shelve
1515 $ hg shelve
1516 shelved as default
1516 shelved as default
1517 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1517 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1518 $ hg branch
1518 $ hg branch
1519 default
1519 default
1520 $ echo "ccc" >> a
1520 $ echo "ccc" >> a
1521 $ hg status
1521 $ hg status
1522 M a
1522 M a
1523 $ hg unshelve
1523 $ hg unshelve
1524 unshelving change 'default'
1524 unshelving change 'default'
1525 temporarily committing pending changes (restore with 'hg unshelve --abort')
1525 temporarily committing pending changes (restore with 'hg unshelve --abort')
1526 rebasing shelved changes
1526 rebasing shelved changes
1527 rebasing 2:425c97ef07f3 "changes to: a" (tip)
1527 rebasing 2:425c97ef07f3 "changes to: a" (tip)
1528 merging a
1528 merging a
1529 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
1529 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
1530 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
1530 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
1531 [1]
1531 [1]
1532
1532
1533 Removing restore branch information from shelvedstate file(making it looks like
1533 Removing restore branch information from shelvedstate file(making it looks like
1534 in previous versions) and running unshelve --continue
1534 in previous versions) and running unshelve --continue
1535
1535
1536 $ head -n 6 < .hg/shelvedstate > .hg/shelvedstate_oldformat
1536 $ head -n 6 < .hg/shelvedstate > .hg/shelvedstate_oldformat
1537 $ rm .hg/shelvedstate
1537 $ rm .hg/shelvedstate
1538 $ mv .hg/shelvedstate_oldformat .hg/shelvedstate
1538 $ mv .hg/shelvedstate_oldformat .hg/shelvedstate
1539
1539
1540 $ echo "aaabbbccc" > a
1540 $ echo "aaabbbccc" > a
1541 $ rm a.orig
1541 $ rm a.orig
1542 $ hg resolve --mark a
1542 $ hg resolve --mark a
1543 (no more unresolved files)
1543 (no more unresolved files)
1544 continue: hg unshelve --continue
1544 continue: hg unshelve --continue
1545 $ hg unshelve --continue
1545 $ hg unshelve --continue
1546 rebasing 2:425c97ef07f3 "changes to: a" (tip)
1546 rebasing 2:425c97ef07f3 "changes to: a" (tip)
1547 unshelve of 'default' complete
1547 unshelve of 'default' complete
1548 $ cat a
1548 $ cat a
1549 aaabbbccc
1549 aaabbbccc
1550 $ hg status
1550 $ hg status
1551 M a
1551 M a
1552 $ hg branch
1552 $ hg branch
1553 default
1553 default
1554
1554
1555 On non bare shelve the branch information shouldn't be restored
1555 On non bare shelve the branch information shouldn't be restored
1556
1556
1557 $ hg init bare_shelve_on_new_branch
1557 $ hg init bare_shelve_on_new_branch
1558 $ cd bare_shelve_on_new_branch
1558 $ cd bare_shelve_on_new_branch
1559 $ echo "aaa" >> a
1559 $ echo "aaa" >> a
1560 $ hg commit -A -m "a"
1560 $ hg commit -A -m "a"
1561 adding a
1561 adding a
1562 $ hg branch
1562 $ hg branch
1563 default
1563 default
1564 $ hg branch test
1564 $ hg branch test
1565 marked working directory as branch test
1565 marked working directory as branch test
1566 (branches are permanent and global, did you want a bookmark?)
1566 (branches are permanent and global, did you want a bookmark?)
1567 $ echo "bbb" >> a
1567 $ echo "bbb" >> a
1568 $ hg status
1568 $ hg status
1569 M a
1569 M a
1570 $ hg shelve a
1570 $ hg shelve a
1571 shelved as default
1571 shelved as default
1572 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1572 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1573 $ hg branch
1573 $ hg branch
1574 test
1574 test
1575 $ hg branch default
1575 $ hg branch default
1576 marked working directory as branch default
1576 marked working directory as branch default
1577 (branches are permanent and global, did you want a bookmark?)
1577 (branches are permanent and global, did you want a bookmark?)
1578 $ echo "bbb" >> b
1578 $ echo "bbb" >> b
1579 $ hg status
1579 $ hg status
1580 ? b
1580 ? b
1581 $ hg unshelve
1581 $ hg unshelve
1582 unshelving change 'default'
1582 unshelving change 'default'
1583 $ hg status
1583 $ hg status
1584 M a
1584 M a
1585 ? b
1585 ? b
1586 $ hg branch
1586 $ hg branch
1587 default
1587 default
1588 $ cd ..
1588 $ cd ..
1589
1589
1590 Prepare unshleve with a corrupted shelvedstate
1590 Prepare unshleve with a corrupted shelvedstate
1591 $ hg init r1 && cd r1
1591 $ hg init r1 && cd r1
1592 $ echo text1 > file && hg add file
1592 $ echo text1 > file && hg add file
1593 $ hg shelve
1593 $ hg shelve
1594 shelved as default
1594 shelved as default
1595 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1595 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1596 $ echo text2 > file && hg ci -Am text1
1596 $ echo text2 > file && hg ci -Am text1
1597 adding file
1597 adding file
1598 $ hg unshelve
1598 $ hg unshelve
1599 unshelving change 'default'
1599 unshelving change 'default'
1600 rebasing shelved changes
1600 rebasing shelved changes
1601 rebasing 1:396ea74229f9 "(changes in empty repository)" (tip)
1601 rebasing 1:396ea74229f9 "(changes in empty repository)" (tip)
1602 merging file
1602 merging file
1603 warning: conflicts while merging file! (edit, then use 'hg resolve --mark')
1603 warning: conflicts while merging file! (edit, then use 'hg resolve --mark')
1604 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
1604 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
1605 [1]
1605 [1]
1606 $ echo somethingsomething > .hg/shelvedstate
1606 $ echo somethingsomething > .hg/shelvedstate
1607
1607
1608 Unshelve --continue fails with appropriate message if shelvedstate is corrupted
1608 Unshelve --continue fails with appropriate message if shelvedstate is corrupted
1609 $ hg unshelve --continue
1609 $ hg unshelve --continue
1610 abort: corrupted shelved state file
1610 abort: corrupted shelved state file
1611 (please run hg unshelve --abort to abort unshelve operation)
1611 (please run hg unshelve --abort to abort unshelve operation)
1612 [255]
1612 [255]
1613
1613
1614 Unshelve --abort works with a corrupted shelvedstate
1614 Unshelve --abort works with a corrupted shelvedstate
1615 $ hg unshelve --abort
1615 $ hg unshelve --abort
1616 could not read shelved state file, your working copy may be in an unexpected state
1616 could not read shelved state file, your working copy may be in an unexpected state
1617 please update to some commit
1617 please update to some commit
1618
1618
1619 Unshelve --abort fails with appropriate message if there's no unshelve in
1619 Unshelve --abort fails with appropriate message if there's no unshelve in
1620 progress
1620 progress
1621 $ hg unshelve --abort
1621 $ hg unshelve --abort
1622 abort: no unshelve in progress
1622 abort: no unshelve in progress
1623 [255]
1623 [255]
1624 $ cd ..
1624 $ cd ..
@@ -1,898 +1,898 b''
1 $ echo "[format]" >> $HGRCPATH
1 $ echo "[format]" >> $HGRCPATH
2 $ echo "usegeneraldelta=yes" >> $HGRCPATH
2 $ echo "usegeneraldelta=yes" >> $HGRCPATH
3 $ echo "[extensions]" >> $HGRCPATH
3 $ echo "[extensions]" >> $HGRCPATH
4 $ echo "strip=" >> $HGRCPATH
4 $ echo "strip=" >> $HGRCPATH
5
5
6 $ restore() {
6 $ restore() {
7 > hg unbundle -q .hg/strip-backup/*
7 > hg unbundle -q .hg/strip-backup/*
8 > rm .hg/strip-backup/*
8 > rm .hg/strip-backup/*
9 > }
9 > }
10 $ teststrip() {
10 $ teststrip() {
11 > hg up -C $1
11 > hg up -C $1
12 > echo % before update $1, strip $2
12 > echo % before update $1, strip $2
13 > hg parents
13 > hg parents
14 > hg --traceback strip $2
14 > hg --traceback strip $2
15 > echo % after update $1, strip $2
15 > echo % after update $1, strip $2
16 > hg parents
16 > hg parents
17 > restore
17 > restore
18 > }
18 > }
19
19
20 $ hg init test
20 $ hg init test
21 $ cd test
21 $ cd test
22
22
23 $ echo foo > bar
23 $ echo foo > bar
24 $ hg ci -Ama
24 $ hg ci -Ama
25 adding bar
25 adding bar
26
26
27 $ echo more >> bar
27 $ echo more >> bar
28 $ hg ci -Amb
28 $ hg ci -Amb
29
29
30 $ echo blah >> bar
30 $ echo blah >> bar
31 $ hg ci -Amc
31 $ hg ci -Amc
32
32
33 $ hg up 1
33 $ hg up 1
34 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
34 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
35 $ echo blah >> bar
35 $ echo blah >> bar
36 $ hg ci -Amd
36 $ hg ci -Amd
37 created new head
37 created new head
38
38
39 $ echo final >> bar
39 $ echo final >> bar
40 $ hg ci -Ame
40 $ hg ci -Ame
41
41
42 $ hg log
42 $ hg log
43 changeset: 4:443431ffac4f
43 changeset: 4:443431ffac4f
44 tag: tip
44 tag: tip
45 user: test
45 user: test
46 date: Thu Jan 01 00:00:00 1970 +0000
46 date: Thu Jan 01 00:00:00 1970 +0000
47 summary: e
47 summary: e
48
48
49 changeset: 3:65bd5f99a4a3
49 changeset: 3:65bd5f99a4a3
50 parent: 1:ef3a871183d7
50 parent: 1:ef3a871183d7
51 user: test
51 user: test
52 date: Thu Jan 01 00:00:00 1970 +0000
52 date: Thu Jan 01 00:00:00 1970 +0000
53 summary: d
53 summary: d
54
54
55 changeset: 2:264128213d29
55 changeset: 2:264128213d29
56 user: test
56 user: test
57 date: Thu Jan 01 00:00:00 1970 +0000
57 date: Thu Jan 01 00:00:00 1970 +0000
58 summary: c
58 summary: c
59
59
60 changeset: 1:ef3a871183d7
60 changeset: 1:ef3a871183d7
61 user: test
61 user: test
62 date: Thu Jan 01 00:00:00 1970 +0000
62 date: Thu Jan 01 00:00:00 1970 +0000
63 summary: b
63 summary: b
64
64
65 changeset: 0:9ab35a2d17cb
65 changeset: 0:9ab35a2d17cb
66 user: test
66 user: test
67 date: Thu Jan 01 00:00:00 1970 +0000
67 date: Thu Jan 01 00:00:00 1970 +0000
68 summary: a
68 summary: a
69
69
70
70
71 $ teststrip 4 4
71 $ teststrip 4 4
72 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
72 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
73 % before update 4, strip 4
73 % before update 4, strip 4
74 changeset: 4:443431ffac4f
74 changeset: 4:443431ffac4f
75 tag: tip
75 tag: tip
76 user: test
76 user: test
77 date: Thu Jan 01 00:00:00 1970 +0000
77 date: Thu Jan 01 00:00:00 1970 +0000
78 summary: e
78 summary: e
79
79
80 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
80 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
81 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
81 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
82 % after update 4, strip 4
82 % after update 4, strip 4
83 changeset: 3:65bd5f99a4a3
83 changeset: 3:65bd5f99a4a3
84 tag: tip
84 tag: tip
85 parent: 1:ef3a871183d7
85 parent: 1:ef3a871183d7
86 user: test
86 user: test
87 date: Thu Jan 01 00:00:00 1970 +0000
87 date: Thu Jan 01 00:00:00 1970 +0000
88 summary: d
88 summary: d
89
89
90 $ teststrip 4 3
90 $ teststrip 4 3
91 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
91 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
92 % before update 4, strip 3
92 % before update 4, strip 3
93 changeset: 4:443431ffac4f
93 changeset: 4:443431ffac4f
94 tag: tip
94 tag: tip
95 user: test
95 user: test
96 date: Thu Jan 01 00:00:00 1970 +0000
96 date: Thu Jan 01 00:00:00 1970 +0000
97 summary: e
97 summary: e
98
98
99 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
99 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
100 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
100 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
101 % after update 4, strip 3
101 % after update 4, strip 3
102 changeset: 1:ef3a871183d7
102 changeset: 1:ef3a871183d7
103 user: test
103 user: test
104 date: Thu Jan 01 00:00:00 1970 +0000
104 date: Thu Jan 01 00:00:00 1970 +0000
105 summary: b
105 summary: b
106
106
107 $ teststrip 1 4
107 $ teststrip 1 4
108 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
108 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
109 % before update 1, strip 4
109 % before update 1, strip 4
110 changeset: 1:ef3a871183d7
110 changeset: 1:ef3a871183d7
111 user: test
111 user: test
112 date: Thu Jan 01 00:00:00 1970 +0000
112 date: Thu Jan 01 00:00:00 1970 +0000
113 summary: b
113 summary: b
114
114
115 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
115 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
116 % after update 1, strip 4
116 % after update 1, strip 4
117 changeset: 1:ef3a871183d7
117 changeset: 1:ef3a871183d7
118 user: test
118 user: test
119 date: Thu Jan 01 00:00:00 1970 +0000
119 date: Thu Jan 01 00:00:00 1970 +0000
120 summary: b
120 summary: b
121
121
122 $ teststrip 4 2
122 $ teststrip 4 2
123 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
123 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
124 % before update 4, strip 2
124 % before update 4, strip 2
125 changeset: 4:443431ffac4f
125 changeset: 4:443431ffac4f
126 tag: tip
126 tag: tip
127 user: test
127 user: test
128 date: Thu Jan 01 00:00:00 1970 +0000
128 date: Thu Jan 01 00:00:00 1970 +0000
129 summary: e
129 summary: e
130
130
131 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
131 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
132 % after update 4, strip 2
132 % after update 4, strip 2
133 changeset: 3:443431ffac4f
133 changeset: 3:443431ffac4f
134 tag: tip
134 tag: tip
135 user: test
135 user: test
136 date: Thu Jan 01 00:00:00 1970 +0000
136 date: Thu Jan 01 00:00:00 1970 +0000
137 summary: e
137 summary: e
138
138
139 $ teststrip 4 1
139 $ teststrip 4 1
140 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
140 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
141 % before update 4, strip 1
141 % before update 4, strip 1
142 changeset: 4:264128213d29
142 changeset: 4:264128213d29
143 tag: tip
143 tag: tip
144 parent: 1:ef3a871183d7
144 parent: 1:ef3a871183d7
145 user: test
145 user: test
146 date: Thu Jan 01 00:00:00 1970 +0000
146 date: Thu Jan 01 00:00:00 1970 +0000
147 summary: c
147 summary: c
148
148
149 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
149 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
150 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
150 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
151 % after update 4, strip 1
151 % after update 4, strip 1
152 changeset: 0:9ab35a2d17cb
152 changeset: 0:9ab35a2d17cb
153 tag: tip
153 tag: tip
154 user: test
154 user: test
155 date: Thu Jan 01 00:00:00 1970 +0000
155 date: Thu Jan 01 00:00:00 1970 +0000
156 summary: a
156 summary: a
157
157
158 $ teststrip null 4
158 $ teststrip null 4
159 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
159 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
160 % before update null, strip 4
160 % before update null, strip 4
161 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
161 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
162 % after update null, strip 4
162 % after update null, strip 4
163
163
164 $ hg log
164 $ hg log
165 changeset: 4:264128213d29
165 changeset: 4:264128213d29
166 tag: tip
166 tag: tip
167 parent: 1:ef3a871183d7
167 parent: 1:ef3a871183d7
168 user: test
168 user: test
169 date: Thu Jan 01 00:00:00 1970 +0000
169 date: Thu Jan 01 00:00:00 1970 +0000
170 summary: c
170 summary: c
171
171
172 changeset: 3:443431ffac4f
172 changeset: 3:443431ffac4f
173 user: test
173 user: test
174 date: Thu Jan 01 00:00:00 1970 +0000
174 date: Thu Jan 01 00:00:00 1970 +0000
175 summary: e
175 summary: e
176
176
177 changeset: 2:65bd5f99a4a3
177 changeset: 2:65bd5f99a4a3
178 user: test
178 user: test
179 date: Thu Jan 01 00:00:00 1970 +0000
179 date: Thu Jan 01 00:00:00 1970 +0000
180 summary: d
180 summary: d
181
181
182 changeset: 1:ef3a871183d7
182 changeset: 1:ef3a871183d7
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: b
185 summary: b
186
186
187 changeset: 0:9ab35a2d17cb
187 changeset: 0:9ab35a2d17cb
188 user: test
188 user: test
189 date: Thu Jan 01 00:00:00 1970 +0000
189 date: Thu Jan 01 00:00:00 1970 +0000
190 summary: a
190 summary: a
191
191
192 $ hg up -C 4
192 $ hg up -C 4
193 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
193 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
194 $ hg parents
194 $ hg parents
195 changeset: 4:264128213d29
195 changeset: 4:264128213d29
196 tag: tip
196 tag: tip
197 parent: 1:ef3a871183d7
197 parent: 1:ef3a871183d7
198 user: test
198 user: test
199 date: Thu Jan 01 00:00:00 1970 +0000
199 date: Thu Jan 01 00:00:00 1970 +0000
200 summary: c
200 summary: c
201
201
202
202
203 $ hg --traceback strip 4
203 $ hg --traceback strip 4
204 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
204 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
205 saved backup bundle to $TESTTMP/test/.hg/strip-backup/264128213d29-0b39d6bf-backup.hg (glob)
205 saved backup bundle to $TESTTMP/test/.hg/strip-backup/264128213d29-0b39d6bf-backup.hg (glob)
206 $ hg parents
206 $ hg parents
207 changeset: 1:ef3a871183d7
207 changeset: 1:ef3a871183d7
208 user: test
208 user: test
209 date: Thu Jan 01 00:00:00 1970 +0000
209 date: Thu Jan 01 00:00:00 1970 +0000
210 summary: b
210 summary: b
211
211
212 $ hg debugbundle .hg/strip-backup/*
212 $ hg debugbundle .hg/strip-backup/*
213 Stream params: sortdict([('Compression', 'BZ')])
213 Stream params: sortdict([('Compression', 'BZ')])
214 changegroup -- "sortdict([('version', '02')])"
214 changegroup -- "sortdict([('version', '02'), ('nbchanges', '1')])"
215 264128213d290d868c54642d13aeaa3675551a78
215 264128213d290d868c54642d13aeaa3675551a78
216 $ hg pull .hg/strip-backup/*
216 $ hg pull .hg/strip-backup/*
217 pulling from .hg/strip-backup/264128213d29-0b39d6bf-backup.hg
217 pulling from .hg/strip-backup/264128213d29-0b39d6bf-backup.hg
218 searching for changes
218 searching for changes
219 adding changesets
219 adding changesets
220 adding manifests
220 adding manifests
221 adding file changes
221 adding file changes
222 added 1 changesets with 0 changes to 0 files (+1 heads)
222 added 1 changesets with 0 changes to 0 files (+1 heads)
223 (run 'hg heads' to see heads, 'hg merge' to merge)
223 (run 'hg heads' to see heads, 'hg merge' to merge)
224 $ rm .hg/strip-backup/*
224 $ rm .hg/strip-backup/*
225 $ hg log --graph
225 $ hg log --graph
226 o changeset: 4:264128213d29
226 o changeset: 4:264128213d29
227 | tag: tip
227 | tag: tip
228 | parent: 1:ef3a871183d7
228 | parent: 1:ef3a871183d7
229 | user: test
229 | user: test
230 | date: Thu Jan 01 00:00:00 1970 +0000
230 | date: Thu Jan 01 00:00:00 1970 +0000
231 | summary: c
231 | summary: c
232 |
232 |
233 | o changeset: 3:443431ffac4f
233 | o changeset: 3:443431ffac4f
234 | | user: test
234 | | user: test
235 | | date: Thu Jan 01 00:00:00 1970 +0000
235 | | date: Thu Jan 01 00:00:00 1970 +0000
236 | | summary: e
236 | | summary: e
237 | |
237 | |
238 | o changeset: 2:65bd5f99a4a3
238 | o changeset: 2:65bd5f99a4a3
239 |/ user: test
239 |/ user: test
240 | date: Thu Jan 01 00:00:00 1970 +0000
240 | date: Thu Jan 01 00:00:00 1970 +0000
241 | summary: d
241 | summary: d
242 |
242 |
243 @ changeset: 1:ef3a871183d7
243 @ changeset: 1:ef3a871183d7
244 | user: test
244 | user: test
245 | date: Thu Jan 01 00:00:00 1970 +0000
245 | date: Thu Jan 01 00:00:00 1970 +0000
246 | summary: b
246 | summary: b
247 |
247 |
248 o changeset: 0:9ab35a2d17cb
248 o changeset: 0:9ab35a2d17cb
249 user: test
249 user: test
250 date: Thu Jan 01 00:00:00 1970 +0000
250 date: Thu Jan 01 00:00:00 1970 +0000
251 summary: a
251 summary: a
252
252
253 $ hg up -C 2
253 $ hg up -C 2
254 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
254 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
255 $ hg merge 4
255 $ hg merge 4
256 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
256 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
257 (branch merge, don't forget to commit)
257 (branch merge, don't forget to commit)
258
258
259 before strip of merge parent
259 before strip of merge parent
260
260
261 $ hg parents
261 $ hg parents
262 changeset: 2:65bd5f99a4a3
262 changeset: 2:65bd5f99a4a3
263 user: test
263 user: test
264 date: Thu Jan 01 00:00:00 1970 +0000
264 date: Thu Jan 01 00:00:00 1970 +0000
265 summary: d
265 summary: d
266
266
267 changeset: 4:264128213d29
267 changeset: 4:264128213d29
268 tag: tip
268 tag: tip
269 parent: 1:ef3a871183d7
269 parent: 1:ef3a871183d7
270 user: test
270 user: test
271 date: Thu Jan 01 00:00:00 1970 +0000
271 date: Thu Jan 01 00:00:00 1970 +0000
272 summary: c
272 summary: c
273
273
274 $ hg strip 4
274 $ hg strip 4
275 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
275 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
276 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
276 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
277
277
278 after strip of merge parent
278 after strip of merge parent
279
279
280 $ hg parents
280 $ hg parents
281 changeset: 1:ef3a871183d7
281 changeset: 1:ef3a871183d7
282 user: test
282 user: test
283 date: Thu Jan 01 00:00:00 1970 +0000
283 date: Thu Jan 01 00:00:00 1970 +0000
284 summary: b
284 summary: b
285
285
286 $ restore
286 $ restore
287
287
288 $ hg up
288 $ hg up
289 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
289 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
290 1 other heads for branch "default"
290 1 other heads for branch "default"
291 $ hg log -G
291 $ hg log -G
292 @ changeset: 4:264128213d29
292 @ changeset: 4:264128213d29
293 | tag: tip
293 | tag: tip
294 | parent: 1:ef3a871183d7
294 | parent: 1:ef3a871183d7
295 | user: test
295 | user: test
296 | date: Thu Jan 01 00:00:00 1970 +0000
296 | date: Thu Jan 01 00:00:00 1970 +0000
297 | summary: c
297 | summary: c
298 |
298 |
299 | o changeset: 3:443431ffac4f
299 | o changeset: 3:443431ffac4f
300 | | user: test
300 | | user: test
301 | | date: Thu Jan 01 00:00:00 1970 +0000
301 | | date: Thu Jan 01 00:00:00 1970 +0000
302 | | summary: e
302 | | summary: e
303 | |
303 | |
304 | o changeset: 2:65bd5f99a4a3
304 | o changeset: 2:65bd5f99a4a3
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: d
307 | summary: d
308 |
308 |
309 o changeset: 1:ef3a871183d7
309 o changeset: 1:ef3a871183d7
310 | user: test
310 | user: test
311 | date: Thu Jan 01 00:00:00 1970 +0000
311 | date: Thu Jan 01 00:00:00 1970 +0000
312 | summary: b
312 | summary: b
313 |
313 |
314 o changeset: 0:9ab35a2d17cb
314 o changeset: 0:9ab35a2d17cb
315 user: test
315 user: test
316 date: Thu Jan 01 00:00:00 1970 +0000
316 date: Thu Jan 01 00:00:00 1970 +0000
317 summary: a
317 summary: a
318
318
319
319
320 2 is parent of 3, only one strip should happen
320 2 is parent of 3, only one strip should happen
321
321
322 $ hg strip "roots(2)" 3
322 $ hg strip "roots(2)" 3
323 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
323 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
324 $ hg log -G
324 $ hg log -G
325 @ changeset: 2:264128213d29
325 @ changeset: 2:264128213d29
326 | tag: tip
326 | tag: tip
327 | user: test
327 | user: test
328 | date: Thu Jan 01 00:00:00 1970 +0000
328 | date: Thu Jan 01 00:00:00 1970 +0000
329 | summary: c
329 | summary: c
330 |
330 |
331 o changeset: 1:ef3a871183d7
331 o changeset: 1:ef3a871183d7
332 | user: test
332 | user: test
333 | date: Thu Jan 01 00:00:00 1970 +0000
333 | date: Thu Jan 01 00:00:00 1970 +0000
334 | summary: b
334 | summary: b
335 |
335 |
336 o changeset: 0:9ab35a2d17cb
336 o changeset: 0:9ab35a2d17cb
337 user: test
337 user: test
338 date: Thu Jan 01 00:00:00 1970 +0000
338 date: Thu Jan 01 00:00:00 1970 +0000
339 summary: a
339 summary: a
340
340
341 $ restore
341 $ restore
342 $ hg log -G
342 $ hg log -G
343 o changeset: 4:443431ffac4f
343 o changeset: 4:443431ffac4f
344 | tag: tip
344 | tag: tip
345 | user: test
345 | user: test
346 | date: Thu Jan 01 00:00:00 1970 +0000
346 | date: Thu Jan 01 00:00:00 1970 +0000
347 | summary: e
347 | summary: e
348 |
348 |
349 o changeset: 3:65bd5f99a4a3
349 o changeset: 3:65bd5f99a4a3
350 | parent: 1:ef3a871183d7
350 | parent: 1:ef3a871183d7
351 | user: test
351 | user: test
352 | date: Thu Jan 01 00:00:00 1970 +0000
352 | date: Thu Jan 01 00:00:00 1970 +0000
353 | summary: d
353 | summary: d
354 |
354 |
355 | @ changeset: 2:264128213d29
355 | @ changeset: 2:264128213d29
356 |/ user: test
356 |/ user: test
357 | date: Thu Jan 01 00:00:00 1970 +0000
357 | date: Thu Jan 01 00:00:00 1970 +0000
358 | summary: c
358 | summary: c
359 |
359 |
360 o changeset: 1:ef3a871183d7
360 o changeset: 1:ef3a871183d7
361 | user: test
361 | user: test
362 | date: Thu Jan 01 00:00:00 1970 +0000
362 | date: Thu Jan 01 00:00:00 1970 +0000
363 | summary: b
363 | summary: b
364 |
364 |
365 o changeset: 0:9ab35a2d17cb
365 o changeset: 0:9ab35a2d17cb
366 user: test
366 user: test
367 date: Thu Jan 01 00:00:00 1970 +0000
367 date: Thu Jan 01 00:00:00 1970 +0000
368 summary: a
368 summary: a
369
369
370
370
371 2 different branches: 2 strips
371 2 different branches: 2 strips
372
372
373 $ hg strip 2 4
373 $ hg strip 2 4
374 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
374 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
375 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
375 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
376 $ hg log -G
376 $ hg log -G
377 o changeset: 2:65bd5f99a4a3
377 o changeset: 2:65bd5f99a4a3
378 | tag: tip
378 | tag: tip
379 | user: test
379 | user: test
380 | date: Thu Jan 01 00:00:00 1970 +0000
380 | date: Thu Jan 01 00:00:00 1970 +0000
381 | summary: d
381 | summary: d
382 |
382 |
383 @ changeset: 1:ef3a871183d7
383 @ changeset: 1:ef3a871183d7
384 | user: test
384 | user: test
385 | date: Thu Jan 01 00:00:00 1970 +0000
385 | date: Thu Jan 01 00:00:00 1970 +0000
386 | summary: b
386 | summary: b
387 |
387 |
388 o changeset: 0:9ab35a2d17cb
388 o changeset: 0:9ab35a2d17cb
389 user: test
389 user: test
390 date: Thu Jan 01 00:00:00 1970 +0000
390 date: Thu Jan 01 00:00:00 1970 +0000
391 summary: a
391 summary: a
392
392
393 $ restore
393 $ restore
394
394
395 2 different branches and a common ancestor: 1 strip
395 2 different branches and a common ancestor: 1 strip
396
396
397 $ hg strip 1 "2|4"
397 $ hg strip 1 "2|4"
398 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
398 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
399 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
399 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
400 $ restore
400 $ restore
401
401
402 verify fncache is kept up-to-date
402 verify fncache is kept up-to-date
403
403
404 $ touch a
404 $ touch a
405 $ hg ci -qAm a
405 $ hg ci -qAm a
406 $ cat .hg/store/fncache | sort
406 $ cat .hg/store/fncache | sort
407 data/a.i
407 data/a.i
408 data/bar.i
408 data/bar.i
409 $ hg strip tip
409 $ hg strip tip
410 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
410 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
411 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
411 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
412 $ cat .hg/store/fncache
412 $ cat .hg/store/fncache
413 data/bar.i
413 data/bar.i
414
414
415 stripping an empty revset
415 stripping an empty revset
416
416
417 $ hg strip "1 and not 1"
417 $ hg strip "1 and not 1"
418 abort: empty revision set
418 abort: empty revision set
419 [255]
419 [255]
420
420
421 remove branchy history for qimport tests
421 remove branchy history for qimport tests
422
422
423 $ hg strip 3
423 $ hg strip 3
424 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
424 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
425
425
426
426
427 strip of applied mq should cleanup status file
427 strip of applied mq should cleanup status file
428
428
429 $ echo "mq=" >> $HGRCPATH
429 $ echo "mq=" >> $HGRCPATH
430 $ hg up -C 3
430 $ hg up -C 3
431 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
431 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
432 $ echo fooagain >> bar
432 $ echo fooagain >> bar
433 $ hg ci -mf
433 $ hg ci -mf
434 $ hg qimport -r tip:2
434 $ hg qimport -r tip:2
435
435
436 applied patches before strip
436 applied patches before strip
437
437
438 $ hg qapplied
438 $ hg qapplied
439 d
439 d
440 e
440 e
441 f
441 f
442
442
443 stripping revision in queue
443 stripping revision in queue
444
444
445 $ hg strip 3
445 $ hg strip 3
446 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
446 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
447 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
447 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
448
448
449 applied patches after stripping rev in queue
449 applied patches after stripping rev in queue
450
450
451 $ hg qapplied
451 $ hg qapplied
452 d
452 d
453
453
454 stripping ancestor of queue
454 stripping ancestor of queue
455
455
456 $ hg strip 1
456 $ hg strip 1
457 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
457 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
458 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
458 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
459
459
460 applied patches after stripping ancestor of queue
460 applied patches after stripping ancestor of queue
461
461
462 $ hg qapplied
462 $ hg qapplied
463
463
464 Verify strip protects against stripping wc parent when there are uncommitted mods
464 Verify strip protects against stripping wc parent when there are uncommitted mods
465
465
466 $ echo b > b
466 $ echo b > b
467 $ echo bb > bar
467 $ echo bb > bar
468 $ hg add b
468 $ hg add b
469 $ hg ci -m 'b'
469 $ hg ci -m 'b'
470 $ hg log --graph
470 $ hg log --graph
471 @ changeset: 1:76dcf9fab855
471 @ changeset: 1:76dcf9fab855
472 | tag: tip
472 | tag: tip
473 | user: test
473 | user: test
474 | date: Thu Jan 01 00:00:00 1970 +0000
474 | date: Thu Jan 01 00:00:00 1970 +0000
475 | summary: b
475 | summary: b
476 |
476 |
477 o changeset: 0:9ab35a2d17cb
477 o changeset: 0:9ab35a2d17cb
478 user: test
478 user: test
479 date: Thu Jan 01 00:00:00 1970 +0000
479 date: Thu Jan 01 00:00:00 1970 +0000
480 summary: a
480 summary: a
481
481
482 $ hg up 0
482 $ hg up 0
483 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
483 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
484 $ echo c > bar
484 $ echo c > bar
485 $ hg up -t false
485 $ hg up -t false
486 merging bar
486 merging bar
487 merging bar failed!
487 merging bar failed!
488 1 files updated, 0 files merged, 0 files removed, 1 files unresolved
488 1 files updated, 0 files merged, 0 files removed, 1 files unresolved
489 use 'hg resolve' to retry unresolved file merges
489 use 'hg resolve' to retry unresolved file merges
490 [1]
490 [1]
491 $ hg sum
491 $ hg sum
492 parent: 1:76dcf9fab855 tip
492 parent: 1:76dcf9fab855 tip
493 b
493 b
494 branch: default
494 branch: default
495 commit: 1 modified, 1 unknown, 1 unresolved
495 commit: 1 modified, 1 unknown, 1 unresolved
496 update: (current)
496 update: (current)
497 phases: 2 draft
497 phases: 2 draft
498 mq: 3 unapplied
498 mq: 3 unapplied
499
499
500 $ echo c > b
500 $ echo c > b
501 $ hg strip tip
501 $ hg strip tip
502 abort: local changes found
502 abort: local changes found
503 [255]
503 [255]
504 $ hg strip tip --keep
504 $ hg strip tip --keep
505 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
505 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
506 $ hg log --graph
506 $ hg log --graph
507 @ changeset: 0:9ab35a2d17cb
507 @ changeset: 0:9ab35a2d17cb
508 tag: tip
508 tag: tip
509 user: test
509 user: test
510 date: Thu Jan 01 00:00:00 1970 +0000
510 date: Thu Jan 01 00:00:00 1970 +0000
511 summary: a
511 summary: a
512
512
513 $ hg status
513 $ hg status
514 M bar
514 M bar
515 ? b
515 ? b
516 ? bar.orig
516 ? bar.orig
517
517
518 $ rm bar.orig
518 $ rm bar.orig
519 $ hg sum
519 $ hg sum
520 parent: 0:9ab35a2d17cb tip
520 parent: 0:9ab35a2d17cb tip
521 a
521 a
522 branch: default
522 branch: default
523 commit: 1 modified, 1 unknown
523 commit: 1 modified, 1 unknown
524 update: (current)
524 update: (current)
525 phases: 1 draft
525 phases: 1 draft
526 mq: 3 unapplied
526 mq: 3 unapplied
527
527
528 Strip adds, removes, modifies with --keep
528 Strip adds, removes, modifies with --keep
529
529
530 $ touch b
530 $ touch b
531 $ hg add b
531 $ hg add b
532 $ hg commit -mb
532 $ hg commit -mb
533 $ touch c
533 $ touch c
534
534
535 ... with a clean working dir
535 ... with a clean working dir
536
536
537 $ hg add c
537 $ hg add c
538 $ hg rm bar
538 $ hg rm bar
539 $ hg commit -mc
539 $ hg commit -mc
540 $ hg status
540 $ hg status
541 $ hg strip --keep tip
541 $ hg strip --keep tip
542 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
542 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
543 $ hg status
543 $ hg status
544 ! bar
544 ! bar
545 ? c
545 ? c
546
546
547 ... with a dirty working dir
547 ... with a dirty working dir
548
548
549 $ hg add c
549 $ hg add c
550 $ hg rm bar
550 $ hg rm bar
551 $ hg commit -mc
551 $ hg commit -mc
552 $ hg status
552 $ hg status
553 $ echo b > b
553 $ echo b > b
554 $ echo d > d
554 $ echo d > d
555 $ hg strip --keep tip
555 $ hg strip --keep tip
556 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
556 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
557 $ hg status
557 $ hg status
558 M b
558 M b
559 ! bar
559 ! bar
560 ? c
560 ? c
561 ? d
561 ? d
562
562
563 ... after updating the dirstate
563 ... after updating the dirstate
564 $ hg add c
564 $ hg add c
565 $ hg commit -mc
565 $ hg commit -mc
566 $ hg rm c
566 $ hg rm c
567 $ hg commit -mc
567 $ hg commit -mc
568 $ hg strip --keep '.^' -q
568 $ hg strip --keep '.^' -q
569 $ cd ..
569 $ cd ..
570
570
571 stripping many nodes on a complex graph (issue3299)
571 stripping many nodes on a complex graph (issue3299)
572
572
573 $ hg init issue3299
573 $ hg init issue3299
574 $ cd issue3299
574 $ cd issue3299
575 $ hg debugbuilddag '@a.:a@b.:b.:x<a@a.:a<b@b.:b<a@a.:a'
575 $ hg debugbuilddag '@a.:a@b.:b.:x<a@a.:a<b@b.:b<a@a.:a'
576 $ hg strip 'not ancestors(x)'
576 $ hg strip 'not ancestors(x)'
577 saved backup bundle to $TESTTMP/issue3299/.hg/strip-backup/*-backup.hg (glob)
577 saved backup bundle to $TESTTMP/issue3299/.hg/strip-backup/*-backup.hg (glob)
578
578
579 test hg strip -B bookmark
579 test hg strip -B bookmark
580
580
581 $ cd ..
581 $ cd ..
582 $ hg init bookmarks
582 $ hg init bookmarks
583 $ cd bookmarks
583 $ cd bookmarks
584 $ hg debugbuilddag '..<2.*1/2:m<2+3:c<m+3:a<2.:b<m+2:d<2.:e<m+1:f'
584 $ hg debugbuilddag '..<2.*1/2:m<2+3:c<m+3:a<2.:b<m+2:d<2.:e<m+1:f'
585 $ hg bookmark -r 'a' 'todelete'
585 $ hg bookmark -r 'a' 'todelete'
586 $ hg bookmark -r 'b' 'B'
586 $ hg bookmark -r 'b' 'B'
587 $ hg bookmark -r 'b' 'nostrip'
587 $ hg bookmark -r 'b' 'nostrip'
588 $ hg bookmark -r 'c' 'delete'
588 $ hg bookmark -r 'c' 'delete'
589 $ hg bookmark -r 'd' 'multipledelete1'
589 $ hg bookmark -r 'd' 'multipledelete1'
590 $ hg bookmark -r 'e' 'multipledelete2'
590 $ hg bookmark -r 'e' 'multipledelete2'
591 $ hg bookmark -r 'f' 'singlenode1'
591 $ hg bookmark -r 'f' 'singlenode1'
592 $ hg bookmark -r 'f' 'singlenode2'
592 $ hg bookmark -r 'f' 'singlenode2'
593 $ hg up -C todelete
593 $ hg up -C todelete
594 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
594 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
595 (activating bookmark todelete)
595 (activating bookmark todelete)
596 $ hg strip -B nostrip
596 $ hg strip -B nostrip
597 bookmark 'nostrip' deleted
597 bookmark 'nostrip' deleted
598 abort: empty revision set
598 abort: empty revision set
599 [255]
599 [255]
600 $ hg strip -B todelete
600 $ hg strip -B todelete
601 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
601 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
602 saved backup bundle to $TESTTMP/bookmarks/.hg/strip-backup/*-backup.hg (glob)
602 saved backup bundle to $TESTTMP/bookmarks/.hg/strip-backup/*-backup.hg (glob)
603 bookmark 'todelete' deleted
603 bookmark 'todelete' deleted
604 $ hg id -ir dcbb326fdec2
604 $ hg id -ir dcbb326fdec2
605 abort: unknown revision 'dcbb326fdec2'!
605 abort: unknown revision 'dcbb326fdec2'!
606 [255]
606 [255]
607 $ hg id -ir d62d843c9a01
607 $ hg id -ir d62d843c9a01
608 d62d843c9a01
608 d62d843c9a01
609 $ hg bookmarks
609 $ hg bookmarks
610 B 9:ff43616e5d0f
610 B 9:ff43616e5d0f
611 delete 6:2702dd0c91e7
611 delete 6:2702dd0c91e7
612 multipledelete1 11:e46a4836065c
612 multipledelete1 11:e46a4836065c
613 multipledelete2 12:b4594d867745
613 multipledelete2 12:b4594d867745
614 singlenode1 13:43227190fef8
614 singlenode1 13:43227190fef8
615 singlenode2 13:43227190fef8
615 singlenode2 13:43227190fef8
616 $ hg strip -B multipledelete1 -B multipledelete2
616 $ hg strip -B multipledelete1 -B multipledelete2
617 saved backup bundle to $TESTTMP/bookmarks/.hg/strip-backup/e46a4836065c-89ec65c2-backup.hg (glob)
617 saved backup bundle to $TESTTMP/bookmarks/.hg/strip-backup/e46a4836065c-89ec65c2-backup.hg (glob)
618 bookmark 'multipledelete1' deleted
618 bookmark 'multipledelete1' deleted
619 bookmark 'multipledelete2' deleted
619 bookmark 'multipledelete2' deleted
620 $ hg id -ir e46a4836065c
620 $ hg id -ir e46a4836065c
621 abort: unknown revision 'e46a4836065c'!
621 abort: unknown revision 'e46a4836065c'!
622 [255]
622 [255]
623 $ hg id -ir b4594d867745
623 $ hg id -ir b4594d867745
624 abort: unknown revision 'b4594d867745'!
624 abort: unknown revision 'b4594d867745'!
625 [255]
625 [255]
626 $ hg strip -B singlenode1 -B singlenode2
626 $ hg strip -B singlenode1 -B singlenode2
627 saved backup bundle to $TESTTMP/bookmarks/.hg/strip-backup/43227190fef8-8da858f2-backup.hg (glob)
627 saved backup bundle to $TESTTMP/bookmarks/.hg/strip-backup/43227190fef8-8da858f2-backup.hg (glob)
628 bookmark 'singlenode1' deleted
628 bookmark 'singlenode1' deleted
629 bookmark 'singlenode2' deleted
629 bookmark 'singlenode2' deleted
630 $ hg id -ir 43227190fef8
630 $ hg id -ir 43227190fef8
631 abort: unknown revision '43227190fef8'!
631 abort: unknown revision '43227190fef8'!
632 [255]
632 [255]
633 $ hg strip -B unknownbookmark
633 $ hg strip -B unknownbookmark
634 abort: bookmark 'unknownbookmark' not found
634 abort: bookmark 'unknownbookmark' not found
635 [255]
635 [255]
636 $ hg strip -B unknownbookmark1 -B unknownbookmark2
636 $ hg strip -B unknownbookmark1 -B unknownbookmark2
637 abort: bookmark 'unknownbookmark1,unknownbookmark2' not found
637 abort: bookmark 'unknownbookmark1,unknownbookmark2' not found
638 [255]
638 [255]
639 $ hg strip -B delete -B unknownbookmark
639 $ hg strip -B delete -B unknownbookmark
640 abort: bookmark 'unknownbookmark' not found
640 abort: bookmark 'unknownbookmark' not found
641 [255]
641 [255]
642 $ hg strip -B delete
642 $ hg strip -B delete
643 saved backup bundle to $TESTTMP/bookmarks/.hg/strip-backup/*-backup.hg (glob)
643 saved backup bundle to $TESTTMP/bookmarks/.hg/strip-backup/*-backup.hg (glob)
644 bookmark 'delete' deleted
644 bookmark 'delete' deleted
645 $ hg id -ir 6:2702dd0c91e7
645 $ hg id -ir 6:2702dd0c91e7
646 abort: unknown revision '2702dd0c91e7'!
646 abort: unknown revision '2702dd0c91e7'!
647 [255]
647 [255]
648 $ hg update B
648 $ hg update B
649 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
649 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
650 (activating bookmark B)
650 (activating bookmark B)
651 $ echo a > a
651 $ echo a > a
652 $ hg add a
652 $ hg add a
653 $ hg strip -B B
653 $ hg strip -B B
654 abort: local changes found
654 abort: local changes found
655 [255]
655 [255]
656 $ hg bookmarks
656 $ hg bookmarks
657 * B 6:ff43616e5d0f
657 * B 6:ff43616e5d0f
658
658
659 Make sure no one adds back a -b option:
659 Make sure no one adds back a -b option:
660
660
661 $ hg strip -b tip
661 $ hg strip -b tip
662 hg strip: option -b not recognized
662 hg strip: option -b not recognized
663 hg strip [-k] [-f] [-B bookmark] [-r] REV...
663 hg strip [-k] [-f] [-B bookmark] [-r] REV...
664
664
665 strip changesets and all their descendants from the repository
665 strip changesets and all their descendants from the repository
666
666
667 (use "hg help -e strip" to show help for the strip extension)
667 (use "hg help -e strip" to show help for the strip extension)
668
668
669 options ([+] can be repeated):
669 options ([+] can be repeated):
670
670
671 -r --rev REV [+] strip specified revision (optional, can specify
671 -r --rev REV [+] strip specified revision (optional, can specify
672 revisions without this option)
672 revisions without this option)
673 -f --force force removal of changesets, discard uncommitted
673 -f --force force removal of changesets, discard uncommitted
674 changes (no backup)
674 changes (no backup)
675 --no-backup no backups
675 --no-backup no backups
676 -k --keep do not modify working directory during strip
676 -k --keep do not modify working directory during strip
677 -B --bookmark VALUE [+] remove revs only reachable from given bookmark
677 -B --bookmark VALUE [+] remove revs only reachable from given bookmark
678 --mq operate on patch repository
678 --mq operate on patch repository
679
679
680 (use "hg strip -h" to show more help)
680 (use "hg strip -h" to show more help)
681 [255]
681 [255]
682
682
683 $ cd ..
683 $ cd ..
684
684
685 Verify bundles don't get overwritten:
685 Verify bundles don't get overwritten:
686
686
687 $ hg init doublebundle
687 $ hg init doublebundle
688 $ cd doublebundle
688 $ cd doublebundle
689 $ touch a
689 $ touch a
690 $ hg commit -Aqm a
690 $ hg commit -Aqm a
691 $ touch b
691 $ touch b
692 $ hg commit -Aqm b
692 $ hg commit -Aqm b
693 $ hg strip -r 0
693 $ hg strip -r 0
694 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
694 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
695 saved backup bundle to $TESTTMP/doublebundle/.hg/strip-backup/3903775176ed-e68910bd-backup.hg (glob)
695 saved backup bundle to $TESTTMP/doublebundle/.hg/strip-backup/3903775176ed-e68910bd-backup.hg (glob)
696 $ ls .hg/strip-backup
696 $ ls .hg/strip-backup
697 3903775176ed-e68910bd-backup.hg
697 3903775176ed-e68910bd-backup.hg
698 $ hg pull -q -r 3903775176ed .hg/strip-backup/3903775176ed-e68910bd-backup.hg
698 $ hg pull -q -r 3903775176ed .hg/strip-backup/3903775176ed-e68910bd-backup.hg
699 $ hg strip -r 0
699 $ hg strip -r 0
700 saved backup bundle to $TESTTMP/doublebundle/.hg/strip-backup/3903775176ed-54390173-backup.hg (glob)
700 saved backup bundle to $TESTTMP/doublebundle/.hg/strip-backup/3903775176ed-54390173-backup.hg (glob)
701 $ ls .hg/strip-backup
701 $ ls .hg/strip-backup
702 3903775176ed-54390173-backup.hg
702 3903775176ed-54390173-backup.hg
703 3903775176ed-e68910bd-backup.hg
703 3903775176ed-e68910bd-backup.hg
704 $ cd ..
704 $ cd ..
705
705
706 Test that we only bundle the stripped changesets (issue4736)
706 Test that we only bundle the stripped changesets (issue4736)
707 ------------------------------------------------------------
707 ------------------------------------------------------------
708
708
709 initialization (previous repo is empty anyway)
709 initialization (previous repo is empty anyway)
710
710
711 $ hg init issue4736
711 $ hg init issue4736
712 $ cd issue4736
712 $ cd issue4736
713 $ echo a > a
713 $ echo a > a
714 $ hg add a
714 $ hg add a
715 $ hg commit -m commitA
715 $ hg commit -m commitA
716 $ echo b > b
716 $ echo b > b
717 $ hg add b
717 $ hg add b
718 $ hg commit -m commitB
718 $ hg commit -m commitB
719 $ echo c > c
719 $ echo c > c
720 $ hg add c
720 $ hg add c
721 $ hg commit -m commitC
721 $ hg commit -m commitC
722 $ hg up 'desc(commitB)'
722 $ hg up 'desc(commitB)'
723 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
723 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
724 $ echo d > d
724 $ echo d > d
725 $ hg add d
725 $ hg add d
726 $ hg commit -m commitD
726 $ hg commit -m commitD
727 created new head
727 created new head
728 $ hg up 'desc(commitC)'
728 $ hg up 'desc(commitC)'
729 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
729 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
730 $ hg merge 'desc(commitD)'
730 $ hg merge 'desc(commitD)'
731 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
731 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
732 (branch merge, don't forget to commit)
732 (branch merge, don't forget to commit)
733 $ hg ci -m 'mergeCD'
733 $ hg ci -m 'mergeCD'
734 $ hg log -G
734 $ hg log -G
735 @ changeset: 4:d8db9d137221
735 @ changeset: 4:d8db9d137221
736 |\ tag: tip
736 |\ tag: tip
737 | | parent: 2:5c51d8d6557d
737 | | parent: 2:5c51d8d6557d
738 | | parent: 3:6625a5168474
738 | | parent: 3:6625a5168474
739 | | user: test
739 | | user: test
740 | | date: Thu Jan 01 00:00:00 1970 +0000
740 | | date: Thu Jan 01 00:00:00 1970 +0000
741 | | summary: mergeCD
741 | | summary: mergeCD
742 | |
742 | |
743 | o changeset: 3:6625a5168474
743 | o changeset: 3:6625a5168474
744 | | parent: 1:eca11cf91c71
744 | | parent: 1:eca11cf91c71
745 | | user: test
745 | | user: test
746 | | date: Thu Jan 01 00:00:00 1970 +0000
746 | | date: Thu Jan 01 00:00:00 1970 +0000
747 | | summary: commitD
747 | | summary: commitD
748 | |
748 | |
749 o | changeset: 2:5c51d8d6557d
749 o | changeset: 2:5c51d8d6557d
750 |/ user: test
750 |/ user: test
751 | date: Thu Jan 01 00:00:00 1970 +0000
751 | date: Thu Jan 01 00:00:00 1970 +0000
752 | summary: commitC
752 | summary: commitC
753 |
753 |
754 o changeset: 1:eca11cf91c71
754 o changeset: 1:eca11cf91c71
755 | user: test
755 | user: test
756 | date: Thu Jan 01 00:00:00 1970 +0000
756 | date: Thu Jan 01 00:00:00 1970 +0000
757 | summary: commitB
757 | summary: commitB
758 |
758 |
759 o changeset: 0:105141ef12d0
759 o changeset: 0:105141ef12d0
760 user: test
760 user: test
761 date: Thu Jan 01 00:00:00 1970 +0000
761 date: Thu Jan 01 00:00:00 1970 +0000
762 summary: commitA
762 summary: commitA
763
763
764
764
765 Check bundle behavior:
765 Check bundle behavior:
766
766
767 $ hg bundle -r 'desc(mergeCD)' --base 'desc(commitC)' ../issue4736.hg
767 $ hg bundle -r 'desc(mergeCD)' --base 'desc(commitC)' ../issue4736.hg
768 2 changesets found
768 2 changesets found
769 $ hg log -r 'bundle()' -R ../issue4736.hg
769 $ hg log -r 'bundle()' -R ../issue4736.hg
770 changeset: 3:6625a5168474
770 changeset: 3:6625a5168474
771 parent: 1:eca11cf91c71
771 parent: 1:eca11cf91c71
772 user: test
772 user: test
773 date: Thu Jan 01 00:00:00 1970 +0000
773 date: Thu Jan 01 00:00:00 1970 +0000
774 summary: commitD
774 summary: commitD
775
775
776 changeset: 4:d8db9d137221
776 changeset: 4:d8db9d137221
777 tag: tip
777 tag: tip
778 parent: 2:5c51d8d6557d
778 parent: 2:5c51d8d6557d
779 parent: 3:6625a5168474
779 parent: 3:6625a5168474
780 user: test
780 user: test
781 date: Thu Jan 01 00:00:00 1970 +0000
781 date: Thu Jan 01 00:00:00 1970 +0000
782 summary: mergeCD
782 summary: mergeCD
783
783
784
784
785 check strip behavior
785 check strip behavior
786
786
787 $ hg --config extensions.strip= strip 'desc(commitD)' --debug
787 $ hg --config extensions.strip= strip 'desc(commitD)' --debug
788 resolving manifests
788 resolving manifests
789 branchmerge: False, force: True, partial: False
789 branchmerge: False, force: True, partial: False
790 ancestor: d8db9d137221+, local: d8db9d137221+, remote: eca11cf91c71
790 ancestor: d8db9d137221+, local: d8db9d137221+, remote: eca11cf91c71
791 c: other deleted -> r
791 c: other deleted -> r
792 removing c
792 removing c
793 d: other deleted -> r
793 d: other deleted -> r
794 removing d
794 removing d
795 starting 4 threads for background file closing (?)
795 starting 4 threads for background file closing (?)
796 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
796 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
797 2 changesets found
797 2 changesets found
798 list of changesets:
798 list of changesets:
799 6625a516847449b6f0fa3737b9ba56e9f0f3032c
799 6625a516847449b6f0fa3737b9ba56e9f0f3032c
800 d8db9d1372214336d2b5570f20ee468d2c72fa8b
800 d8db9d1372214336d2b5570f20ee468d2c72fa8b
801 bundle2-output-bundle: "HG20", (1 params) 1 parts total
801 bundle2-output-bundle: "HG20", (1 params) 1 parts total
802 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
802 bundle2-output-part: "changegroup" (params: 1 mandatory 1 advisory) streamed payload
803 saved backup bundle to $TESTTMP/issue4736/.hg/strip-backup/6625a5168474-345bb43d-backup.hg (glob)
803 saved backup bundle to $TESTTMP/issue4736/.hg/strip-backup/6625a5168474-345bb43d-backup.hg (glob)
804 invalid branchheads cache (served): tip differs
804 invalid branchheads cache (served): tip differs
805 truncating cache/rbc-revs-v1 to 24
805 truncating cache/rbc-revs-v1 to 24
806 $ hg log -G
806 $ hg log -G
807 o changeset: 2:5c51d8d6557d
807 o changeset: 2:5c51d8d6557d
808 | tag: tip
808 | tag: tip
809 | user: test
809 | user: test
810 | date: Thu Jan 01 00:00:00 1970 +0000
810 | date: Thu Jan 01 00:00:00 1970 +0000
811 | summary: commitC
811 | summary: commitC
812 |
812 |
813 @ changeset: 1:eca11cf91c71
813 @ changeset: 1:eca11cf91c71
814 | user: test
814 | user: test
815 | date: Thu Jan 01 00:00:00 1970 +0000
815 | date: Thu Jan 01 00:00:00 1970 +0000
816 | summary: commitB
816 | summary: commitB
817 |
817 |
818 o changeset: 0:105141ef12d0
818 o changeset: 0:105141ef12d0
819 user: test
819 user: test
820 date: Thu Jan 01 00:00:00 1970 +0000
820 date: Thu Jan 01 00:00:00 1970 +0000
821 summary: commitA
821 summary: commitA
822
822
823
823
824 strip backup content
824 strip backup content
825
825
826 $ hg log -r 'bundle()' -R .hg/strip-backup/6625a5168474-*-backup.hg
826 $ hg log -r 'bundle()' -R .hg/strip-backup/6625a5168474-*-backup.hg
827 changeset: 3:6625a5168474
827 changeset: 3:6625a5168474
828 parent: 1:eca11cf91c71
828 parent: 1:eca11cf91c71
829 user: test
829 user: test
830 date: Thu Jan 01 00:00:00 1970 +0000
830 date: Thu Jan 01 00:00:00 1970 +0000
831 summary: commitD
831 summary: commitD
832
832
833 changeset: 4:d8db9d137221
833 changeset: 4:d8db9d137221
834 tag: tip
834 tag: tip
835 parent: 2:5c51d8d6557d
835 parent: 2:5c51d8d6557d
836 parent: 3:6625a5168474
836 parent: 3:6625a5168474
837 user: test
837 user: test
838 date: Thu Jan 01 00:00:00 1970 +0000
838 date: Thu Jan 01 00:00:00 1970 +0000
839 summary: mergeCD
839 summary: mergeCD
840
840
841 Check that the phase cache is properly invalidated after a strip with bookmark.
841 Check that the phase cache is properly invalidated after a strip with bookmark.
842
842
843 $ cat > ../stripstalephasecache.py << EOF
843 $ cat > ../stripstalephasecache.py << EOF
844 > from mercurial import extensions, localrepo
844 > from mercurial import extensions, localrepo
845 > def transactioncallback(orig, repo, desc, *args, **kwargs):
845 > def transactioncallback(orig, repo, desc, *args, **kwargs):
846 > def test(transaction):
846 > def test(transaction):
847 > # observe cache inconsistency
847 > # observe cache inconsistency
848 > try:
848 > try:
849 > [repo.changelog.node(r) for r in repo.revs("not public()")]
849 > [repo.changelog.node(r) for r in repo.revs("not public()")]
850 > except IndexError:
850 > except IndexError:
851 > repo.ui.status("Index error!\n")
851 > repo.ui.status("Index error!\n")
852 > transaction = orig(repo, desc, *args, **kwargs)
852 > transaction = orig(repo, desc, *args, **kwargs)
853 > # warm up the phase cache
853 > # warm up the phase cache
854 > list(repo.revs("not public()"))
854 > list(repo.revs("not public()"))
855 > if desc != 'strip':
855 > if desc != 'strip':
856 > transaction.addpostclose("phase invalidation test", test)
856 > transaction.addpostclose("phase invalidation test", test)
857 > return transaction
857 > return transaction
858 > def extsetup(ui):
858 > def extsetup(ui):
859 > extensions.wrapfunction(localrepo.localrepository, "transaction",
859 > extensions.wrapfunction(localrepo.localrepository, "transaction",
860 > transactioncallback)
860 > transactioncallback)
861 > EOF
861 > EOF
862 $ hg up -C 2
862 $ hg up -C 2
863 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
863 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
864 $ echo k > k
864 $ echo k > k
865 $ hg add k
865 $ hg add k
866 $ hg commit -m commitK
866 $ hg commit -m commitK
867 $ echo l > l
867 $ echo l > l
868 $ hg add l
868 $ hg add l
869 $ hg commit -m commitL
869 $ hg commit -m commitL
870 $ hg book -r tip blah
870 $ hg book -r tip blah
871 $ hg strip ".^" --config extensions.crash=$TESTTMP/stripstalephasecache.py
871 $ hg strip ".^" --config extensions.crash=$TESTTMP/stripstalephasecache.py
872 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
872 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
873 saved backup bundle to $TESTTMP/issue4736/.hg/strip-backup/8f0b4384875c-4fa10deb-backup.hg (glob)
873 saved backup bundle to $TESTTMP/issue4736/.hg/strip-backup/8f0b4384875c-4fa10deb-backup.hg (glob)
874 $ hg up -C 1
874 $ hg up -C 1
875 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
875 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
876
876
877 Error during post-close callback of the strip transaction
877 Error during post-close callback of the strip transaction
878 (They should be gracefully handled and reported)
878 (They should be gracefully handled and reported)
879
879
880 $ cat > ../crashstrip.py << EOF
880 $ cat > ../crashstrip.py << EOF
881 > from mercurial import error
881 > from mercurial import error
882 > def reposetup(ui, repo):
882 > def reposetup(ui, repo):
883 > class crashstriprepo(repo.__class__):
883 > class crashstriprepo(repo.__class__):
884 > def transaction(self, desc, *args, **kwargs):
884 > def transaction(self, desc, *args, **kwargs):
885 > tr = super(crashstriprepo, self).transaction(self, desc, *args, **kwargs)
885 > tr = super(crashstriprepo, self).transaction(self, desc, *args, **kwargs)
886 > if desc == 'strip':
886 > if desc == 'strip':
887 > def crash(tra): raise error.Abort('boom')
887 > def crash(tra): raise error.Abort('boom')
888 > tr.addpostclose('crash', crash)
888 > tr.addpostclose('crash', crash)
889 > return tr
889 > return tr
890 > repo.__class__ = crashstriprepo
890 > repo.__class__ = crashstriprepo
891 > EOF
891 > EOF
892 $ hg strip tip --config extensions.crash=$TESTTMP/crashstrip.py
892 $ hg strip tip --config extensions.crash=$TESTTMP/crashstrip.py
893 saved backup bundle to $TESTTMP/issue4736/.hg/strip-backup/5c51d8d6557d-70daef06-backup.hg (glob)
893 saved backup bundle to $TESTTMP/issue4736/.hg/strip-backup/5c51d8d6557d-70daef06-backup.hg (glob)
894 strip failed, full bundle stored in '$TESTTMP/issue4736/.hg/strip-backup/5c51d8d6557d-70daef06-backup.hg' (glob)
894 strip failed, full bundle stored in '$TESTTMP/issue4736/.hg/strip-backup/5c51d8d6557d-70daef06-backup.hg' (glob)
895 abort: boom
895 abort: boom
896 [255]
896 [255]
897
897
898
898
General Comments 0
You need to be logged in to leave comments. Login now