##// END OF EJS Templates
changegroup: change topics during generation...
Gregory Szorc -
r39275:0617a700 default
parent child Browse files
Show More
@@ -1,1394 +1,1394 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 weakref
12 import weakref
13
13
14 from .i18n import _
14 from .i18n import _
15 from .node import (
15 from .node import (
16 hex,
16 hex,
17 nullid,
17 nullid,
18 nullrev,
18 nullrev,
19 short,
19 short,
20 )
20 )
21
21
22 from .thirdparty import (
22 from .thirdparty import (
23 attr,
23 attr,
24 )
24 )
25
25
26 from . import (
26 from . import (
27 dagop,
27 dagop,
28 error,
28 error,
29 match as matchmod,
29 match as matchmod,
30 mdiff,
30 mdiff,
31 phases,
31 phases,
32 pycompat,
32 pycompat,
33 repository,
33 repository,
34 util,
34 util,
35 )
35 )
36
36
37 from .utils import (
37 from .utils import (
38 interfaceutil,
38 interfaceutil,
39 stringutil,
39 stringutil,
40 )
40 )
41
41
42 _CHANGEGROUPV1_DELTA_HEADER = struct.Struct("20s20s20s20s")
42 _CHANGEGROUPV1_DELTA_HEADER = struct.Struct("20s20s20s20s")
43 _CHANGEGROUPV2_DELTA_HEADER = struct.Struct("20s20s20s20s20s")
43 _CHANGEGROUPV2_DELTA_HEADER = struct.Struct("20s20s20s20s20s")
44 _CHANGEGROUPV3_DELTA_HEADER = struct.Struct(">20s20s20s20s20sH")
44 _CHANGEGROUPV3_DELTA_HEADER = struct.Struct(">20s20s20s20s20sH")
45
45
46 LFS_REQUIREMENT = 'lfs'
46 LFS_REQUIREMENT = 'lfs'
47
47
48 readexactly = util.readexactly
48 readexactly = util.readexactly
49
49
50 def getchunk(stream):
50 def getchunk(stream):
51 """return the next chunk from stream as a string"""
51 """return the next chunk from stream as a string"""
52 d = readexactly(stream, 4)
52 d = readexactly(stream, 4)
53 l = struct.unpack(">l", d)[0]
53 l = struct.unpack(">l", d)[0]
54 if l <= 4:
54 if l <= 4:
55 if l:
55 if l:
56 raise error.Abort(_("invalid chunk length %d") % l)
56 raise error.Abort(_("invalid chunk length %d") % l)
57 return ""
57 return ""
58 return readexactly(stream, l - 4)
58 return readexactly(stream, l - 4)
59
59
60 def chunkheader(length):
60 def chunkheader(length):
61 """return a changegroup chunk header (string)"""
61 """return a changegroup chunk header (string)"""
62 return struct.pack(">l", length + 4)
62 return struct.pack(">l", length + 4)
63
63
64 def closechunk():
64 def closechunk():
65 """return a changegroup chunk header (string) for a zero-length chunk"""
65 """return a changegroup chunk header (string) for a zero-length chunk"""
66 return struct.pack(">l", 0)
66 return struct.pack(">l", 0)
67
67
68 def _fileheader(path):
68 def _fileheader(path):
69 """Obtain a changegroup chunk header for a named path."""
69 """Obtain a changegroup chunk header for a named path."""
70 return chunkheader(len(path)) + path
70 return chunkheader(len(path)) + path
71
71
72 def writechunks(ui, chunks, filename, vfs=None):
72 def writechunks(ui, chunks, filename, vfs=None):
73 """Write chunks to a file and return its filename.
73 """Write chunks to a file and return its filename.
74
74
75 The stream is assumed to be a bundle file.
75 The stream is assumed to be a bundle file.
76 Existing files will not be overwritten.
76 Existing files will not be overwritten.
77 If no filename is specified, a temporary file is created.
77 If no filename is specified, a temporary file is created.
78 """
78 """
79 fh = None
79 fh = None
80 cleanup = None
80 cleanup = None
81 try:
81 try:
82 if filename:
82 if filename:
83 if vfs:
83 if vfs:
84 fh = vfs.open(filename, "wb")
84 fh = vfs.open(filename, "wb")
85 else:
85 else:
86 # Increase default buffer size because default is usually
86 # Increase default buffer size because default is usually
87 # small (4k is common on Linux).
87 # small (4k is common on Linux).
88 fh = open(filename, "wb", 131072)
88 fh = open(filename, "wb", 131072)
89 else:
89 else:
90 fd, filename = pycompat.mkstemp(prefix="hg-bundle-", suffix=".hg")
90 fd, filename = pycompat.mkstemp(prefix="hg-bundle-", suffix=".hg")
91 fh = os.fdopen(fd, r"wb")
91 fh = os.fdopen(fd, r"wb")
92 cleanup = filename
92 cleanup = filename
93 for c in chunks:
93 for c in chunks:
94 fh.write(c)
94 fh.write(c)
95 cleanup = None
95 cleanup = None
96 return filename
96 return filename
97 finally:
97 finally:
98 if fh is not None:
98 if fh is not None:
99 fh.close()
99 fh.close()
100 if cleanup is not None:
100 if cleanup is not None:
101 if filename and vfs:
101 if filename and vfs:
102 vfs.unlink(cleanup)
102 vfs.unlink(cleanup)
103 else:
103 else:
104 os.unlink(cleanup)
104 os.unlink(cleanup)
105
105
106 class cg1unpacker(object):
106 class cg1unpacker(object):
107 """Unpacker for cg1 changegroup streams.
107 """Unpacker for cg1 changegroup streams.
108
108
109 A changegroup unpacker handles the framing of the revision data in
109 A changegroup unpacker handles the framing of the revision data in
110 the wire format. Most consumers will want to use the apply()
110 the wire format. Most consumers will want to use the apply()
111 method to add the changes from the changegroup to a repository.
111 method to add the changes from the changegroup to a repository.
112
112
113 If you're forwarding a changegroup unmodified to another consumer,
113 If you're forwarding a changegroup unmodified to another consumer,
114 use getchunks(), which returns an iterator of changegroup
114 use getchunks(), which returns an iterator of changegroup
115 chunks. This is mostly useful for cases where you need to know the
115 chunks. This is mostly useful for cases where you need to know the
116 data stream has ended by observing the end of the changegroup.
116 data stream has ended by observing the end of the changegroup.
117
117
118 deltachunk() is useful only if you're applying delta data. Most
118 deltachunk() is useful only if you're applying delta data. Most
119 consumers should prefer apply() instead.
119 consumers should prefer apply() instead.
120
120
121 A few other public methods exist. Those are used only for
121 A few other public methods exist. Those are used only for
122 bundlerepo and some debug commands - their use is discouraged.
122 bundlerepo and some debug commands - their use is discouraged.
123 """
123 """
124 deltaheader = _CHANGEGROUPV1_DELTA_HEADER
124 deltaheader = _CHANGEGROUPV1_DELTA_HEADER
125 deltaheadersize = deltaheader.size
125 deltaheadersize = deltaheader.size
126 version = '01'
126 version = '01'
127 _grouplistcount = 1 # One list of files after the manifests
127 _grouplistcount = 1 # One list of files after the manifests
128
128
129 def __init__(self, fh, alg, extras=None):
129 def __init__(self, fh, alg, extras=None):
130 if alg is None:
130 if alg is None:
131 alg = 'UN'
131 alg = 'UN'
132 if alg not in util.compengines.supportedbundletypes:
132 if alg not in util.compengines.supportedbundletypes:
133 raise error.Abort(_('unknown stream compression type: %s')
133 raise error.Abort(_('unknown stream compression type: %s')
134 % alg)
134 % alg)
135 if alg == 'BZ':
135 if alg == 'BZ':
136 alg = '_truncatedBZ'
136 alg = '_truncatedBZ'
137
137
138 compengine = util.compengines.forbundletype(alg)
138 compengine = util.compengines.forbundletype(alg)
139 self._stream = compengine.decompressorreader(fh)
139 self._stream = compengine.decompressorreader(fh)
140 self._type = alg
140 self._type = alg
141 self.extras = extras or {}
141 self.extras = extras or {}
142 self.callback = None
142 self.callback = None
143
143
144 # These methods (compressed, read, seek, tell) all appear to only
144 # These methods (compressed, read, seek, tell) all appear to only
145 # be used by bundlerepo, but it's a little hard to tell.
145 # be used by bundlerepo, but it's a little hard to tell.
146 def compressed(self):
146 def compressed(self):
147 return self._type is not None and self._type != 'UN'
147 return self._type is not None and self._type != 'UN'
148 def read(self, l):
148 def read(self, l):
149 return self._stream.read(l)
149 return self._stream.read(l)
150 def seek(self, pos):
150 def seek(self, pos):
151 return self._stream.seek(pos)
151 return self._stream.seek(pos)
152 def tell(self):
152 def tell(self):
153 return self._stream.tell()
153 return self._stream.tell()
154 def close(self):
154 def close(self):
155 return self._stream.close()
155 return self._stream.close()
156
156
157 def _chunklength(self):
157 def _chunklength(self):
158 d = readexactly(self._stream, 4)
158 d = readexactly(self._stream, 4)
159 l = struct.unpack(">l", d)[0]
159 l = struct.unpack(">l", d)[0]
160 if l <= 4:
160 if l <= 4:
161 if l:
161 if l:
162 raise error.Abort(_("invalid chunk length %d") % l)
162 raise error.Abort(_("invalid chunk length %d") % l)
163 return 0
163 return 0
164 if self.callback:
164 if self.callback:
165 self.callback()
165 self.callback()
166 return l - 4
166 return l - 4
167
167
168 def changelogheader(self):
168 def changelogheader(self):
169 """v10 does not have a changelog header chunk"""
169 """v10 does not have a changelog header chunk"""
170 return {}
170 return {}
171
171
172 def manifestheader(self):
172 def manifestheader(self):
173 """v10 does not have a manifest header chunk"""
173 """v10 does not have a manifest header chunk"""
174 return {}
174 return {}
175
175
176 def filelogheader(self):
176 def filelogheader(self):
177 """return the header of the filelogs chunk, v10 only has the filename"""
177 """return the header of the filelogs chunk, v10 only has the filename"""
178 l = self._chunklength()
178 l = self._chunklength()
179 if not l:
179 if not l:
180 return {}
180 return {}
181 fname = readexactly(self._stream, l)
181 fname = readexactly(self._stream, l)
182 return {'filename': fname}
182 return {'filename': fname}
183
183
184 def _deltaheader(self, headertuple, prevnode):
184 def _deltaheader(self, headertuple, prevnode):
185 node, p1, p2, cs = headertuple
185 node, p1, p2, cs = headertuple
186 if prevnode is None:
186 if prevnode is None:
187 deltabase = p1
187 deltabase = p1
188 else:
188 else:
189 deltabase = prevnode
189 deltabase = prevnode
190 flags = 0
190 flags = 0
191 return node, p1, p2, deltabase, cs, flags
191 return node, p1, p2, deltabase, cs, flags
192
192
193 def deltachunk(self, prevnode):
193 def deltachunk(self, prevnode):
194 l = self._chunklength()
194 l = self._chunklength()
195 if not l:
195 if not l:
196 return {}
196 return {}
197 headerdata = readexactly(self._stream, self.deltaheadersize)
197 headerdata = readexactly(self._stream, self.deltaheadersize)
198 header = self.deltaheader.unpack(headerdata)
198 header = self.deltaheader.unpack(headerdata)
199 delta = readexactly(self._stream, l - self.deltaheadersize)
199 delta = readexactly(self._stream, l - self.deltaheadersize)
200 node, p1, p2, deltabase, cs, flags = self._deltaheader(header, prevnode)
200 node, p1, p2, deltabase, cs, flags = self._deltaheader(header, prevnode)
201 return (node, p1, p2, cs, deltabase, delta, flags)
201 return (node, p1, p2, cs, deltabase, delta, flags)
202
202
203 def getchunks(self):
203 def getchunks(self):
204 """returns all the chunks contains in the bundle
204 """returns all the chunks contains in the bundle
205
205
206 Used when you need to forward the binary stream to a file or another
206 Used when you need to forward the binary stream to a file or another
207 network API. To do so, it parse the changegroup data, otherwise it will
207 network API. To do so, it parse the changegroup data, otherwise it will
208 block in case of sshrepo because it don't know the end of the stream.
208 block in case of sshrepo because it don't know the end of the stream.
209 """
209 """
210 # For changegroup 1 and 2, we expect 3 parts: changelog, manifestlog,
210 # For changegroup 1 and 2, we expect 3 parts: changelog, manifestlog,
211 # and a list of filelogs. For changegroup 3, we expect 4 parts:
211 # and a list of filelogs. For changegroup 3, we expect 4 parts:
212 # changelog, manifestlog, a list of tree manifestlogs, and a list of
212 # changelog, manifestlog, a list of tree manifestlogs, and a list of
213 # filelogs.
213 # filelogs.
214 #
214 #
215 # Changelog and manifestlog parts are terminated with empty chunks. The
215 # Changelog and manifestlog parts are terminated with empty chunks. The
216 # tree and file parts are a list of entry sections. Each entry section
216 # tree and file parts are a list of entry sections. Each entry section
217 # is a series of chunks terminating in an empty chunk. The list of these
217 # is a series of chunks terminating in an empty chunk. The list of these
218 # entry sections is terminated in yet another empty chunk, so we know
218 # entry sections is terminated in yet another empty chunk, so we know
219 # we've reached the end of the tree/file list when we reach an empty
219 # we've reached the end of the tree/file list when we reach an empty
220 # chunk that was proceeded by no non-empty chunks.
220 # chunk that was proceeded by no non-empty chunks.
221
221
222 parts = 0
222 parts = 0
223 while parts < 2 + self._grouplistcount:
223 while parts < 2 + self._grouplistcount:
224 noentries = True
224 noentries = True
225 while True:
225 while True:
226 chunk = getchunk(self)
226 chunk = getchunk(self)
227 if not chunk:
227 if not chunk:
228 # The first two empty chunks represent the end of the
228 # The first two empty chunks represent the end of the
229 # changelog and the manifestlog portions. The remaining
229 # changelog and the manifestlog portions. The remaining
230 # empty chunks represent either A) the end of individual
230 # empty chunks represent either A) the end of individual
231 # tree or file entries in the file list, or B) the end of
231 # tree or file entries in the file list, or B) the end of
232 # the entire list. It's the end of the entire list if there
232 # the entire list. It's the end of the entire list if there
233 # were no entries (i.e. noentries is True).
233 # were no entries (i.e. noentries is True).
234 if parts < 2:
234 if parts < 2:
235 parts += 1
235 parts += 1
236 elif noentries:
236 elif noentries:
237 parts += 1
237 parts += 1
238 break
238 break
239 noentries = False
239 noentries = False
240 yield chunkheader(len(chunk))
240 yield chunkheader(len(chunk))
241 pos = 0
241 pos = 0
242 while pos < len(chunk):
242 while pos < len(chunk):
243 next = pos + 2**20
243 next = pos + 2**20
244 yield chunk[pos:next]
244 yield chunk[pos:next]
245 pos = next
245 pos = next
246 yield closechunk()
246 yield closechunk()
247
247
248 def _unpackmanifests(self, repo, revmap, trp, prog):
248 def _unpackmanifests(self, repo, revmap, trp, prog):
249 self.callback = prog.increment
249 self.callback = prog.increment
250 # no need to check for empty manifest group here:
250 # no need to check for empty manifest group here:
251 # if the result of the merge of 1 and 2 is the same in 3 and 4,
251 # if the result of the merge of 1 and 2 is the same in 3 and 4,
252 # no new manifest will be created and the manifest group will
252 # no new manifest will be created and the manifest group will
253 # be empty during the pull
253 # be empty during the pull
254 self.manifestheader()
254 self.manifestheader()
255 deltas = self.deltaiter()
255 deltas = self.deltaiter()
256 repo.manifestlog.addgroup(deltas, revmap, trp)
256 repo.manifestlog.addgroup(deltas, revmap, trp)
257 prog.complete()
257 prog.complete()
258 self.callback = None
258 self.callback = None
259
259
260 def apply(self, repo, tr, srctype, url, targetphase=phases.draft,
260 def apply(self, repo, tr, srctype, url, targetphase=phases.draft,
261 expectedtotal=None):
261 expectedtotal=None):
262 """Add the changegroup returned by source.read() to this repo.
262 """Add the changegroup returned by source.read() to this repo.
263 srctype is a string like 'push', 'pull', or 'unbundle'. url is
263 srctype is a string like 'push', 'pull', or 'unbundle'. url is
264 the URL of the repo where this changegroup is coming from.
264 the URL of the repo where this changegroup is coming from.
265
265
266 Return an integer summarizing the change to this repo:
266 Return an integer summarizing the change to this repo:
267 - nothing changed or no source: 0
267 - nothing changed or no source: 0
268 - more heads than before: 1+added heads (2..n)
268 - more heads than before: 1+added heads (2..n)
269 - fewer heads than before: -1-removed heads (-2..-n)
269 - fewer heads than before: -1-removed heads (-2..-n)
270 - number of heads stays the same: 1
270 - number of heads stays the same: 1
271 """
271 """
272 repo = repo.unfiltered()
272 repo = repo.unfiltered()
273 def csmap(x):
273 def csmap(x):
274 repo.ui.debug("add changeset %s\n" % short(x))
274 repo.ui.debug("add changeset %s\n" % short(x))
275 return len(cl)
275 return len(cl)
276
276
277 def revmap(x):
277 def revmap(x):
278 return cl.rev(x)
278 return cl.rev(x)
279
279
280 changesets = files = revisions = 0
280 changesets = files = revisions = 0
281
281
282 try:
282 try:
283 # The transaction may already carry source information. In this
283 # The transaction may already carry source information. In this
284 # case we use the top level data. We overwrite the argument
284 # case we use the top level data. We overwrite the argument
285 # because we need to use the top level value (if they exist)
285 # because we need to use the top level value (if they exist)
286 # in this function.
286 # in this function.
287 srctype = tr.hookargs.setdefault('source', srctype)
287 srctype = tr.hookargs.setdefault('source', srctype)
288 url = tr.hookargs.setdefault('url', url)
288 url = tr.hookargs.setdefault('url', url)
289 repo.hook('prechangegroup',
289 repo.hook('prechangegroup',
290 throw=True, **pycompat.strkwargs(tr.hookargs))
290 throw=True, **pycompat.strkwargs(tr.hookargs))
291
291
292 # write changelog data to temp files so concurrent readers
292 # write changelog data to temp files so concurrent readers
293 # will not see an inconsistent view
293 # will not see an inconsistent view
294 cl = repo.changelog
294 cl = repo.changelog
295 cl.delayupdate(tr)
295 cl.delayupdate(tr)
296 oldheads = set(cl.heads())
296 oldheads = set(cl.heads())
297
297
298 trp = weakref.proxy(tr)
298 trp = weakref.proxy(tr)
299 # pull off the changeset group
299 # pull off the changeset group
300 repo.ui.status(_("adding changesets\n"))
300 repo.ui.status(_("adding changesets\n"))
301 clstart = len(cl)
301 clstart = len(cl)
302 progress = repo.ui.makeprogress(_('changesets'), unit=_('chunks'),
302 progress = repo.ui.makeprogress(_('changesets'), unit=_('chunks'),
303 total=expectedtotal)
303 total=expectedtotal)
304 self.callback = progress.increment
304 self.callback = progress.increment
305
305
306 efiles = set()
306 efiles = set()
307 def onchangelog(cl, node):
307 def onchangelog(cl, node):
308 efiles.update(cl.readfiles(node))
308 efiles.update(cl.readfiles(node))
309
309
310 self.changelogheader()
310 self.changelogheader()
311 deltas = self.deltaiter()
311 deltas = self.deltaiter()
312 cgnodes = cl.addgroup(deltas, csmap, trp, addrevisioncb=onchangelog)
312 cgnodes = cl.addgroup(deltas, csmap, trp, addrevisioncb=onchangelog)
313 efiles = len(efiles)
313 efiles = len(efiles)
314
314
315 if not cgnodes:
315 if not cgnodes:
316 repo.ui.develwarn('applied empty changegroup',
316 repo.ui.develwarn('applied empty changegroup',
317 config='warn-empty-changegroup')
317 config='warn-empty-changegroup')
318 clend = len(cl)
318 clend = len(cl)
319 changesets = clend - clstart
319 changesets = clend - clstart
320 progress.complete()
320 progress.complete()
321 self.callback = None
321 self.callback = None
322
322
323 # pull off the manifest group
323 # pull off the manifest group
324 repo.ui.status(_("adding manifests\n"))
324 repo.ui.status(_("adding manifests\n"))
325 # We know that we'll never have more manifests than we had
325 # We know that we'll never have more manifests than we had
326 # changesets.
326 # changesets.
327 progress = repo.ui.makeprogress(_('manifests'), unit=_('chunks'),
327 progress = repo.ui.makeprogress(_('manifests'), unit=_('chunks'),
328 total=changesets)
328 total=changesets)
329 self._unpackmanifests(repo, revmap, trp, progress)
329 self._unpackmanifests(repo, revmap, trp, progress)
330
330
331 needfiles = {}
331 needfiles = {}
332 if repo.ui.configbool('server', 'validate'):
332 if repo.ui.configbool('server', 'validate'):
333 cl = repo.changelog
333 cl = repo.changelog
334 ml = repo.manifestlog
334 ml = repo.manifestlog
335 # validate incoming csets have their manifests
335 # validate incoming csets have their manifests
336 for cset in pycompat.xrange(clstart, clend):
336 for cset in pycompat.xrange(clstart, clend):
337 mfnode = cl.changelogrevision(cset).manifest
337 mfnode = cl.changelogrevision(cset).manifest
338 mfest = ml[mfnode].readdelta()
338 mfest = ml[mfnode].readdelta()
339 # store file cgnodes we must see
339 # store file cgnodes we must see
340 for f, n in mfest.iteritems():
340 for f, n in mfest.iteritems():
341 needfiles.setdefault(f, set()).add(n)
341 needfiles.setdefault(f, set()).add(n)
342
342
343 # process the files
343 # process the files
344 repo.ui.status(_("adding file changes\n"))
344 repo.ui.status(_("adding file changes\n"))
345 newrevs, newfiles = _addchangegroupfiles(
345 newrevs, newfiles = _addchangegroupfiles(
346 repo, self, revmap, trp, efiles, needfiles)
346 repo, self, revmap, trp, efiles, needfiles)
347 revisions += newrevs
347 revisions += newrevs
348 files += newfiles
348 files += newfiles
349
349
350 deltaheads = 0
350 deltaheads = 0
351 if oldheads:
351 if oldheads:
352 heads = cl.heads()
352 heads = cl.heads()
353 deltaheads = len(heads) - len(oldheads)
353 deltaheads = len(heads) - len(oldheads)
354 for h in heads:
354 for h in heads:
355 if h not in oldheads and repo[h].closesbranch():
355 if h not in oldheads and repo[h].closesbranch():
356 deltaheads -= 1
356 deltaheads -= 1
357 htext = ""
357 htext = ""
358 if deltaheads:
358 if deltaheads:
359 htext = _(" (%+d heads)") % deltaheads
359 htext = _(" (%+d heads)") % deltaheads
360
360
361 repo.ui.status(_("added %d changesets"
361 repo.ui.status(_("added %d changesets"
362 " with %d changes to %d files%s\n")
362 " with %d changes to %d files%s\n")
363 % (changesets, revisions, files, htext))
363 % (changesets, revisions, files, htext))
364 repo.invalidatevolatilesets()
364 repo.invalidatevolatilesets()
365
365
366 if changesets > 0:
366 if changesets > 0:
367 if 'node' not in tr.hookargs:
367 if 'node' not in tr.hookargs:
368 tr.hookargs['node'] = hex(cl.node(clstart))
368 tr.hookargs['node'] = hex(cl.node(clstart))
369 tr.hookargs['node_last'] = hex(cl.node(clend - 1))
369 tr.hookargs['node_last'] = hex(cl.node(clend - 1))
370 hookargs = dict(tr.hookargs)
370 hookargs = dict(tr.hookargs)
371 else:
371 else:
372 hookargs = dict(tr.hookargs)
372 hookargs = dict(tr.hookargs)
373 hookargs['node'] = hex(cl.node(clstart))
373 hookargs['node'] = hex(cl.node(clstart))
374 hookargs['node_last'] = hex(cl.node(clend - 1))
374 hookargs['node_last'] = hex(cl.node(clend - 1))
375 repo.hook('pretxnchangegroup',
375 repo.hook('pretxnchangegroup',
376 throw=True, **pycompat.strkwargs(hookargs))
376 throw=True, **pycompat.strkwargs(hookargs))
377
377
378 added = [cl.node(r) for r in pycompat.xrange(clstart, clend)]
378 added = [cl.node(r) for r in pycompat.xrange(clstart, clend)]
379 phaseall = None
379 phaseall = None
380 if srctype in ('push', 'serve'):
380 if srctype in ('push', 'serve'):
381 # Old servers can not push the boundary themselves.
381 # Old servers can not push the boundary themselves.
382 # New servers won't push the boundary if changeset already
382 # New servers won't push the boundary if changeset already
383 # exists locally as secret
383 # exists locally as secret
384 #
384 #
385 # We should not use added here but the list of all change in
385 # We should not use added here but the list of all change in
386 # the bundle
386 # the bundle
387 if repo.publishing():
387 if repo.publishing():
388 targetphase = phaseall = phases.public
388 targetphase = phaseall = phases.public
389 else:
389 else:
390 # closer target phase computation
390 # closer target phase computation
391
391
392 # Those changesets have been pushed from the
392 # Those changesets have been pushed from the
393 # outside, their phases are going to be pushed
393 # outside, their phases are going to be pushed
394 # alongside. Therefor `targetphase` is
394 # alongside. Therefor `targetphase` is
395 # ignored.
395 # ignored.
396 targetphase = phaseall = phases.draft
396 targetphase = phaseall = phases.draft
397 if added:
397 if added:
398 phases.registernew(repo, tr, targetphase, added)
398 phases.registernew(repo, tr, targetphase, added)
399 if phaseall is not None:
399 if phaseall is not None:
400 phases.advanceboundary(repo, tr, phaseall, cgnodes)
400 phases.advanceboundary(repo, tr, phaseall, cgnodes)
401
401
402 if changesets > 0:
402 if changesets > 0:
403
403
404 def runhooks():
404 def runhooks():
405 # These hooks run when the lock releases, not when the
405 # These hooks run when the lock releases, not when the
406 # transaction closes. So it's possible for the changelog
406 # transaction closes. So it's possible for the changelog
407 # to have changed since we last saw it.
407 # to have changed since we last saw it.
408 if clstart >= len(repo):
408 if clstart >= len(repo):
409 return
409 return
410
410
411 repo.hook("changegroup", **pycompat.strkwargs(hookargs))
411 repo.hook("changegroup", **pycompat.strkwargs(hookargs))
412
412
413 for n in added:
413 for n in added:
414 args = hookargs.copy()
414 args = hookargs.copy()
415 args['node'] = hex(n)
415 args['node'] = hex(n)
416 del args['node_last']
416 del args['node_last']
417 repo.hook("incoming", **pycompat.strkwargs(args))
417 repo.hook("incoming", **pycompat.strkwargs(args))
418
418
419 newheads = [h for h in repo.heads()
419 newheads = [h for h in repo.heads()
420 if h not in oldheads]
420 if h not in oldheads]
421 repo.ui.log("incoming",
421 repo.ui.log("incoming",
422 "%d incoming changes - new heads: %s\n",
422 "%d incoming changes - new heads: %s\n",
423 len(added),
423 len(added),
424 ', '.join([hex(c[:6]) for c in newheads]))
424 ', '.join([hex(c[:6]) for c in newheads]))
425
425
426 tr.addpostclose('changegroup-runhooks-%020i' % clstart,
426 tr.addpostclose('changegroup-runhooks-%020i' % clstart,
427 lambda tr: repo._afterlock(runhooks))
427 lambda tr: repo._afterlock(runhooks))
428 finally:
428 finally:
429 repo.ui.flush()
429 repo.ui.flush()
430 # never return 0 here:
430 # never return 0 here:
431 if deltaheads < 0:
431 if deltaheads < 0:
432 ret = deltaheads - 1
432 ret = deltaheads - 1
433 else:
433 else:
434 ret = deltaheads + 1
434 ret = deltaheads + 1
435 return ret
435 return ret
436
436
437 def deltaiter(self):
437 def deltaiter(self):
438 """
438 """
439 returns an iterator of the deltas in this changegroup
439 returns an iterator of the deltas in this changegroup
440
440
441 Useful for passing to the underlying storage system to be stored.
441 Useful for passing to the underlying storage system to be stored.
442 """
442 """
443 chain = None
443 chain = None
444 for chunkdata in iter(lambda: self.deltachunk(chain), {}):
444 for chunkdata in iter(lambda: self.deltachunk(chain), {}):
445 # Chunkdata: (node, p1, p2, cs, deltabase, delta, flags)
445 # Chunkdata: (node, p1, p2, cs, deltabase, delta, flags)
446 yield chunkdata
446 yield chunkdata
447 chain = chunkdata[0]
447 chain = chunkdata[0]
448
448
449 class cg2unpacker(cg1unpacker):
449 class cg2unpacker(cg1unpacker):
450 """Unpacker for cg2 streams.
450 """Unpacker for cg2 streams.
451
451
452 cg2 streams add support for generaldelta, so the delta header
452 cg2 streams add support for generaldelta, so the delta header
453 format is slightly different. All other features about the data
453 format is slightly different. All other features about the data
454 remain the same.
454 remain the same.
455 """
455 """
456 deltaheader = _CHANGEGROUPV2_DELTA_HEADER
456 deltaheader = _CHANGEGROUPV2_DELTA_HEADER
457 deltaheadersize = deltaheader.size
457 deltaheadersize = deltaheader.size
458 version = '02'
458 version = '02'
459
459
460 def _deltaheader(self, headertuple, prevnode):
460 def _deltaheader(self, headertuple, prevnode):
461 node, p1, p2, deltabase, cs = headertuple
461 node, p1, p2, deltabase, cs = headertuple
462 flags = 0
462 flags = 0
463 return node, p1, p2, deltabase, cs, flags
463 return node, p1, p2, deltabase, cs, flags
464
464
465 class cg3unpacker(cg2unpacker):
465 class cg3unpacker(cg2unpacker):
466 """Unpacker for cg3 streams.
466 """Unpacker for cg3 streams.
467
467
468 cg3 streams add support for exchanging treemanifests and revlog
468 cg3 streams add support for exchanging treemanifests and revlog
469 flags. It adds the revlog flags to the delta header and an empty chunk
469 flags. It adds the revlog flags to the delta header and an empty chunk
470 separating manifests and files.
470 separating manifests and files.
471 """
471 """
472 deltaheader = _CHANGEGROUPV3_DELTA_HEADER
472 deltaheader = _CHANGEGROUPV3_DELTA_HEADER
473 deltaheadersize = deltaheader.size
473 deltaheadersize = deltaheader.size
474 version = '03'
474 version = '03'
475 _grouplistcount = 2 # One list of manifests and one list of files
475 _grouplistcount = 2 # One list of manifests and one list of files
476
476
477 def _deltaheader(self, headertuple, prevnode):
477 def _deltaheader(self, headertuple, prevnode):
478 node, p1, p2, deltabase, cs, flags = headertuple
478 node, p1, p2, deltabase, cs, flags = headertuple
479 return node, p1, p2, deltabase, cs, flags
479 return node, p1, p2, deltabase, cs, flags
480
480
481 def _unpackmanifests(self, repo, revmap, trp, prog):
481 def _unpackmanifests(self, repo, revmap, trp, prog):
482 super(cg3unpacker, self)._unpackmanifests(repo, revmap, trp, prog)
482 super(cg3unpacker, self)._unpackmanifests(repo, revmap, trp, prog)
483 for chunkdata in iter(self.filelogheader, {}):
483 for chunkdata in iter(self.filelogheader, {}):
484 # If we get here, there are directory manifests in the changegroup
484 # If we get here, there are directory manifests in the changegroup
485 d = chunkdata["filename"]
485 d = chunkdata["filename"]
486 repo.ui.debug("adding %s revisions\n" % d)
486 repo.ui.debug("adding %s revisions\n" % d)
487 dirlog = repo.manifestlog._revlog.dirlog(d)
487 dirlog = repo.manifestlog._revlog.dirlog(d)
488 deltas = self.deltaiter()
488 deltas = self.deltaiter()
489 if not dirlog.addgroup(deltas, revmap, trp):
489 if not dirlog.addgroup(deltas, revmap, trp):
490 raise error.Abort(_("received dir revlog group is empty"))
490 raise error.Abort(_("received dir revlog group is empty"))
491
491
492 class headerlessfixup(object):
492 class headerlessfixup(object):
493 def __init__(self, fh, h):
493 def __init__(self, fh, h):
494 self._h = h
494 self._h = h
495 self._fh = fh
495 self._fh = fh
496 def read(self, n):
496 def read(self, n):
497 if self._h:
497 if self._h:
498 d, self._h = self._h[:n], self._h[n:]
498 d, self._h = self._h[:n], self._h[n:]
499 if len(d) < n:
499 if len(d) < n:
500 d += readexactly(self._fh, n - len(d))
500 d += readexactly(self._fh, n - len(d))
501 return d
501 return d
502 return readexactly(self._fh, n)
502 return readexactly(self._fh, n)
503
503
504 @interfaceutil.implementer(repository.irevisiondeltarequest)
504 @interfaceutil.implementer(repository.irevisiondeltarequest)
505 @attr.s(slots=True, frozen=True)
505 @attr.s(slots=True, frozen=True)
506 class revisiondeltarequest(object):
506 class revisiondeltarequest(object):
507 node = attr.ib()
507 node = attr.ib()
508 linknode = attr.ib()
508 linknode = attr.ib()
509 p1node = attr.ib()
509 p1node = attr.ib()
510 p2node = attr.ib()
510 p2node = attr.ib()
511 basenode = attr.ib()
511 basenode = attr.ib()
512 ellipsis = attr.ib(default=False)
512 ellipsis = attr.ib(default=False)
513
513
514 def _revisiondeltatochunks(delta, headerfn):
514 def _revisiondeltatochunks(delta, headerfn):
515 """Serialize a revisiondelta to changegroup chunks."""
515 """Serialize a revisiondelta to changegroup chunks."""
516
516
517 # The captured revision delta may be encoded as a delta against
517 # The captured revision delta may be encoded as a delta against
518 # a base revision or as a full revision. The changegroup format
518 # a base revision or as a full revision. The changegroup format
519 # requires that everything on the wire be deltas. So for full
519 # requires that everything on the wire be deltas. So for full
520 # revisions, we need to invent a header that says to rewrite
520 # revisions, we need to invent a header that says to rewrite
521 # data.
521 # data.
522
522
523 if delta.delta is not None:
523 if delta.delta is not None:
524 prefix, data = b'', delta.delta
524 prefix, data = b'', delta.delta
525 elif delta.basenode == nullid:
525 elif delta.basenode == nullid:
526 data = delta.revision
526 data = delta.revision
527 prefix = mdiff.trivialdiffheader(len(data))
527 prefix = mdiff.trivialdiffheader(len(data))
528 else:
528 else:
529 data = delta.revision
529 data = delta.revision
530 prefix = mdiff.replacediffheader(delta.baserevisionsize,
530 prefix = mdiff.replacediffheader(delta.baserevisionsize,
531 len(data))
531 len(data))
532
532
533 meta = headerfn(delta)
533 meta = headerfn(delta)
534
534
535 yield chunkheader(len(meta) + len(prefix) + len(data))
535 yield chunkheader(len(meta) + len(prefix) + len(data))
536 yield meta
536 yield meta
537 if prefix:
537 if prefix:
538 yield prefix
538 yield prefix
539 yield data
539 yield data
540
540
541 def _sortnodesnormal(store, nodes, reorder):
541 def _sortnodesnormal(store, nodes, reorder):
542 """Sort nodes for changegroup generation and turn into revnums."""
542 """Sort nodes for changegroup generation and turn into revnums."""
543 # for generaldelta revlogs, we linearize the revs; this will both be
543 # for generaldelta revlogs, we linearize the revs; this will both be
544 # much quicker and generate a much smaller bundle
544 # much quicker and generate a much smaller bundle
545 if (store._generaldelta and reorder is None) or reorder:
545 if (store._generaldelta and reorder is None) or reorder:
546 revs = set(store.rev(n) for n in nodes)
546 revs = set(store.rev(n) for n in nodes)
547 return dagop.linearize(revs, store.parentrevs)
547 return dagop.linearize(revs, store.parentrevs)
548 else:
548 else:
549 return sorted([store.rev(n) for n in nodes])
549 return sorted([store.rev(n) for n in nodes])
550
550
551 def _sortnodesellipsis(store, nodes, cl, lookup):
551 def _sortnodesellipsis(store, nodes, cl, lookup):
552 """Sort nodes for changegroup generation and turn into revnums."""
552 """Sort nodes for changegroup generation and turn into revnums."""
553 # Ellipses serving mode.
553 # Ellipses serving mode.
554 #
554 #
555 # In a perfect world, we'd generate better ellipsis-ified graphs
555 # In a perfect world, we'd generate better ellipsis-ified graphs
556 # for non-changelog revlogs. In practice, we haven't started doing
556 # for non-changelog revlogs. In practice, we haven't started doing
557 # that yet, so the resulting DAGs for the manifestlog and filelogs
557 # that yet, so the resulting DAGs for the manifestlog and filelogs
558 # are actually full of bogus parentage on all the ellipsis
558 # are actually full of bogus parentage on all the ellipsis
559 # nodes. This has the side effect that, while the contents are
559 # nodes. This has the side effect that, while the contents are
560 # correct, the individual DAGs might be completely out of whack in
560 # correct, the individual DAGs might be completely out of whack in
561 # a case like 882681bc3166 and its ancestors (back about 10
561 # a case like 882681bc3166 and its ancestors (back about 10
562 # revisions or so) in the main hg repo.
562 # revisions or so) in the main hg repo.
563 #
563 #
564 # The one invariant we *know* holds is that the new (potentially
564 # The one invariant we *know* holds is that the new (potentially
565 # bogus) DAG shape will be valid if we order the nodes in the
565 # bogus) DAG shape will be valid if we order the nodes in the
566 # order that they're introduced in dramatis personae by the
566 # order that they're introduced in dramatis personae by the
567 # changelog, so what we do is we sort the non-changelog histories
567 # changelog, so what we do is we sort the non-changelog histories
568 # by the order in which they are used by the changelog.
568 # by the order in which they are used by the changelog.
569 key = lambda n: cl.rev(lookup(n))
569 key = lambda n: cl.rev(lookup(n))
570 return [store.rev(n) for n in sorted(nodes, key=key)]
570 return [store.rev(n) for n in sorted(nodes, key=key)]
571
571
572 def _makenarrowdeltarequest(cl, store, ischangelog, rev, node, linkrev,
572 def _makenarrowdeltarequest(cl, store, ischangelog, rev, node, linkrev,
573 linknode, clrevtolocalrev, fullclnodes,
573 linknode, clrevtolocalrev, fullclnodes,
574 precomputedellipsis):
574 precomputedellipsis):
575 linkparents = precomputedellipsis[linkrev]
575 linkparents = precomputedellipsis[linkrev]
576 def local(clrev):
576 def local(clrev):
577 """Turn a changelog revnum into a local revnum.
577 """Turn a changelog revnum into a local revnum.
578
578
579 The ellipsis dag is stored as revnums on the changelog,
579 The ellipsis dag is stored as revnums on the changelog,
580 but when we're producing ellipsis entries for
580 but when we're producing ellipsis entries for
581 non-changelog revlogs, we need to turn those numbers into
581 non-changelog revlogs, we need to turn those numbers into
582 something local. This does that for us, and during the
582 something local. This does that for us, and during the
583 changelog sending phase will also expand the stored
583 changelog sending phase will also expand the stored
584 mappings as needed.
584 mappings as needed.
585 """
585 """
586 if clrev == nullrev:
586 if clrev == nullrev:
587 return nullrev
587 return nullrev
588
588
589 if ischangelog:
589 if ischangelog:
590 return clrev
590 return clrev
591
591
592 # Walk the ellipsis-ized changelog breadth-first looking for a
592 # Walk the ellipsis-ized changelog breadth-first looking for a
593 # change that has been linked from the current revlog.
593 # change that has been linked from the current revlog.
594 #
594 #
595 # For a flat manifest revlog only a single step should be necessary
595 # For a flat manifest revlog only a single step should be necessary
596 # as all relevant changelog entries are relevant to the flat
596 # as all relevant changelog entries are relevant to the flat
597 # manifest.
597 # manifest.
598 #
598 #
599 # For a filelog or tree manifest dirlog however not every changelog
599 # For a filelog or tree manifest dirlog however not every changelog
600 # entry will have been relevant, so we need to skip some changelog
600 # entry will have been relevant, so we need to skip some changelog
601 # nodes even after ellipsis-izing.
601 # nodes even after ellipsis-izing.
602 walk = [clrev]
602 walk = [clrev]
603 while walk:
603 while walk:
604 p = walk[0]
604 p = walk[0]
605 walk = walk[1:]
605 walk = walk[1:]
606 if p in clrevtolocalrev:
606 if p in clrevtolocalrev:
607 return clrevtolocalrev[p]
607 return clrevtolocalrev[p]
608 elif p in fullclnodes:
608 elif p in fullclnodes:
609 walk.extend([pp for pp in cl.parentrevs(p)
609 walk.extend([pp for pp in cl.parentrevs(p)
610 if pp != nullrev])
610 if pp != nullrev])
611 elif p in precomputedellipsis:
611 elif p in precomputedellipsis:
612 walk.extend([pp for pp in precomputedellipsis[p]
612 walk.extend([pp for pp in precomputedellipsis[p]
613 if pp != nullrev])
613 if pp != nullrev])
614 else:
614 else:
615 # In this case, we've got an ellipsis with parents
615 # In this case, we've got an ellipsis with parents
616 # outside the current bundle (likely an
616 # outside the current bundle (likely an
617 # incremental pull). We "know" that we can use the
617 # incremental pull). We "know" that we can use the
618 # value of this same revlog at whatever revision
618 # value of this same revlog at whatever revision
619 # is pointed to by linknode. "Know" is in scare
619 # is pointed to by linknode. "Know" is in scare
620 # quotes because I haven't done enough examination
620 # quotes because I haven't done enough examination
621 # of edge cases to convince myself this is really
621 # of edge cases to convince myself this is really
622 # a fact - it works for all the (admittedly
622 # a fact - it works for all the (admittedly
623 # thorough) cases in our testsuite, but I would be
623 # thorough) cases in our testsuite, but I would be
624 # somewhat unsurprised to find a case in the wild
624 # somewhat unsurprised to find a case in the wild
625 # where this breaks down a bit. That said, I don't
625 # where this breaks down a bit. That said, I don't
626 # know if it would hurt anything.
626 # know if it would hurt anything.
627 for i in pycompat.xrange(rev, 0, -1):
627 for i in pycompat.xrange(rev, 0, -1):
628 if store.linkrev(i) == clrev:
628 if store.linkrev(i) == clrev:
629 return i
629 return i
630 # We failed to resolve a parent for this node, so
630 # We failed to resolve a parent for this node, so
631 # we crash the changegroup construction.
631 # we crash the changegroup construction.
632 raise error.Abort(
632 raise error.Abort(
633 'unable to resolve parent while packing %r %r'
633 'unable to resolve parent while packing %r %r'
634 ' for changeset %r' % (store.indexfile, rev, clrev))
634 ' for changeset %r' % (store.indexfile, rev, clrev))
635
635
636 return nullrev
636 return nullrev
637
637
638 if not linkparents or (
638 if not linkparents or (
639 store.parentrevs(rev) == (nullrev, nullrev)):
639 store.parentrevs(rev) == (nullrev, nullrev)):
640 p1, p2 = nullrev, nullrev
640 p1, p2 = nullrev, nullrev
641 elif len(linkparents) == 1:
641 elif len(linkparents) == 1:
642 p1, = sorted(local(p) for p in linkparents)
642 p1, = sorted(local(p) for p in linkparents)
643 p2 = nullrev
643 p2 = nullrev
644 else:
644 else:
645 p1, p2 = sorted(local(p) for p in linkparents)
645 p1, p2 = sorted(local(p) for p in linkparents)
646
646
647 p1node, p2node = store.node(p1), store.node(p2)
647 p1node, p2node = store.node(p1), store.node(p2)
648
648
649 # TODO: try and actually send deltas for ellipsis data blocks
649 # TODO: try and actually send deltas for ellipsis data blocks
650 return revisiondeltarequest(
650 return revisiondeltarequest(
651 node=node,
651 node=node,
652 p1node=p1node,
652 p1node=p1node,
653 p2node=p2node,
653 p2node=p2node,
654 linknode=linknode,
654 linknode=linknode,
655 basenode=nullid,
655 basenode=nullid,
656 ellipsis=True,
656 ellipsis=True,
657 )
657 )
658
658
659 def deltagroup(repo, store, nodes, ischangelog, lookup, forcedeltaparentprev,
659 def deltagroup(repo, store, nodes, ischangelog, lookup, forcedeltaparentprev,
660 allowreorder,
660 allowreorder,
661 units=None,
661 topic=None,
662 ellipses=False, clrevtolocalrev=None, fullclnodes=None,
662 ellipses=False, clrevtolocalrev=None, fullclnodes=None,
663 precomputedellipsis=None):
663 precomputedellipsis=None):
664 """Calculate deltas for a set of revisions.
664 """Calculate deltas for a set of revisions.
665
665
666 Is a generator of ``revisiondelta`` instances.
666 Is a generator of ``revisiondelta`` instances.
667
667
668 If units is not None, progress detail will be generated, units specifies
668 If topic is not None, progress detail will be generated using this
669 the type of revlog that is touched (changelog, manifest, etc.).
669 topic name (e.g. changesets, manifests, etc).
670 """
670 """
671 if not nodes:
671 if not nodes:
672 return
672 return
673
673
674 # We perform two passes over the revisions whose data we will emit.
674 # We perform two passes over the revisions whose data we will emit.
675 #
675 #
676 # In the first pass, we obtain information about the deltas that will
676 # In the first pass, we obtain information about the deltas that will
677 # be generated. This involves computing linknodes and adjusting the
677 # be generated. This involves computing linknodes and adjusting the
678 # request to take shallow fetching into account. The end result of
678 # request to take shallow fetching into account. The end result of
679 # this pass is a list of "request" objects stating which deltas
679 # this pass is a list of "request" objects stating which deltas
680 # to obtain.
680 # to obtain.
681 #
681 #
682 # The second pass is simply resolving the requested deltas.
682 # The second pass is simply resolving the requested deltas.
683
683
684 cl = repo.changelog
684 cl = repo.changelog
685
685
686 if ischangelog:
686 if ischangelog:
687 # Changelog doesn't benefit from reordering revisions. So send
687 # Changelog doesn't benefit from reordering revisions. So send
688 # out revisions in store order.
688 # out revisions in store order.
689 # TODO the API would be cleaner if this were controlled by the
689 # TODO the API would be cleaner if this were controlled by the
690 # store producing the deltas.
690 # store producing the deltas.
691 revs = sorted(cl.rev(n) for n in nodes)
691 revs = sorted(cl.rev(n) for n in nodes)
692 elif ellipses:
692 elif ellipses:
693 revs = _sortnodesellipsis(store, nodes, cl, lookup)
693 revs = _sortnodesellipsis(store, nodes, cl, lookup)
694 else:
694 else:
695 revs = _sortnodesnormal(store, nodes, allowreorder)
695 revs = _sortnodesnormal(store, nodes, allowreorder)
696
696
697 # In the first pass, collect info about the deltas we'll be
697 # In the first pass, collect info about the deltas we'll be
698 # generating.
698 # generating.
699 requests = []
699 requests = []
700
700
701 # Add the parent of the first rev.
701 # Add the parent of the first rev.
702 revs.insert(0, store.parentrevs(revs[0])[0])
702 revs.insert(0, store.parentrevs(revs[0])[0])
703
703
704 for i in pycompat.xrange(len(revs) - 1):
704 for i in pycompat.xrange(len(revs) - 1):
705 prev = revs[i]
705 prev = revs[i]
706 curr = revs[i + 1]
706 curr = revs[i + 1]
707
707
708 node = store.node(curr)
708 node = store.node(curr)
709 linknode = lookup(node)
709 linknode = lookup(node)
710 p1node, p2node = store.parents(node)
710 p1node, p2node = store.parents(node)
711
711
712 if ellipses:
712 if ellipses:
713 linkrev = cl.rev(linknode)
713 linkrev = cl.rev(linknode)
714 clrevtolocalrev[linkrev] = curr
714 clrevtolocalrev[linkrev] = curr
715
715
716 # This is a node to send in full, because the changeset it
716 # This is a node to send in full, because the changeset it
717 # corresponds to was a full changeset.
717 # corresponds to was a full changeset.
718 if linknode in fullclnodes:
718 if linknode in fullclnodes:
719 requests.append(revisiondeltarequest(
719 requests.append(revisiondeltarequest(
720 node=node,
720 node=node,
721 p1node=p1node,
721 p1node=p1node,
722 p2node=p2node,
722 p2node=p2node,
723 linknode=linknode,
723 linknode=linknode,
724 basenode=None,
724 basenode=None,
725 ))
725 ))
726
726
727 elif linkrev not in precomputedellipsis:
727 elif linkrev not in precomputedellipsis:
728 pass
728 pass
729 else:
729 else:
730 requests.append(_makenarrowdeltarequest(
730 requests.append(_makenarrowdeltarequest(
731 cl, store, ischangelog, curr, node, linkrev, linknode,
731 cl, store, ischangelog, curr, node, linkrev, linknode,
732 clrevtolocalrev, fullclnodes,
732 clrevtolocalrev, fullclnodes,
733 precomputedellipsis))
733 precomputedellipsis))
734 else:
734 else:
735 requests.append(revisiondeltarequest(
735 requests.append(revisiondeltarequest(
736 node=node,
736 node=node,
737 p1node=p1node,
737 p1node=p1node,
738 p2node=p2node,
738 p2node=p2node,
739 linknode=linknode,
739 linknode=linknode,
740 basenode=store.node(prev) if forcedeltaparentprev else None,
740 basenode=store.node(prev) if forcedeltaparentprev else None,
741 ))
741 ))
742
742
743 # We expect the first pass to be fast, so we only engage the progress
743 # We expect the first pass to be fast, so we only engage the progress
744 # meter for constructing the revision deltas.
744 # meter for constructing the revision deltas.
745 progress = None
745 progress = None
746 if units is not None:
746 if topic is not None:
747 progress = repo.ui.makeprogress(_('bundling'), unit=units,
747 progress = repo.ui.makeprogress(topic, unit=_('chunks'),
748 total=len(requests))
748 total=len(requests))
749
749
750 for i, delta in enumerate(store.emitrevisiondeltas(requests)):
750 for i, delta in enumerate(store.emitrevisiondeltas(requests)):
751 if progress:
751 if progress:
752 progress.update(i + 1)
752 progress.update(i + 1)
753
753
754 yield delta
754 yield delta
755
755
756 if progress:
756 if progress:
757 progress.complete()
757 progress.complete()
758
758
759 class cgpacker(object):
759 class cgpacker(object):
760 def __init__(self, repo, filematcher, version, allowreorder,
760 def __init__(self, repo, filematcher, version, allowreorder,
761 builddeltaheader, manifestsend,
761 builddeltaheader, manifestsend,
762 forcedeltaparentprev=False,
762 forcedeltaparentprev=False,
763 bundlecaps=None, ellipses=False,
763 bundlecaps=None, ellipses=False,
764 shallow=False, ellipsisroots=None, fullnodes=None):
764 shallow=False, ellipsisroots=None, fullnodes=None):
765 """Given a source repo, construct a bundler.
765 """Given a source repo, construct a bundler.
766
766
767 filematcher is a matcher that matches on files to include in the
767 filematcher is a matcher that matches on files to include in the
768 changegroup. Used to facilitate sparse changegroups.
768 changegroup. Used to facilitate sparse changegroups.
769
769
770 allowreorder controls whether reordering of revisions is allowed.
770 allowreorder controls whether reordering of revisions is allowed.
771 This value is used when ``bundle.reorder`` is ``auto`` or isn't
771 This value is used when ``bundle.reorder`` is ``auto`` or isn't
772 set.
772 set.
773
773
774 forcedeltaparentprev indicates whether delta parents must be against
774 forcedeltaparentprev indicates whether delta parents must be against
775 the previous revision in a delta group. This should only be used for
775 the previous revision in a delta group. This should only be used for
776 compatibility with changegroup version 1.
776 compatibility with changegroup version 1.
777
777
778 builddeltaheader is a callable that constructs the header for a group
778 builddeltaheader is a callable that constructs the header for a group
779 delta.
779 delta.
780
780
781 manifestsend is a chunk to send after manifests have been fully emitted.
781 manifestsend is a chunk to send after manifests have been fully emitted.
782
782
783 ellipses indicates whether ellipsis serving mode is enabled.
783 ellipses indicates whether ellipsis serving mode is enabled.
784
784
785 bundlecaps is optional and can be used to specify the set of
785 bundlecaps is optional and can be used to specify the set of
786 capabilities which can be used to build the bundle. While bundlecaps is
786 capabilities which can be used to build the bundle. While bundlecaps is
787 unused in core Mercurial, extensions rely on this feature to communicate
787 unused in core Mercurial, extensions rely on this feature to communicate
788 capabilities to customize the changegroup packer.
788 capabilities to customize the changegroup packer.
789
789
790 shallow indicates whether shallow data might be sent. The packer may
790 shallow indicates whether shallow data might be sent. The packer may
791 need to pack file contents not introduced by the changes being packed.
791 need to pack file contents not introduced by the changes being packed.
792
792
793 fullnodes is the set of changelog nodes which should not be ellipsis
793 fullnodes is the set of changelog nodes which should not be ellipsis
794 nodes. We store this rather than the set of nodes that should be
794 nodes. We store this rather than the set of nodes that should be
795 ellipsis because for very large histories we expect this to be
795 ellipsis because for very large histories we expect this to be
796 significantly smaller.
796 significantly smaller.
797 """
797 """
798 assert filematcher
798 assert filematcher
799 self._filematcher = filematcher
799 self._filematcher = filematcher
800
800
801 self.version = version
801 self.version = version
802 self._forcedeltaparentprev = forcedeltaparentprev
802 self._forcedeltaparentprev = forcedeltaparentprev
803 self._builddeltaheader = builddeltaheader
803 self._builddeltaheader = builddeltaheader
804 self._manifestsend = manifestsend
804 self._manifestsend = manifestsend
805 self._ellipses = ellipses
805 self._ellipses = ellipses
806
806
807 # Set of capabilities we can use to build the bundle.
807 # Set of capabilities we can use to build the bundle.
808 if bundlecaps is None:
808 if bundlecaps is None:
809 bundlecaps = set()
809 bundlecaps = set()
810 self._bundlecaps = bundlecaps
810 self._bundlecaps = bundlecaps
811 self._isshallow = shallow
811 self._isshallow = shallow
812 self._fullclnodes = fullnodes
812 self._fullclnodes = fullnodes
813
813
814 # Maps ellipsis revs to their roots at the changelog level.
814 # Maps ellipsis revs to their roots at the changelog level.
815 self._precomputedellipsis = ellipsisroots
815 self._precomputedellipsis = ellipsisroots
816
816
817 # experimental config: bundle.reorder
817 # experimental config: bundle.reorder
818 reorder = repo.ui.config('bundle', 'reorder')
818 reorder = repo.ui.config('bundle', 'reorder')
819 if reorder == 'auto':
819 if reorder == 'auto':
820 self._reorder = allowreorder
820 self._reorder = allowreorder
821 else:
821 else:
822 self._reorder = stringutil.parsebool(reorder)
822 self._reorder = stringutil.parsebool(reorder)
823
823
824 self._repo = repo
824 self._repo = repo
825
825
826 if self._repo.ui.verbose and not self._repo.ui.debugflag:
826 if self._repo.ui.verbose and not self._repo.ui.debugflag:
827 self._verbosenote = self._repo.ui.note
827 self._verbosenote = self._repo.ui.note
828 else:
828 else:
829 self._verbosenote = lambda s: None
829 self._verbosenote = lambda s: None
830
830
831 def generate(self, commonrevs, clnodes, fastpathlinkrev, source):
831 def generate(self, commonrevs, clnodes, fastpathlinkrev, source):
832 """Yield a sequence of changegroup byte chunks."""
832 """Yield a sequence of changegroup byte chunks."""
833
833
834 repo = self._repo
834 repo = self._repo
835 cl = repo.changelog
835 cl = repo.changelog
836
836
837 self._verbosenote(_('uncompressed size of bundle content:\n'))
837 self._verbosenote(_('uncompressed size of bundle content:\n'))
838 size = 0
838 size = 0
839
839
840 clstate, deltas = self._generatechangelog(cl, clnodes)
840 clstate, deltas = self._generatechangelog(cl, clnodes)
841 for delta in deltas:
841 for delta in deltas:
842 for chunk in _revisiondeltatochunks(delta, self._builddeltaheader):
842 for chunk in _revisiondeltatochunks(delta, self._builddeltaheader):
843 size += len(chunk)
843 size += len(chunk)
844 yield chunk
844 yield chunk
845
845
846 close = closechunk()
846 close = closechunk()
847 size += len(close)
847 size += len(close)
848 yield closechunk()
848 yield closechunk()
849
849
850 self._verbosenote(_('%8.i (changelog)\n') % size)
850 self._verbosenote(_('%8.i (changelog)\n') % size)
851
851
852 clrevorder = clstate['clrevorder']
852 clrevorder = clstate['clrevorder']
853 manifests = clstate['manifests']
853 manifests = clstate['manifests']
854 changedfiles = clstate['changedfiles']
854 changedfiles = clstate['changedfiles']
855
855
856 # We need to make sure that the linkrev in the changegroup refers to
856 # We need to make sure that the linkrev in the changegroup refers to
857 # the first changeset that introduced the manifest or file revision.
857 # the first changeset that introduced the manifest or file revision.
858 # The fastpath is usually safer than the slowpath, because the filelogs
858 # The fastpath is usually safer than the slowpath, because the filelogs
859 # are walked in revlog order.
859 # are walked in revlog order.
860 #
860 #
861 # When taking the slowpath with reorder=None and the manifest revlog
861 # When taking the slowpath with reorder=None and the manifest revlog
862 # uses generaldelta, the manifest may be walked in the "wrong" order.
862 # uses generaldelta, the manifest may be walked in the "wrong" order.
863 # Without 'clrevorder', we would get an incorrect linkrev (see fix in
863 # Without 'clrevorder', we would get an incorrect linkrev (see fix in
864 # cc0ff93d0c0c).
864 # cc0ff93d0c0c).
865 #
865 #
866 # When taking the fastpath, we are only vulnerable to reordering
866 # When taking the fastpath, we are only vulnerable to reordering
867 # of the changelog itself. The changelog never uses generaldelta, so
867 # of the changelog itself. The changelog never uses generaldelta, so
868 # it is only reordered when reorder=True. To handle this case, we
868 # it is only reordered when reorder=True. To handle this case, we
869 # simply take the slowpath, which already has the 'clrevorder' logic.
869 # simply take the slowpath, which already has the 'clrevorder' logic.
870 # This was also fixed in cc0ff93d0c0c.
870 # This was also fixed in cc0ff93d0c0c.
871 fastpathlinkrev = fastpathlinkrev and not self._reorder
871 fastpathlinkrev = fastpathlinkrev and not self._reorder
872 # Treemanifests don't work correctly with fastpathlinkrev
872 # Treemanifests don't work correctly with fastpathlinkrev
873 # either, because we don't discover which directory nodes to
873 # either, because we don't discover which directory nodes to
874 # send along with files. This could probably be fixed.
874 # send along with files. This could probably be fixed.
875 fastpathlinkrev = fastpathlinkrev and (
875 fastpathlinkrev = fastpathlinkrev and (
876 'treemanifest' not in repo.requirements)
876 'treemanifest' not in repo.requirements)
877
877
878 fnodes = {} # needed file nodes
878 fnodes = {} # needed file nodes
879
879
880 size = 0
880 size = 0
881 it = self.generatemanifests(
881 it = self.generatemanifests(
882 commonrevs, clrevorder, fastpathlinkrev, manifests, fnodes, source,
882 commonrevs, clrevorder, fastpathlinkrev, manifests, fnodes, source,
883 clstate['clrevtomanifestrev'])
883 clstate['clrevtomanifestrev'])
884
884
885 for tree, deltas in it:
885 for tree, deltas in it:
886 if tree:
886 if tree:
887 assert self.version == b'03'
887 assert self.version == b'03'
888 chunk = _fileheader(tree)
888 chunk = _fileheader(tree)
889 size += len(chunk)
889 size += len(chunk)
890 yield chunk
890 yield chunk
891
891
892 for delta in deltas:
892 for delta in deltas:
893 chunks = _revisiondeltatochunks(delta, self._builddeltaheader)
893 chunks = _revisiondeltatochunks(delta, self._builddeltaheader)
894 for chunk in chunks:
894 for chunk in chunks:
895 size += len(chunk)
895 size += len(chunk)
896 yield chunk
896 yield chunk
897
897
898 close = closechunk()
898 close = closechunk()
899 size += len(close)
899 size += len(close)
900 yield close
900 yield close
901
901
902 self._verbosenote(_('%8.i (manifests)\n') % size)
902 self._verbosenote(_('%8.i (manifests)\n') % size)
903 yield self._manifestsend
903 yield self._manifestsend
904
904
905 mfdicts = None
905 mfdicts = None
906 if self._ellipses and self._isshallow:
906 if self._ellipses and self._isshallow:
907 mfdicts = [(self._repo.manifestlog[n].read(), lr)
907 mfdicts = [(self._repo.manifestlog[n].read(), lr)
908 for (n, lr) in manifests.iteritems()]
908 for (n, lr) in manifests.iteritems()]
909
909
910 manifests.clear()
910 manifests.clear()
911 clrevs = set(cl.rev(x) for x in clnodes)
911 clrevs = set(cl.rev(x) for x in clnodes)
912
912
913 it = self.generatefiles(changedfiles, commonrevs,
913 it = self.generatefiles(changedfiles, commonrevs,
914 source, mfdicts, fastpathlinkrev,
914 source, mfdicts, fastpathlinkrev,
915 fnodes, clrevs)
915 fnodes, clrevs)
916
916
917 for path, deltas in it:
917 for path, deltas in it:
918 h = _fileheader(path)
918 h = _fileheader(path)
919 size = len(h)
919 size = len(h)
920 yield h
920 yield h
921
921
922 for delta in deltas:
922 for delta in deltas:
923 chunks = _revisiondeltatochunks(delta, self._builddeltaheader)
923 chunks = _revisiondeltatochunks(delta, self._builddeltaheader)
924 for chunk in chunks:
924 for chunk in chunks:
925 size += len(chunk)
925 size += len(chunk)
926 yield chunk
926 yield chunk
927
927
928 close = closechunk()
928 close = closechunk()
929 size += len(close)
929 size += len(close)
930 yield close
930 yield close
931
931
932 self._verbosenote(_('%8.i %s\n') % (size, path))
932 self._verbosenote(_('%8.i %s\n') % (size, path))
933
933
934 yield closechunk()
934 yield closechunk()
935
935
936 if clnodes:
936 if clnodes:
937 repo.hook('outgoing', node=hex(clnodes[0]), source=source)
937 repo.hook('outgoing', node=hex(clnodes[0]), source=source)
938
938
939 def _generatechangelog(self, cl, nodes):
939 def _generatechangelog(self, cl, nodes):
940 """Generate data for changelog chunks.
940 """Generate data for changelog chunks.
941
941
942 Returns a 2-tuple of a dict containing state and an iterable of
942 Returns a 2-tuple of a dict containing state and an iterable of
943 byte chunks. The state will not be fully populated until the
943 byte chunks. The state will not be fully populated until the
944 chunk stream has been fully consumed.
944 chunk stream has been fully consumed.
945 """
945 """
946 clrevorder = {}
946 clrevorder = {}
947 manifests = {}
947 manifests = {}
948 mfl = self._repo.manifestlog
948 mfl = self._repo.manifestlog
949 changedfiles = set()
949 changedfiles = set()
950 clrevtomanifestrev = {}
950 clrevtomanifestrev = {}
951
951
952 # Callback for the changelog, used to collect changed files and
952 # Callback for the changelog, used to collect changed files and
953 # manifest nodes.
953 # manifest nodes.
954 # Returns the linkrev node (identity in the changelog case).
954 # Returns the linkrev node (identity in the changelog case).
955 def lookupcl(x):
955 def lookupcl(x):
956 c = cl.changelogrevision(x)
956 c = cl.changelogrevision(x)
957 clrevorder[x] = len(clrevorder)
957 clrevorder[x] = len(clrevorder)
958
958
959 if self._ellipses:
959 if self._ellipses:
960 # Only update manifests if x is going to be sent. Otherwise we
960 # Only update manifests if x is going to be sent. Otherwise we
961 # end up with bogus linkrevs specified for manifests and
961 # end up with bogus linkrevs specified for manifests and
962 # we skip some manifest nodes that we should otherwise
962 # we skip some manifest nodes that we should otherwise
963 # have sent.
963 # have sent.
964 if (x in self._fullclnodes
964 if (x in self._fullclnodes
965 or cl.rev(x) in self._precomputedellipsis):
965 or cl.rev(x) in self._precomputedellipsis):
966
966
967 manifestnode = c.manifest
967 manifestnode = c.manifest
968 # Record the first changeset introducing this manifest
968 # Record the first changeset introducing this manifest
969 # version.
969 # version.
970 manifests.setdefault(manifestnode, x)
970 manifests.setdefault(manifestnode, x)
971 # Set this narrow-specific dict so we have the lowest
971 # Set this narrow-specific dict so we have the lowest
972 # manifest revnum to look up for this cl revnum. (Part of
972 # manifest revnum to look up for this cl revnum. (Part of
973 # mapping changelog ellipsis parents to manifest ellipsis
973 # mapping changelog ellipsis parents to manifest ellipsis
974 # parents)
974 # parents)
975 clrevtomanifestrev.setdefault(
975 clrevtomanifestrev.setdefault(
976 cl.rev(x), mfl.rev(manifestnode))
976 cl.rev(x), mfl.rev(manifestnode))
977 # We can't trust the changed files list in the changeset if the
977 # We can't trust the changed files list in the changeset if the
978 # client requested a shallow clone.
978 # client requested a shallow clone.
979 if self._isshallow:
979 if self._isshallow:
980 changedfiles.update(mfl[c.manifest].read().keys())
980 changedfiles.update(mfl[c.manifest].read().keys())
981 else:
981 else:
982 changedfiles.update(c.files)
982 changedfiles.update(c.files)
983 else:
983 else:
984 # record the first changeset introducing this manifest version
984 # record the first changeset introducing this manifest version
985 manifests.setdefault(c.manifest, x)
985 manifests.setdefault(c.manifest, x)
986 # Record a complete list of potentially-changed files in
986 # Record a complete list of potentially-changed files in
987 # this manifest.
987 # this manifest.
988 changedfiles.update(c.files)
988 changedfiles.update(c.files)
989
989
990 return x
990 return x
991
991
992 state = {
992 state = {
993 'clrevorder': clrevorder,
993 'clrevorder': clrevorder,
994 'manifests': manifests,
994 'manifests': manifests,
995 'changedfiles': changedfiles,
995 'changedfiles': changedfiles,
996 'clrevtomanifestrev': clrevtomanifestrev,
996 'clrevtomanifestrev': clrevtomanifestrev,
997 }
997 }
998
998
999 gen = deltagroup(
999 gen = deltagroup(
1000 self._repo, cl, nodes, True, lookupcl,
1000 self._repo, cl, nodes, True, lookupcl,
1001 self._forcedeltaparentprev,
1001 self._forcedeltaparentprev,
1002 # Reorder settings are currently ignored for changelog.
1002 # Reorder settings are currently ignored for changelog.
1003 True,
1003 True,
1004 ellipses=self._ellipses,
1004 ellipses=self._ellipses,
1005 units=_('changesets'),
1005 topic=_('changesets'),
1006 clrevtolocalrev={},
1006 clrevtolocalrev={},
1007 fullclnodes=self._fullclnodes,
1007 fullclnodes=self._fullclnodes,
1008 precomputedellipsis=self._precomputedellipsis)
1008 precomputedellipsis=self._precomputedellipsis)
1009
1009
1010 return state, gen
1010 return state, gen
1011
1011
1012 def generatemanifests(self, commonrevs, clrevorder, fastpathlinkrev,
1012 def generatemanifests(self, commonrevs, clrevorder, fastpathlinkrev,
1013 manifests, fnodes, source, clrevtolocalrev):
1013 manifests, fnodes, source, clrevtolocalrev):
1014 """Returns an iterator of changegroup chunks containing manifests.
1014 """Returns an iterator of changegroup chunks containing manifests.
1015
1015
1016 `source` is unused here, but is used by extensions like remotefilelog to
1016 `source` is unused here, but is used by extensions like remotefilelog to
1017 change what is sent based in pulls vs pushes, etc.
1017 change what is sent based in pulls vs pushes, etc.
1018 """
1018 """
1019 repo = self._repo
1019 repo = self._repo
1020 mfl = repo.manifestlog
1020 mfl = repo.manifestlog
1021 dirlog = mfl._revlog.dirlog
1021 dirlog = mfl._revlog.dirlog
1022 tmfnodes = {'': manifests}
1022 tmfnodes = {'': manifests}
1023
1023
1024 # Callback for the manifest, used to collect linkrevs for filelog
1024 # Callback for the manifest, used to collect linkrevs for filelog
1025 # revisions.
1025 # revisions.
1026 # Returns the linkrev node (collected in lookupcl).
1026 # Returns the linkrev node (collected in lookupcl).
1027 def makelookupmflinknode(tree, nodes):
1027 def makelookupmflinknode(tree, nodes):
1028 if fastpathlinkrev:
1028 if fastpathlinkrev:
1029 assert not tree
1029 assert not tree
1030 return manifests.__getitem__
1030 return manifests.__getitem__
1031
1031
1032 def lookupmflinknode(x):
1032 def lookupmflinknode(x):
1033 """Callback for looking up the linknode for manifests.
1033 """Callback for looking up the linknode for manifests.
1034
1034
1035 Returns the linkrev node for the specified manifest.
1035 Returns the linkrev node for the specified manifest.
1036
1036
1037 SIDE EFFECT:
1037 SIDE EFFECT:
1038
1038
1039 1) fclnodes gets populated with the list of relevant
1039 1) fclnodes gets populated with the list of relevant
1040 file nodes if we're not using fastpathlinkrev
1040 file nodes if we're not using fastpathlinkrev
1041 2) When treemanifests are in use, collects treemanifest nodes
1041 2) When treemanifests are in use, collects treemanifest nodes
1042 to send
1042 to send
1043
1043
1044 Note that this means manifests must be completely sent to
1044 Note that this means manifests must be completely sent to
1045 the client before you can trust the list of files and
1045 the client before you can trust the list of files and
1046 treemanifests to send.
1046 treemanifests to send.
1047 """
1047 """
1048 clnode = nodes[x]
1048 clnode = nodes[x]
1049 mdata = mfl.get(tree, x).readfast(shallow=True)
1049 mdata = mfl.get(tree, x).readfast(shallow=True)
1050 for p, n, fl in mdata.iterentries():
1050 for p, n, fl in mdata.iterentries():
1051 if fl == 't': # subdirectory manifest
1051 if fl == 't': # subdirectory manifest
1052 subtree = tree + p + '/'
1052 subtree = tree + p + '/'
1053 tmfclnodes = tmfnodes.setdefault(subtree, {})
1053 tmfclnodes = tmfnodes.setdefault(subtree, {})
1054 tmfclnode = tmfclnodes.setdefault(n, clnode)
1054 tmfclnode = tmfclnodes.setdefault(n, clnode)
1055 if clrevorder[clnode] < clrevorder[tmfclnode]:
1055 if clrevorder[clnode] < clrevorder[tmfclnode]:
1056 tmfclnodes[n] = clnode
1056 tmfclnodes[n] = clnode
1057 else:
1057 else:
1058 f = tree + p
1058 f = tree + p
1059 fclnodes = fnodes.setdefault(f, {})
1059 fclnodes = fnodes.setdefault(f, {})
1060 fclnode = fclnodes.setdefault(n, clnode)
1060 fclnode = fclnodes.setdefault(n, clnode)
1061 if clrevorder[clnode] < clrevorder[fclnode]:
1061 if clrevorder[clnode] < clrevorder[fclnode]:
1062 fclnodes[n] = clnode
1062 fclnodes[n] = clnode
1063 return clnode
1063 return clnode
1064 return lookupmflinknode
1064 return lookupmflinknode
1065
1065
1066 while tmfnodes:
1066 while tmfnodes:
1067 tree, nodes = tmfnodes.popitem()
1067 tree, nodes = tmfnodes.popitem()
1068 store = dirlog(tree)
1068 store = dirlog(tree)
1069
1069
1070 if not self._filematcher.visitdir(store._dir[:-1] or '.'):
1070 if not self._filematcher.visitdir(store._dir[:-1] or '.'):
1071 prunednodes = []
1071 prunednodes = []
1072 else:
1072 else:
1073 frev, flr = store.rev, store.linkrev
1073 frev, flr = store.rev, store.linkrev
1074 prunednodes = [n for n in nodes
1074 prunednodes = [n for n in nodes
1075 if flr(frev(n)) not in commonrevs]
1075 if flr(frev(n)) not in commonrevs]
1076
1076
1077 if tree and not prunednodes:
1077 if tree and not prunednodes:
1078 continue
1078 continue
1079
1079
1080 lookupfn = makelookupmflinknode(tree, nodes)
1080 lookupfn = makelookupmflinknode(tree, nodes)
1081
1081
1082 deltas = deltagroup(
1082 deltas = deltagroup(
1083 self._repo, store, prunednodes, False, lookupfn,
1083 self._repo, store, prunednodes, False, lookupfn,
1084 self._forcedeltaparentprev, self._reorder,
1084 self._forcedeltaparentprev, self._reorder,
1085 ellipses=self._ellipses,
1085 ellipses=self._ellipses,
1086 units=_('manifests'),
1086 topic=_('manifests'),
1087 clrevtolocalrev=clrevtolocalrev,
1087 clrevtolocalrev=clrevtolocalrev,
1088 fullclnodes=self._fullclnodes,
1088 fullclnodes=self._fullclnodes,
1089 precomputedellipsis=self._precomputedellipsis)
1089 precomputedellipsis=self._precomputedellipsis)
1090
1090
1091 yield tree, deltas
1091 yield tree, deltas
1092
1092
1093 # The 'source' parameter is useful for extensions
1093 # The 'source' parameter is useful for extensions
1094 def generatefiles(self, changedfiles, commonrevs, source,
1094 def generatefiles(self, changedfiles, commonrevs, source,
1095 mfdicts, fastpathlinkrev, fnodes, clrevs):
1095 mfdicts, fastpathlinkrev, fnodes, clrevs):
1096 changedfiles = list(filter(self._filematcher, changedfiles))
1096 changedfiles = list(filter(self._filematcher, changedfiles))
1097
1097
1098 if not fastpathlinkrev:
1098 if not fastpathlinkrev:
1099 def normallinknodes(unused, fname):
1099 def normallinknodes(unused, fname):
1100 return fnodes.get(fname, {})
1100 return fnodes.get(fname, {})
1101 else:
1101 else:
1102 cln = self._repo.changelog.node
1102 cln = self._repo.changelog.node
1103
1103
1104 def normallinknodes(store, fname):
1104 def normallinknodes(store, fname):
1105 flinkrev = store.linkrev
1105 flinkrev = store.linkrev
1106 fnode = store.node
1106 fnode = store.node
1107 revs = ((r, flinkrev(r)) for r in store)
1107 revs = ((r, flinkrev(r)) for r in store)
1108 return dict((fnode(r), cln(lr))
1108 return dict((fnode(r), cln(lr))
1109 for r, lr in revs if lr in clrevs)
1109 for r, lr in revs if lr in clrevs)
1110
1110
1111 clrevtolocalrev = {}
1111 clrevtolocalrev = {}
1112
1112
1113 if self._isshallow:
1113 if self._isshallow:
1114 # In a shallow clone, the linknodes callback needs to also include
1114 # In a shallow clone, the linknodes callback needs to also include
1115 # those file nodes that are in the manifests we sent but weren't
1115 # those file nodes that are in the manifests we sent but weren't
1116 # introduced by those manifests.
1116 # introduced by those manifests.
1117 commonctxs = [self._repo[c] for c in commonrevs]
1117 commonctxs = [self._repo[c] for c in commonrevs]
1118 clrev = self._repo.changelog.rev
1118 clrev = self._repo.changelog.rev
1119
1119
1120 # Defining this function has a side-effect of overriding the
1120 # Defining this function has a side-effect of overriding the
1121 # function of the same name that was passed in as an argument.
1121 # function of the same name that was passed in as an argument.
1122 # TODO have caller pass in appropriate function.
1122 # TODO have caller pass in appropriate function.
1123 def linknodes(flog, fname):
1123 def linknodes(flog, fname):
1124 for c in commonctxs:
1124 for c in commonctxs:
1125 try:
1125 try:
1126 fnode = c.filenode(fname)
1126 fnode = c.filenode(fname)
1127 clrevtolocalrev[c.rev()] = flog.rev(fnode)
1127 clrevtolocalrev[c.rev()] = flog.rev(fnode)
1128 except error.ManifestLookupError:
1128 except error.ManifestLookupError:
1129 pass
1129 pass
1130 links = normallinknodes(flog, fname)
1130 links = normallinknodes(flog, fname)
1131 if len(links) != len(mfdicts):
1131 if len(links) != len(mfdicts):
1132 for mf, lr in mfdicts:
1132 for mf, lr in mfdicts:
1133 fnode = mf.get(fname, None)
1133 fnode = mf.get(fname, None)
1134 if fnode in links:
1134 if fnode in links:
1135 links[fnode] = min(links[fnode], lr, key=clrev)
1135 links[fnode] = min(links[fnode], lr, key=clrev)
1136 elif fnode:
1136 elif fnode:
1137 links[fnode] = lr
1137 links[fnode] = lr
1138 return links
1138 return links
1139 else:
1139 else:
1140 linknodes = normallinknodes
1140 linknodes = normallinknodes
1141
1141
1142 repo = self._repo
1142 repo = self._repo
1143 progress = repo.ui.makeprogress(_('bundling'), unit=_('files'),
1143 progress = repo.ui.makeprogress(_('files'), unit=_('files'),
1144 total=len(changedfiles))
1144 total=len(changedfiles))
1145 for i, fname in enumerate(sorted(changedfiles)):
1145 for i, fname in enumerate(sorted(changedfiles)):
1146 filerevlog = repo.file(fname)
1146 filerevlog = repo.file(fname)
1147 if not filerevlog:
1147 if not filerevlog:
1148 raise error.Abort(_("empty or missing file data for %s") %
1148 raise error.Abort(_("empty or missing file data for %s") %
1149 fname)
1149 fname)
1150
1150
1151 clrevtolocalrev.clear()
1151 clrevtolocalrev.clear()
1152
1152
1153 linkrevnodes = linknodes(filerevlog, fname)
1153 linkrevnodes = linknodes(filerevlog, fname)
1154 # Lookup for filenodes, we collected the linkrev nodes above in the
1154 # Lookup for filenodes, we collected the linkrev nodes above in the
1155 # fastpath case and with lookupmf in the slowpath case.
1155 # fastpath case and with lookupmf in the slowpath case.
1156 def lookupfilelog(x):
1156 def lookupfilelog(x):
1157 return linkrevnodes[x]
1157 return linkrevnodes[x]
1158
1158
1159 frev, flr = filerevlog.rev, filerevlog.linkrev
1159 frev, flr = filerevlog.rev, filerevlog.linkrev
1160 filenodes = [n for n in linkrevnodes
1160 filenodes = [n for n in linkrevnodes
1161 if flr(frev(n)) not in commonrevs]
1161 if flr(frev(n)) not in commonrevs]
1162
1162
1163 if not filenodes:
1163 if not filenodes:
1164 continue
1164 continue
1165
1165
1166 progress.update(i + 1, item=fname)
1166 progress.update(i + 1, item=fname)
1167
1167
1168 deltas = deltagroup(
1168 deltas = deltagroup(
1169 self._repo, filerevlog, filenodes, False, lookupfilelog,
1169 self._repo, filerevlog, filenodes, False, lookupfilelog,
1170 self._forcedeltaparentprev, self._reorder,
1170 self._forcedeltaparentprev, self._reorder,
1171 ellipses=self._ellipses,
1171 ellipses=self._ellipses,
1172 clrevtolocalrev=clrevtolocalrev,
1172 clrevtolocalrev=clrevtolocalrev,
1173 fullclnodes=self._fullclnodes,
1173 fullclnodes=self._fullclnodes,
1174 precomputedellipsis=self._precomputedellipsis)
1174 precomputedellipsis=self._precomputedellipsis)
1175
1175
1176 yield fname, deltas
1176 yield fname, deltas
1177
1177
1178 progress.complete()
1178 progress.complete()
1179
1179
1180 def _makecg1packer(repo, filematcher, bundlecaps, ellipses=False,
1180 def _makecg1packer(repo, filematcher, bundlecaps, ellipses=False,
1181 shallow=False, ellipsisroots=None, fullnodes=None):
1181 shallow=False, ellipsisroots=None, fullnodes=None):
1182 builddeltaheader = lambda d: _CHANGEGROUPV1_DELTA_HEADER.pack(
1182 builddeltaheader = lambda d: _CHANGEGROUPV1_DELTA_HEADER.pack(
1183 d.node, d.p1node, d.p2node, d.linknode)
1183 d.node, d.p1node, d.p2node, d.linknode)
1184
1184
1185 return cgpacker(repo, filematcher, b'01',
1185 return cgpacker(repo, filematcher, b'01',
1186 allowreorder=None,
1186 allowreorder=None,
1187 builddeltaheader=builddeltaheader,
1187 builddeltaheader=builddeltaheader,
1188 manifestsend=b'',
1188 manifestsend=b'',
1189 forcedeltaparentprev=True,
1189 forcedeltaparentprev=True,
1190 bundlecaps=bundlecaps,
1190 bundlecaps=bundlecaps,
1191 ellipses=ellipses,
1191 ellipses=ellipses,
1192 shallow=shallow,
1192 shallow=shallow,
1193 ellipsisroots=ellipsisroots,
1193 ellipsisroots=ellipsisroots,
1194 fullnodes=fullnodes)
1194 fullnodes=fullnodes)
1195
1195
1196 def _makecg2packer(repo, filematcher, bundlecaps, ellipses=False,
1196 def _makecg2packer(repo, filematcher, bundlecaps, ellipses=False,
1197 shallow=False, ellipsisroots=None, fullnodes=None):
1197 shallow=False, ellipsisroots=None, fullnodes=None):
1198 builddeltaheader = lambda d: _CHANGEGROUPV2_DELTA_HEADER.pack(
1198 builddeltaheader = lambda d: _CHANGEGROUPV2_DELTA_HEADER.pack(
1199 d.node, d.p1node, d.p2node, d.basenode, d.linknode)
1199 d.node, d.p1node, d.p2node, d.basenode, d.linknode)
1200
1200
1201 # Since generaldelta is directly supported by cg2, reordering
1201 # Since generaldelta is directly supported by cg2, reordering
1202 # generally doesn't help, so we disable it by default (treating
1202 # generally doesn't help, so we disable it by default (treating
1203 # bundle.reorder=auto just like bundle.reorder=False).
1203 # bundle.reorder=auto just like bundle.reorder=False).
1204 return cgpacker(repo, filematcher, b'02',
1204 return cgpacker(repo, filematcher, b'02',
1205 allowreorder=False,
1205 allowreorder=False,
1206 builddeltaheader=builddeltaheader,
1206 builddeltaheader=builddeltaheader,
1207 manifestsend=b'',
1207 manifestsend=b'',
1208 bundlecaps=bundlecaps,
1208 bundlecaps=bundlecaps,
1209 ellipses=ellipses,
1209 ellipses=ellipses,
1210 shallow=shallow,
1210 shallow=shallow,
1211 ellipsisroots=ellipsisroots,
1211 ellipsisroots=ellipsisroots,
1212 fullnodes=fullnodes)
1212 fullnodes=fullnodes)
1213
1213
1214 def _makecg3packer(repo, filematcher, bundlecaps, ellipses=False,
1214 def _makecg3packer(repo, filematcher, bundlecaps, ellipses=False,
1215 shallow=False, ellipsisroots=None, fullnodes=None):
1215 shallow=False, ellipsisroots=None, fullnodes=None):
1216 builddeltaheader = lambda d: _CHANGEGROUPV3_DELTA_HEADER.pack(
1216 builddeltaheader = lambda d: _CHANGEGROUPV3_DELTA_HEADER.pack(
1217 d.node, d.p1node, d.p2node, d.basenode, d.linknode, d.flags)
1217 d.node, d.p1node, d.p2node, d.basenode, d.linknode, d.flags)
1218
1218
1219 return cgpacker(repo, filematcher, b'03',
1219 return cgpacker(repo, filematcher, b'03',
1220 allowreorder=False,
1220 allowreorder=False,
1221 builddeltaheader=builddeltaheader,
1221 builddeltaheader=builddeltaheader,
1222 manifestsend=closechunk(),
1222 manifestsend=closechunk(),
1223 bundlecaps=bundlecaps,
1223 bundlecaps=bundlecaps,
1224 ellipses=ellipses,
1224 ellipses=ellipses,
1225 shallow=shallow,
1225 shallow=shallow,
1226 ellipsisroots=ellipsisroots,
1226 ellipsisroots=ellipsisroots,
1227 fullnodes=fullnodes)
1227 fullnodes=fullnodes)
1228
1228
1229 _packermap = {'01': (_makecg1packer, cg1unpacker),
1229 _packermap = {'01': (_makecg1packer, cg1unpacker),
1230 # cg2 adds support for exchanging generaldelta
1230 # cg2 adds support for exchanging generaldelta
1231 '02': (_makecg2packer, cg2unpacker),
1231 '02': (_makecg2packer, cg2unpacker),
1232 # cg3 adds support for exchanging revlog flags and treemanifests
1232 # cg3 adds support for exchanging revlog flags and treemanifests
1233 '03': (_makecg3packer, cg3unpacker),
1233 '03': (_makecg3packer, cg3unpacker),
1234 }
1234 }
1235
1235
1236 def allsupportedversions(repo):
1236 def allsupportedversions(repo):
1237 versions = set(_packermap.keys())
1237 versions = set(_packermap.keys())
1238 if not (repo.ui.configbool('experimental', 'changegroup3') or
1238 if not (repo.ui.configbool('experimental', 'changegroup3') or
1239 repo.ui.configbool('experimental', 'treemanifest') or
1239 repo.ui.configbool('experimental', 'treemanifest') or
1240 'treemanifest' in repo.requirements):
1240 'treemanifest' in repo.requirements):
1241 versions.discard('03')
1241 versions.discard('03')
1242 return versions
1242 return versions
1243
1243
1244 # Changegroup versions that can be applied to the repo
1244 # Changegroup versions that can be applied to the repo
1245 def supportedincomingversions(repo):
1245 def supportedincomingversions(repo):
1246 return allsupportedversions(repo)
1246 return allsupportedversions(repo)
1247
1247
1248 # Changegroup versions that can be created from the repo
1248 # Changegroup versions that can be created from the repo
1249 def supportedoutgoingversions(repo):
1249 def supportedoutgoingversions(repo):
1250 versions = allsupportedversions(repo)
1250 versions = allsupportedversions(repo)
1251 if 'treemanifest' in repo.requirements:
1251 if 'treemanifest' in repo.requirements:
1252 # Versions 01 and 02 support only flat manifests and it's just too
1252 # Versions 01 and 02 support only flat manifests and it's just too
1253 # expensive to convert between the flat manifest and tree manifest on
1253 # expensive to convert between the flat manifest and tree manifest on
1254 # the fly. Since tree manifests are hashed differently, all of history
1254 # the fly. Since tree manifests are hashed differently, all of history
1255 # would have to be converted. Instead, we simply don't even pretend to
1255 # would have to be converted. Instead, we simply don't even pretend to
1256 # support versions 01 and 02.
1256 # support versions 01 and 02.
1257 versions.discard('01')
1257 versions.discard('01')
1258 versions.discard('02')
1258 versions.discard('02')
1259 if repository.NARROW_REQUIREMENT in repo.requirements:
1259 if repository.NARROW_REQUIREMENT in repo.requirements:
1260 # Versions 01 and 02 don't support revlog flags, and we need to
1260 # Versions 01 and 02 don't support revlog flags, and we need to
1261 # support that for stripping and unbundling to work.
1261 # support that for stripping and unbundling to work.
1262 versions.discard('01')
1262 versions.discard('01')
1263 versions.discard('02')
1263 versions.discard('02')
1264 if LFS_REQUIREMENT in repo.requirements:
1264 if LFS_REQUIREMENT in repo.requirements:
1265 # Versions 01 and 02 don't support revlog flags, and we need to
1265 # Versions 01 and 02 don't support revlog flags, and we need to
1266 # mark LFS entries with REVIDX_EXTSTORED.
1266 # mark LFS entries with REVIDX_EXTSTORED.
1267 versions.discard('01')
1267 versions.discard('01')
1268 versions.discard('02')
1268 versions.discard('02')
1269
1269
1270 return versions
1270 return versions
1271
1271
1272 def localversion(repo):
1272 def localversion(repo):
1273 # Finds the best version to use for bundles that are meant to be used
1273 # Finds the best version to use for bundles that are meant to be used
1274 # locally, such as those from strip and shelve, and temporary bundles.
1274 # locally, such as those from strip and shelve, and temporary bundles.
1275 return max(supportedoutgoingversions(repo))
1275 return max(supportedoutgoingversions(repo))
1276
1276
1277 def safeversion(repo):
1277 def safeversion(repo):
1278 # Finds the smallest version that it's safe to assume clients of the repo
1278 # Finds the smallest version that it's safe to assume clients of the repo
1279 # will support. For example, all hg versions that support generaldelta also
1279 # will support. For example, all hg versions that support generaldelta also
1280 # support changegroup 02.
1280 # support changegroup 02.
1281 versions = supportedoutgoingversions(repo)
1281 versions = supportedoutgoingversions(repo)
1282 if 'generaldelta' in repo.requirements:
1282 if 'generaldelta' in repo.requirements:
1283 versions.discard('01')
1283 versions.discard('01')
1284 assert versions
1284 assert versions
1285 return min(versions)
1285 return min(versions)
1286
1286
1287 def getbundler(version, repo, bundlecaps=None, filematcher=None,
1287 def getbundler(version, repo, bundlecaps=None, filematcher=None,
1288 ellipses=False, shallow=False, ellipsisroots=None,
1288 ellipses=False, shallow=False, ellipsisroots=None,
1289 fullnodes=None):
1289 fullnodes=None):
1290 assert version in supportedoutgoingversions(repo)
1290 assert version in supportedoutgoingversions(repo)
1291
1291
1292 if filematcher is None:
1292 if filematcher is None:
1293 filematcher = matchmod.alwaysmatcher(repo.root, '')
1293 filematcher = matchmod.alwaysmatcher(repo.root, '')
1294
1294
1295 if version == '01' and not filematcher.always():
1295 if version == '01' and not filematcher.always():
1296 raise error.ProgrammingError('version 01 changegroups do not support '
1296 raise error.ProgrammingError('version 01 changegroups do not support '
1297 'sparse file matchers')
1297 'sparse file matchers')
1298
1298
1299 if ellipses and version in (b'01', b'02'):
1299 if ellipses and version in (b'01', b'02'):
1300 raise error.Abort(
1300 raise error.Abort(
1301 _('ellipsis nodes require at least cg3 on client and server, '
1301 _('ellipsis nodes require at least cg3 on client and server, '
1302 'but negotiated version %s') % version)
1302 'but negotiated version %s') % version)
1303
1303
1304 # Requested files could include files not in the local store. So
1304 # Requested files could include files not in the local store. So
1305 # filter those out.
1305 # filter those out.
1306 filematcher = matchmod.intersectmatchers(repo.narrowmatch(),
1306 filematcher = matchmod.intersectmatchers(repo.narrowmatch(),
1307 filematcher)
1307 filematcher)
1308
1308
1309 fn = _packermap[version][0]
1309 fn = _packermap[version][0]
1310 return fn(repo, filematcher, bundlecaps, ellipses=ellipses,
1310 return fn(repo, filematcher, bundlecaps, ellipses=ellipses,
1311 shallow=shallow, ellipsisroots=ellipsisroots,
1311 shallow=shallow, ellipsisroots=ellipsisroots,
1312 fullnodes=fullnodes)
1312 fullnodes=fullnodes)
1313
1313
1314 def getunbundler(version, fh, alg, extras=None):
1314 def getunbundler(version, fh, alg, extras=None):
1315 return _packermap[version][1](fh, alg, extras=extras)
1315 return _packermap[version][1](fh, alg, extras=extras)
1316
1316
1317 def _changegroupinfo(repo, nodes, source):
1317 def _changegroupinfo(repo, nodes, source):
1318 if repo.ui.verbose or source == 'bundle':
1318 if repo.ui.verbose or source == 'bundle':
1319 repo.ui.status(_("%d changesets found\n") % len(nodes))
1319 repo.ui.status(_("%d changesets found\n") % len(nodes))
1320 if repo.ui.debugflag:
1320 if repo.ui.debugflag:
1321 repo.ui.debug("list of changesets:\n")
1321 repo.ui.debug("list of changesets:\n")
1322 for node in nodes:
1322 for node in nodes:
1323 repo.ui.debug("%s\n" % hex(node))
1323 repo.ui.debug("%s\n" % hex(node))
1324
1324
1325 def makechangegroup(repo, outgoing, version, source, fastpath=False,
1325 def makechangegroup(repo, outgoing, version, source, fastpath=False,
1326 bundlecaps=None):
1326 bundlecaps=None):
1327 cgstream = makestream(repo, outgoing, version, source,
1327 cgstream = makestream(repo, outgoing, version, source,
1328 fastpath=fastpath, bundlecaps=bundlecaps)
1328 fastpath=fastpath, bundlecaps=bundlecaps)
1329 return getunbundler(version, util.chunkbuffer(cgstream), None,
1329 return getunbundler(version, util.chunkbuffer(cgstream), None,
1330 {'clcount': len(outgoing.missing) })
1330 {'clcount': len(outgoing.missing) })
1331
1331
1332 def makestream(repo, outgoing, version, source, fastpath=False,
1332 def makestream(repo, outgoing, version, source, fastpath=False,
1333 bundlecaps=None, filematcher=None):
1333 bundlecaps=None, filematcher=None):
1334 bundler = getbundler(version, repo, bundlecaps=bundlecaps,
1334 bundler = getbundler(version, repo, bundlecaps=bundlecaps,
1335 filematcher=filematcher)
1335 filematcher=filematcher)
1336
1336
1337 repo = repo.unfiltered()
1337 repo = repo.unfiltered()
1338 commonrevs = outgoing.common
1338 commonrevs = outgoing.common
1339 csets = outgoing.missing
1339 csets = outgoing.missing
1340 heads = outgoing.missingheads
1340 heads = outgoing.missingheads
1341 # We go through the fast path if we get told to, or if all (unfiltered
1341 # We go through the fast path if we get told to, or if all (unfiltered
1342 # heads have been requested (since we then know there all linkrevs will
1342 # heads have been requested (since we then know there all linkrevs will
1343 # be pulled by the client).
1343 # be pulled by the client).
1344 heads.sort()
1344 heads.sort()
1345 fastpathlinkrev = fastpath or (
1345 fastpathlinkrev = fastpath or (
1346 repo.filtername is None and heads == sorted(repo.heads()))
1346 repo.filtername is None and heads == sorted(repo.heads()))
1347
1347
1348 repo.hook('preoutgoing', throw=True, source=source)
1348 repo.hook('preoutgoing', throw=True, source=source)
1349 _changegroupinfo(repo, csets, source)
1349 _changegroupinfo(repo, csets, source)
1350 return bundler.generate(commonrevs, csets, fastpathlinkrev, source)
1350 return bundler.generate(commonrevs, csets, fastpathlinkrev, source)
1351
1351
1352 def _addchangegroupfiles(repo, source, revmap, trp, expectedfiles, needfiles):
1352 def _addchangegroupfiles(repo, source, revmap, trp, expectedfiles, needfiles):
1353 revisions = 0
1353 revisions = 0
1354 files = 0
1354 files = 0
1355 progress = repo.ui.makeprogress(_('files'), unit=_('files'),
1355 progress = repo.ui.makeprogress(_('files'), unit=_('files'),
1356 total=expectedfiles)
1356 total=expectedfiles)
1357 for chunkdata in iter(source.filelogheader, {}):
1357 for chunkdata in iter(source.filelogheader, {}):
1358 files += 1
1358 files += 1
1359 f = chunkdata["filename"]
1359 f = chunkdata["filename"]
1360 repo.ui.debug("adding %s revisions\n" % f)
1360 repo.ui.debug("adding %s revisions\n" % f)
1361 progress.increment()
1361 progress.increment()
1362 fl = repo.file(f)
1362 fl = repo.file(f)
1363 o = len(fl)
1363 o = len(fl)
1364 try:
1364 try:
1365 deltas = source.deltaiter()
1365 deltas = source.deltaiter()
1366 if not fl.addgroup(deltas, revmap, trp):
1366 if not fl.addgroup(deltas, revmap, trp):
1367 raise error.Abort(_("received file revlog group is empty"))
1367 raise error.Abort(_("received file revlog group is empty"))
1368 except error.CensoredBaseError as e:
1368 except error.CensoredBaseError as e:
1369 raise error.Abort(_("received delta base is censored: %s") % e)
1369 raise error.Abort(_("received delta base is censored: %s") % e)
1370 revisions += len(fl) - o
1370 revisions += len(fl) - o
1371 if f in needfiles:
1371 if f in needfiles:
1372 needs = needfiles[f]
1372 needs = needfiles[f]
1373 for new in pycompat.xrange(o, len(fl)):
1373 for new in pycompat.xrange(o, len(fl)):
1374 n = fl.node(new)
1374 n = fl.node(new)
1375 if n in needs:
1375 if n in needs:
1376 needs.remove(n)
1376 needs.remove(n)
1377 else:
1377 else:
1378 raise error.Abort(
1378 raise error.Abort(
1379 _("received spurious file revlog entry"))
1379 _("received spurious file revlog entry"))
1380 if not needs:
1380 if not needs:
1381 del needfiles[f]
1381 del needfiles[f]
1382 progress.complete()
1382 progress.complete()
1383
1383
1384 for f, needs in needfiles.iteritems():
1384 for f, needs in needfiles.iteritems():
1385 fl = repo.file(f)
1385 fl = repo.file(f)
1386 for n in needs:
1386 for n in needs:
1387 try:
1387 try:
1388 fl.rev(n)
1388 fl.rev(n)
1389 except error.LookupError:
1389 except error.LookupError:
1390 raise error.Abort(
1390 raise error.Abort(
1391 _('missing file data for %s:%s - run hg verify') %
1391 _('missing file data for %s:%s - run hg verify') %
1392 (f, hex(n)))
1392 (f, hex(n)))
1393
1393
1394 return revisions, files
1394 return revisions, files
@@ -1,902 +1,902 b''
1 Setting up test
1 Setting up test
2
2
3 $ hg init test
3 $ hg init test
4 $ cd test
4 $ cd test
5 $ echo 0 > afile
5 $ echo 0 > afile
6 $ hg add afile
6 $ hg add afile
7 $ hg commit -m "0.0"
7 $ hg commit -m "0.0"
8 $ echo 1 >> afile
8 $ echo 1 >> afile
9 $ hg commit -m "0.1"
9 $ hg commit -m "0.1"
10 $ echo 2 >> afile
10 $ echo 2 >> afile
11 $ hg commit -m "0.2"
11 $ hg commit -m "0.2"
12 $ echo 3 >> afile
12 $ echo 3 >> afile
13 $ hg commit -m "0.3"
13 $ hg commit -m "0.3"
14 $ hg update -C 0
14 $ hg update -C 0
15 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
15 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
16 $ echo 1 >> afile
16 $ echo 1 >> afile
17 $ hg commit -m "1.1"
17 $ hg commit -m "1.1"
18 created new head
18 created new head
19 $ echo 2 >> afile
19 $ echo 2 >> afile
20 $ hg commit -m "1.2"
20 $ hg commit -m "1.2"
21 $ echo "a line" > fred
21 $ echo "a line" > fred
22 $ echo 3 >> afile
22 $ echo 3 >> afile
23 $ hg add fred
23 $ hg add fred
24 $ hg commit -m "1.3"
24 $ hg commit -m "1.3"
25 $ hg mv afile adifferentfile
25 $ hg mv afile adifferentfile
26 $ hg commit -m "1.3m"
26 $ hg commit -m "1.3m"
27 $ hg update -C 3
27 $ hg update -C 3
28 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
28 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
29 $ hg mv afile anotherfile
29 $ hg mv afile anotherfile
30 $ hg commit -m "0.3m"
30 $ hg commit -m "0.3m"
31 $ hg verify
31 $ hg verify
32 checking changesets
32 checking changesets
33 checking manifests
33 checking manifests
34 crosschecking files in changesets and manifests
34 crosschecking files in changesets and manifests
35 checking files
35 checking files
36 4 files, 9 changesets, 7 total revisions
36 4 files, 9 changesets, 7 total revisions
37 $ cd ..
37 $ cd ..
38 $ hg init empty
38 $ hg init empty
39
39
40 Bundle and phase
40 Bundle and phase
41
41
42 $ hg -R test phase --force --secret 0
42 $ hg -R test phase --force --secret 0
43 $ hg -R test bundle phase.hg empty
43 $ hg -R test bundle phase.hg empty
44 searching for changes
44 searching for changes
45 no changes found (ignored 9 secret changesets)
45 no changes found (ignored 9 secret changesets)
46 [1]
46 [1]
47 $ hg -R test phase --draft -r 'head()'
47 $ hg -R test phase --draft -r 'head()'
48
48
49 Bundle --all
49 Bundle --all
50
50
51 $ hg -R test bundle --all all.hg
51 $ hg -R test bundle --all all.hg
52 9 changesets found
52 9 changesets found
53
53
54 Bundle test to full.hg
54 Bundle test to full.hg
55
55
56 $ hg -R test bundle full.hg empty
56 $ hg -R test bundle full.hg empty
57 searching for changes
57 searching for changes
58 9 changesets found
58 9 changesets found
59
59
60 Unbundle full.hg in test
60 Unbundle full.hg in test
61
61
62 $ hg -R test unbundle full.hg
62 $ hg -R test unbundle full.hg
63 adding changesets
63 adding changesets
64 adding manifests
64 adding manifests
65 adding file changes
65 adding file changes
66 added 0 changesets with 0 changes to 4 files
66 added 0 changesets with 0 changes to 4 files
67 (run 'hg update' to get a working copy)
67 (run 'hg update' to get a working copy)
68
68
69 Verify empty
69 Verify empty
70
70
71 $ hg -R empty heads
71 $ hg -R empty heads
72 [1]
72 [1]
73 $ hg -R empty verify
73 $ hg -R empty verify
74 checking changesets
74 checking changesets
75 checking manifests
75 checking manifests
76 crosschecking files in changesets and manifests
76 crosschecking files in changesets and manifests
77 checking files
77 checking files
78 0 files, 0 changesets, 0 total revisions
78 0 files, 0 changesets, 0 total revisions
79
79
80 #if repobundlerepo
80 #if repobundlerepo
81
81
82 Pull full.hg into test (using --cwd)
82 Pull full.hg into test (using --cwd)
83
83
84 $ hg --cwd test pull ../full.hg
84 $ hg --cwd test pull ../full.hg
85 pulling from ../full.hg
85 pulling from ../full.hg
86 searching for changes
86 searching for changes
87 no changes found
87 no changes found
88
88
89 Verify that there are no leaked temporary files after pull (issue2797)
89 Verify that there are no leaked temporary files after pull (issue2797)
90
90
91 $ ls test/.hg | grep .hg10un
91 $ ls test/.hg | grep .hg10un
92 [1]
92 [1]
93
93
94 Pull full.hg into empty (using --cwd)
94 Pull full.hg into empty (using --cwd)
95
95
96 $ hg --cwd empty pull ../full.hg
96 $ hg --cwd empty pull ../full.hg
97 pulling from ../full.hg
97 pulling from ../full.hg
98 requesting all changes
98 requesting all changes
99 adding changesets
99 adding changesets
100 adding manifests
100 adding manifests
101 adding file changes
101 adding file changes
102 added 9 changesets with 7 changes to 4 files (+1 heads)
102 added 9 changesets with 7 changes to 4 files (+1 heads)
103 new changesets f9ee2f85a263:aa35859c02ea
103 new changesets f9ee2f85a263:aa35859c02ea
104 (run 'hg heads' to see heads, 'hg merge' to merge)
104 (run 'hg heads' to see heads, 'hg merge' to merge)
105
105
106 Rollback empty
106 Rollback empty
107
107
108 $ hg -R empty rollback
108 $ hg -R empty rollback
109 repository tip rolled back to revision -1 (undo pull)
109 repository tip rolled back to revision -1 (undo pull)
110
110
111 Pull full.hg into empty again (using --cwd)
111 Pull full.hg into empty again (using --cwd)
112
112
113 $ hg --cwd empty pull ../full.hg
113 $ hg --cwd empty pull ../full.hg
114 pulling from ../full.hg
114 pulling from ../full.hg
115 requesting all changes
115 requesting all changes
116 adding changesets
116 adding changesets
117 adding manifests
117 adding manifests
118 adding file changes
118 adding file changes
119 added 9 changesets with 7 changes to 4 files (+1 heads)
119 added 9 changesets with 7 changes to 4 files (+1 heads)
120 new changesets f9ee2f85a263:aa35859c02ea
120 new changesets f9ee2f85a263:aa35859c02ea
121 (run 'hg heads' to see heads, 'hg merge' to merge)
121 (run 'hg heads' to see heads, 'hg merge' to merge)
122
122
123 Pull full.hg into test (using -R)
123 Pull full.hg into test (using -R)
124
124
125 $ hg -R test pull full.hg
125 $ hg -R test pull full.hg
126 pulling from full.hg
126 pulling from full.hg
127 searching for changes
127 searching for changes
128 no changes found
128 no changes found
129
129
130 Pull full.hg into empty (using -R)
130 Pull full.hg into empty (using -R)
131
131
132 $ hg -R empty pull full.hg
132 $ hg -R empty pull full.hg
133 pulling from full.hg
133 pulling from full.hg
134 searching for changes
134 searching for changes
135 no changes found
135 no changes found
136
136
137 Rollback empty
137 Rollback empty
138
138
139 $ hg -R empty rollback
139 $ hg -R empty rollback
140 repository tip rolled back to revision -1 (undo pull)
140 repository tip rolled back to revision -1 (undo pull)
141
141
142 Pull full.hg into empty again (using -R)
142 Pull full.hg into empty again (using -R)
143
143
144 $ hg -R empty pull full.hg
144 $ hg -R empty pull full.hg
145 pulling from full.hg
145 pulling from full.hg
146 requesting all changes
146 requesting all changes
147 adding changesets
147 adding changesets
148 adding manifests
148 adding manifests
149 adding file changes
149 adding file changes
150 added 9 changesets with 7 changes to 4 files (+1 heads)
150 added 9 changesets with 7 changes to 4 files (+1 heads)
151 new changesets f9ee2f85a263:aa35859c02ea
151 new changesets f9ee2f85a263:aa35859c02ea
152 (run 'hg heads' to see heads, 'hg merge' to merge)
152 (run 'hg heads' to see heads, 'hg merge' to merge)
153
153
154 Log -R full.hg in fresh empty
154 Log -R full.hg in fresh empty
155
155
156 $ rm -r empty
156 $ rm -r empty
157 $ hg init empty
157 $ hg init empty
158 $ cd empty
158 $ cd empty
159 $ hg -R bundle://../full.hg log
159 $ hg -R bundle://../full.hg log
160 changeset: 8:aa35859c02ea
160 changeset: 8:aa35859c02ea
161 tag: tip
161 tag: tip
162 parent: 3:eebf5a27f8ca
162 parent: 3:eebf5a27f8ca
163 user: test
163 user: test
164 date: Thu Jan 01 00:00:00 1970 +0000
164 date: Thu Jan 01 00:00:00 1970 +0000
165 summary: 0.3m
165 summary: 0.3m
166
166
167 changeset: 7:a6a34bfa0076
167 changeset: 7:a6a34bfa0076
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: 1.3m
170 summary: 1.3m
171
171
172 changeset: 6:7373c1169842
172 changeset: 6:7373c1169842
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: 1.3
175 summary: 1.3
176
176
177 changeset: 5:1bb50a9436a7
177 changeset: 5:1bb50a9436a7
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: 1.2
180 summary: 1.2
181
181
182 changeset: 4:095197eb4973
182 changeset: 4:095197eb4973
183 parent: 0:f9ee2f85a263
183 parent: 0:f9ee2f85a263
184 user: test
184 user: test
185 date: Thu Jan 01 00:00:00 1970 +0000
185 date: Thu Jan 01 00:00:00 1970 +0000
186 summary: 1.1
186 summary: 1.1
187
187
188 changeset: 3:eebf5a27f8ca
188 changeset: 3:eebf5a27f8ca
189 user: test
189 user: test
190 date: Thu Jan 01 00:00:00 1970 +0000
190 date: Thu Jan 01 00:00:00 1970 +0000
191 summary: 0.3
191 summary: 0.3
192
192
193 changeset: 2:e38ba6f5b7e0
193 changeset: 2:e38ba6f5b7e0
194 user: test
194 user: test
195 date: Thu Jan 01 00:00:00 1970 +0000
195 date: Thu Jan 01 00:00:00 1970 +0000
196 summary: 0.2
196 summary: 0.2
197
197
198 changeset: 1:34c2bf6b0626
198 changeset: 1:34c2bf6b0626
199 user: test
199 user: test
200 date: Thu Jan 01 00:00:00 1970 +0000
200 date: Thu Jan 01 00:00:00 1970 +0000
201 summary: 0.1
201 summary: 0.1
202
202
203 changeset: 0:f9ee2f85a263
203 changeset: 0:f9ee2f85a263
204 user: test
204 user: test
205 date: Thu Jan 01 00:00:00 1970 +0000
205 date: Thu Jan 01 00:00:00 1970 +0000
206 summary: 0.0
206 summary: 0.0
207
207
208 Make sure bundlerepo doesn't leak tempfiles (issue2491)
208 Make sure bundlerepo doesn't leak tempfiles (issue2491)
209
209
210 $ ls .hg
210 $ ls .hg
211 00changelog.i
211 00changelog.i
212 cache
212 cache
213 requires
213 requires
214 store
214 store
215
215
216 Pull ../full.hg into empty (with hook)
216 Pull ../full.hg into empty (with hook)
217
217
218 $ cat >> .hg/hgrc <<EOF
218 $ cat >> .hg/hgrc <<EOF
219 > [hooks]
219 > [hooks]
220 > changegroup = sh -c "printenv.py changegroup"
220 > changegroup = sh -c "printenv.py changegroup"
221 > EOF
221 > EOF
222
222
223 doesn't work (yet ?)
223 doesn't work (yet ?)
224
224
225 hg -R bundle://../full.hg verify
225 hg -R bundle://../full.hg verify
226
226
227 $ hg pull bundle://../full.hg
227 $ hg pull bundle://../full.hg
228 pulling from bundle:../full.hg
228 pulling from bundle:../full.hg
229 requesting all changes
229 requesting all changes
230 adding changesets
230 adding changesets
231 adding manifests
231 adding manifests
232 adding file changes
232 adding file changes
233 added 9 changesets with 7 changes to 4 files (+1 heads)
233 added 9 changesets with 7 changes to 4 files (+1 heads)
234 new changesets f9ee2f85a263:aa35859c02ea
234 new changesets f9ee2f85a263:aa35859c02ea
235 changegroup hook: HG_HOOKNAME=changegroup HG_HOOKTYPE=changegroup HG_NODE=f9ee2f85a263049e9ae6d37a0e67e96194ffb735 HG_NODE_LAST=aa35859c02ea8bd48da5da68cd2740ac71afcbaf HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=bundle*../full.hg (glob)
235 changegroup hook: HG_HOOKNAME=changegroup HG_HOOKTYPE=changegroup HG_NODE=f9ee2f85a263049e9ae6d37a0e67e96194ffb735 HG_NODE_LAST=aa35859c02ea8bd48da5da68cd2740ac71afcbaf HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=bundle*../full.hg (glob)
236 (run 'hg heads' to see heads, 'hg merge' to merge)
236 (run 'hg heads' to see heads, 'hg merge' to merge)
237
237
238 Rollback empty
238 Rollback empty
239
239
240 $ hg rollback
240 $ hg rollback
241 repository tip rolled back to revision -1 (undo pull)
241 repository tip rolled back to revision -1 (undo pull)
242 $ cd ..
242 $ cd ..
243
243
244 Log -R bundle:empty+full.hg
244 Log -R bundle:empty+full.hg
245
245
246 $ hg -R bundle:empty+full.hg log --template="{rev} "; echo ""
246 $ hg -R bundle:empty+full.hg log --template="{rev} "; echo ""
247 8 7 6 5 4 3 2 1 0
247 8 7 6 5 4 3 2 1 0
248
248
249 Pull full.hg into empty again (using -R; with hook)
249 Pull full.hg into empty again (using -R; with hook)
250
250
251 $ hg -R empty pull full.hg
251 $ hg -R empty pull full.hg
252 pulling from full.hg
252 pulling from full.hg
253 requesting all changes
253 requesting all changes
254 adding changesets
254 adding changesets
255 adding manifests
255 adding manifests
256 adding file changes
256 adding file changes
257 added 9 changesets with 7 changes to 4 files (+1 heads)
257 added 9 changesets with 7 changes to 4 files (+1 heads)
258 new changesets f9ee2f85a263:aa35859c02ea
258 new changesets f9ee2f85a263:aa35859c02ea
259 changegroup hook: HG_HOOKNAME=changegroup HG_HOOKTYPE=changegroup HG_NODE=f9ee2f85a263049e9ae6d37a0e67e96194ffb735 HG_NODE_LAST=aa35859c02ea8bd48da5da68cd2740ac71afcbaf HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=bundle:empty+full.hg
259 changegroup hook: HG_HOOKNAME=changegroup HG_HOOKTYPE=changegroup HG_NODE=f9ee2f85a263049e9ae6d37a0e67e96194ffb735 HG_NODE_LAST=aa35859c02ea8bd48da5da68cd2740ac71afcbaf HG_SOURCE=pull HG_TXNID=TXN:$ID$ HG_URL=bundle:empty+full.hg
260 (run 'hg heads' to see heads, 'hg merge' to merge)
260 (run 'hg heads' to see heads, 'hg merge' to merge)
261
261
262 #endif
262 #endif
263
263
264 Cannot produce streaming clone bundles with "hg bundle"
264 Cannot produce streaming clone bundles with "hg bundle"
265
265
266 $ hg -R test bundle -t packed1 packed.hg
266 $ hg -R test bundle -t packed1 packed.hg
267 abort: packed bundles cannot be produced by "hg bundle"
267 abort: packed bundles cannot be produced by "hg bundle"
268 (use 'hg debugcreatestreamclonebundle')
268 (use 'hg debugcreatestreamclonebundle')
269 [255]
269 [255]
270
270
271 packed1 is produced properly
271 packed1 is produced properly
272
272
273 #if reporevlogstore
273 #if reporevlogstore
274
274
275 $ hg -R test debugcreatestreamclonebundle packed.hg
275 $ hg -R test debugcreatestreamclonebundle packed.hg
276 writing 2664 bytes for 6 files
276 writing 2664 bytes for 6 files
277 bundle requirements: generaldelta, revlogv1
277 bundle requirements: generaldelta, revlogv1
278
278
279 $ f -B 64 --size --sha1 --hexdump packed.hg
279 $ f -B 64 --size --sha1 --hexdump packed.hg
280 packed.hg: size=2827, sha1=9d14cb90c66a21462d915ab33656f38b9deed686
280 packed.hg: size=2827, sha1=9d14cb90c66a21462d915ab33656f38b9deed686
281 0000: 48 47 53 31 55 4e 00 00 00 00 00 00 00 06 00 00 |HGS1UN..........|
281 0000: 48 47 53 31 55 4e 00 00 00 00 00 00 00 06 00 00 |HGS1UN..........|
282 0010: 00 00 00 00 0a 68 00 16 67 65 6e 65 72 61 6c 64 |.....h..generald|
282 0010: 00 00 00 00 0a 68 00 16 67 65 6e 65 72 61 6c 64 |.....h..generald|
283 0020: 65 6c 74 61 2c 72 65 76 6c 6f 67 76 31 00 64 61 |elta,revlogv1.da|
283 0020: 65 6c 74 61 2c 72 65 76 6c 6f 67 76 31 00 64 61 |elta,revlogv1.da|
284 0030: 74 61 2f 61 64 69 66 66 65 72 65 6e 74 66 69 6c |ta/adifferentfil|
284 0030: 74 61 2f 61 64 69 66 66 65 72 65 6e 74 66 69 6c |ta/adifferentfil|
285
285
286 $ hg debugbundle --spec packed.hg
286 $ hg debugbundle --spec packed.hg
287 none-packed1;requirements%3Dgeneraldelta%2Crevlogv1
287 none-packed1;requirements%3Dgeneraldelta%2Crevlogv1
288
288
289 generaldelta requirement is not listed in stream clone bundles unless used
289 generaldelta requirement is not listed in stream clone bundles unless used
290
290
291 $ hg --config format.usegeneraldelta=false init testnongd
291 $ hg --config format.usegeneraldelta=false init testnongd
292 $ cd testnongd
292 $ cd testnongd
293 $ touch foo
293 $ touch foo
294 $ hg -q commit -A -m initial
294 $ hg -q commit -A -m initial
295 $ cd ..
295 $ cd ..
296 $ hg -R testnongd debugcreatestreamclonebundle packednongd.hg
296 $ hg -R testnongd debugcreatestreamclonebundle packednongd.hg
297 writing 301 bytes for 3 files
297 writing 301 bytes for 3 files
298 bundle requirements: revlogv1
298 bundle requirements: revlogv1
299
299
300 $ f -B 64 --size --sha1 --hexdump packednongd.hg
300 $ f -B 64 --size --sha1 --hexdump packednongd.hg
301 packednongd.hg: size=383, sha1=1d9c230238edd5d38907100b729ba72b1831fe6f
301 packednongd.hg: size=383, sha1=1d9c230238edd5d38907100b729ba72b1831fe6f
302 0000: 48 47 53 31 55 4e 00 00 00 00 00 00 00 03 00 00 |HGS1UN..........|
302 0000: 48 47 53 31 55 4e 00 00 00 00 00 00 00 03 00 00 |HGS1UN..........|
303 0010: 00 00 00 00 01 2d 00 09 72 65 76 6c 6f 67 76 31 |.....-..revlogv1|
303 0010: 00 00 00 00 01 2d 00 09 72 65 76 6c 6f 67 76 31 |.....-..revlogv1|
304 0020: 00 64 61 74 61 2f 66 6f 6f 2e 69 00 36 34 0a 00 |.data/foo.i.64..|
304 0020: 00 64 61 74 61 2f 66 6f 6f 2e 69 00 36 34 0a 00 |.data/foo.i.64..|
305 0030: 01 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
305 0030: 01 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
306
306
307 $ hg debugbundle --spec packednongd.hg
307 $ hg debugbundle --spec packednongd.hg
308 none-packed1;requirements%3Drevlogv1
308 none-packed1;requirements%3Drevlogv1
309
309
310 Warning emitted when packed bundles contain secret changesets
310 Warning emitted when packed bundles contain secret changesets
311
311
312 $ hg init testsecret
312 $ hg init testsecret
313 $ cd testsecret
313 $ cd testsecret
314 $ touch foo
314 $ touch foo
315 $ hg -q commit -A -m initial
315 $ hg -q commit -A -m initial
316 $ hg phase --force --secret -r .
316 $ hg phase --force --secret -r .
317 $ cd ..
317 $ cd ..
318
318
319 $ hg -R testsecret debugcreatestreamclonebundle packedsecret.hg
319 $ hg -R testsecret debugcreatestreamclonebundle packedsecret.hg
320 (warning: stream clone bundle will contain secret revisions)
320 (warning: stream clone bundle will contain secret revisions)
321 writing 301 bytes for 3 files
321 writing 301 bytes for 3 files
322 bundle requirements: generaldelta, revlogv1
322 bundle requirements: generaldelta, revlogv1
323
323
324 Unpacking packed1 bundles with "hg unbundle" isn't allowed
324 Unpacking packed1 bundles with "hg unbundle" isn't allowed
325
325
326 $ hg init packed
326 $ hg init packed
327 $ hg -R packed unbundle packed.hg
327 $ hg -R packed unbundle packed.hg
328 abort: packed bundles cannot be applied with "hg unbundle"
328 abort: packed bundles cannot be applied with "hg unbundle"
329 (use "hg debugapplystreamclonebundle")
329 (use "hg debugapplystreamclonebundle")
330 [255]
330 [255]
331
331
332 packed1 can be consumed from debug command
332 packed1 can be consumed from debug command
333
333
334 (this also confirms that streamclone-ed changes are visible via
334 (this also confirms that streamclone-ed changes are visible via
335 @filecache properties to in-process procedures before closing
335 @filecache properties to in-process procedures before closing
336 transaction)
336 transaction)
337
337
338 $ cat > $TESTTMP/showtip.py <<EOF
338 $ cat > $TESTTMP/showtip.py <<EOF
339 > from __future__ import absolute_import
339 > from __future__ import absolute_import
340 >
340 >
341 > def showtip(ui, repo, hooktype, **kwargs):
341 > def showtip(ui, repo, hooktype, **kwargs):
342 > ui.warn(b'%s: %s\n' % (hooktype, repo[b'tip'].hex()[:12]))
342 > ui.warn(b'%s: %s\n' % (hooktype, repo[b'tip'].hex()[:12]))
343 >
343 >
344 > def reposetup(ui, repo):
344 > def reposetup(ui, repo):
345 > # this confirms (and ensures) that (empty) 00changelog.i
345 > # this confirms (and ensures) that (empty) 00changelog.i
346 > # before streamclone is already cached as repo.changelog
346 > # before streamclone is already cached as repo.changelog
347 > ui.setconfig(b'hooks', b'pretxnopen.showtip', showtip)
347 > ui.setconfig(b'hooks', b'pretxnopen.showtip', showtip)
348 >
348 >
349 > # this confirms that streamclone-ed changes are visible to
349 > # this confirms that streamclone-ed changes are visible to
350 > # in-process procedures before closing transaction
350 > # in-process procedures before closing transaction
351 > ui.setconfig(b'hooks', b'pretxnclose.showtip', showtip)
351 > ui.setconfig(b'hooks', b'pretxnclose.showtip', showtip)
352 >
352 >
353 > # this confirms that streamclone-ed changes are still visible
353 > # this confirms that streamclone-ed changes are still visible
354 > # after closing transaction
354 > # after closing transaction
355 > ui.setconfig(b'hooks', b'txnclose.showtip', showtip)
355 > ui.setconfig(b'hooks', b'txnclose.showtip', showtip)
356 > EOF
356 > EOF
357 $ cat >> $HGRCPATH <<EOF
357 $ cat >> $HGRCPATH <<EOF
358 > [extensions]
358 > [extensions]
359 > showtip = $TESTTMP/showtip.py
359 > showtip = $TESTTMP/showtip.py
360 > EOF
360 > EOF
361
361
362 $ hg -R packed debugapplystreamclonebundle packed.hg
362 $ hg -R packed debugapplystreamclonebundle packed.hg
363 6 files to transfer, 2.60 KB of data
363 6 files to transfer, 2.60 KB of data
364 pretxnopen: 000000000000
364 pretxnopen: 000000000000
365 pretxnclose: aa35859c02ea
365 pretxnclose: aa35859c02ea
366 transferred 2.60 KB in *.* seconds (* */sec) (glob)
366 transferred 2.60 KB in *.* seconds (* */sec) (glob)
367 txnclose: aa35859c02ea
367 txnclose: aa35859c02ea
368
368
369 (for safety, confirm visibility of streamclone-ed changes by another
369 (for safety, confirm visibility of streamclone-ed changes by another
370 process, too)
370 process, too)
371
371
372 $ hg -R packed tip -T "{node|short}\n"
372 $ hg -R packed tip -T "{node|short}\n"
373 aa35859c02ea
373 aa35859c02ea
374
374
375 $ cat >> $HGRCPATH <<EOF
375 $ cat >> $HGRCPATH <<EOF
376 > [extensions]
376 > [extensions]
377 > showtip = !
377 > showtip = !
378 > EOF
378 > EOF
379
379
380 Does not work on non-empty repo
380 Does not work on non-empty repo
381
381
382 $ hg -R packed debugapplystreamclonebundle packed.hg
382 $ hg -R packed debugapplystreamclonebundle packed.hg
383 abort: cannot apply stream clone bundle on non-empty repo
383 abort: cannot apply stream clone bundle on non-empty repo
384 [255]
384 [255]
385
385
386 #endif
386 #endif
387
387
388 Create partial clones
388 Create partial clones
389
389
390 $ rm -r empty
390 $ rm -r empty
391 $ hg init empty
391 $ hg init empty
392 $ hg clone -r 3 test partial
392 $ hg clone -r 3 test partial
393 adding changesets
393 adding changesets
394 adding manifests
394 adding manifests
395 adding file changes
395 adding file changes
396 added 4 changesets with 4 changes to 1 files
396 added 4 changesets with 4 changes to 1 files
397 new changesets f9ee2f85a263:eebf5a27f8ca
397 new changesets f9ee2f85a263:eebf5a27f8ca
398 updating to branch default
398 updating to branch default
399 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
399 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
400 $ hg clone partial partial2
400 $ hg clone partial partial2
401 updating to branch default
401 updating to branch default
402 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
402 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
403 $ cd partial
403 $ cd partial
404
404
405 #if repobundlerepo
405 #if repobundlerepo
406
406
407 Log -R full.hg in partial
407 Log -R full.hg in partial
408
408
409 $ hg -R bundle://../full.hg log -T phases
409 $ hg -R bundle://../full.hg log -T phases
410 changeset: 8:aa35859c02ea
410 changeset: 8:aa35859c02ea
411 tag: tip
411 tag: tip
412 phase: draft
412 phase: draft
413 parent: 3:eebf5a27f8ca
413 parent: 3:eebf5a27f8ca
414 user: test
414 user: test
415 date: Thu Jan 01 00:00:00 1970 +0000
415 date: Thu Jan 01 00:00:00 1970 +0000
416 summary: 0.3m
416 summary: 0.3m
417
417
418 changeset: 7:a6a34bfa0076
418 changeset: 7:a6a34bfa0076
419 phase: draft
419 phase: draft
420 user: test
420 user: test
421 date: Thu Jan 01 00:00:00 1970 +0000
421 date: Thu Jan 01 00:00:00 1970 +0000
422 summary: 1.3m
422 summary: 1.3m
423
423
424 changeset: 6:7373c1169842
424 changeset: 6:7373c1169842
425 phase: draft
425 phase: draft
426 user: test
426 user: test
427 date: Thu Jan 01 00:00:00 1970 +0000
427 date: Thu Jan 01 00:00:00 1970 +0000
428 summary: 1.3
428 summary: 1.3
429
429
430 changeset: 5:1bb50a9436a7
430 changeset: 5:1bb50a9436a7
431 phase: draft
431 phase: draft
432 user: test
432 user: test
433 date: Thu Jan 01 00:00:00 1970 +0000
433 date: Thu Jan 01 00:00:00 1970 +0000
434 summary: 1.2
434 summary: 1.2
435
435
436 changeset: 4:095197eb4973
436 changeset: 4:095197eb4973
437 phase: draft
437 phase: draft
438 parent: 0:f9ee2f85a263
438 parent: 0:f9ee2f85a263
439 user: test
439 user: test
440 date: Thu Jan 01 00:00:00 1970 +0000
440 date: Thu Jan 01 00:00:00 1970 +0000
441 summary: 1.1
441 summary: 1.1
442
442
443 changeset: 3:eebf5a27f8ca
443 changeset: 3:eebf5a27f8ca
444 phase: public
444 phase: public
445 user: test
445 user: test
446 date: Thu Jan 01 00:00:00 1970 +0000
446 date: Thu Jan 01 00:00:00 1970 +0000
447 summary: 0.3
447 summary: 0.3
448
448
449 changeset: 2:e38ba6f5b7e0
449 changeset: 2:e38ba6f5b7e0
450 phase: public
450 phase: public
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: 0.2
453 summary: 0.2
454
454
455 changeset: 1:34c2bf6b0626
455 changeset: 1:34c2bf6b0626
456 phase: public
456 phase: public
457 user: test
457 user: test
458 date: Thu Jan 01 00:00:00 1970 +0000
458 date: Thu Jan 01 00:00:00 1970 +0000
459 summary: 0.1
459 summary: 0.1
460
460
461 changeset: 0:f9ee2f85a263
461 changeset: 0:f9ee2f85a263
462 phase: public
462 phase: public
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.0
465 summary: 0.0
466
466
467
467
468 Incoming full.hg in partial
468 Incoming full.hg in partial
469
469
470 $ hg incoming bundle://../full.hg
470 $ hg incoming bundle://../full.hg
471 comparing with bundle:../full.hg
471 comparing with bundle:../full.hg
472 searching for changes
472 searching for changes
473 changeset: 4:095197eb4973
473 changeset: 4:095197eb4973
474 parent: 0:f9ee2f85a263
474 parent: 0:f9ee2f85a263
475 user: test
475 user: test
476 date: Thu Jan 01 00:00:00 1970 +0000
476 date: Thu Jan 01 00:00:00 1970 +0000
477 summary: 1.1
477 summary: 1.1
478
478
479 changeset: 5:1bb50a9436a7
479 changeset: 5:1bb50a9436a7
480 user: test
480 user: test
481 date: Thu Jan 01 00:00:00 1970 +0000
481 date: Thu Jan 01 00:00:00 1970 +0000
482 summary: 1.2
482 summary: 1.2
483
483
484 changeset: 6:7373c1169842
484 changeset: 6:7373c1169842
485 user: test
485 user: test
486 date: Thu Jan 01 00:00:00 1970 +0000
486 date: Thu Jan 01 00:00:00 1970 +0000
487 summary: 1.3
487 summary: 1.3
488
488
489 changeset: 7:a6a34bfa0076
489 changeset: 7:a6a34bfa0076
490 user: test
490 user: test
491 date: Thu Jan 01 00:00:00 1970 +0000
491 date: Thu Jan 01 00:00:00 1970 +0000
492 summary: 1.3m
492 summary: 1.3m
493
493
494 changeset: 8:aa35859c02ea
494 changeset: 8:aa35859c02ea
495 tag: tip
495 tag: tip
496 parent: 3:eebf5a27f8ca
496 parent: 3:eebf5a27f8ca
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: 0.3m
499 summary: 0.3m
500
500
501
501
502 Outgoing -R full.hg vs partial2 in partial
502 Outgoing -R full.hg vs partial2 in partial
503
503
504 $ hg -R bundle://../full.hg outgoing ../partial2
504 $ hg -R bundle://../full.hg outgoing ../partial2
505 comparing with ../partial2
505 comparing with ../partial2
506 searching for changes
506 searching for changes
507 changeset: 4:095197eb4973
507 changeset: 4:095197eb4973
508 parent: 0:f9ee2f85a263
508 parent: 0:f9ee2f85a263
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: 1.1
511 summary: 1.1
512
512
513 changeset: 5:1bb50a9436a7
513 changeset: 5:1bb50a9436a7
514 user: test
514 user: test
515 date: Thu Jan 01 00:00:00 1970 +0000
515 date: Thu Jan 01 00:00:00 1970 +0000
516 summary: 1.2
516 summary: 1.2
517
517
518 changeset: 6:7373c1169842
518 changeset: 6:7373c1169842
519 user: test
519 user: test
520 date: Thu Jan 01 00:00:00 1970 +0000
520 date: Thu Jan 01 00:00:00 1970 +0000
521 summary: 1.3
521 summary: 1.3
522
522
523 changeset: 7:a6a34bfa0076
523 changeset: 7:a6a34bfa0076
524 user: test
524 user: test
525 date: Thu Jan 01 00:00:00 1970 +0000
525 date: Thu Jan 01 00:00:00 1970 +0000
526 summary: 1.3m
526 summary: 1.3m
527
527
528 changeset: 8:aa35859c02ea
528 changeset: 8:aa35859c02ea
529 tag: tip
529 tag: tip
530 parent: 3:eebf5a27f8ca
530 parent: 3:eebf5a27f8ca
531 user: test
531 user: test
532 date: Thu Jan 01 00:00:00 1970 +0000
532 date: Thu Jan 01 00:00:00 1970 +0000
533 summary: 0.3m
533 summary: 0.3m
534
534
535
535
536 Outgoing -R does-not-exist.hg vs partial2 in partial
536 Outgoing -R does-not-exist.hg vs partial2 in partial
537
537
538 $ hg -R bundle://../does-not-exist.hg outgoing ../partial2
538 $ hg -R bundle://../does-not-exist.hg outgoing ../partial2
539 abort: *../does-not-exist.hg* (glob)
539 abort: *../does-not-exist.hg* (glob)
540 [255]
540 [255]
541
541
542 #endif
542 #endif
543
543
544 $ cd ..
544 $ cd ..
545
545
546 hide outer repo
546 hide outer repo
547 $ hg init
547 $ hg init
548
548
549 Direct clone from bundle (all-history)
549 Direct clone from bundle (all-history)
550
550
551 #if repobundlerepo
551 #if repobundlerepo
552
552
553 $ hg clone full.hg full-clone
553 $ hg clone full.hg full-clone
554 requesting all changes
554 requesting all changes
555 adding changesets
555 adding changesets
556 adding manifests
556 adding manifests
557 adding file changes
557 adding file changes
558 added 9 changesets with 7 changes to 4 files (+1 heads)
558 added 9 changesets with 7 changes to 4 files (+1 heads)
559 new changesets f9ee2f85a263:aa35859c02ea
559 new changesets f9ee2f85a263:aa35859c02ea
560 updating to branch default
560 updating to branch default
561 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
561 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
562 $ hg -R full-clone heads
562 $ hg -R full-clone heads
563 changeset: 8:aa35859c02ea
563 changeset: 8:aa35859c02ea
564 tag: tip
564 tag: tip
565 parent: 3:eebf5a27f8ca
565 parent: 3:eebf5a27f8ca
566 user: test
566 user: test
567 date: Thu Jan 01 00:00:00 1970 +0000
567 date: Thu Jan 01 00:00:00 1970 +0000
568 summary: 0.3m
568 summary: 0.3m
569
569
570 changeset: 7:a6a34bfa0076
570 changeset: 7:a6a34bfa0076
571 user: test
571 user: test
572 date: Thu Jan 01 00:00:00 1970 +0000
572 date: Thu Jan 01 00:00:00 1970 +0000
573 summary: 1.3m
573 summary: 1.3m
574
574
575 $ rm -r full-clone
575 $ rm -r full-clone
576
576
577 When cloning from a non-copiable repository into '', do not
577 When cloning from a non-copiable repository into '', do not
578 recurse infinitely (issue2528)
578 recurse infinitely (issue2528)
579
579
580 $ hg clone full.hg ''
580 $ hg clone full.hg ''
581 abort: empty destination path is not valid
581 abort: empty destination path is not valid
582 [255]
582 [255]
583
583
584 test for https://bz.mercurial-scm.org/216
584 test for https://bz.mercurial-scm.org/216
585
585
586 Unbundle incremental bundles into fresh empty in one go
586 Unbundle incremental bundles into fresh empty in one go
587
587
588 $ rm -r empty
588 $ rm -r empty
589 $ hg init empty
589 $ hg init empty
590 $ hg -R test bundle --base null -r 0 ../0.hg
590 $ hg -R test bundle --base null -r 0 ../0.hg
591 1 changesets found
591 1 changesets found
592 $ hg -R test bundle --base 0 -r 1 ../1.hg
592 $ hg -R test bundle --base 0 -r 1 ../1.hg
593 1 changesets found
593 1 changesets found
594 $ hg -R empty unbundle -u ../0.hg ../1.hg
594 $ hg -R empty unbundle -u ../0.hg ../1.hg
595 adding changesets
595 adding changesets
596 adding manifests
596 adding manifests
597 adding file changes
597 adding file changes
598 added 1 changesets with 1 changes to 1 files
598 added 1 changesets with 1 changes to 1 files
599 new changesets f9ee2f85a263
599 new changesets f9ee2f85a263
600 adding changesets
600 adding changesets
601 adding manifests
601 adding manifests
602 adding file changes
602 adding file changes
603 added 1 changesets with 1 changes to 1 files
603 added 1 changesets with 1 changes to 1 files
604 new changesets 34c2bf6b0626
604 new changesets 34c2bf6b0626
605 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
605 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
606
606
607 View full contents of the bundle
607 View full contents of the bundle
608 $ hg -R test bundle --base null -r 3 ../partial.hg
608 $ hg -R test bundle --base null -r 3 ../partial.hg
609 4 changesets found
609 4 changesets found
610 $ cd test
610 $ cd test
611 $ hg -R ../../partial.hg log -r "bundle()"
611 $ hg -R ../../partial.hg log -r "bundle()"
612 changeset: 0:f9ee2f85a263
612 changeset: 0:f9ee2f85a263
613 user: test
613 user: test
614 date: Thu Jan 01 00:00:00 1970 +0000
614 date: Thu Jan 01 00:00:00 1970 +0000
615 summary: 0.0
615 summary: 0.0
616
616
617 changeset: 1:34c2bf6b0626
617 changeset: 1:34c2bf6b0626
618 user: test
618 user: test
619 date: Thu Jan 01 00:00:00 1970 +0000
619 date: Thu Jan 01 00:00:00 1970 +0000
620 summary: 0.1
620 summary: 0.1
621
621
622 changeset: 2:e38ba6f5b7e0
622 changeset: 2:e38ba6f5b7e0
623 user: test
623 user: test
624 date: Thu Jan 01 00:00:00 1970 +0000
624 date: Thu Jan 01 00:00:00 1970 +0000
625 summary: 0.2
625 summary: 0.2
626
626
627 changeset: 3:eebf5a27f8ca
627 changeset: 3:eebf5a27f8ca
628 user: test
628 user: test
629 date: Thu Jan 01 00:00:00 1970 +0000
629 date: Thu Jan 01 00:00:00 1970 +0000
630 summary: 0.3
630 summary: 0.3
631
631
632 $ cd ..
632 $ cd ..
633
633
634 #endif
634 #endif
635
635
636 test for 540d1059c802
636 test for 540d1059c802
637
637
638 $ hg init orig
638 $ hg init orig
639 $ cd orig
639 $ cd orig
640 $ echo foo > foo
640 $ echo foo > foo
641 $ hg add foo
641 $ hg add foo
642 $ hg ci -m 'add foo'
642 $ hg ci -m 'add foo'
643
643
644 $ hg clone . ../copy
644 $ hg clone . ../copy
645 updating to branch default
645 updating to branch default
646 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
646 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
647 $ hg tag foo
647 $ hg tag foo
648
648
649 $ cd ../copy
649 $ cd ../copy
650 $ echo >> foo
650 $ echo >> foo
651 $ hg ci -m 'change foo'
651 $ hg ci -m 'change foo'
652 $ hg bundle ../bundle.hg ../orig
652 $ hg bundle ../bundle.hg ../orig
653 searching for changes
653 searching for changes
654 1 changesets found
654 1 changesets found
655
655
656 $ cd ..
656 $ cd ..
657
657
658 #if repobundlerepo
658 #if repobundlerepo
659 $ cd orig
659 $ cd orig
660 $ hg incoming ../bundle.hg
660 $ hg incoming ../bundle.hg
661 comparing with ../bundle.hg
661 comparing with ../bundle.hg
662 searching for changes
662 searching for changes
663 changeset: 2:ed1b79f46b9a
663 changeset: 2:ed1b79f46b9a
664 tag: tip
664 tag: tip
665 parent: 0:bbd179dfa0a7
665 parent: 0:bbd179dfa0a7
666 user: test
666 user: test
667 date: Thu Jan 01 00:00:00 1970 +0000
667 date: Thu Jan 01 00:00:00 1970 +0000
668 summary: change foo
668 summary: change foo
669
669
670 $ cd ..
670 $ cd ..
671
671
672 test bundle with # in the filename (issue2154):
672 test bundle with # in the filename (issue2154):
673
673
674 $ cp bundle.hg 'test#bundle.hg'
674 $ cp bundle.hg 'test#bundle.hg'
675 $ cd orig
675 $ cd orig
676 $ hg incoming '../test#bundle.hg'
676 $ hg incoming '../test#bundle.hg'
677 comparing with ../test
677 comparing with ../test
678 abort: unknown revision 'bundle.hg'!
678 abort: unknown revision 'bundle.hg'!
679 [255]
679 [255]
680
680
681 note that percent encoding is not handled:
681 note that percent encoding is not handled:
682
682
683 $ hg incoming ../test%23bundle.hg
683 $ hg incoming ../test%23bundle.hg
684 abort: repository ../test%23bundle.hg not found!
684 abort: repository ../test%23bundle.hg not found!
685 [255]
685 [255]
686 $ cd ..
686 $ cd ..
687
687
688 #endif
688 #endif
689
689
690 test to bundle revisions on the newly created branch (issue3828):
690 test to bundle revisions on the newly created branch (issue3828):
691
691
692 $ hg -q clone -U test test-clone
692 $ hg -q clone -U test test-clone
693 $ cd test
693 $ cd test
694
694
695 $ hg -q branch foo
695 $ hg -q branch foo
696 $ hg commit -m "create foo branch"
696 $ hg commit -m "create foo branch"
697 $ hg -q outgoing ../test-clone
697 $ hg -q outgoing ../test-clone
698 9:b4f5acb1ee27
698 9:b4f5acb1ee27
699 $ hg -q bundle --branch foo foo.hg ../test-clone
699 $ hg -q bundle --branch foo foo.hg ../test-clone
700 #if repobundlerepo
700 #if repobundlerepo
701 $ hg -R foo.hg -q log -r "bundle()"
701 $ hg -R foo.hg -q log -r "bundle()"
702 9:b4f5acb1ee27
702 9:b4f5acb1ee27
703 #endif
703 #endif
704
704
705 $ cd ..
705 $ cd ..
706
706
707 test for https://bz.mercurial-scm.org/1144
707 test for https://bz.mercurial-scm.org/1144
708
708
709 test that verify bundle does not traceback
709 test that verify bundle does not traceback
710
710
711 partial history bundle, fails w/ unknown parent
711 partial history bundle, fails w/ unknown parent
712
712
713 $ hg -R bundle.hg verify
713 $ hg -R bundle.hg verify
714 abort: 00changelog.i@bbd179dfa0a7: unknown parent!
714 abort: 00changelog.i@bbd179dfa0a7: unknown parent!
715 [255]
715 [255]
716
716
717 full history bundle, refuses to verify non-local repo
717 full history bundle, refuses to verify non-local repo
718
718
719 #if repobundlerepo
719 #if repobundlerepo
720 $ hg -R all.hg verify
720 $ hg -R all.hg verify
721 abort: cannot verify bundle or remote repos
721 abort: cannot verify bundle or remote repos
722 [255]
722 [255]
723 #endif
723 #endif
724
724
725 but, regular verify must continue to work
725 but, regular verify must continue to work
726
726
727 $ hg -R orig verify
727 $ hg -R orig verify
728 checking changesets
728 checking changesets
729 checking manifests
729 checking manifests
730 crosschecking files in changesets and manifests
730 crosschecking files in changesets and manifests
731 checking files
731 checking files
732 2 files, 2 changesets, 2 total revisions
732 2 files, 2 changesets, 2 total revisions
733
733
734 #if repobundlerepo
734 #if repobundlerepo
735 diff against bundle
735 diff against bundle
736
736
737 $ hg init b
737 $ hg init b
738 $ cd b
738 $ cd b
739 $ hg -R ../all.hg diff -r tip
739 $ hg -R ../all.hg diff -r tip
740 diff -r aa35859c02ea anotherfile
740 diff -r aa35859c02ea anotherfile
741 --- a/anotherfile Thu Jan 01 00:00:00 1970 +0000
741 --- a/anotherfile Thu Jan 01 00:00:00 1970 +0000
742 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
742 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
743 @@ -1,4 +0,0 @@
743 @@ -1,4 +0,0 @@
744 -0
744 -0
745 -1
745 -1
746 -2
746 -2
747 -3
747 -3
748 $ cd ..
748 $ cd ..
749 #endif
749 #endif
750
750
751 bundle single branch
751 bundle single branch
752
752
753 $ hg init branchy
753 $ hg init branchy
754 $ cd branchy
754 $ cd branchy
755 $ echo a >a
755 $ echo a >a
756 $ echo x >x
756 $ echo x >x
757 $ hg ci -Ama
757 $ hg ci -Ama
758 adding a
758 adding a
759 adding x
759 adding x
760 $ echo c >c
760 $ echo c >c
761 $ echo xx >x
761 $ echo xx >x
762 $ hg ci -Amc
762 $ hg ci -Amc
763 adding c
763 adding c
764 $ echo c1 >c1
764 $ echo c1 >c1
765 $ hg ci -Amc1
765 $ hg ci -Amc1
766 adding c1
766 adding c1
767 $ hg up 0
767 $ hg up 0
768 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
768 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
769 $ echo b >b
769 $ echo b >b
770 $ hg ci -Amb
770 $ hg ci -Amb
771 adding b
771 adding b
772 created new head
772 created new head
773 $ echo b1 >b1
773 $ echo b1 >b1
774 $ echo xx >x
774 $ echo xx >x
775 $ hg ci -Amb1
775 $ hg ci -Amb1
776 adding b1
776 adding b1
777 $ hg clone -q -r2 . part
777 $ hg clone -q -r2 . part
778
778
779 == bundling via incoming
779 == bundling via incoming
780
780
781 $ hg in -R part --bundle incoming.hg --template "{node}\n" .
781 $ hg in -R part --bundle incoming.hg --template "{node}\n" .
782 comparing with .
782 comparing with .
783 searching for changes
783 searching for changes
784 1a38c1b849e8b70c756d2d80b0b9a3ac0b7ea11a
784 1a38c1b849e8b70c756d2d80b0b9a3ac0b7ea11a
785 057f4db07f61970e1c11e83be79e9d08adc4dc31
785 057f4db07f61970e1c11e83be79e9d08adc4dc31
786
786
787 == bundling
787 == bundling
788
788
789 $ hg bundle bundle.hg part --debug --config progress.debug=true
789 $ hg bundle bundle.hg part --debug --config progress.debug=true
790 query 1; heads
790 query 1; heads
791 searching for changes
791 searching for changes
792 all remote heads known locally
792 all remote heads known locally
793 2 changesets found
793 2 changesets found
794 list of changesets:
794 list of changesets:
795 1a38c1b849e8b70c756d2d80b0b9a3ac0b7ea11a
795 1a38c1b849e8b70c756d2d80b0b9a3ac0b7ea11a
796 057f4db07f61970e1c11e83be79e9d08adc4dc31
796 057f4db07f61970e1c11e83be79e9d08adc4dc31
797 bundle2-output-bundle: "HG20", (1 params) 2 parts total
797 bundle2-output-bundle: "HG20", (1 params) 2 parts total
798 bundle2-output-part: "changegroup" (params: 1 mandatory 1 advisory) streamed payload
798 bundle2-output-part: "changegroup" (params: 1 mandatory 1 advisory) streamed payload
799 bundling: 1/2 changesets (50.00%)
799 changesets: 1/2 chunks (50.00%)
800 bundling: 2/2 changesets (100.00%)
800 changesets: 2/2 chunks (100.00%)
801 bundling: 1/2 manifests (50.00%)
801 manifests: 1/2 chunks (50.00%)
802 bundling: 2/2 manifests (100.00%)
802 manifests: 2/2 chunks (100.00%)
803 bundling: b 1/3 files (33.33%)
803 files: b 1/3 files (33.33%)
804 bundling: b1 2/3 files (66.67%)
804 files: b1 2/3 files (66.67%)
805 bundling: x 3/3 files (100.00%)
805 files: x 3/3 files (100.00%)
806 bundle2-output-part: "cache:rev-branch-cache" (advisory) streamed payload
806 bundle2-output-part: "cache:rev-branch-cache" (advisory) streamed payload
807
807
808 #if repobundlerepo
808 #if repobundlerepo
809 == Test for issue3441
809 == Test for issue3441
810
810
811 $ hg clone -q -r0 . part2
811 $ hg clone -q -r0 . part2
812 $ hg -q -R part2 pull bundle.hg
812 $ hg -q -R part2 pull bundle.hg
813 $ hg -R part2 verify
813 $ hg -R part2 verify
814 checking changesets
814 checking changesets
815 checking manifests
815 checking manifests
816 crosschecking files in changesets and manifests
816 crosschecking files in changesets and manifests
817 checking files
817 checking files
818 4 files, 3 changesets, 5 total revisions
818 4 files, 3 changesets, 5 total revisions
819 #endif
819 #endif
820
820
821 == Test bundling no commits
821 == Test bundling no commits
822
822
823 $ hg bundle -r 'public()' no-output.hg
823 $ hg bundle -r 'public()' no-output.hg
824 abort: no commits to bundle
824 abort: no commits to bundle
825 [255]
825 [255]
826
826
827 $ cd ..
827 $ cd ..
828
828
829 When user merges to the revision existing only in the bundle,
829 When user merges to the revision existing only in the bundle,
830 it should show warning that second parent of the working
830 it should show warning that second parent of the working
831 directory does not exist
831 directory does not exist
832
832
833 $ hg init update2bundled
833 $ hg init update2bundled
834 $ cd update2bundled
834 $ cd update2bundled
835 $ cat <<EOF >> .hg/hgrc
835 $ cat <<EOF >> .hg/hgrc
836 > [extensions]
836 > [extensions]
837 > strip =
837 > strip =
838 > EOF
838 > EOF
839 $ echo "aaa" >> a
839 $ echo "aaa" >> a
840 $ hg commit -A -m 0
840 $ hg commit -A -m 0
841 adding a
841 adding a
842 $ echo "bbb" >> b
842 $ echo "bbb" >> b
843 $ hg commit -A -m 1
843 $ hg commit -A -m 1
844 adding b
844 adding b
845 $ echo "ccc" >> c
845 $ echo "ccc" >> c
846 $ hg commit -A -m 2
846 $ hg commit -A -m 2
847 adding c
847 adding c
848 $ hg update -r 1
848 $ hg update -r 1
849 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
849 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
850 $ echo "ddd" >> d
850 $ echo "ddd" >> d
851 $ hg commit -A -m 3
851 $ hg commit -A -m 3
852 adding d
852 adding d
853 created new head
853 created new head
854 $ hg update -r 2
854 $ hg update -r 2
855 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
855 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
856 $ hg log -G
856 $ hg log -G
857 o changeset: 3:8bd3e1f196af
857 o changeset: 3:8bd3e1f196af
858 | tag: tip
858 | tag: tip
859 | parent: 1:a01eca7af26d
859 | parent: 1:a01eca7af26d
860 | user: test
860 | user: test
861 | date: Thu Jan 01 00:00:00 1970 +0000
861 | date: Thu Jan 01 00:00:00 1970 +0000
862 | summary: 3
862 | summary: 3
863 |
863 |
864 | @ changeset: 2:4652c276ac4f
864 | @ changeset: 2:4652c276ac4f
865 |/ user: test
865 |/ user: test
866 | date: Thu Jan 01 00:00:00 1970 +0000
866 | date: Thu Jan 01 00:00:00 1970 +0000
867 | summary: 2
867 | summary: 2
868 |
868 |
869 o changeset: 1:a01eca7af26d
869 o changeset: 1:a01eca7af26d
870 | user: test
870 | user: test
871 | date: Thu Jan 01 00:00:00 1970 +0000
871 | date: Thu Jan 01 00:00:00 1970 +0000
872 | summary: 1
872 | summary: 1
873 |
873 |
874 o changeset: 0:4fe08cd4693e
874 o changeset: 0:4fe08cd4693e
875 user: test
875 user: test
876 date: Thu Jan 01 00:00:00 1970 +0000
876 date: Thu Jan 01 00:00:00 1970 +0000
877 summary: 0
877 summary: 0
878
878
879
879
880 #if repobundlerepo
880 #if repobundlerepo
881 $ hg bundle --base 1 -r 3 ../update2bundled.hg
881 $ hg bundle --base 1 -r 3 ../update2bundled.hg
882 1 changesets found
882 1 changesets found
883 $ hg strip -r 3
883 $ hg strip -r 3
884 saved backup bundle to $TESTTMP/update2bundled/.hg/strip-backup/8bd3e1f196af-017e56d8-backup.hg
884 saved backup bundle to $TESTTMP/update2bundled/.hg/strip-backup/8bd3e1f196af-017e56d8-backup.hg
885 $ hg merge -R ../update2bundled.hg -r 3
885 $ hg merge -R ../update2bundled.hg -r 3
886 setting parent to node 8bd3e1f196af289b2b121be08031e76d7ae92098 that only exists in the bundle
886 setting parent to node 8bd3e1f196af289b2b121be08031e76d7ae92098 that only exists in the bundle
887 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
887 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
888 (branch merge, don't forget to commit)
888 (branch merge, don't forget to commit)
889
889
890 When user updates to the revision existing only in the bundle,
890 When user updates to the revision existing only in the bundle,
891 it should show warning
891 it should show warning
892
892
893 $ hg update -R ../update2bundled.hg --clean -r 3
893 $ hg update -R ../update2bundled.hg --clean -r 3
894 setting parent to node 8bd3e1f196af289b2b121be08031e76d7ae92098 that only exists in the bundle
894 setting parent to node 8bd3e1f196af289b2b121be08031e76d7ae92098 that only exists in the bundle
895 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
895 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
896
896
897 When user updates to the revision existing in the local repository
897 When user updates to the revision existing in the local repository
898 the warning shouldn't be emitted
898 the warning shouldn't be emitted
899
899
900 $ hg update -R ../update2bundled.hg -r 0
900 $ hg update -R ../update2bundled.hg -r 0
901 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
901 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
902 #endif
902 #endif
@@ -1,1236 +1,1236 b''
1 This test is dedicated to test the bundle2 container format
1 This test is dedicated to test the bundle2 container format
2
2
3 It test multiple existing parts to test different feature of the container. You
3 It test multiple existing parts to test different feature of the container. You
4 probably do not need to touch this test unless you change the binary encoding
4 probably do not need to touch this test unless you change the binary encoding
5 of the bundle2 format itself.
5 of the bundle2 format itself.
6
6
7 Create an extension to test bundle2 API
7 Create an extension to test bundle2 API
8
8
9 $ cat > bundle2.py << EOF
9 $ cat > bundle2.py << EOF
10 > """A small extension to test bundle2 implementation
10 > """A small extension to test bundle2 implementation
11 >
11 >
12 > This extension allows detailed testing of the various bundle2 API and
12 > This extension allows detailed testing of the various bundle2 API and
13 > behaviors.
13 > behaviors.
14 > """
14 > """
15 > import gc
15 > import gc
16 > import os
16 > import os
17 > import sys
17 > import sys
18 > from mercurial import util
18 > from mercurial import util
19 > from mercurial import bundle2
19 > from mercurial import bundle2
20 > from mercurial import scmutil
20 > from mercurial import scmutil
21 > from mercurial import discovery
21 > from mercurial import discovery
22 > from mercurial import changegroup
22 > from mercurial import changegroup
23 > from mercurial import error
23 > from mercurial import error
24 > from mercurial import obsolete
24 > from mercurial import obsolete
25 > from mercurial import pycompat
25 > from mercurial import pycompat
26 > from mercurial import registrar
26 > from mercurial import registrar
27 >
27 >
28 >
28 >
29 > try:
29 > try:
30 > import msvcrt
30 > import msvcrt
31 > msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY)
31 > msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY)
32 > msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
32 > msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
33 > msvcrt.setmode(sys.stderr.fileno(), os.O_BINARY)
33 > msvcrt.setmode(sys.stderr.fileno(), os.O_BINARY)
34 > except ImportError:
34 > except ImportError:
35 > pass
35 > pass
36 >
36 >
37 > cmdtable = {}
37 > cmdtable = {}
38 > command = registrar.command(cmdtable)
38 > command = registrar.command(cmdtable)
39 >
39 >
40 > ELEPHANTSSONG = b"""Patali Dirapata, Cromda Cromda Ripalo, Pata Pata, Ko Ko Ko
40 > ELEPHANTSSONG = b"""Patali Dirapata, Cromda Cromda Ripalo, Pata Pata, Ko Ko Ko
41 > Bokoro Dipoulito, Rondi Rondi Pepino, Pata Pata, Ko Ko Ko
41 > Bokoro Dipoulito, Rondi Rondi Pepino, Pata Pata, Ko Ko Ko
42 > Emana Karassoli, Loucra Loucra Ponponto, Pata Pata, Ko Ko Ko."""
42 > Emana Karassoli, Loucra Loucra Ponponto, Pata Pata, Ko Ko Ko."""
43 > assert len(ELEPHANTSSONG) == 178 # future test say 178 bytes, trust it.
43 > assert len(ELEPHANTSSONG) == 178 # future test say 178 bytes, trust it.
44 >
44 >
45 > @bundle2.parthandler(b'test:song')
45 > @bundle2.parthandler(b'test:song')
46 > def songhandler(op, part):
46 > def songhandler(op, part):
47 > """handle a "test:song" bundle2 part, printing the lyrics on stdin"""
47 > """handle a "test:song" bundle2 part, printing the lyrics on stdin"""
48 > op.ui.write(b'The choir starts singing:\n')
48 > op.ui.write(b'The choir starts singing:\n')
49 > verses = 0
49 > verses = 0
50 > for line in part.read().split(b'\n'):
50 > for line in part.read().split(b'\n'):
51 > op.ui.write(b' %s\n' % line)
51 > op.ui.write(b' %s\n' % line)
52 > verses += 1
52 > verses += 1
53 > op.records.add(b'song', {b'verses': verses})
53 > op.records.add(b'song', {b'verses': verses})
54 >
54 >
55 > @bundle2.parthandler(b'test:ping')
55 > @bundle2.parthandler(b'test:ping')
56 > def pinghandler(op, part):
56 > def pinghandler(op, part):
57 > op.ui.write(b'received ping request (id %i)\n' % part.id)
57 > op.ui.write(b'received ping request (id %i)\n' % part.id)
58 > if op.reply is not None and b'ping-pong' in op.reply.capabilities:
58 > if op.reply is not None and b'ping-pong' in op.reply.capabilities:
59 > op.ui.write_err(b'replying to ping request (id %i)\n' % part.id)
59 > op.ui.write_err(b'replying to ping request (id %i)\n' % part.id)
60 > op.reply.newpart(b'test:pong', [(b'in-reply-to', b'%d' % part.id)],
60 > op.reply.newpart(b'test:pong', [(b'in-reply-to', b'%d' % part.id)],
61 > mandatory=False)
61 > mandatory=False)
62 >
62 >
63 > @bundle2.parthandler(b'test:debugreply')
63 > @bundle2.parthandler(b'test:debugreply')
64 > def debugreply(op, part):
64 > def debugreply(op, part):
65 > """print data about the capacity of the bundle reply"""
65 > """print data about the capacity of the bundle reply"""
66 > if op.reply is None:
66 > if op.reply is None:
67 > op.ui.write(b'debugreply: no reply\n')
67 > op.ui.write(b'debugreply: no reply\n')
68 > else:
68 > else:
69 > op.ui.write(b'debugreply: capabilities:\n')
69 > op.ui.write(b'debugreply: capabilities:\n')
70 > for cap in sorted(op.reply.capabilities):
70 > for cap in sorted(op.reply.capabilities):
71 > op.ui.write(b"debugreply: '%s'\n" % cap)
71 > op.ui.write(b"debugreply: '%s'\n" % cap)
72 > for val in op.reply.capabilities[cap]:
72 > for val in op.reply.capabilities[cap]:
73 > op.ui.write(b"debugreply: '%s'\n" % val)
73 > op.ui.write(b"debugreply: '%s'\n" % val)
74 >
74 >
75 > @command(b'bundle2',
75 > @command(b'bundle2',
76 > [(b'', b'param', [], b'stream level parameter'),
76 > [(b'', b'param', [], b'stream level parameter'),
77 > (b'', b'unknown', False, b'include an unknown mandatory part in the bundle'),
77 > (b'', b'unknown', False, b'include an unknown mandatory part in the bundle'),
78 > (b'', b'unknownparams', False, b'include an unknown part parameters in the bundle'),
78 > (b'', b'unknownparams', False, b'include an unknown part parameters in the bundle'),
79 > (b'', b'parts', False, b'include some arbitrary parts to the bundle'),
79 > (b'', b'parts', False, b'include some arbitrary parts to the bundle'),
80 > (b'', b'reply', False, b'produce a reply bundle'),
80 > (b'', b'reply', False, b'produce a reply bundle'),
81 > (b'', b'pushrace', False, b'includes a check:head part with unknown nodes'),
81 > (b'', b'pushrace', False, b'includes a check:head part with unknown nodes'),
82 > (b'', b'genraise', False, b'includes a part that raise an exception during generation'),
82 > (b'', b'genraise', False, b'includes a part that raise an exception during generation'),
83 > (b'', b'timeout', False, b'emulate a timeout during bundle generation'),
83 > (b'', b'timeout', False, b'emulate a timeout during bundle generation'),
84 > (b'r', b'rev', [], b'includes those changeset in the bundle'),
84 > (b'r', b'rev', [], b'includes those changeset in the bundle'),
85 > (b'', b'compress', b'', b'compress the stream'),],
85 > (b'', b'compress', b'', b'compress the stream'),],
86 > b'[OUTPUTFILE]')
86 > b'[OUTPUTFILE]')
87 > def cmdbundle2(ui, repo, path=None, **opts):
87 > def cmdbundle2(ui, repo, path=None, **opts):
88 > """write a bundle2 container on standard output"""
88 > """write a bundle2 container on standard output"""
89 > bundler = bundle2.bundle20(ui)
89 > bundler = bundle2.bundle20(ui)
90 > for p in opts['param']:
90 > for p in opts['param']:
91 > p = p.split(b'=', 1)
91 > p = p.split(b'=', 1)
92 > try:
92 > try:
93 > bundler.addparam(*p)
93 > bundler.addparam(*p)
94 > except error.ProgrammingError as exc:
94 > except error.ProgrammingError as exc:
95 > raise error.Abort(b'%s' % exc)
95 > raise error.Abort(b'%s' % exc)
96 >
96 >
97 > if opts['compress']:
97 > if opts['compress']:
98 > bundler.setcompression(opts['compress'])
98 > bundler.setcompression(opts['compress'])
99 >
99 >
100 > if opts['reply']:
100 > if opts['reply']:
101 > capsstring = b'ping-pong\nelephants=babar,celeste\ncity%3D%21=celeste%2Cville'
101 > capsstring = b'ping-pong\nelephants=babar,celeste\ncity%3D%21=celeste%2Cville'
102 > bundler.newpart(b'replycaps', data=capsstring)
102 > bundler.newpart(b'replycaps', data=capsstring)
103 >
103 >
104 > if opts['pushrace']:
104 > if opts['pushrace']:
105 > # also serve to test the assignement of data outside of init
105 > # also serve to test the assignement of data outside of init
106 > part = bundler.newpart(b'check:heads')
106 > part = bundler.newpart(b'check:heads')
107 > part.data = b'01234567890123456789'
107 > part.data = b'01234567890123456789'
108 >
108 >
109 > revs = opts['rev']
109 > revs = opts['rev']
110 > if 'rev' in opts:
110 > if 'rev' in opts:
111 > revs = scmutil.revrange(repo, opts['rev'])
111 > revs = scmutil.revrange(repo, opts['rev'])
112 > if revs:
112 > if revs:
113 > # very crude version of a changegroup part creation
113 > # very crude version of a changegroup part creation
114 > bundled = repo.revs('%ld::%ld', revs, revs)
114 > bundled = repo.revs('%ld::%ld', revs, revs)
115 > headmissing = [c.node() for c in repo.set('heads(%ld)', revs)]
115 > headmissing = [c.node() for c in repo.set('heads(%ld)', revs)]
116 > headcommon = [c.node() for c in repo.set('parents(%ld) - %ld', revs, revs)]
116 > headcommon = [c.node() for c in repo.set('parents(%ld) - %ld', revs, revs)]
117 > outgoing = discovery.outgoing(repo, headcommon, headmissing)
117 > outgoing = discovery.outgoing(repo, headcommon, headmissing)
118 > cg = changegroup.makechangegroup(repo, outgoing, b'01',
118 > cg = changegroup.makechangegroup(repo, outgoing, b'01',
119 > b'test:bundle2')
119 > b'test:bundle2')
120 > bundler.newpart(b'changegroup', data=cg.getchunks(),
120 > bundler.newpart(b'changegroup', data=cg.getchunks(),
121 > mandatory=False)
121 > mandatory=False)
122 >
122 >
123 > if opts['parts']:
123 > if opts['parts']:
124 > bundler.newpart(b'test:empty', mandatory=False)
124 > bundler.newpart(b'test:empty', mandatory=False)
125 > # add a second one to make sure we handle multiple parts
125 > # add a second one to make sure we handle multiple parts
126 > bundler.newpart(b'test:empty', mandatory=False)
126 > bundler.newpart(b'test:empty', mandatory=False)
127 > bundler.newpart(b'test:song', data=ELEPHANTSSONG, mandatory=False)
127 > bundler.newpart(b'test:song', data=ELEPHANTSSONG, mandatory=False)
128 > bundler.newpart(b'test:debugreply', mandatory=False)
128 > bundler.newpart(b'test:debugreply', mandatory=False)
129 > mathpart = bundler.newpart(b'test:math')
129 > mathpart = bundler.newpart(b'test:math')
130 > mathpart.addparam(b'pi', b'3.14')
130 > mathpart.addparam(b'pi', b'3.14')
131 > mathpart.addparam(b'e', b'2.72')
131 > mathpart.addparam(b'e', b'2.72')
132 > mathpart.addparam(b'cooking', b'raw', mandatory=False)
132 > mathpart.addparam(b'cooking', b'raw', mandatory=False)
133 > mathpart.data = b'42'
133 > mathpart.data = b'42'
134 > mathpart.mandatory = False
134 > mathpart.mandatory = False
135 > # advisory known part with unknown mandatory param
135 > # advisory known part with unknown mandatory param
136 > bundler.newpart(b'test:song', [(b'randomparam', b'')], mandatory=False)
136 > bundler.newpart(b'test:song', [(b'randomparam', b'')], mandatory=False)
137 > if opts['unknown']:
137 > if opts['unknown']:
138 > bundler.newpart(b'test:unknown', data=b'some random content')
138 > bundler.newpart(b'test:unknown', data=b'some random content')
139 > if opts['unknownparams']:
139 > if opts['unknownparams']:
140 > bundler.newpart(b'test:song', [(b'randomparams', b'')])
140 > bundler.newpart(b'test:song', [(b'randomparams', b'')])
141 > if opts['parts']:
141 > if opts['parts']:
142 > bundler.newpart(b'test:ping', mandatory=False)
142 > bundler.newpart(b'test:ping', mandatory=False)
143 > if opts['genraise']:
143 > if opts['genraise']:
144 > def genraise():
144 > def genraise():
145 > yield b'first line\n'
145 > yield b'first line\n'
146 > raise RuntimeError('Someone set up us the bomb!')
146 > raise RuntimeError('Someone set up us the bomb!')
147 > bundler.newpart(b'output', data=genraise(), mandatory=False)
147 > bundler.newpart(b'output', data=genraise(), mandatory=False)
148 >
148 >
149 > if path is None:
149 > if path is None:
150 > file = pycompat.stdout
150 > file = pycompat.stdout
151 > else:
151 > else:
152 > file = open(path, 'wb')
152 > file = open(path, 'wb')
153 >
153 >
154 > if opts['timeout']:
154 > if opts['timeout']:
155 > bundler.newpart(b'test:song', data=ELEPHANTSSONG, mandatory=False)
155 > bundler.newpart(b'test:song', data=ELEPHANTSSONG, mandatory=False)
156 > for idx, junk in enumerate(bundler.getchunks()):
156 > for idx, junk in enumerate(bundler.getchunks()):
157 > ui.write(b'%d chunk\n' % idx)
157 > ui.write(b'%d chunk\n' % idx)
158 > if idx > 4:
158 > if idx > 4:
159 > # This throws a GeneratorExit inside the generator, which
159 > # This throws a GeneratorExit inside the generator, which
160 > # can cause problems if the exception-recovery code is
160 > # can cause problems if the exception-recovery code is
161 > # too zealous. It's important for this test that the break
161 > # too zealous. It's important for this test that the break
162 > # occur while we're in the middle of a part.
162 > # occur while we're in the middle of a part.
163 > break
163 > break
164 > gc.collect()
164 > gc.collect()
165 > ui.write(b'fake timeout complete.\n')
165 > ui.write(b'fake timeout complete.\n')
166 > return
166 > return
167 > try:
167 > try:
168 > for chunk in bundler.getchunks():
168 > for chunk in bundler.getchunks():
169 > file.write(chunk)
169 > file.write(chunk)
170 > except RuntimeError as exc:
170 > except RuntimeError as exc:
171 > raise error.Abort(exc)
171 > raise error.Abort(exc)
172 > finally:
172 > finally:
173 > file.flush()
173 > file.flush()
174 >
174 >
175 > @command(b'unbundle2', [], b'')
175 > @command(b'unbundle2', [], b'')
176 > def cmdunbundle2(ui, repo, replypath=None):
176 > def cmdunbundle2(ui, repo, replypath=None):
177 > """process a bundle2 stream from stdin on the current repo"""
177 > """process a bundle2 stream from stdin on the current repo"""
178 > try:
178 > try:
179 > tr = None
179 > tr = None
180 > lock = repo.lock()
180 > lock = repo.lock()
181 > tr = repo.transaction(b'processbundle')
181 > tr = repo.transaction(b'processbundle')
182 > try:
182 > try:
183 > unbundler = bundle2.getunbundler(ui, pycompat.stdin)
183 > unbundler = bundle2.getunbundler(ui, pycompat.stdin)
184 > op = bundle2.processbundle(repo, unbundler, lambda: tr)
184 > op = bundle2.processbundle(repo, unbundler, lambda: tr)
185 > tr.close()
185 > tr.close()
186 > except error.BundleValueError as exc:
186 > except error.BundleValueError as exc:
187 > raise error.Abort(b'missing support for %s' % exc)
187 > raise error.Abort(b'missing support for %s' % exc)
188 > except error.PushRaced as exc:
188 > except error.PushRaced as exc:
189 > raise error.Abort(b'push race: %s' % exc)
189 > raise error.Abort(b'push race: %s' % exc)
190 > finally:
190 > finally:
191 > if tr is not None:
191 > if tr is not None:
192 > tr.release()
192 > tr.release()
193 > lock.release()
193 > lock.release()
194 > remains = pycompat.stdin.read()
194 > remains = pycompat.stdin.read()
195 > ui.write(b'%i unread bytes\n' % len(remains))
195 > ui.write(b'%i unread bytes\n' % len(remains))
196 > if op.records[b'song']:
196 > if op.records[b'song']:
197 > totalverses = sum(r[b'verses'] for r in op.records[b'song'])
197 > totalverses = sum(r[b'verses'] for r in op.records[b'song'])
198 > ui.write(b'%i total verses sung\n' % totalverses)
198 > ui.write(b'%i total verses sung\n' % totalverses)
199 > for rec in op.records[b'changegroup']:
199 > for rec in op.records[b'changegroup']:
200 > ui.write(b'addchangegroup return: %i\n' % rec[b'return'])
200 > ui.write(b'addchangegroup return: %i\n' % rec[b'return'])
201 > if op.reply is not None and replypath is not None:
201 > if op.reply is not None and replypath is not None:
202 > with open(replypath, 'wb') as file:
202 > with open(replypath, 'wb') as file:
203 > for chunk in op.reply.getchunks():
203 > for chunk in op.reply.getchunks():
204 > file.write(chunk)
204 > file.write(chunk)
205 >
205 >
206 > @command(b'statbundle2', [], b'')
206 > @command(b'statbundle2', [], b'')
207 > def cmdstatbundle2(ui, repo):
207 > def cmdstatbundle2(ui, repo):
208 > """print statistic on the bundle2 container read from stdin"""
208 > """print statistic on the bundle2 container read from stdin"""
209 > unbundler = bundle2.getunbundler(ui, pycompat.stdin)
209 > unbundler = bundle2.getunbundler(ui, pycompat.stdin)
210 > try:
210 > try:
211 > params = unbundler.params
211 > params = unbundler.params
212 > except error.BundleValueError as exc:
212 > except error.BundleValueError as exc:
213 > raise error.Abort(b'unknown parameters: %s' % exc)
213 > raise error.Abort(b'unknown parameters: %s' % exc)
214 > ui.write(b'options count: %i\n' % len(params))
214 > ui.write(b'options count: %i\n' % len(params))
215 > for key in sorted(params):
215 > for key in sorted(params):
216 > ui.write(b'- %s\n' % key)
216 > ui.write(b'- %s\n' % key)
217 > value = params[key]
217 > value = params[key]
218 > if value is not None:
218 > if value is not None:
219 > ui.write(b' %s\n' % value)
219 > ui.write(b' %s\n' % value)
220 > count = 0
220 > count = 0
221 > for p in unbundler.iterparts():
221 > for p in unbundler.iterparts():
222 > count += 1
222 > count += 1
223 > ui.write(b' :%s:\n' % p.type)
223 > ui.write(b' :%s:\n' % p.type)
224 > ui.write(b' mandatory: %i\n' % len(p.mandatoryparams))
224 > ui.write(b' mandatory: %i\n' % len(p.mandatoryparams))
225 > ui.write(b' advisory: %i\n' % len(p.advisoryparams))
225 > ui.write(b' advisory: %i\n' % len(p.advisoryparams))
226 > ui.write(b' payload: %i bytes\n' % len(p.read()))
226 > ui.write(b' payload: %i bytes\n' % len(p.read()))
227 > ui.write(b'parts count: %i\n' % count)
227 > ui.write(b'parts count: %i\n' % count)
228 > EOF
228 > EOF
229 $ cat >> $HGRCPATH << EOF
229 $ cat >> $HGRCPATH << EOF
230 > [extensions]
230 > [extensions]
231 > bundle2=$TESTTMP/bundle2.py
231 > bundle2=$TESTTMP/bundle2.py
232 > [experimental]
232 > [experimental]
233 > evolution.createmarkers=True
233 > evolution.createmarkers=True
234 > [ui]
234 > [ui]
235 > ssh=$PYTHON "$TESTDIR/dummyssh"
235 > ssh=$PYTHON "$TESTDIR/dummyssh"
236 > logtemplate={rev}:{node|short} {phase} {author} {bookmarks} {desc|firstline}
236 > logtemplate={rev}:{node|short} {phase} {author} {bookmarks} {desc|firstline}
237 > [web]
237 > [web]
238 > push_ssl = false
238 > push_ssl = false
239 > allow_push = *
239 > allow_push = *
240 > [phases]
240 > [phases]
241 > publish=False
241 > publish=False
242 > EOF
242 > EOF
243
243
244 The extension requires a repo (currently unused)
244 The extension requires a repo (currently unused)
245
245
246 $ hg init main
246 $ hg init main
247 $ cd main
247 $ cd main
248 $ touch a
248 $ touch a
249 $ hg add a
249 $ hg add a
250 $ hg commit -m 'a'
250 $ hg commit -m 'a'
251
251
252
252
253 Empty bundle
253 Empty bundle
254 =================
254 =================
255
255
256 - no option
256 - no option
257 - no parts
257 - no parts
258
258
259 Test bundling
259 Test bundling
260
260
261 $ hg bundle2 | f --hexdump
261 $ hg bundle2 | f --hexdump
262
262
263 0000: 48 47 32 30 00 00 00 00 00 00 00 00 |HG20........|
263 0000: 48 47 32 30 00 00 00 00 00 00 00 00 |HG20........|
264
264
265 Test timeouts during bundling
265 Test timeouts during bundling
266 $ hg bundle2 --timeout --debug --config devel.bundle2.debug=yes
266 $ hg bundle2 --timeout --debug --config devel.bundle2.debug=yes
267 bundle2-output-bundle: "HG20", 1 parts total
267 bundle2-output-bundle: "HG20", 1 parts total
268 bundle2-output: start emission of HG20 stream
268 bundle2-output: start emission of HG20 stream
269 0 chunk
269 0 chunk
270 bundle2-output: bundle parameter:
270 bundle2-output: bundle parameter:
271 1 chunk
271 1 chunk
272 bundle2-output: start of parts
272 bundle2-output: start of parts
273 bundle2-output: bundle part: "test:song"
273 bundle2-output: bundle part: "test:song"
274 bundle2-output-part: "test:song" (advisory) 178 bytes payload
274 bundle2-output-part: "test:song" (advisory) 178 bytes payload
275 bundle2-output: part 0: "test:song"
275 bundle2-output: part 0: "test:song"
276 bundle2-output: header chunk size: 16
276 bundle2-output: header chunk size: 16
277 2 chunk
277 2 chunk
278 3 chunk
278 3 chunk
279 bundle2-output: payload chunk size: 178
279 bundle2-output: payload chunk size: 178
280 4 chunk
280 4 chunk
281 5 chunk
281 5 chunk
282 bundle2-generatorexit
282 bundle2-generatorexit
283 fake timeout complete.
283 fake timeout complete.
284
284
285 Test unbundling
285 Test unbundling
286
286
287 $ hg bundle2 | hg statbundle2
287 $ hg bundle2 | hg statbundle2
288 options count: 0
288 options count: 0
289 parts count: 0
289 parts count: 0
290
290
291 Test old style bundle are detected and refused
291 Test old style bundle are detected and refused
292
292
293 $ hg bundle --all --type v1 ../bundle.hg
293 $ hg bundle --all --type v1 ../bundle.hg
294 1 changesets found
294 1 changesets found
295 $ hg statbundle2 < ../bundle.hg
295 $ hg statbundle2 < ../bundle.hg
296 abort: unknown bundle version 10
296 abort: unknown bundle version 10
297 [255]
297 [255]
298
298
299 Test parameters
299 Test parameters
300 =================
300 =================
301
301
302 - some options
302 - some options
303 - no parts
303 - no parts
304
304
305 advisory parameters, no value
305 advisory parameters, no value
306 -------------------------------
306 -------------------------------
307
307
308 Simplest possible parameters form
308 Simplest possible parameters form
309
309
310 Test generation simple option
310 Test generation simple option
311
311
312 $ hg bundle2 --param 'caution' | f --hexdump
312 $ hg bundle2 --param 'caution' | f --hexdump
313
313
314 0000: 48 47 32 30 00 00 00 07 63 61 75 74 69 6f 6e 00 |HG20....caution.|
314 0000: 48 47 32 30 00 00 00 07 63 61 75 74 69 6f 6e 00 |HG20....caution.|
315 0010: 00 00 00 |...|
315 0010: 00 00 00 |...|
316
316
317 Test unbundling
317 Test unbundling
318
318
319 $ hg bundle2 --param 'caution' | hg statbundle2
319 $ hg bundle2 --param 'caution' | hg statbundle2
320 options count: 1
320 options count: 1
321 - caution
321 - caution
322 parts count: 0
322 parts count: 0
323
323
324 Test generation multiple option
324 Test generation multiple option
325
325
326 $ hg bundle2 --param 'caution' --param 'meal' | f --hexdump
326 $ hg bundle2 --param 'caution' --param 'meal' | f --hexdump
327
327
328 0000: 48 47 32 30 00 00 00 0c 63 61 75 74 69 6f 6e 20 |HG20....caution |
328 0000: 48 47 32 30 00 00 00 0c 63 61 75 74 69 6f 6e 20 |HG20....caution |
329 0010: 6d 65 61 6c 00 00 00 00 |meal....|
329 0010: 6d 65 61 6c 00 00 00 00 |meal....|
330
330
331 Test unbundling
331 Test unbundling
332
332
333 $ hg bundle2 --param 'caution' --param 'meal' | hg statbundle2
333 $ hg bundle2 --param 'caution' --param 'meal' | hg statbundle2
334 options count: 2
334 options count: 2
335 - caution
335 - caution
336 - meal
336 - meal
337 parts count: 0
337 parts count: 0
338
338
339 advisory parameters, with value
339 advisory parameters, with value
340 -------------------------------
340 -------------------------------
341
341
342 Test generation
342 Test generation
343
343
344 $ hg bundle2 --param 'caution' --param 'meal=vegan' --param 'elephants' | f --hexdump
344 $ hg bundle2 --param 'caution' --param 'meal=vegan' --param 'elephants' | f --hexdump
345
345
346 0000: 48 47 32 30 00 00 00 1c 63 61 75 74 69 6f 6e 20 |HG20....caution |
346 0000: 48 47 32 30 00 00 00 1c 63 61 75 74 69 6f 6e 20 |HG20....caution |
347 0010: 6d 65 61 6c 3d 76 65 67 61 6e 20 65 6c 65 70 68 |meal=vegan eleph|
347 0010: 6d 65 61 6c 3d 76 65 67 61 6e 20 65 6c 65 70 68 |meal=vegan eleph|
348 0020: 61 6e 74 73 00 00 00 00 |ants....|
348 0020: 61 6e 74 73 00 00 00 00 |ants....|
349
349
350 Test unbundling
350 Test unbundling
351
351
352 $ hg bundle2 --param 'caution' --param 'meal=vegan' --param 'elephants' | hg statbundle2
352 $ hg bundle2 --param 'caution' --param 'meal=vegan' --param 'elephants' | hg statbundle2
353 options count: 3
353 options count: 3
354 - caution
354 - caution
355 - elephants
355 - elephants
356 - meal
356 - meal
357 vegan
357 vegan
358 parts count: 0
358 parts count: 0
359
359
360 parameter with special char in value
360 parameter with special char in value
361 ---------------------------------------------------
361 ---------------------------------------------------
362
362
363 Test generation
363 Test generation
364
364
365 $ hg bundle2 --param 'e|! 7/=babar%#==tutu' --param simple | f --hexdump
365 $ hg bundle2 --param 'e|! 7/=babar%#==tutu' --param simple | f --hexdump
366
366
367 0000: 48 47 32 30 00 00 00 29 65 25 37 43 25 32 31 25 |HG20...)e%7C%21%|
367 0000: 48 47 32 30 00 00 00 29 65 25 37 43 25 32 31 25 |HG20...)e%7C%21%|
368 0010: 32 30 37 2f 3d 62 61 62 61 72 25 32 35 25 32 33 |207/=babar%25%23|
368 0010: 32 30 37 2f 3d 62 61 62 61 72 25 32 35 25 32 33 |207/=babar%25%23|
369 0020: 25 33 44 25 33 44 74 75 74 75 20 73 69 6d 70 6c |%3D%3Dtutu simpl|
369 0020: 25 33 44 25 33 44 74 75 74 75 20 73 69 6d 70 6c |%3D%3Dtutu simpl|
370 0030: 65 00 00 00 00 |e....|
370 0030: 65 00 00 00 00 |e....|
371
371
372 Test unbundling
372 Test unbundling
373
373
374 $ hg bundle2 --param 'e|! 7/=babar%#==tutu' --param simple | hg statbundle2
374 $ hg bundle2 --param 'e|! 7/=babar%#==tutu' --param simple | hg statbundle2
375 options count: 2
375 options count: 2
376 - e|! 7/
376 - e|! 7/
377 babar%#==tutu
377 babar%#==tutu
378 - simple
378 - simple
379 parts count: 0
379 parts count: 0
380
380
381 Test unknown mandatory option
381 Test unknown mandatory option
382 ---------------------------------------------------
382 ---------------------------------------------------
383
383
384 $ hg bundle2 --param 'Gravity' | hg statbundle2
384 $ hg bundle2 --param 'Gravity' | hg statbundle2
385 abort: unknown parameters: Stream Parameter - Gravity
385 abort: unknown parameters: Stream Parameter - Gravity
386 [255]
386 [255]
387
387
388 Test debug output
388 Test debug output
389 ---------------------------------------------------
389 ---------------------------------------------------
390
390
391 bundling debug
391 bundling debug
392
392
393 $ hg bundle2 --debug --param 'e|! 7/=babar%#==tutu' --param simple ../out.hg2 --config progress.debug=true --config devel.bundle2.debug=true
393 $ hg bundle2 --debug --param 'e|! 7/=babar%#==tutu' --param simple ../out.hg2 --config progress.debug=true --config devel.bundle2.debug=true
394 bundle2-output-bundle: "HG20", (2 params) 0 parts total
394 bundle2-output-bundle: "HG20", (2 params) 0 parts total
395 bundle2-output: start emission of HG20 stream
395 bundle2-output: start emission of HG20 stream
396 bundle2-output: bundle parameter: e%7C%21%207/=babar%25%23%3D%3Dtutu simple
396 bundle2-output: bundle parameter: e%7C%21%207/=babar%25%23%3D%3Dtutu simple
397 bundle2-output: start of parts
397 bundle2-output: start of parts
398 bundle2-output: end of bundle
398 bundle2-output: end of bundle
399
399
400 file content is ok
400 file content is ok
401
401
402 $ f --hexdump ../out.hg2
402 $ f --hexdump ../out.hg2
403 ../out.hg2:
403 ../out.hg2:
404 0000: 48 47 32 30 00 00 00 29 65 25 37 43 25 32 31 25 |HG20...)e%7C%21%|
404 0000: 48 47 32 30 00 00 00 29 65 25 37 43 25 32 31 25 |HG20...)e%7C%21%|
405 0010: 32 30 37 2f 3d 62 61 62 61 72 25 32 35 25 32 33 |207/=babar%25%23|
405 0010: 32 30 37 2f 3d 62 61 62 61 72 25 32 35 25 32 33 |207/=babar%25%23|
406 0020: 25 33 44 25 33 44 74 75 74 75 20 73 69 6d 70 6c |%3D%3Dtutu simpl|
406 0020: 25 33 44 25 33 44 74 75 74 75 20 73 69 6d 70 6c |%3D%3Dtutu simpl|
407 0030: 65 00 00 00 00 |e....|
407 0030: 65 00 00 00 00 |e....|
408
408
409 unbundling debug
409 unbundling debug
410
410
411 $ hg statbundle2 --debug --config progress.debug=true --config devel.bundle2.debug=true < ../out.hg2
411 $ hg statbundle2 --debug --config progress.debug=true --config devel.bundle2.debug=true < ../out.hg2
412 bundle2-input: start processing of HG20 stream
412 bundle2-input: start processing of HG20 stream
413 bundle2-input: reading bundle2 stream parameters
413 bundle2-input: reading bundle2 stream parameters
414 bundle2-input: ignoring unknown parameter e|! 7/
414 bundle2-input: ignoring unknown parameter e|! 7/
415 bundle2-input: ignoring unknown parameter simple
415 bundle2-input: ignoring unknown parameter simple
416 options count: 2
416 options count: 2
417 - e|! 7/
417 - e|! 7/
418 babar%#==tutu
418 babar%#==tutu
419 - simple
419 - simple
420 bundle2-input: start extraction of bundle2 parts
420 bundle2-input: start extraction of bundle2 parts
421 bundle2-input: part header size: 0
421 bundle2-input: part header size: 0
422 bundle2-input: end of bundle2 stream
422 bundle2-input: end of bundle2 stream
423 parts count: 0
423 parts count: 0
424
424
425
425
426 Test buggy input
426 Test buggy input
427 ---------------------------------------------------
427 ---------------------------------------------------
428
428
429 empty parameter name
429 empty parameter name
430
430
431 $ hg bundle2 --param '' --quiet
431 $ hg bundle2 --param '' --quiet
432 abort: empty parameter name
432 abort: empty parameter name
433 [255]
433 [255]
434
434
435 bad parameter name
435 bad parameter name
436
436
437 $ hg bundle2 --param 42babar
437 $ hg bundle2 --param 42babar
438 abort: non letter first character: 42babar
438 abort: non letter first character: 42babar
439 [255]
439 [255]
440
440
441
441
442 Test part
442 Test part
443 =================
443 =================
444
444
445 $ hg bundle2 --parts ../parts.hg2 --debug --config progress.debug=true --config devel.bundle2.debug=true
445 $ hg bundle2 --parts ../parts.hg2 --debug --config progress.debug=true --config devel.bundle2.debug=true
446 bundle2-output-bundle: "HG20", 7 parts total
446 bundle2-output-bundle: "HG20", 7 parts total
447 bundle2-output: start emission of HG20 stream
447 bundle2-output: start emission of HG20 stream
448 bundle2-output: bundle parameter:
448 bundle2-output: bundle parameter:
449 bundle2-output: start of parts
449 bundle2-output: start of parts
450 bundle2-output: bundle part: "test:empty"
450 bundle2-output: bundle part: "test:empty"
451 bundle2-output-part: "test:empty" (advisory) empty payload
451 bundle2-output-part: "test:empty" (advisory) empty payload
452 bundle2-output: part 0: "test:empty"
452 bundle2-output: part 0: "test:empty"
453 bundle2-output: header chunk size: 17
453 bundle2-output: header chunk size: 17
454 bundle2-output: closing payload chunk
454 bundle2-output: closing payload chunk
455 bundle2-output: bundle part: "test:empty"
455 bundle2-output: bundle part: "test:empty"
456 bundle2-output-part: "test:empty" (advisory) empty payload
456 bundle2-output-part: "test:empty" (advisory) empty payload
457 bundle2-output: part 1: "test:empty"
457 bundle2-output: part 1: "test:empty"
458 bundle2-output: header chunk size: 17
458 bundle2-output: header chunk size: 17
459 bundle2-output: closing payload chunk
459 bundle2-output: closing payload chunk
460 bundle2-output: bundle part: "test:song"
460 bundle2-output: bundle part: "test:song"
461 bundle2-output-part: "test:song" (advisory) 178 bytes payload
461 bundle2-output-part: "test:song" (advisory) 178 bytes payload
462 bundle2-output: part 2: "test:song"
462 bundle2-output: part 2: "test:song"
463 bundle2-output: header chunk size: 16
463 bundle2-output: header chunk size: 16
464 bundle2-output: payload chunk size: 178
464 bundle2-output: payload chunk size: 178
465 bundle2-output: closing payload chunk
465 bundle2-output: closing payload chunk
466 bundle2-output: bundle part: "test:debugreply"
466 bundle2-output: bundle part: "test:debugreply"
467 bundle2-output-part: "test:debugreply" (advisory) empty payload
467 bundle2-output-part: "test:debugreply" (advisory) empty payload
468 bundle2-output: part 3: "test:debugreply"
468 bundle2-output: part 3: "test:debugreply"
469 bundle2-output: header chunk size: 22
469 bundle2-output: header chunk size: 22
470 bundle2-output: closing payload chunk
470 bundle2-output: closing payload chunk
471 bundle2-output: bundle part: "test:math"
471 bundle2-output: bundle part: "test:math"
472 bundle2-output-part: "test:math" (advisory) (params: 2 mandatory 2 advisory) 2 bytes payload
472 bundle2-output-part: "test:math" (advisory) (params: 2 mandatory 2 advisory) 2 bytes payload
473 bundle2-output: part 4: "test:math"
473 bundle2-output: part 4: "test:math"
474 bundle2-output: header chunk size: 43
474 bundle2-output: header chunk size: 43
475 bundle2-output: payload chunk size: 2
475 bundle2-output: payload chunk size: 2
476 bundle2-output: closing payload chunk
476 bundle2-output: closing payload chunk
477 bundle2-output: bundle part: "test:song"
477 bundle2-output: bundle part: "test:song"
478 bundle2-output-part: "test:song" (advisory) (params: 1 mandatory) empty payload
478 bundle2-output-part: "test:song" (advisory) (params: 1 mandatory) empty payload
479 bundle2-output: part 5: "test:song"
479 bundle2-output: part 5: "test:song"
480 bundle2-output: header chunk size: 29
480 bundle2-output: header chunk size: 29
481 bundle2-output: closing payload chunk
481 bundle2-output: closing payload chunk
482 bundle2-output: bundle part: "test:ping"
482 bundle2-output: bundle part: "test:ping"
483 bundle2-output-part: "test:ping" (advisory) empty payload
483 bundle2-output-part: "test:ping" (advisory) empty payload
484 bundle2-output: part 6: "test:ping"
484 bundle2-output: part 6: "test:ping"
485 bundle2-output: header chunk size: 16
485 bundle2-output: header chunk size: 16
486 bundle2-output: closing payload chunk
486 bundle2-output: closing payload chunk
487 bundle2-output: end of bundle
487 bundle2-output: end of bundle
488
488
489 $ f --hexdump ../parts.hg2
489 $ f --hexdump ../parts.hg2
490 ../parts.hg2:
490 ../parts.hg2:
491 0000: 48 47 32 30 00 00 00 00 00 00 00 11 0a 74 65 73 |HG20.........tes|
491 0000: 48 47 32 30 00 00 00 00 00 00 00 11 0a 74 65 73 |HG20.........tes|
492 0010: 74 3a 65 6d 70 74 79 00 00 00 00 00 00 00 00 00 |t:empty.........|
492 0010: 74 3a 65 6d 70 74 79 00 00 00 00 00 00 00 00 00 |t:empty.........|
493 0020: 00 00 00 00 11 0a 74 65 73 74 3a 65 6d 70 74 79 |......test:empty|
493 0020: 00 00 00 00 11 0a 74 65 73 74 3a 65 6d 70 74 79 |......test:empty|
494 0030: 00 00 00 01 00 00 00 00 00 00 00 00 00 10 09 74 |...............t|
494 0030: 00 00 00 01 00 00 00 00 00 00 00 00 00 10 09 74 |...............t|
495 0040: 65 73 74 3a 73 6f 6e 67 00 00 00 02 00 00 00 00 |est:song........|
495 0040: 65 73 74 3a 73 6f 6e 67 00 00 00 02 00 00 00 00 |est:song........|
496 0050: 00 b2 50 61 74 61 6c 69 20 44 69 72 61 70 61 74 |..Patali Dirapat|
496 0050: 00 b2 50 61 74 61 6c 69 20 44 69 72 61 70 61 74 |..Patali Dirapat|
497 0060: 61 2c 20 43 72 6f 6d 64 61 20 43 72 6f 6d 64 61 |a, Cromda Cromda|
497 0060: 61 2c 20 43 72 6f 6d 64 61 20 43 72 6f 6d 64 61 |a, Cromda Cromda|
498 0070: 20 52 69 70 61 6c 6f 2c 20 50 61 74 61 20 50 61 | Ripalo, Pata Pa|
498 0070: 20 52 69 70 61 6c 6f 2c 20 50 61 74 61 20 50 61 | Ripalo, Pata Pa|
499 0080: 74 61 2c 20 4b 6f 20 4b 6f 20 4b 6f 0a 42 6f 6b |ta, Ko Ko Ko.Bok|
499 0080: 74 61 2c 20 4b 6f 20 4b 6f 20 4b 6f 0a 42 6f 6b |ta, Ko Ko Ko.Bok|
500 0090: 6f 72 6f 20 44 69 70 6f 75 6c 69 74 6f 2c 20 52 |oro Dipoulito, R|
500 0090: 6f 72 6f 20 44 69 70 6f 75 6c 69 74 6f 2c 20 52 |oro Dipoulito, R|
501 00a0: 6f 6e 64 69 20 52 6f 6e 64 69 20 50 65 70 69 6e |ondi Rondi Pepin|
501 00a0: 6f 6e 64 69 20 52 6f 6e 64 69 20 50 65 70 69 6e |ondi Rondi Pepin|
502 00b0: 6f 2c 20 50 61 74 61 20 50 61 74 61 2c 20 4b 6f |o, Pata Pata, Ko|
502 00b0: 6f 2c 20 50 61 74 61 20 50 61 74 61 2c 20 4b 6f |o, Pata Pata, Ko|
503 00c0: 20 4b 6f 20 4b 6f 0a 45 6d 61 6e 61 20 4b 61 72 | Ko Ko.Emana Kar|
503 00c0: 20 4b 6f 20 4b 6f 0a 45 6d 61 6e 61 20 4b 61 72 | Ko Ko.Emana Kar|
504 00d0: 61 73 73 6f 6c 69 2c 20 4c 6f 75 63 72 61 20 4c |assoli, Loucra L|
504 00d0: 61 73 73 6f 6c 69 2c 20 4c 6f 75 63 72 61 20 4c |assoli, Loucra L|
505 00e0: 6f 75 63 72 61 20 50 6f 6e 70 6f 6e 74 6f 2c 20 |oucra Ponponto, |
505 00e0: 6f 75 63 72 61 20 50 6f 6e 70 6f 6e 74 6f 2c 20 |oucra Ponponto, |
506 00f0: 50 61 74 61 20 50 61 74 61 2c 20 4b 6f 20 4b 6f |Pata Pata, Ko Ko|
506 00f0: 50 61 74 61 20 50 61 74 61 2c 20 4b 6f 20 4b 6f |Pata Pata, Ko Ko|
507 0100: 20 4b 6f 2e 00 00 00 00 00 00 00 16 0f 74 65 73 | Ko..........tes|
507 0100: 20 4b 6f 2e 00 00 00 00 00 00 00 16 0f 74 65 73 | Ko..........tes|
508 0110: 74 3a 64 65 62 75 67 72 65 70 6c 79 00 00 00 03 |t:debugreply....|
508 0110: 74 3a 64 65 62 75 67 72 65 70 6c 79 00 00 00 03 |t:debugreply....|
509 0120: 00 00 00 00 00 00 00 00 00 2b 09 74 65 73 74 3a |.........+.test:|
509 0120: 00 00 00 00 00 00 00 00 00 2b 09 74 65 73 74 3a |.........+.test:|
510 0130: 6d 61 74 68 00 00 00 04 02 01 02 04 01 04 07 03 |math............|
510 0130: 6d 61 74 68 00 00 00 04 02 01 02 04 01 04 07 03 |math............|
511 0140: 70 69 33 2e 31 34 65 32 2e 37 32 63 6f 6f 6b 69 |pi3.14e2.72cooki|
511 0140: 70 69 33 2e 31 34 65 32 2e 37 32 63 6f 6f 6b 69 |pi3.14e2.72cooki|
512 0150: 6e 67 72 61 77 00 00 00 02 34 32 00 00 00 00 00 |ngraw....42.....|
512 0150: 6e 67 72 61 77 00 00 00 02 34 32 00 00 00 00 00 |ngraw....42.....|
513 0160: 00 00 1d 09 74 65 73 74 3a 73 6f 6e 67 00 00 00 |....test:song...|
513 0160: 00 00 1d 09 74 65 73 74 3a 73 6f 6e 67 00 00 00 |....test:song...|
514 0170: 05 01 00 0b 00 72 61 6e 64 6f 6d 70 61 72 61 6d |.....randomparam|
514 0170: 05 01 00 0b 00 72 61 6e 64 6f 6d 70 61 72 61 6d |.....randomparam|
515 0180: 00 00 00 00 00 00 00 10 09 74 65 73 74 3a 70 69 |.........test:pi|
515 0180: 00 00 00 00 00 00 00 10 09 74 65 73 74 3a 70 69 |.........test:pi|
516 0190: 6e 67 00 00 00 06 00 00 00 00 00 00 00 00 00 00 |ng..............|
516 0190: 6e 67 00 00 00 06 00 00 00 00 00 00 00 00 00 00 |ng..............|
517
517
518
518
519 $ hg statbundle2 < ../parts.hg2
519 $ hg statbundle2 < ../parts.hg2
520 options count: 0
520 options count: 0
521 :test:empty:
521 :test:empty:
522 mandatory: 0
522 mandatory: 0
523 advisory: 0
523 advisory: 0
524 payload: 0 bytes
524 payload: 0 bytes
525 :test:empty:
525 :test:empty:
526 mandatory: 0
526 mandatory: 0
527 advisory: 0
527 advisory: 0
528 payload: 0 bytes
528 payload: 0 bytes
529 :test:song:
529 :test:song:
530 mandatory: 0
530 mandatory: 0
531 advisory: 0
531 advisory: 0
532 payload: 178 bytes
532 payload: 178 bytes
533 :test:debugreply:
533 :test:debugreply:
534 mandatory: 0
534 mandatory: 0
535 advisory: 0
535 advisory: 0
536 payload: 0 bytes
536 payload: 0 bytes
537 :test:math:
537 :test:math:
538 mandatory: 2
538 mandatory: 2
539 advisory: 1
539 advisory: 1
540 payload: 2 bytes
540 payload: 2 bytes
541 :test:song:
541 :test:song:
542 mandatory: 1
542 mandatory: 1
543 advisory: 0
543 advisory: 0
544 payload: 0 bytes
544 payload: 0 bytes
545 :test:ping:
545 :test:ping:
546 mandatory: 0
546 mandatory: 0
547 advisory: 0
547 advisory: 0
548 payload: 0 bytes
548 payload: 0 bytes
549 parts count: 7
549 parts count: 7
550
550
551 $ hg statbundle2 --debug --config progress.debug=true --config devel.bundle2.debug=true < ../parts.hg2
551 $ hg statbundle2 --debug --config progress.debug=true --config devel.bundle2.debug=true < ../parts.hg2
552 bundle2-input: start processing of HG20 stream
552 bundle2-input: start processing of HG20 stream
553 bundle2-input: reading bundle2 stream parameters
553 bundle2-input: reading bundle2 stream parameters
554 options count: 0
554 options count: 0
555 bundle2-input: start extraction of bundle2 parts
555 bundle2-input: start extraction of bundle2 parts
556 bundle2-input: part header size: 17
556 bundle2-input: part header size: 17
557 bundle2-input: part type: "test:empty"
557 bundle2-input: part type: "test:empty"
558 bundle2-input: part id: "0"
558 bundle2-input: part id: "0"
559 bundle2-input: part parameters: 0
559 bundle2-input: part parameters: 0
560 :test:empty:
560 :test:empty:
561 mandatory: 0
561 mandatory: 0
562 advisory: 0
562 advisory: 0
563 bundle2-input: payload chunk size: 0
563 bundle2-input: payload chunk size: 0
564 payload: 0 bytes
564 payload: 0 bytes
565 bundle2-input: part header size: 17
565 bundle2-input: part header size: 17
566 bundle2-input: part type: "test:empty"
566 bundle2-input: part type: "test:empty"
567 bundle2-input: part id: "1"
567 bundle2-input: part id: "1"
568 bundle2-input: part parameters: 0
568 bundle2-input: part parameters: 0
569 :test:empty:
569 :test:empty:
570 mandatory: 0
570 mandatory: 0
571 advisory: 0
571 advisory: 0
572 bundle2-input: payload chunk size: 0
572 bundle2-input: payload chunk size: 0
573 payload: 0 bytes
573 payload: 0 bytes
574 bundle2-input: part header size: 16
574 bundle2-input: part header size: 16
575 bundle2-input: part type: "test:song"
575 bundle2-input: part type: "test:song"
576 bundle2-input: part id: "2"
576 bundle2-input: part id: "2"
577 bundle2-input: part parameters: 0
577 bundle2-input: part parameters: 0
578 :test:song:
578 :test:song:
579 mandatory: 0
579 mandatory: 0
580 advisory: 0
580 advisory: 0
581 bundle2-input: payload chunk size: 178
581 bundle2-input: payload chunk size: 178
582 bundle2-input: payload chunk size: 0
582 bundle2-input: payload chunk size: 0
583 bundle2-input-part: total payload size 178
583 bundle2-input-part: total payload size 178
584 payload: 178 bytes
584 payload: 178 bytes
585 bundle2-input: part header size: 22
585 bundle2-input: part header size: 22
586 bundle2-input: part type: "test:debugreply"
586 bundle2-input: part type: "test:debugreply"
587 bundle2-input: part id: "3"
587 bundle2-input: part id: "3"
588 bundle2-input: part parameters: 0
588 bundle2-input: part parameters: 0
589 :test:debugreply:
589 :test:debugreply:
590 mandatory: 0
590 mandatory: 0
591 advisory: 0
591 advisory: 0
592 bundle2-input: payload chunk size: 0
592 bundle2-input: payload chunk size: 0
593 payload: 0 bytes
593 payload: 0 bytes
594 bundle2-input: part header size: 43
594 bundle2-input: part header size: 43
595 bundle2-input: part type: "test:math"
595 bundle2-input: part type: "test:math"
596 bundle2-input: part id: "4"
596 bundle2-input: part id: "4"
597 bundle2-input: part parameters: 3
597 bundle2-input: part parameters: 3
598 :test:math:
598 :test:math:
599 mandatory: 2
599 mandatory: 2
600 advisory: 1
600 advisory: 1
601 bundle2-input: payload chunk size: 2
601 bundle2-input: payload chunk size: 2
602 bundle2-input: payload chunk size: 0
602 bundle2-input: payload chunk size: 0
603 bundle2-input-part: total payload size 2
603 bundle2-input-part: total payload size 2
604 payload: 2 bytes
604 payload: 2 bytes
605 bundle2-input: part header size: 29
605 bundle2-input: part header size: 29
606 bundle2-input: part type: "test:song"
606 bundle2-input: part type: "test:song"
607 bundle2-input: part id: "5"
607 bundle2-input: part id: "5"
608 bundle2-input: part parameters: 1
608 bundle2-input: part parameters: 1
609 :test:song:
609 :test:song:
610 mandatory: 1
610 mandatory: 1
611 advisory: 0
611 advisory: 0
612 bundle2-input: payload chunk size: 0
612 bundle2-input: payload chunk size: 0
613 payload: 0 bytes
613 payload: 0 bytes
614 bundle2-input: part header size: 16
614 bundle2-input: part header size: 16
615 bundle2-input: part type: "test:ping"
615 bundle2-input: part type: "test:ping"
616 bundle2-input: part id: "6"
616 bundle2-input: part id: "6"
617 bundle2-input: part parameters: 0
617 bundle2-input: part parameters: 0
618 :test:ping:
618 :test:ping:
619 mandatory: 0
619 mandatory: 0
620 advisory: 0
620 advisory: 0
621 bundle2-input: payload chunk size: 0
621 bundle2-input: payload chunk size: 0
622 payload: 0 bytes
622 payload: 0 bytes
623 bundle2-input: part header size: 0
623 bundle2-input: part header size: 0
624 bundle2-input: end of bundle2 stream
624 bundle2-input: end of bundle2 stream
625 parts count: 7
625 parts count: 7
626
626
627 Test actual unbundling of test part
627 Test actual unbundling of test part
628 =======================================
628 =======================================
629
629
630 Process the bundle
630 Process the bundle
631
631
632 $ hg unbundle2 --debug --config progress.debug=true --config devel.bundle2.debug=true < ../parts.hg2
632 $ hg unbundle2 --debug --config progress.debug=true --config devel.bundle2.debug=true < ../parts.hg2
633 bundle2-input: start processing of HG20 stream
633 bundle2-input: start processing of HG20 stream
634 bundle2-input: reading bundle2 stream parameters
634 bundle2-input: reading bundle2 stream parameters
635 bundle2-input-bundle: with-transaction
635 bundle2-input-bundle: with-transaction
636 bundle2-input: start extraction of bundle2 parts
636 bundle2-input: start extraction of bundle2 parts
637 bundle2-input: part header size: 17
637 bundle2-input: part header size: 17
638 bundle2-input: part type: "test:empty"
638 bundle2-input: part type: "test:empty"
639 bundle2-input: part id: "0"
639 bundle2-input: part id: "0"
640 bundle2-input: part parameters: 0
640 bundle2-input: part parameters: 0
641 bundle2-input: ignoring unsupported advisory part test:empty
641 bundle2-input: ignoring unsupported advisory part test:empty
642 bundle2-input-part: "test:empty" (advisory) unsupported-type
642 bundle2-input-part: "test:empty" (advisory) unsupported-type
643 bundle2-input: payload chunk size: 0
643 bundle2-input: payload chunk size: 0
644 bundle2-input: part header size: 17
644 bundle2-input: part header size: 17
645 bundle2-input: part type: "test:empty"
645 bundle2-input: part type: "test:empty"
646 bundle2-input: part id: "1"
646 bundle2-input: part id: "1"
647 bundle2-input: part parameters: 0
647 bundle2-input: part parameters: 0
648 bundle2-input: ignoring unsupported advisory part test:empty
648 bundle2-input: ignoring unsupported advisory part test:empty
649 bundle2-input-part: "test:empty" (advisory) unsupported-type
649 bundle2-input-part: "test:empty" (advisory) unsupported-type
650 bundle2-input: payload chunk size: 0
650 bundle2-input: payload chunk size: 0
651 bundle2-input: part header size: 16
651 bundle2-input: part header size: 16
652 bundle2-input: part type: "test:song"
652 bundle2-input: part type: "test:song"
653 bundle2-input: part id: "2"
653 bundle2-input: part id: "2"
654 bundle2-input: part parameters: 0
654 bundle2-input: part parameters: 0
655 bundle2-input: found a handler for part test:song
655 bundle2-input: found a handler for part test:song
656 bundle2-input-part: "test:song" (advisory) supported
656 bundle2-input-part: "test:song" (advisory) supported
657 The choir starts singing:
657 The choir starts singing:
658 bundle2-input: payload chunk size: 178
658 bundle2-input: payload chunk size: 178
659 bundle2-input: payload chunk size: 0
659 bundle2-input: payload chunk size: 0
660 bundle2-input-part: total payload size 178
660 bundle2-input-part: total payload size 178
661 Patali Dirapata, Cromda Cromda Ripalo, Pata Pata, Ko Ko Ko
661 Patali Dirapata, Cromda Cromda Ripalo, Pata Pata, Ko Ko Ko
662 Bokoro Dipoulito, Rondi Rondi Pepino, Pata Pata, Ko Ko Ko
662 Bokoro Dipoulito, Rondi Rondi Pepino, Pata Pata, Ko Ko Ko
663 Emana Karassoli, Loucra Loucra Ponponto, Pata Pata, Ko Ko Ko.
663 Emana Karassoli, Loucra Loucra Ponponto, Pata Pata, Ko Ko Ko.
664 bundle2-input: part header size: 22
664 bundle2-input: part header size: 22
665 bundle2-input: part type: "test:debugreply"
665 bundle2-input: part type: "test:debugreply"
666 bundle2-input: part id: "3"
666 bundle2-input: part id: "3"
667 bundle2-input: part parameters: 0
667 bundle2-input: part parameters: 0
668 bundle2-input: found a handler for part test:debugreply
668 bundle2-input: found a handler for part test:debugreply
669 bundle2-input-part: "test:debugreply" (advisory) supported
669 bundle2-input-part: "test:debugreply" (advisory) supported
670 debugreply: no reply
670 debugreply: no reply
671 bundle2-input: payload chunk size: 0
671 bundle2-input: payload chunk size: 0
672 bundle2-input: part header size: 43
672 bundle2-input: part header size: 43
673 bundle2-input: part type: "test:math"
673 bundle2-input: part type: "test:math"
674 bundle2-input: part id: "4"
674 bundle2-input: part id: "4"
675 bundle2-input: part parameters: 3
675 bundle2-input: part parameters: 3
676 bundle2-input: ignoring unsupported advisory part test:math
676 bundle2-input: ignoring unsupported advisory part test:math
677 bundle2-input-part: "test:math" (advisory) (params: 2 mandatory 2 advisory) unsupported-type
677 bundle2-input-part: "test:math" (advisory) (params: 2 mandatory 2 advisory) unsupported-type
678 bundle2-input: payload chunk size: 2
678 bundle2-input: payload chunk size: 2
679 bundle2-input: payload chunk size: 0
679 bundle2-input: payload chunk size: 0
680 bundle2-input-part: total payload size 2
680 bundle2-input-part: total payload size 2
681 bundle2-input: part header size: 29
681 bundle2-input: part header size: 29
682 bundle2-input: part type: "test:song"
682 bundle2-input: part type: "test:song"
683 bundle2-input: part id: "5"
683 bundle2-input: part id: "5"
684 bundle2-input: part parameters: 1
684 bundle2-input: part parameters: 1
685 bundle2-input: found a handler for part test:song
685 bundle2-input: found a handler for part test:song
686 bundle2-input: ignoring unsupported advisory part test:song - randomparam
686 bundle2-input: ignoring unsupported advisory part test:song - randomparam
687 bundle2-input-part: "test:song" (advisory) (params: 1 mandatory) unsupported-params (randomparam)
687 bundle2-input-part: "test:song" (advisory) (params: 1 mandatory) unsupported-params (randomparam)
688 bundle2-input: payload chunk size: 0
688 bundle2-input: payload chunk size: 0
689 bundle2-input: part header size: 16
689 bundle2-input: part header size: 16
690 bundle2-input: part type: "test:ping"
690 bundle2-input: part type: "test:ping"
691 bundle2-input: part id: "6"
691 bundle2-input: part id: "6"
692 bundle2-input: part parameters: 0
692 bundle2-input: part parameters: 0
693 bundle2-input: found a handler for part test:ping
693 bundle2-input: found a handler for part test:ping
694 bundle2-input-part: "test:ping" (advisory) supported
694 bundle2-input-part: "test:ping" (advisory) supported
695 received ping request (id 6)
695 received ping request (id 6)
696 bundle2-input: payload chunk size: 0
696 bundle2-input: payload chunk size: 0
697 bundle2-input: part header size: 0
697 bundle2-input: part header size: 0
698 bundle2-input: end of bundle2 stream
698 bundle2-input: end of bundle2 stream
699 bundle2-input-bundle: 6 parts total
699 bundle2-input-bundle: 6 parts total
700 0 unread bytes
700 0 unread bytes
701 3 total verses sung
701 3 total verses sung
702
702
703 Unbundle with an unknown mandatory part
703 Unbundle with an unknown mandatory part
704 (should abort)
704 (should abort)
705
705
706 $ hg bundle2 --parts --unknown ../unknown.hg2
706 $ hg bundle2 --parts --unknown ../unknown.hg2
707
707
708 $ hg unbundle2 < ../unknown.hg2
708 $ hg unbundle2 < ../unknown.hg2
709 The choir starts singing:
709 The choir starts singing:
710 Patali Dirapata, Cromda Cromda Ripalo, Pata Pata, Ko Ko Ko
710 Patali Dirapata, Cromda Cromda Ripalo, Pata Pata, Ko Ko Ko
711 Bokoro Dipoulito, Rondi Rondi Pepino, Pata Pata, Ko Ko Ko
711 Bokoro Dipoulito, Rondi Rondi Pepino, Pata Pata, Ko Ko Ko
712 Emana Karassoli, Loucra Loucra Ponponto, Pata Pata, Ko Ko Ko.
712 Emana Karassoli, Loucra Loucra Ponponto, Pata Pata, Ko Ko Ko.
713 debugreply: no reply
713 debugreply: no reply
714 0 unread bytes
714 0 unread bytes
715 abort: missing support for test:unknown
715 abort: missing support for test:unknown
716 [255]
716 [255]
717
717
718 Unbundle with an unknown mandatory part parameters
718 Unbundle with an unknown mandatory part parameters
719 (should abort)
719 (should abort)
720
720
721 $ hg bundle2 --unknownparams ../unknown.hg2
721 $ hg bundle2 --unknownparams ../unknown.hg2
722
722
723 $ hg unbundle2 < ../unknown.hg2
723 $ hg unbundle2 < ../unknown.hg2
724 0 unread bytes
724 0 unread bytes
725 abort: missing support for test:song - randomparams
725 abort: missing support for test:song - randomparams
726 [255]
726 [255]
727
727
728 unbundle with a reply
728 unbundle with a reply
729
729
730 $ hg bundle2 --parts --reply ../parts-reply.hg2
730 $ hg bundle2 --parts --reply ../parts-reply.hg2
731 $ hg unbundle2 ../reply.hg2 < ../parts-reply.hg2
731 $ hg unbundle2 ../reply.hg2 < ../parts-reply.hg2
732 0 unread bytes
732 0 unread bytes
733 3 total verses sung
733 3 total verses sung
734
734
735 The reply is a bundle
735 The reply is a bundle
736
736
737 $ f --hexdump ../reply.hg2
737 $ f --hexdump ../reply.hg2
738 ../reply.hg2:
738 ../reply.hg2:
739 0000: 48 47 32 30 00 00 00 00 00 00 00 1b 06 6f 75 74 |HG20.........out|
739 0000: 48 47 32 30 00 00 00 00 00 00 00 1b 06 6f 75 74 |HG20.........out|
740 0010: 70 75 74 00 00 00 00 00 01 0b 01 69 6e 2d 72 65 |put........in-re|
740 0010: 70 75 74 00 00 00 00 00 01 0b 01 69 6e 2d 72 65 |put........in-re|
741 0020: 70 6c 79 2d 74 6f 33 00 00 00 d9 54 68 65 20 63 |ply-to3....The c|
741 0020: 70 6c 79 2d 74 6f 33 00 00 00 d9 54 68 65 20 63 |ply-to3....The c|
742 0030: 68 6f 69 72 20 73 74 61 72 74 73 20 73 69 6e 67 |hoir starts sing|
742 0030: 68 6f 69 72 20 73 74 61 72 74 73 20 73 69 6e 67 |hoir starts sing|
743 0040: 69 6e 67 3a 0a 20 20 20 20 50 61 74 61 6c 69 20 |ing:. Patali |
743 0040: 69 6e 67 3a 0a 20 20 20 20 50 61 74 61 6c 69 20 |ing:. Patali |
744 0050: 44 69 72 61 70 61 74 61 2c 20 43 72 6f 6d 64 61 |Dirapata, Cromda|
744 0050: 44 69 72 61 70 61 74 61 2c 20 43 72 6f 6d 64 61 |Dirapata, Cromda|
745 0060: 20 43 72 6f 6d 64 61 20 52 69 70 61 6c 6f 2c 20 | Cromda Ripalo, |
745 0060: 20 43 72 6f 6d 64 61 20 52 69 70 61 6c 6f 2c 20 | Cromda Ripalo, |
746 0070: 50 61 74 61 20 50 61 74 61 2c 20 4b 6f 20 4b 6f |Pata Pata, Ko Ko|
746 0070: 50 61 74 61 20 50 61 74 61 2c 20 4b 6f 20 4b 6f |Pata Pata, Ko Ko|
747 0080: 20 4b 6f 0a 20 20 20 20 42 6f 6b 6f 72 6f 20 44 | Ko. Bokoro D|
747 0080: 20 4b 6f 0a 20 20 20 20 42 6f 6b 6f 72 6f 20 44 | Ko. Bokoro D|
748 0090: 69 70 6f 75 6c 69 74 6f 2c 20 52 6f 6e 64 69 20 |ipoulito, Rondi |
748 0090: 69 70 6f 75 6c 69 74 6f 2c 20 52 6f 6e 64 69 20 |ipoulito, Rondi |
749 00a0: 52 6f 6e 64 69 20 50 65 70 69 6e 6f 2c 20 50 61 |Rondi Pepino, Pa|
749 00a0: 52 6f 6e 64 69 20 50 65 70 69 6e 6f 2c 20 50 61 |Rondi Pepino, Pa|
750 00b0: 74 61 20 50 61 74 61 2c 20 4b 6f 20 4b 6f 20 4b |ta Pata, Ko Ko K|
750 00b0: 74 61 20 50 61 74 61 2c 20 4b 6f 20 4b 6f 20 4b |ta Pata, Ko Ko K|
751 00c0: 6f 0a 20 20 20 20 45 6d 61 6e 61 20 4b 61 72 61 |o. Emana Kara|
751 00c0: 6f 0a 20 20 20 20 45 6d 61 6e 61 20 4b 61 72 61 |o. Emana Kara|
752 00d0: 73 73 6f 6c 69 2c 20 4c 6f 75 63 72 61 20 4c 6f |ssoli, Loucra Lo|
752 00d0: 73 73 6f 6c 69 2c 20 4c 6f 75 63 72 61 20 4c 6f |ssoli, Loucra Lo|
753 00e0: 75 63 72 61 20 50 6f 6e 70 6f 6e 74 6f 2c 20 50 |ucra Ponponto, P|
753 00e0: 75 63 72 61 20 50 6f 6e 70 6f 6e 74 6f 2c 20 50 |ucra Ponponto, P|
754 00f0: 61 74 61 20 50 61 74 61 2c 20 4b 6f 20 4b 6f 20 |ata Pata, Ko Ko |
754 00f0: 61 74 61 20 50 61 74 61 2c 20 4b 6f 20 4b 6f 20 |ata Pata, Ko Ko |
755 0100: 4b 6f 2e 0a 00 00 00 00 00 00 00 1b 06 6f 75 74 |Ko...........out|
755 0100: 4b 6f 2e 0a 00 00 00 00 00 00 00 1b 06 6f 75 74 |Ko...........out|
756 0110: 70 75 74 00 00 00 01 00 01 0b 01 69 6e 2d 72 65 |put........in-re|
756 0110: 70 75 74 00 00 00 01 00 01 0b 01 69 6e 2d 72 65 |put........in-re|
757 0120: 70 6c 79 2d 74 6f 34 00 00 00 c9 64 65 62 75 67 |ply-to4....debug|
757 0120: 70 6c 79 2d 74 6f 34 00 00 00 c9 64 65 62 75 67 |ply-to4....debug|
758 0130: 72 65 70 6c 79 3a 20 63 61 70 61 62 69 6c 69 74 |reply: capabilit|
758 0130: 72 65 70 6c 79 3a 20 63 61 70 61 62 69 6c 69 74 |reply: capabilit|
759 0140: 69 65 73 3a 0a 64 65 62 75 67 72 65 70 6c 79 3a |ies:.debugreply:|
759 0140: 69 65 73 3a 0a 64 65 62 75 67 72 65 70 6c 79 3a |ies:.debugreply:|
760 0150: 20 20 20 20 20 27 63 69 74 79 3d 21 27 0a 64 65 | 'city=!'.de|
760 0150: 20 20 20 20 20 27 63 69 74 79 3d 21 27 0a 64 65 | 'city=!'.de|
761 0160: 62 75 67 72 65 70 6c 79 3a 20 20 20 20 20 20 20 |bugreply: |
761 0160: 62 75 67 72 65 70 6c 79 3a 20 20 20 20 20 20 20 |bugreply: |
762 0170: 20 20 27 63 65 6c 65 73 74 65 2c 76 69 6c 6c 65 | 'celeste,ville|
762 0170: 20 20 27 63 65 6c 65 73 74 65 2c 76 69 6c 6c 65 | 'celeste,ville|
763 0180: 27 0a 64 65 62 75 67 72 65 70 6c 79 3a 20 20 20 |'.debugreply: |
763 0180: 27 0a 64 65 62 75 67 72 65 70 6c 79 3a 20 20 20 |'.debugreply: |
764 0190: 20 20 27 65 6c 65 70 68 61 6e 74 73 27 0a 64 65 | 'elephants'.de|
764 0190: 20 20 27 65 6c 65 70 68 61 6e 74 73 27 0a 64 65 | 'elephants'.de|
765 01a0: 62 75 67 72 65 70 6c 79 3a 20 20 20 20 20 20 20 |bugreply: |
765 01a0: 62 75 67 72 65 70 6c 79 3a 20 20 20 20 20 20 20 |bugreply: |
766 01b0: 20 20 27 62 61 62 61 72 27 0a 64 65 62 75 67 72 | 'babar'.debugr|
766 01b0: 20 20 27 62 61 62 61 72 27 0a 64 65 62 75 67 72 | 'babar'.debugr|
767 01c0: 65 70 6c 79 3a 20 20 20 20 20 20 20 20 20 27 63 |eply: 'c|
767 01c0: 65 70 6c 79 3a 20 20 20 20 20 20 20 20 20 27 63 |eply: 'c|
768 01d0: 65 6c 65 73 74 65 27 0a 64 65 62 75 67 72 65 70 |eleste'.debugrep|
768 01d0: 65 6c 65 73 74 65 27 0a 64 65 62 75 67 72 65 70 |eleste'.debugrep|
769 01e0: 6c 79 3a 20 20 20 20 20 27 70 69 6e 67 2d 70 6f |ly: 'ping-po|
769 01e0: 6c 79 3a 20 20 20 20 20 27 70 69 6e 67 2d 70 6f |ly: 'ping-po|
770 01f0: 6e 67 27 0a 00 00 00 00 00 00 00 1e 09 74 65 73 |ng'..........tes|
770 01f0: 6e 67 27 0a 00 00 00 00 00 00 00 1e 09 74 65 73 |ng'..........tes|
771 0200: 74 3a 70 6f 6e 67 00 00 00 02 01 00 0b 01 69 6e |t:pong........in|
771 0200: 74 3a 70 6f 6e 67 00 00 00 02 01 00 0b 01 69 6e |t:pong........in|
772 0210: 2d 72 65 70 6c 79 2d 74 6f 37 00 00 00 00 00 00 |-reply-to7......|
772 0210: 2d 72 65 70 6c 79 2d 74 6f 37 00 00 00 00 00 00 |-reply-to7......|
773 0220: 00 1b 06 6f 75 74 70 75 74 00 00 00 03 00 01 0b |...output.......|
773 0220: 00 1b 06 6f 75 74 70 75 74 00 00 00 03 00 01 0b |...output.......|
774 0230: 01 69 6e 2d 72 65 70 6c 79 2d 74 6f 37 00 00 00 |.in-reply-to7...|
774 0230: 01 69 6e 2d 72 65 70 6c 79 2d 74 6f 37 00 00 00 |.in-reply-to7...|
775 0240: 3d 72 65 63 65 69 76 65 64 20 70 69 6e 67 20 72 |=received ping r|
775 0240: 3d 72 65 63 65 69 76 65 64 20 70 69 6e 67 20 72 |=received ping r|
776 0250: 65 71 75 65 73 74 20 28 69 64 20 37 29 0a 72 65 |equest (id 7).re|
776 0250: 65 71 75 65 73 74 20 28 69 64 20 37 29 0a 72 65 |equest (id 7).re|
777 0260: 70 6c 79 69 6e 67 20 74 6f 20 70 69 6e 67 20 72 |plying to ping r|
777 0260: 70 6c 79 69 6e 67 20 74 6f 20 70 69 6e 67 20 72 |plying to ping r|
778 0270: 65 71 75 65 73 74 20 28 69 64 20 37 29 0a 00 00 |equest (id 7)...|
778 0270: 65 71 75 65 73 74 20 28 69 64 20 37 29 0a 00 00 |equest (id 7)...|
779 0280: 00 00 00 00 00 00 |......|
779 0280: 00 00 00 00 00 00 |......|
780
780
781 The reply is valid
781 The reply is valid
782
782
783 $ hg statbundle2 < ../reply.hg2
783 $ hg statbundle2 < ../reply.hg2
784 options count: 0
784 options count: 0
785 :output:
785 :output:
786 mandatory: 0
786 mandatory: 0
787 advisory: 1
787 advisory: 1
788 payload: 217 bytes
788 payload: 217 bytes
789 :output:
789 :output:
790 mandatory: 0
790 mandatory: 0
791 advisory: 1
791 advisory: 1
792 payload: 201 bytes
792 payload: 201 bytes
793 :test:pong:
793 :test:pong:
794 mandatory: 1
794 mandatory: 1
795 advisory: 0
795 advisory: 0
796 payload: 0 bytes
796 payload: 0 bytes
797 :output:
797 :output:
798 mandatory: 0
798 mandatory: 0
799 advisory: 1
799 advisory: 1
800 payload: 61 bytes
800 payload: 61 bytes
801 parts count: 4
801 parts count: 4
802
802
803 Unbundle the reply to get the output:
803 Unbundle the reply to get the output:
804
804
805 $ hg unbundle2 < ../reply.hg2
805 $ hg unbundle2 < ../reply.hg2
806 remote: The choir starts singing:
806 remote: The choir starts singing:
807 remote: Patali Dirapata, Cromda Cromda Ripalo, Pata Pata, Ko Ko Ko
807 remote: Patali Dirapata, Cromda Cromda Ripalo, Pata Pata, Ko Ko Ko
808 remote: Bokoro Dipoulito, Rondi Rondi Pepino, Pata Pata, Ko Ko Ko
808 remote: Bokoro Dipoulito, Rondi Rondi Pepino, Pata Pata, Ko Ko Ko
809 remote: Emana Karassoli, Loucra Loucra Ponponto, Pata Pata, Ko Ko Ko.
809 remote: Emana Karassoli, Loucra Loucra Ponponto, Pata Pata, Ko Ko Ko.
810 remote: debugreply: capabilities:
810 remote: debugreply: capabilities:
811 remote: debugreply: 'city=!'
811 remote: debugreply: 'city=!'
812 remote: debugreply: 'celeste,ville'
812 remote: debugreply: 'celeste,ville'
813 remote: debugreply: 'elephants'
813 remote: debugreply: 'elephants'
814 remote: debugreply: 'babar'
814 remote: debugreply: 'babar'
815 remote: debugreply: 'celeste'
815 remote: debugreply: 'celeste'
816 remote: debugreply: 'ping-pong'
816 remote: debugreply: 'ping-pong'
817 remote: received ping request (id 7)
817 remote: received ping request (id 7)
818 remote: replying to ping request (id 7)
818 remote: replying to ping request (id 7)
819 0 unread bytes
819 0 unread bytes
820
820
821 Test push race detection
821 Test push race detection
822
822
823 $ hg bundle2 --pushrace ../part-race.hg2
823 $ hg bundle2 --pushrace ../part-race.hg2
824
824
825 $ hg unbundle2 < ../part-race.hg2
825 $ hg unbundle2 < ../part-race.hg2
826 0 unread bytes
826 0 unread bytes
827 abort: push race: repository changed while pushing - please try again
827 abort: push race: repository changed while pushing - please try again
828 [255]
828 [255]
829
829
830 Support for changegroup
830 Support for changegroup
831 ===================================
831 ===================================
832
832
833 $ hg unbundle $TESTDIR/bundles/rebase.hg
833 $ hg unbundle $TESTDIR/bundles/rebase.hg
834 adding changesets
834 adding changesets
835 adding manifests
835 adding manifests
836 adding file changes
836 adding file changes
837 added 8 changesets with 7 changes to 7 files (+3 heads)
837 added 8 changesets with 7 changes to 7 files (+3 heads)
838 new changesets cd010b8cd998:02de42196ebe
838 new changesets cd010b8cd998:02de42196ebe
839 (run 'hg heads' to see heads, 'hg merge' to merge)
839 (run 'hg heads' to see heads, 'hg merge' to merge)
840
840
841 $ hg log -G
841 $ hg log -G
842 o 8:02de42196ebe draft Nicolas Dumazet <nicdumz.commits@gmail.com> H
842 o 8:02de42196ebe draft Nicolas Dumazet <nicdumz.commits@gmail.com> H
843 |
843 |
844 | o 7:eea13746799a draft Nicolas Dumazet <nicdumz.commits@gmail.com> G
844 | o 7:eea13746799a draft Nicolas Dumazet <nicdumz.commits@gmail.com> G
845 |/|
845 |/|
846 o | 6:24b6387c8c8c draft Nicolas Dumazet <nicdumz.commits@gmail.com> F
846 o | 6:24b6387c8c8c draft Nicolas Dumazet <nicdumz.commits@gmail.com> F
847 | |
847 | |
848 | o 5:9520eea781bc draft Nicolas Dumazet <nicdumz.commits@gmail.com> E
848 | o 5:9520eea781bc draft Nicolas Dumazet <nicdumz.commits@gmail.com> E
849 |/
849 |/
850 | o 4:32af7686d403 draft Nicolas Dumazet <nicdumz.commits@gmail.com> D
850 | o 4:32af7686d403 draft Nicolas Dumazet <nicdumz.commits@gmail.com> D
851 | |
851 | |
852 | o 3:5fddd98957c8 draft Nicolas Dumazet <nicdumz.commits@gmail.com> C
852 | o 3:5fddd98957c8 draft Nicolas Dumazet <nicdumz.commits@gmail.com> C
853 | |
853 | |
854 | o 2:42ccdea3bb16 draft Nicolas Dumazet <nicdumz.commits@gmail.com> B
854 | o 2:42ccdea3bb16 draft Nicolas Dumazet <nicdumz.commits@gmail.com> B
855 |/
855 |/
856 o 1:cd010b8cd998 draft Nicolas Dumazet <nicdumz.commits@gmail.com> A
856 o 1:cd010b8cd998 draft Nicolas Dumazet <nicdumz.commits@gmail.com> A
857
857
858 @ 0:3903775176ed draft test a
858 @ 0:3903775176ed draft test a
859
859
860
860
861 $ hg bundle2 --debug --config progress.debug=true --config devel.bundle2.debug=true --rev '8+7+5+4' ../rev.hg2
861 $ hg bundle2 --debug --config progress.debug=true --config devel.bundle2.debug=true --rev '8+7+5+4' ../rev.hg2
862 4 changesets found
862 4 changesets found
863 list of changesets:
863 list of changesets:
864 32af7686d403cf45b5d95f2d70cebea587ac806a
864 32af7686d403cf45b5d95f2d70cebea587ac806a
865 9520eea781bcca16c1e15acc0ba14335a0e8e5ba
865 9520eea781bcca16c1e15acc0ba14335a0e8e5ba
866 eea13746799a9e0bfd88f29d3c2e9dc9389f524f
866 eea13746799a9e0bfd88f29d3c2e9dc9389f524f
867 02de42196ebee42ef284b6780a87cdc96e8eaab6
867 02de42196ebee42ef284b6780a87cdc96e8eaab6
868 bundle2-output-bundle: "HG20", 1 parts total
868 bundle2-output-bundle: "HG20", 1 parts total
869 bundle2-output: start emission of HG20 stream
869 bundle2-output: start emission of HG20 stream
870 bundle2-output: bundle parameter:
870 bundle2-output: bundle parameter:
871 bundle2-output: start of parts
871 bundle2-output: start of parts
872 bundle2-output: bundle part: "changegroup"
872 bundle2-output: bundle part: "changegroup"
873 bundle2-output-part: "changegroup" (advisory) streamed payload
873 bundle2-output-part: "changegroup" (advisory) streamed payload
874 bundle2-output: part 0: "changegroup"
874 bundle2-output: part 0: "changegroup"
875 bundle2-output: header chunk size: 18
875 bundle2-output: header chunk size: 18
876 bundling: 1/4 changesets (25.00%)
876 changesets: 1/4 chunks (25.00%)
877 bundling: 2/4 changesets (50.00%)
877 changesets: 2/4 chunks (50.00%)
878 bundling: 3/4 changesets (75.00%)
878 changesets: 3/4 chunks (75.00%)
879 bundling: 4/4 changesets (100.00%)
879 changesets: 4/4 chunks (100.00%)
880 bundling: 1/4 manifests (25.00%)
880 manifests: 1/4 chunks (25.00%)
881 bundling: 2/4 manifests (50.00%)
881 manifests: 2/4 chunks (50.00%)
882 bundling: 3/4 manifests (75.00%)
882 manifests: 3/4 chunks (75.00%)
883 bundling: 4/4 manifests (100.00%)
883 manifests: 4/4 chunks (100.00%)
884 bundling: D 1/3 files (33.33%)
884 files: D 1/3 files (33.33%)
885 bundling: E 2/3 files (66.67%)
885 files: E 2/3 files (66.67%)
886 bundling: H 3/3 files (100.00%)
886 files: H 3/3 files (100.00%)
887 bundle2-output: payload chunk size: 1555
887 bundle2-output: payload chunk size: 1555
888 bundle2-output: closing payload chunk
888 bundle2-output: closing payload chunk
889 bundle2-output: end of bundle
889 bundle2-output: end of bundle
890
890
891 $ f --hexdump ../rev.hg2
891 $ f --hexdump ../rev.hg2
892 ../rev.hg2:
892 ../rev.hg2:
893 0000: 48 47 32 30 00 00 00 00 00 00 00 12 0b 63 68 61 |HG20.........cha|
893 0000: 48 47 32 30 00 00 00 00 00 00 00 12 0b 63 68 61 |HG20.........cha|
894 0010: 6e 67 65 67 72 6f 75 70 00 00 00 00 00 00 00 00 |ngegroup........|
894 0010: 6e 67 65 67 72 6f 75 70 00 00 00 00 00 00 00 00 |ngegroup........|
895 0020: 06 13 00 00 00 a4 32 af 76 86 d4 03 cf 45 b5 d9 |......2.v....E..|
895 0020: 06 13 00 00 00 a4 32 af 76 86 d4 03 cf 45 b5 d9 |......2.v....E..|
896 0030: 5f 2d 70 ce be a5 87 ac 80 6a 5f dd d9 89 57 c8 |_-p......j_...W.|
896 0030: 5f 2d 70 ce be a5 87 ac 80 6a 5f dd d9 89 57 c8 |_-p......j_...W.|
897 0040: a5 4a 4d 43 6d fe 1d a9 d8 7f 21 a1 b9 7b 00 00 |.JMCm.....!..{..|
897 0040: a5 4a 4d 43 6d fe 1d a9 d8 7f 21 a1 b9 7b 00 00 |.JMCm.....!..{..|
898 0050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
898 0050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
899 0060: 00 00 32 af 76 86 d4 03 cf 45 b5 d9 5f 2d 70 ce |..2.v....E.._-p.|
899 0060: 00 00 32 af 76 86 d4 03 cf 45 b5 d9 5f 2d 70 ce |..2.v....E.._-p.|
900 0070: be a5 87 ac 80 6a 00 00 00 00 00 00 00 29 00 00 |.....j.......)..|
900 0070: be a5 87 ac 80 6a 00 00 00 00 00 00 00 29 00 00 |.....j.......)..|
901 0080: 00 29 36 65 31 66 34 63 34 37 65 63 62 35 33 33 |.)6e1f4c47ecb533|
901 0080: 00 29 36 65 31 66 34 63 34 37 65 63 62 35 33 33 |.)6e1f4c47ecb533|
902 0090: 66 66 64 30 63 38 65 35 32 63 64 63 38 38 61 66 |ffd0c8e52cdc88af|
902 0090: 66 66 64 30 63 38 65 35 32 63 64 63 38 38 61 66 |ffd0c8e52cdc88af|
903 00a0: 62 36 63 64 33 39 65 32 30 63 0a 00 00 00 66 00 |b6cd39e20c....f.|
903 00a0: 62 36 63 64 33 39 65 32 30 63 0a 00 00 00 66 00 |b6cd39e20c....f.|
904 00b0: 00 00 68 00 00 00 02 44 0a 00 00 00 69 00 00 00 |..h....D....i...|
904 00b0: 00 00 68 00 00 00 02 44 0a 00 00 00 69 00 00 00 |..h....D....i...|
905 00c0: 6a 00 00 00 01 44 00 00 00 a4 95 20 ee a7 81 bc |j....D..... ....|
905 00c0: 6a 00 00 00 01 44 00 00 00 a4 95 20 ee a7 81 bc |j....D..... ....|
906 00d0: ca 16 c1 e1 5a cc 0b a1 43 35 a0 e8 e5 ba cd 01 |....Z...C5......|
906 00d0: ca 16 c1 e1 5a cc 0b a1 43 35 a0 e8 e5 ba cd 01 |....Z...C5......|
907 00e0: 0b 8c d9 98 f3 98 1a 5a 81 15 f9 4f 8d a4 ab 50 |.......Z...O...P|
907 00e0: 0b 8c d9 98 f3 98 1a 5a 81 15 f9 4f 8d a4 ab 50 |.......Z...O...P|
908 00f0: 60 89 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |`...............|
908 00f0: 60 89 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |`...............|
909 0100: 00 00 00 00 00 00 95 20 ee a7 81 bc ca 16 c1 e1 |....... ........|
909 0100: 00 00 00 00 00 00 95 20 ee a7 81 bc ca 16 c1 e1 |....... ........|
910 0110: 5a cc 0b a1 43 35 a0 e8 e5 ba 00 00 00 00 00 00 |Z...C5..........|
910 0110: 5a cc 0b a1 43 35 a0 e8 e5 ba 00 00 00 00 00 00 |Z...C5..........|
911 0120: 00 29 00 00 00 29 34 64 65 63 65 39 63 38 32 36 |.)...)4dece9c826|
911 0120: 00 29 00 00 00 29 34 64 65 63 65 39 63 38 32 36 |.)...)4dece9c826|
912 0130: 66 36 39 34 39 30 35 30 37 62 39 38 63 36 33 38 |f69490507b98c638|
912 0130: 66 36 39 34 39 30 35 30 37 62 39 38 63 36 33 38 |f69490507b98c638|
913 0140: 33 61 33 30 30 39 62 32 39 35 38 33 37 64 0a 00 |3a3009b295837d..|
913 0140: 33 61 33 30 30 39 62 32 39 35 38 33 37 64 0a 00 |3a3009b295837d..|
914 0150: 00 00 66 00 00 00 68 00 00 00 02 45 0a 00 00 00 |..f...h....E....|
914 0150: 00 00 66 00 00 00 68 00 00 00 02 45 0a 00 00 00 |..f...h....E....|
915 0160: 69 00 00 00 6a 00 00 00 01 45 00 00 00 a2 ee a1 |i...j....E......|
915 0160: 69 00 00 00 6a 00 00 00 01 45 00 00 00 a2 ee a1 |i...j....E......|
916 0170: 37 46 79 9a 9e 0b fd 88 f2 9d 3c 2e 9d c9 38 9f |7Fy.......<...8.|
916 0170: 37 46 79 9a 9e 0b fd 88 f2 9d 3c 2e 9d c9 38 9f |7Fy.......<...8.|
917 0180: 52 4f 24 b6 38 7c 8c 8c ae 37 17 88 80 f3 fa 95 |RO$.8|...7......|
917 0180: 52 4f 24 b6 38 7c 8c 8c ae 37 17 88 80 f3 fa 95 |RO$.8|...7......|
918 0190: de d3 cb 1c f7 85 95 20 ee a7 81 bc ca 16 c1 e1 |....... ........|
918 0190: de d3 cb 1c f7 85 95 20 ee a7 81 bc ca 16 c1 e1 |....... ........|
919 01a0: 5a cc 0b a1 43 35 a0 e8 e5 ba ee a1 37 46 79 9a |Z...C5......7Fy.|
919 01a0: 5a cc 0b a1 43 35 a0 e8 e5 ba ee a1 37 46 79 9a |Z...C5......7Fy.|
920 01b0: 9e 0b fd 88 f2 9d 3c 2e 9d c9 38 9f 52 4f 00 00 |......<...8.RO..|
920 01b0: 9e 0b fd 88 f2 9d 3c 2e 9d c9 38 9f 52 4f 00 00 |......<...8.RO..|
921 01c0: 00 00 00 00 00 29 00 00 00 29 33 36 35 62 39 33 |.....)...)365b93|
921 01c0: 00 00 00 00 00 29 00 00 00 29 33 36 35 62 39 33 |.....)...)365b93|
922 01d0: 64 35 37 66 64 66 34 38 31 34 65 32 62 35 39 31 |d57fdf4814e2b591|
922 01d0: 64 35 37 66 64 66 34 38 31 34 65 32 62 35 39 31 |d57fdf4814e2b591|
923 01e0: 31 64 36 62 61 63 66 66 32 62 31 32 30 31 34 34 |1d6bacff2b120144|
923 01e0: 31 64 36 62 61 63 66 66 32 62 31 32 30 31 34 34 |1d6bacff2b120144|
924 01f0: 34 31 0a 00 00 00 66 00 00 00 68 00 00 00 00 00 |41....f...h.....|
924 01f0: 34 31 0a 00 00 00 66 00 00 00 68 00 00 00 00 00 |41....f...h.....|
925 0200: 00 00 69 00 00 00 6a 00 00 00 01 47 00 00 00 a4 |..i...j....G....|
925 0200: 00 00 69 00 00 00 6a 00 00 00 01 47 00 00 00 a4 |..i...j....G....|
926 0210: 02 de 42 19 6e be e4 2e f2 84 b6 78 0a 87 cd c9 |..B.n......x....|
926 0210: 02 de 42 19 6e be e4 2e f2 84 b6 78 0a 87 cd c9 |..B.n......x....|
927 0220: 6e 8e aa b6 24 b6 38 7c 8c 8c ae 37 17 88 80 f3 |n...$.8|...7....|
927 0220: 6e 8e aa b6 24 b6 38 7c 8c 8c ae 37 17 88 80 f3 |n...$.8|...7....|
928 0230: fa 95 de d3 cb 1c f7 85 00 00 00 00 00 00 00 00 |................|
928 0230: fa 95 de d3 cb 1c f7 85 00 00 00 00 00 00 00 00 |................|
929 0240: 00 00 00 00 00 00 00 00 00 00 00 00 02 de 42 19 |..............B.|
929 0240: 00 00 00 00 00 00 00 00 00 00 00 00 02 de 42 19 |..............B.|
930 0250: 6e be e4 2e f2 84 b6 78 0a 87 cd c9 6e 8e aa b6 |n......x....n...|
930 0250: 6e be e4 2e f2 84 b6 78 0a 87 cd c9 6e 8e aa b6 |n......x....n...|
931 0260: 00 00 00 00 00 00 00 29 00 00 00 29 38 62 65 65 |.......)...)8bee|
931 0260: 00 00 00 00 00 00 00 29 00 00 00 29 38 62 65 65 |.......)...)8bee|
932 0270: 34 38 65 64 63 37 33 31 38 35 34 31 66 63 30 30 |48edc7318541fc00|
932 0270: 34 38 65 64 63 37 33 31 38 35 34 31 66 63 30 30 |48edc7318541fc00|
933 0280: 31 33 65 65 34 31 62 30 38 39 32 37 36 61 38 63 |13ee41b089276a8c|
933 0280: 31 33 65 65 34 31 62 30 38 39 32 37 36 61 38 63 |13ee41b089276a8c|
934 0290: 32 34 62 66 0a 00 00 00 66 00 00 00 66 00 00 00 |24bf....f...f...|
934 0290: 32 34 62 66 0a 00 00 00 66 00 00 00 66 00 00 00 |24bf....f...f...|
935 02a0: 02 48 0a 00 00 00 67 00 00 00 68 00 00 00 01 48 |.H....g...h....H|
935 02a0: 02 48 0a 00 00 00 67 00 00 00 68 00 00 00 01 48 |.H....g...h....H|
936 02b0: 00 00 00 00 00 00 00 8b 6e 1f 4c 47 ec b5 33 ff |........n.LG..3.|
936 02b0: 00 00 00 00 00 00 00 8b 6e 1f 4c 47 ec b5 33 ff |........n.LG..3.|
937 02c0: d0 c8 e5 2c dc 88 af b6 cd 39 e2 0c 66 a5 a0 18 |...,.....9..f...|
937 02c0: d0 c8 e5 2c dc 88 af b6 cd 39 e2 0c 66 a5 a0 18 |...,.....9..f...|
938 02d0: 17 fd f5 23 9c 27 38 02 b5 b7 61 8d 05 1c 89 e4 |...#.'8...a.....|
938 02d0: 17 fd f5 23 9c 27 38 02 b5 b7 61 8d 05 1c 89 e4 |...#.'8...a.....|
939 02e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
939 02e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
940 02f0: 00 00 00 00 32 af 76 86 d4 03 cf 45 b5 d9 5f 2d |....2.v....E.._-|
940 02f0: 00 00 00 00 32 af 76 86 d4 03 cf 45 b5 d9 5f 2d |....2.v....E.._-|
941 0300: 70 ce be a5 87 ac 80 6a 00 00 00 81 00 00 00 81 |p......j........|
941 0300: 70 ce be a5 87 ac 80 6a 00 00 00 81 00 00 00 81 |p......j........|
942 0310: 00 00 00 2b 44 00 63 33 66 31 63 61 32 39 32 34 |...+D.c3f1ca2924|
942 0310: 00 00 00 2b 44 00 63 33 66 31 63 61 32 39 32 34 |...+D.c3f1ca2924|
943 0320: 63 31 36 61 31 39 62 30 36 35 36 61 38 34 39 30 |c16a19b0656a8490|
943 0320: 63 31 36 61 31 39 62 30 36 35 36 61 38 34 39 30 |c16a19b0656a8490|
944 0330: 30 65 35 30 34 65 35 62 30 61 65 63 32 64 0a 00 |0e504e5b0aec2d..|
944 0330: 30 65 35 30 34 65 35 62 30 61 65 63 32 64 0a 00 |0e504e5b0aec2d..|
945 0340: 00 00 8b 4d ec e9 c8 26 f6 94 90 50 7b 98 c6 38 |...M...&...P{..8|
945 0340: 00 00 8b 4d ec e9 c8 26 f6 94 90 50 7b 98 c6 38 |...M...&...P{..8|
946 0350: 3a 30 09 b2 95 83 7d 00 7d 8c 9d 88 84 13 25 f5 |:0....}.}.....%.|
946 0350: 3a 30 09 b2 95 83 7d 00 7d 8c 9d 88 84 13 25 f5 |:0....}.}.....%.|
947 0360: c6 b0 63 71 b3 5b 4e 8a 2b 1a 83 00 00 00 00 00 |..cq.[N.+.......|
947 0360: c6 b0 63 71 b3 5b 4e 8a 2b 1a 83 00 00 00 00 00 |..cq.[N.+.......|
948 0370: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 95 |................|
948 0370: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 95 |................|
949 0380: 20 ee a7 81 bc ca 16 c1 e1 5a cc 0b a1 43 35 a0 | ........Z...C5.|
949 0380: 20 ee a7 81 bc ca 16 c1 e1 5a cc 0b a1 43 35 a0 | ........Z...C5.|
950 0390: e8 e5 ba 00 00 00 2b 00 00 00 ac 00 00 00 2b 45 |......+.......+E|
950 0390: e8 e5 ba 00 00 00 2b 00 00 00 ac 00 00 00 2b 45 |......+.......+E|
951 03a0: 00 39 63 36 66 64 30 33 35 30 61 36 63 30 64 30 |.9c6fd0350a6c0d0|
951 03a0: 00 39 63 36 66 64 30 33 35 30 61 36 63 30 64 30 |.9c6fd0350a6c0d0|
952 03b0: 63 34 39 64 34 61 39 63 35 30 31 37 63 66 30 37 |c49d4a9c5017cf07|
952 03b0: 63 34 39 64 34 61 39 63 35 30 31 37 63 66 30 37 |c49d4a9c5017cf07|
953 03c0: 30 34 33 66 35 34 65 35 38 0a 00 00 00 8b 36 5b |043f54e58.....6[|
953 03c0: 30 34 33 66 35 34 65 35 38 0a 00 00 00 8b 36 5b |043f54e58.....6[|
954 03d0: 93 d5 7f df 48 14 e2 b5 91 1d 6b ac ff 2b 12 01 |....H.....k..+..|
954 03d0: 93 d5 7f df 48 14 e2 b5 91 1d 6b ac ff 2b 12 01 |....H.....k..+..|
955 03e0: 44 41 28 a5 84 c6 5e f1 21 f8 9e b6 6a b7 d0 bc |DA(...^.!...j...|
955 03e0: 44 41 28 a5 84 c6 5e f1 21 f8 9e b6 6a b7 d0 bc |DA(...^.!...j...|
956 03f0: 15 3d 80 99 e7 ce 4d ec e9 c8 26 f6 94 90 50 7b |.=....M...&...P{|
956 03f0: 15 3d 80 99 e7 ce 4d ec e9 c8 26 f6 94 90 50 7b |.=....M...&...P{|
957 0400: 98 c6 38 3a 30 09 b2 95 83 7d ee a1 37 46 79 9a |..8:0....}..7Fy.|
957 0400: 98 c6 38 3a 30 09 b2 95 83 7d ee a1 37 46 79 9a |..8:0....}..7Fy.|
958 0410: 9e 0b fd 88 f2 9d 3c 2e 9d c9 38 9f 52 4f 00 00 |......<...8.RO..|
958 0410: 9e 0b fd 88 f2 9d 3c 2e 9d c9 38 9f 52 4f 00 00 |......<...8.RO..|
959 0420: 00 56 00 00 00 56 00 00 00 2b 46 00 32 32 62 66 |.V...V...+F.22bf|
959 0420: 00 56 00 00 00 56 00 00 00 2b 46 00 32 32 62 66 |.V...V...+F.22bf|
960 0430: 63 66 64 36 32 61 32 31 61 33 32 38 37 65 64 62 |cfd62a21a3287edb|
960 0430: 63 66 64 36 32 61 32 31 61 33 32 38 37 65 64 62 |cfd62a21a3287edb|
961 0440: 64 34 64 36 35 36 32 31 38 64 30 66 35 32 35 65 |d4d656218d0f525e|
961 0440: 64 34 64 36 35 36 32 31 38 64 30 66 35 32 35 65 |d4d656218d0f525e|
962 0450: 64 37 36 61 0a 00 00 00 97 8b ee 48 ed c7 31 85 |d76a.......H..1.|
962 0450: 64 37 36 61 0a 00 00 00 97 8b ee 48 ed c7 31 85 |d76a.......H..1.|
963 0460: 41 fc 00 13 ee 41 b0 89 27 6a 8c 24 bf 28 a5 84 |A....A..'j.$.(..|
963 0460: 41 fc 00 13 ee 41 b0 89 27 6a 8c 24 bf 28 a5 84 |A....A..'j.$.(..|
964 0470: c6 5e f1 21 f8 9e b6 6a b7 d0 bc 15 3d 80 99 e7 |.^.!...j....=...|
964 0470: c6 5e f1 21 f8 9e b6 6a b7 d0 bc 15 3d 80 99 e7 |.^.!...j....=...|
965 0480: ce 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
965 0480: ce 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
966 0490: 00 00 00 00 00 02 de 42 19 6e be e4 2e f2 84 b6 |.......B.n......|
966 0490: 00 00 00 00 00 02 de 42 19 6e be e4 2e f2 84 b6 |.......B.n......|
967 04a0: 78 0a 87 cd c9 6e 8e aa b6 00 00 00 2b 00 00 00 |x....n......+...|
967 04a0: 78 0a 87 cd c9 6e 8e aa b6 00 00 00 2b 00 00 00 |x....n......+...|
968 04b0: 56 00 00 00 00 00 00 00 81 00 00 00 81 00 00 00 |V...............|
968 04b0: 56 00 00 00 00 00 00 00 81 00 00 00 81 00 00 00 |V...............|
969 04c0: 2b 48 00 38 35 30 30 31 38 39 65 37 34 61 39 65 |+H.8500189e74a9e|
969 04c0: 2b 48 00 38 35 30 30 31 38 39 65 37 34 61 39 65 |+H.8500189e74a9e|
970 04d0: 30 34 37 35 65 38 32 32 30 39 33 62 63 37 64 62 |0475e822093bc7db|
970 04d0: 30 34 37 35 65 38 32 32 30 39 33 62 63 37 64 62 |0475e822093bc7db|
971 04e0: 30 64 36 33 31 61 65 62 30 62 34 0a 00 00 00 00 |0d631aeb0b4.....|
971 04e0: 30 64 36 33 31 61 65 62 30 62 34 0a 00 00 00 00 |0d631aeb0b4.....|
972 04f0: 00 00 00 05 44 00 00 00 62 c3 f1 ca 29 24 c1 6a |....D...b...)$.j|
972 04f0: 00 00 00 05 44 00 00 00 62 c3 f1 ca 29 24 c1 6a |....D...b...)$.j|
973 0500: 19 b0 65 6a 84 90 0e 50 4e 5b 0a ec 2d 00 00 00 |..ej...PN[..-...|
973 0500: 19 b0 65 6a 84 90 0e 50 4e 5b 0a ec 2d 00 00 00 |..ej...PN[..-...|
974 0510: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
974 0510: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
975 0520: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
975 0520: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
976 0530: 00 00 00 00 00 32 af 76 86 d4 03 cf 45 b5 d9 5f |.....2.v....E.._|
976 0530: 00 00 00 00 00 32 af 76 86 d4 03 cf 45 b5 d9 5f |.....2.v....E.._|
977 0540: 2d 70 ce be a5 87 ac 80 6a 00 00 00 00 00 00 00 |-p......j.......|
977 0540: 2d 70 ce be a5 87 ac 80 6a 00 00 00 00 00 00 00 |-p......j.......|
978 0550: 00 00 00 00 02 44 0a 00 00 00 00 00 00 00 05 45 |.....D.........E|
978 0550: 00 00 00 00 02 44 0a 00 00 00 00 00 00 00 05 45 |.....D.........E|
979 0560: 00 00 00 62 9c 6f d0 35 0a 6c 0d 0c 49 d4 a9 c5 |...b.o.5.l..I...|
979 0560: 00 00 00 62 9c 6f d0 35 0a 6c 0d 0c 49 d4 a9 c5 |...b.o.5.l..I...|
980 0570: 01 7c f0 70 43 f5 4e 58 00 00 00 00 00 00 00 00 |.|.pC.NX........|
980 0570: 01 7c f0 70 43 f5 4e 58 00 00 00 00 00 00 00 00 |.|.pC.NX........|
981 0580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
981 0580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
982 0590: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
982 0590: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
983 05a0: 95 20 ee a7 81 bc ca 16 c1 e1 5a cc 0b a1 43 35 |. ........Z...C5|
983 05a0: 95 20 ee a7 81 bc ca 16 c1 e1 5a cc 0b a1 43 35 |. ........Z...C5|
984 05b0: a0 e8 e5 ba 00 00 00 00 00 00 00 00 00 00 00 02 |................|
984 05b0: a0 e8 e5 ba 00 00 00 00 00 00 00 00 00 00 00 02 |................|
985 05c0: 45 0a 00 00 00 00 00 00 00 05 48 00 00 00 62 85 |E.........H...b.|
985 05c0: 45 0a 00 00 00 00 00 00 00 05 48 00 00 00 62 85 |E.........H...b.|
986 05d0: 00 18 9e 74 a9 e0 47 5e 82 20 93 bc 7d b0 d6 31 |...t..G^. ..}..1|
986 05d0: 00 18 9e 74 a9 e0 47 5e 82 20 93 bc 7d b0 d6 31 |...t..G^. ..}..1|
987 05e0: ae b0 b4 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
987 05e0: ae b0 b4 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
988 05f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
988 05f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
989 0600: 00 00 00 00 00 00 00 00 00 00 00 02 de 42 19 6e |.............B.n|
989 0600: 00 00 00 00 00 00 00 00 00 00 00 02 de 42 19 6e |.............B.n|
990 0610: be e4 2e f2 84 b6 78 0a 87 cd c9 6e 8e aa b6 00 |......x....n....|
990 0610: be e4 2e f2 84 b6 78 0a 87 cd c9 6e 8e aa b6 00 |......x....n....|
991 0620: 00 00 00 00 00 00 00 00 00 00 02 48 0a 00 00 00 |...........H....|
991 0620: 00 00 00 00 00 00 00 00 00 00 02 48 0a 00 00 00 |...........H....|
992 0630: 00 00 00 00 00 00 00 00 00 00 00 00 00 |.............|
992 0630: 00 00 00 00 00 00 00 00 00 00 00 00 00 |.............|
993
993
994 $ hg debugbundle ../rev.hg2
994 $ hg debugbundle ../rev.hg2
995 Stream params: {}
995 Stream params: {}
996 changegroup -- {} (mandatory: False)
996 changegroup -- {} (mandatory: False)
997 32af7686d403cf45b5d95f2d70cebea587ac806a
997 32af7686d403cf45b5d95f2d70cebea587ac806a
998 9520eea781bcca16c1e15acc0ba14335a0e8e5ba
998 9520eea781bcca16c1e15acc0ba14335a0e8e5ba
999 eea13746799a9e0bfd88f29d3c2e9dc9389f524f
999 eea13746799a9e0bfd88f29d3c2e9dc9389f524f
1000 02de42196ebee42ef284b6780a87cdc96e8eaab6
1000 02de42196ebee42ef284b6780a87cdc96e8eaab6
1001 $ hg unbundle ../rev.hg2
1001 $ hg unbundle ../rev.hg2
1002 adding changesets
1002 adding changesets
1003 adding manifests
1003 adding manifests
1004 adding file changes
1004 adding file changes
1005 added 0 changesets with 0 changes to 3 files
1005 added 0 changesets with 0 changes to 3 files
1006 (run 'hg update' to get a working copy)
1006 (run 'hg update' to get a working copy)
1007
1007
1008 with reply
1008 with reply
1009
1009
1010 $ hg bundle2 --rev '8+7+5+4' --reply ../rev-rr.hg2
1010 $ hg bundle2 --rev '8+7+5+4' --reply ../rev-rr.hg2
1011 $ hg unbundle2 ../rev-reply.hg2 < ../rev-rr.hg2
1011 $ hg unbundle2 ../rev-reply.hg2 < ../rev-rr.hg2
1012 0 unread bytes
1012 0 unread bytes
1013 addchangegroup return: 1
1013 addchangegroup return: 1
1014
1014
1015 $ f --hexdump ../rev-reply.hg2
1015 $ f --hexdump ../rev-reply.hg2
1016 ../rev-reply.hg2:
1016 ../rev-reply.hg2:
1017 0000: 48 47 32 30 00 00 00 00 00 00 00 2f 11 72 65 70 |HG20......./.rep|
1017 0000: 48 47 32 30 00 00 00 00 00 00 00 2f 11 72 65 70 |HG20......./.rep|
1018 0010: 6c 79 3a 63 68 61 6e 67 65 67 72 6f 75 70 00 00 |ly:changegroup..|
1018 0010: 6c 79 3a 63 68 61 6e 67 65 67 72 6f 75 70 00 00 |ly:changegroup..|
1019 0020: 00 00 00 02 0b 01 06 01 69 6e 2d 72 65 70 6c 79 |........in-reply|
1019 0020: 00 00 00 02 0b 01 06 01 69 6e 2d 72 65 70 6c 79 |........in-reply|
1020 0030: 2d 74 6f 31 72 65 74 75 72 6e 31 00 00 00 00 00 |-to1return1.....|
1020 0030: 2d 74 6f 31 72 65 74 75 72 6e 31 00 00 00 00 00 |-to1return1.....|
1021 0040: 00 00 1b 06 6f 75 74 70 75 74 00 00 00 01 00 01 |....output......|
1021 0040: 00 00 1b 06 6f 75 74 70 75 74 00 00 00 01 00 01 |....output......|
1022 0050: 0b 01 69 6e 2d 72 65 70 6c 79 2d 74 6f 31 00 00 |..in-reply-to1..|
1022 0050: 0b 01 69 6e 2d 72 65 70 6c 79 2d 74 6f 31 00 00 |..in-reply-to1..|
1023 0060: 00 64 61 64 64 69 6e 67 20 63 68 61 6e 67 65 73 |.dadding changes|
1023 0060: 00 64 61 64 64 69 6e 67 20 63 68 61 6e 67 65 73 |.dadding changes|
1024 0070: 65 74 73 0a 61 64 64 69 6e 67 20 6d 61 6e 69 66 |ets.adding manif|
1024 0070: 65 74 73 0a 61 64 64 69 6e 67 20 6d 61 6e 69 66 |ets.adding manif|
1025 0080: 65 73 74 73 0a 61 64 64 69 6e 67 20 66 69 6c 65 |ests.adding file|
1025 0080: 65 73 74 73 0a 61 64 64 69 6e 67 20 66 69 6c 65 |ests.adding file|
1026 0090: 20 63 68 61 6e 67 65 73 0a 61 64 64 65 64 20 30 | changes.added 0|
1026 0090: 20 63 68 61 6e 67 65 73 0a 61 64 64 65 64 20 30 | changes.added 0|
1027 00a0: 20 63 68 61 6e 67 65 73 65 74 73 20 77 69 74 68 | changesets with|
1027 00a0: 20 63 68 61 6e 67 65 73 65 74 73 20 77 69 74 68 | changesets with|
1028 00b0: 20 30 20 63 68 61 6e 67 65 73 20 74 6f 20 33 20 | 0 changes to 3 |
1028 00b0: 20 30 20 63 68 61 6e 67 65 73 20 74 6f 20 33 20 | 0 changes to 3 |
1029 00c0: 66 69 6c 65 73 0a 00 00 00 00 00 00 00 00 |files.........|
1029 00c0: 66 69 6c 65 73 0a 00 00 00 00 00 00 00 00 |files.........|
1030
1030
1031 Check handling of exception during generation.
1031 Check handling of exception during generation.
1032 ----------------------------------------------
1032 ----------------------------------------------
1033
1033
1034 $ hg bundle2 --genraise > ../genfailed.hg2
1034 $ hg bundle2 --genraise > ../genfailed.hg2
1035 abort: Someone set up us the bomb!
1035 abort: Someone set up us the bomb!
1036 [255]
1036 [255]
1037
1037
1038 Should still be a valid bundle
1038 Should still be a valid bundle
1039
1039
1040 $ f --hexdump ../genfailed.hg2
1040 $ f --hexdump ../genfailed.hg2
1041 ../genfailed.hg2:
1041 ../genfailed.hg2:
1042 0000: 48 47 32 30 00 00 00 00 00 00 00 0d 06 6f 75 74 |HG20.........out|
1042 0000: 48 47 32 30 00 00 00 00 00 00 00 0d 06 6f 75 74 |HG20.........out|
1043 0010: 70 75 74 00 00 00 00 00 00 ff ff ff ff 00 00 00 |put.............|
1043 0010: 70 75 74 00 00 00 00 00 00 ff ff ff ff 00 00 00 |put.............|
1044 0020: 48 0b 65 72 72 6f 72 3a 61 62 6f 72 74 00 00 00 |H.error:abort...|
1044 0020: 48 0b 65 72 72 6f 72 3a 61 62 6f 72 74 00 00 00 |H.error:abort...|
1045 0030: 00 01 00 07 2d 6d 65 73 73 61 67 65 75 6e 65 78 |....-messageunex|
1045 0030: 00 01 00 07 2d 6d 65 73 73 61 67 65 75 6e 65 78 |....-messageunex|
1046 0040: 70 65 63 74 65 64 20 65 72 72 6f 72 3a 20 53 6f |pected error: So|
1046 0040: 70 65 63 74 65 64 20 65 72 72 6f 72 3a 20 53 6f |pected error: So|
1047 0050: 6d 65 6f 6e 65 20 73 65 74 20 75 70 20 75 73 20 |meone set up us |
1047 0050: 6d 65 6f 6e 65 20 73 65 74 20 75 70 20 75 73 20 |meone set up us |
1048 0060: 74 68 65 20 62 6f 6d 62 21 00 00 00 00 00 00 00 |the bomb!.......|
1048 0060: 74 68 65 20 62 6f 6d 62 21 00 00 00 00 00 00 00 |the bomb!.......|
1049 0070: 00 |.|
1049 0070: 00 |.|
1050
1050
1051 And its handling on the other size raise a clean exception
1051 And its handling on the other size raise a clean exception
1052
1052
1053 $ cat ../genfailed.hg2 | hg unbundle2
1053 $ cat ../genfailed.hg2 | hg unbundle2
1054 0 unread bytes
1054 0 unread bytes
1055 abort: unexpected error: Someone set up us the bomb!
1055 abort: unexpected error: Someone set up us the bomb!
1056 [255]
1056 [255]
1057
1057
1058 Test compression
1058 Test compression
1059 ================
1059 ================
1060
1060
1061 Simple case where it just work: GZ
1061 Simple case where it just work: GZ
1062 ----------------------------------
1062 ----------------------------------
1063
1063
1064 $ hg bundle2 --compress GZ --rev '8+7+5+4' ../rev.hg2.bz
1064 $ hg bundle2 --compress GZ --rev '8+7+5+4' ../rev.hg2.bz
1065 $ f --hexdump ../rev.hg2.bz
1065 $ f --hexdump ../rev.hg2.bz
1066 ../rev.hg2.bz:
1066 ../rev.hg2.bz:
1067 0000: 48 47 32 30 00 00 00 0e 43 6f 6d 70 72 65 73 73 |HG20....Compress|
1067 0000: 48 47 32 30 00 00 00 0e 43 6f 6d 70 72 65 73 73 |HG20....Compress|
1068 0010: 69 6f 6e 3d 47 5a 78 9c 95 94 7d 68 95 55 1c c7 |ion=GZx...}h.U..|
1068 0010: 69 6f 6e 3d 47 5a 78 9c 95 94 7d 68 95 55 1c c7 |ion=GZx...}h.U..|
1069 0020: 9f 3b 31 e8 ce fa c3 65 be a0 a4 b4 52 b9 29 e7 |.;1....e....R.).|
1069 0020: 9f 3b 31 e8 ce fa c3 65 be a0 a4 b4 52 b9 29 e7 |.;1....e....R.).|
1070 0030: f5 79 ce 89 fa 63 ed 5e 77 8b 9c c3 3f 2a 1c 68 |.y...c.^w...?*.h|
1070 0030: f5 79 ce 89 fa 63 ed 5e 77 8b 9c c3 3f 2a 1c 68 |.y...c.^w...?*.h|
1071 0040: cf 79 9b dd 6a ae b0 28 74 b8 e5 96 5b bb 86 61 |.y..j..(t...[..a|
1071 0040: cf 79 9b dd 6a ae b0 28 74 b8 e5 96 5b bb 86 61 |.y..j..(t...[..a|
1072 0050: a3 15 6e 3a 71 c8 6a e8 a5 da 95 64 28 22 ce 69 |..n:q.j....d(".i|
1072 0050: a3 15 6e 3a 71 c8 6a e8 a5 da 95 64 28 22 ce 69 |..n:q.j....d(".i|
1073 0060: cd 06 59 34 28 2b 51 2a 58 c3 17 56 2a 9a 9d 67 |..Y4(+Q*X..V*..g|
1073 0060: cd 06 59 34 28 2b 51 2a 58 c3 17 56 2a 9a 9d 67 |..Y4(+Q*X..V*..g|
1074 0070: dc c6 35 9e c4 1d f8 9e 87 f3 9c f3 3b bf 0f bf |..5.........;...|
1074 0070: dc c6 35 9e c4 1d f8 9e 87 f3 9c f3 3b bf 0f bf |..5.........;...|
1075 0080: 97 e3 38 ce f4 42 b9 d6 af ae d2 55 af ae 7b ad |..8..B.....U..{.|
1075 0080: 97 e3 38 ce f4 42 b9 d6 af ae d2 55 af ae 7b ad |..8..B.....U..{.|
1076 0090: c6 c9 8d bb 8a ec b4 07 ed 7f fd ed d3 53 be 4e |.............S.N|
1076 0090: c6 c9 8d bb 8a ec b4 07 ed 7f fd ed d3 53 be 4e |.............S.N|
1077 00a0: f4 0e af 59 52 73 ea 50 d7 96 9e ba d4 9a 1f 87 |...YRs.P........|
1077 00a0: f4 0e af 59 52 73 ea 50 d7 96 9e ba d4 9a 1f 87 |...YRs.P........|
1078 00b0: 9b 9f 1d e8 7a 6a 79 e9 cb 7f cf eb fe 7e d3 82 |....zjy......~..|
1078 00b0: 9b 9f 1d e8 7a 6a 79 e9 cb 7f cf eb fe 7e d3 82 |....zjy......~..|
1079 00c0: ce 2f 36 38 21 23 cc 36 b7 b5 38 90 ab a1 21 92 |./68!#.6..8...!.|
1079 00c0: ce 2f 36 38 21 23 cc 36 b7 b5 38 90 ab a1 21 92 |./68!#.6..8...!.|
1080 00d0: 78 5a 0a 8a b1 31 0a 48 a6 29 92 4a 32 e6 1b e1 |xZ...1.H.).J2...|
1080 00d0: 78 5a 0a 8a b1 31 0a 48 a6 29 92 4a 32 e6 1b e1 |xZ...1.H.).J2...|
1081 00e0: 4a 85 b9 46 40 46 ed 61 63 b5 d6 aa 20 1e ac 5e |J..F@F.ac... ..^|
1081 00e0: 4a 85 b9 46 40 46 ed 61 63 b5 d6 aa 20 1e ac 5e |J..F@F.ac... ..^|
1082 00f0: b0 0a ae 8a c4 03 c6 d6 f9 a3 7b eb fb 4e de 7f |..........{..N..|
1082 00f0: b0 0a ae 8a c4 03 c6 d6 f9 a3 7b eb fb 4e de 7f |..........{..N..|
1083 0100: e4 97 55 5f 15 76 96 d2 5d bf 9d 3f 38 18 29 4c |..U_.v..]..?8.)L|
1083 0100: e4 97 55 5f 15 76 96 d2 5d bf 9d 3f 38 18 29 4c |..U_.v..]..?8.)L|
1084 0110: 0f b7 5d 6e 9b b3 aa 7e c6 d5 15 5b f7 7c 52 f1 |..]n...~...[.|R.|
1084 0110: 0f b7 5d 6e 9b b3 aa 7e c6 d5 15 5b f7 7c 52 f1 |..]n...~...[.|R.|
1085 0120: 7c 73 18 63 98 6d 3e 23 51 5a 6a 2e 19 72 8d cb ||s.c.m>#QZj..r..|
1085 0120: 7c 73 18 63 98 6d 3e 23 51 5a 6a 2e 19 72 8d cb ||s.c.m>#QZj..r..|
1086 0130: 09 07 14 78 82 33 e9 62 86 7d 0c 00 17 88 53 86 |...x.3.b.}....S.|
1086 0130: 09 07 14 78 82 33 e9 62 86 7d 0c 00 17 88 53 86 |...x.3.b.}....S.|
1087 0140: 3d 75 0b 63 e2 16 c6 84 9d 76 8f 76 7a cb de fc |=u.c.....v.vz...|
1087 0140: 3d 75 0b 63 e2 16 c6 84 9d 76 8f 76 7a cb de fc |=u.c.....v.vz...|
1088 0150: a8 a3 f0 46 d3 a5 f6 c7 96 b6 9f 60 3b 57 ae 28 |...F.......`;W.(|
1088 0150: a8 a3 f0 46 d3 a5 f6 c7 96 b6 9f 60 3b 57 ae 28 |...F.......`;W.(|
1089 0160: ce b2 8d e9 f4 3e 6f 66 53 dd e5 6b ad 67 be f9 |.....>ofS..k.g..|
1089 0160: ce b2 8d e9 f4 3e 6f 66 53 dd e5 6b ad 67 be f9 |.....>ofS..k.g..|
1090 0170: 72 ee 5f 8d 61 3c 61 b6 f9 8c d8 a5 82 63 45 3d |r._.a<a......cE=|
1090 0170: 72 ee 5f 8d 61 3c 61 b6 f9 8c d8 a5 82 63 45 3d |r._.a<a......cE=|
1091 0180: a3 0c 61 90 68 24 28 87 50 b9 c2 97 c6 20 01 11 |..a.h$(.P.... ..|
1091 0180: a3 0c 61 90 68 24 28 87 50 b9 c2 97 c6 20 01 11 |..a.h$(.P.... ..|
1092 0190: 80 84 10 98 cf e8 e4 13 96 05 51 2c 38 f3 c4 ec |..........Q,8...|
1092 0190: 80 84 10 98 cf e8 e4 13 96 05 51 2c 38 f3 c4 ec |..........Q,8...|
1093 01a0: ea 43 e7 96 5e 6a c8 be 11 dd 32 78 a2 fa dd 8f |.C..^j....2x....|
1093 01a0: ea 43 e7 96 5e 6a c8 be 11 dd 32 78 a2 fa dd 8f |.C..^j....2x....|
1094 01b0: b3 61 84 61 51 0c b3 cd 27 64 42 6b c2 b4 92 1e |.a.aQ...'dBk....|
1094 01b0: b3 61 84 61 51 0c b3 cd 27 64 42 6b c2 b4 92 1e |.a.aQ...'dBk....|
1095 01c0: 86 8c 12 68 24 00 10 db 7f 50 00 c6 91 e7 fa 4c |...h$....P.....L|
1095 01c0: 86 8c 12 68 24 00 10 db 7f 50 00 c6 91 e7 fa 4c |...h$....P.....L|
1096 01d0: 22 22 cc bf 84 81 0a 92 c1 aa 2a c7 1b 49 e6 ee |""........*..I..|
1096 01d0: 22 22 cc bf 84 81 0a 92 c1 aa 2a c7 1b 49 e6 ee |""........*..I..|
1097 01e0: 6b a9 7e e0 e9 b2 91 5e 7c 73 68 e0 fc 23 3f 34 |k.~....^|sh..#?4|
1097 01e0: 6b a9 7e e0 e9 b2 91 5e 7c 73 68 e0 fc 23 3f 34 |k.~....^|sh..#?4|
1098 01f0: ed cf 0e f2 b3 d3 4c d7 ae 59 33 6f 8c 3d b8 63 |......L..Y3o.=.c|
1098 01f0: ed cf 0e f2 b3 d3 4c d7 ae 59 33 6f 8c 3d b8 63 |......L..Y3o.=.c|
1099 0200: 21 2b e8 3d e0 6f 9d 3a b7 f9 dc 24 2a b2 3e a7 |!+.=.o.:...$*.>.|
1099 0200: 21 2b e8 3d e0 6f 9d 3a b7 f9 dc 24 2a b2 3e a7 |!+.=.o.:...$*.>.|
1100 0210: 58 dc 91 d8 40 e9 23 8e 88 84 ae 0f b9 00 2e b5 |X...@.#.........|
1100 0210: 58 dc 91 d8 40 e9 23 8e 88 84 ae 0f b9 00 2e b5 |X...@.#.........|
1101 0220: 74 36 f3 40 53 40 34 15 c0 d7 12 8d e7 bb 65 f9 |t6.@S@4.......e.|
1101 0220: 74 36 f3 40 53 40 34 15 c0 d7 12 8d e7 bb 65 f9 |t6.@S@4.......e.|
1102 0230: c8 ef 03 0f ff f9 fe b6 8a 0d 6d fd ec 51 70 f7 |..........m..Qp.|
1102 0230: c8 ef 03 0f ff f9 fe b6 8a 0d 6d fd ec 51 70 f7 |..........m..Qp.|
1103 0240: a7 ad 9b 6b 9d da 74 7b 53 43 d1 43 63 fd 19 f9 |...k..t{SC.Cc...|
1103 0240: a7 ad 9b 6b 9d da 74 7b 53 43 d1 43 63 fd 19 f9 |...k..t{SC.Cc...|
1104 0250: ca 67 95 e5 ef c4 e6 6c 9e 44 e1 c5 ac 7a 82 6f |.g.....l.D...z.o|
1104 0250: ca 67 95 e5 ef c4 e6 6c 9e 44 e1 c5 ac 7a 82 6f |.g.....l.D...z.o|
1105 0260: c2 e1 d2 b5 2d 81 29 f0 5d 09 6c 6f 10 ae 88 cf |....-.).].lo....|
1105 0260: c2 e1 d2 b5 2d 81 29 f0 5d 09 6c 6f 10 ae 88 cf |....-.).].lo....|
1106 0270: 25 05 d0 93 06 78 80 60 43 2d 10 1b 47 71 2b b7 |%....x.`C-..Gq+.|
1106 0270: 25 05 d0 93 06 78 80 60 43 2d 10 1b 47 71 2b b7 |%....x.`C-..Gq+.|
1107 0280: 7f bb e9 a7 e4 7d 67 7b df 9b f7 62 cf cd d8 f4 |.....}g{...b....|
1107 0280: 7f bb e9 a7 e4 7d 67 7b df 9b f7 62 cf cd d8 f4 |.....}g{...b....|
1108 0290: 48 bc 64 51 57 43 ff ea 8b 0b ae 74 64 53 07 86 |H.dQWC.....tdS..|
1108 0290: 48 bc 64 51 57 43 ff ea 8b 0b ae 74 64 53 07 86 |H.dQWC.....tdS..|
1109 02a0: fa 66 3c 5e f7 e1 af a7 c2 90 ff a7 be 9e c9 29 |.f<^...........)|
1109 02a0: fa 66 3c 5e f7 e1 af a7 c2 90 ff a7 be 9e c9 29 |.f<^...........)|
1110 02b0: b6 cc 41 48 18 69 94 8b 7c 04 7d 8c 98 a7 95 50 |..AH.i..|.}....P|
1110 02b0: b6 cc 41 48 18 69 94 8b 7c 04 7d 8c 98 a7 95 50 |..AH.i..|.}....P|
1111 02c0: 44 d9 d0 20 c8 14 30 14 51 ad 6c 16 03 94 0f 5a |D.. ..0.Q.l....Z|
1111 02c0: 44 d9 d0 20 c8 14 30 14 51 ad 6c 16 03 94 0f 5a |D.. ..0.Q.l....Z|
1112 02d0: 46 93 7f 1c 87 8d 25 d7 9d a2 d1 92 4c f3 c2 54 |F.....%.....L..T|
1112 02d0: 46 93 7f 1c 87 8d 25 d7 9d a2 d1 92 4c f3 c2 54 |F.....%.....L..T|
1113 02e0: ba f8 70 18 ca 24 0a 29 96 43 71 f2 93 95 74 18 |..p..$.).Cq...t.|
1113 02e0: ba f8 70 18 ca 24 0a 29 96 43 71 f2 93 95 74 18 |..p..$.).Cq...t.|
1114 02f0: b5 65 c4 b8 f6 6c 5c 34 20 1e d5 0c 21 c0 b1 90 |.e...l\4 ...!...|
1114 02f0: b5 65 c4 b8 f6 6c 5c 34 20 1e d5 0c 21 c0 b1 90 |.e...l\4 ...!...|
1115 0300: 9e 12 40 b9 18 fa 5a 00 41 a2 39 d3 a9 c1 73 21 |..@...Z.A.9...s!|
1115 0300: 9e 12 40 b9 18 fa 5a 00 41 a2 39 d3 a9 c1 73 21 |..@...Z.A.9...s!|
1116 0310: 8e 5e 3c b9 b8 f8 48 6a 76 46 a7 1a b6 dd 5b 51 |.^<...HjvF....[Q|
1116 0310: 8e 5e 3c b9 b8 f8 48 6a 76 46 a7 1a b6 dd 5b 51 |.^<...HjvF....[Q|
1117 0320: 5e 19 1d 59 12 c6 32 89 02 9a c0 8f 4f b8 0a ba |^..Y..2.....O...|
1117 0320: 5e 19 1d 59 12 c6 32 89 02 9a c0 8f 4f b8 0a ba |^..Y..2.....O...|
1118 0330: 5e ec 58 37 44 a3 2f dd 33 ed c9 d3 dd c7 22 1b |^.X7D./.3.....".|
1118 0330: 5e ec 58 37 44 a3 2f dd 33 ed c9 d3 dd c7 22 1b |^.X7D./.3.....".|
1119 0340: 2f d4 94 8e 95 3f 77 a7 ae 6e f3 32 8d bb 4a 4c |/....?w..n.2..JL|
1119 0340: 2f d4 94 8e 95 3f 77 a7 ae 6e f3 32 8d bb 4a 4c |/....?w..n.2..JL|
1120 0350: b8 0a 5a 43 34 3a b3 3a d6 77 ff 5c b6 fa ad f9 |..ZC4:.:.w.\....|
1120 0350: b8 0a 5a 43 34 3a b3 3a d6 77 ff 5c b6 fa ad f9 |..ZC4:.:.w.\....|
1121 0360: db fb 6a 33 df c1 7d 99 cf ef d4 d5 6d da 77 7c |..j3..}.....m.w||
1121 0360: db fb 6a 33 df c1 7d 99 cf ef d4 d5 6d da 77 7c |..j3..}.....m.w||
1122 0370: 3b 19 fd af c5 3f f1 60 c3 17 |;....?.`..|
1122 0370: 3b 19 fd af c5 3f f1 60 c3 17 |;....?.`..|
1123 $ hg debugbundle ../rev.hg2.bz
1123 $ hg debugbundle ../rev.hg2.bz
1124 Stream params: {Compression: GZ}
1124 Stream params: {Compression: GZ}
1125 changegroup -- {} (mandatory: False)
1125 changegroup -- {} (mandatory: False)
1126 32af7686d403cf45b5d95f2d70cebea587ac806a
1126 32af7686d403cf45b5d95f2d70cebea587ac806a
1127 9520eea781bcca16c1e15acc0ba14335a0e8e5ba
1127 9520eea781bcca16c1e15acc0ba14335a0e8e5ba
1128 eea13746799a9e0bfd88f29d3c2e9dc9389f524f
1128 eea13746799a9e0bfd88f29d3c2e9dc9389f524f
1129 02de42196ebee42ef284b6780a87cdc96e8eaab6
1129 02de42196ebee42ef284b6780a87cdc96e8eaab6
1130 $ hg unbundle ../rev.hg2.bz
1130 $ hg unbundle ../rev.hg2.bz
1131 adding changesets
1131 adding changesets
1132 adding manifests
1132 adding manifests
1133 adding file changes
1133 adding file changes
1134 added 0 changesets with 0 changes to 3 files
1134 added 0 changesets with 0 changes to 3 files
1135 (run 'hg update' to get a working copy)
1135 (run 'hg update' to get a working copy)
1136 Simple case where it just work: BZ
1136 Simple case where it just work: BZ
1137 ----------------------------------
1137 ----------------------------------
1138
1138
1139 $ hg bundle2 --compress BZ --rev '8+7+5+4' ../rev.hg2.bz
1139 $ hg bundle2 --compress BZ --rev '8+7+5+4' ../rev.hg2.bz
1140 $ f --hexdump ../rev.hg2.bz
1140 $ f --hexdump ../rev.hg2.bz
1141 ../rev.hg2.bz:
1141 ../rev.hg2.bz:
1142 0000: 48 47 32 30 00 00 00 0e 43 6f 6d 70 72 65 73 73 |HG20....Compress|
1142 0000: 48 47 32 30 00 00 00 0e 43 6f 6d 70 72 65 73 73 |HG20....Compress|
1143 0010: 69 6f 6e 3d 42 5a 42 5a 68 39 31 41 59 26 53 59 |ion=BZBZh91AY&SY|
1143 0010: 69 6f 6e 3d 42 5a 42 5a 68 39 31 41 59 26 53 59 |ion=BZBZh91AY&SY|
1144 0020: a3 4b 18 3d 00 00 1a 7f ff ff bf 5f f6 ef ef 7f |.K.=......._....|
1144 0020: a3 4b 18 3d 00 00 1a 7f ff ff bf 5f f6 ef ef 7f |.K.=......._....|
1145 0030: f6 3f f7 d1 d9 ff ff f7 6e ff ff 6e f7 f6 bd df |.?......n..n....|
1145 0030: f6 3f f7 d1 d9 ff ff f7 6e ff ff 6e f7 f6 bd df |.?......n..n....|
1146 0040: b5 ab ff cf 67 f6 e7 7b f7 c0 02 d7 33 82 8b 51 |....g..{....3..Q|
1146 0040: b5 ab ff cf 67 f6 e7 7b f7 c0 02 d7 33 82 8b 51 |....g..{....3..Q|
1147 0050: 04 a5 53 d5 3d 27 a0 99 18 4d 0d 34 00 d1 a1 e8 |..S.='...M.4....|
1147 0050: 04 a5 53 d5 3d 27 a0 99 18 4d 0d 34 00 d1 a1 e8 |..S.='...M.4....|
1148 0060: 80 c8 7a 87 a9 a3 43 6a 3d 46 86 26 80 34 3d 40 |..z...Cj=F.&.4=@|
1148 0060: 80 c8 7a 87 a9 a3 43 6a 3d 46 86 26 80 34 3d 40 |..z...Cj=F.&.4=@|
1149 0070: c8 c9 b5 34 f4 8f 48 0f 51 ea 34 34 fd 4d aa 19 |...4..H.Q.44.M..|
1149 0070: c8 c9 b5 34 f4 8f 48 0f 51 ea 34 34 fd 4d aa 19 |...4..H.Q.44.M..|
1150 0080: 03 40 0c 08 da 86 43 d4 f5 0f 42 1e a0 f3 54 33 |.@....C...B...T3|
1150 0080: 03 40 0c 08 da 86 43 d4 f5 0f 42 1e a0 f3 54 33 |.@....C...B...T3|
1151 0090: 54 d3 13 4d 03 40 32 00 00 32 03 26 80 0d 00 0d |T..M.@2..2.&....|
1151 0090: 54 d3 13 4d 03 40 32 00 00 32 03 26 80 0d 00 0d |T..M.@2..2.&....|
1152 00a0: 00 68 c8 c8 03 20 32 30 98 8c 80 00 00 03 4d 00 |.h... 20......M.|
1152 00a0: 00 68 c8 c8 03 20 32 30 98 8c 80 00 00 03 4d 00 |.h... 20......M.|
1153 00b0: c8 00 00 0d 00 00 22 99 a1 34 c2 64 a6 d5 34 1a |......"..4.d..4.|
1153 00b0: c8 00 00 0d 00 00 22 99 a1 34 c2 64 a6 d5 34 1a |......"..4.d..4.|
1154 00c0: 00 00 06 86 83 4d 07 a8 d1 a0 68 01 a0 00 00 00 |.....M....h.....|
1154 00c0: 00 00 06 86 83 4d 07 a8 d1 a0 68 01 a0 00 00 00 |.....M....h.....|
1155 00d0: 00 0d 06 80 00 00 00 0d 00 03 40 00 00 04 a4 a1 |..........@.....|
1155 00d0: 00 0d 06 80 00 00 00 0d 00 03 40 00 00 04 a4 a1 |..........@.....|
1156 00e0: 4d a9 89 89 b4 9a 32 0c 43 46 86 87 a9 8d 41 9a |M.....2.CF....A.|
1156 00e0: 4d a9 89 89 b4 9a 32 0c 43 46 86 87 a9 8d 41 9a |M.....2.CF....A.|
1157 00f0: 98 46 9a 0d 31 32 1a 34 0d 0c 8d a2 0c 98 4d 06 |.F..12.4......M.|
1157 00f0: 98 46 9a 0d 31 32 1a 34 0d 0c 8d a2 0c 98 4d 06 |.F..12.4......M.|
1158 0100: 8c 40 c2 60 8d 0d 0c 20 c9 89 fa a0 d0 d3 21 a1 |.@.`... ......!.|
1158 0100: 8c 40 c2 60 8d 0d 0c 20 c9 89 fa a0 d0 d3 21 a1 |.@.`... ......!.|
1159 0110: ea 34 d3 68 9e a6 d1 74 05 33 cb 66 96 93 28 64 |.4.h...t.3.f..(d|
1159 0110: ea 34 d3 68 9e a6 d1 74 05 33 cb 66 96 93 28 64 |.4.h...t.3.f..(d|
1160 0120: 40 91 22 ac 55 9b ea 40 7b 38 94 e2 f8 06 00 cb |@.".U..@{8......|
1160 0120: 40 91 22 ac 55 9b ea 40 7b 38 94 e2 f8 06 00 cb |@.".U..@{8......|
1161 0130: 28 02 00 4d ab 40 24 10 43 18 cf 64 b4 06 83 0c |(..M.@$.C..d....|
1161 0130: 28 02 00 4d ab 40 24 10 43 18 cf 64 b4 06 83 0c |(..M.@$.C..d....|
1162 0140: 34 6c b4 a3 d4 0a 0a e4 a8 5c 4e 23 c0 c9 7a 31 |4l.......\N#..z1|
1162 0140: 34 6c b4 a3 d4 0a 0a e4 a8 5c 4e 23 c0 c9 7a 31 |4l.......\N#..z1|
1163 0150: 97 87 77 7a 64 88 80 8e 60 97 20 93 0f 8e eb c4 |..wzd...`. .....|
1163 0150: 97 87 77 7a 64 88 80 8e 60 97 20 93 0f 8e eb c4 |..wzd...`. .....|
1164 0160: 62 a4 44 a3 52 20 b2 99 a9 2e e1 d7 29 4a 54 ac |b.D.R ......)JT.|
1164 0160: 62 a4 44 a3 52 20 b2 99 a9 2e e1 d7 29 4a 54 ac |b.D.R ......)JT.|
1165 0170: 44 7a bb cc 04 3d e0 aa bd 6a 33 5e 9b a2 57 36 |Dz...=...j3^..W6|
1165 0170: 44 7a bb cc 04 3d e0 aa bd 6a 33 5e 9b a2 57 36 |Dz...=...j3^..W6|
1166 0180: fa cb 45 bb 6d 3e c1 d9 d9 f5 83 69 8a d0 e0 e2 |..E.m>.....i....|
1166 0180: fa cb 45 bb 6d 3e c1 d9 d9 f5 83 69 8a d0 e0 e2 |..E.m>.....i....|
1167 0190: e7 ae 90 55 24 da 3f ab 78 c0 4c b4 56 a3 9e a4 |...U$.?.x.L.V...|
1167 0190: e7 ae 90 55 24 da 3f ab 78 c0 4c b4 56 a3 9e a4 |...U$.?.x.L.V...|
1168 01a0: af 9c 65 74 86 ec 6d dc 62 dc 33 ca c8 50 dd 9d |..et..m.b.3..P..|
1168 01a0: af 9c 65 74 86 ec 6d dc 62 dc 33 ca c8 50 dd 9d |..et..m.b.3..P..|
1169 01b0: 98 8e 9e 59 20 f3 f0 42 91 4a 09 f5 75 8d 3d a5 |...Y ..B.J..u.=.|
1169 01b0: 98 8e 9e 59 20 f3 f0 42 91 4a 09 f5 75 8d 3d a5 |...Y ..B.J..u.=.|
1170 01c0: a5 15 cb 8d 10 63 b0 c2 2e b2 81 f7 c1 76 0e 53 |.....c.......v.S|
1170 01c0: a5 15 cb 8d 10 63 b0 c2 2e b2 81 f7 c1 76 0e 53 |.....c.......v.S|
1171 01d0: 6c 0e 46 73 b5 ae 67 f9 4c 0b 45 6b a8 32 2a 2f |l.Fs..g.L.Ek.2*/|
1171 01d0: 6c 0e 46 73 b5 ae 67 f9 4c 0b 45 6b a8 32 2a 2f |l.Fs..g.L.Ek.2*/|
1172 01e0: a2 54 a4 44 05 20 a1 38 d1 a4 c6 09 a8 2b 08 99 |.T.D. .8.....+..|
1172 01e0: a2 54 a4 44 05 20 a1 38 d1 a4 c6 09 a8 2b 08 99 |.T.D. .8.....+..|
1173 01f0: a4 14 ae 8d a3 e3 aa 34 27 d8 44 ca c3 5d 21 8b |.......4'.D..]!.|
1173 01f0: a4 14 ae 8d a3 e3 aa 34 27 d8 44 ca c3 5d 21 8b |.......4'.D..]!.|
1174 0200: 1a 1e 97 29 71 2b 09 4a 4a 55 55 94 58 65 b2 bc |...)q+.JJUU.Xe..|
1174 0200: 1a 1e 97 29 71 2b 09 4a 4a 55 55 94 58 65 b2 bc |...)q+.JJUU.Xe..|
1175 0210: f3 a5 90 26 36 76 67 7a 51 98 d6 8a 4a 99 50 b5 |...&6vgzQ...J.P.|
1175 0210: f3 a5 90 26 36 76 67 7a 51 98 d6 8a 4a 99 50 b5 |...&6vgzQ...J.P.|
1176 0220: 99 8f 94 21 17 a9 8b f3 ad 4c 33 d4 2e 40 c8 0c |...!.....L3..@..|
1176 0220: 99 8f 94 21 17 a9 8b f3 ad 4c 33 d4 2e 40 c8 0c |...!.....L3..@..|
1177 0230: 3b 90 53 39 db 48 02 34 83 48 d6 b3 99 13 d2 58 |;.S9.H.4.H.....X|
1177 0230: 3b 90 53 39 db 48 02 34 83 48 d6 b3 99 13 d2 58 |;.S9.H.4.H.....X|
1178 0240: 65 8e 71 ac a9 06 95 f2 c4 8e b4 08 6b d3 0c ae |e.q.........k...|
1178 0240: 65 8e 71 ac a9 06 95 f2 c4 8e b4 08 6b d3 0c ae |e.q.........k...|
1179 0250: d9 90 56 71 43 a7 a2 62 16 3e 50 63 d3 57 3c 2d |..VqC..b.>Pc.W<-|
1179 0250: d9 90 56 71 43 a7 a2 62 16 3e 50 63 d3 57 3c 2d |..VqC..b.>Pc.W<-|
1180 0260: 9f 0f 34 05 08 d8 a6 4b 59 31 54 66 3a 45 0c 8a |..4....KY1Tf:E..|
1180 0260: 9f 0f 34 05 08 d8 a6 4b 59 31 54 66 3a 45 0c 8a |..4....KY1Tf:E..|
1181 0270: c7 90 3a f0 6a 83 1b f5 ca fb 80 2b 50 06 fb 51 |..:.j......+P..Q|
1181 0270: c7 90 3a f0 6a 83 1b f5 ca fb 80 2b 50 06 fb 51 |..:.j......+P..Q|
1182 0280: 7e a6 a4 d4 81 44 82 21 54 00 5b 1a 30 83 62 a3 |~....D.!T.[.0.b.|
1182 0280: 7e a6 a4 d4 81 44 82 21 54 00 5b 1a 30 83 62 a3 |~....D.!T.[.0.b.|
1183 0290: 18 b6 24 19 1e 45 df 4d 5c db a6 af 5b ac 90 fa |..$..E.M\...[...|
1183 0290: 18 b6 24 19 1e 45 df 4d 5c db a6 af 5b ac 90 fa |..$..E.M\...[...|
1184 02a0: 3e ed f9 ec 4c ba 36 ee d8 60 20 a7 c7 3b cb d1 |>...L.6..` ..;..|
1184 02a0: 3e ed f9 ec 4c ba 36 ee d8 60 20 a7 c7 3b cb d1 |>...L.6..` ..;..|
1185 02b0: 90 43 7d 27 16 50 5d ad f4 14 07 0b 90 5c cc 6b |.C}'.P]......\.k|
1185 02b0: 90 43 7d 27 16 50 5d ad f4 14 07 0b 90 5c cc 6b |.C}'.P]......\.k|
1186 02c0: 8d 3f a6 88 f4 34 37 a8 cf 14 63 36 19 f7 3e 28 |.?...47...c6..>(|
1186 02c0: 8d 3f a6 88 f4 34 37 a8 cf 14 63 36 19 f7 3e 28 |.?...47...c6..>(|
1187 02d0: de 99 e8 16 a4 9d 0d 40 a1 a7 24 52 14 a6 72 62 |.......@..$R..rb|
1187 02d0: de 99 e8 16 a4 9d 0d 40 a1 a7 24 52 14 a6 72 62 |.......@..$R..rb|
1188 02e0: 59 5a ca 2d e5 51 90 78 88 d9 c6 c7 21 d0 f7 46 |YZ.-.Q.x....!..F|
1188 02e0: 59 5a ca 2d e5 51 90 78 88 d9 c6 c7 21 d0 f7 46 |YZ.-.Q.x....!..F|
1189 02f0: b2 04 46 44 4e 20 9c 12 b1 03 4e 25 e0 a9 0c 58 |..FDN ....N%...X|
1189 02f0: b2 04 46 44 4e 20 9c 12 b1 03 4e 25 e0 a9 0c 58 |..FDN ....N%...X|
1190 0300: 5b 1d 3c 93 20 01 51 de a9 1c 69 23 32 46 14 b4 |[.<. .Q...i#2F..|
1190 0300: 5b 1d 3c 93 20 01 51 de a9 1c 69 23 32 46 14 b4 |[.<. .Q...i#2F..|
1191 0310: 90 db 17 98 98 50 03 90 29 aa 40 b0 13 d8 43 d2 |.....P..).@...C.|
1191 0310: 90 db 17 98 98 50 03 90 29 aa 40 b0 13 d8 43 d2 |.....P..).@...C.|
1192 0320: 5f c5 9d eb f3 f2 ad 41 e8 7a a9 ed a1 58 84 a6 |_......A.z...X..|
1192 0320: 5f c5 9d eb f3 f2 ad 41 e8 7a a9 ed a1 58 84 a6 |_......A.z...X..|
1193 0330: 42 bf d6 fc 24 82 c1 20 32 26 4a 15 a6 1d 29 7f |B...$.. 2&J...).|
1193 0330: 42 bf d6 fc 24 82 c1 20 32 26 4a 15 a6 1d 29 7f |B...$.. 2&J...).|
1194 0340: 7e f4 3d 07 bc 62 9a 5b ec 44 3d 72 1d 41 8b 5c |~.=..b.[.D=r.A.\|
1194 0340: 7e f4 3d 07 bc 62 9a 5b ec 44 3d 72 1d 41 8b 5c |~.=..b.[.D=r.A.\|
1195 0350: 80 de 0e 62 9a 2e f8 83 00 d5 07 a0 9c c6 74 98 |...b..........t.|
1195 0350: 80 de 0e 62 9a 2e f8 83 00 d5 07 a0 9c c6 74 98 |...b..........t.|
1196 0360: 11 b2 5e a9 38 02 03 ee fd 86 5c f4 86 b3 ae da |..^.8.....\.....|
1196 0360: 11 b2 5e a9 38 02 03 ee fd 86 5c f4 86 b3 ae da |..^.8.....\.....|
1197 0370: 05 94 01 c5 c6 ea 18 e6 ba 2a ba b3 04 5c 96 89 |.........*...\..|
1197 0370: 05 94 01 c5 c6 ea 18 e6 ba 2a ba b3 04 5c 96 89 |.........*...\..|
1198 0380: 72 63 5b 10 11 f6 67 34 98 cb e4 c0 4e fa e6 99 |rc[...g4....N...|
1198 0380: 72 63 5b 10 11 f6 67 34 98 cb e4 c0 4e fa e6 99 |rc[...g4....N...|
1199 0390: 19 6e 50 e8 26 8d 0c 17 e0 be ef e1 8e 02 6f 32 |.nP.&.........o2|
1199 0390: 19 6e 50 e8 26 8d 0c 17 e0 be ef e1 8e 02 6f 32 |.nP.&.........o2|
1200 03a0: 82 dc 26 f8 a1 08 f3 8a 0d f3 c4 75 00 48 73 b8 |..&........u.Hs.|
1200 03a0: 82 dc 26 f8 a1 08 f3 8a 0d f3 c4 75 00 48 73 b8 |..&........u.Hs.|
1201 03b0: be 3b 0d 7f d0 fd c7 78 96 ec e0 03 80 68 4d 8d |.;.....x.....hM.|
1201 03b0: be 3b 0d 7f d0 fd c7 78 96 ec e0 03 80 68 4d 8d |.;.....x.....hM.|
1202 03c0: 43 8c d7 68 58 f9 50 f0 18 cb 21 58 1b 60 cd 1f |C..hX.P...!X.`..|
1202 03c0: 43 8c d7 68 58 f9 50 f0 18 cb 21 58 1b 60 cd 1f |C..hX.P...!X.`..|
1203 03d0: 84 36 2e 16 1f 0a f7 4e 8f eb df 01 2d c2 79 0b |.6.....N....-.y.|
1203 03d0: 84 36 2e 16 1f 0a f7 4e 8f eb df 01 2d c2 79 0b |.6.....N....-.y.|
1204 03e0: f7 24 ea 0d e8 59 86 51 6e 1c 30 a3 ad 2f ee 8c |.$...Y.Qn.0../..|
1204 03e0: f7 24 ea 0d e8 59 86 51 6e 1c 30 a3 ad 2f ee 8c |.$...Y.Qn.0../..|
1205 03f0: 90 c8 84 d5 e8 34 c1 95 b2 c9 f6 4d 87 1c 7d 19 |.....4.....M..}.|
1205 03f0: 90 c8 84 d5 e8 34 c1 95 b2 c9 f6 4d 87 1c 7d 19 |.....4.....M..}.|
1206 0400: d6 41 58 56 7a e0 6c ba 10 c7 e8 33 39 36 96 e7 |.AXVz.l....396..|
1206 0400: d6 41 58 56 7a e0 6c ba 10 c7 e8 33 39 36 96 e7 |.AXVz.l....396..|
1207 0410: d2 f9 59 9a 08 95 48 38 e7 0b b7 0a 24 67 c4 39 |..Y...H8....$g.9|
1207 0410: d2 f9 59 9a 08 95 48 38 e7 0b b7 0a 24 67 c4 39 |..Y...H8....$g.9|
1208 0420: 8b 43 88 57 9c 01 f5 61 b5 e1 27 41 7e af 83 fe |.C.W...a..'A~...|
1208 0420: 8b 43 88 57 9c 01 f5 61 b5 e1 27 41 7e af 83 fe |.C.W...a..'A~...|
1209 0430: 2e e4 8a 70 a1 21 46 96 30 7a |...p.!F.0z|
1209 0430: 2e e4 8a 70 a1 21 46 96 30 7a |...p.!F.0z|
1210 $ hg debugbundle ../rev.hg2.bz
1210 $ hg debugbundle ../rev.hg2.bz
1211 Stream params: {Compression: BZ}
1211 Stream params: {Compression: BZ}
1212 changegroup -- {} (mandatory: False)
1212 changegroup -- {} (mandatory: False)
1213 32af7686d403cf45b5d95f2d70cebea587ac806a
1213 32af7686d403cf45b5d95f2d70cebea587ac806a
1214 9520eea781bcca16c1e15acc0ba14335a0e8e5ba
1214 9520eea781bcca16c1e15acc0ba14335a0e8e5ba
1215 eea13746799a9e0bfd88f29d3c2e9dc9389f524f
1215 eea13746799a9e0bfd88f29d3c2e9dc9389f524f
1216 02de42196ebee42ef284b6780a87cdc96e8eaab6
1216 02de42196ebee42ef284b6780a87cdc96e8eaab6
1217 $ hg unbundle ../rev.hg2.bz
1217 $ hg unbundle ../rev.hg2.bz
1218 adding changesets
1218 adding changesets
1219 adding manifests
1219 adding manifests
1220 adding file changes
1220 adding file changes
1221 added 0 changesets with 0 changes to 3 files
1221 added 0 changesets with 0 changes to 3 files
1222 (run 'hg update' to get a working copy)
1222 (run 'hg update' to get a working copy)
1223
1223
1224 unknown compression while unbundling
1224 unknown compression while unbundling
1225 -----------------------------
1225 -----------------------------
1226
1226
1227 $ hg bundle2 --param Compression=FooBarUnknown --rev '8+7+5+4' ../rev.hg2.bz
1227 $ hg bundle2 --param Compression=FooBarUnknown --rev '8+7+5+4' ../rev.hg2.bz
1228 $ cat ../rev.hg2.bz | hg statbundle2
1228 $ cat ../rev.hg2.bz | hg statbundle2
1229 abort: unknown parameters: Stream Parameter - Compression='FooBarUnknown'
1229 abort: unknown parameters: Stream Parameter - Compression='FooBarUnknown'
1230 [255]
1230 [255]
1231 $ hg unbundle ../rev.hg2.bz
1231 $ hg unbundle ../rev.hg2.bz
1232 abort: ../rev.hg2.bz: unknown bundle feature, Stream Parameter - Compression='FooBarUnknown'
1232 abort: ../rev.hg2.bz: unknown bundle feature, Stream Parameter - Compression='FooBarUnknown'
1233 (see https://mercurial-scm.org/wiki/BundleFeature for more information)
1233 (see https://mercurial-scm.org/wiki/BundleFeature for more information)
1234 [255]
1234 [255]
1235
1235
1236 $ cd ..
1236 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now