##// END OF EJS Templates
bundle: warn when update to revision existing only in a bundle (issue5004)...
liscju -
r28714:dac81729 default
parent child Browse files
Show More
@@ -1,531 +1,542 b''
1 # bundlerepo.py - repository class for viewing uncompressed bundles
1 # bundlerepo.py - repository class for viewing uncompressed bundles
2 #
2 #
3 # Copyright 2006, 2007 Benoit Boissinot <bboissin@gmail.com>
3 # Copyright 2006, 2007 Benoit Boissinot <bboissin@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 """Repository class for viewing uncompressed bundles.
8 """Repository class for viewing uncompressed bundles.
9
9
10 This provides a read-only repository interface to bundles as if they
10 This provides a read-only repository interface to bundles as if they
11 were part of the actual repository.
11 were part of the actual repository.
12 """
12 """
13
13
14 from __future__ import absolute_import
14 from __future__ import absolute_import
15
15
16 import os
16 import os
17 import shutil
17 import shutil
18 import tempfile
18 import tempfile
19
19
20 from .i18n import _
20 from .i18n import _
21 from .node import nullid
21 from .node import nullid
22
22
23 from . import (
23 from . import (
24 bundle2,
24 bundle2,
25 changegroup,
25 changegroup,
26 changelog,
26 changelog,
27 cmdutil,
27 cmdutil,
28 discovery,
28 discovery,
29 error,
29 error,
30 exchange,
30 exchange,
31 filelog,
31 filelog,
32 localrepo,
32 localrepo,
33 manifest,
33 manifest,
34 mdiff,
34 mdiff,
35 node as nodemod,
35 pathutil,
36 pathutil,
36 phases,
37 phases,
37 revlog,
38 revlog,
38 scmutil,
39 scmutil,
39 util,
40 util,
40 )
41 )
41
42
42 class bundlerevlog(revlog.revlog):
43 class bundlerevlog(revlog.revlog):
43 def __init__(self, opener, indexfile, bundle, linkmapper):
44 def __init__(self, opener, indexfile, bundle, linkmapper):
44 # How it works:
45 # How it works:
45 # To retrieve a revision, we need to know the offset of the revision in
46 # To retrieve a revision, we need to know the offset of the revision in
46 # the bundle (an unbundle object). We store this offset in the index
47 # the bundle (an unbundle object). We store this offset in the index
47 # (start). The base of the delta is stored in the base field.
48 # (start). The base of the delta is stored in the base field.
48 #
49 #
49 # To differentiate a rev in the bundle from a rev in the revlog, we
50 # To differentiate a rev in the bundle from a rev in the revlog, we
50 # check revision against repotiprev.
51 # check revision against repotiprev.
51 opener = scmutil.readonlyvfs(opener)
52 opener = scmutil.readonlyvfs(opener)
52 revlog.revlog.__init__(self, opener, indexfile)
53 revlog.revlog.__init__(self, opener, indexfile)
53 self.bundle = bundle
54 self.bundle = bundle
54 n = len(self)
55 n = len(self)
55 self.repotiprev = n - 1
56 self.repotiprev = n - 1
56 chain = None
57 chain = None
57 self.bundlerevs = set() # used by 'bundle()' revset expression
58 self.bundlerevs = set() # used by 'bundle()' revset expression
58 while True:
59 while True:
59 chunkdata = bundle.deltachunk(chain)
60 chunkdata = bundle.deltachunk(chain)
60 if not chunkdata:
61 if not chunkdata:
61 break
62 break
62 node = chunkdata['node']
63 node = chunkdata['node']
63 p1 = chunkdata['p1']
64 p1 = chunkdata['p1']
64 p2 = chunkdata['p2']
65 p2 = chunkdata['p2']
65 cs = chunkdata['cs']
66 cs = chunkdata['cs']
66 deltabase = chunkdata['deltabase']
67 deltabase = chunkdata['deltabase']
67 delta = chunkdata['delta']
68 delta = chunkdata['delta']
68
69
69 size = len(delta)
70 size = len(delta)
70 start = bundle.tell() - size
71 start = bundle.tell() - size
71
72
72 link = linkmapper(cs)
73 link = linkmapper(cs)
73 if node in self.nodemap:
74 if node in self.nodemap:
74 # this can happen if two branches make the same change
75 # this can happen if two branches make the same change
75 chain = node
76 chain = node
76 self.bundlerevs.add(self.nodemap[node])
77 self.bundlerevs.add(self.nodemap[node])
77 continue
78 continue
78
79
79 for p in (p1, p2):
80 for p in (p1, p2):
80 if p not in self.nodemap:
81 if p not in self.nodemap:
81 raise error.LookupError(p, self.indexfile,
82 raise error.LookupError(p, self.indexfile,
82 _("unknown parent"))
83 _("unknown parent"))
83
84
84 if deltabase not in self.nodemap:
85 if deltabase not in self.nodemap:
85 raise LookupError(deltabase, self.indexfile,
86 raise LookupError(deltabase, self.indexfile,
86 _('unknown delta base'))
87 _('unknown delta base'))
87
88
88 baserev = self.rev(deltabase)
89 baserev = self.rev(deltabase)
89 # start, size, full unc. size, base (unused), link, p1, p2, node
90 # start, size, full unc. size, base (unused), link, p1, p2, node
90 e = (revlog.offset_type(start, 0), size, -1, baserev, link,
91 e = (revlog.offset_type(start, 0), size, -1, baserev, link,
91 self.rev(p1), self.rev(p2), node)
92 self.rev(p1), self.rev(p2), node)
92 self.index.insert(-1, e)
93 self.index.insert(-1, e)
93 self.nodemap[node] = n
94 self.nodemap[node] = n
94 self.bundlerevs.add(n)
95 self.bundlerevs.add(n)
95 chain = node
96 chain = node
96 n += 1
97 n += 1
97
98
98 def _chunk(self, rev):
99 def _chunk(self, rev):
99 # Warning: in case of bundle, the diff is against what we stored as
100 # Warning: in case of bundle, the diff is against what we stored as
100 # delta base, not against rev - 1
101 # delta base, not against rev - 1
101 # XXX: could use some caching
102 # XXX: could use some caching
102 if rev <= self.repotiprev:
103 if rev <= self.repotiprev:
103 return revlog.revlog._chunk(self, rev)
104 return revlog.revlog._chunk(self, rev)
104 self.bundle.seek(self.start(rev))
105 self.bundle.seek(self.start(rev))
105 return self.bundle.read(self.length(rev))
106 return self.bundle.read(self.length(rev))
106
107
107 def revdiff(self, rev1, rev2):
108 def revdiff(self, rev1, rev2):
108 """return or calculate a delta between two revisions"""
109 """return or calculate a delta between two revisions"""
109 if rev1 > self.repotiprev and rev2 > self.repotiprev:
110 if rev1 > self.repotiprev and rev2 > self.repotiprev:
110 # hot path for bundle
111 # hot path for bundle
111 revb = self.index[rev2][3]
112 revb = self.index[rev2][3]
112 if revb == rev1:
113 if revb == rev1:
113 return self._chunk(rev2)
114 return self._chunk(rev2)
114 elif rev1 <= self.repotiprev and rev2 <= self.repotiprev:
115 elif rev1 <= self.repotiprev and rev2 <= self.repotiprev:
115 return revlog.revlog.revdiff(self, rev1, rev2)
116 return revlog.revlog.revdiff(self, rev1, rev2)
116
117
117 return mdiff.textdiff(self.revision(self.node(rev1)),
118 return mdiff.textdiff(self.revision(self.node(rev1)),
118 self.revision(self.node(rev2)))
119 self.revision(self.node(rev2)))
119
120
120 def revision(self, nodeorrev):
121 def revision(self, nodeorrev):
121 """return an uncompressed revision of a given node or revision
122 """return an uncompressed revision of a given node or revision
122 number.
123 number.
123 """
124 """
124 if isinstance(nodeorrev, int):
125 if isinstance(nodeorrev, int):
125 rev = nodeorrev
126 rev = nodeorrev
126 node = self.node(rev)
127 node = self.node(rev)
127 else:
128 else:
128 node = nodeorrev
129 node = nodeorrev
129 rev = self.rev(node)
130 rev = self.rev(node)
130
131
131 if node == nullid:
132 if node == nullid:
132 return ""
133 return ""
133
134
134 text = None
135 text = None
135 chain = []
136 chain = []
136 iterrev = rev
137 iterrev = rev
137 # reconstruct the revision if it is from a changegroup
138 # reconstruct the revision if it is from a changegroup
138 while iterrev > self.repotiprev:
139 while iterrev > self.repotiprev:
139 if self._cache and self._cache[1] == iterrev:
140 if self._cache and self._cache[1] == iterrev:
140 text = self._cache[2]
141 text = self._cache[2]
141 break
142 break
142 chain.append(iterrev)
143 chain.append(iterrev)
143 iterrev = self.index[iterrev][3]
144 iterrev = self.index[iterrev][3]
144 if text is None:
145 if text is None:
145 text = self.baserevision(iterrev)
146 text = self.baserevision(iterrev)
146
147
147 while chain:
148 while chain:
148 delta = self._chunk(chain.pop())
149 delta = self._chunk(chain.pop())
149 text = mdiff.patches(text, [delta])
150 text = mdiff.patches(text, [delta])
150
151
151 self._checkhash(text, node, rev)
152 self._checkhash(text, node, rev)
152 self._cache = (node, rev, text)
153 self._cache = (node, rev, text)
153 return text
154 return text
154
155
155 def baserevision(self, nodeorrev):
156 def baserevision(self, nodeorrev):
156 # Revlog subclasses may override 'revision' method to modify format of
157 # Revlog subclasses may override 'revision' method to modify format of
157 # content retrieved from revlog. To use bundlerevlog with such class one
158 # content retrieved from revlog. To use bundlerevlog with such class one
158 # needs to override 'baserevision' and make more specific call here.
159 # needs to override 'baserevision' and make more specific call here.
159 return revlog.revlog.revision(self, nodeorrev)
160 return revlog.revlog.revision(self, nodeorrev)
160
161
161 def addrevision(self, text, transaction, link, p1=None, p2=None, d=None):
162 def addrevision(self, text, transaction, link, p1=None, p2=None, d=None):
162 raise NotImplementedError
163 raise NotImplementedError
163 def addgroup(self, revs, linkmapper, transaction):
164 def addgroup(self, revs, linkmapper, transaction):
164 raise NotImplementedError
165 raise NotImplementedError
165 def strip(self, rev, minlink):
166 def strip(self, rev, minlink):
166 raise NotImplementedError
167 raise NotImplementedError
167 def checksize(self):
168 def checksize(self):
168 raise NotImplementedError
169 raise NotImplementedError
169
170
170 class bundlechangelog(bundlerevlog, changelog.changelog):
171 class bundlechangelog(bundlerevlog, changelog.changelog):
171 def __init__(self, opener, bundle):
172 def __init__(self, opener, bundle):
172 changelog.changelog.__init__(self, opener)
173 changelog.changelog.__init__(self, opener)
173 linkmapper = lambda x: x
174 linkmapper = lambda x: x
174 bundlerevlog.__init__(self, opener, self.indexfile, bundle,
175 bundlerevlog.__init__(self, opener, self.indexfile, bundle,
175 linkmapper)
176 linkmapper)
176
177
177 def baserevision(self, nodeorrev):
178 def baserevision(self, nodeorrev):
178 # Although changelog doesn't override 'revision' method, some extensions
179 # Although changelog doesn't override 'revision' method, some extensions
179 # may replace this class with another that does. Same story with
180 # may replace this class with another that does. Same story with
180 # manifest and filelog classes.
181 # manifest and filelog classes.
181
182
182 # This bypasses filtering on changelog.node() and rev() because we need
183 # This bypasses filtering on changelog.node() and rev() because we need
183 # revision text of the bundle base even if it is hidden.
184 # revision text of the bundle base even if it is hidden.
184 oldfilter = self.filteredrevs
185 oldfilter = self.filteredrevs
185 try:
186 try:
186 self.filteredrevs = ()
187 self.filteredrevs = ()
187 return changelog.changelog.revision(self, nodeorrev)
188 return changelog.changelog.revision(self, nodeorrev)
188 finally:
189 finally:
189 self.filteredrevs = oldfilter
190 self.filteredrevs = oldfilter
190
191
191 class bundlemanifest(bundlerevlog, manifest.manifest):
192 class bundlemanifest(bundlerevlog, manifest.manifest):
192 def __init__(self, opener, bundle, linkmapper):
193 def __init__(self, opener, bundle, linkmapper):
193 manifest.manifest.__init__(self, opener)
194 manifest.manifest.__init__(self, opener)
194 bundlerevlog.__init__(self, opener, self.indexfile, bundle,
195 bundlerevlog.__init__(self, opener, self.indexfile, bundle,
195 linkmapper)
196 linkmapper)
196
197
197 def baserevision(self, nodeorrev):
198 def baserevision(self, nodeorrev):
198 node = nodeorrev
199 node = nodeorrev
199 if isinstance(node, int):
200 if isinstance(node, int):
200 node = self.node(node)
201 node = self.node(node)
201
202
202 if node in self._mancache:
203 if node in self._mancache:
203 result = self._mancache[node][0].text()
204 result = self._mancache[node][0].text()
204 else:
205 else:
205 result = manifest.manifest.revision(self, nodeorrev)
206 result = manifest.manifest.revision(self, nodeorrev)
206 return result
207 return result
207
208
208 class bundlefilelog(bundlerevlog, filelog.filelog):
209 class bundlefilelog(bundlerevlog, filelog.filelog):
209 def __init__(self, opener, path, bundle, linkmapper):
210 def __init__(self, opener, path, bundle, linkmapper):
210 filelog.filelog.__init__(self, opener, path)
211 filelog.filelog.__init__(self, opener, path)
211 bundlerevlog.__init__(self, opener, self.indexfile, bundle,
212 bundlerevlog.__init__(self, opener, self.indexfile, bundle,
212 linkmapper)
213 linkmapper)
213
214
214 def baserevision(self, nodeorrev):
215 def baserevision(self, nodeorrev):
215 return filelog.filelog.revision(self, nodeorrev)
216 return filelog.filelog.revision(self, nodeorrev)
216
217
217 class bundlepeer(localrepo.localpeer):
218 class bundlepeer(localrepo.localpeer):
218 def canpush(self):
219 def canpush(self):
219 return False
220 return False
220
221
221 class bundlephasecache(phases.phasecache):
222 class bundlephasecache(phases.phasecache):
222 def __init__(self, *args, **kwargs):
223 def __init__(self, *args, **kwargs):
223 super(bundlephasecache, self).__init__(*args, **kwargs)
224 super(bundlephasecache, self).__init__(*args, **kwargs)
224 if util.safehasattr(self, 'opener'):
225 if util.safehasattr(self, 'opener'):
225 self.opener = scmutil.readonlyvfs(self.opener)
226 self.opener = scmutil.readonlyvfs(self.opener)
226
227
227 def write(self):
228 def write(self):
228 raise NotImplementedError
229 raise NotImplementedError
229
230
230 def _write(self, fp):
231 def _write(self, fp):
231 raise NotImplementedError
232 raise NotImplementedError
232
233
233 def _updateroots(self, phase, newroots, tr):
234 def _updateroots(self, phase, newroots, tr):
234 self.phaseroots[phase] = newroots
235 self.phaseroots[phase] = newroots
235 self.invalidate()
236 self.invalidate()
236 self.dirty = True
237 self.dirty = True
237
238
238 class bundlerepository(localrepo.localrepository):
239 class bundlerepository(localrepo.localrepository):
239 def __init__(self, ui, path, bundlename):
240 def __init__(self, ui, path, bundlename):
240 def _writetempbundle(read, suffix, header=''):
241 def _writetempbundle(read, suffix, header=''):
241 """Write a temporary file to disk
242 """Write a temporary file to disk
242
243
243 This is closure because we need to make sure this tracked by
244 This is closure because we need to make sure this tracked by
244 self.tempfile for cleanup purposes."""
245 self.tempfile for cleanup purposes."""
245 fdtemp, temp = self.vfs.mkstemp(prefix="hg-bundle-",
246 fdtemp, temp = self.vfs.mkstemp(prefix="hg-bundle-",
246 suffix=".hg10un")
247 suffix=".hg10un")
247 self.tempfile = temp
248 self.tempfile = temp
248
249
249 with os.fdopen(fdtemp, 'wb') as fptemp:
250 with os.fdopen(fdtemp, 'wb') as fptemp:
250 fptemp.write(header)
251 fptemp.write(header)
251 while True:
252 while True:
252 chunk = read(2**18)
253 chunk = read(2**18)
253 if not chunk:
254 if not chunk:
254 break
255 break
255 fptemp.write(chunk)
256 fptemp.write(chunk)
256
257
257 return self.vfs.open(self.tempfile, mode="rb")
258 return self.vfs.open(self.tempfile, mode="rb")
258 self._tempparent = None
259 self._tempparent = None
259 try:
260 try:
260 localrepo.localrepository.__init__(self, ui, path)
261 localrepo.localrepository.__init__(self, ui, path)
261 except error.RepoError:
262 except error.RepoError:
262 self._tempparent = tempfile.mkdtemp()
263 self._tempparent = tempfile.mkdtemp()
263 localrepo.instance(ui, self._tempparent, 1)
264 localrepo.instance(ui, self._tempparent, 1)
264 localrepo.localrepository.__init__(self, ui, self._tempparent)
265 localrepo.localrepository.__init__(self, ui, self._tempparent)
265 self.ui.setconfig('phases', 'publish', False, 'bundlerepo')
266 self.ui.setconfig('phases', 'publish', False, 'bundlerepo')
266
267
267 if path:
268 if path:
268 self._url = 'bundle:' + util.expandpath(path) + '+' + bundlename
269 self._url = 'bundle:' + util.expandpath(path) + '+' + bundlename
269 else:
270 else:
270 self._url = 'bundle:' + bundlename
271 self._url = 'bundle:' + bundlename
271
272
272 self.tempfile = None
273 self.tempfile = None
273 f = util.posixfile(bundlename, "rb")
274 f = util.posixfile(bundlename, "rb")
274 self.bundlefile = self.bundle = exchange.readbundle(ui, f, bundlename)
275 self.bundlefile = self.bundle = exchange.readbundle(ui, f, bundlename)
275
276
276 if isinstance(self.bundle, bundle2.unbundle20):
277 if isinstance(self.bundle, bundle2.unbundle20):
277 cgstream = None
278 cgstream = None
278 for part in self.bundle.iterparts():
279 for part in self.bundle.iterparts():
279 if part.type == 'changegroup':
280 if part.type == 'changegroup':
280 if cgstream is not None:
281 if cgstream is not None:
281 raise NotImplementedError("can't process "
282 raise NotImplementedError("can't process "
282 "multiple changegroups")
283 "multiple changegroups")
283 cgstream = part
284 cgstream = part
284 version = part.params.get('version', '01')
285 version = part.params.get('version', '01')
285 if version not in changegroup.allsupportedversions(ui):
286 if version not in changegroup.allsupportedversions(ui):
286 msg = _('Unsupported changegroup version: %s')
287 msg = _('Unsupported changegroup version: %s')
287 raise error.Abort(msg % version)
288 raise error.Abort(msg % version)
288 if self.bundle.compressed():
289 if self.bundle.compressed():
289 cgstream = _writetempbundle(part.read,
290 cgstream = _writetempbundle(part.read,
290 ".cg%sun" % version)
291 ".cg%sun" % version)
291
292
292 if cgstream is None:
293 if cgstream is None:
293 raise error.Abort('No changegroups found')
294 raise error.Abort('No changegroups found')
294 cgstream.seek(0)
295 cgstream.seek(0)
295
296
296 self.bundle = changegroup.getunbundler(version, cgstream, 'UN')
297 self.bundle = changegroup.getunbundler(version, cgstream, 'UN')
297
298
298 elif self.bundle.compressed():
299 elif self.bundle.compressed():
299 f = _writetempbundle(self.bundle.read, '.hg10un', header='HG10UN')
300 f = _writetempbundle(self.bundle.read, '.hg10un', header='HG10UN')
300 self.bundlefile = self.bundle = exchange.readbundle(ui, f,
301 self.bundlefile = self.bundle = exchange.readbundle(ui, f,
301 bundlename,
302 bundlename,
302 self.vfs)
303 self.vfs)
303
304
304 # dict with the mapping 'filename' -> position in the bundle
305 # dict with the mapping 'filename' -> position in the bundle
305 self.bundlefilespos = {}
306 self.bundlefilespos = {}
306
307
307 self.firstnewrev = self.changelog.repotiprev + 1
308 self.firstnewrev = self.changelog.repotiprev + 1
308 phases.retractboundary(self, None, phases.draft,
309 phases.retractboundary(self, None, phases.draft,
309 [ctx.node() for ctx in self[self.firstnewrev:]])
310 [ctx.node() for ctx in self[self.firstnewrev:]])
310
311
311 @localrepo.unfilteredpropertycache
312 @localrepo.unfilteredpropertycache
312 def _phasecache(self):
313 def _phasecache(self):
313 return bundlephasecache(self, self._phasedefaults)
314 return bundlephasecache(self, self._phasedefaults)
314
315
315 @localrepo.unfilteredpropertycache
316 @localrepo.unfilteredpropertycache
316 def changelog(self):
317 def changelog(self):
317 # consume the header if it exists
318 # consume the header if it exists
318 self.bundle.changelogheader()
319 self.bundle.changelogheader()
319 c = bundlechangelog(self.svfs, self.bundle)
320 c = bundlechangelog(self.svfs, self.bundle)
320 self.manstart = self.bundle.tell()
321 self.manstart = self.bundle.tell()
321 return c
322 return c
322
323
323 @localrepo.unfilteredpropertycache
324 @localrepo.unfilteredpropertycache
324 def manifest(self):
325 def manifest(self):
325 self.bundle.seek(self.manstart)
326 self.bundle.seek(self.manstart)
326 # consume the header if it exists
327 # consume the header if it exists
327 self.bundle.manifestheader()
328 self.bundle.manifestheader()
328 linkmapper = self.unfiltered().changelog.rev
329 linkmapper = self.unfiltered().changelog.rev
329 m = bundlemanifest(self.svfs, self.bundle, linkmapper)
330 m = bundlemanifest(self.svfs, self.bundle, linkmapper)
330 # XXX: hack to work with changegroup3, but we still don't handle
331 # XXX: hack to work with changegroup3, but we still don't handle
331 # tree manifests correctly
332 # tree manifests correctly
332 if self.bundle.version == "03":
333 if self.bundle.version == "03":
333 self.bundle.filelogheader()
334 self.bundle.filelogheader()
334 self.filestart = self.bundle.tell()
335 self.filestart = self.bundle.tell()
335 return m
336 return m
336
337
337 @localrepo.unfilteredpropertycache
338 @localrepo.unfilteredpropertycache
338 def manstart(self):
339 def manstart(self):
339 self.changelog
340 self.changelog
340 return self.manstart
341 return self.manstart
341
342
342 @localrepo.unfilteredpropertycache
343 @localrepo.unfilteredpropertycache
343 def filestart(self):
344 def filestart(self):
344 self.manifest
345 self.manifest
345 return self.filestart
346 return self.filestart
346
347
347 def url(self):
348 def url(self):
348 return self._url
349 return self._url
349
350
350 def file(self, f):
351 def file(self, f):
351 if not self.bundlefilespos:
352 if not self.bundlefilespos:
352 self.bundle.seek(self.filestart)
353 self.bundle.seek(self.filestart)
353 while True:
354 while True:
354 chunkdata = self.bundle.filelogheader()
355 chunkdata = self.bundle.filelogheader()
355 if not chunkdata:
356 if not chunkdata:
356 break
357 break
357 fname = chunkdata['filename']
358 fname = chunkdata['filename']
358 self.bundlefilespos[fname] = self.bundle.tell()
359 self.bundlefilespos[fname] = self.bundle.tell()
359 while True:
360 while True:
360 c = self.bundle.deltachunk(None)
361 c = self.bundle.deltachunk(None)
361 if not c:
362 if not c:
362 break
363 break
363
364
364 if f in self.bundlefilespos:
365 if f in self.bundlefilespos:
365 self.bundle.seek(self.bundlefilespos[f])
366 self.bundle.seek(self.bundlefilespos[f])
366 linkmapper = self.unfiltered().changelog.rev
367 linkmapper = self.unfiltered().changelog.rev
367 return bundlefilelog(self.svfs, f, self.bundle, linkmapper)
368 return bundlefilelog(self.svfs, f, self.bundle, linkmapper)
368 else:
369 else:
369 return filelog.filelog(self.svfs, f)
370 return filelog.filelog(self.svfs, f)
370
371
371 def close(self):
372 def close(self):
372 """Close assigned bundle file immediately."""
373 """Close assigned bundle file immediately."""
373 self.bundlefile.close()
374 self.bundlefile.close()
374 if self.tempfile is not None:
375 if self.tempfile is not None:
375 self.vfs.unlink(self.tempfile)
376 self.vfs.unlink(self.tempfile)
376 if self._tempparent:
377 if self._tempparent:
377 shutil.rmtree(self._tempparent, True)
378 shutil.rmtree(self._tempparent, True)
378
379
379 def cancopy(self):
380 def cancopy(self):
380 return False
381 return False
381
382
382 def peer(self):
383 def peer(self):
383 return bundlepeer(self)
384 return bundlepeer(self)
384
385
385 def getcwd(self):
386 def getcwd(self):
386 return os.getcwd() # always outside the repo
387 return os.getcwd() # always outside the repo
387
388
389 # Check if parents exist in localrepo before setting
390 def setparents(self, p1, p2=nullid):
391 p1rev = self.changelog.rev(p1)
392 p2rev = self.changelog.rev(p2)
393 msg = _("setting parent to node %s that only exists in the bundle\n")
394 if self.changelog.repotiprev < p1rev:
395 self.ui.warn(msg % nodemod.hex(p1))
396 if self.changelog.repotiprev < p2rev:
397 self.ui.warn(msg % nodemod.hex(p2))
398 return super(bundlerepository, self).setparents(p1, p2)
388
399
389 def instance(ui, path, create):
400 def instance(ui, path, create):
390 if create:
401 if create:
391 raise error.Abort(_('cannot create new bundle repository'))
402 raise error.Abort(_('cannot create new bundle repository'))
392 # internal config: bundle.mainreporoot
403 # internal config: bundle.mainreporoot
393 parentpath = ui.config("bundle", "mainreporoot", "")
404 parentpath = ui.config("bundle", "mainreporoot", "")
394 if not parentpath:
405 if not parentpath:
395 # try to find the correct path to the working directory repo
406 # try to find the correct path to the working directory repo
396 parentpath = cmdutil.findrepo(os.getcwd())
407 parentpath = cmdutil.findrepo(os.getcwd())
397 if parentpath is None:
408 if parentpath is None:
398 parentpath = ''
409 parentpath = ''
399 if parentpath:
410 if parentpath:
400 # Try to make the full path relative so we get a nice, short URL.
411 # Try to make the full path relative so we get a nice, short URL.
401 # In particular, we don't want temp dir names in test outputs.
412 # In particular, we don't want temp dir names in test outputs.
402 cwd = os.getcwd()
413 cwd = os.getcwd()
403 if parentpath == cwd:
414 if parentpath == cwd:
404 parentpath = ''
415 parentpath = ''
405 else:
416 else:
406 cwd = pathutil.normasprefix(cwd)
417 cwd = pathutil.normasprefix(cwd)
407 if parentpath.startswith(cwd):
418 if parentpath.startswith(cwd):
408 parentpath = parentpath[len(cwd):]
419 parentpath = parentpath[len(cwd):]
409 u = util.url(path)
420 u = util.url(path)
410 path = u.localpath()
421 path = u.localpath()
411 if u.scheme == 'bundle':
422 if u.scheme == 'bundle':
412 s = path.split("+", 1)
423 s = path.split("+", 1)
413 if len(s) == 1:
424 if len(s) == 1:
414 repopath, bundlename = parentpath, s[0]
425 repopath, bundlename = parentpath, s[0]
415 else:
426 else:
416 repopath, bundlename = s
427 repopath, bundlename = s
417 else:
428 else:
418 repopath, bundlename = parentpath, path
429 repopath, bundlename = parentpath, path
419 return bundlerepository(ui, repopath, bundlename)
430 return bundlerepository(ui, repopath, bundlename)
420
431
421 class bundletransactionmanager(object):
432 class bundletransactionmanager(object):
422 def transaction(self):
433 def transaction(self):
423 return None
434 return None
424
435
425 def close(self):
436 def close(self):
426 raise NotImplementedError
437 raise NotImplementedError
427
438
428 def release(self):
439 def release(self):
429 raise NotImplementedError
440 raise NotImplementedError
430
441
431 def getremotechanges(ui, repo, other, onlyheads=None, bundlename=None,
442 def getremotechanges(ui, repo, other, onlyheads=None, bundlename=None,
432 force=False):
443 force=False):
433 '''obtains a bundle of changes incoming from other
444 '''obtains a bundle of changes incoming from other
434
445
435 "onlyheads" restricts the returned changes to those reachable from the
446 "onlyheads" restricts the returned changes to those reachable from the
436 specified heads.
447 specified heads.
437 "bundlename", if given, stores the bundle to this file path permanently;
448 "bundlename", if given, stores the bundle to this file path permanently;
438 otherwise it's stored to a temp file and gets deleted again when you call
449 otherwise it's stored to a temp file and gets deleted again when you call
439 the returned "cleanupfn".
450 the returned "cleanupfn".
440 "force" indicates whether to proceed on unrelated repos.
451 "force" indicates whether to proceed on unrelated repos.
441
452
442 Returns a tuple (local, csets, cleanupfn):
453 Returns a tuple (local, csets, cleanupfn):
443
454
444 "local" is a local repo from which to obtain the actual incoming
455 "local" is a local repo from which to obtain the actual incoming
445 changesets; it is a bundlerepo for the obtained bundle when the
456 changesets; it is a bundlerepo for the obtained bundle when the
446 original "other" is remote.
457 original "other" is remote.
447 "csets" lists the incoming changeset node ids.
458 "csets" lists the incoming changeset node ids.
448 "cleanupfn" must be called without arguments when you're done processing
459 "cleanupfn" must be called without arguments when you're done processing
449 the changes; it closes both the original "other" and the one returned
460 the changes; it closes both the original "other" and the one returned
450 here.
461 here.
451 '''
462 '''
452 tmp = discovery.findcommonincoming(repo, other, heads=onlyheads,
463 tmp = discovery.findcommonincoming(repo, other, heads=onlyheads,
453 force=force)
464 force=force)
454 common, incoming, rheads = tmp
465 common, incoming, rheads = tmp
455 if not incoming:
466 if not incoming:
456 try:
467 try:
457 if bundlename:
468 if bundlename:
458 os.unlink(bundlename)
469 os.unlink(bundlename)
459 except OSError:
470 except OSError:
460 pass
471 pass
461 return repo, [], other.close
472 return repo, [], other.close
462
473
463 commonset = set(common)
474 commonset = set(common)
464 rheads = [x for x in rheads if x not in commonset]
475 rheads = [x for x in rheads if x not in commonset]
465
476
466 bundle = None
477 bundle = None
467 bundlerepo = None
478 bundlerepo = None
468 localrepo = other.local()
479 localrepo = other.local()
469 if bundlename or not localrepo:
480 if bundlename or not localrepo:
470 # create a bundle (uncompressed if other repo is not local)
481 # create a bundle (uncompressed if other repo is not local)
471
482
472 canbundle2 = (ui.configbool('experimental', 'bundle2-exp', True)
483 canbundle2 = (ui.configbool('experimental', 'bundle2-exp', True)
473 and other.capable('getbundle')
484 and other.capable('getbundle')
474 and other.capable('bundle2'))
485 and other.capable('bundle2'))
475 if canbundle2:
486 if canbundle2:
476 kwargs = {}
487 kwargs = {}
477 kwargs['common'] = common
488 kwargs['common'] = common
478 kwargs['heads'] = rheads
489 kwargs['heads'] = rheads
479 kwargs['bundlecaps'] = exchange.caps20to10(repo)
490 kwargs['bundlecaps'] = exchange.caps20to10(repo)
480 kwargs['cg'] = True
491 kwargs['cg'] = True
481 b2 = other.getbundle('incoming', **kwargs)
492 b2 = other.getbundle('incoming', **kwargs)
482 fname = bundle = changegroup.writechunks(ui, b2._forwardchunks(),
493 fname = bundle = changegroup.writechunks(ui, b2._forwardchunks(),
483 bundlename)
494 bundlename)
484 else:
495 else:
485 if other.capable('getbundle'):
496 if other.capable('getbundle'):
486 cg = other.getbundle('incoming', common=common, heads=rheads)
497 cg = other.getbundle('incoming', common=common, heads=rheads)
487 elif onlyheads is None and not other.capable('changegroupsubset'):
498 elif onlyheads is None and not other.capable('changegroupsubset'):
488 # compat with older servers when pulling all remote heads
499 # compat with older servers when pulling all remote heads
489 cg = other.changegroup(incoming, "incoming")
500 cg = other.changegroup(incoming, "incoming")
490 rheads = None
501 rheads = None
491 else:
502 else:
492 cg = other.changegroupsubset(incoming, rheads, 'incoming')
503 cg = other.changegroupsubset(incoming, rheads, 'incoming')
493 if localrepo:
504 if localrepo:
494 bundletype = "HG10BZ"
505 bundletype = "HG10BZ"
495 else:
506 else:
496 bundletype = "HG10UN"
507 bundletype = "HG10UN"
497 fname = bundle = bundle2.writebundle(ui, cg, bundlename,
508 fname = bundle = bundle2.writebundle(ui, cg, bundlename,
498 bundletype)
509 bundletype)
499 # keep written bundle?
510 # keep written bundle?
500 if bundlename:
511 if bundlename:
501 bundle = None
512 bundle = None
502 if not localrepo:
513 if not localrepo:
503 # use the created uncompressed bundlerepo
514 # use the created uncompressed bundlerepo
504 localrepo = bundlerepo = bundlerepository(repo.baseui, repo.root,
515 localrepo = bundlerepo = bundlerepository(repo.baseui, repo.root,
505 fname)
516 fname)
506 # this repo contains local and other now, so filter out local again
517 # this repo contains local and other now, so filter out local again
507 common = repo.heads()
518 common = repo.heads()
508 if localrepo:
519 if localrepo:
509 # Part of common may be remotely filtered
520 # Part of common may be remotely filtered
510 # So use an unfiltered version
521 # So use an unfiltered version
511 # The discovery process probably need cleanup to avoid that
522 # The discovery process probably need cleanup to avoid that
512 localrepo = localrepo.unfiltered()
523 localrepo = localrepo.unfiltered()
513
524
514 csets = localrepo.changelog.findmissing(common, rheads)
525 csets = localrepo.changelog.findmissing(common, rheads)
515
526
516 if bundlerepo:
527 if bundlerepo:
517 reponodes = [ctx.node() for ctx in bundlerepo[bundlerepo.firstnewrev:]]
528 reponodes = [ctx.node() for ctx in bundlerepo[bundlerepo.firstnewrev:]]
518 remotephases = other.listkeys('phases')
529 remotephases = other.listkeys('phases')
519
530
520 pullop = exchange.pulloperation(bundlerepo, other, heads=reponodes)
531 pullop = exchange.pulloperation(bundlerepo, other, heads=reponodes)
521 pullop.trmanager = bundletransactionmanager()
532 pullop.trmanager = bundletransactionmanager()
522 exchange._pullapplyphases(pullop, remotephases)
533 exchange._pullapplyphases(pullop, remotephases)
523
534
524 def cleanup():
535 def cleanup():
525 if bundlerepo:
536 if bundlerepo:
526 bundlerepo.close()
537 bundlerepo.close()
527 if bundle:
538 if bundle:
528 os.unlink(bundle)
539 os.unlink(bundle)
529 other.close()
540 other.close()
530
541
531 return (localrepo, csets, cleanup)
542 return (localrepo, csets, cleanup)
@@ -1,735 +1,809 b''
1
1
2 $ cat << EOF >> $HGRCPATH
2 $ cat << EOF >> $HGRCPATH
3 > [format]
3 > [format]
4 > usegeneraldelta=yes
4 > usegeneraldelta=yes
5 > EOF
5 > EOF
6
6
7 Setting up test
7 Setting up test
8
8
9 $ hg init test
9 $ hg init test
10 $ cd test
10 $ cd test
11 $ echo 0 > afile
11 $ echo 0 > afile
12 $ hg add afile
12 $ hg add afile
13 $ hg commit -m "0.0"
13 $ hg commit -m "0.0"
14 $ echo 1 >> afile
14 $ echo 1 >> afile
15 $ hg commit -m "0.1"
15 $ hg commit -m "0.1"
16 $ echo 2 >> afile
16 $ echo 2 >> afile
17 $ hg commit -m "0.2"
17 $ hg commit -m "0.2"
18 $ echo 3 >> afile
18 $ echo 3 >> afile
19 $ hg commit -m "0.3"
19 $ hg commit -m "0.3"
20 $ hg update -C 0
20 $ hg update -C 0
21 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
21 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
22 $ echo 1 >> afile
22 $ echo 1 >> afile
23 $ hg commit -m "1.1"
23 $ hg commit -m "1.1"
24 created new head
24 created new head
25 $ echo 2 >> afile
25 $ echo 2 >> afile
26 $ hg commit -m "1.2"
26 $ hg commit -m "1.2"
27 $ echo "a line" > fred
27 $ echo "a line" > fred
28 $ echo 3 >> afile
28 $ echo 3 >> afile
29 $ hg add fred
29 $ hg add fred
30 $ hg commit -m "1.3"
30 $ hg commit -m "1.3"
31 $ hg mv afile adifferentfile
31 $ hg mv afile adifferentfile
32 $ hg commit -m "1.3m"
32 $ hg commit -m "1.3m"
33 $ hg update -C 3
33 $ hg update -C 3
34 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
34 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
35 $ hg mv afile anotherfile
35 $ hg mv afile anotherfile
36 $ hg commit -m "0.3m"
36 $ hg commit -m "0.3m"
37 $ hg verify
37 $ hg verify
38 checking changesets
38 checking changesets
39 checking manifests
39 checking manifests
40 crosschecking files in changesets and manifests
40 crosschecking files in changesets and manifests
41 checking files
41 checking files
42 4 files, 9 changesets, 7 total revisions
42 4 files, 9 changesets, 7 total revisions
43 $ cd ..
43 $ cd ..
44 $ hg init empty
44 $ hg init empty
45
45
46 Bundle and phase
46 Bundle and phase
47
47
48 $ hg -R test phase --force --secret 0
48 $ hg -R test phase --force --secret 0
49 $ hg -R test bundle phase.hg empty
49 $ hg -R test bundle phase.hg empty
50 searching for changes
50 searching for changes
51 no changes found (ignored 9 secret changesets)
51 no changes found (ignored 9 secret changesets)
52 [1]
52 [1]
53 $ hg -R test phase --draft -r 'head()'
53 $ hg -R test phase --draft -r 'head()'
54
54
55 Bundle --all
55 Bundle --all
56
56
57 $ hg -R test bundle --all all.hg
57 $ hg -R test bundle --all all.hg
58 9 changesets found
58 9 changesets found
59
59
60 Bundle test to full.hg
60 Bundle test to full.hg
61
61
62 $ hg -R test bundle full.hg empty
62 $ hg -R test bundle full.hg empty
63 searching for changes
63 searching for changes
64 9 changesets found
64 9 changesets found
65
65
66 Unbundle full.hg in test
66 Unbundle full.hg in test
67
67
68 $ hg -R test unbundle full.hg
68 $ hg -R test unbundle full.hg
69 adding changesets
69 adding changesets
70 adding manifests
70 adding manifests
71 adding file changes
71 adding file changes
72 added 0 changesets with 0 changes to 4 files
72 added 0 changesets with 0 changes to 4 files
73 (run 'hg update' to get a working copy)
73 (run 'hg update' to get a working copy)
74
74
75 Verify empty
75 Verify empty
76
76
77 $ hg -R empty heads
77 $ hg -R empty heads
78 [1]
78 [1]
79 $ hg -R empty verify
79 $ hg -R empty verify
80 checking changesets
80 checking changesets
81 checking manifests
81 checking manifests
82 crosschecking files in changesets and manifests
82 crosschecking files in changesets and manifests
83 checking files
83 checking files
84 0 files, 0 changesets, 0 total revisions
84 0 files, 0 changesets, 0 total revisions
85
85
86 Pull full.hg into test (using --cwd)
86 Pull full.hg into test (using --cwd)
87
87
88 $ hg --cwd test pull ../full.hg
88 $ hg --cwd test pull ../full.hg
89 pulling from ../full.hg
89 pulling from ../full.hg
90 searching for changes
90 searching for changes
91 no changes found
91 no changes found
92
92
93 Verify that there are no leaked temporary files after pull (issue2797)
93 Verify that there are no leaked temporary files after pull (issue2797)
94
94
95 $ ls test/.hg | grep .hg10un
95 $ ls test/.hg | grep .hg10un
96 [1]
96 [1]
97
97
98 Pull full.hg into empty (using --cwd)
98 Pull full.hg into empty (using --cwd)
99
99
100 $ hg --cwd empty pull ../full.hg
100 $ hg --cwd empty pull ../full.hg
101 pulling from ../full.hg
101 pulling from ../full.hg
102 requesting all changes
102 requesting all changes
103 adding changesets
103 adding changesets
104 adding manifests
104 adding manifests
105 adding file changes
105 adding file changes
106 added 9 changesets with 7 changes to 4 files (+1 heads)
106 added 9 changesets with 7 changes to 4 files (+1 heads)
107 (run 'hg heads' to see heads, 'hg merge' to merge)
107 (run 'hg heads' to see heads, 'hg merge' to merge)
108
108
109 Rollback empty
109 Rollback empty
110
110
111 $ hg -R empty rollback
111 $ hg -R empty rollback
112 repository tip rolled back to revision -1 (undo pull)
112 repository tip rolled back to revision -1 (undo pull)
113
113
114 Pull full.hg into empty again (using --cwd)
114 Pull full.hg into empty again (using --cwd)
115
115
116 $ hg --cwd empty pull ../full.hg
116 $ hg --cwd empty pull ../full.hg
117 pulling from ../full.hg
117 pulling from ../full.hg
118 requesting all changes
118 requesting all changes
119 adding changesets
119 adding changesets
120 adding manifests
120 adding manifests
121 adding file changes
121 adding file changes
122 added 9 changesets with 7 changes to 4 files (+1 heads)
122 added 9 changesets with 7 changes to 4 files (+1 heads)
123 (run 'hg heads' to see heads, 'hg merge' to merge)
123 (run 'hg heads' to see heads, 'hg merge' to merge)
124
124
125 Pull full.hg into test (using -R)
125 Pull full.hg into test (using -R)
126
126
127 $ hg -R test pull full.hg
127 $ hg -R test pull full.hg
128 pulling from full.hg
128 pulling from full.hg
129 searching for changes
129 searching for changes
130 no changes found
130 no changes found
131
131
132 Pull full.hg into empty (using -R)
132 Pull full.hg into empty (using -R)
133
133
134 $ hg -R empty pull full.hg
134 $ hg -R empty pull full.hg
135 pulling from full.hg
135 pulling from full.hg
136 searching for changes
136 searching for changes
137 no changes found
137 no changes found
138
138
139 Rollback empty
139 Rollback empty
140
140
141 $ hg -R empty rollback
141 $ hg -R empty rollback
142 repository tip rolled back to revision -1 (undo pull)
142 repository tip rolled back to revision -1 (undo pull)
143
143
144 Pull full.hg into empty again (using -R)
144 Pull full.hg into empty again (using -R)
145
145
146 $ hg -R empty pull full.hg
146 $ hg -R empty pull full.hg
147 pulling from full.hg
147 pulling from full.hg
148 requesting all changes
148 requesting all changes
149 adding changesets
149 adding changesets
150 adding manifests
150 adding manifests
151 adding file changes
151 adding file changes
152 added 9 changesets with 7 changes to 4 files (+1 heads)
152 added 9 changesets with 7 changes to 4 files (+1 heads)
153 (run 'hg heads' to see heads, 'hg merge' to merge)
153 (run 'hg heads' to see heads, 'hg merge' to merge)
154
154
155 Log -R full.hg in fresh empty
155 Log -R full.hg in fresh empty
156
156
157 $ rm -r empty
157 $ rm -r empty
158 $ hg init empty
158 $ hg init empty
159 $ cd empty
159 $ cd empty
160 $ hg -R bundle://../full.hg log
160 $ hg -R bundle://../full.hg log
161 changeset: 8:aa35859c02ea
161 changeset: 8:aa35859c02ea
162 tag: tip
162 tag: tip
163 parent: 3:eebf5a27f8ca
163 parent: 3:eebf5a27f8ca
164 user: test
164 user: test
165 date: Thu Jan 01 00:00:00 1970 +0000
165 date: Thu Jan 01 00:00:00 1970 +0000
166 summary: 0.3m
166 summary: 0.3m
167
167
168 changeset: 7:a6a34bfa0076
168 changeset: 7:a6a34bfa0076
169 user: test
169 user: test
170 date: Thu Jan 01 00:00:00 1970 +0000
170 date: Thu Jan 01 00:00:00 1970 +0000
171 summary: 1.3m
171 summary: 1.3m
172
172
173 changeset: 6:7373c1169842
173 changeset: 6:7373c1169842
174 user: test
174 user: test
175 date: Thu Jan 01 00:00:00 1970 +0000
175 date: Thu Jan 01 00:00:00 1970 +0000
176 summary: 1.3
176 summary: 1.3
177
177
178 changeset: 5:1bb50a9436a7
178 changeset: 5:1bb50a9436a7
179 user: test
179 user: test
180 date: Thu Jan 01 00:00:00 1970 +0000
180 date: Thu Jan 01 00:00:00 1970 +0000
181 summary: 1.2
181 summary: 1.2
182
182
183 changeset: 4:095197eb4973
183 changeset: 4:095197eb4973
184 parent: 0:f9ee2f85a263
184 parent: 0:f9ee2f85a263
185 user: test
185 user: test
186 date: Thu Jan 01 00:00:00 1970 +0000
186 date: Thu Jan 01 00:00:00 1970 +0000
187 summary: 1.1
187 summary: 1.1
188
188
189 changeset: 3:eebf5a27f8ca
189 changeset: 3:eebf5a27f8ca
190 user: test
190 user: test
191 date: Thu Jan 01 00:00:00 1970 +0000
191 date: Thu Jan 01 00:00:00 1970 +0000
192 summary: 0.3
192 summary: 0.3
193
193
194 changeset: 2:e38ba6f5b7e0
194 changeset: 2:e38ba6f5b7e0
195 user: test
195 user: test
196 date: Thu Jan 01 00:00:00 1970 +0000
196 date: Thu Jan 01 00:00:00 1970 +0000
197 summary: 0.2
197 summary: 0.2
198
198
199 changeset: 1:34c2bf6b0626
199 changeset: 1:34c2bf6b0626
200 user: test
200 user: test
201 date: Thu Jan 01 00:00:00 1970 +0000
201 date: Thu Jan 01 00:00:00 1970 +0000
202 summary: 0.1
202 summary: 0.1
203
203
204 changeset: 0:f9ee2f85a263
204 changeset: 0:f9ee2f85a263
205 user: test
205 user: test
206 date: Thu Jan 01 00:00:00 1970 +0000
206 date: Thu Jan 01 00:00:00 1970 +0000
207 summary: 0.0
207 summary: 0.0
208
208
209 Make sure bundlerepo doesn't leak tempfiles (issue2491)
209 Make sure bundlerepo doesn't leak tempfiles (issue2491)
210
210
211 $ ls .hg
211 $ ls .hg
212 00changelog.i
212 00changelog.i
213 cache
213 cache
214 requires
214 requires
215 store
215 store
216
216
217 Pull ../full.hg into empty (with hook)
217 Pull ../full.hg into empty (with hook)
218
218
219 $ echo "[hooks]" >> .hg/hgrc
219 $ echo "[hooks]" >> .hg/hgrc
220 $ echo "changegroup = printenv.py changegroup" >> .hg/hgrc
220 $ echo "changegroup = printenv.py changegroup" >> .hg/hgrc
221
221
222 doesn't work (yet ?)
222 doesn't work (yet ?)
223
223
224 hg -R bundle://../full.hg verify
224 hg -R bundle://../full.hg verify
225
225
226 $ hg pull bundle://../full.hg
226 $ hg pull bundle://../full.hg
227 pulling from bundle:../full.hg
227 pulling from bundle:../full.hg
228 requesting all changes
228 requesting all changes
229 adding changesets
229 adding changesets
230 adding manifests
230 adding manifests
231 adding file changes
231 adding file changes
232 added 9 changesets with 7 changes to 4 files (+1 heads)
232 added 9 changesets with 7 changes to 4 files (+1 heads)
233 changegroup hook: HG_NODE=f9ee2f85a263049e9ae6d37a0e67e96194ffb735 HG_NODE_LAST=aa35859c02ea8bd48da5da68cd2740ac71afcbaf HG_SOURCE=pull HG_TXNID=TXN:* HG_URL=bundle:../full.hg (glob)
233 changegroup hook: HG_NODE=f9ee2f85a263049e9ae6d37a0e67e96194ffb735 HG_NODE_LAST=aa35859c02ea8bd48da5da68cd2740ac71afcbaf HG_SOURCE=pull HG_TXNID=TXN:* HG_URL=bundle:../full.hg (glob)
234 (run 'hg heads' to see heads, 'hg merge' to merge)
234 (run 'hg heads' to see heads, 'hg merge' to merge)
235
235
236 Rollback empty
236 Rollback empty
237
237
238 $ hg rollback
238 $ hg rollback
239 repository tip rolled back to revision -1 (undo pull)
239 repository tip rolled back to revision -1 (undo pull)
240 $ cd ..
240 $ cd ..
241
241
242 Log -R bundle:empty+full.hg
242 Log -R bundle:empty+full.hg
243
243
244 $ hg -R bundle:empty+full.hg log --template="{rev} "; echo ""
244 $ hg -R bundle:empty+full.hg log --template="{rev} "; echo ""
245 8 7 6 5 4 3 2 1 0
245 8 7 6 5 4 3 2 1 0
246
246
247 Pull full.hg into empty again (using -R; with hook)
247 Pull full.hg into empty again (using -R; with hook)
248
248
249 $ hg -R empty pull full.hg
249 $ hg -R empty pull full.hg
250 pulling from full.hg
250 pulling from full.hg
251 requesting all changes
251 requesting all changes
252 adding changesets
252 adding changesets
253 adding manifests
253 adding manifests
254 adding file changes
254 adding file changes
255 added 9 changesets with 7 changes to 4 files (+1 heads)
255 added 9 changesets with 7 changes to 4 files (+1 heads)
256 changegroup hook: HG_NODE=f9ee2f85a263049e9ae6d37a0e67e96194ffb735 HG_NODE_LAST=aa35859c02ea8bd48da5da68cd2740ac71afcbaf HG_SOURCE=pull HG_TXNID=TXN:* HG_URL=bundle:empty+full.hg (glob)
256 changegroup hook: HG_NODE=f9ee2f85a263049e9ae6d37a0e67e96194ffb735 HG_NODE_LAST=aa35859c02ea8bd48da5da68cd2740ac71afcbaf HG_SOURCE=pull HG_TXNID=TXN:* HG_URL=bundle:empty+full.hg (glob)
257 (run 'hg heads' to see heads, 'hg merge' to merge)
257 (run 'hg heads' to see heads, 'hg merge' to merge)
258
258
259 Cannot produce streaming clone bundles with "hg bundle"
259 Cannot produce streaming clone bundles with "hg bundle"
260
260
261 $ hg -R test bundle -t packed1 packed.hg
261 $ hg -R test bundle -t packed1 packed.hg
262 abort: packed bundles cannot be produced by "hg bundle"
262 abort: packed bundles cannot be produced by "hg bundle"
263 (use "hg debugcreatestreamclonebundle")
263 (use "hg debugcreatestreamclonebundle")
264 [255]
264 [255]
265
265
266 packed1 is produced properly
266 packed1 is produced properly
267
267
268 $ hg -R test debugcreatestreamclonebundle packed.hg
268 $ hg -R test debugcreatestreamclonebundle packed.hg
269 writing 2663 bytes for 6 files
269 writing 2663 bytes for 6 files
270 bundle requirements: generaldelta, revlogv1
270 bundle requirements: generaldelta, revlogv1
271
271
272 $ f -B 64 --size --sha1 --hexdump packed.hg
272 $ f -B 64 --size --sha1 --hexdump packed.hg
273 packed.hg: size=2826, sha1=e139f97692a142b19cdcff64a69697d5307ce6d4
273 packed.hg: size=2826, sha1=e139f97692a142b19cdcff64a69697d5307ce6d4
274 0000: 48 47 53 31 55 4e 00 00 00 00 00 00 00 06 00 00 |HGS1UN..........|
274 0000: 48 47 53 31 55 4e 00 00 00 00 00 00 00 06 00 00 |HGS1UN..........|
275 0010: 00 00 00 00 0a 67 00 16 67 65 6e 65 72 61 6c 64 |.....g..generald|
275 0010: 00 00 00 00 0a 67 00 16 67 65 6e 65 72 61 6c 64 |.....g..generald|
276 0020: 65 6c 74 61 2c 72 65 76 6c 6f 67 76 31 00 64 61 |elta,revlogv1.da|
276 0020: 65 6c 74 61 2c 72 65 76 6c 6f 67 76 31 00 64 61 |elta,revlogv1.da|
277 0030: 74 61 2f 61 64 69 66 66 65 72 65 6e 74 66 69 6c |ta/adifferentfil|
277 0030: 74 61 2f 61 64 69 66 66 65 72 65 6e 74 66 69 6c |ta/adifferentfil|
278
278
279 $ hg debugbundle --spec packed.hg
279 $ hg debugbundle --spec packed.hg
280 none-packed1;requirements%3Dgeneraldelta%2Crevlogv1
280 none-packed1;requirements%3Dgeneraldelta%2Crevlogv1
281
281
282 generaldelta requirement is listed in stream clone bundles
282 generaldelta requirement is listed in stream clone bundles
283
283
284 $ hg --config format.generaldelta=true init testgd
284 $ hg --config format.generaldelta=true init testgd
285 $ cd testgd
285 $ cd testgd
286 $ touch foo
286 $ touch foo
287 $ hg -q commit -A -m initial
287 $ hg -q commit -A -m initial
288 $ cd ..
288 $ cd ..
289 $ hg -R testgd debugcreatestreamclonebundle packedgd.hg
289 $ hg -R testgd debugcreatestreamclonebundle packedgd.hg
290 writing 301 bytes for 3 files
290 writing 301 bytes for 3 files
291 bundle requirements: generaldelta, revlogv1
291 bundle requirements: generaldelta, revlogv1
292
292
293 $ f -B 64 --size --sha1 --hexdump packedgd.hg
293 $ f -B 64 --size --sha1 --hexdump packedgd.hg
294 packedgd.hg: size=396, sha1=981f9e589799335304a5a9a44caa3623a48d2a9f
294 packedgd.hg: size=396, sha1=981f9e589799335304a5a9a44caa3623a48d2a9f
295 0000: 48 47 53 31 55 4e 00 00 00 00 00 00 00 03 00 00 |HGS1UN..........|
295 0000: 48 47 53 31 55 4e 00 00 00 00 00 00 00 03 00 00 |HGS1UN..........|
296 0010: 00 00 00 00 01 2d 00 16 67 65 6e 65 72 61 6c 64 |.....-..generald|
296 0010: 00 00 00 00 01 2d 00 16 67 65 6e 65 72 61 6c 64 |.....-..generald|
297 0020: 65 6c 74 61 2c 72 65 76 6c 6f 67 76 31 00 64 61 |elta,revlogv1.da|
297 0020: 65 6c 74 61 2c 72 65 76 6c 6f 67 76 31 00 64 61 |elta,revlogv1.da|
298 0030: 74 61 2f 66 6f 6f 2e 69 00 36 34 0a 00 03 00 01 |ta/foo.i.64.....|
298 0030: 74 61 2f 66 6f 6f 2e 69 00 36 34 0a 00 03 00 01 |ta/foo.i.64.....|
299
299
300 $ hg debugbundle --spec packedgd.hg
300 $ hg debugbundle --spec packedgd.hg
301 none-packed1;requirements%3Dgeneraldelta%2Crevlogv1
301 none-packed1;requirements%3Dgeneraldelta%2Crevlogv1
302
302
303 Unpacking packed1 bundles with "hg unbundle" isn't allowed
303 Unpacking packed1 bundles with "hg unbundle" isn't allowed
304
304
305 $ hg init packed
305 $ hg init packed
306 $ hg -R packed unbundle packed.hg
306 $ hg -R packed unbundle packed.hg
307 abort: packed bundles cannot be applied with "hg unbundle"
307 abort: packed bundles cannot be applied with "hg unbundle"
308 (use "hg debugapplystreamclonebundle")
308 (use "hg debugapplystreamclonebundle")
309 [255]
309 [255]
310
310
311 packed1 can be consumed from debug command
311 packed1 can be consumed from debug command
312
312
313 $ hg -R packed debugapplystreamclonebundle packed.hg
313 $ hg -R packed debugapplystreamclonebundle packed.hg
314 6 files to transfer, 2.60 KB of data
314 6 files to transfer, 2.60 KB of data
315 transferred 2.60 KB in *.* seconds (* */sec) (glob)
315 transferred 2.60 KB in *.* seconds (* */sec) (glob)
316
316
317 Does not work on non-empty repo
317 Does not work on non-empty repo
318
318
319 $ hg -R packed debugapplystreamclonebundle packed.hg
319 $ hg -R packed debugapplystreamclonebundle packed.hg
320 abort: cannot apply stream clone bundle on non-empty repo
320 abort: cannot apply stream clone bundle on non-empty repo
321 [255]
321 [255]
322
322
323 Create partial clones
323 Create partial clones
324
324
325 $ rm -r empty
325 $ rm -r empty
326 $ hg init empty
326 $ hg init empty
327 $ hg clone -r 3 test partial
327 $ hg clone -r 3 test partial
328 adding changesets
328 adding changesets
329 adding manifests
329 adding manifests
330 adding file changes
330 adding file changes
331 added 4 changesets with 4 changes to 1 files
331 added 4 changesets with 4 changes to 1 files
332 updating to branch default
332 updating to branch default
333 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
333 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
334 $ hg clone partial partial2
334 $ hg clone partial partial2
335 updating to branch default
335 updating to branch default
336 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
336 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
337 $ cd partial
337 $ cd partial
338
338
339 Log -R full.hg in partial
339 Log -R full.hg in partial
340
340
341 $ hg -R bundle://../full.hg log -T phases
341 $ hg -R bundle://../full.hg log -T phases
342 changeset: 8:aa35859c02ea
342 changeset: 8:aa35859c02ea
343 tag: tip
343 tag: tip
344 phase: draft
344 phase: draft
345 parent: 3:eebf5a27f8ca
345 parent: 3:eebf5a27f8ca
346 user: test
346 user: test
347 date: Thu Jan 01 00:00:00 1970 +0000
347 date: Thu Jan 01 00:00:00 1970 +0000
348 summary: 0.3m
348 summary: 0.3m
349
349
350 changeset: 7:a6a34bfa0076
350 changeset: 7:a6a34bfa0076
351 phase: draft
351 phase: draft
352 user: test
352 user: test
353 date: Thu Jan 01 00:00:00 1970 +0000
353 date: Thu Jan 01 00:00:00 1970 +0000
354 summary: 1.3m
354 summary: 1.3m
355
355
356 changeset: 6:7373c1169842
356 changeset: 6:7373c1169842
357 phase: draft
357 phase: draft
358 user: test
358 user: test
359 date: Thu Jan 01 00:00:00 1970 +0000
359 date: Thu Jan 01 00:00:00 1970 +0000
360 summary: 1.3
360 summary: 1.3
361
361
362 changeset: 5:1bb50a9436a7
362 changeset: 5:1bb50a9436a7
363 phase: draft
363 phase: draft
364 user: test
364 user: test
365 date: Thu Jan 01 00:00:00 1970 +0000
365 date: Thu Jan 01 00:00:00 1970 +0000
366 summary: 1.2
366 summary: 1.2
367
367
368 changeset: 4:095197eb4973
368 changeset: 4:095197eb4973
369 phase: draft
369 phase: draft
370 parent: 0:f9ee2f85a263
370 parent: 0:f9ee2f85a263
371 user: test
371 user: test
372 date: Thu Jan 01 00:00:00 1970 +0000
372 date: Thu Jan 01 00:00:00 1970 +0000
373 summary: 1.1
373 summary: 1.1
374
374
375 changeset: 3:eebf5a27f8ca
375 changeset: 3:eebf5a27f8ca
376 phase: public
376 phase: public
377 user: test
377 user: test
378 date: Thu Jan 01 00:00:00 1970 +0000
378 date: Thu Jan 01 00:00:00 1970 +0000
379 summary: 0.3
379 summary: 0.3
380
380
381 changeset: 2:e38ba6f5b7e0
381 changeset: 2:e38ba6f5b7e0
382 phase: public
382 phase: public
383 user: test
383 user: test
384 date: Thu Jan 01 00:00:00 1970 +0000
384 date: Thu Jan 01 00:00:00 1970 +0000
385 summary: 0.2
385 summary: 0.2
386
386
387 changeset: 1:34c2bf6b0626
387 changeset: 1:34c2bf6b0626
388 phase: public
388 phase: public
389 user: test
389 user: test
390 date: Thu Jan 01 00:00:00 1970 +0000
390 date: Thu Jan 01 00:00:00 1970 +0000
391 summary: 0.1
391 summary: 0.1
392
392
393 changeset: 0:f9ee2f85a263
393 changeset: 0:f9ee2f85a263
394 phase: public
394 phase: public
395 user: test
395 user: test
396 date: Thu Jan 01 00:00:00 1970 +0000
396 date: Thu Jan 01 00:00:00 1970 +0000
397 summary: 0.0
397 summary: 0.0
398
398
399
399
400 Incoming full.hg in partial
400 Incoming full.hg in partial
401
401
402 $ hg incoming bundle://../full.hg
402 $ hg incoming bundle://../full.hg
403 comparing with bundle:../full.hg
403 comparing with bundle:../full.hg
404 searching for changes
404 searching for changes
405 changeset: 4:095197eb4973
405 changeset: 4:095197eb4973
406 parent: 0:f9ee2f85a263
406 parent: 0:f9ee2f85a263
407 user: test
407 user: test
408 date: Thu Jan 01 00:00:00 1970 +0000
408 date: Thu Jan 01 00:00:00 1970 +0000
409 summary: 1.1
409 summary: 1.1
410
410
411 changeset: 5:1bb50a9436a7
411 changeset: 5:1bb50a9436a7
412 user: test
412 user: test
413 date: Thu Jan 01 00:00:00 1970 +0000
413 date: Thu Jan 01 00:00:00 1970 +0000
414 summary: 1.2
414 summary: 1.2
415
415
416 changeset: 6:7373c1169842
416 changeset: 6:7373c1169842
417 user: test
417 user: test
418 date: Thu Jan 01 00:00:00 1970 +0000
418 date: Thu Jan 01 00:00:00 1970 +0000
419 summary: 1.3
419 summary: 1.3
420
420
421 changeset: 7:a6a34bfa0076
421 changeset: 7:a6a34bfa0076
422 user: test
422 user: test
423 date: Thu Jan 01 00:00:00 1970 +0000
423 date: Thu Jan 01 00:00:00 1970 +0000
424 summary: 1.3m
424 summary: 1.3m
425
425
426 changeset: 8:aa35859c02ea
426 changeset: 8:aa35859c02ea
427 tag: tip
427 tag: tip
428 parent: 3:eebf5a27f8ca
428 parent: 3:eebf5a27f8ca
429 user: test
429 user: test
430 date: Thu Jan 01 00:00:00 1970 +0000
430 date: Thu Jan 01 00:00:00 1970 +0000
431 summary: 0.3m
431 summary: 0.3m
432
432
433
433
434 Outgoing -R full.hg vs partial2 in partial
434 Outgoing -R full.hg vs partial2 in partial
435
435
436 $ hg -R bundle://../full.hg outgoing ../partial2
436 $ hg -R bundle://../full.hg outgoing ../partial2
437 comparing with ../partial2
437 comparing with ../partial2
438 searching for changes
438 searching for changes
439 changeset: 4:095197eb4973
439 changeset: 4:095197eb4973
440 parent: 0:f9ee2f85a263
440 parent: 0:f9ee2f85a263
441 user: test
441 user: test
442 date: Thu Jan 01 00:00:00 1970 +0000
442 date: Thu Jan 01 00:00:00 1970 +0000
443 summary: 1.1
443 summary: 1.1
444
444
445 changeset: 5:1bb50a9436a7
445 changeset: 5:1bb50a9436a7
446 user: test
446 user: test
447 date: Thu Jan 01 00:00:00 1970 +0000
447 date: Thu Jan 01 00:00:00 1970 +0000
448 summary: 1.2
448 summary: 1.2
449
449
450 changeset: 6:7373c1169842
450 changeset: 6:7373c1169842
451 user: test
451 user: test
452 date: Thu Jan 01 00:00:00 1970 +0000
452 date: Thu Jan 01 00:00:00 1970 +0000
453 summary: 1.3
453 summary: 1.3
454
454
455 changeset: 7:a6a34bfa0076
455 changeset: 7:a6a34bfa0076
456 user: test
456 user: test
457 date: Thu Jan 01 00:00:00 1970 +0000
457 date: Thu Jan 01 00:00:00 1970 +0000
458 summary: 1.3m
458 summary: 1.3m
459
459
460 changeset: 8:aa35859c02ea
460 changeset: 8:aa35859c02ea
461 tag: tip
461 tag: tip
462 parent: 3:eebf5a27f8ca
462 parent: 3:eebf5a27f8ca
463 user: test
463 user: test
464 date: Thu Jan 01 00:00:00 1970 +0000
464 date: Thu Jan 01 00:00:00 1970 +0000
465 summary: 0.3m
465 summary: 0.3m
466
466
467
467
468 Outgoing -R does-not-exist.hg vs partial2 in partial
468 Outgoing -R does-not-exist.hg vs partial2 in partial
469
469
470 $ hg -R bundle://../does-not-exist.hg outgoing ../partial2
470 $ hg -R bundle://../does-not-exist.hg outgoing ../partial2
471 abort: *../does-not-exist.hg* (glob)
471 abort: *../does-not-exist.hg* (glob)
472 [255]
472 [255]
473 $ cd ..
473 $ cd ..
474
474
475 hide outer repo
475 hide outer repo
476 $ hg init
476 $ hg init
477
477
478 Direct clone from bundle (all-history)
478 Direct clone from bundle (all-history)
479
479
480 $ hg clone full.hg full-clone
480 $ hg clone full.hg full-clone
481 requesting all changes
481 requesting all changes
482 adding changesets
482 adding changesets
483 adding manifests
483 adding manifests
484 adding file changes
484 adding file changes
485 added 9 changesets with 7 changes to 4 files (+1 heads)
485 added 9 changesets with 7 changes to 4 files (+1 heads)
486 updating to branch default
486 updating to branch default
487 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
487 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
488 $ hg -R full-clone heads
488 $ hg -R full-clone heads
489 changeset: 8:aa35859c02ea
489 changeset: 8:aa35859c02ea
490 tag: tip
490 tag: tip
491 parent: 3:eebf5a27f8ca
491 parent: 3:eebf5a27f8ca
492 user: test
492 user: test
493 date: Thu Jan 01 00:00:00 1970 +0000
493 date: Thu Jan 01 00:00:00 1970 +0000
494 summary: 0.3m
494 summary: 0.3m
495
495
496 changeset: 7:a6a34bfa0076
496 changeset: 7:a6a34bfa0076
497 user: test
497 user: test
498 date: Thu Jan 01 00:00:00 1970 +0000
498 date: Thu Jan 01 00:00:00 1970 +0000
499 summary: 1.3m
499 summary: 1.3m
500
500
501 $ rm -r full-clone
501 $ rm -r full-clone
502
502
503 When cloning from a non-copiable repository into '', do not
503 When cloning from a non-copiable repository into '', do not
504 recurse infinitely (issue2528)
504 recurse infinitely (issue2528)
505
505
506 $ hg clone full.hg ''
506 $ hg clone full.hg ''
507 abort: empty destination path is not valid
507 abort: empty destination path is not valid
508 [255]
508 [255]
509
509
510 test for https://bz.mercurial-scm.org/216
510 test for https://bz.mercurial-scm.org/216
511
511
512 Unbundle incremental bundles into fresh empty in one go
512 Unbundle incremental bundles into fresh empty in one go
513
513
514 $ rm -r empty
514 $ rm -r empty
515 $ hg init empty
515 $ hg init empty
516 $ hg -R test bundle --base null -r 0 ../0.hg
516 $ hg -R test bundle --base null -r 0 ../0.hg
517 1 changesets found
517 1 changesets found
518 $ hg -R test bundle --base 0 -r 1 ../1.hg
518 $ hg -R test bundle --base 0 -r 1 ../1.hg
519 1 changesets found
519 1 changesets found
520 $ hg -R empty unbundle -u ../0.hg ../1.hg
520 $ hg -R empty unbundle -u ../0.hg ../1.hg
521 adding changesets
521 adding changesets
522 adding manifests
522 adding manifests
523 adding file changes
523 adding file changes
524 added 1 changesets with 1 changes to 1 files
524 added 1 changesets with 1 changes to 1 files
525 adding changesets
525 adding changesets
526 adding manifests
526 adding manifests
527 adding file changes
527 adding file changes
528 added 1 changesets with 1 changes to 1 files
528 added 1 changesets with 1 changes to 1 files
529 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
529 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
530
530
531 View full contents of the bundle
531 View full contents of the bundle
532 $ hg -R test bundle --base null -r 3 ../partial.hg
532 $ hg -R test bundle --base null -r 3 ../partial.hg
533 4 changesets found
533 4 changesets found
534 $ cd test
534 $ cd test
535 $ hg -R ../../partial.hg log -r "bundle()"
535 $ hg -R ../../partial.hg log -r "bundle()"
536 changeset: 0:f9ee2f85a263
536 changeset: 0:f9ee2f85a263
537 user: test
537 user: test
538 date: Thu Jan 01 00:00:00 1970 +0000
538 date: Thu Jan 01 00:00:00 1970 +0000
539 summary: 0.0
539 summary: 0.0
540
540
541 changeset: 1:34c2bf6b0626
541 changeset: 1:34c2bf6b0626
542 user: test
542 user: test
543 date: Thu Jan 01 00:00:00 1970 +0000
543 date: Thu Jan 01 00:00:00 1970 +0000
544 summary: 0.1
544 summary: 0.1
545
545
546 changeset: 2:e38ba6f5b7e0
546 changeset: 2:e38ba6f5b7e0
547 user: test
547 user: test
548 date: Thu Jan 01 00:00:00 1970 +0000
548 date: Thu Jan 01 00:00:00 1970 +0000
549 summary: 0.2
549 summary: 0.2
550
550
551 changeset: 3:eebf5a27f8ca
551 changeset: 3:eebf5a27f8ca
552 user: test
552 user: test
553 date: Thu Jan 01 00:00:00 1970 +0000
553 date: Thu Jan 01 00:00:00 1970 +0000
554 summary: 0.3
554 summary: 0.3
555
555
556 $ cd ..
556 $ cd ..
557
557
558 test for 540d1059c802
558 test for 540d1059c802
559
559
560 test for 540d1059c802
560 test for 540d1059c802
561
561
562 $ hg init orig
562 $ hg init orig
563 $ cd orig
563 $ cd orig
564 $ echo foo > foo
564 $ echo foo > foo
565 $ hg add foo
565 $ hg add foo
566 $ hg ci -m 'add foo'
566 $ hg ci -m 'add foo'
567
567
568 $ hg clone . ../copy
568 $ hg clone . ../copy
569 updating to branch default
569 updating to branch default
570 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
570 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
571 $ hg tag foo
571 $ hg tag foo
572
572
573 $ cd ../copy
573 $ cd ../copy
574 $ echo >> foo
574 $ echo >> foo
575 $ hg ci -m 'change foo'
575 $ hg ci -m 'change foo'
576 $ hg bundle ../bundle.hg ../orig
576 $ hg bundle ../bundle.hg ../orig
577 searching for changes
577 searching for changes
578 1 changesets found
578 1 changesets found
579
579
580 $ cd ../orig
580 $ cd ../orig
581 $ hg incoming ../bundle.hg
581 $ hg incoming ../bundle.hg
582 comparing with ../bundle.hg
582 comparing with ../bundle.hg
583 searching for changes
583 searching for changes
584 changeset: 2:ed1b79f46b9a
584 changeset: 2:ed1b79f46b9a
585 tag: tip
585 tag: tip
586 parent: 0:bbd179dfa0a7
586 parent: 0:bbd179dfa0a7
587 user: test
587 user: test
588 date: Thu Jan 01 00:00:00 1970 +0000
588 date: Thu Jan 01 00:00:00 1970 +0000
589 summary: change foo
589 summary: change foo
590
590
591 $ cd ..
591 $ cd ..
592
592
593 test bundle with # in the filename (issue2154):
593 test bundle with # in the filename (issue2154):
594
594
595 $ cp bundle.hg 'test#bundle.hg'
595 $ cp bundle.hg 'test#bundle.hg'
596 $ cd orig
596 $ cd orig
597 $ hg incoming '../test#bundle.hg'
597 $ hg incoming '../test#bundle.hg'
598 comparing with ../test
598 comparing with ../test
599 abort: unknown revision 'bundle.hg'!
599 abort: unknown revision 'bundle.hg'!
600 [255]
600 [255]
601
601
602 note that percent encoding is not handled:
602 note that percent encoding is not handled:
603
603
604 $ hg incoming ../test%23bundle.hg
604 $ hg incoming ../test%23bundle.hg
605 abort: repository ../test%23bundle.hg not found!
605 abort: repository ../test%23bundle.hg not found!
606 [255]
606 [255]
607 $ cd ..
607 $ cd ..
608
608
609 test to bundle revisions on the newly created branch (issue3828):
609 test to bundle revisions on the newly created branch (issue3828):
610
610
611 $ hg -q clone -U test test-clone
611 $ hg -q clone -U test test-clone
612 $ cd test
612 $ cd test
613
613
614 $ hg -q branch foo
614 $ hg -q branch foo
615 $ hg commit -m "create foo branch"
615 $ hg commit -m "create foo branch"
616 $ hg -q outgoing ../test-clone
616 $ hg -q outgoing ../test-clone
617 9:b4f5acb1ee27
617 9:b4f5acb1ee27
618 $ hg -q bundle --branch foo foo.hg ../test-clone
618 $ hg -q bundle --branch foo foo.hg ../test-clone
619 $ hg -R foo.hg -q log -r "bundle()"
619 $ hg -R foo.hg -q log -r "bundle()"
620 9:b4f5acb1ee27
620 9:b4f5acb1ee27
621
621
622 $ cd ..
622 $ cd ..
623
623
624 test for https://bz.mercurial-scm.org/1144
624 test for https://bz.mercurial-scm.org/1144
625
625
626 test that verify bundle does not traceback
626 test that verify bundle does not traceback
627
627
628 partial history bundle, fails w/ unknown parent
628 partial history bundle, fails w/ unknown parent
629
629
630 $ hg -R bundle.hg verify
630 $ hg -R bundle.hg verify
631 abort: 00changelog.i@bbd179dfa0a7: unknown parent!
631 abort: 00changelog.i@bbd179dfa0a7: unknown parent!
632 [255]
632 [255]
633
633
634 full history bundle, refuses to verify non-local repo
634 full history bundle, refuses to verify non-local repo
635
635
636 $ hg -R all.hg verify
636 $ hg -R all.hg verify
637 abort: cannot verify bundle or remote repos
637 abort: cannot verify bundle or remote repos
638 [255]
638 [255]
639
639
640 but, regular verify must continue to work
640 but, regular verify must continue to work
641
641
642 $ hg -R orig verify
642 $ hg -R orig verify
643 checking changesets
643 checking changesets
644 checking manifests
644 checking manifests
645 crosschecking files in changesets and manifests
645 crosschecking files in changesets and manifests
646 checking files
646 checking files
647 2 files, 2 changesets, 2 total revisions
647 2 files, 2 changesets, 2 total revisions
648
648
649 diff against bundle
649 diff against bundle
650
650
651 $ hg init b
651 $ hg init b
652 $ cd b
652 $ cd b
653 $ hg -R ../all.hg diff -r tip
653 $ hg -R ../all.hg diff -r tip
654 diff -r aa35859c02ea anotherfile
654 diff -r aa35859c02ea anotherfile
655 --- a/anotherfile Thu Jan 01 00:00:00 1970 +0000
655 --- a/anotherfile Thu Jan 01 00:00:00 1970 +0000
656 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
656 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
657 @@ -1,4 +0,0 @@
657 @@ -1,4 +0,0 @@
658 -0
658 -0
659 -1
659 -1
660 -2
660 -2
661 -3
661 -3
662 $ cd ..
662 $ cd ..
663
663
664 bundle single branch
664 bundle single branch
665
665
666 $ hg init branchy
666 $ hg init branchy
667 $ cd branchy
667 $ cd branchy
668 $ echo a >a
668 $ echo a >a
669 $ echo x >x
669 $ echo x >x
670 $ hg ci -Ama
670 $ hg ci -Ama
671 adding a
671 adding a
672 adding x
672 adding x
673 $ echo c >c
673 $ echo c >c
674 $ echo xx >x
674 $ echo xx >x
675 $ hg ci -Amc
675 $ hg ci -Amc
676 adding c
676 adding c
677 $ echo c1 >c1
677 $ echo c1 >c1
678 $ hg ci -Amc1
678 $ hg ci -Amc1
679 adding c1
679 adding c1
680 $ hg up 0
680 $ hg up 0
681 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
681 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
682 $ echo b >b
682 $ echo b >b
683 $ hg ci -Amb
683 $ hg ci -Amb
684 adding b
684 adding b
685 created new head
685 created new head
686 $ echo b1 >b1
686 $ echo b1 >b1
687 $ echo xx >x
687 $ echo xx >x
688 $ hg ci -Amb1
688 $ hg ci -Amb1
689 adding b1
689 adding b1
690 $ hg clone -q -r2 . part
690 $ hg clone -q -r2 . part
691
691
692 == bundling via incoming
692 == bundling via incoming
693
693
694 $ hg in -R part --bundle incoming.hg --template "{node}\n" .
694 $ hg in -R part --bundle incoming.hg --template "{node}\n" .
695 comparing with .
695 comparing with .
696 searching for changes
696 searching for changes
697 1a38c1b849e8b70c756d2d80b0b9a3ac0b7ea11a
697 1a38c1b849e8b70c756d2d80b0b9a3ac0b7ea11a
698 057f4db07f61970e1c11e83be79e9d08adc4dc31
698 057f4db07f61970e1c11e83be79e9d08adc4dc31
699
699
700 == bundling
700 == bundling
701
701
702 $ hg bundle bundle.hg part --debug --config progress.debug=true
702 $ hg bundle bundle.hg part --debug --config progress.debug=true
703 query 1; heads
703 query 1; heads
704 searching for changes
704 searching for changes
705 all remote heads known locally
705 all remote heads known locally
706 2 changesets found
706 2 changesets found
707 list of changesets:
707 list of changesets:
708 1a38c1b849e8b70c756d2d80b0b9a3ac0b7ea11a
708 1a38c1b849e8b70c756d2d80b0b9a3ac0b7ea11a
709 057f4db07f61970e1c11e83be79e9d08adc4dc31
709 057f4db07f61970e1c11e83be79e9d08adc4dc31
710 bundle2-output-bundle: "HG20", (1 params) 1 parts total
710 bundle2-output-bundle: "HG20", (1 params) 1 parts total
711 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
711 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
712 bundling: 1/2 changesets (50.00%)
712 bundling: 1/2 changesets (50.00%)
713 bundling: 2/2 changesets (100.00%)
713 bundling: 2/2 changesets (100.00%)
714 bundling: 1/2 manifests (50.00%)
714 bundling: 1/2 manifests (50.00%)
715 bundling: 2/2 manifests (100.00%)
715 bundling: 2/2 manifests (100.00%)
716 bundling: b 1/3 files (33.33%)
716 bundling: b 1/3 files (33.33%)
717 bundling: b1 2/3 files (66.67%)
717 bundling: b1 2/3 files (66.67%)
718 bundling: x 3/3 files (100.00%)
718 bundling: x 3/3 files (100.00%)
719
719
720 == Test for issue3441
720 == Test for issue3441
721
721
722 $ hg clone -q -r0 . part2
722 $ hg clone -q -r0 . part2
723 $ hg -q -R part2 pull bundle.hg
723 $ hg -q -R part2 pull bundle.hg
724 $ hg -R part2 verify
724 $ hg -R part2 verify
725 checking changesets
725 checking changesets
726 checking manifests
726 checking manifests
727 crosschecking files in changesets and manifests
727 crosschecking files in changesets and manifests
728 checking files
728 checking files
729 4 files, 3 changesets, 5 total revisions
729 4 files, 3 changesets, 5 total revisions
730
730
731 == Test bundling no commits
731 == Test bundling no commits
732
732
733 $ hg bundle -r 'public()' no-output.hg
733 $ hg bundle -r 'public()' no-output.hg
734 abort: no commits to bundle
734 abort: no commits to bundle
735 [255]
735 [255]
736
737 $ cd ..
738
739 When user merges to the revision existing only in the bundle,
740 it should show warning that second parent of the working
741 directory does not exist
742
743 $ hg init update2bundled
744 $ cd update2bundled
745 $ cat <<EOF >> .hg/hgrc
746 > [extensions]
747 > strip =
748 > EOF
749 $ echo "aaa" >> a
750 $ hg commit -A -m 0
751 adding a
752 $ echo "bbb" >> b
753 $ hg commit -A -m 1
754 adding b
755 $ echo "ccc" >> c
756 $ hg commit -A -m 2
757 adding c
758 $ hg update -r 1
759 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
760 $ echo "ddd" >> d
761 $ hg commit -A -m 3
762 adding d
763 created new head
764 $ hg update -r 2
765 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
766 $ hg log -G
767 o changeset: 3:8bd3e1f196af
768 | tag: tip
769 | parent: 1:a01eca7af26d
770 | user: test
771 | date: Thu Jan 01 00:00:00 1970 +0000
772 | summary: 3
773 |
774 | @ changeset: 2:4652c276ac4f
775 |/ user: test
776 | date: Thu Jan 01 00:00:00 1970 +0000
777 | summary: 2
778 |
779 o changeset: 1:a01eca7af26d
780 | user: test
781 | date: Thu Jan 01 00:00:00 1970 +0000
782 | summary: 1
783 |
784 o changeset: 0:4fe08cd4693e
785 user: test
786 date: Thu Jan 01 00:00:00 1970 +0000
787 summary: 0
788
789 $ hg bundle --base 1 -r 3 ../update2bundled.hg
790 1 changesets found
791 $ hg strip -r 3
792 saved backup bundle to $TESTTMP/update2bundled/.hg/strip-backup/8bd3e1f196af-017e56d8-backup.hg (glob)
793 $ hg merge -R ../update2bundled.hg -r 3
794 setting parent to node 8bd3e1f196af289b2b121be08031e76d7ae92098 that only exists in the bundle
795 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
796 (branch merge, don't forget to commit)
797
798 When user updates to the revision existing only in the bundle,
799 it should show warning
800
801 $ hg update -R ../update2bundled.hg --clean -r 3
802 setting parent to node 8bd3e1f196af289b2b121be08031e76d7ae92098 that only exists in the bundle
803 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
804
805 When user updates to the revision existing in the local repository
806 the warning shouldn't be emitted
807
808 $ hg update -R ../update2bundled.hg -r 0
809 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