##// END OF EJS Templates
streamclone: clear caches after writing changes into files for visibility...
FUJIWARA Katsunori -
r29919:519a0226 default
parent child Browse files
Show More
@@ -1,383 +1,398 b''
1 # streamclone.py - producing and consuming streaming repository data
1 # streamclone.py - producing and consuming streaming repository data
2 #
2 #
3 # Copyright 2015 Gregory Szorc <gregory.szorc@gmail.com>
3 # Copyright 2015 Gregory Szorc <gregory.szorc@gmail.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 struct
10 import struct
11 import time
11 import time
12
12
13 from .i18n import _
13 from .i18n import _
14 from . import (
14 from . import (
15 branchmap,
15 branchmap,
16 error,
16 error,
17 store,
17 store,
18 util,
18 util,
19 )
19 )
20
20
21 def canperformstreamclone(pullop, bailifbundle2supported=False):
21 def canperformstreamclone(pullop, bailifbundle2supported=False):
22 """Whether it is possible to perform a streaming clone as part of pull.
22 """Whether it is possible to perform a streaming clone as part of pull.
23
23
24 ``bailifbundle2supported`` will cause the function to return False if
24 ``bailifbundle2supported`` will cause the function to return False if
25 bundle2 stream clones are supported. It should only be called by the
25 bundle2 stream clones are supported. It should only be called by the
26 legacy stream clone code path.
26 legacy stream clone code path.
27
27
28 Returns a tuple of (supported, requirements). ``supported`` is True if
28 Returns a tuple of (supported, requirements). ``supported`` is True if
29 streaming clone is supported and False otherwise. ``requirements`` is
29 streaming clone is supported and False otherwise. ``requirements`` is
30 a set of repo requirements from the remote, or ``None`` if stream clone
30 a set of repo requirements from the remote, or ``None`` if stream clone
31 isn't supported.
31 isn't supported.
32 """
32 """
33 repo = pullop.repo
33 repo = pullop.repo
34 remote = pullop.remote
34 remote = pullop.remote
35
35
36 bundle2supported = False
36 bundle2supported = False
37 if pullop.canusebundle2:
37 if pullop.canusebundle2:
38 if 'v1' in pullop.remotebundle2caps.get('stream', []):
38 if 'v1' in pullop.remotebundle2caps.get('stream', []):
39 bundle2supported = True
39 bundle2supported = True
40 # else
40 # else
41 # Server doesn't support bundle2 stream clone or doesn't support
41 # Server doesn't support bundle2 stream clone or doesn't support
42 # the versions we support. Fall back and possibly allow legacy.
42 # the versions we support. Fall back and possibly allow legacy.
43
43
44 # Ensures legacy code path uses available bundle2.
44 # Ensures legacy code path uses available bundle2.
45 if bailifbundle2supported and bundle2supported:
45 if bailifbundle2supported and bundle2supported:
46 return False, None
46 return False, None
47 # Ensures bundle2 doesn't try to do a stream clone if it isn't supported.
47 # Ensures bundle2 doesn't try to do a stream clone if it isn't supported.
48 #elif not bailifbundle2supported and not bundle2supported:
48 #elif not bailifbundle2supported and not bundle2supported:
49 # return False, None
49 # return False, None
50
50
51 # Streaming clone only works on empty repositories.
51 # Streaming clone only works on empty repositories.
52 if len(repo):
52 if len(repo):
53 return False, None
53 return False, None
54
54
55 # Streaming clone only works if all data is being requested.
55 # Streaming clone only works if all data is being requested.
56 if pullop.heads:
56 if pullop.heads:
57 return False, None
57 return False, None
58
58
59 streamrequested = pullop.streamclonerequested
59 streamrequested = pullop.streamclonerequested
60
60
61 # If we don't have a preference, let the server decide for us. This
61 # If we don't have a preference, let the server decide for us. This
62 # likely only comes into play in LANs.
62 # likely only comes into play in LANs.
63 if streamrequested is None:
63 if streamrequested is None:
64 # The server can advertise whether to prefer streaming clone.
64 # The server can advertise whether to prefer streaming clone.
65 streamrequested = remote.capable('stream-preferred')
65 streamrequested = remote.capable('stream-preferred')
66
66
67 if not streamrequested:
67 if not streamrequested:
68 return False, None
68 return False, None
69
69
70 # In order for stream clone to work, the client has to support all the
70 # In order for stream clone to work, the client has to support all the
71 # requirements advertised by the server.
71 # requirements advertised by the server.
72 #
72 #
73 # The server advertises its requirements via the "stream" and "streamreqs"
73 # The server advertises its requirements via the "stream" and "streamreqs"
74 # capability. "stream" (a value-less capability) is advertised if and only
74 # capability. "stream" (a value-less capability) is advertised if and only
75 # if the only requirement is "revlogv1." Else, the "streamreqs" capability
75 # if the only requirement is "revlogv1." Else, the "streamreqs" capability
76 # is advertised and contains a comma-delimited list of requirements.
76 # is advertised and contains a comma-delimited list of requirements.
77 requirements = set()
77 requirements = set()
78 if remote.capable('stream'):
78 if remote.capable('stream'):
79 requirements.add('revlogv1')
79 requirements.add('revlogv1')
80 else:
80 else:
81 streamreqs = remote.capable('streamreqs')
81 streamreqs = remote.capable('streamreqs')
82 # This is weird and shouldn't happen with modern servers.
82 # This is weird and shouldn't happen with modern servers.
83 if not streamreqs:
83 if not streamreqs:
84 return False, None
84 return False, None
85
85
86 streamreqs = set(streamreqs.split(','))
86 streamreqs = set(streamreqs.split(','))
87 # Server requires something we don't support. Bail.
87 # Server requires something we don't support. Bail.
88 if streamreqs - repo.supportedformats:
88 if streamreqs - repo.supportedformats:
89 return False, None
89 return False, None
90 requirements = streamreqs
90 requirements = streamreqs
91
91
92 return True, requirements
92 return True, requirements
93
93
94 def maybeperformlegacystreamclone(pullop):
94 def maybeperformlegacystreamclone(pullop):
95 """Possibly perform a legacy stream clone operation.
95 """Possibly perform a legacy stream clone operation.
96
96
97 Legacy stream clones are performed as part of pull but before all other
97 Legacy stream clones are performed as part of pull but before all other
98 operations.
98 operations.
99
99
100 A legacy stream clone will not be performed if a bundle2 stream clone is
100 A legacy stream clone will not be performed if a bundle2 stream clone is
101 supported.
101 supported.
102 """
102 """
103 supported, requirements = canperformstreamclone(pullop)
103 supported, requirements = canperformstreamclone(pullop)
104
104
105 if not supported:
105 if not supported:
106 return
106 return
107
107
108 repo = pullop.repo
108 repo = pullop.repo
109 remote = pullop.remote
109 remote = pullop.remote
110
110
111 # Save remote branchmap. We will use it later to speed up branchcache
111 # Save remote branchmap. We will use it later to speed up branchcache
112 # creation.
112 # creation.
113 rbranchmap = None
113 rbranchmap = None
114 if remote.capable('branchmap'):
114 if remote.capable('branchmap'):
115 rbranchmap = remote.branchmap()
115 rbranchmap = remote.branchmap()
116
116
117 repo.ui.status(_('streaming all changes\n'))
117 repo.ui.status(_('streaming all changes\n'))
118
118
119 fp = remote.stream_out()
119 fp = remote.stream_out()
120 l = fp.readline()
120 l = fp.readline()
121 try:
121 try:
122 resp = int(l)
122 resp = int(l)
123 except ValueError:
123 except ValueError:
124 raise error.ResponseError(
124 raise error.ResponseError(
125 _('unexpected response from remote server:'), l)
125 _('unexpected response from remote server:'), l)
126 if resp == 1:
126 if resp == 1:
127 raise error.Abort(_('operation forbidden by server'))
127 raise error.Abort(_('operation forbidden by server'))
128 elif resp == 2:
128 elif resp == 2:
129 raise error.Abort(_('locking the remote repository failed'))
129 raise error.Abort(_('locking the remote repository failed'))
130 elif resp != 0:
130 elif resp != 0:
131 raise error.Abort(_('the server sent an unknown error code'))
131 raise error.Abort(_('the server sent an unknown error code'))
132
132
133 l = fp.readline()
133 l = fp.readline()
134 try:
134 try:
135 filecount, bytecount = map(int, l.split(' ', 1))
135 filecount, bytecount = map(int, l.split(' ', 1))
136 except (ValueError, TypeError):
136 except (ValueError, TypeError):
137 raise error.ResponseError(
137 raise error.ResponseError(
138 _('unexpected response from remote server:'), l)
138 _('unexpected response from remote server:'), l)
139
139
140 with repo.lock():
140 with repo.lock():
141 consumev1(repo, fp, filecount, bytecount)
141 consumev1(repo, fp, filecount, bytecount)
142
142
143 # new requirements = old non-format requirements +
143 # new requirements = old non-format requirements +
144 # new format-related remote requirements
144 # new format-related remote requirements
145 # requirements from the streamed-in repository
145 # requirements from the streamed-in repository
146 repo.requirements = requirements | (
146 repo.requirements = requirements | (
147 repo.requirements - repo.supportedformats)
147 repo.requirements - repo.supportedformats)
148 repo._applyopenerreqs()
148 repo._applyopenerreqs()
149 repo._writerequirements()
149 repo._writerequirements()
150
150
151 if rbranchmap:
151 if rbranchmap:
152 branchmap.replacecache(repo, rbranchmap)
152 branchmap.replacecache(repo, rbranchmap)
153
153
154 repo.invalidate()
154 repo.invalidate()
155
155
156 def allowservergeneration(ui):
156 def allowservergeneration(ui):
157 """Whether streaming clones are allowed from the server."""
157 """Whether streaming clones are allowed from the server."""
158 return ui.configbool('server', 'uncompressed', True, untrusted=True)
158 return ui.configbool('server', 'uncompressed', True, untrusted=True)
159
159
160 # This is it's own function so extensions can override it.
160 # This is it's own function so extensions can override it.
161 def _walkstreamfiles(repo):
161 def _walkstreamfiles(repo):
162 return repo.store.walk()
162 return repo.store.walk()
163
163
164 def generatev1(repo):
164 def generatev1(repo):
165 """Emit content for version 1 of a streaming clone.
165 """Emit content for version 1 of a streaming clone.
166
166
167 This returns a 3-tuple of (file count, byte size, data iterator).
167 This returns a 3-tuple of (file count, byte size, data iterator).
168
168
169 The data iterator consists of N entries for each file being transferred.
169 The data iterator consists of N entries for each file being transferred.
170 Each file entry starts as a line with the file name and integer size
170 Each file entry starts as a line with the file name and integer size
171 delimited by a null byte.
171 delimited by a null byte.
172
172
173 The raw file data follows. Following the raw file data is the next file
173 The raw file data follows. Following the raw file data is the next file
174 entry, or EOF.
174 entry, or EOF.
175
175
176 When used on the wire protocol, an additional line indicating protocol
176 When used on the wire protocol, an additional line indicating protocol
177 success will be prepended to the stream. This function is not responsible
177 success will be prepended to the stream. This function is not responsible
178 for adding it.
178 for adding it.
179
179
180 This function will obtain a repository lock to ensure a consistent view of
180 This function will obtain a repository lock to ensure a consistent view of
181 the store is captured. It therefore may raise LockError.
181 the store is captured. It therefore may raise LockError.
182 """
182 """
183 entries = []
183 entries = []
184 total_bytes = 0
184 total_bytes = 0
185 # Get consistent snapshot of repo, lock during scan.
185 # Get consistent snapshot of repo, lock during scan.
186 with repo.lock():
186 with repo.lock():
187 repo.ui.debug('scanning\n')
187 repo.ui.debug('scanning\n')
188 for name, ename, size in _walkstreamfiles(repo):
188 for name, ename, size in _walkstreamfiles(repo):
189 if size:
189 if size:
190 entries.append((name, size))
190 entries.append((name, size))
191 total_bytes += size
191 total_bytes += size
192
192
193 repo.ui.debug('%d files, %d bytes to transfer\n' %
193 repo.ui.debug('%d files, %d bytes to transfer\n' %
194 (len(entries), total_bytes))
194 (len(entries), total_bytes))
195
195
196 svfs = repo.svfs
196 svfs = repo.svfs
197 oldaudit = svfs.mustaudit
197 oldaudit = svfs.mustaudit
198 debugflag = repo.ui.debugflag
198 debugflag = repo.ui.debugflag
199 svfs.mustaudit = False
199 svfs.mustaudit = False
200
200
201 def emitrevlogdata():
201 def emitrevlogdata():
202 try:
202 try:
203 for name, size in entries:
203 for name, size in entries:
204 if debugflag:
204 if debugflag:
205 repo.ui.debug('sending %s (%d bytes)\n' % (name, size))
205 repo.ui.debug('sending %s (%d bytes)\n' % (name, size))
206 # partially encode name over the wire for backwards compat
206 # partially encode name over the wire for backwards compat
207 yield '%s\0%d\n' % (store.encodedir(name), size)
207 yield '%s\0%d\n' % (store.encodedir(name), size)
208 if size <= 65536:
208 if size <= 65536:
209 with svfs(name, 'rb') as fp:
209 with svfs(name, 'rb') as fp:
210 yield fp.read(size)
210 yield fp.read(size)
211 else:
211 else:
212 for chunk in util.filechunkiter(svfs(name), limit=size):
212 for chunk in util.filechunkiter(svfs(name), limit=size):
213 yield chunk
213 yield chunk
214 finally:
214 finally:
215 svfs.mustaudit = oldaudit
215 svfs.mustaudit = oldaudit
216
216
217 return len(entries), total_bytes, emitrevlogdata()
217 return len(entries), total_bytes, emitrevlogdata()
218
218
219 def generatev1wireproto(repo):
219 def generatev1wireproto(repo):
220 """Emit content for version 1 of streaming clone suitable for the wire.
220 """Emit content for version 1 of streaming clone suitable for the wire.
221
221
222 This is the data output from ``generatev1()`` with a header line
222 This is the data output from ``generatev1()`` with a header line
223 indicating file count and byte size.
223 indicating file count and byte size.
224 """
224 """
225 filecount, bytecount, it = generatev1(repo)
225 filecount, bytecount, it = generatev1(repo)
226 yield '%d %d\n' % (filecount, bytecount)
226 yield '%d %d\n' % (filecount, bytecount)
227 for chunk in it:
227 for chunk in it:
228 yield chunk
228 yield chunk
229
229
230 def generatebundlev1(repo, compression='UN'):
230 def generatebundlev1(repo, compression='UN'):
231 """Emit content for version 1 of a stream clone bundle.
231 """Emit content for version 1 of a stream clone bundle.
232
232
233 The first 4 bytes of the output ("HGS1") denote this as stream clone
233 The first 4 bytes of the output ("HGS1") denote this as stream clone
234 bundle version 1.
234 bundle version 1.
235
235
236 The next 2 bytes indicate the compression type. Only "UN" is currently
236 The next 2 bytes indicate the compression type. Only "UN" is currently
237 supported.
237 supported.
238
238
239 The next 16 bytes are two 64-bit big endian unsigned integers indicating
239 The next 16 bytes are two 64-bit big endian unsigned integers indicating
240 file count and byte count, respectively.
240 file count and byte count, respectively.
241
241
242 The next 2 bytes is a 16-bit big endian unsigned short declaring the length
242 The next 2 bytes is a 16-bit big endian unsigned short declaring the length
243 of the requirements string, including a trailing \0. The following N bytes
243 of the requirements string, including a trailing \0. The following N bytes
244 are the requirements string, which is ASCII containing a comma-delimited
244 are the requirements string, which is ASCII containing a comma-delimited
245 list of repo requirements that are needed to support the data.
245 list of repo requirements that are needed to support the data.
246
246
247 The remaining content is the output of ``generatev1()`` (which may be
247 The remaining content is the output of ``generatev1()`` (which may be
248 compressed in the future).
248 compressed in the future).
249
249
250 Returns a tuple of (requirements, data generator).
250 Returns a tuple of (requirements, data generator).
251 """
251 """
252 if compression != 'UN':
252 if compression != 'UN':
253 raise ValueError('we do not support the compression argument yet')
253 raise ValueError('we do not support the compression argument yet')
254
254
255 requirements = repo.requirements & repo.supportedformats
255 requirements = repo.requirements & repo.supportedformats
256 requires = ','.join(sorted(requirements))
256 requires = ','.join(sorted(requirements))
257
257
258 def gen():
258 def gen():
259 yield 'HGS1'
259 yield 'HGS1'
260 yield compression
260 yield compression
261
261
262 filecount, bytecount, it = generatev1(repo)
262 filecount, bytecount, it = generatev1(repo)
263 repo.ui.status(_('writing %d bytes for %d files\n') %
263 repo.ui.status(_('writing %d bytes for %d files\n') %
264 (bytecount, filecount))
264 (bytecount, filecount))
265
265
266 yield struct.pack('>QQ', filecount, bytecount)
266 yield struct.pack('>QQ', filecount, bytecount)
267 yield struct.pack('>H', len(requires) + 1)
267 yield struct.pack('>H', len(requires) + 1)
268 yield requires + '\0'
268 yield requires + '\0'
269
269
270 # This is where we'll add compression in the future.
270 # This is where we'll add compression in the future.
271 assert compression == 'UN'
271 assert compression == 'UN'
272
272
273 seen = 0
273 seen = 0
274 repo.ui.progress(_('bundle'), 0, total=bytecount, unit=_('bytes'))
274 repo.ui.progress(_('bundle'), 0, total=bytecount, unit=_('bytes'))
275
275
276 for chunk in it:
276 for chunk in it:
277 seen += len(chunk)
277 seen += len(chunk)
278 repo.ui.progress(_('bundle'), seen, total=bytecount,
278 repo.ui.progress(_('bundle'), seen, total=bytecount,
279 unit=_('bytes'))
279 unit=_('bytes'))
280 yield chunk
280 yield chunk
281
281
282 repo.ui.progress(_('bundle'), None)
282 repo.ui.progress(_('bundle'), None)
283
283
284 return requirements, gen()
284 return requirements, gen()
285
285
286 def consumev1(repo, fp, filecount, bytecount):
286 def consumev1(repo, fp, filecount, bytecount):
287 """Apply the contents from version 1 of a streaming clone file handle.
287 """Apply the contents from version 1 of a streaming clone file handle.
288
288
289 This takes the output from "streamout" and applies it to the specified
289 This takes the output from "streamout" and applies it to the specified
290 repository.
290 repository.
291
291
292 Like "streamout," the status line added by the wire protocol is not handled
292 Like "streamout," the status line added by the wire protocol is not handled
293 by this function.
293 by this function.
294 """
294 """
295 with repo.lock():
295 with repo.lock():
296 repo.ui.status(_('%d files to transfer, %s of data\n') %
296 repo.ui.status(_('%d files to transfer, %s of data\n') %
297 (filecount, util.bytecount(bytecount)))
297 (filecount, util.bytecount(bytecount)))
298 handled_bytes = 0
298 handled_bytes = 0
299 repo.ui.progress(_('clone'), 0, total=bytecount, unit=_('bytes'))
299 repo.ui.progress(_('clone'), 0, total=bytecount, unit=_('bytes'))
300 start = time.time()
300 start = time.time()
301
301
302 # TODO: get rid of (potential) inconsistency
303 #
304 # If transaction is started and any @filecache property is
305 # changed at this point, it causes inconsistency between
306 # in-memory cached property and streamclone-ed file on the
307 # disk. Nested transaction prevents transaction scope "clone"
308 # below from writing in-memory changes out at the end of it,
309 # even though in-memory changes are discarded at the end of it
310 # regardless of transaction nesting.
311 #
312 # But transaction nesting can't be simply prohibited, because
313 # nesting occurs also in ordinary case (e.g. enabling
314 # clonebundles).
315
302 with repo.transaction('clone'):
316 with repo.transaction('clone'):
303 with repo.svfs.backgroundclosing(repo.ui, expectedcount=filecount):
317 with repo.svfs.backgroundclosing(repo.ui, expectedcount=filecount):
304 for i in xrange(filecount):
318 for i in xrange(filecount):
305 # XXX doesn't support '\n' or '\r' in filenames
319 # XXX doesn't support '\n' or '\r' in filenames
306 l = fp.readline()
320 l = fp.readline()
307 try:
321 try:
308 name, size = l.split('\0', 1)
322 name, size = l.split('\0', 1)
309 size = int(size)
323 size = int(size)
310 except (ValueError, TypeError):
324 except (ValueError, TypeError):
311 raise error.ResponseError(
325 raise error.ResponseError(
312 _('unexpected response from remote server:'), l)
326 _('unexpected response from remote server:'), l)
313 if repo.ui.debugflag:
327 if repo.ui.debugflag:
314 repo.ui.debug('adding %s (%s)\n' %
328 repo.ui.debug('adding %s (%s)\n' %
315 (name, util.bytecount(size)))
329 (name, util.bytecount(size)))
316 # for backwards compat, name was partially encoded
330 # for backwards compat, name was partially encoded
317 path = store.decodedir(name)
331 path = store.decodedir(name)
318 with repo.svfs(path, 'w', backgroundclose=True) as ofp:
332 with repo.svfs(path, 'w', backgroundclose=True) as ofp:
319 for chunk in util.filechunkiter(fp, limit=size):
333 for chunk in util.filechunkiter(fp, limit=size):
320 handled_bytes += len(chunk)
334 handled_bytes += len(chunk)
321 repo.ui.progress(_('clone'), handled_bytes,
335 repo.ui.progress(_('clone'), handled_bytes,
322 total=bytecount, unit=_('bytes'))
336 total=bytecount, unit=_('bytes'))
323 ofp.write(chunk)
337 ofp.write(chunk)
324
338
325 # Writing straight to files circumvented the inmemory caches
339 # force @filecache properties to be reloaded from
326 repo.invalidate(clearfilecache=True)
340 # streamclone-ed file at next access
341 repo.invalidate(clearfilecache=True)
327
342
328 elapsed = time.time() - start
343 elapsed = time.time() - start
329 if elapsed <= 0:
344 if elapsed <= 0:
330 elapsed = 0.001
345 elapsed = 0.001
331 repo.ui.progress(_('clone'), None)
346 repo.ui.progress(_('clone'), None)
332 repo.ui.status(_('transferred %s in %.1f seconds (%s/sec)\n') %
347 repo.ui.status(_('transferred %s in %.1f seconds (%s/sec)\n') %
333 (util.bytecount(bytecount), elapsed,
348 (util.bytecount(bytecount), elapsed,
334 util.bytecount(bytecount / elapsed)))
349 util.bytecount(bytecount / elapsed)))
335
350
336 def readbundle1header(fp):
351 def readbundle1header(fp):
337 compression = fp.read(2)
352 compression = fp.read(2)
338 if compression != 'UN':
353 if compression != 'UN':
339 raise error.Abort(_('only uncompressed stream clone bundles are '
354 raise error.Abort(_('only uncompressed stream clone bundles are '
340 'supported; got %s') % compression)
355 'supported; got %s') % compression)
341
356
342 filecount, bytecount = struct.unpack('>QQ', fp.read(16))
357 filecount, bytecount = struct.unpack('>QQ', fp.read(16))
343 requireslen = struct.unpack('>H', fp.read(2))[0]
358 requireslen = struct.unpack('>H', fp.read(2))[0]
344 requires = fp.read(requireslen)
359 requires = fp.read(requireslen)
345
360
346 if not requires.endswith('\0'):
361 if not requires.endswith('\0'):
347 raise error.Abort(_('malformed stream clone bundle: '
362 raise error.Abort(_('malformed stream clone bundle: '
348 'requirements not properly encoded'))
363 'requirements not properly encoded'))
349
364
350 requirements = set(requires.rstrip('\0').split(','))
365 requirements = set(requires.rstrip('\0').split(','))
351
366
352 return filecount, bytecount, requirements
367 return filecount, bytecount, requirements
353
368
354 def applybundlev1(repo, fp):
369 def applybundlev1(repo, fp):
355 """Apply the content from a stream clone bundle version 1.
370 """Apply the content from a stream clone bundle version 1.
356
371
357 We assume the 4 byte header has been read and validated and the file handle
372 We assume the 4 byte header has been read and validated and the file handle
358 is at the 2 byte compression identifier.
373 is at the 2 byte compression identifier.
359 """
374 """
360 if len(repo):
375 if len(repo):
361 raise error.Abort(_('cannot apply stream clone bundle on non-empty '
376 raise error.Abort(_('cannot apply stream clone bundle on non-empty '
362 'repo'))
377 'repo'))
363
378
364 filecount, bytecount, requirements = readbundle1header(fp)
379 filecount, bytecount, requirements = readbundle1header(fp)
365 missingreqs = requirements - repo.supportedformats
380 missingreqs = requirements - repo.supportedformats
366 if missingreqs:
381 if missingreqs:
367 raise error.Abort(_('unable to apply stream clone: '
382 raise error.Abort(_('unable to apply stream clone: '
368 'unsupported format: %s') %
383 'unsupported format: %s') %
369 ', '.join(sorted(missingreqs)))
384 ', '.join(sorted(missingreqs)))
370
385
371 consumev1(repo, fp, filecount, bytecount)
386 consumev1(repo, fp, filecount, bytecount)
372
387
373 class streamcloneapplier(object):
388 class streamcloneapplier(object):
374 """Class to manage applying streaming clone bundles.
389 """Class to manage applying streaming clone bundles.
375
390
376 We need to wrap ``applybundlev1()`` in a dedicated type to enable bundle
391 We need to wrap ``applybundlev1()`` in a dedicated type to enable bundle
377 readers to perform bundle type-specific functionality.
392 readers to perform bundle type-specific functionality.
378 """
393 """
379 def __init__(self, fh):
394 def __init__(self, fh):
380 self._fh = fh
395 self._fh = fh
381
396
382 def apply(self, repo):
397 def apply(self, repo):
383 return applybundlev1(repo, self._fh)
398 return applybundlev1(repo, self._fh)
@@ -1,809 +1,851 b''
1
1
2 $ cat << EOF >> $HGRCPATH
2 $ cat << EOF >> $HGRCPATH
3 > [format]
3 > [format]
4 > usegeneraldelta=yes
4 > usegeneraldelta=yes
5 > EOF
5 > EOF
6
6
7 Setting up test
7 Setting up test
8
8
9 $ hg init test
9 $ hg init test
10 $ cd test
10 $ cd test
11 $ echo 0 > afile
11 $ echo 0 > afile
12 $ hg add afile
12 $ hg add afile
13 $ hg commit -m "0.0"
13 $ hg commit -m "0.0"
14 $ echo 1 >> afile
14 $ echo 1 >> afile
15 $ hg commit -m "0.1"
15 $ hg commit -m "0.1"
16 $ echo 2 >> afile
16 $ echo 2 >> afile
17 $ hg commit -m "0.2"
17 $ hg commit -m "0.2"
18 $ echo 3 >> afile
18 $ echo 3 >> afile
19 $ hg commit -m "0.3"
19 $ hg commit -m "0.3"
20 $ hg update -C 0
20 $ hg update -C 0
21 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
21 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
22 $ echo 1 >> afile
22 $ echo 1 >> afile
23 $ hg commit -m "1.1"
23 $ hg commit -m "1.1"
24 created new head
24 created new head
25 $ echo 2 >> afile
25 $ echo 2 >> afile
26 $ hg commit -m "1.2"
26 $ hg commit -m "1.2"
27 $ echo "a line" > fred
27 $ echo "a line" > fred
28 $ echo 3 >> afile
28 $ echo 3 >> afile
29 $ hg add fred
29 $ hg add fred
30 $ hg commit -m "1.3"
30 $ hg commit -m "1.3"
31 $ hg mv afile adifferentfile
31 $ hg mv afile adifferentfile
32 $ hg commit -m "1.3m"
32 $ hg commit -m "1.3m"
33 $ hg update -C 3
33 $ hg update -C 3
34 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
34 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
35 $ hg mv afile anotherfile
35 $ hg mv afile anotherfile
36 $ hg commit -m "0.3m"
36 $ hg commit -m "0.3m"
37 $ hg verify
37 $ hg verify
38 checking changesets
38 checking changesets
39 checking manifests
39 checking manifests
40 crosschecking files in changesets and manifests
40 crosschecking files in changesets and manifests
41 checking files
41 checking files
42 4 files, 9 changesets, 7 total revisions
42 4 files, 9 changesets, 7 total revisions
43 $ cd ..
43 $ cd ..
44 $ hg init empty
44 $ hg init empty
45
45
46 Bundle and phase
46 Bundle and phase
47
47
48 $ hg -R test phase --force --secret 0
48 $ hg -R test phase --force --secret 0
49 $ hg -R test bundle phase.hg empty
49 $ hg -R test bundle phase.hg empty
50 searching for changes
50 searching for changes
51 no changes found (ignored 9 secret changesets)
51 no changes found (ignored 9 secret changesets)
52 [1]
52 [1]
53 $ hg -R test phase --draft -r 'head()'
53 $ hg -R test phase --draft -r 'head()'
54
54
55 Bundle --all
55 Bundle --all
56
56
57 $ hg -R test bundle --all all.hg
57 $ hg -R test bundle --all all.hg
58 9 changesets found
58 9 changesets found
59
59
60 Bundle test to full.hg
60 Bundle test to full.hg
61
61
62 $ hg -R test bundle full.hg empty
62 $ hg -R test bundle full.hg empty
63 searching for changes
63 searching for changes
64 9 changesets found
64 9 changesets found
65
65
66 Unbundle full.hg in test
66 Unbundle full.hg in test
67
67
68 $ hg -R test unbundle full.hg
68 $ hg -R test unbundle full.hg
69 adding changesets
69 adding changesets
70 adding manifests
70 adding manifests
71 adding file changes
71 adding file changes
72 added 0 changesets with 0 changes to 4 files
72 added 0 changesets with 0 changes to 4 files
73 (run 'hg update' to get a working copy)
73 (run 'hg update' to get a working copy)
74
74
75 Verify empty
75 Verify empty
76
76
77 $ hg -R empty heads
77 $ hg -R empty heads
78 [1]
78 [1]
79 $ hg -R empty verify
79 $ hg -R empty verify
80 checking changesets
80 checking changesets
81 checking manifests
81 checking manifests
82 crosschecking files in changesets and manifests
82 crosschecking files in changesets and manifests
83 checking files
83 checking files
84 0 files, 0 changesets, 0 total revisions
84 0 files, 0 changesets, 0 total revisions
85
85
86 Pull full.hg into test (using --cwd)
86 Pull full.hg into test (using --cwd)
87
87
88 $ hg --cwd test pull ../full.hg
88 $ hg --cwd test pull ../full.hg
89 pulling from ../full.hg
89 pulling from ../full.hg
90 searching for changes
90 searching for changes
91 no changes found
91 no changes found
92
92
93 Verify that there are no leaked temporary files after pull (issue2797)
93 Verify that there are no leaked temporary files after pull (issue2797)
94
94
95 $ ls test/.hg | grep .hg10un
95 $ ls test/.hg | grep .hg10un
96 [1]
96 [1]
97
97
98 Pull full.hg into empty (using --cwd)
98 Pull full.hg into empty (using --cwd)
99
99
100 $ hg --cwd empty pull ../full.hg
100 $ hg --cwd empty pull ../full.hg
101 pulling from ../full.hg
101 pulling from ../full.hg
102 requesting all changes
102 requesting all changes
103 adding changesets
103 adding changesets
104 adding manifests
104 adding manifests
105 adding file changes
105 adding file changes
106 added 9 changesets with 7 changes to 4 files (+1 heads)
106 added 9 changesets with 7 changes to 4 files (+1 heads)
107 (run 'hg heads' to see heads, 'hg merge' to merge)
107 (run 'hg heads' to see heads, 'hg merge' to merge)
108
108
109 Rollback empty
109 Rollback empty
110
110
111 $ hg -R empty rollback
111 $ hg -R empty rollback
112 repository tip rolled back to revision -1 (undo pull)
112 repository tip rolled back to revision -1 (undo pull)
113
113
114 Pull full.hg into empty again (using --cwd)
114 Pull full.hg into empty again (using --cwd)
115
115
116 $ hg --cwd empty pull ../full.hg
116 $ hg --cwd empty pull ../full.hg
117 pulling from ../full.hg
117 pulling from ../full.hg
118 requesting all changes
118 requesting all changes
119 adding changesets
119 adding changesets
120 adding manifests
120 adding manifests
121 adding file changes
121 adding file changes
122 added 9 changesets with 7 changes to 4 files (+1 heads)
122 added 9 changesets with 7 changes to 4 files (+1 heads)
123 (run 'hg heads' to see heads, 'hg merge' to merge)
123 (run 'hg heads' to see heads, 'hg merge' to merge)
124
124
125 Pull full.hg into test (using -R)
125 Pull full.hg into test (using -R)
126
126
127 $ hg -R test pull full.hg
127 $ hg -R test pull full.hg
128 pulling from full.hg
128 pulling from full.hg
129 searching for changes
129 searching for changes
130 no changes found
130 no changes found
131
131
132 Pull full.hg into empty (using -R)
132 Pull full.hg into empty (using -R)
133
133
134 $ hg -R empty pull full.hg
134 $ hg -R empty pull full.hg
135 pulling from full.hg
135 pulling from full.hg
136 searching for changes
136 searching for changes
137 no changes found
137 no changes found
138
138
139 Rollback empty
139 Rollback empty
140
140
141 $ hg -R empty rollback
141 $ hg -R empty rollback
142 repository tip rolled back to revision -1 (undo pull)
142 repository tip rolled back to revision -1 (undo pull)
143
143
144 Pull full.hg into empty again (using -R)
144 Pull full.hg into empty again (using -R)
145
145
146 $ hg -R empty pull full.hg
146 $ hg -R empty pull full.hg
147 pulling from full.hg
147 pulling from full.hg
148 requesting all changes
148 requesting all changes
149 adding changesets
149 adding changesets
150 adding manifests
150 adding manifests
151 adding file changes
151 adding file changes
152 added 9 changesets with 7 changes to 4 files (+1 heads)
152 added 9 changesets with 7 changes to 4 files (+1 heads)
153 (run 'hg heads' to see heads, 'hg merge' to merge)
153 (run 'hg heads' to see heads, 'hg merge' to merge)
154
154
155 Log -R full.hg in fresh empty
155 Log -R full.hg in fresh empty
156
156
157 $ rm -r empty
157 $ rm -r empty
158 $ hg init empty
158 $ hg init empty
159 $ cd empty
159 $ cd empty
160 $ hg -R bundle://../full.hg log
160 $ hg -R bundle://../full.hg log
161 changeset: 8:aa35859c02ea
161 changeset: 8:aa35859c02ea
162 tag: tip
162 tag: tip
163 parent: 3:eebf5a27f8ca
163 parent: 3:eebf5a27f8ca
164 user: test
164 user: test
165 date: Thu Jan 01 00:00:00 1970 +0000
165 date: Thu Jan 01 00:00:00 1970 +0000
166 summary: 0.3m
166 summary: 0.3m
167
167
168 changeset: 7:a6a34bfa0076
168 changeset: 7:a6a34bfa0076
169 user: test
169 user: test
170 date: Thu Jan 01 00:00:00 1970 +0000
170 date: Thu Jan 01 00:00:00 1970 +0000
171 summary: 1.3m
171 summary: 1.3m
172
172
173 changeset: 6:7373c1169842
173 changeset: 6:7373c1169842
174 user: test
174 user: test
175 date: Thu Jan 01 00:00:00 1970 +0000
175 date: Thu Jan 01 00:00:00 1970 +0000
176 summary: 1.3
176 summary: 1.3
177
177
178 changeset: 5:1bb50a9436a7
178 changeset: 5:1bb50a9436a7
179 user: test
179 user: test
180 date: Thu Jan 01 00:00:00 1970 +0000
180 date: Thu Jan 01 00:00:00 1970 +0000
181 summary: 1.2
181 summary: 1.2
182
182
183 changeset: 4:095197eb4973
183 changeset: 4:095197eb4973
184 parent: 0:f9ee2f85a263
184 parent: 0:f9ee2f85a263
185 user: test
185 user: test
186 date: Thu Jan 01 00:00:00 1970 +0000
186 date: Thu Jan 01 00:00:00 1970 +0000
187 summary: 1.1
187 summary: 1.1
188
188
189 changeset: 3:eebf5a27f8ca
189 changeset: 3:eebf5a27f8ca
190 user: test
190 user: test
191 date: Thu Jan 01 00:00:00 1970 +0000
191 date: Thu Jan 01 00:00:00 1970 +0000
192 summary: 0.3
192 summary: 0.3
193
193
194 changeset: 2:e38ba6f5b7e0
194 changeset: 2:e38ba6f5b7e0
195 user: test
195 user: test
196 date: Thu Jan 01 00:00:00 1970 +0000
196 date: Thu Jan 01 00:00:00 1970 +0000
197 summary: 0.2
197 summary: 0.2
198
198
199 changeset: 1:34c2bf6b0626
199 changeset: 1:34c2bf6b0626
200 user: test
200 user: test
201 date: Thu Jan 01 00:00:00 1970 +0000
201 date: Thu Jan 01 00:00:00 1970 +0000
202 summary: 0.1
202 summary: 0.1
203
203
204 changeset: 0:f9ee2f85a263
204 changeset: 0:f9ee2f85a263
205 user: test
205 user: test
206 date: Thu Jan 01 00:00:00 1970 +0000
206 date: Thu Jan 01 00:00:00 1970 +0000
207 summary: 0.0
207 summary: 0.0
208
208
209 Make sure bundlerepo doesn't leak tempfiles (issue2491)
209 Make sure bundlerepo doesn't leak tempfiles (issue2491)
210
210
211 $ ls .hg
211 $ ls .hg
212 00changelog.i
212 00changelog.i
213 cache
213 cache
214 requires
214 requires
215 store
215 store
216
216
217 Pull ../full.hg into empty (with hook)
217 Pull ../full.hg into empty (with hook)
218
218
219 $ echo "[hooks]" >> .hg/hgrc
219 $ echo "[hooks]" >> .hg/hgrc
220 $ echo "changegroup = printenv.py changegroup" >> .hg/hgrc
220 $ echo "changegroup = printenv.py changegroup" >> .hg/hgrc
221
221
222 doesn't work (yet ?)
222 doesn't work (yet ?)
223
223
224 hg -R bundle://../full.hg verify
224 hg -R bundle://../full.hg verify
225
225
226 $ hg pull bundle://../full.hg
226 $ hg pull bundle://../full.hg
227 pulling from bundle:../full.hg
227 pulling from bundle:../full.hg
228 requesting all changes
228 requesting all changes
229 adding changesets
229 adding changesets
230 adding manifests
230 adding manifests
231 adding file changes
231 adding file changes
232 added 9 changesets with 7 changes to 4 files (+1 heads)
232 added 9 changesets with 7 changes to 4 files (+1 heads)
233 changegroup hook: HG_NODE=f9ee2f85a263049e9ae6d37a0e67e96194ffb735 HG_NODE_LAST=aa35859c02ea8bd48da5da68cd2740ac71afcbaf HG_SOURCE=pull HG_TXNID=TXN:* HG_URL=bundle:../full.hg (glob)
233 changegroup hook: HG_NODE=f9ee2f85a263049e9ae6d37a0e67e96194ffb735 HG_NODE_LAST=aa35859c02ea8bd48da5da68cd2740ac71afcbaf HG_SOURCE=pull HG_TXNID=TXN:* HG_URL=bundle:../full.hg (glob)
234 (run 'hg heads' to see heads, 'hg merge' to merge)
234 (run 'hg heads' to see heads, 'hg merge' to merge)
235
235
236 Rollback empty
236 Rollback empty
237
237
238 $ hg rollback
238 $ hg rollback
239 repository tip rolled back to revision -1 (undo pull)
239 repository tip rolled back to revision -1 (undo pull)
240 $ cd ..
240 $ cd ..
241
241
242 Log -R bundle:empty+full.hg
242 Log -R bundle:empty+full.hg
243
243
244 $ hg -R bundle:empty+full.hg log --template="{rev} "; echo ""
244 $ hg -R bundle:empty+full.hg log --template="{rev} "; echo ""
245 8 7 6 5 4 3 2 1 0
245 8 7 6 5 4 3 2 1 0
246
246
247 Pull full.hg into empty again (using -R; with hook)
247 Pull full.hg into empty again (using -R; with hook)
248
248
249 $ hg -R empty pull full.hg
249 $ hg -R empty pull full.hg
250 pulling from full.hg
250 pulling from full.hg
251 requesting all changes
251 requesting all changes
252 adding changesets
252 adding changesets
253 adding manifests
253 adding manifests
254 adding file changes
254 adding file changes
255 added 9 changesets with 7 changes to 4 files (+1 heads)
255 added 9 changesets with 7 changes to 4 files (+1 heads)
256 changegroup hook: HG_NODE=f9ee2f85a263049e9ae6d37a0e67e96194ffb735 HG_NODE_LAST=aa35859c02ea8bd48da5da68cd2740ac71afcbaf HG_SOURCE=pull HG_TXNID=TXN:* HG_URL=bundle:empty+full.hg (glob)
256 changegroup hook: HG_NODE=f9ee2f85a263049e9ae6d37a0e67e96194ffb735 HG_NODE_LAST=aa35859c02ea8bd48da5da68cd2740ac71afcbaf HG_SOURCE=pull HG_TXNID=TXN:* HG_URL=bundle:empty+full.hg (glob)
257 (run 'hg heads' to see heads, 'hg merge' to merge)
257 (run 'hg heads' to see heads, 'hg merge' to merge)
258
258
259 Cannot produce streaming clone bundles with "hg bundle"
259 Cannot produce streaming clone bundles with "hg bundle"
260
260
261 $ hg -R test bundle -t packed1 packed.hg
261 $ hg -R test bundle -t packed1 packed.hg
262 abort: packed bundles cannot be produced by "hg bundle"
262 abort: packed bundles cannot be produced by "hg bundle"
263 (use 'hg debugcreatestreamclonebundle')
263 (use 'hg debugcreatestreamclonebundle')
264 [255]
264 [255]
265
265
266 packed1 is produced properly
266 packed1 is produced properly
267
267
268 $ hg -R test debugcreatestreamclonebundle packed.hg
268 $ hg -R test debugcreatestreamclonebundle packed.hg
269 writing 2663 bytes for 6 files
269 writing 2663 bytes for 6 files
270 bundle requirements: generaldelta, revlogv1
270 bundle requirements: generaldelta, revlogv1
271
271
272 $ f -B 64 --size --sha1 --hexdump packed.hg
272 $ f -B 64 --size --sha1 --hexdump packed.hg
273 packed.hg: size=2826, sha1=e139f97692a142b19cdcff64a69697d5307ce6d4
273 packed.hg: size=2826, sha1=e139f97692a142b19cdcff64a69697d5307ce6d4
274 0000: 48 47 53 31 55 4e 00 00 00 00 00 00 00 06 00 00 |HGS1UN..........|
274 0000: 48 47 53 31 55 4e 00 00 00 00 00 00 00 06 00 00 |HGS1UN..........|
275 0010: 00 00 00 00 0a 67 00 16 67 65 6e 65 72 61 6c 64 |.....g..generald|
275 0010: 00 00 00 00 0a 67 00 16 67 65 6e 65 72 61 6c 64 |.....g..generald|
276 0020: 65 6c 74 61 2c 72 65 76 6c 6f 67 76 31 00 64 61 |elta,revlogv1.da|
276 0020: 65 6c 74 61 2c 72 65 76 6c 6f 67 76 31 00 64 61 |elta,revlogv1.da|
277 0030: 74 61 2f 61 64 69 66 66 65 72 65 6e 74 66 69 6c |ta/adifferentfil|
277 0030: 74 61 2f 61 64 69 66 66 65 72 65 6e 74 66 69 6c |ta/adifferentfil|
278
278
279 $ hg debugbundle --spec packed.hg
279 $ hg debugbundle --spec packed.hg
280 none-packed1;requirements%3Dgeneraldelta%2Crevlogv1
280 none-packed1;requirements%3Dgeneraldelta%2Crevlogv1
281
281
282 generaldelta requirement is listed in stream clone bundles
282 generaldelta requirement is listed in stream clone bundles
283
283
284 $ hg --config format.generaldelta=true init testgd
284 $ hg --config format.generaldelta=true init testgd
285 $ cd testgd
285 $ cd testgd
286 $ touch foo
286 $ touch foo
287 $ hg -q commit -A -m initial
287 $ hg -q commit -A -m initial
288 $ cd ..
288 $ cd ..
289 $ hg -R testgd debugcreatestreamclonebundle packedgd.hg
289 $ hg -R testgd debugcreatestreamclonebundle packedgd.hg
290 writing 301 bytes for 3 files
290 writing 301 bytes for 3 files
291 bundle requirements: generaldelta, revlogv1
291 bundle requirements: generaldelta, revlogv1
292
292
293 $ f -B 64 --size --sha1 --hexdump packedgd.hg
293 $ f -B 64 --size --sha1 --hexdump packedgd.hg
294 packedgd.hg: size=396, sha1=981f9e589799335304a5a9a44caa3623a48d2a9f
294 packedgd.hg: size=396, sha1=981f9e589799335304a5a9a44caa3623a48d2a9f
295 0000: 48 47 53 31 55 4e 00 00 00 00 00 00 00 03 00 00 |HGS1UN..........|
295 0000: 48 47 53 31 55 4e 00 00 00 00 00 00 00 03 00 00 |HGS1UN..........|
296 0010: 00 00 00 00 01 2d 00 16 67 65 6e 65 72 61 6c 64 |.....-..generald|
296 0010: 00 00 00 00 01 2d 00 16 67 65 6e 65 72 61 6c 64 |.....-..generald|
297 0020: 65 6c 74 61 2c 72 65 76 6c 6f 67 76 31 00 64 61 |elta,revlogv1.da|
297 0020: 65 6c 74 61 2c 72 65 76 6c 6f 67 76 31 00 64 61 |elta,revlogv1.da|
298 0030: 74 61 2f 66 6f 6f 2e 69 00 36 34 0a 00 03 00 01 |ta/foo.i.64.....|
298 0030: 74 61 2f 66 6f 6f 2e 69 00 36 34 0a 00 03 00 01 |ta/foo.i.64.....|
299
299
300 $ hg debugbundle --spec packedgd.hg
300 $ hg debugbundle --spec packedgd.hg
301 none-packed1;requirements%3Dgeneraldelta%2Crevlogv1
301 none-packed1;requirements%3Dgeneraldelta%2Crevlogv1
302
302
303 Unpacking packed1 bundles with "hg unbundle" isn't allowed
303 Unpacking packed1 bundles with "hg unbundle" isn't allowed
304
304
305 $ hg init packed
305 $ hg init packed
306 $ hg -R packed unbundle packed.hg
306 $ hg -R packed unbundle packed.hg
307 abort: packed bundles cannot be applied with "hg unbundle"
307 abort: packed bundles cannot be applied with "hg unbundle"
308 (use "hg debugapplystreamclonebundle")
308 (use "hg debugapplystreamclonebundle")
309 [255]
309 [255]
310
310
311 packed1 can be consumed from debug command
311 packed1 can be consumed from debug command
312
312
313 (this also confirms that streamclone-ed changes are visible via
314 @filecache properties to in-process procedures before closing
315 transaction)
316
317 $ cat > $TESTTMP/showtip.py <<EOF
318 > from __future__ import absolute_import
319 >
320 > def showtip(ui, repo, hooktype, **kwargs):
321 > ui.warn('%s: %s\n' % (hooktype, repo['tip'].hex()[:12]))
322 >
323 > def reposetup(ui, repo):
324 > # this confirms (and ensures) that (empty) 00changelog.i
325 > # before streamclone is already cached as repo.changelog
326 > ui.setconfig('hooks', 'pretxnopen.showtip', showtip)
327 >
328 > # this confirms that streamclone-ed changes are visible to
329 > # in-process procedures before closing transaction
330 > ui.setconfig('hooks', 'pretxnclose.showtip', showtip)
331 >
332 > # this confirms that streamclone-ed changes are still visible
333 > # after closing transaction
334 > ui.setconfig('hooks', 'txnclose.showtip', showtip)
335 > EOF
336 $ cat >> $HGRCPATH <<EOF
337 > [extensions]
338 > showtip = $TESTTMP/showtip.py
339 > EOF
340
313 $ hg -R packed debugapplystreamclonebundle packed.hg
341 $ hg -R packed debugapplystreamclonebundle packed.hg
314 6 files to transfer, 2.60 KB of data
342 6 files to transfer, 2.60 KB of data
343 pretxnopen: 000000000000
344 pretxnclose: aa35859c02ea
315 transferred 2.60 KB in *.* seconds (* */sec) (glob)
345 transferred 2.60 KB in *.* seconds (* */sec) (glob)
346 txnclose: aa35859c02ea
347
348 (for safety, confirm visibility of streamclone-ed changes by another
349 process, too)
350
351 $ hg -R packed tip -T "{node|short}\n"
352 aa35859c02ea
353
354 $ cat >> $HGRCPATH <<EOF
355 > [extensions]
356 > showtip = !
357 > EOF
316
358
317 Does not work on non-empty repo
359 Does not work on non-empty repo
318
360
319 $ hg -R packed debugapplystreamclonebundle packed.hg
361 $ hg -R packed debugapplystreamclonebundle packed.hg
320 abort: cannot apply stream clone bundle on non-empty repo
362 abort: cannot apply stream clone bundle on non-empty repo
321 [255]
363 [255]
322
364
323 Create partial clones
365 Create partial clones
324
366
325 $ rm -r empty
367 $ rm -r empty
326 $ hg init empty
368 $ hg init empty
327 $ hg clone -r 3 test partial
369 $ hg clone -r 3 test partial
328 adding changesets
370 adding changesets
329 adding manifests
371 adding manifests
330 adding file changes
372 adding file changes
331 added 4 changesets with 4 changes to 1 files
373 added 4 changesets with 4 changes to 1 files
332 updating to branch default
374 updating to branch default
333 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
375 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
334 $ hg clone partial partial2
376 $ hg clone partial partial2
335 updating to branch default
377 updating to branch default
336 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
378 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
337 $ cd partial
379 $ cd partial
338
380
339 Log -R full.hg in partial
381 Log -R full.hg in partial
340
382
341 $ hg -R bundle://../full.hg log -T phases
383 $ hg -R bundle://../full.hg log -T phases
342 changeset: 8:aa35859c02ea
384 changeset: 8:aa35859c02ea
343 tag: tip
385 tag: tip
344 phase: draft
386 phase: draft
345 parent: 3:eebf5a27f8ca
387 parent: 3:eebf5a27f8ca
346 user: test
388 user: test
347 date: Thu Jan 01 00:00:00 1970 +0000
389 date: Thu Jan 01 00:00:00 1970 +0000
348 summary: 0.3m
390 summary: 0.3m
349
391
350 changeset: 7:a6a34bfa0076
392 changeset: 7:a6a34bfa0076
351 phase: draft
393 phase: draft
352 user: test
394 user: test
353 date: Thu Jan 01 00:00:00 1970 +0000
395 date: Thu Jan 01 00:00:00 1970 +0000
354 summary: 1.3m
396 summary: 1.3m
355
397
356 changeset: 6:7373c1169842
398 changeset: 6:7373c1169842
357 phase: draft
399 phase: draft
358 user: test
400 user: test
359 date: Thu Jan 01 00:00:00 1970 +0000
401 date: Thu Jan 01 00:00:00 1970 +0000
360 summary: 1.3
402 summary: 1.3
361
403
362 changeset: 5:1bb50a9436a7
404 changeset: 5:1bb50a9436a7
363 phase: draft
405 phase: draft
364 user: test
406 user: test
365 date: Thu Jan 01 00:00:00 1970 +0000
407 date: Thu Jan 01 00:00:00 1970 +0000
366 summary: 1.2
408 summary: 1.2
367
409
368 changeset: 4:095197eb4973
410 changeset: 4:095197eb4973
369 phase: draft
411 phase: draft
370 parent: 0:f9ee2f85a263
412 parent: 0:f9ee2f85a263
371 user: test
413 user: test
372 date: Thu Jan 01 00:00:00 1970 +0000
414 date: Thu Jan 01 00:00:00 1970 +0000
373 summary: 1.1
415 summary: 1.1
374
416
375 changeset: 3:eebf5a27f8ca
417 changeset: 3:eebf5a27f8ca
376 phase: public
418 phase: public
377 user: test
419 user: test
378 date: Thu Jan 01 00:00:00 1970 +0000
420 date: Thu Jan 01 00:00:00 1970 +0000
379 summary: 0.3
421 summary: 0.3
380
422
381 changeset: 2:e38ba6f5b7e0
423 changeset: 2:e38ba6f5b7e0
382 phase: public
424 phase: public
383 user: test
425 user: test
384 date: Thu Jan 01 00:00:00 1970 +0000
426 date: Thu Jan 01 00:00:00 1970 +0000
385 summary: 0.2
427 summary: 0.2
386
428
387 changeset: 1:34c2bf6b0626
429 changeset: 1:34c2bf6b0626
388 phase: public
430 phase: public
389 user: test
431 user: test
390 date: Thu Jan 01 00:00:00 1970 +0000
432 date: Thu Jan 01 00:00:00 1970 +0000
391 summary: 0.1
433 summary: 0.1
392
434
393 changeset: 0:f9ee2f85a263
435 changeset: 0:f9ee2f85a263
394 phase: public
436 phase: public
395 user: test
437 user: test
396 date: Thu Jan 01 00:00:00 1970 +0000
438 date: Thu Jan 01 00:00:00 1970 +0000
397 summary: 0.0
439 summary: 0.0
398
440
399
441
400 Incoming full.hg in partial
442 Incoming full.hg in partial
401
443
402 $ hg incoming bundle://../full.hg
444 $ hg incoming bundle://../full.hg
403 comparing with bundle:../full.hg
445 comparing with bundle:../full.hg
404 searching for changes
446 searching for changes
405 changeset: 4:095197eb4973
447 changeset: 4:095197eb4973
406 parent: 0:f9ee2f85a263
448 parent: 0:f9ee2f85a263
407 user: test
449 user: test
408 date: Thu Jan 01 00:00:00 1970 +0000
450 date: Thu Jan 01 00:00:00 1970 +0000
409 summary: 1.1
451 summary: 1.1
410
452
411 changeset: 5:1bb50a9436a7
453 changeset: 5:1bb50a9436a7
412 user: test
454 user: test
413 date: Thu Jan 01 00:00:00 1970 +0000
455 date: Thu Jan 01 00:00:00 1970 +0000
414 summary: 1.2
456 summary: 1.2
415
457
416 changeset: 6:7373c1169842
458 changeset: 6:7373c1169842
417 user: test
459 user: test
418 date: Thu Jan 01 00:00:00 1970 +0000
460 date: Thu Jan 01 00:00:00 1970 +0000
419 summary: 1.3
461 summary: 1.3
420
462
421 changeset: 7:a6a34bfa0076
463 changeset: 7:a6a34bfa0076
422 user: test
464 user: test
423 date: Thu Jan 01 00:00:00 1970 +0000
465 date: Thu Jan 01 00:00:00 1970 +0000
424 summary: 1.3m
466 summary: 1.3m
425
467
426 changeset: 8:aa35859c02ea
468 changeset: 8:aa35859c02ea
427 tag: tip
469 tag: tip
428 parent: 3:eebf5a27f8ca
470 parent: 3:eebf5a27f8ca
429 user: test
471 user: test
430 date: Thu Jan 01 00:00:00 1970 +0000
472 date: Thu Jan 01 00:00:00 1970 +0000
431 summary: 0.3m
473 summary: 0.3m
432
474
433
475
434 Outgoing -R full.hg vs partial2 in partial
476 Outgoing -R full.hg vs partial2 in partial
435
477
436 $ hg -R bundle://../full.hg outgoing ../partial2
478 $ hg -R bundle://../full.hg outgoing ../partial2
437 comparing with ../partial2
479 comparing with ../partial2
438 searching for changes
480 searching for changes
439 changeset: 4:095197eb4973
481 changeset: 4:095197eb4973
440 parent: 0:f9ee2f85a263
482 parent: 0:f9ee2f85a263
441 user: test
483 user: test
442 date: Thu Jan 01 00:00:00 1970 +0000
484 date: Thu Jan 01 00:00:00 1970 +0000
443 summary: 1.1
485 summary: 1.1
444
486
445 changeset: 5:1bb50a9436a7
487 changeset: 5:1bb50a9436a7
446 user: test
488 user: test
447 date: Thu Jan 01 00:00:00 1970 +0000
489 date: Thu Jan 01 00:00:00 1970 +0000
448 summary: 1.2
490 summary: 1.2
449
491
450 changeset: 6:7373c1169842
492 changeset: 6:7373c1169842
451 user: test
493 user: test
452 date: Thu Jan 01 00:00:00 1970 +0000
494 date: Thu Jan 01 00:00:00 1970 +0000
453 summary: 1.3
495 summary: 1.3
454
496
455 changeset: 7:a6a34bfa0076
497 changeset: 7:a6a34bfa0076
456 user: test
498 user: test
457 date: Thu Jan 01 00:00:00 1970 +0000
499 date: Thu Jan 01 00:00:00 1970 +0000
458 summary: 1.3m
500 summary: 1.3m
459
501
460 changeset: 8:aa35859c02ea
502 changeset: 8:aa35859c02ea
461 tag: tip
503 tag: tip
462 parent: 3:eebf5a27f8ca
504 parent: 3:eebf5a27f8ca
463 user: test
505 user: test
464 date: Thu Jan 01 00:00:00 1970 +0000
506 date: Thu Jan 01 00:00:00 1970 +0000
465 summary: 0.3m
507 summary: 0.3m
466
508
467
509
468 Outgoing -R does-not-exist.hg vs partial2 in partial
510 Outgoing -R does-not-exist.hg vs partial2 in partial
469
511
470 $ hg -R bundle://../does-not-exist.hg outgoing ../partial2
512 $ hg -R bundle://../does-not-exist.hg outgoing ../partial2
471 abort: *../does-not-exist.hg* (glob)
513 abort: *../does-not-exist.hg* (glob)
472 [255]
514 [255]
473 $ cd ..
515 $ cd ..
474
516
475 hide outer repo
517 hide outer repo
476 $ hg init
518 $ hg init
477
519
478 Direct clone from bundle (all-history)
520 Direct clone from bundle (all-history)
479
521
480 $ hg clone full.hg full-clone
522 $ hg clone full.hg full-clone
481 requesting all changes
523 requesting all changes
482 adding changesets
524 adding changesets
483 adding manifests
525 adding manifests
484 adding file changes
526 adding file changes
485 added 9 changesets with 7 changes to 4 files (+1 heads)
527 added 9 changesets with 7 changes to 4 files (+1 heads)
486 updating to branch default
528 updating to branch default
487 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
529 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
488 $ hg -R full-clone heads
530 $ hg -R full-clone heads
489 changeset: 8:aa35859c02ea
531 changeset: 8:aa35859c02ea
490 tag: tip
532 tag: tip
491 parent: 3:eebf5a27f8ca
533 parent: 3:eebf5a27f8ca
492 user: test
534 user: test
493 date: Thu Jan 01 00:00:00 1970 +0000
535 date: Thu Jan 01 00:00:00 1970 +0000
494 summary: 0.3m
536 summary: 0.3m
495
537
496 changeset: 7:a6a34bfa0076
538 changeset: 7:a6a34bfa0076
497 user: test
539 user: test
498 date: Thu Jan 01 00:00:00 1970 +0000
540 date: Thu Jan 01 00:00:00 1970 +0000
499 summary: 1.3m
541 summary: 1.3m
500
542
501 $ rm -r full-clone
543 $ rm -r full-clone
502
544
503 When cloning from a non-copiable repository into '', do not
545 When cloning from a non-copiable repository into '', do not
504 recurse infinitely (issue2528)
546 recurse infinitely (issue2528)
505
547
506 $ hg clone full.hg ''
548 $ hg clone full.hg ''
507 abort: empty destination path is not valid
549 abort: empty destination path is not valid
508 [255]
550 [255]
509
551
510 test for https://bz.mercurial-scm.org/216
552 test for https://bz.mercurial-scm.org/216
511
553
512 Unbundle incremental bundles into fresh empty in one go
554 Unbundle incremental bundles into fresh empty in one go
513
555
514 $ rm -r empty
556 $ rm -r empty
515 $ hg init empty
557 $ hg init empty
516 $ hg -R test bundle --base null -r 0 ../0.hg
558 $ hg -R test bundle --base null -r 0 ../0.hg
517 1 changesets found
559 1 changesets found
518 $ hg -R test bundle --base 0 -r 1 ../1.hg
560 $ hg -R test bundle --base 0 -r 1 ../1.hg
519 1 changesets found
561 1 changesets found
520 $ hg -R empty unbundle -u ../0.hg ../1.hg
562 $ hg -R empty unbundle -u ../0.hg ../1.hg
521 adding changesets
563 adding changesets
522 adding manifests
564 adding manifests
523 adding file changes
565 adding file changes
524 added 1 changesets with 1 changes to 1 files
566 added 1 changesets with 1 changes to 1 files
525 adding changesets
567 adding changesets
526 adding manifests
568 adding manifests
527 adding file changes
569 adding file changes
528 added 1 changesets with 1 changes to 1 files
570 added 1 changesets with 1 changes to 1 files
529 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
571 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
530
572
531 View full contents of the bundle
573 View full contents of the bundle
532 $ hg -R test bundle --base null -r 3 ../partial.hg
574 $ hg -R test bundle --base null -r 3 ../partial.hg
533 4 changesets found
575 4 changesets found
534 $ cd test
576 $ cd test
535 $ hg -R ../../partial.hg log -r "bundle()"
577 $ hg -R ../../partial.hg log -r "bundle()"
536 changeset: 0:f9ee2f85a263
578 changeset: 0:f9ee2f85a263
537 user: test
579 user: test
538 date: Thu Jan 01 00:00:00 1970 +0000
580 date: Thu Jan 01 00:00:00 1970 +0000
539 summary: 0.0
581 summary: 0.0
540
582
541 changeset: 1:34c2bf6b0626
583 changeset: 1:34c2bf6b0626
542 user: test
584 user: test
543 date: Thu Jan 01 00:00:00 1970 +0000
585 date: Thu Jan 01 00:00:00 1970 +0000
544 summary: 0.1
586 summary: 0.1
545
587
546 changeset: 2:e38ba6f5b7e0
588 changeset: 2:e38ba6f5b7e0
547 user: test
589 user: test
548 date: Thu Jan 01 00:00:00 1970 +0000
590 date: Thu Jan 01 00:00:00 1970 +0000
549 summary: 0.2
591 summary: 0.2
550
592
551 changeset: 3:eebf5a27f8ca
593 changeset: 3:eebf5a27f8ca
552 user: test
594 user: test
553 date: Thu Jan 01 00:00:00 1970 +0000
595 date: Thu Jan 01 00:00:00 1970 +0000
554 summary: 0.3
596 summary: 0.3
555
597
556 $ cd ..
598 $ cd ..
557
599
558 test for 540d1059c802
600 test for 540d1059c802
559
601
560 test for 540d1059c802
602 test for 540d1059c802
561
603
562 $ hg init orig
604 $ hg init orig
563 $ cd orig
605 $ cd orig
564 $ echo foo > foo
606 $ echo foo > foo
565 $ hg add foo
607 $ hg add foo
566 $ hg ci -m 'add foo'
608 $ hg ci -m 'add foo'
567
609
568 $ hg clone . ../copy
610 $ hg clone . ../copy
569 updating to branch default
611 updating to branch default
570 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
612 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
571 $ hg tag foo
613 $ hg tag foo
572
614
573 $ cd ../copy
615 $ cd ../copy
574 $ echo >> foo
616 $ echo >> foo
575 $ hg ci -m 'change foo'
617 $ hg ci -m 'change foo'
576 $ hg bundle ../bundle.hg ../orig
618 $ hg bundle ../bundle.hg ../orig
577 searching for changes
619 searching for changes
578 1 changesets found
620 1 changesets found
579
621
580 $ cd ../orig
622 $ cd ../orig
581 $ hg incoming ../bundle.hg
623 $ hg incoming ../bundle.hg
582 comparing with ../bundle.hg
624 comparing with ../bundle.hg
583 searching for changes
625 searching for changes
584 changeset: 2:ed1b79f46b9a
626 changeset: 2:ed1b79f46b9a
585 tag: tip
627 tag: tip
586 parent: 0:bbd179dfa0a7
628 parent: 0:bbd179dfa0a7
587 user: test
629 user: test
588 date: Thu Jan 01 00:00:00 1970 +0000
630 date: Thu Jan 01 00:00:00 1970 +0000
589 summary: change foo
631 summary: change foo
590
632
591 $ cd ..
633 $ cd ..
592
634
593 test bundle with # in the filename (issue2154):
635 test bundle with # in the filename (issue2154):
594
636
595 $ cp bundle.hg 'test#bundle.hg'
637 $ cp bundle.hg 'test#bundle.hg'
596 $ cd orig
638 $ cd orig
597 $ hg incoming '../test#bundle.hg'
639 $ hg incoming '../test#bundle.hg'
598 comparing with ../test
640 comparing with ../test
599 abort: unknown revision 'bundle.hg'!
641 abort: unknown revision 'bundle.hg'!
600 [255]
642 [255]
601
643
602 note that percent encoding is not handled:
644 note that percent encoding is not handled:
603
645
604 $ hg incoming ../test%23bundle.hg
646 $ hg incoming ../test%23bundle.hg
605 abort: repository ../test%23bundle.hg not found!
647 abort: repository ../test%23bundle.hg not found!
606 [255]
648 [255]
607 $ cd ..
649 $ cd ..
608
650
609 test to bundle revisions on the newly created branch (issue3828):
651 test to bundle revisions on the newly created branch (issue3828):
610
652
611 $ hg -q clone -U test test-clone
653 $ hg -q clone -U test test-clone
612 $ cd test
654 $ cd test
613
655
614 $ hg -q branch foo
656 $ hg -q branch foo
615 $ hg commit -m "create foo branch"
657 $ hg commit -m "create foo branch"
616 $ hg -q outgoing ../test-clone
658 $ hg -q outgoing ../test-clone
617 9:b4f5acb1ee27
659 9:b4f5acb1ee27
618 $ hg -q bundle --branch foo foo.hg ../test-clone
660 $ hg -q bundle --branch foo foo.hg ../test-clone
619 $ hg -R foo.hg -q log -r "bundle()"
661 $ hg -R foo.hg -q log -r "bundle()"
620 9:b4f5acb1ee27
662 9:b4f5acb1ee27
621
663
622 $ cd ..
664 $ cd ..
623
665
624 test for https://bz.mercurial-scm.org/1144
666 test for https://bz.mercurial-scm.org/1144
625
667
626 test that verify bundle does not traceback
668 test that verify bundle does not traceback
627
669
628 partial history bundle, fails w/ unknown parent
670 partial history bundle, fails w/ unknown parent
629
671
630 $ hg -R bundle.hg verify
672 $ hg -R bundle.hg verify
631 abort: 00changelog.i@bbd179dfa0a7: unknown parent!
673 abort: 00changelog.i@bbd179dfa0a7: unknown parent!
632 [255]
674 [255]
633
675
634 full history bundle, refuses to verify non-local repo
676 full history bundle, refuses to verify non-local repo
635
677
636 $ hg -R all.hg verify
678 $ hg -R all.hg verify
637 abort: cannot verify bundle or remote repos
679 abort: cannot verify bundle or remote repos
638 [255]
680 [255]
639
681
640 but, regular verify must continue to work
682 but, regular verify must continue to work
641
683
642 $ hg -R orig verify
684 $ hg -R orig verify
643 checking changesets
685 checking changesets
644 checking manifests
686 checking manifests
645 crosschecking files in changesets and manifests
687 crosschecking files in changesets and manifests
646 checking files
688 checking files
647 2 files, 2 changesets, 2 total revisions
689 2 files, 2 changesets, 2 total revisions
648
690
649 diff against bundle
691 diff against bundle
650
692
651 $ hg init b
693 $ hg init b
652 $ cd b
694 $ cd b
653 $ hg -R ../all.hg diff -r tip
695 $ hg -R ../all.hg diff -r tip
654 diff -r aa35859c02ea anotherfile
696 diff -r aa35859c02ea anotherfile
655 --- a/anotherfile Thu Jan 01 00:00:00 1970 +0000
697 --- a/anotherfile Thu Jan 01 00:00:00 1970 +0000
656 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
698 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
657 @@ -1,4 +0,0 @@
699 @@ -1,4 +0,0 @@
658 -0
700 -0
659 -1
701 -1
660 -2
702 -2
661 -3
703 -3
662 $ cd ..
704 $ cd ..
663
705
664 bundle single branch
706 bundle single branch
665
707
666 $ hg init branchy
708 $ hg init branchy
667 $ cd branchy
709 $ cd branchy
668 $ echo a >a
710 $ echo a >a
669 $ echo x >x
711 $ echo x >x
670 $ hg ci -Ama
712 $ hg ci -Ama
671 adding a
713 adding a
672 adding x
714 adding x
673 $ echo c >c
715 $ echo c >c
674 $ echo xx >x
716 $ echo xx >x
675 $ hg ci -Amc
717 $ hg ci -Amc
676 adding c
718 adding c
677 $ echo c1 >c1
719 $ echo c1 >c1
678 $ hg ci -Amc1
720 $ hg ci -Amc1
679 adding c1
721 adding c1
680 $ hg up 0
722 $ hg up 0
681 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
723 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
682 $ echo b >b
724 $ echo b >b
683 $ hg ci -Amb
725 $ hg ci -Amb
684 adding b
726 adding b
685 created new head
727 created new head
686 $ echo b1 >b1
728 $ echo b1 >b1
687 $ echo xx >x
729 $ echo xx >x
688 $ hg ci -Amb1
730 $ hg ci -Amb1
689 adding b1
731 adding b1
690 $ hg clone -q -r2 . part
732 $ hg clone -q -r2 . part
691
733
692 == bundling via incoming
734 == bundling via incoming
693
735
694 $ hg in -R part --bundle incoming.hg --template "{node}\n" .
736 $ hg in -R part --bundle incoming.hg --template "{node}\n" .
695 comparing with .
737 comparing with .
696 searching for changes
738 searching for changes
697 1a38c1b849e8b70c756d2d80b0b9a3ac0b7ea11a
739 1a38c1b849e8b70c756d2d80b0b9a3ac0b7ea11a
698 057f4db07f61970e1c11e83be79e9d08adc4dc31
740 057f4db07f61970e1c11e83be79e9d08adc4dc31
699
741
700 == bundling
742 == bundling
701
743
702 $ hg bundle bundle.hg part --debug --config progress.debug=true
744 $ hg bundle bundle.hg part --debug --config progress.debug=true
703 query 1; heads
745 query 1; heads
704 searching for changes
746 searching for changes
705 all remote heads known locally
747 all remote heads known locally
706 2 changesets found
748 2 changesets found
707 list of changesets:
749 list of changesets:
708 1a38c1b849e8b70c756d2d80b0b9a3ac0b7ea11a
750 1a38c1b849e8b70c756d2d80b0b9a3ac0b7ea11a
709 057f4db07f61970e1c11e83be79e9d08adc4dc31
751 057f4db07f61970e1c11e83be79e9d08adc4dc31
710 bundle2-output-bundle: "HG20", (1 params) 1 parts total
752 bundle2-output-bundle: "HG20", (1 params) 1 parts total
711 bundle2-output-part: "changegroup" (params: 1 mandatory 1 advisory) streamed payload
753 bundle2-output-part: "changegroup" (params: 1 mandatory 1 advisory) streamed payload
712 bundling: 1/2 changesets (50.00%)
754 bundling: 1/2 changesets (50.00%)
713 bundling: 2/2 changesets (100.00%)
755 bundling: 2/2 changesets (100.00%)
714 bundling: 1/2 manifests (50.00%)
756 bundling: 1/2 manifests (50.00%)
715 bundling: 2/2 manifests (100.00%)
757 bundling: 2/2 manifests (100.00%)
716 bundling: b 1/3 files (33.33%)
758 bundling: b 1/3 files (33.33%)
717 bundling: b1 2/3 files (66.67%)
759 bundling: b1 2/3 files (66.67%)
718 bundling: x 3/3 files (100.00%)
760 bundling: x 3/3 files (100.00%)
719
761
720 == Test for issue3441
762 == Test for issue3441
721
763
722 $ hg clone -q -r0 . part2
764 $ hg clone -q -r0 . part2
723 $ hg -q -R part2 pull bundle.hg
765 $ hg -q -R part2 pull bundle.hg
724 $ hg -R part2 verify
766 $ hg -R part2 verify
725 checking changesets
767 checking changesets
726 checking manifests
768 checking manifests
727 crosschecking files in changesets and manifests
769 crosschecking files in changesets and manifests
728 checking files
770 checking files
729 4 files, 3 changesets, 5 total revisions
771 4 files, 3 changesets, 5 total revisions
730
772
731 == Test bundling no commits
773 == Test bundling no commits
732
774
733 $ hg bundle -r 'public()' no-output.hg
775 $ hg bundle -r 'public()' no-output.hg
734 abort: no commits to bundle
776 abort: no commits to bundle
735 [255]
777 [255]
736
778
737 $ cd ..
779 $ cd ..
738
780
739 When user merges to the revision existing only in the bundle,
781 When user merges to the revision existing only in the bundle,
740 it should show warning that second parent of the working
782 it should show warning that second parent of the working
741 directory does not exist
783 directory does not exist
742
784
743 $ hg init update2bundled
785 $ hg init update2bundled
744 $ cd update2bundled
786 $ cd update2bundled
745 $ cat <<EOF >> .hg/hgrc
787 $ cat <<EOF >> .hg/hgrc
746 > [extensions]
788 > [extensions]
747 > strip =
789 > strip =
748 > EOF
790 > EOF
749 $ echo "aaa" >> a
791 $ echo "aaa" >> a
750 $ hg commit -A -m 0
792 $ hg commit -A -m 0
751 adding a
793 adding a
752 $ echo "bbb" >> b
794 $ echo "bbb" >> b
753 $ hg commit -A -m 1
795 $ hg commit -A -m 1
754 adding b
796 adding b
755 $ echo "ccc" >> c
797 $ echo "ccc" >> c
756 $ hg commit -A -m 2
798 $ hg commit -A -m 2
757 adding c
799 adding c
758 $ hg update -r 1
800 $ hg update -r 1
759 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
801 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
760 $ echo "ddd" >> d
802 $ echo "ddd" >> d
761 $ hg commit -A -m 3
803 $ hg commit -A -m 3
762 adding d
804 adding d
763 created new head
805 created new head
764 $ hg update -r 2
806 $ hg update -r 2
765 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
807 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
766 $ hg log -G
808 $ hg log -G
767 o changeset: 3:8bd3e1f196af
809 o changeset: 3:8bd3e1f196af
768 | tag: tip
810 | tag: tip
769 | parent: 1:a01eca7af26d
811 | parent: 1:a01eca7af26d
770 | user: test
812 | user: test
771 | date: Thu Jan 01 00:00:00 1970 +0000
813 | date: Thu Jan 01 00:00:00 1970 +0000
772 | summary: 3
814 | summary: 3
773 |
815 |
774 | @ changeset: 2:4652c276ac4f
816 | @ changeset: 2:4652c276ac4f
775 |/ user: test
817 |/ user: test
776 | date: Thu Jan 01 00:00:00 1970 +0000
818 | date: Thu Jan 01 00:00:00 1970 +0000
777 | summary: 2
819 | summary: 2
778 |
820 |
779 o changeset: 1:a01eca7af26d
821 o changeset: 1:a01eca7af26d
780 | user: test
822 | user: test
781 | date: Thu Jan 01 00:00:00 1970 +0000
823 | date: Thu Jan 01 00:00:00 1970 +0000
782 | summary: 1
824 | summary: 1
783 |
825 |
784 o changeset: 0:4fe08cd4693e
826 o changeset: 0:4fe08cd4693e
785 user: test
827 user: test
786 date: Thu Jan 01 00:00:00 1970 +0000
828 date: Thu Jan 01 00:00:00 1970 +0000
787 summary: 0
829 summary: 0
788
830
789 $ hg bundle --base 1 -r 3 ../update2bundled.hg
831 $ hg bundle --base 1 -r 3 ../update2bundled.hg
790 1 changesets found
832 1 changesets found
791 $ hg strip -r 3
833 $ hg strip -r 3
792 saved backup bundle to $TESTTMP/update2bundled/.hg/strip-backup/8bd3e1f196af-017e56d8-backup.hg (glob)
834 saved backup bundle to $TESTTMP/update2bundled/.hg/strip-backup/8bd3e1f196af-017e56d8-backup.hg (glob)
793 $ hg merge -R ../update2bundled.hg -r 3
835 $ hg merge -R ../update2bundled.hg -r 3
794 setting parent to node 8bd3e1f196af289b2b121be08031e76d7ae92098 that only exists in the bundle
836 setting parent to node 8bd3e1f196af289b2b121be08031e76d7ae92098 that only exists in the bundle
795 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
837 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
796 (branch merge, don't forget to commit)
838 (branch merge, don't forget to commit)
797
839
798 When user updates to the revision existing only in the bundle,
840 When user updates to the revision existing only in the bundle,
799 it should show warning
841 it should show warning
800
842
801 $ hg update -R ../update2bundled.hg --clean -r 3
843 $ hg update -R ../update2bundled.hg --clean -r 3
802 setting parent to node 8bd3e1f196af289b2b121be08031e76d7ae92098 that only exists in the bundle
844 setting parent to node 8bd3e1f196af289b2b121be08031e76d7ae92098 that only exists in the bundle
803 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
845 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
804
846
805 When user updates to the revision existing in the local repository
847 When user updates to the revision existing in the local repository
806 the warning shouldn't be emitted
848 the warning shouldn't be emitted
807
849
808 $ hg update -R ../update2bundled.hg -r 0
850 $ hg update -R ../update2bundled.hg -r 0
809 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
851 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
General Comments 0
You need to be logged in to leave comments. Login now